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