"""Driver for flowmeterskid.""" import threading import json import time from random import randint import os from device_base import deviceBase from Channel import PLCChannel, ModbusChannel,read_tag, write_tag, TAG_DATAERROR_SLEEPTIME import persistence from utilities import get_public_ip_address, get_private_ip_address from file_logger import filelogger as logger PLC_IP_ADDRESS = "192.168.1.12" from Tags import tags from datetime import datetime as dt logger.info("flowmeterskid startup") # GLOBAL VARIABLES WAIT_FOR_CONNECTION_SECONDS = 20 IP_CHECK_PERIOD = 60 _ = None CHANNELS = tags class start(threading.Thread, deviceBase): """Start class required by Meshify.""" def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, companyId=None, offset=None, mqtt=None, Nodes=None): """Initialize the driver.""" threading.Thread.__init__(self) deviceBase.__init__(self, name=name, number=number, mac=mac, Q=Q, mcu=mcu, companyId=companyId, offset=offset, mqtt=mqtt, Nodes=Nodes) self.daemon = True self.version = "1" self.finished = threading.Event() self.force_send = False self.public_ip_address = "" self.public_ip_address_last_checked = 0 self.private_ip_address = "" self.ping_counter = 0 threading.Thread.start(self) # this is a required function for all drivers, its goal is to upload some piece of data # about your device so it can be seen on the web def register(self): """Register the driver.""" # self.sendtodb("log", "BOOM! Booted.", 0) pass def run(self): # pass """Actually run the driver.""" for i in range(0, WAIT_FOR_CONNECTION_SECONDS): print("flowmeterskid driver will start in {} seconds".format(WAIT_FOR_CONNECTION_SECONDS - i)) time.sleep(1) logger.info("BOOM! Starting flowmeterskid driver...") self._check_ip_address() self.nodes["flowmeterskid_0199"] = self send_loops = 0 while True: if self.force_send: logger.warning("FORCE SEND: TRUE") if int(time.time()) % 600 == 0 or self.force_send: payload = {"ts": (round(dt.timestamp(dt.now())/600)*600)*1000, "values": {}} resetPayload = {"ts": "", "values": {}} dayReset, weekReset, monthReset, yearReset = False, False, False, False for chan in CHANNELS: val = chan.read() try: if chan in ["totalizer_1"]: payload["values"]["day_volume"], dayReset = self.totalizeDay(val) payload["values"]["week_volume"], weekReset = self.totalizeWeek(val) payload["values"]["month_volume"], monthReset = self.totalizeMonth(val) payload["values"]["year_volume"], yearReset = self.totalizeYear(val) payload["values"][chan.mesh_name] = val except Exception as e: logger.error(e) self.sendToTB(json.dumps(payload)) if dayReset: resetPayload["values"]["yesterday_volume"] = payload["values"]["day_volume"] resetPayload["values"]["day_volume"] = 0 if weekReset: resetPayload["values"]["last_week_volume"] = payload["values"]["week_volume"] resetPayload["values"]["week_volume"] = 0 if monthReset: resetPayload["values"]["last_month_volume"] = payload["values"]["month_volume"] resetPayload["values"]["month_volume"] = 0 if yearReset: resetPayload["values"]["last_year_volume"] = payload["values"]["year_volume"] resetPayload["values"]["year_volume"] = 0 if resetPayload["values"]: resetPayload["ts"] = 1 + (round(dt.timestamp(dt.now())/600)*600)*1000 self.sendToTB(json.dumps(resetPayload)) if self.force_send: self.force_send = False def flowmeterskid_sync(self, name, value): """Sync all data from the driver.""" self.force_send = True self.sendtodb("log", "synced", 0) return True def saveTotalizers(self, totalizers): try: with open("/root/python_firmware/totalizers.json", "w") as t: json.dump(totalizers,t) except Exception as e: logger.error(e) def get_totalizers(self): saveFile = "/root/python_firmware/totalizers.json" # Check if the state file exists. if not os.path.exists(saveFile): return { "day": 0, "week": 0, "month": 0, "year": 0, "lifetime": 0, "dayHolding": 0, "weekHolding": 0, "monthHolding": 0, "yearHolding": 0 } try: with open("/root/python_firmware/totalizers.json", "r") as t: totalizers = json.load(t) if not totalizers: logger.info("-----INITIALIZING TOTALIZERS-----") totalizers = { "day": 0, "week": 0, "month": 0, "year": 0, "lifetime": 0, "dayHolding": 0, "weekHolding": 0, "monthHolding": 0, "yearHolding": 0 } except: totalizers = { "day": 0, "week": 0, "month": 0, "year": 0, "lifetime": 0, "dayHolding": 0, "weekHolding": 0, "monthHolding": 0, "yearHolding": 0 } return totalizers def totalizeDay(self,lifetime): totalizers = self.get_totalizers() now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600) reset = False value = lifetime - totalizers["dayHolding"] if not int(now.strftime("%d")) == int(totalizers["day"]): totalizers["dayHolding"] = lifetime totalizers["day"] = int(now.strftime("%d")) self.saveTotalizers(totalizers) reset = True return (value,reset) def totalizeWeek(self,lifetime): totalizers = self.get_totalizers() now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600) reset = False value = lifetime - totalizers["weekHolding"] if (not now.strftime("%U") == totalizers["week"] and now.strftime("%a") == "Sun") or totalizers["week"] == 0: totalizers["weekHolding"] = lifetime totalizers["week"] = now.strftime("%U") self.saveTotalizers(totalizers) reset = True return (value, reset) def totalizeMonth(self,lifetime): totalizers = self.get_totalizers() now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600) reset = False value = lifetime - totalizers["monthHolding"] if not int(now.strftime("%m")) == int(totalizers["month"]): totalizers["monthHolding"] = lifetime totalizers["month"] = now.strftime("%m") self.saveTotalizers(totalizers) reset = True return (value,reset) def totalizeYear(self,lifetime): totalizers = self.get_totalizers() now = dt.fromtimestamp(round(dt.timestamp(dt.now())/600)*600) reset = False value = lifetime - totalizers["yearHolding"] if not int(now.strftime("%Y")) == int(totalizers["year"]): totalizers["yearHolding"] = lifetime totalizers["year"] = now.strftime("%Y") self.saveTotalizers(totalizers) reset = True return (value, reset)