Adds watchdog and pocloud files
This commit is contained in:
14056
RigPump.ACD
14056
RigPump.ACD
File diff suppressed because one or more lines are too long
1
rigpump/html-templates/Alerts.html
Normal file
1
rigpump/html-templates/Alerts.html
Normal file
@@ -0,0 +1 @@
|
||||
<module>Alerts</module>
|
||||
6
rigpump/html-templates/NodeDetailHeader.html
Normal file
6
rigpump/html-templates/NodeDetailHeader.html
Normal file
@@ -0,0 +1,6 @@
|
||||
<div class='col-xs-1'>
|
||||
<div class="<%= nodecolors.statuscolor %> nodecolor"></div>
|
||||
</div>
|
||||
<div class='col-xs-6'>
|
||||
<h3><%= node.vanityname %></h3>
|
||||
</div>
|
||||
31
rigpump/html-templates/Nodelist.html
Normal file
31
rigpump/html-templates/Nodelist.html
Normal file
@@ -0,0 +1,31 @@
|
||||
<style>
|
||||
.header h4 {
|
||||
position: relative;
|
||||
top: 0.9em;
|
||||
}
|
||||
.header h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #aaa;
|
||||
margin: 0.75em 0;
|
||||
}
|
||||
.header p {
|
||||
font-size: 24px;
|
||||
color: black;
|
||||
font-weight: 600;
|
||||
}
|
||||
</style>
|
||||
|
||||
<div class="row header">
|
||||
<div class="col-xs-1">
|
||||
<div class="<%= nodecolors.statuscolor %> nodecolor"></div>
|
||||
</div>
|
||||
|
||||
<div class="col-xs-2">
|
||||
<img src="<%= nodeimgurl %>" />
|
||||
</div>
|
||||
|
||||
<div class="col-xs-4">
|
||||
<h4><%= node.vanityname %></h4>
|
||||
</div>
|
||||
</div>
|
||||
121
rigpump/html-templates/Overview.html
Normal file
121
rigpump/html-templates/Overview.html
Normal file
@@ -0,0 +1,121 @@
|
||||
|
||||
<div class="row row-flex box-me">
|
||||
<div class="col-xs-12 text-center">
|
||||
<h1>HEADER 1</h1>
|
||||
</div>
|
||||
<div class="col-xs-4 text-center">
|
||||
<h2>CHANNEL 1</h2>
|
||||
<div class="gauge-box">
|
||||
<div data-labelheight="10"
|
||||
style="height: 170px; background: transparent; margin: 0 auto;"
|
||||
id="gauge-channel_1"
|
||||
data-chart="solidgauge"
|
||||
data-nodename="rigpump.channel_1"
|
||||
data-units="UNITS"
|
||||
data-min="0"
|
||||
data-max="100"
|
||||
data-decimalplaces="2"
|
||||
data-colors="0.1:#DF5353,0.5:#DDDF0D,0.9:#55BF3B"
|
||||
data-valuefontsize="18px">
|
||||
</div>
|
||||
<div class- "timestamp-box">
|
||||
<a href="#" data-channelId="<%= channels['rigpump.channel_1'].channelId %>" class="data-table" title="Download Channel History">
|
||||
<i class="fa fa-download"></i>
|
||||
</a>
|
||||
</div>
|
||||
<span data-timeupdate="lt11_level">
|
||||
<%= channels["rigpump.channel_1"].timestamp %>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
|
||||
|
||||
|
||||
|
||||
<style>
|
||||
|
||||
.box-me {
|
||||
position: relative;
|
||||
padding: 0.5em;
|
||||
padding-bottom: 1.5em;
|
||||
border: 1px solid #eee;
|
||||
/*margin: 1em 0;*/
|
||||
}
|
||||
|
||||
.box-me .gauge-box {
|
||||
margin-top: -0.25em;
|
||||
}
|
||||
|
||||
.pad15 {
|
||||
margin: 15px 15px;
|
||||
}
|
||||
|
||||
.box-me h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.dynamic-chart-form {
|
||||
background-color: whiteSmoke;
|
||||
padding: 1em 0.5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
|
||||
.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;
|
||||
}
|
||||
|
||||
#systemStatusTimelineContainer h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
|
||||
.slice.node-detail hr {
|
||||
border-color: #ccc;
|
||||
}
|
||||
.slice.node-detail #alarms li {
|
||||
margin-bottom: 1em;
|
||||
padding: 0.5em;
|
||||
}
|
||||
.slice.node-detail #alarms li:nth-child(even){
|
||||
background-color: whiteSmoke;
|
||||
}
|
||||
.slice.node-detail #alarms li span {
|
||||
margin-left: 1em;
|
||||
color: #aaa;
|
||||
}
|
||||
</style>
|
||||
|
||||
<script>
|
||||
|
||||
$('.val_box').each(function(topLevel){
|
||||
$(this).change(function(){
|
||||
var id = "#" + $(this).closest(".entry-top-level").attr('id');
|
||||
if (id !== "#undefined"){
|
||||
var val = $(id).find('.val_box').val();
|
||||
var tag = $(id).find('.setstatic').attr('data-staticsend', val);
|
||||
console.log($(id).find('.setstatic').attr('data-staticsend'));
|
||||
}
|
||||
});
|
||||
});
|
||||
|
||||
</script>
|
||||
15
rigpump/html-templates/Sidebar.html
Normal file
15
rigpump/html-templates/Sidebar.html
Normal file
@@ -0,0 +1,15 @@
|
||||
<a href="#"
|
||||
data-channelId="<%= channels["rigpump.log"].channelId %>"
|
||||
class="data-table btn-block btn btn-theme animated"
|
||||
title="Device Log"><i style='margin-left: 0.5em; cursor: pointer' class="fa fa-th-list icon-theme"></i> Device Log</a>
|
||||
|
||||
<a href="#"
|
||||
data-refreshpause="1"
|
||||
data-staticsend="1"
|
||||
data-channelId="<%= channels["rigpump.sync"].channelId %>"
|
||||
data-techname="<%=channels["rigpump.sync"].techName %>"
|
||||
data-name="<%= channels["rigpump.sync"].name%>"
|
||||
data-nodechannelcurrentId="<%= channels["rigpump.sync"].nodechannelcurrentId %>"
|
||||
id="<%= channels["rigpump.sync"].channelId %>"
|
||||
class="btn btn-large btn-block btn-theme animated setstatic mqtt">
|
||||
<i class="icon-repeat icon-white mqtt" ></i>Sync All Data</a>
|
||||
37
rigpump/html-templates/Trends.html
Normal file
37
rigpump/html-templates/Trends.html
Normal file
@@ -0,0 +1,37 @@
|
||||
<div class='col-xs-12' style="padding-top: 1em; margin-bottom: 1em;">
|
||||
<div class="input-daterange input-group" id="datepicker">
|
||||
<input data-chartid="dynamicChart" id="fromDate" data-daysofhistory="7" type="text" class="form-control" name="start">
|
||||
<span class="input-group-addon">to</span>
|
||||
<input class="form-control" data-chartid="dynamicChart" id="toDate" type="text" name="end">
|
||||
<span class='input-group-btn'>
|
||||
<a href="#!" data-chartid="dynamicChart" data-otherchartids="statusTimeline" class="btn chart-update btn-theme">Run</a>
|
||||
</span>
|
||||
</div>
|
||||
</div>
|
||||
<hr>
|
||||
<div class='clearfix col-xs-12'
|
||||
style='height: 450px'
|
||||
id="dynamicChart"
|
||||
data-chart="dynamicchart"
|
||||
data-daysofhistory="7"
|
||||
data-chartlabel="Data"
|
||||
data-ylabel=""
|
||||
data-xlabel="Date"
|
||||
data-units=""
|
||||
data-channelnames="rigpump.channel_1,">
|
||||
</div>
|
||||
<style>
|
||||
.dynamic-chart-form {
|
||||
background-color: whiteSmoke;
|
||||
padding: 1em 0.5em;
|
||||
margin-top: 1em;
|
||||
}
|
||||
#systemStatusTimelineContainer h2 {
|
||||
text-transform: uppercase;
|
||||
font-size: 14px;
|
||||
color: #666;
|
||||
font-weight: 400;
|
||||
letter-spacing: 1px;
|
||||
z-index: 100;
|
||||
}
|
||||
</style>
|
||||
211
rigpump/python-driver/Channel.py
Normal file
211
rigpump/python-driver/Channel.py
Normal file
@@ -0,0 +1,211 @@
|
||||
"""Define Meshify channel class."""
|
||||
from pycomm.ab_comm.clx import Driver as ClxDriver
|
||||
from pycomm.cip.cip_base import CommError, DataError
|
||||
import time
|
||||
|
||||
|
||||
def binarray(intval):
|
||||
"""Split an integer into its bits."""
|
||||
bin_string = '{0:08b}'.format(intval)
|
||||
bin_arr = [i for i in bin_string]
|
||||
bin_arr.reverse()
|
||||
return bin_arr
|
||||
|
||||
|
||||
def read_tag(addr, tag):
|
||||
"""Read a tag from the PLC."""
|
||||
c = ClxDriver()
|
||||
try:
|
||||
if c.open(addr):
|
||||
try:
|
||||
v = c.read_tag(tag)
|
||||
return v
|
||||
except DataError:
|
||||
c.close()
|
||||
print("Data Error during readTag({}, {})".format(addr, tag))
|
||||
except CommError:
|
||||
# err = c.get_status()
|
||||
c.close()
|
||||
print("Could not connect during readTag({}, {})".format(addr, tag))
|
||||
# print err
|
||||
except AttributeError as e:
|
||||
c.close()
|
||||
print("AttributeError during readTag({}, {}): \n{}".format(addr, tag, e))
|
||||
c.close()
|
||||
return False
|
||||
|
||||
|
||||
def read_array(addr, tag, start, end):
|
||||
"""Read an array from the PLC."""
|
||||
c = ClxDriver()
|
||||
if c.open(addr):
|
||||
arr_vals = []
|
||||
try:
|
||||
for i in range(start, end):
|
||||
tag_w_index = tag + "[{}]".format(i)
|
||||
v = c.read_tag(tag_w_index)
|
||||
# print('{} - {}'.format(tag_w_index, v))
|
||||
arr_vals.append(round(v[0], 4))
|
||||
# print(v)
|
||||
if len(arr_vals) > 0:
|
||||
return arr_vals
|
||||
else:
|
||||
print("No length for {}".format(addr))
|
||||
return False
|
||||
except Exception:
|
||||
print("Error during readArray({}, {}, {}, {})".format(addr, tag, start, end))
|
||||
err = c.get_status()
|
||||
c.close()
|
||||
print err
|
||||
pass
|
||||
c.close()
|
||||
|
||||
|
||||
def write_tag(addr, tag, val):
|
||||
"""Write a tag value to the PLC."""
|
||||
c = ClxDriver()
|
||||
if c.open(addr):
|
||||
try:
|
||||
cv = c.read_tag(tag)
|
||||
wt = c.write_tag(tag, val, cv[1])
|
||||
return wt
|
||||
except Exception:
|
||||
print("Error during writeTag({}, {}, {})".format(addr, tag, val))
|
||||
err = c.get_status()
|
||||
c.close()
|
||||
print err
|
||||
c.close()
|
||||
|
||||
|
||||
class Channel:
|
||||
"""Holds the configuration for a Meshify channel."""
|
||||
|
||||
def __init__(self, ip, mesh_name, plc_tag, data_type, chg_threshold, guarantee_sec, map_=False, write_enabled=False):
|
||||
"""Initialize the channel."""
|
||||
self.plc_ip = ip
|
||||
self.mesh_name = mesh_name
|
||||
self.plc_tag = plc_tag
|
||||
self.data_type = data_type
|
||||
self.last_value = None
|
||||
self.value = None
|
||||
self.last_send_time = 0
|
||||
self.chg_threshold = chg_threshold
|
||||
self.guarantee_sec = guarantee_sec
|
||||
self.map_ = map_
|
||||
self.write_enabled = write_enabled
|
||||
|
||||
def __str__(self):
|
||||
"""Create a string for the channel."""
|
||||
return "{}: {}\nvalue: {}, last_send_time: {}".format(self.mesh_name, self.plc_tag, self.value, self.last_send_time)
|
||||
|
||||
def read(self, force_send=False):
|
||||
"""Read the value and check to see if needs to be stored."""
|
||||
send_needed = False
|
||||
send_reason = ""
|
||||
if self.plc_tag:
|
||||
v = read_tag(self.plc_ip, self.plc_tag)
|
||||
if v:
|
||||
if self.data_type == 'BOOL' or self.data_type == 'STRING':
|
||||
if self.last_send_time == 0:
|
||||
send_needed = True
|
||||
send_reason = "no send time"
|
||||
elif self.value is None:
|
||||
send_needed = True
|
||||
send_reason = "no value"
|
||||
elif not (self.value == v[0]):
|
||||
if self.map_:
|
||||
if not self.value == self.map_[v[0]]:
|
||||
send_needed = True
|
||||
send_reason = "value change"
|
||||
else:
|
||||
send_needed = True
|
||||
send_reason = "value change"
|
||||
elif (time.time() - self.last_send_time) > self.guarantee_sec:
|
||||
send_needed = True
|
||||
send_reason = "guarantee sec"
|
||||
elif force_send:
|
||||
send_needed = True
|
||||
send_reason = "forced"
|
||||
else:
|
||||
if self.last_send_time == 0:
|
||||
send_needed = True
|
||||
send_reason = "no send time"
|
||||
elif self.value is None:
|
||||
send_needed = True
|
||||
send_reason = "no value"
|
||||
elif abs(self.value - v[0]) > self.chg_threshold:
|
||||
send_needed = True
|
||||
send_reason = "change threshold"
|
||||
elif (time.time() - self.last_send_time) > self.guarantee_sec:
|
||||
send_needed = True
|
||||
send_reason = "guarantee sec"
|
||||
elif force_send:
|
||||
send_needed = True
|
||||
send_reason = "forced"
|
||||
if send_needed:
|
||||
self.last_value = self.value
|
||||
if self.map_:
|
||||
try:
|
||||
self.value = self.map_[v[0]]
|
||||
except KeyError:
|
||||
print("Cannot find a map value for {} in {} for {}".format(v[0], self.map_, self.mesh_name))
|
||||
self.value = v[0]
|
||||
else:
|
||||
self.value = v[0]
|
||||
self.last_send_time = time.time()
|
||||
print("Sending {} for {} - {}".format(self.value, self.mesh_name, send_reason))
|
||||
return send_needed
|
||||
|
||||
|
||||
class BoolArrayChannels(Channel):
|
||||
"""Hold the configuration for a set of boolean array channels."""
|
||||
|
||||
def compare_values(self, new_val_dict):
|
||||
"""Compare new values to old values to see if the values need storing."""
|
||||
send = False
|
||||
for idx in new_val_dict:
|
||||
try:
|
||||
if new_val_dict[idx] != self.last_value[idx]:
|
||||
send = True
|
||||
except KeyError:
|
||||
print("Key Error in self.compare_values for index {}".format(idx))
|
||||
send = True
|
||||
return send
|
||||
|
||||
def read(self, force_send=False):
|
||||
"""Read the value and check to see if needs to be stored."""
|
||||
send_needed = False
|
||||
send_reason = ""
|
||||
if self.plc_tag:
|
||||
v = read_tag(self.plc_ip, self.plc_tag)
|
||||
if v:
|
||||
bool_arr = binarray(v[0])
|
||||
new_val = {}
|
||||
for idx in self.map_:
|
||||
try:
|
||||
new_val[self.map_[idx]] = bool_arr[idx]
|
||||
except KeyError:
|
||||
print("Not able to get value for index {}".format(idx))
|
||||
|
||||
if self.last_send_time == 0:
|
||||
send_needed = True
|
||||
send_reason = "no send time"
|
||||
elif self.value is None:
|
||||
send_needed = True
|
||||
send_reason = "no value"
|
||||
elif self.compare_values(new_val):
|
||||
send_needed = True
|
||||
send_reason = "value change"
|
||||
elif (time.time() - self.last_send_time) > self.guarantee_sec:
|
||||
send_needed = True
|
||||
send_reason = "guarantee sec"
|
||||
elif force_send:
|
||||
send_needed = True
|
||||
send_reason = "forced"
|
||||
|
||||
if send_needed:
|
||||
self.value = new_val
|
||||
self.last_value = self.value
|
||||
self.last_send_time = time.time()
|
||||
print("Sending {} for {} - {}".format(self.value, self.mesh_name, send_reason))
|
||||
return send_needed
|
||||
3
rigpump/python-driver/Maps.py
Normal file
3
rigpump/python-driver/Maps.py
Normal file
@@ -0,0 +1,3 @@
|
||||
"""Holds map values for rigpump."""
|
||||
|
||||
rigpump_map = {}
|
||||
15
rigpump/python-driver/config.txt
Normal file
15
rigpump/python-driver/config.txt
Normal file
@@ -0,0 +1,15 @@
|
||||
{
|
||||
|
||||
"driverFileName":"rigpump.py",
|
||||
"deviceName":"rigpump",
|
||||
"driverId":"0150",
|
||||
"releaseVersion":"1",
|
||||
"files": {
|
||||
"file1":"rigpump.py",
|
||||
"file2":"Channel.py",
|
||||
"file3":"Maps.py",
|
||||
"file4":"Scheduler.py",
|
||||
"file5":"modbusMap.p"
|
||||
}
|
||||
|
||||
}
|
||||
912
rigpump/python-driver/modbusMap.p
Normal file
912
rigpump/python-driver/modbusMap.p
Normal file
@@ -0,0 +1,912 @@
|
||||
(dp0
|
||||
S'1'
|
||||
p1
|
||||
(dp2
|
||||
S'c'
|
||||
p3
|
||||
VETHERNET/IP
|
||||
p4
|
||||
sS'b'
|
||||
p5
|
||||
V192.168.1.10
|
||||
p6
|
||||
sS'addresses'
|
||||
p7
|
||||
(dp8
|
||||
V300
|
||||
p9
|
||||
(dp10
|
||||
V2-2
|
||||
p11
|
||||
(dp12
|
||||
Val
|
||||
p13
|
||||
V
|
||||
p14
|
||||
sVah
|
||||
p15
|
||||
g14
|
||||
sVbytary
|
||||
p16
|
||||
NsVvm
|
||||
p17
|
||||
NsVvn
|
||||
p18
|
||||
VVFD Current
|
||||
p19
|
||||
sVct
|
||||
p20
|
||||
Vnumber
|
||||
p21
|
||||
sVle
|
||||
p22
|
||||
V16
|
||||
p23
|
||||
sVgrp
|
||||
p24
|
||||
V3600
|
||||
p25
|
||||
sVla
|
||||
p26
|
||||
F0.0
|
||||
sVchn
|
||||
p27
|
||||
Vvfd_current
|
||||
p28
|
||||
sVun
|
||||
p29
|
||||
V1
|
||||
p30
|
||||
sVdn
|
||||
p31
|
||||
Vrigpump
|
||||
p32
|
||||
sVda
|
||||
p33
|
||||
V300
|
||||
p34
|
||||
sVlrt
|
||||
p35
|
||||
F1504128305.682013
|
||||
sVr
|
||||
p36
|
||||
V0-250
|
||||
p37
|
||||
sVa
|
||||
p38
|
||||
VVFD_OutCurrent
|
||||
p39
|
||||
sVc
|
||||
p40
|
||||
V1.0
|
||||
p41
|
||||
sVmisc_u
|
||||
p42
|
||||
VAmps
|
||||
p43
|
||||
sVf
|
||||
p44
|
||||
g30
|
||||
sVmrt
|
||||
p45
|
||||
V60
|
||||
p46
|
||||
sVm
|
||||
p47
|
||||
Vnone
|
||||
p48
|
||||
sS'm1ch'
|
||||
p49
|
||||
g11
|
||||
sVs
|
||||
p50
|
||||
VOn
|
||||
p51
|
||||
sVmv
|
||||
p52
|
||||
V0
|
||||
p53
|
||||
sVt
|
||||
p54
|
||||
Vint
|
||||
p55
|
||||
ssV2-3
|
||||
p56
|
||||
(dp57
|
||||
Vah
|
||||
p58
|
||||
g14
|
||||
sVbytary
|
||||
p59
|
||||
NsVal
|
||||
p60
|
||||
g14
|
||||
sVvn
|
||||
p61
|
||||
VVFD Frequency
|
||||
p62
|
||||
sVct
|
||||
p63
|
||||
Vnumber
|
||||
p64
|
||||
sVle
|
||||
p65
|
||||
V16
|
||||
p66
|
||||
sVgrp
|
||||
p67
|
||||
V3600
|
||||
p68
|
||||
sVla
|
||||
p69
|
||||
F0.0
|
||||
sVchn
|
||||
p70
|
||||
Vvfd_frequency
|
||||
p71
|
||||
sVun
|
||||
p72
|
||||
g30
|
||||
sVdn
|
||||
p73
|
||||
Vrigpump
|
||||
p74
|
||||
sVvm
|
||||
p75
|
||||
NsVlrt
|
||||
p76
|
||||
F1504129549.8809668
|
||||
sVda
|
||||
p77
|
||||
V300
|
||||
p78
|
||||
sg38
|
||||
VVFD_SpeedFdbk
|
||||
p79
|
||||
sg40
|
||||
V0.5
|
||||
p80
|
||||
sVmisc_u
|
||||
p81
|
||||
VHz
|
||||
p82
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p83
|
||||
V60
|
||||
p84
|
||||
sg47
|
||||
Vnone
|
||||
p85
|
||||
sVm1ch
|
||||
p86
|
||||
g56
|
||||
sVmv
|
||||
p87
|
||||
g53
|
||||
sg50
|
||||
VOn
|
||||
p88
|
||||
sg36
|
||||
V0-75
|
||||
p89
|
||||
sg54
|
||||
Vint
|
||||
p90
|
||||
ssV2-1
|
||||
p91
|
||||
(dp92
|
||||
Val
|
||||
p93
|
||||
g14
|
||||
sVah
|
||||
p94
|
||||
g14
|
||||
sVbytary
|
||||
p95
|
||||
NsVvm
|
||||
p96
|
||||
NsVvn
|
||||
p97
|
||||
VDischarge Pressure
|
||||
p98
|
||||
sVct
|
||||
p99
|
||||
Vnumber
|
||||
p100
|
||||
sVle
|
||||
p101
|
||||
V16
|
||||
p102
|
||||
sVgrp
|
||||
p103
|
||||
V3600
|
||||
p104
|
||||
sVla
|
||||
p105
|
||||
F0.0
|
||||
sVchn
|
||||
p106
|
||||
Vdischarge_pressure
|
||||
p107
|
||||
sVun
|
||||
p108
|
||||
g30
|
||||
sVdn
|
||||
p109
|
||||
Vrigpump
|
||||
p110
|
||||
sVda
|
||||
p111
|
||||
V300
|
||||
p112
|
||||
sVlrt
|
||||
p113
|
||||
F1504129459.392449
|
||||
sg36
|
||||
V0-500
|
||||
p114
|
||||
sg38
|
||||
Vval_DischargePressure
|
||||
p115
|
||||
sg40
|
||||
V5.0
|
||||
p116
|
||||
sVmisc_u
|
||||
p117
|
||||
VPSI
|
||||
p118
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p119
|
||||
V60
|
||||
p120
|
||||
sg47
|
||||
Vnone
|
||||
p121
|
||||
sg49
|
||||
g91
|
||||
sg50
|
||||
VOn
|
||||
p122
|
||||
sVmv
|
||||
p123
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p124
|
||||
ssV2-6
|
||||
p125
|
||||
(dp126
|
||||
Val
|
||||
p127
|
||||
g14
|
||||
sVah
|
||||
p128
|
||||
g14
|
||||
sVbytary
|
||||
p129
|
||||
NsVvm
|
||||
p130
|
||||
NsVvn
|
||||
p131
|
||||
VDischarge Pressure Setpoint
|
||||
p132
|
||||
sVct
|
||||
p133
|
||||
Vnumber
|
||||
p134
|
||||
sVle
|
||||
p135
|
||||
V16
|
||||
p136
|
||||
sVgrp
|
||||
p137
|
||||
V3600
|
||||
p138
|
||||
sVla
|
||||
p139
|
||||
F30.0
|
||||
sVchn
|
||||
p140
|
||||
Vdischarge_pressure_setpoint
|
||||
p141
|
||||
sVun
|
||||
p142
|
||||
g30
|
||||
sVdn
|
||||
p143
|
||||
Vrigpump
|
||||
p144
|
||||
sVda
|
||||
p145
|
||||
V300
|
||||
p146
|
||||
sVlrt
|
||||
p147
|
||||
F1504128306.392521
|
||||
sg36
|
||||
V0-500
|
||||
p148
|
||||
sg38
|
||||
Vcfg_PID_DischargePressureSP
|
||||
p149
|
||||
sg40
|
||||
V0.5
|
||||
p150
|
||||
sVmisc_u
|
||||
p151
|
||||
VPSI
|
||||
p152
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p153
|
||||
V60
|
||||
p154
|
||||
sg47
|
||||
Vnone
|
||||
p155
|
||||
sg49
|
||||
g125
|
||||
sg50
|
||||
VOn
|
||||
p156
|
||||
sVmv
|
||||
p157
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p158
|
||||
ssV2-7
|
||||
p159
|
||||
(dp160
|
||||
Val
|
||||
p161
|
||||
g14
|
||||
sVah
|
||||
p162
|
||||
g14
|
||||
sVbytary
|
||||
p163
|
||||
NsVvm
|
||||
p164
|
||||
NsVvn
|
||||
p165
|
||||
VVFD Frequency Setpoint
|
||||
p166
|
||||
sVct
|
||||
p167
|
||||
Vnumber
|
||||
p168
|
||||
sVle
|
||||
p169
|
||||
V16
|
||||
p170
|
||||
sVgrp
|
||||
p171
|
||||
V3600
|
||||
p172
|
||||
sVla
|
||||
p173
|
||||
F55.0
|
||||
sVchn
|
||||
p174
|
||||
Vvfd_frequency_setpoint
|
||||
p175
|
||||
sVun
|
||||
p176
|
||||
g30
|
||||
sVdn
|
||||
p177
|
||||
Vrigpump
|
||||
p178
|
||||
sVda
|
||||
p179
|
||||
V300
|
||||
p180
|
||||
sVlrt
|
||||
p181
|
||||
F1504128306.597828
|
||||
sg36
|
||||
V0-75
|
||||
p182
|
||||
sg38
|
||||
Vcfg_PID_ManualSP
|
||||
p183
|
||||
sg40
|
||||
V0.5
|
||||
p184
|
||||
sVmisc_u
|
||||
p185
|
||||
VHz
|
||||
p186
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p187
|
||||
V60
|
||||
p188
|
||||
sg47
|
||||
Vnone
|
||||
p189
|
||||
sg49
|
||||
g159
|
||||
sg50
|
||||
VOn
|
||||
p190
|
||||
sVmv
|
||||
p191
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p192
|
||||
ssV2-4
|
||||
p193
|
||||
(dp194
|
||||
Val
|
||||
p195
|
||||
g14
|
||||
sVah
|
||||
p196
|
||||
g14
|
||||
sVbytary
|
||||
p197
|
||||
NsVvm
|
||||
p198
|
||||
(dp199
|
||||
g30
|
||||
VRunning
|
||||
p200
|
||||
sV128
|
||||
p201
|
||||
VOverpressure
|
||||
p202
|
||||
sV64
|
||||
p203
|
||||
VIdle
|
||||
p204
|
||||
sV1024
|
||||
p205
|
||||
VFaulted
|
||||
p206
|
||||
ssVvn
|
||||
p207
|
||||
VDevice Status
|
||||
p208
|
||||
sVct
|
||||
p209
|
||||
Vnumber
|
||||
p210
|
||||
sVle
|
||||
p211
|
||||
V16
|
||||
p212
|
||||
sVgrp
|
||||
p213
|
||||
V3600
|
||||
p214
|
||||
sVla
|
||||
p215
|
||||
I64
|
||||
sVchn
|
||||
p216
|
||||
Vdevice_status
|
||||
p217
|
||||
sVun
|
||||
p218
|
||||
g30
|
||||
sVdn
|
||||
p219
|
||||
Vrigpump
|
||||
p220
|
||||
sVda
|
||||
p221
|
||||
V300
|
||||
p222
|
||||
sVlrt
|
||||
p223
|
||||
F1504128306.7821309
|
||||
sg36
|
||||
V0-32768
|
||||
p224
|
||||
sg38
|
||||
VRigPump.State
|
||||
p225
|
||||
sg40
|
||||
g30
|
||||
sVmisc_u
|
||||
p226
|
||||
g14
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p227
|
||||
V60
|
||||
p228
|
||||
sg47
|
||||
Vnone
|
||||
p229
|
||||
sg49
|
||||
g193
|
||||
sg50
|
||||
VOn
|
||||
p230
|
||||
sVmv
|
||||
p231
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p232
|
||||
ssV2-5
|
||||
p233
|
||||
(dp234
|
||||
Val
|
||||
p235
|
||||
g14
|
||||
sVah
|
||||
p236
|
||||
g14
|
||||
sVbytary
|
||||
p237
|
||||
NsVvm
|
||||
p238
|
||||
NsVvn
|
||||
p239
|
||||
VFlow Rate Setpoint
|
||||
p240
|
||||
sVct
|
||||
p241
|
||||
Vnumber
|
||||
p242
|
||||
sVle
|
||||
p243
|
||||
V16
|
||||
p244
|
||||
sVgrp
|
||||
p245
|
||||
V3600
|
||||
p246
|
||||
sVla
|
||||
p247
|
||||
F50.0
|
||||
sVchn
|
||||
p248
|
||||
Vflow_rate_setpoint
|
||||
p249
|
||||
sVun
|
||||
p250
|
||||
g30
|
||||
sVdn
|
||||
p251
|
||||
Vrigpump
|
||||
p252
|
||||
sVda
|
||||
p253
|
||||
V300
|
||||
p254
|
||||
sVlrt
|
||||
p255
|
||||
F1504128306.9468218
|
||||
sg36
|
||||
V0-5000
|
||||
p256
|
||||
sg38
|
||||
Vcfg_PID_FlowSP
|
||||
p257
|
||||
sg40
|
||||
V0.1
|
||||
p258
|
||||
sVmisc_u
|
||||
p259
|
||||
VBPM
|
||||
p260
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p261
|
||||
V60
|
||||
p262
|
||||
sg47
|
||||
Vnone
|
||||
p263
|
||||
sg49
|
||||
g233
|
||||
sg50
|
||||
VOn
|
||||
p264
|
||||
sVmv
|
||||
p265
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p266
|
||||
ssV2-8
|
||||
p267
|
||||
(dp268
|
||||
Val
|
||||
p269
|
||||
g14
|
||||
sVah
|
||||
p270
|
||||
g14
|
||||
sVbytary
|
||||
p271
|
||||
NsVvm
|
||||
p272
|
||||
(dp273
|
||||
g30
|
||||
VAuto
|
||||
p274
|
||||
sg53
|
||||
VManual
|
||||
p275
|
||||
ssVvn
|
||||
p276
|
||||
VAuto/Manual Mode
|
||||
p277
|
||||
sVct
|
||||
p278
|
||||
Vnumber
|
||||
p279
|
||||
sVle
|
||||
p280
|
||||
V16
|
||||
p281
|
||||
sVgrp
|
||||
p282
|
||||
V3600
|
||||
p283
|
||||
sVla
|
||||
p284
|
||||
I0
|
||||
sVchn
|
||||
p285
|
||||
Vauto_manual
|
||||
p286
|
||||
sVun
|
||||
p287
|
||||
g30
|
||||
sVdn
|
||||
p288
|
||||
Vrigpump
|
||||
p289
|
||||
sVda
|
||||
p290
|
||||
V300
|
||||
p291
|
||||
sVlrt
|
||||
p292
|
||||
F1504128307.132611
|
||||
sg36
|
||||
V0-1
|
||||
p293
|
||||
sg38
|
||||
Vmode_Auto
|
||||
p294
|
||||
sg40
|
||||
g53
|
||||
sVmisc_u
|
||||
p295
|
||||
g14
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p296
|
||||
V60
|
||||
p297
|
||||
sg47
|
||||
Vnone
|
||||
p298
|
||||
sg49
|
||||
g267
|
||||
sg50
|
||||
VOn
|
||||
p299
|
||||
sVmv
|
||||
p300
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p301
|
||||
ssV2-9
|
||||
p302
|
||||
(dp303
|
||||
Vah
|
||||
p304
|
||||
g14
|
||||
sVbytary
|
||||
p305
|
||||
NsVal
|
||||
p306
|
||||
g14
|
||||
sVvn
|
||||
p307
|
||||
VControl Mode
|
||||
p308
|
||||
sVct
|
||||
p309
|
||||
Vnumber
|
||||
p310
|
||||
sVle
|
||||
p311
|
||||
V16
|
||||
p312
|
||||
sVgrp
|
||||
p313
|
||||
V3600
|
||||
p314
|
||||
sVla
|
||||
p315
|
||||
NsVchn
|
||||
p316
|
||||
Vauto_control_mode
|
||||
p317
|
||||
sVun
|
||||
p318
|
||||
g30
|
||||
sVdn
|
||||
p319
|
||||
Vrigpump
|
||||
p320
|
||||
sVvm
|
||||
p321
|
||||
(dp322
|
||||
g30
|
||||
VFlow
|
||||
p323
|
||||
sg53
|
||||
VPressure
|
||||
p324
|
||||
ssVlrt
|
||||
p325
|
||||
g53
|
||||
sVda
|
||||
p326
|
||||
V300
|
||||
p327
|
||||
sg38
|
||||
Vauto_control_mode
|
||||
p328
|
||||
sg40
|
||||
g53
|
||||
sVmisc_u
|
||||
p329
|
||||
g14
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p330
|
||||
V60
|
||||
p331
|
||||
sg47
|
||||
Vnone
|
||||
p332
|
||||
sVm1ch
|
||||
p333
|
||||
g302
|
||||
sVmv
|
||||
p334
|
||||
g53
|
||||
sg50
|
||||
VOn
|
||||
p335
|
||||
sg36
|
||||
V0-1
|
||||
p336
|
||||
sg54
|
||||
Vint
|
||||
p337
|
||||
ssV2-11
|
||||
p338
|
||||
(dp339
|
||||
Val
|
||||
p340
|
||||
g14
|
||||
sVah
|
||||
p341
|
||||
g14
|
||||
sVbytary
|
||||
p342
|
||||
NsVvm
|
||||
p343
|
||||
NsVvn
|
||||
p344
|
||||
VFlow Rate
|
||||
p345
|
||||
sVct
|
||||
p346
|
||||
Vnumber
|
||||
p347
|
||||
sVle
|
||||
p348
|
||||
V16
|
||||
p349
|
||||
sVgrp
|
||||
p350
|
||||
V3600
|
||||
p351
|
||||
sVla
|
||||
p352
|
||||
F0.0
|
||||
sVchn
|
||||
p353
|
||||
Vflow_rate
|
||||
p354
|
||||
sVun
|
||||
p355
|
||||
g30
|
||||
sVdn
|
||||
p356
|
||||
Vrigpump
|
||||
p357
|
||||
sVda
|
||||
p358
|
||||
g9
|
||||
sVlrt
|
||||
p359
|
||||
F1504128307.4822289
|
||||
sg36
|
||||
V0-50000
|
||||
p360
|
||||
sg38
|
||||
Vval_Flowmeter
|
||||
p361
|
||||
sg40
|
||||
V5.0
|
||||
p362
|
||||
sVmisc_u
|
||||
p363
|
||||
VBPM
|
||||
p364
|
||||
sg44
|
||||
g30
|
||||
sVmrt
|
||||
p365
|
||||
V60
|
||||
p366
|
||||
sg47
|
||||
Vnone
|
||||
p367
|
||||
sg49
|
||||
g338
|
||||
sg50
|
||||
VOn
|
||||
p368
|
||||
sVmv
|
||||
p369
|
||||
g53
|
||||
sg54
|
||||
Vint
|
||||
p370
|
||||
ssssS'f'
|
||||
p371
|
||||
VOff
|
||||
p372
|
||||
sS'p'
|
||||
p373
|
||||
g14
|
||||
sS's'
|
||||
p374
|
||||
g30
|
||||
ssS'2'
|
||||
p375
|
||||
(dp376
|
||||
g3
|
||||
VM1-232
|
||||
p377
|
||||
sg5
|
||||
V9600
|
||||
p378
|
||||
sg7
|
||||
(dp379
|
||||
sg371
|
||||
VOff
|
||||
p380
|
||||
sg373
|
||||
g14
|
||||
sg374
|
||||
g30
|
||||
ss.
|
||||
118
rigpump/python-driver/rigpump.py
Normal file
118
rigpump/python-driver/rigpump.py
Normal file
@@ -0,0 +1,118 @@
|
||||
"""Driver for rigpump"""
|
||||
|
||||
import threading
|
||||
from device_base import deviceBase
|
||||
from Channel import Channel, write_tag, BoolArrayChannels, read_tag
|
||||
from Maps import rigpump_map as maps
|
||||
from random import randint
|
||||
import json
|
||||
import time
|
||||
|
||||
_ = None
|
||||
|
||||
try:
|
||||
with open("persist.json", 'r') as persist_file:
|
||||
persist = json.load(persist_file)
|
||||
except Exception:
|
||||
persist = {}
|
||||
|
||||
plc_ip_address = "192.168.1.10"
|
||||
|
||||
|
||||
def reverse_map(value, map_):
|
||||
"""Perform the opposite of mapping to an object."""
|
||||
for x in map_:
|
||||
if map_[x] == value:
|
||||
return x
|
||||
return None
|
||||
|
||||
|
||||
channels = []
|
||||
|
||||
|
||||
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 = "3"
|
||||
self.finished = threading.Event()
|
||||
self.forceSend = False
|
||||
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):
|
||||
"""Actually run the driver."""
|
||||
global persist
|
||||
watchdog = self.rigpump_watchdog()
|
||||
wait_sec = 60
|
||||
for i in range(0, wait_sec):
|
||||
print("rigpump driver will start in {} seconds".format(wait_sec - i))
|
||||
time.sleep(1)
|
||||
print("BOOM! Starting rigpump driver...")
|
||||
# after its booted up assuming that M1 is now reading modbus data
|
||||
# we can replace the reference made to this device name to the M1 driver with this
|
||||
# driver. The 01 in the 0199 below is the device number you referenced in the modbus wizard
|
||||
self.nodes["rigpump_0199"] = self
|
||||
send_loops = 0
|
||||
watchdog_loops = 0
|
||||
watchdog_check_after = 5000
|
||||
while True:
|
||||
if self.forceSend:
|
||||
print "FORCE SEND: TRUE"
|
||||
|
||||
# for c in channels:
|
||||
# if c.read(self.forceSend):
|
||||
# self.sendtodb(c.mesh_name, c.value, 0)
|
||||
|
||||
# print("rigpump driver still alive...")
|
||||
if self.forceSend:
|
||||
if send_loops > 2:
|
||||
print("Turning off forceSend")
|
||||
self.forceSend = False
|
||||
send_loops = 0
|
||||
else:
|
||||
send_loops += 1
|
||||
|
||||
watchdog_loops += 1
|
||||
if (watchdog_loops >= watchdog_check_after):
|
||||
test_watchdog = self.rigpump_watchdog()
|
||||
if not test_watchdog == watchdog:
|
||||
self.sendtodb('watchdog', test_watchdog, 0)
|
||||
watchdog = test_watchdog
|
||||
watchdog_loops = 0
|
||||
|
||||
def rigpump_watchdog(self):
|
||||
"""Write a random integer to the PLC and then 1 seconds later check that it has been decremented by 1."""
|
||||
randval = randint(0, 32767)
|
||||
write_tag(str(plc_ip_address), 'watchdog_INT', randval)
|
||||
time.sleep(1)
|
||||
watchdog_val = read_tag(str(plc_ip_address), 'watchdog_INT')
|
||||
return (randval - 1) == watchdog_val[0]
|
||||
|
||||
def rigpump_sync(self, name, value):
|
||||
"""Sync all data from the driver."""
|
||||
self.forceSend = True
|
||||
# self.sendtodb("log", "synced", 0)
|
||||
return True
|
||||
|
||||
def rigpump_writeplctag(self, name, value):
|
||||
"""Write a value to the PLC."""
|
||||
new_val = json.loads(str(value).replace("'", '"'))
|
||||
tag_n = str(new_val['tag']) # "cmd_Start"
|
||||
val_n = new_val['val']
|
||||
w = write_tag(str(plc_ip_address), tag_n, val_n)
|
||||
print("Result of rigpump_writeplctag(self, {}, {}) = {}".format(name, value, w))
|
||||
if w is None:
|
||||
w = "Error writing to PLC..."
|
||||
return w
|
||||
Reference in New Issue
Block a user