diff --git a/abbflow.py b/abbflow.py deleted file mode 100644 index db9628b..0000000 --- a/abbflow.py +++ /dev/null @@ -1,31 +0,0 @@ -"""Driver for connecting ABB Flowmeter to Meshify.""" -import threading -from device_base import deviceBase - - -class start(threading.Thread, deviceBase): - """Start class required for driver.""" - - def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, - companyId=None, offset=None, mqtt=None, Nodes=None): - """Initalize 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 = "7" - self.finished = threading.Event() - 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.channels["status"]["last_value"] = "" - - def run(self): - """Run the driver.""" - pass diff --git a/channels_abbflow.csv b/channels_abbflow.csv new file mode 100644 index 0000000..ea9451d --- /dev/null +++ b/channels_abbflow.csv @@ -0,0 +1,14 @@ +id,name,deviceTypeId,fromMe,io,subTitle,helpExplanation,channelType,dataType,defaultValue,regex,regexErrMsg,units,min,max,change,guaranteedReportPeriod,minReportTime +8333,battery_voltage,317,FALSE,readonly,Battery Voltage,V,device,float,,,,,,,,, +8334,volume_flow,317,FALSE,readonly,Volume Flow,MCF/Day,device,float,,,,,,,,, +8335,today_volume,317,FALSE,readonly,Today Volume,MCF,device,float,,,,,,,,, +8336,yesterday_volume,317,FALSE,readonly,Yesterday Volume,MCF,device,float,,,,,,,,, +8337,accumulated_volume,317,FALSE,readonly,Accumulated Volume,MCF,device,float,,,,,,,,, +8338,last_calculation_period_volume,317,FALSE,readonly,Last Calculation Period Volume,SCF,device,float,,,,,,,,, +8339,differential_pressure,317,FALSE,readonly,Differential Pressure,InH2O,device,float,,,,,,,,, +8340,static_pressure,317,FALSE,readonly,Static Pressure,PSIA,device,float,,,,,,,,, +8341,temperature,317,FALSE,readonly,Temperature,deg F,device,float,,,,,,,,, +8349,charger_voltage,317,FALSE,readonly,Charger Voltage,V,device,float,,,,,,,,, +8358,notes,317,FALSE,readwrite,Notes,User-entered notes,user input,string,No notes yet...,,,,,,,, +9018,sleeplog,317,FALSE,readonly,Sleep Log,Log of sleep and awakeness,device,string,Nothing here yet...,,,,,,,, +,public_ip_address,317,FALSE,readonly,Public IP Address,Network Address,device,string,n/a,,,,,,,, \ No newline at end of file diff --git a/html-templates/Device.html b/html-templates/Device.html new file mode 100644 index 0000000..5feeb9b --- /dev/null +++ b/html-templates/Device.html @@ -0,0 +1,42 @@ +
+
+

Public IP Address

+

<%= channels["abbflow.public_ip_address"].value %>

+

+
+ + diff --git a/History.html b/html-templates/History.html similarity index 100% rename from History.html rename to html-templates/History.html diff --git a/NodeDetailHeader.html b/html-templates/NodeDetailHeader.html similarity index 100% rename from NodeDetailHeader.html rename to html-templates/NodeDetailHeader.html diff --git a/NodeList.html b/html-templates/NodeList.html similarity index 100% rename from NodeList.html rename to html-templates/NodeList.html diff --git a/Overview.html b/html-templates/Overview.html similarity index 100% rename from Overview.html rename to html-templates/Overview.html diff --git a/Sidebar.html b/html-templates/Sidebar.html similarity index 100% rename from Sidebar.html rename to html-templates/Sidebar.html diff --git a/python-driver/abbflow.py b/python-driver/abbflow.py new file mode 100644 index 0000000..e8c98ae --- /dev/null +++ b/python-driver/abbflow.py @@ -0,0 +1,53 @@ +"""Driver for connecting ABB Flowmeter to Meshify.""" +import threading +import time +from device_base import deviceBase +from utilities import get_public_ip_address + +WAIT_FOR_CONNECTION_SECONDS = 60 +IP_CHECK_PERIOD = 60 + +class start(threading.Thread, deviceBase): + """Start class required for driver.""" + + def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, + companyId=None, offset=None, mqtt=None, Nodes=None): + """Initalize 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 = "8" + self.finished = threading.Event() + self.public_ip_address = "" + self.public_ip_address_last_checked = 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.channels["status"]["last_value"] = "" + + def run(self): + """Run the driver.""" + for i in range(0, WAIT_FOR_CONNECTION_SECONDS): + print("abbflow driver will start in {} seconds".format(WAIT_FOR_CONNECTION_SECONDS - i)) + time.sleep(1) + + while True: + if (time.time() - self.public_ip_address_last_checked) > IP_CHECK_PERIOD: + self._check_ip_address() + + def _check_ip_address(self): + """Check the public IP address and send to Meshify if changed.""" + print("Checking IP Address...") + self.public_ip_address_last_checked = time.time() + test_public_ip = get_public_ip_address() + print("Got {} for IP Address".format(test_public_ip)) + if not test_public_ip == self.public_ip_address: + self.sendtodbDev(1, 'public_ip_address', test_public_ip, 0, 'abbflow') + self.public_ip_address = test_public_ip diff --git a/config.txt b/python-driver/config.txt similarity index 86% rename from config.txt rename to python-driver/config.txt index 8c1a4e4..0715dd5 100644 --- a/config.txt +++ b/python-driver/config.txt @@ -3,7 +3,7 @@ "driverFileName":"abbflow.py", "deviceName":"abbflow", "driverId":"0110", -"releaseVersion":"7", +"releaseVersion":"8", "files": { "file1":"abbflow.py", "file2":"modbusMap.p" } diff --git a/python-driver/driverConfig.json b/python-driver/driverConfig.json new file mode 100644 index 0000000..cbfbdcb --- /dev/null +++ b/python-driver/driverConfig.json @@ -0,0 +1,11 @@ +{ + "name": "abbflow", + "driverFilename": "abbflow.py", + "driverId": "0110", + "additionalDriverFiles": [ + "utilities.py", + "modbusMap.p" + ], + "version": 8, + "s3BucketName": "abbflow" +} diff --git a/modbusMap.p b/python-driver/modbusMap.p similarity index 100% rename from modbusMap.p rename to python-driver/modbusMap.p diff --git a/python-driver/utilities.py b/python-driver/utilities.py new file mode 100644 index 0000000..fbd2556 --- /dev/null +++ b/python-driver/utilities.py @@ -0,0 +1,49 @@ +"""Utility functions for the driver.""" +import socket +import struct + + +def get_public_ip_address(): + """Find the public IP Address of the host device.""" + sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM) + sock.connect(("8.8.8.8", 80)) + ip_address = sock.getsockname()[0] + sock.close() + return ip_address + + +def int_to_float16(int_to_convert): + """Convert integer into float16 representation.""" + bin_rep = ('0' * 16 + '{0:b}'.format(int_to_convert))[-16:] + sign = 1.0 + if int(bin_rep[0]) == 1: + sign = -1.0 + exponent = float(int(bin_rep[1:6], 2)) + fraction = float(int(bin_rep[6:17], 2)) + + if exponent == float(0b00000): + return sign * 2 ** -14 * fraction / (2.0 ** 10.0) + elif exponent == float(0b11111): + if fraction == 0: + return sign * float("inf") + return float("NaN") + frac_part = 1.0 + fraction / (2.0 ** 10.0) + return sign * (2 ** (exponent - 15)) * frac_part + + +def ints_to_float(int1, int2): + """Convert 2 registers into a floating point number.""" + mypack = struct.pack('>HH', int1, int2) + f_unpacked = struct.unpack('>f', mypack) + print("[{}, {}] >> {}".format(int1, int2, f_unpacked[0])) + return f_unpacked[0] + + +def degf_to_degc(temp_f): + """Convert deg F to deg C.""" + return (temp_f - 32.0) * (5.0/9.0) + + +def degc_to_degf(temp_c): + """Convert deg C to deg F.""" + return temp_c * 1.8 + 32.0