2 Commits

Author SHA1 Message Date
Patrick McDonagh
b8778389e5 Adds device IP address to channels 2018-07-11 15:21:46 -05:00
Patrick McDonagh
668cbf3b9f v7 allows for up to 5000 mcf total 2017-08-14 11:13:54 -05:00
13 changed files with 424 additions and 286 deletions

View File

@@ -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 = "6"
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

14
channels_abbflow.csv Normal file
View File

@@ -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,,,,,,,,
1 id name deviceTypeId fromMe io subTitle helpExplanation channelType dataType defaultValue regex regexErrMsg units min max change guaranteedReportPeriod minReportTime
2 8333 battery_voltage 317 FALSE readonly Battery Voltage V device float
3 8334 volume_flow 317 FALSE readonly Volume Flow MCF/Day device float
4 8335 today_volume 317 FALSE readonly Today Volume MCF device float
5 8336 yesterday_volume 317 FALSE readonly Yesterday Volume MCF device float
6 8337 accumulated_volume 317 FALSE readonly Accumulated Volume MCF device float
7 8338 last_calculation_period_volume 317 FALSE readonly Last Calculation Period Volume SCF device float
8 8339 differential_pressure 317 FALSE readonly Differential Pressure InH2O device float
9 8340 static_pressure 317 FALSE readonly Static Pressure PSIA device float
10 8341 temperature 317 FALSE readonly Temperature deg F device float
11 8349 charger_voltage 317 FALSE readonly Charger Voltage V device float
12 8358 notes 317 FALSE readwrite Notes User-entered notes user input string No notes yet...
13 9018 sleeplog 317 FALSE readonly Sleep Log Log of sleep and awakeness device string Nothing here yet...
14 public_ip_address 317 FALSE readonly Public IP Address Network Address device string n/a

View File

@@ -0,0 +1,42 @@
<div class="row row-flex box-me">
<div class="col-md-6 text-center">
<h2 class="uppercase">Public IP Address</h2>
<p><%= channels["abbflow.public_ip_address"].value %><p>
</div>
</div>
<style>
.uppercase {
text-transform: uppercase;
font-size: 14px;
color: #666;
font-weight: 400;
letter-spacing: 1px;
z-index: 100;
}
.box-me {
position: relative;
padding: 0.5em;
padding-bottom: 1.5em;
border: 1px solid #eee;
/*margin: 1em 0;*/
}
.row-flex {
display: -webkit-box;
display: -webkit-flex;
display: -ms-flexbox;
display: flex;
flex-wrap: wrap;
}
.row-flex > [class*='col-'] {
display: flex;
flex-direction: column;
}
p {
font-size: 1.25em;
}
</style>

53
python-driver/abbflow.py Normal file
View File

@@ -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

View File

@@ -3,7 +3,7 @@
"driverFileName":"abbflow.py",
"deviceName":"abbflow",
"driverId":"0110",
"releaseVersion":"6",
"releaseVersion":"8",
"files": {
"file1":"abbflow.py",
"file2":"modbusMap.p" }

View File

@@ -0,0 +1,11 @@
{
"name": "abbflow",
"driverFilename": "abbflow.py",
"driverId": "0110",
"additionalDriverFiles": [
"utilities.py",
"modbusMap.p"
],
"version": 8,
"s3BucketName": "abbflow"
}

View File

@@ -46,63 +46,63 @@ V3600
p24
sVla
p25
F447.099
F1301.77
sVchn
p26
Vvolume_flow
p27
sVr
p28
V0-5000
p29
sVun
p30
p28
V1
p31
p29
sVdn
p32
p30
Vabbflow
p33
p31
sVda
p34
g31
p32
g29
sVlrt
p35
F1495637476.975421
p33
F1502726350.0681692
sVa
p36
p34
V4003
p37
p35
sVc
p38
p36
V20.0
p39
p37
sVmisc_u
p40
p38
VMCF/Day
p41
p39
sVf
p42
p40
V4
p43
p41
sVmrt
p44
p42
V60
p45
p43
sVm
p46
p44
Vnone
p47
p45
sVm1ch
p48
p46
g11
sVmv
p47
V0
p48
sVs
p49
VOn
p50
sVmv
sVr
p51
V0
V0-5000
p52
sVt
p53
@@ -120,7 +120,7 @@ sVbytary
p59
NsVal
p60
g52
g48
sVvn
p61
VToday Volume
@@ -139,55 +139,55 @@ V3600
p68
sVla
p69
F40.842
F214.742
sVchn
p70
Vtoday_volume
p71
sVun
p72
g31
g29
sVdn
p73
Vabbflow
p74
sVda
p75
g31
g29
sVlrt
p76
F1495637477.7369371
sg36
V4005
F1502726379.1855019
sg51
V0-1000
p77
sg38
V10.0
sg34
V4005
p78
sVmisc_u
sg36
V10.0
p79
VMCF
sVmisc_u
p80
sg42
g43
sVmrt
VMCF
p81
V60
sg40
g41
sVmrt
p82
sg46
Vnone
V60
p83
sVm1ch
sg44
Vnone
p84
g56
sVmv
sVm1ch
p85
g52
g56
sg49
VOn
p86
sg28
V0-1000
sVmv
p87
g48
sg53
Vfloat
p88
@@ -222,55 +222,55 @@ V3600
p102
sVla
p103
F12.765
F12.477
sVchn
p104
Vbattery_voltage
p105
sVun
sg51
V0-50
p106
g31
sVdn
p107
Vabbflow
p108
sVda
p109
g31
g29
sVlrt
p110
F1495635171.9785649
sg28
V0-50
F1502725891.0710198
sg34
V4001
p111
sg36
V4001
p112
sg38
V5
p113
p112
sVmisc_u
p114
p113
VV
p115
sg42
g43
p114
sg40
g41
sVmrt
p116
p115
V60
p117
sg46
p116
sg44
Vnone
p118
p117
sVm1ch
p119
p118
g90
sVmv
p119
g48
sg49
VOn
p120
sVmv
sVun
p121
g52
g29
sg53
Vfloat
p122
@@ -286,7 +286,7 @@ sVbytary
p127
NsVal
p128
g52
g48
sVvn
p129
VLast Calc. Period Volume
@@ -305,55 +305,55 @@ V86400
p136
sVla
p137
F306.472
F14.691
sVchn
p138
Vlast_calculation_period_volume
p139
sg28
V0-1000000
p140
sVun
p141
g31
p140
g29
sVdn
p142
p141
Vabbflow
p143
p142
sVda
p144
g31
p143
g29
sVlrt
p145
F1495637453.2386899
sg36
p144
F1502682560.7307109
sg34
V4011
p146
sg38
p145
sg36
V10
p147
p146
sVmisc_u
p148
p147
VSCF
p149
sg42
g43
p148
sg40
g41
sVmrt
p150
p149
V60
p151
sg46
p150
sg44
Vnone
p152
p151
sVm1ch
p153
p152
g124
sVmv
p153
g48
sg49
VOn
p154
sVmv
sg51
V0-1000000
p155
g52
sg53
Vfloat
p156
@@ -369,7 +369,7 @@ sVbytary
p161
NsVal
p162
g52
g48
sVvn
p163
VDifferential Pressure
@@ -388,54 +388,54 @@ V3600
p170
sVla
p171
F17.853000000000003
F3.095
sVchn
p172
Vdifferential_pressure
p173
sVun
p174
g31
g29
sVdn
p175
Vabbflow
p176
sVda
p177
g31
g29
sVlrt
p178
F1495634999.4304049
sg36
V4013
F1502725891.811299
sg51
V0-500
p179
sg38
g113
sVmisc_u
sg34
V4013
p180
VInH20
sg36
g112
sVmisc_u
p181
sg42
g43
sVmrt
VInH20
p182
V60
sg40
g41
sVmrt
p183
sg46
Vnone
V60
p184
sVm1ch
sg44
Vnone
p185
g158
sVmv
sVm1ch
p186
g52
g158
sg49
VOn
p187
sg28
V0-500
sVmv
p188
g48
sg53
Vfloat
p189
@@ -471,14 +471,14 @@ V21600
p204
sVla
p205
F0.152
F640.448
sVchn
p206
Vyesterday_volume
p207
sVr
sVun
p208
V0-1000
V1
p209
sVdn
p210
@@ -486,48 +486,48 @@ Vabbflow
p211
sVda
p212
V1
p213
g209
sVlrt
p214
F1486680992.5114956
p213
F1502517692.3270172
sVa
p215
p214
V4007
p216
p215
sVc
p217
p216
V10.0
p218
p217
sVmisc_u
p219
p218
VMCF
p220
p219
sVf
p221
p220
V4
p222
p221
sVmrt
p223
p222
V60
p224
p223
sVm
p225
p224
Vnone
p226
p225
sVm1ch
p227
p226
g191
sVmv
p228
p227
g196
sVs
p229
p228
VOn
p229
sVr
p230
sVun
V0-5000
p231
g213
sVt
p232
Vfloat
@@ -544,7 +544,7 @@ sVbytary
p238
NsVal
p239
g52
g48
sVvn
p240
VAccumulated Volume
@@ -563,55 +563,55 @@ V3600
p247
sVla
p248
F452604.031
F23666.424
sVchn
p249
Vaccumulated_volume
p250
sg28
V0-1000000
p251
sVun
p252
g31
p251
g29
sVdn
p253
p252
Vabbflow
p254
p253
sVda
p255
g31
p254
g29
sVlrt
p256
F1495636904.8846778
sg36
p255
F1502726134.0120882
sg34
V4009
p257
sg38
p256
sg36
V10
p258
p257
sVmisc_u
p259
p258
VMCF
p260
sg42
g43
p259
sg40
g41
sVmrt
p261
p260
V60
p262
sg46
p261
sg44
Vnone
p263
p262
sVm1ch
p264
p263
g235
sVmv
p264
g48
sg49
VOn
p265
sVmv
sg51
V0-1000000
p266
g52
sg53
Vfloat
p267
@@ -627,7 +627,7 @@ sVbytary
p272
NsVal
p273
g52
g48
sVvn
p274
VStatic Pressure
@@ -646,54 +646,54 @@ V3600
p281
sVla
p282
F35.65
F27.048
sVchn
p283
Vstatic_pressure
p284
sg28
sg51
V0-250
p285
sVdn
sVun
p286
Vabbflow
g29
sVdn
p287
sVda
Vabbflow
p288
g31
sVlrt
sVda
p289
F1495637183.4340781
sg36
V4015
g29
sVlrt
p290
sg38
g113
sVmisc_u
F1502725884.2453662
sg34
V4015
p291
VPSIA
sg36
g112
sVmisc_u
p292
sg42
g43
sVmrt
VPSIA
p293
V60
sg40
g41
sVmrt
p294
sg46
Vnone
V60
p295
sVm1ch
sg44
Vnone
p296
g269
sVmv
sVm1ch
p297
g52
g269
sg49
VOn
p298
sVun
sVmv
p299
g31
g48
sg53
Vfloat
p300
@@ -709,7 +709,7 @@ sVbytary
p305
NsVal
p306
g52
g48
sVvn
p307
VTemperature
@@ -728,54 +728,54 @@ V3600
p314
sVla
p315
F81.696
F85.208
sVchn
p316
Vtemperature
p317
sg28
sg51
V0-300
p318
sVdn
sVun
p319
Vabbflow
g29
sVdn
p320
sVda
Vabbflow
p321
g31
sVlrt
sVda
p322
F1495636998.6918399
sg36
V4017
g29
sVlrt
p323
sg38
g113
sVmisc_u
F1502724763.458232
sg34
V4017
p324
Vdeg F
sg36
g112
sVmisc_u
p325
sg42
g43
sVmrt
Vdeg F
p326
V60
sg40
g41
sVmrt
p327
sg46
Vnone
V60
p328
sVm1ch
sg44
Vnone
p329
g302
sVmv
sVm1ch
p330
g52
g302
sg49
VOn
p331
sVun
sVmv
p332
g31
g48
sg53
Vfloat
p333
@@ -810,53 +810,53 @@ V3600
p347
sVla
p348
F13.67
F13.356
sVchn
p349
Vcharger_voltage
p350
sVun
sg51
V0-50
p351
g31
sVdn
p352
Vabbflow
p353
sVda
p354
g31
g29
sVlrt
p355
F1495637353.177689
sg28
V0-50
F1502725893.760519
sg34
V4019
p356
sg36
V4019
p357
sg38
g113
g112
sVmisc_u
p358
g115
sg42
g43
p357
g114
sg40
g41
sVmrt
p359
p358
V60
p360
sg46
p359
sg44
Vnone
p361
p360
sVm1ch
p362
p361
g335
sVmv
p362
g48
sg49
VOn
p363
sVmv
sVun
p364
g52
g29
sg53
Vfloat
p365
@@ -871,7 +871,7 @@ p369
g14
sS's'
p370
g213
g209
ssS'2'
p371
(dp372
@@ -889,5 +889,5 @@ p376
sg369
g14
sg370
g213
g209
ss.

View File

@@ -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