127 lines
3.9 KiB
Python
127 lines
3.9 KiB
Python
import configparser
|
|
import pprint
|
|
import time
|
|
from datetime import datetime
|
|
|
|
from energy_monitor import CONN_STR, DatabaseManager, PlcManager
|
|
from logger_setup import setup_logger
|
|
|
|
# Globals
|
|
DEVICE_DELAY = 1 # Delay between device data fetches
|
|
POOL_RATE = 2 # 2s polling rate reading of NextRead value from database
|
|
FALLBACK_INTERVAL = 20 # 1h = 3600s interval in case db read issue
|
|
|
|
# Logger setup
|
|
logger = setup_logger()
|
|
|
|
# Load config.ini
|
|
config = configparser.ConfigParser()
|
|
config.read("config.ini")
|
|
|
|
|
|
def process_plc_devices(db_manager: DatabaseManager, plc_manager: PlcManager):
|
|
plc_configs = db_manager.get_plc_configs()
|
|
# If debug print out plc_configs to logs
|
|
logger.debug(
|
|
{
|
|
"msg": "Retrieved PLC configurations",
|
|
"plc_configs": [
|
|
{
|
|
"id": plc.id,
|
|
"ip": plc.ip,
|
|
"location": plc.location,
|
|
"is_enabled": plc.is_enabled,
|
|
"db_number": plc.db_number,
|
|
}
|
|
for plc in plc_configs
|
|
],
|
|
"timestamp": datetime.now().isoformat(),
|
|
},
|
|
)
|
|
for plc_config in plc_configs:
|
|
try:
|
|
if not plc_manager.check_connection(plc_config.ip):
|
|
logger.error(
|
|
{
|
|
"msg": "PLC connection failed",
|
|
"PlcId": plc_config.id,
|
|
"PlcIp": plc_config.ip,
|
|
"timestamp": datetime.now().isoformat(),
|
|
}
|
|
)
|
|
continue
|
|
|
|
air_value, energy_value, run_status = plc_manager.read_plc_data(plc_config)
|
|
db_manager.save_energy_data(plc_config.id, energy_value, air_value, True)
|
|
|
|
logger.info(
|
|
{
|
|
"msg": ":white_check_mark: Data successfully read and saved",
|
|
"PlcId": plc_config.id,
|
|
"PlcIp": plc_config.ip,
|
|
"energy_value": energy_value,
|
|
"air_value": air_value,
|
|
"timestamp": datetime.now().isoformat(),
|
|
},
|
|
)
|
|
|
|
time.sleep(DEVICE_DELAY) # n-second delay between devices
|
|
|
|
except Exception as e:
|
|
logger.error(
|
|
{
|
|
"msg": "Error reading PLC data",
|
|
"PlcId": plc_config.id,
|
|
"PlcIp": plc_config.ip,
|
|
"error": str(e),
|
|
"timestamp": datetime.now().isoformat(),
|
|
},
|
|
)
|
|
|
|
|
|
def main():
|
|
db_manager = DatabaseManager(CONN_STR)
|
|
plc_manager = PlcManager()
|
|
|
|
pprint.pp(
|
|
{
|
|
"SQL_Config": {
|
|
"Server": config["mssql"]["host"],
|
|
"Database": config["mssql"]["name"],
|
|
"User": config["mssql"]["user"],
|
|
# Masking password for security
|
|
"Password": "****",
|
|
},
|
|
"SEQ_Config": {
|
|
"URL": config["seq"]["url"],
|
|
# Masking API key for security
|
|
"API_Key": "****",
|
|
},
|
|
"timestamp": datetime.now().isoformat(),
|
|
}
|
|
)
|
|
|
|
while True:
|
|
try:
|
|
scheduler_config = db_manager.get_scheduler_config()
|
|
|
|
if datetime.now() >= scheduler_config.next_read:
|
|
process_plc_devices(db_manager, plc_manager)
|
|
db_manager.update_next_read(scheduler_config.interval)
|
|
|
|
time.sleep(POOL_RATE)
|
|
|
|
except Exception as e:
|
|
logger.error(
|
|
{
|
|
"msg": "Main loop error! Falling back to 1h interval.",
|
|
"error": str(e),
|
|
"timestamp": datetime.now().isoformat(),
|
|
},
|
|
)
|
|
time.sleep(FALLBACK_INTERVAL) # Default fallback interval
|
|
|
|
|
|
if __name__ == "__main__":
|
|
main()
|