Added Folders
Add all the driver folders
This commit is contained in:
345
dh_monitor/dhMonitor.py
Normal file
345
dh_monitor/dhMonitor.py
Normal file
@@ -0,0 +1,345 @@
|
||||
#!/usr/bin/python
|
||||
|
||||
import types
|
||||
import traceback
|
||||
import binascii
|
||||
import threading
|
||||
import time
|
||||
import thread
|
||||
import os
|
||||
import struct
|
||||
import sys
|
||||
import serial
|
||||
import minimalmodbus
|
||||
import pickle
|
||||
from device_base import deviceBase
|
||||
from datetime import datetime
|
||||
|
||||
import requests
|
||||
try:
|
||||
import json
|
||||
except:
|
||||
import simplejson as json
|
||||
import calendar
|
||||
from math import ceil, floor
|
||||
|
||||
data_channels = {
|
||||
"IntakeTemperature":{"modbus_register":0, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180},
|
||||
"IntakePressure": {"modbus_register":1, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180},
|
||||
"WindingTemperature": {"modbus_register":2, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180},
|
||||
"DischargeTemperature": {"modbus_register":5, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180},
|
||||
"DischargePressure": {"modbus_register":6, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180},
|
||||
"VibrationX": {"modbus_register":3, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180},
|
||||
"VibrationY": {"modbus_register":4, "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180}
|
||||
}
|
||||
|
||||
status_channels = {
|
||||
"DownholeStatus": {"modbus_register":97, "map":"mainStatus" "value":"", "last_value":"", "last_send_time":0, "min_change_limit":0, "change_threshold":0, "min_upload_time":180}
|
||||
}
|
||||
|
||||
map = {
|
||||
"mainStatus": {
|
||||
0: "OK",
|
||||
1: "Connecting",
|
||||
2: "Open circuit",
|
||||
3: "Shorted",
|
||||
4: "Cannot decode"
|
||||
},
|
||||
}
|
||||
|
||||
class start(threading.Thread, deviceBase):
|
||||
|
||||
def __init__(self, name=None, number=None, mac=None, Q=None, mcu=None, companyId=None, offset=None, mqtt=None, Nodes=None):
|
||||
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.forceSend = True
|
||||
self.version = "2"
|
||||
self.cardLoopTimer = 600
|
||||
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):
|
||||
channels["status"]["last_value"] = ""
|
||||
|
||||
|
||||
def run(self):
|
||||
self.runLoopStatus = ""
|
||||
while True:
|
||||
try:
|
||||
runLoopStatus = "readStatusRegisters"
|
||||
self.readStatusRegisters()
|
||||
|
||||
runLoopStatus = "readDataRegisters"
|
||||
self.readDataRegisters()
|
||||
|
||||
runLoopStatus = "Complete"
|
||||
|
||||
time.sleep(3)
|
||||
|
||||
except Exception, e:
|
||||
sleep_timer = 20
|
||||
print "Error during {0} of run loop: {1}\nWill try again in {2} seconds...".format(runLoopStatus, e, sleep_timer)
|
||||
time.sleep(sleep_timer)
|
||||
|
||||
|
||||
def readStatusRegisters(self):
|
||||
for entry in day:
|
||||
if go_channels.has_key(entry):
|
||||
#"percent_run":{"meshifyName":"go_percent_run","last_value":"","last_send_time":0,"data_type":"float","change_amount":0},
|
||||
if go_channels[entry]["last_value"] != day[entry]:
|
||||
print entry, day[entry]
|
||||
print go_channels[entry]["meshifyName"], day[entry], timestamp
|
||||
self.sendtodb(go_channels[entry]["meshifyName"], day[entry], timestamp)
|
||||
go_channels[entry]["last_value"] = day[entry]
|
||||
|
||||
|
||||
def checkBackup(self):
|
||||
backupList = json.loads(requests.get(self.device_address + "/json/backups").text)
|
||||
file = backupList["backups"][0]
|
||||
data = json.loads(requests.get(self.device_address + "/json/backups/" + file).text)
|
||||
timestamp = time.time()
|
||||
if data != self.wellSetup or self.forceSend:
|
||||
self.sendtodbJSON("well_setup", json.dumps(data), timestamp)
|
||||
self.wellSetup = data;
|
||||
with open('wellSetup.p', 'wb') as handle:
|
||||
pickle.dump(self.wellSetup, handle)
|
||||
|
||||
def checkEvents(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/event_list").text)
|
||||
events = data["events"]
|
||||
for event in events:
|
||||
if int(event["id"]) not in self.eventIds:
|
||||
timestamp = calendar.timegm(time.strptime(event["datetime"], '%Y-%m-%dT%H:%M:%S.%fZ'))
|
||||
#we have a new event
|
||||
self.sendtodbJSON("events", json.dumps(event), timestamp)
|
||||
self.eventIds.append(int(event["id"]))
|
||||
if len(self.eventIds) > 50:
|
||||
del self.eventIds[0]
|
||||
with open('eventIds.p', 'wb') as handle:
|
||||
pickle.dump(self.eventIds, handle)
|
||||
|
||||
|
||||
|
||||
|
||||
def checkStatus(self):
|
||||
statusMap = {
|
||||
0:'Stopped',
|
||||
1:'Running',
|
||||
2:'Pumped Off',
|
||||
3:'Faulted',
|
||||
4:'Starting',
|
||||
5:'Recovering',
|
||||
100:'Read Error',
|
||||
1000:'PLC Error',
|
||||
9999:'No Response'
|
||||
}
|
||||
st_response = requests.get(self.device_address + "/json/status")
|
||||
if st_response.status_code == 200:
|
||||
data = json.loads(st_response.text)
|
||||
date = data["ISOdate"]
|
||||
status = statusMap[int(data["status"])]
|
||||
|
||||
if channels["status"]["last_value"] != status:
|
||||
self.statusChanged = True
|
||||
print "Status has changed from {0} to {1} @ {2}".format(channels["status"]["last_value"], status, time.time())
|
||||
else:
|
||||
self.statusChanged = False
|
||||
|
||||
if self.statusChanged or self.forceSend:
|
||||
self.status = status
|
||||
timestamp = int(time.mktime(time.strptime(date, '%Y-%m-%dT%H:%M:%S.%fZ')))
|
||||
self.sendtodb("status", status, timestamp)
|
||||
channels["status"]["last_value"] = status
|
||||
self.checkLatestCard()
|
||||
|
||||
|
||||
def checkDailyTotals(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/totals").text)
|
||||
total = data["totals"]
|
||||
if total['status'] == "success":
|
||||
timestamp = 0
|
||||
for val in total['values']:
|
||||
if dt_channels.has_key(val['name']):
|
||||
if ((time.time() - int(dt_channels[val['name']]['last_time_uploaded'])) > int(dt_channels[val['name']]['min_time_between_uploads'])):
|
||||
if (float(val['value']) >= (float(dt_channels[val['name']]["last_value"]) + float(dt_channels[val['name']]["change_amount"]))) or (float(val['value']) <= (float(dt_channels[val['name']]["last_value"]) - float(dt_channels[val['name']]["change_amount"]))):
|
||||
print("[dailyTotal] {0}: {1}".format(val['name'], val['value']))
|
||||
self.sendtodb(dt_channels[val['name']]["meshify_channel"], float(val['value']), timestamp)
|
||||
dt_channels[val['name']]["last_value"] = float(val['value'])
|
||||
dt_channels[val['name']]["last_time_uploaded"] = time.time()
|
||||
else:
|
||||
print("checkDailyTotalsError: {0}".format(total.message))
|
||||
|
||||
|
||||
def checkGaugeOffData(self):
|
||||
data = json.loads(requests.get(self.device_address + "/json/history").text)
|
||||
day = data["hist"]
|
||||
# print day["gauge_date"]
|
||||
#timestamp = calendar.timegm(time.strptime(day["gauge_date"], '%Y-%m-%dT%H:%M:%S.%fZ'))
|
||||
timestamp = time.mktime(time.strptime(day["gauge_date"], '%Y-%m-%dT%H:%M:%S.%Z'))
|
||||
for entry in day:
|
||||
if go_channels.has_key(entry):
|
||||
#"percent_run":{"meshifyName":"go_percent_run","last_value":"","last_send_time":0,"data_type":"float","change_amount":0},
|
||||
if go_channels[entry]["last_value"] != day[entry]:
|
||||
print entry, day[entry]
|
||||
print go_channels[entry]["meshifyName"], day[entry], timestamp
|
||||
self.sendtodb(go_channels[entry]["meshifyName"], day[entry], timestamp)
|
||||
go_channels[entry]["last_value"] = day[entry]
|
||||
|
||||
|
||||
def checkLatestCard(self):
|
||||
latest = requests.get(self.device_address + "/json/latest")
|
||||
latest = json.loads(latest.text)
|
||||
folder = str(latest["folder"])
|
||||
file = latest["file"].replace(".csv", "")
|
||||
|
||||
|
||||
#check the card to see if its new
|
||||
# 1. if its new send the folder/file_name to the card_history channel
|
||||
# 2. if its new and its been 10 minutes since you last sent an entire card, then send up all of the data
|
||||
|
||||
if channels["card_history"]["last_value"] != (folder + "/" + file):
|
||||
#we have a new card
|
||||
#get the data for this event
|
||||
data = json.loads(requests.get(self.device_address + "/json/" + folder + "/" + file).text)
|
||||
dateTime = str(data["contents"]["utctime"])
|
||||
#timestamp = time.mktime(time.strptime(dateTime, '%Y-%m-%d %H:%M:%S.%f'))
|
||||
#timestamp = calendar.timegm(time.strptime(dateTime, '%Y-%m-%d %H:%M:%S.%f'))
|
||||
timestamp = time.mktime(time.strptime(dateTime, '%Y-%m-%d %H:%M:%S.%f'))
|
||||
|
||||
print "New card detected @ {0}".format(datetime.strftime(datetime.fromtimestamp(timestamp),"%Y-%m-%d %H:%M:%S.%f"))
|
||||
#set the last value = to current value and upload your data
|
||||
channels["card_history"]["last_value"] = (folder + "/" + file)
|
||||
self.sendtodb("card_history", (folder + "/" + file), timestamp)
|
||||
|
||||
#check the last time the card was updated
|
||||
if (time.time() - int(channels["card_history"]["last_time_uploaded"])) > self.cardLoopTimer or self.statusChanged or self.forceSend:
|
||||
#its been 10 minutes, send the full upload
|
||||
print "Either status has changed or last stored card is too old."
|
||||
channels["card_history"]["last_time_uploaded"] = time.time()
|
||||
self.process_card(data, timestamp, sendCards=True)
|
||||
return
|
||||
|
||||
self.process_card(data, timestamp, sendCards=False)
|
||||
|
||||
def process_card(self, data, timestamp, sendCards=False):
|
||||
|
||||
#if sendCards = True then we upload all data no matter what, including cards
|
||||
|
||||
#check what type of data it is
|
||||
#check if its changed, if it has, how long has it been since it changed
|
||||
#NOTE: the initial vaue of "" is given to all channels in the channels object,
|
||||
# so to avoid comparing a string to a float, and to make sure on startup we send all of the values, the first time through we send everything that has a "" as its last value
|
||||
|
||||
# We don't want to store any data on starting, just the cards
|
||||
if self.status != 'Starting':
|
||||
for channel in data["contents"]:
|
||||
if channels.has_key(channel):
|
||||
if channels[channel]["data_type"] == "str":
|
||||
if (data["contents"][channel] != channels[channel]["last_value"] and ((time.time() - int(channels[channel]["last_time_uploaded"])) > int(channels[channel]["min_time_between_uploads"]))) or sendCards == True:
|
||||
print "new value for: ", channel
|
||||
print data["contents"][channel]
|
||||
self.sendtodb(channel, str(data["contents"][channel]), int(timestamp))
|
||||
channels[channel]["last_value"] = data["contents"][channel]
|
||||
channels[channel]["last_time_uploaded"] = time.time()
|
||||
if channels[channel]["data_type"] == "float" or channels[channel]["data_type"] == "int":
|
||||
if channels[channel]["last_value"] == "":
|
||||
#print "first time getting data"
|
||||
print "new value for: ", channel
|
||||
print data["contents"][channel]
|
||||
self.sendtodb(channel, str(data["contents"][channel]), int(timestamp))
|
||||
channels[channel]["last_value"] = data["contents"][channel]
|
||||
channels[channel]["last_time_uploaded"] = time.time()
|
||||
if (abs(float(data["contents"][channel]) - float(channels[channel]["last_value"])) > channels[channel]["change_amount"] and ((time.time() - int(channels[channel]["last_time_uploaded"])) > int(channels[channel]["min_time_between_uploads"]))) or sendCards == True:
|
||||
# print "first time getting data"
|
||||
print "new value for: ", channel
|
||||
print data["contents"][channel]
|
||||
self.sendtodb(channel, str(data["contents"][channel]), int(timestamp))
|
||||
channels[channel]["last_value"] = data["contents"][channel]
|
||||
channels[channel]["last_time_uploaded"] = time.time()
|
||||
|
||||
if sendCards:
|
||||
sc = data["s"]
|
||||
dc = data["d"]
|
||||
for i in range(len(data["d"])):
|
||||
try:
|
||||
for x in range(len(data["d"][i])):
|
||||
data["d"][i][x] = float('%.3f' % data["d"][i][x])
|
||||
except Exception, e:
|
||||
print e
|
||||
for i in range(len(data["s"])):
|
||||
try:
|
||||
for x in range(len(data["s"][i])):
|
||||
data["s"][i][x] = float('%.3f' % data["s"][i][x])
|
||||
except Exception, e:
|
||||
print e
|
||||
|
||||
sc = data["s"]
|
||||
dc = data["d"]
|
||||
newSc = "["
|
||||
for i in sc:
|
||||
try:
|
||||
if i[0] is None:
|
||||
continue
|
||||
if i[0] != 0.0 and i[1]!= 0.0:
|
||||
newSc += "[" + str(i[0]) + "," + str(i[1]) + "],"
|
||||
except:
|
||||
pass
|
||||
newSc += "[" + str(sc[0][0]) + "," + str(sc[0][1]) + "]"
|
||||
newSc += "]"
|
||||
|
||||
|
||||
newDc = "["
|
||||
for i in dc:
|
||||
try:
|
||||
if i[0] is None:
|
||||
continue
|
||||
if i[0] != 0.0 and i[1]!= 0.0:
|
||||
newDc += "[" + str(i[0]) + "," + str(i[1]) + "],"
|
||||
except:
|
||||
pass
|
||||
newDc += "[" + str(dc[0][0]) + "," + str(dc[0][1]) + "]"
|
||||
newDc += "]"
|
||||
|
||||
self.sendtodb("sc", newSc, timestamp)
|
||||
self.sendtodb("dc", newDc, timestamp)
|
||||
|
||||
def getLatestXCards(self, numCards):
|
||||
data = json.loads(requests.get(self.device_address + "/json/latest/"+ str(int(numCards))).text)
|
||||
for card in data['cards']:
|
||||
card_data = json.loads(requests.get(self.device_address + "/json/" + data['folder'] + "/" + card).text)
|
||||
dateTime = str(card_data["contents"]["utctime"])
|
||||
timestamp = time.mktime(time.strptime(dateTime, '%Y-%m-%d %H:%M:%S.%f'))
|
||||
self.process_card(card_data, timestamp, sendCards=True)
|
||||
|
||||
|
||||
|
||||
|
||||
def poc_get_card(self, name, value):
|
||||
self.getcard(value)
|
||||
|
||||
def poc_sync(self, name, value):
|
||||
self.sendtodb("connected", "true", 0)
|
||||
return True
|
||||
|
||||
def poc_set_address(self, name, value):
|
||||
self.device_address = value
|
||||
return True
|
||||
|
||||
def poc_refresh_data(self, name, value):
|
||||
self.forceSend = True
|
||||
return True
|
||||
|
||||
def poc_read_tag(self, name, value):
|
||||
print "Reading Tag {0}".format(str(value))
|
||||
tagObj = readTag.readTag(str(value))
|
||||
print "tagObj: {0}".format(tagObj)
|
||||
if tagObj['status'] == 'success':
|
||||
result = "{{'tag':{0},'value':{1}}}".format(str(value),str(tagObj['value']))
|
||||
self.sendtodb("read_tag_value", result, 0)
|
||||
return True
|
||||
else:
|
||||
return tagObj['message']
|
||||
Reference in New Issue
Block a user