From 4311bc503748ff9bb835a3d24f86b83442ed505e Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 13 May 2016 18:08:53 -0500 Subject: [PATCH 01/23] adds init script --- init/loggers | 37 +++++++++++++++++++++++++++++++++++++ 1 file changed, 37 insertions(+) create mode 100644 init/loggers diff --git a/init/loggers b/init/loggers new file mode 100644 index 0000000..abce8f4 --- /dev/null +++ b/init/loggers @@ -0,0 +1,37 @@ +#! /bin/sh +# /etc/init.d/loggers + +### BEGIN INIT INFO +# Provides: loggers +# Required-Start: $remote_fs $syslog +# Required-Stop: $remote_fs $syslog +# Default-Start: 2 3 4 5 +# Default-Stop: 0 1 6 +# Short-Description: Simple script to start a program at boot +# Description: A simple script from www.stuffaboutcode.com which will start / stop a program a boot / shutdown. +### END INIT INFO + +# If you want a command to always run, put it here + +# Carry out specific functions when asked to by the system +case "$1" in + start) + echo "Starting loggers" + kill -9 $(cat /root/dataLogger.pid) + # run application you want to start + /usr/bin/python /home/poconsole/datalogger/dataLogger.py > /dev/null 2>&1 & echo $! > "/root/dataLogger.pid" + + ;; + stop) + echo "Stopping loggers" + # kill application you want to stop + kill -9 $(cat /root/dataLogger.pid) + +;; + *) + echo "Usage: /etc/init.d/loggers {start|stop}" + exit 1 + ;; +esac + +exit 0 From a871da9c613fdb2c0c2a776d2e037e465faeb4bd Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 13:38:22 -0500 Subject: [PATCH 02/23] Uses the sail-ready tag submodule --- tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tag b/tag index 10c044e..c610c9f 160000 --- a/tag +++ b/tag @@ -1 +1 @@ -Subproject commit 10c044e3d2985e27512b01617402c72d63d08861 +Subproject commit c610c9fa2cf18c547fefc9ee83db9f352d59609c From 061189de4e379b921afae4b7c01334da57e0b89b Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 14:48:05 -0500 Subject: [PATCH 03/23] adds Sails datalogger --- dataLogger.py | 371 ++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 371 insertions(+) create mode 100644 dataLogger.py diff --git a/dataLogger.py b/dataLogger.py new file mode 100644 index 0000000..4233382 --- /dev/null +++ b/dataLogger.py @@ -0,0 +1,371 @@ +#!/usr/bin/env python + + +import time +from pycomm.ab_comm.clx import Driver as ClxDriver +from tag.tag import Tag +from tag.alarm import AnalogAlarm +from tag.alarm import bitAlarm +import traceback +import json +import requests + +# DEFAULTS +web_address = "http://localhost:3000" +scan_rate = 30 # seconds +save_all = "test" # use True, False, or any string +plc_handshake_tags = {} +last_handshake_time = 0 + +# GLOBAL VARIABLES +device_types = {} +devices = [] +main_plc = {} + +# ---------- MAP FUNCTIONS ---------- # +maps = { + 'modeMap': { + 0: "Error", + 1: "Auto", + 2: "POC", + 3: "Timer", + 4: "Manual", + 5: "DH PID" + }, + 'card_type_map': { + 0: "Normal", + 1: "Shutdown", + 2: "Alarm", + 3: "Startup", + 4: "Low Fillage" + }, + 'statusMap': { + 0: 'Stopped', + 1: 'Running', + 2: 'Pumped Off', + 3: 'Faulted', + 4: 'Starting', + 5: 'Recovering', + 100: 'Read Error', + 1000: 'PLC Error', + 9999: 'No Response' + }, + 'conditionMap': { + 20: "Low", + 21: "High", + 24: "LoLo", + 25: "HiHi", + 32: "Input Failure", + 34: "Configuration Error", + 16: "Failure to Stop", + 17: "Failure to Start", + 18: "Drive Fault" + } +} +# ---------- TAGS ---------- # +stroke_tags = {} # Tags stored for every single stroke +history_tags = {} # Tags stored on value change or age +gaugeoff_tags = {} # Tags stored at gauge off +welltest_tags = {} # Tags stored at well test submit +bit_tags = {} +safety_tags = {} +custom_tags = {} + + +class Status(Tag): + def sendToDB(self): + post_data = {'status': self.value} + r = requests.post('{}/run_status'.format(web_address), data=post_data) + resp = json.loads(r.text) + print("Stored {} for {} at {}".format(resp['val'], self.name, resp['createdAt'])) + self.last_send_time = time.time() + + +def getDeviceTypes(): + global web_address + device_types = {} + try: + get_device_type_request = requests.get('{}/device_type'.format(web_address)) + device_types_json = json.loads(get_device_type_request.text) + for t in device_types_json: + device_types[t['id']] = t['dType'] + return device_types + except Exception, e: + print("Error getting tags: {}".format(e)) + return False + + +def readConfig(): + global web_address, scan_rate, save_all + try: + sr_req_data = 'where={"parameter": "scan_rate"}' + sr_req = requests.get('{}/config?{}'.format(web_address, sr_req_data)) + sr_try = json.loads(sr_req.text) + if len(sr_try) > 0: + scan_rate = int(sr_try[0]['val']) + except Exception, e: + print("Error getting scan rate: {}".format(e)) + print("I'll just use {} seconds as the scan rate...".format(scan_rate)) + + try: + sa_req_data = {"where": {"parameter": "save_all"}} + sa_req = requests.get('{}/config'.format(web_address), params=sa_req_data) + sa_try = json.loads(sa_req.text) + if len(sa_try) > 0: + if sa_try[0]['val'].lower() == "true": + save_all = True + elif sa_try[0]['val'].lower() == "false": + save_all = False + except Exception, e: + print("Error getting save-all: {}".format(e)) + print("I'll just use {} as the save-all parameter...".format(save_all)) + + return True + + +def readTag(addr, tag): + c = ClxDriver() + if c.open(addr): + try: + v = c.read_tag(tag) + return v + except Exception: + print("ERROR RETRIEVING TAG: {}".format(tag)) + c.close() + traceback.print_exc() + c.close() + + +def readArray(addr, arr, length): + c = ClxDriver() + if c.open(addr): + try: + v = c.read_array(arr, length) + return map(lambda x: x[1], v) + except Exception: + print("ERROR RETRIEVING ARRAY: {}".format(arr)) + err = c.get_status() + c.close() + print err + traceback.print_exc() + c.close() + + +def setupTags(): + global device_types, web_address, stroke_tags, gaugeoff_tags, history_tags, welltest_tags, custom_tags + try: + # Get tags stored in database + get_tag_request = requests.get('{}/tag'.format(web_address)) + tags = json.loads(get_tag_request.text) + for t in tags: + if t['tag_class']['class_type'] == 'stroke': + stroke_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + + elif t['tag_class']['class_type'] == 'history': + history_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + + elif t['tag_class']['class_type'] == 'gaugeoff': + gaugeoff_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + + elif t['tag_class']['class_type'] == 'welltest': + welltest_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + + elif t['tag_class']['class_type'] == 'custom': + custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + + get_event_request = requests.get('{}/event_config'.format(web_address)) + events = json.loads(get_event_request.text) + for e in events: + if e['event_class']['event_class'] == 'analog': + safety_tags[e['name']] = AnalogAlarm(e['name'], e['tag'], e['id'], ip_address=e['deviceID']['address'], device_type=device_types[e['deviceID']['device_type']]) + elif e['event_class']['event_class'] == 'bit': + bit_tags[e['name']] = bitAlarm(e['name'], e['tag'], e['event_condition'], e['id'], ip_address=e['deviceID']['address'], device_type=device_types[e['deviceID']['device_type']]) + return True + except Exception, e: + print("Error getting tags: {}".format(e)) + return False + + +def getMainPLC(): + get_plc_req_data = {'where': {'id': 0}} + get_plc_request = requests.get('{}/device'.format(web_address), data=get_plc_req_data) + return json.loads(get_plc_request.text) + + +def readPoints(): + global main_plc + num_points = readTag(main_plc['address'], "Card_Past[1].Num_Points")[0] + surf_pos = readArray(main_plc['address'], "Card_Past[1].Surface_Position", num_points + 1)[1:] + surf_pos.append(surf_pos[0]) + surf_lod = readArray(main_plc['address'], "Card_Past[1].Surface_Load", num_points + 1)[1:] + surf_lod.append(surf_lod[0]) + down_pos = readArray(main_plc['address'], "Card_Past[1].Downhole_Position", num_points + 1)[1:] + down_pos.append(down_pos[0]) + down_lod = readArray(main_plc['address'], "Card_Past[1].Downhole_Load", num_points + 1)[1:] + down_lod.append(down_lod[0]) + return([surf_pos, surf_lod, down_pos, down_lod]) + + +def evalTapers(): + return True +# TODO: Read taper data +# global main_plc +# ts = time.time() +# numTapers = int(readTag(main_plc['address'], 'Card_Current.Params.Num_Tapers')[0]) +# for t in range(1, numTapers + 1): +# taper_length = readTag(main_plc['address'], 'Taper.Taper[{}].Setup.Length'.format(t))[0] +# taper_diameter = readTag(main_plc['address'], 'Taper.Taper[{}].Setup.Diameter'.format(t))[0] +# taper_material = readTag(main_plc['address'], 'Taper.Taper[{}].Setup.Material'.format(t))[0] +# if (taper_material == 1): +# taper_material = "Steel" +# elif (taper_material == 2): +# taper_material = "Fiberglass" +# +# tStr = "{{'taper':{}, 'length': {}, 'diameter': {}, 'material':'{}'}}".format(t, taper_length, taper_diameter, taper_material) +# tQuery = 'INSERT INTO well_config (tstamp, type, val) VALUES ({}, "taper", "{}")'.format(ts, tStr) +# print tQuery +# con.connect() +# cur = con.cursor() +# cur.execute(tQuery) +# con.commit() +# +# pump_diameter = readTag(main_plc['address'], 'UnitConfig.Pump_Diameter')[0] +# cfgQuery = "INSERT INTO well_config (tstamp, type, val) VALUES ({}, 'pump_diameter', '{}')".format(ts, pump_diameter) +# con.connect() +# cur = con.cursor() +# cur.execute(cfgQuery) +# con.commit() +# print "TAPER DATA READ!" +# return True + + +def main(): + global main_plc + + readConfig() + if setupTags(): + pass + else: + main() + + status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'], ip_address=main_plc['address'], device_type=device_types[main_plc['device_type']]) + read_tapers = False + already_gauged_off = False + already_entered_well_test = False + last_stroke = 0 + last_status = "" + statusChanged = False + + while True: + try: + current_status = status.read("test") + statusChanged = not (current_status == last_status) + if statusChanged: + last_status = current_status + ############# + # CARD DATA # + ############# + stroke_tags['card_id'].read('test') + + if not (last_stroke == stroke_tags['card_id'].value): + sData = {} + last_stroke = stroke_tags['card_id'].value + for t in stroke_tags: + if not t == "card_id": + stroke_tags[t].read(True) + [sData['Surface_Position'], sData['Surface_Load'], sData['Downhole_Position'], sData['Downhole_Load']] = readPoints() + + sData["card_type"] = stroke_tags['card_type'].value + sData["card_id"] = stroke_tags['card_id'].value + sData['sp_string'] = ', '.join(map(str, sData['Surface_Position'])) + sData['sl_string'] = ', '.join(map(str, sData['Surface_Load'])) + sData['dp_string'] = ', '.join(map(str, sData['Downhole_Position'])) + sData['dl_string'] = ', '.join(map(str, sData['Downhole_Load'])) + + card_ins_req_data = { + 'card_id': sData['card_id'], + 'card_type': sData['card_type'], + 'surface_position': sData['sp_string'], + 'surface_load': sData['sl_string'], + 'downhole_position': sData['dp_string'], + 'downhole_load': sData['dl_string'] + } + r = requests.post('{}/card'.format(web_address), data=card_ins_req_data) + resp = json.loads(r.text) + print "CARD NUMBER {} READ AT {}!".format(resp["card_id"], resp['createdAt']) + + ################### + # HISTORICAL DATA # + ################### + + for hist in history_tags: + h = history_tags[hist] + h.read("test") + + for cust in custom_tags: + t = custom_tags[cust] + t.read("test") + + ############## + # TAPER DATA # + ############## + + update_taper = readTag(main_plc['address'], "Write_Tapers")[0] > 0 + if (update_taper == 0): + if read_tapers: + read_tapers = False + print "Update Tapers = False" + + if (update_taper and (not read_tapers)): + print "reading taper file" + read_tapers = evalTapers() + + ################## + # GAUGE OFF DATA # + ################## + gauge_off = readTag(main_plc['address'], "Gauge_Off_Command")[0] + if (gauge_off == 0): + if already_gauged_off: + already_gauged_off = False + print "Already gauged off... Setting gauge_off to False" + + if (gauge_off and (not already_gauged_off)): + print "Gauging off..." + for goff in gaugeoff_tags: + g = gaugeoff_tags[goff] + g.read(True) + + already_gauged_off = True + print "Gauged off!" + + ################## + # WELL TEST DATA # + ################## + + well_test_entered = readTag(main_plc['address'], "Well_Test.Test_Submit")[0] > 0 + if (well_test_entered == 0): + if already_entered_well_test: + already_entered_well_test = False + print "Already entered well Test... Setting well_test_entered to False" + if (well_test_entered and (not already_entered_well_test)): + for wtest in welltest_tags: + w = welltest_tags[wtest] + w.read(True) + already_entered_well_test = True + print "Well Test Stored!" + + ################### + # ALARMS & EVENTS # + ################### + for t in safety_tags: + safety_tags[t].checkStatus(stroke_tags['card_id'].value) + + for b in bit_tags: + bit_tags[b].checkStatus(stroke_tags['card_id'].value) + + time.sleep(.20) + except Exception, e: + print("Error during loop: {}".format(e)) + traceback.print_exc() +if __name__ == '__main__': + main() From 9151a337019b3f85cb408d4ba06a1c1c00fe60c3 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 16:39:18 -0500 Subject: [PATCH 04/23] Adds a little error message --- dataLogger.py | 1 + 1 file changed, 1 insertion(+) diff --git a/dataLogger.py b/dataLogger.py index 4233382..434f0ad 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -246,6 +246,7 @@ def main(): if setupTags(): pass else: + print("Unable to read tags... Restarting.") main() status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'], ip_address=main_plc['address'], device_type=device_types[main_plc['device_type']]) From d8a589c33f750796aeb36fa4de100a4587911643 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 20:43:30 -0500 Subject: [PATCH 05/23] Device Types not being found before accessing --- dataLogger.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index 434f0ad..313b27e 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -240,9 +240,10 @@ def evalTapers(): def main(): - global main_plc + global main_plc, device_types readConfig() + device_types = getDeviceTypes() if setupTags(): pass else: From 22f20d90a2ec59b67a83d24585c7b3912cd1d0b9 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 20:45:38 -0500 Subject: [PATCH 06/23] Was never getting main PLC --- dataLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index 313b27e..df98581 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -241,7 +241,7 @@ def evalTapers(): def main(): global main_plc, device_types - + main_plc = getMainPLC() readConfig() device_types = getDeviceTypes() if setupTags(): From b750edc4bd03d933f01e3f3a210a024686e2b432 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 20:47:24 -0500 Subject: [PATCH 07/23] getMainPLC was returning a list instead of an object --- dataLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index df98581..302107b 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -189,7 +189,7 @@ def setupTags(): def getMainPLC(): get_plc_req_data = {'where': {'id': 0}} get_plc_request = requests.get('{}/device'.format(web_address), data=get_plc_req_data) - return json.loads(get_plc_request.text) + return json.loads(get_plc_request.text)[0] def readPoints(): From bf90060f9742d2ec49964254f1ab19c70506976c Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 20:50:00 -0500 Subject: [PATCH 08/23] need to specify the id of the data_type for main_plc --- dataLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index 302107b..90a1e24 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -250,7 +250,7 @@ def main(): print("Unable to read tags... Restarting.") main() - status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'], ip_address=main_plc['address'], device_type=device_types[main_plc['device_type']]) + status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'], ip_address=main_plc['address'], device_type=device_types[main_plc['device_type']['id']]) read_tapers = False already_gauged_off = False already_entered_well_test = False From b0811208583a99e8d2d8aa381972325d43f9360c Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Mon, 6 Jun 2016 20:52:35 -0500 Subject: [PATCH 09/23] run_status uses 'status' instead of 'val' --- dataLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index 90a1e24..b57e52a 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -77,7 +77,7 @@ class Status(Tag): post_data = {'status': self.value} r = requests.post('{}/run_status'.format(web_address), data=post_data) resp = json.loads(r.text) - print("Stored {} for {} at {}".format(resp['val'], self.name, resp['createdAt'])) + print("Stored {} for {} at {}".format(resp['status'], self.name, resp['createdAt'])) self.last_send_time = time.time() From 9035959a1b5354b6b8cac440dc6395b70d1c0271 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Wed, 8 Jun 2016 15:55:31 -0500 Subject: [PATCH 10/23] fixes map functions --- dataLogger.py | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/dataLogger.py b/dataLogger.py index b57e52a..c3aa1c7 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -159,19 +159,19 @@ def setupTags(): tags = json.loads(get_tag_request.text) for t in tags: if t['tag_class']['class_type'] == 'stroke': - stroke_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + stroke_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'history': - history_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + history_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'gaugeoff': - gaugeoff_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + gaugeoff_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'welltest': - welltest_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + welltest_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'custom': - custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=t['map_function'], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) get_event_request = requests.get('{}/event_config'.format(web_address)) events = json.loads(get_event_request.text) From 706c40a4eda6b8280120a6b26947b51f0ae37f50 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Tue, 14 Jun 2016 19:06:35 -0500 Subject: [PATCH 11/23] Fixes driver. This file runs & works. --- dataLogger.py | 14 ++++++++------ dbMySQL/readConfig_MySQL.py | 1 + 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/dataLogger.py b/dataLogger.py index c3aa1c7..d20ee74 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -60,7 +60,9 @@ maps = { 16: "Failure to Stop", 17: "Failure to Start", 18: "Drive Fault" - } + }, + None: None, + 'null': None } # ---------- TAGS ---------- # stroke_tags = {} # Tags stored for every single stroke @@ -159,19 +161,19 @@ def setupTags(): tags = json.loads(get_tag_request.text) for t in tags: if t['tag_class']['class_type'] == 'stroke': - stroke_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + stroke_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'history': - history_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + history_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'gaugeoff': - gaugeoff_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + gaugeoff_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'welltest': - welltest_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + welltest_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) elif t['tag_class']['class_type'] == 'custom': - custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) get_event_request = requests.get('{}/event_config'.format(web_address)) events = json.loads(get_event_request.text) diff --git a/dbMySQL/readConfig_MySQL.py b/dbMySQL/readConfig_MySQL.py index 7c04f0c..b87df8f 100644 --- a/dbMySQL/readConfig_MySQL.py +++ b/dbMySQL/readConfig_MySQL.py @@ -7,6 +7,7 @@ with open(os.path.realpath('.') + '/mysql_cfg.pickle', 'rb') as cfgFile: mysql_cfg = pickle.load(cfgFile) con = mysqlcon.connect(**mysql_cfg) + def readConfig(): configProperties = {} configObj = {} From 4481aa47b01aede7aef816574dcf3f33f3405dc1 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Tue, 14 Jun 2016 19:09:03 -0500 Subject: [PATCH 12/23] Updates tag so I don't have to keep fixing Micro800 imports --- tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tag b/tag index c610c9f..01d54be 160000 --- a/tag +++ b/tag @@ -1 +1 @@ -Subproject commit c610c9fa2cf18c547fefc9ee83db9f352d59609c +Subproject commit 01d54be292cba93a07c967d75780d0d29441c200 From a1200ec23417725dee78e52ff79381cc1f73098c Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 16 Jun 2016 10:50:54 -0500 Subject: [PATCH 13/23] Fixes tag read bug --- tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tag b/tag index 01d54be..80e887a 160000 --- a/tag +++ b/tag @@ -1 +1 @@ -Subproject commit 01d54be292cba93a07c967d75780d0d29441c200 +Subproject commit 80e887ab23a43c87af04fdfb3536bc7e011aab7a From 59d1f08f8c14daf492a8627b6a7bca658e073cb1 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 16 Jun 2016 16:06:59 -0500 Subject: [PATCH 14/23] Fixed tag names for using pretty names --- dataLogger.py | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/dataLogger.py b/dataLogger.py index d20ee74..94fc2aa 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -271,16 +271,16 @@ def main(): ############# stroke_tags['card_id'].read('test') - if not (last_stroke == stroke_tags['card_id'].value): + if not (last_stroke == stroke_tags['Card ID'].value): sData = {} - last_stroke = stroke_tags['card_id'].value + last_stroke = stroke_tags['Card ID'].value for t in stroke_tags: - if not t == "card_id": + if not t == "Card ID": stroke_tags[t].read(True) [sData['Surface_Position'], sData['Surface_Load'], sData['Downhole_Position'], sData['Downhole_Load']] = readPoints() - sData["card_type"] = stroke_tags['card_type'].value - sData["card_id"] = stroke_tags['card_id'].value + sData["card_type"] = stroke_tags['Card Type'].value + sData["card_id"] = stroke_tags['Card ID'].value sData['sp_string'] = ', '.join(map(str, sData['Surface_Position'])) sData['sl_string'] = ', '.join(map(str, sData['Surface_Load'])) sData['dp_string'] = ', '.join(map(str, sData['Downhole_Position'])) @@ -347,7 +347,7 @@ def main(): ################## well_test_entered = readTag(main_plc['address'], "Well_Test.Test_Submit")[0] > 0 - if (well_test_entered == 0): + if well_test_entered: if already_entered_well_test: already_entered_well_test = False print "Already entered well Test... Setting well_test_entered to False" @@ -362,10 +362,10 @@ def main(): # ALARMS & EVENTS # ################### for t in safety_tags: - safety_tags[t].checkStatus(stroke_tags['card_id'].value) + safety_tags[t].checkStatus(stroke_tags['Card ID'].value) for b in bit_tags: - bit_tags[b].checkStatus(stroke_tags['card_id'].value) + bit_tags[b].checkStatus(stroke_tags['Card ID'].value) time.sleep(.20) except Exception, e: From 637ad310dbf5c94719d2d746049af661cb0d998f Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 16 Jun 2016 16:08:43 -0500 Subject: [PATCH 15/23] Missed one. --- dataLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index 94fc2aa..92eb21c 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -269,7 +269,7 @@ def main(): ############# # CARD DATA # ############# - stroke_tags['card_id'].read('test') + stroke_tags['Card ID'].read('test') if not (last_stroke == stroke_tags['Card ID'].value): sData = {} From 2d1b3d9134d705641a74e79291ba92b77e3d48c6 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Wed, 22 Jun 2016 11:58:02 -0500 Subject: [PATCH 16/23] POCONSOLE-51 forces HTTPS --- dataLogger.py | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/dataLogger.py b/dataLogger.py index 92eb21c..4fab31a 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -11,7 +11,7 @@ import json import requests # DEFAULTS -web_address = "http://localhost:3000" +web_address = "https://localhost:3000" scan_rate = 30 # seconds save_all = "test" # use True, False, or any string plc_handshake_tags = {} @@ -77,7 +77,7 @@ custom_tags = {} class Status(Tag): def sendToDB(self): post_data = {'status': self.value} - r = requests.post('{}/run_status'.format(web_address), data=post_data) + r = requests.post('{}/run_status'.format(web_address), data=post_data, verify=False) resp = json.loads(r.text) print("Stored {} for {} at {}".format(resp['status'], self.name, resp['createdAt'])) self.last_send_time = time.time() @@ -87,7 +87,7 @@ def getDeviceTypes(): global web_address device_types = {} try: - get_device_type_request = requests.get('{}/device_type'.format(web_address)) + get_device_type_request = requests.get('{}/device_type'.format(web_address), verify=False) device_types_json = json.loads(get_device_type_request.text) for t in device_types_json: device_types[t['id']] = t['dType'] @@ -101,7 +101,7 @@ def readConfig(): global web_address, scan_rate, save_all try: sr_req_data = 'where={"parameter": "scan_rate"}' - sr_req = requests.get('{}/config?{}'.format(web_address, sr_req_data)) + sr_req = requests.get('{}/config?{}'.format(web_address, sr_req_data), verify=False) sr_try = json.loads(sr_req.text) if len(sr_try) > 0: scan_rate = int(sr_try[0]['val']) @@ -111,7 +111,7 @@ def readConfig(): try: sa_req_data = {"where": {"parameter": "save_all"}} - sa_req = requests.get('{}/config'.format(web_address), params=sa_req_data) + sa_req = requests.get('{}/config'.format(web_address), params=sa_req_data, verify=False) sa_try = json.loads(sa_req.text) if len(sa_try) > 0: if sa_try[0]['val'].lower() == "true": @@ -157,7 +157,7 @@ def setupTags(): global device_types, web_address, stroke_tags, gaugeoff_tags, history_tags, welltest_tags, custom_tags try: # Get tags stored in database - get_tag_request = requests.get('{}/tag'.format(web_address)) + get_tag_request = requests.get('{}/tag'.format(web_address), verify=False) tags = json.loads(get_tag_request.text) for t in tags: if t['tag_class']['class_type'] == 'stroke': @@ -175,7 +175,7 @@ def setupTags(): elif t['tag_class']['class_type'] == 'custom': custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) - get_event_request = requests.get('{}/event_config'.format(web_address)) + get_event_request = requests.get('{}/event_config'.format(web_address), verify=False) events = json.loads(get_event_request.text) for e in events: if e['event_class']['event_class'] == 'analog': @@ -190,7 +190,7 @@ def setupTags(): def getMainPLC(): get_plc_req_data = {'where': {'id': 0}} - get_plc_request = requests.get('{}/device'.format(web_address), data=get_plc_req_data) + get_plc_request = requests.get('{}/device'.format(web_address), data=get_plc_req_data, verify=False) return json.loads(get_plc_request.text)[0] @@ -294,7 +294,7 @@ def main(): 'downhole_position': sData['dp_string'], 'downhole_load': sData['dl_string'] } - r = requests.post('{}/card'.format(web_address), data=card_ins_req_data) + r = requests.post('{}/card'.format(web_address), data=card_ins_req_data, verify=False) resp = json.loads(r.text) print "CARD NUMBER {} READ AT {}!".format(resp["card_id"], resp['createdAt']) From a61cdf0e55367646f0f7262b6d500190aaa57cda Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 23 Jun 2016 10:23:28 -0500 Subject: [PATCH 17/23] Updated Tag submodule to work with POCONSOLE-51 (HTTPS) --- tag | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/tag b/tag index 80e887a..a89ed46 160000 --- a/tag +++ b/tag @@ -1 +1 @@ -Subproject commit 80e887ab23a43c87af04fdfb3536bc7e011aab7a +Subproject commit a89ed46bdf570044dec4bac4f17e668dd7c79ab0 From 49e6e0605f03124ccae84cc4b8980106945e634a Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 5 Aug 2016 16:00:42 -0500 Subject: [PATCH 18/23] Fix to init script --- init/loggers | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/init/loggers b/init/loggers index abce8f4..1005ad3 100644 --- a/init/loggers +++ b/init/loggers @@ -19,7 +19,7 @@ case "$1" in echo "Starting loggers" kill -9 $(cat /root/dataLogger.pid) # run application you want to start - /usr/bin/python /home/poconsole/datalogger/dataLogger.py > /dev/null 2>&1 & echo $! > "/root/dataLogger.pid" + /usr/bin/python /root/datalogger/dataLogger.py > /dev/null 2>&1 & echo $! > "/root/dataLogger.pid" ;; stop) From 2d928cc1aa09877b30cb4cabe9126bf10ec4d9bd Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 9 Sep 2016 18:16:53 -0500 Subject: [PATCH 19/23] per POCONSOLE-59, updates submodule --- .gitmodules | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.gitmodules b/.gitmodules index 7206881..663a721 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,3 +1,3 @@ [submodule "tag"] path = tag - url = http://patrickjmcd@bitbucket.poconsole.net/scm/poconsole/tag.git +url=ssh://git-codecommit.us-east-1.amazonaws.com/v1/repos/POCONSOLE-Tag From a8ed2b5c08927e99ffd83dacdd389aef4d227b18 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 11 Nov 2016 17:43:52 -0600 Subject: [PATCH 20/23] Mostly completes POCONSOLE-39. Still need to get it on an actual well to test the data coming in --- dataLogger.py | 348 +++++++++++++++++++++++++++----------------------- 1 file changed, 186 insertions(+), 162 deletions(-) diff --git a/dataLogger.py b/dataLogger.py index 4fab31a..347ff5f 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -3,15 +3,19 @@ import time from pycomm.ab_comm.clx import Driver as ClxDriver -from tag.tag import Tag -from tag.alarm import AnalogAlarm -from tag.alarm import bitAlarm +from pycomm_helper.tag import Tag +from pycomm_helper.alarm import AnalogAlarm, bitAlarm import traceback import json import requests # DEFAULTS -web_address = "https://localhost:3000" +API_METHOD = "https" +API_ADDRESS = "localhost" +API_PORT = 5000 + +API_BASE_URL = "{}://{}:{}/api".format(API_METHOD, API_ADDRESS, API_PORT) + scan_rate = 30 # seconds save_all = "test" # use True, False, or any string plc_handshake_tags = {} @@ -65,10 +69,7 @@ maps = { 'null': None } # ---------- TAGS ---------- # -stroke_tags = {} # Tags stored for every single stroke -history_tags = {} # Tags stored on value change or age -gaugeoff_tags = {} # Tags stored at gauge off -welltest_tags = {} # Tags stored at well test submit +tag_list = {} bit_tags = {} safety_tags = {} custom_tags = {} @@ -76,54 +77,56 @@ custom_tags = {} class Status(Tag): def sendToDB(self): - post_data = {'status': self.value} - r = requests.post('{}/run_status'.format(web_address), data=post_data, verify=False) + global API_BASE_URL + post_data = {'run_status': self.value} + r = requests.post('{}/run_status_log'.format(API_BASE_URL), data=json.dumps(post_data), headers={'Content-Type': 'application/json'}, verify=False) resp = json.loads(r.text) - print("Stored {} for {} at {}".format(resp['status'], self.name, resp['createdAt'])) + print("Stored {} for Run Status at {}".format(resp['run_status'], self.name, resp['created_on'])) self.last_send_time = time.time() -def getDeviceTypes(): - global web_address - device_types = {} - try: - get_device_type_request = requests.get('{}/device_type'.format(web_address), verify=False) - device_types_json = json.loads(get_device_type_request.text) - for t in device_types_json: - device_types[t['id']] = t['dType'] - return device_types - except Exception, e: - print("Error getting tags: {}".format(e)) - return False - - def readConfig(): - global web_address, scan_rate, save_all - try: - sr_req_data = 'where={"parameter": "scan_rate"}' - sr_req = requests.get('{}/config?{}'.format(web_address, sr_req_data), verify=False) - sr_try = json.loads(sr_req.text) - if len(sr_try) > 0: - scan_rate = int(sr_try[0]['val']) - except Exception, e: - print("Error getting scan rate: {}".format(e)) - print("I'll just use {} seconds as the scan rate...".format(scan_rate)) + global API_BASE_URL, scan_rate, save_all + req = requests.get('{}/configs'.format(API_BASE_URL), verify=False) + res = json.loads(req.text)['objects'] - try: - sa_req_data = {"where": {"parameter": "save_all"}} - sa_req = requests.get('{}/config'.format(web_address), params=sa_req_data, verify=False) - sa_try = json.loads(sa_req.text) - if len(sa_try) > 0: - if sa_try[0]['val'].lower() == "true": - save_all = True - elif sa_try[0]['val'].lower() == "false": - save_all = False - except Exception, e: - print("Error getting save-all: {}".format(e)) - print("I'll just use {} as the save-all parameter...".format(save_all)) + if len(res) > 0: + for x in res: + if x['parameter'] == "scan_rate": + try: + scan_rate = int(x['val']) + except Exception as e: + print("Error setting scan_rate to {}".format(x['val'])) + + elif x['parameter'] == "save_all": + try: + if x['val'].lower() == 'true': + save_all = True + elif x['val'].lower() == 'true': + save_all = False + else: + print("Invalid save_all parameter: {}".format(x['val'])) + except Exception as e: + print("Error setting save_all to {}".format(x['val'])) + else: + print("No configuration data found.") return True +def getDeviceTypes(): + global API_BASE_URL + req = requests.get('{}/device_types'.format(API_BASE_URL), verify=False) + res = json.loads(req.text)['objects'] + device_types = {} + if len(res) > 0: + for x in res: + device_types[x['_id']] = x['device_type'] + return device_types + else: + print("No device type data found.") + + return False + def readTag(addr, tag): c = ClxDriver() @@ -148,65 +151,78 @@ def readArray(addr, arr, length): print("ERROR RETRIEVING ARRAY: {}".format(arr)) err = c.get_status() c.close() - print err + print(err) traceback.print_exc() c.close() def setupTags(): - global device_types, web_address, stroke_tags, gaugeoff_tags, history_tags, welltest_tags, custom_tags - try: - # Get tags stored in database - get_tag_request = requests.get('{}/tag'.format(web_address), verify=False) - tags = json.loads(get_tag_request.text) - for t in tags: - if t['tag_class']['class_type'] == 'stroke': - stroke_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + global device_types, API_BASE_URL, tag_list, safety_tags, bit_tags + # try: + # Get tags stored in database + get_tag_request = requests.get('{}/tags'.format(API_BASE_URL), verify=False) + tags = json.loads(get_tag_request.text)['objects'] + for t in tags: - elif t['tag_class']['class_type'] == 'history': - history_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) + tag_list[t['name']] = Tag(t['name'], t['tag'], t['_id'], t['data_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['device']['address'], device_type=device_types[t['device']['device_type_id']]) - elif t['tag_class']['class_type'] == 'gaugeoff': - gaugeoff_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) - - elif t['tag_class']['class_type'] == 'welltest': - welltest_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) - - elif t['tag_class']['class_type'] == 'custom': - custom_tags[t['name']] = Tag(t['name'], t['tag'], t['id'], t['data_type']['plc_type'], t['change_threshold'], t['guarantee_sec'], mapFn=maps[t['map_function']], ip_address=t['deviceID']['address'], device_type=device_types[t['deviceID']['device_type']]) - - get_event_request = requests.get('{}/event_config'.format(web_address), verify=False) - events = json.loads(get_event_request.text) - for e in events: - if e['event_class']['event_class'] == 'analog': - safety_tags[e['name']] = AnalogAlarm(e['name'], e['tag'], e['id'], ip_address=e['deviceID']['address'], device_type=device_types[e['deviceID']['device_type']]) - elif e['event_class']['event_class'] == 'bit': - bit_tags[e['name']] = bitAlarm(e['name'], e['tag'], e['event_condition'], e['id'], ip_address=e['deviceID']['address'], device_type=device_types[e['deviceID']['device_type']]) - return True - except Exception, e: - print("Error getting tags: {}".format(e)) - return False + get_event_request = requests.get('{}/event_configs'.format(API_BASE_URL), verify=False) + events = json.loads(get_event_request.text)['objects'] + for e in events: + if e['event_type'] == 'analog': + safety_tags[e['name']] = AnalogAlarm(e['name'], e['tag'], e['_id'], ip_address=e['device']['address'], device_type=device_types[e['device']['device_type_id']]) + elif e['event_type'] == 'bit': + bit_tags[e['name']] = bitAlarm(e['name'], e['tag'], e['condition'], e['_id'], ip_address=e['device']['address'], device_type=device_types[e['device']['device_type_id']]) + return True + # except Exception as e: + # print("Error getting tags: {}".format(e)) + # return False def getMainPLC(): - get_plc_req_data = {'where': {'id': 0}} - get_plc_request = requests.get('{}/device'.format(web_address), data=get_plc_req_data, verify=False) - return json.loads(get_plc_request.text)[0] + global API_BASE_URL + get_plc_request = requests.get('{}/devices'.format(API_BASE_URL), verify=False) + return json.loads(get_plc_request.text)['objects'][0] -def readPoints(): + + + +def readGaugeOffData(): global main_plc - num_points = readTag(main_plc['address'], "Card_Past[1].Num_Points")[0] - surf_pos = readArray(main_plc['address'], "Card_Past[1].Surface_Position", num_points + 1)[1:] - surf_pos.append(surf_pos[0]) - surf_lod = readArray(main_plc['address'], "Card_Past[1].Surface_Load", num_points + 1)[1:] - surf_lod.append(surf_lod[0]) - down_pos = readArray(main_plc['address'], "Card_Past[1].Downhole_Position", num_points + 1)[1:] - down_pos.append(down_pos[0]) - down_lod = readArray(main_plc['address'], "Card_Past[1].Downhole_Load", num_points + 1)[1:] - down_lod.append(down_lod[0]) - return([surf_pos, surf_lod, down_pos, down_lod]) + try: + gaugeOffData = { + 'spm_average': readTag(main_plc['address'], 'GAUGEOFF_Average_SPM')[0], + 'downhole_gross_stroke_average': readTag(main_plc['address'], 'GAUGEOFF_Downhole_GrossStroke')[0], + 'downhole_net_stroke_average': readTag(main_plc['address'], 'GAUGEOFF_Downhole_NetStroke')[0], + 'electricity_cost_total': readTag(main_plc['address'], 'GAUGEOFF_Electricity_Cost')[0], + 'fluid_level_average': readTag(main_plc['address'], 'GAUGEOFF_Fluid_Above_Pump')[0], + 'full_card_production_total': readTag(main_plc['address'], 'GAUGEOFF_Full_Card_Production')[0], + 'inflow_rate_average': readTag(main_plc['address'], 'GAUGEOFF_Inflow_Rate')[0], + 'kWh_used_total': readTag(main_plc['address'], 'GAUGEOFF_kWh')[0], + 'kWh_regen_total': readTag(main_plc['address'], 'GAUGEOFF_kWh_Regen')[0], + 'lifting_cost_average': readTag(main_plc['address'], 'GAUGEOFF_Lifting_Cost')[0], + 'peak_pr_load': readTag(main_plc['address'], 'GAUGEOFF_Max_Load')[0], + 'min_pr_load': readTag(main_plc['address'], 'GAUGEOFF_Min_Load')[0], + 'percent_run': readTag(main_plc['address'], 'GAUGEOFF_Percent_Run')[0], + 'polished_rod_hp_average': readTag(main_plc['address'], 'GAUGEOFF_Polished_Rod_HP')[0], + 'pump_hp_average': readTag(main_plc['address'], 'GAUGEOFF_Production_Calculated')[0], + 'production_total': readTag(main_plc['address'], 'GAUGEOFF_Pump_HP')[0], + 'pump_intake_pressure_average': readTag(main_plc['address'], 'GAUGEOFF_Pump_Intake_Pressure')[0], + 'surface_stroke_length_average': readTag(main_plc['address'], 'GAUGEOFF_Surface_StrokeLength')[0], + 'tubing_movement_average': readTag(main_plc['address'], 'GAUGEOFF_Tubing_Movement')[0] + } + except Exception as e: + print("Could not get all gauge off tags: {}".format(e)) + return False + post_req = requests.post(API_BASE_URL + "/gauge_off_vals", data=json.dumps(gaugeOffData), headers={'Content-Type': 'application/json'}, verify=False) + try: + post_res_id = json.loads(post_req.text)['_id'] + return True + except Exception as e: + print("Did not get a valid JSON object back, got: {}".format(post_req.text)) + return False def evalTapers(): return True @@ -225,7 +241,7 @@ def evalTapers(): # # tStr = "{{'taper':{}, 'length': {}, 'diameter': {}, 'material':'{}'}}".format(t, taper_length, taper_diameter, taper_material) # tQuery = 'INSERT INTO well_config (tstamp, type, val) VALUES ({}, "taper", "{}")'.format(ts, tStr) -# print tQuery +# print(tQuery) # con.connect() # cur = con.cursor() # cur.execute(tQuery) @@ -237,26 +253,82 @@ def evalTapers(): # cur = con.cursor() # cur.execute(cfgQuery) # con.commit() -# print "TAPER DATA READ!" +# print("TAPER DATA READ!") # return True +def readPoints(): + global main_plc + num_points = readTag(main_plc['address'], "Card_Past[1].Num_Points")[0] + surf_pos = readArray(main_plc['address'], "Card_Past[1].Surface_Position", num_points + 1)[1:] + surf_pos.append(surf_pos[0]) + surf_lod = readArray(main_plc['address'], "Card_Past[1].Surface_Load", num_points + 1)[1:] + surf_lod.append(surf_lod[0]) + down_pos = readArray(main_plc['address'], "Card_Past[1].Downhole_Position", num_points + 1)[1:] + down_pos.append(down_pos[0]) + down_lod = readArray(main_plc['address'], "Card_Past[1].Downhole_Load", num_points + 1)[1:] + down_lod.append(down_lod[0]) + return([surf_pos, surf_lod, down_pos, down_lod]) + + +def checkCardDataAndStore(last_card_id): + ''' + Check to see if a new stroke has been made and stores the stroke in the database. + Returns the current ID of the card + ''' + + global maps, main_plc, API_BASE_URL + + try: + current_card_id = readTag(main_plc['address'], 'Card_Past[1].ID')[0] + if not (last_card_id == current_card_id): + [surface_position, surface_load, downhole_position, downhole_load] = readPoints() + card_type = maps['card_type_map'][readTag(main_plc['address'], 'Card_Past[1].Card_Type')[0]] + + card_data = { + 'stroke_number': current_card_id, + 'stroke_type': card_type, + 'surf_pos': str(surface_position), + 'surf_lod': str(surface_load), + 'down_pos': str(downhole_position), + 'down_lod': str(downhole_load) + } + r = requests.post('{}/cards'.format(API_BASE_URL), data=json.dumps(card_data), headers={'Content-Type': 'application/json'}, verify=False) + resp = json.loads(r.text) + print("CARD NUMBER {} READ AT {}!".format(resp["stroke_number"], resp['created_on'])) + last_card_id = current_card_id + return current_card_id + else: + return last_card_id + except Exception as e: + print("Exception during checkCardDataAndStore: {}".format(e)) + return last_card_id + def main(): global main_plc, device_types main_plc = getMainPLC() - readConfig() + + rc_attempts = 0 + rc = readConfig() + while not rc and rc_attempts < 10: + rc = readConfig() + + device_type_attempts = 0 device_types = getDeviceTypes() + while not device_types and attempts < 10: + device_types = getDeviceTypes() + if setupTags(): pass else: print("Unable to read tags... Restarting.") main() - status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'], ip_address=main_plc['address'], device_type=device_types[main_plc['device_type']['id']]) + status = Status('run_status', 'Pump.Run_Status', 0, 'STRING', 0, 3600, mapFn=maps['statusMap'], ip_address=main_plc['address'], device_type=device_types[main_plc['device_type']['_id']]) read_tapers = False already_gauged_off = False already_entered_well_test = False - last_stroke = 0 + last_card_id = 0 last_status = "" statusChanged = False @@ -266,97 +338,49 @@ def main(): statusChanged = not (current_status == last_status) if statusChanged: last_status = current_status - ############# - # CARD DATA # - ############# - stroke_tags['Card ID'].read('test') - if not (last_stroke == stroke_tags['Card ID'].value): - sData = {} - last_stroke = stroke_tags['Card ID'].value - for t in stroke_tags: - if not t == "Card ID": - stroke_tags[t].read(True) - [sData['Surface_Position'], sData['Surface_Load'], sData['Downhole_Position'], sData['Downhole_Load']] = readPoints() + last_card_id = checkCardDataAndStore(last_card_id) - sData["card_type"] = stroke_tags['Card Type'].value - sData["card_id"] = stroke_tags['Card ID'].value - sData['sp_string'] = ', '.join(map(str, sData['Surface_Position'])) - sData['sl_string'] = ', '.join(map(str, sData['Surface_Load'])) - sData['dp_string'] = ', '.join(map(str, sData['Downhole_Position'])) - sData['dl_string'] = ', '.join(map(str, sData['Downhole_Load'])) - - card_ins_req_data = { - 'card_id': sData['card_id'], - 'card_type': sData['card_type'], - 'surface_position': sData['sp_string'], - 'surface_load': sData['sl_string'], - 'downhole_position': sData['dp_string'], - 'downhole_load': sData['dl_string'] - } - r = requests.post('{}/card'.format(web_address), data=card_ins_req_data, verify=False) - resp = json.loads(r.text) - print "CARD NUMBER {} READ AT {}!".format(resp["card_id"], resp['createdAt']) - - ################### - # HISTORICAL DATA # - ################### - - for hist in history_tags: - h = history_tags[hist] - h.read("test") - - for cust in custom_tags: - t = custom_tags[cust] - t.read("test") - - ############## - # TAPER DATA # - ############## + # read tags in tag_list and store if values require saving + for t in tag_list: + tag = tag_list[t] + tag.read(save_all) + # check if taper data has changed and store taper parameters if it has update_taper = readTag(main_plc['address'], "Write_Tapers")[0] > 0 if (update_taper == 0): if read_tapers: read_tapers = False - print "Update Tapers = False" + print("Update Tapers = False") if (update_taper and (not read_tapers)): - print "reading taper file" + print("reading taper file") read_tapers = evalTapers() - ################## - # GAUGE OFF DATA # - ################## + # store gauge-off data once it is set gauge_off = readTag(main_plc['address'], "Gauge_Off_Command")[0] if (gauge_off == 0): if already_gauged_off: already_gauged_off = False - print "Already gauged off... Setting gauge_off to False" + print("Already gauged off... Setting gauge_off to False") if (gauge_off and (not already_gauged_off)): - print "Gauging off..." - for goff in gaugeoff_tags: - g = gaugeoff_tags[goff] - g.read(True) - - already_gauged_off = True - print "Gauged off!" - - ################## - # WELL TEST DATA # - ################## + print("Gauging off...") + already_gauged_off = readGaugeOffData() + print("Gauged off!") + # well_test_entered = readTag(main_plc['address'], "Well_Test.Test_Submit")[0] > 0 if well_test_entered: if already_entered_well_test: already_entered_well_test = False - print "Already entered well Test... Setting well_test_entered to False" + print("Already entered well Test... Setting well_test_entered to False") if (well_test_entered and (not already_entered_well_test)): for wtest in welltest_tags: w = welltest_tags[wtest] w.read(True) already_entered_well_test = True - print "Well Test Stored!" + print("Well Test Stored!") ################### # ALARMS & EVENTS # @@ -368,7 +392,7 @@ def main(): bit_tags[b].checkStatus(stroke_tags['Card ID'].value) time.sleep(.20) - except Exception, e: + except Exception as e: print("Error during loop: {}".format(e)) traceback.print_exc() if __name__ == '__main__': From 00c04636c829cbf1bdbbc65422de6a07378c9d03 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Tue, 15 Nov 2016 11:21:52 -0600 Subject: [PATCH 21/23] Fixes error using stroke_tags --- dataLogger.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/dataLogger.py b/dataLogger.py index 347ff5f..edc2a08 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -386,10 +386,10 @@ def main(): # ALARMS & EVENTS # ################### for t in safety_tags: - safety_tags[t].checkStatus(stroke_tags['Card ID'].value) + safety_tags[t].checkStatus(last_card_id) for b in bit_tags: - bit_tags[b].checkStatus(stroke_tags['Card ID'].value) + bit_tags[b].checkStatus(last_card_id) time.sleep(.20) except Exception as e: From 6f4f925f76b5d71bb48f38d7d383ef3d99005e34 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 17 Nov 2016 16:20:03 -0600 Subject: [PATCH 22/23] updates gauge off url --- dataLogger.py | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/dataLogger.py b/dataLogger.py index edc2a08..e92275d 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -216,7 +216,7 @@ def readGaugeOffData(): print("Could not get all gauge off tags: {}".format(e)) return False - post_req = requests.post(API_BASE_URL + "/gauge_off_vals", data=json.dumps(gaugeOffData), headers={'Content-Type': 'application/json'}, verify=False) + post_req = requests.post(API_BASE_URL + "/gauge_off", data=json.dumps(gaugeOffData), headers={'Content-Type': 'application/json'}, verify=False) try: post_res_id = json.loads(post_req.text)['_id'] return True From 387e08d5bda3469b06e3729ef84db2d50df3087c Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Fri, 18 Nov 2016 14:32:07 -0600 Subject: [PATCH 23/23] Attempts to save some space by rounding points in cards to 2 digits --- dataLogger.py | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/dataLogger.py b/dataLogger.py index e92275d..265cbf8 100644 --- a/dataLogger.py +++ b/dataLogger.py @@ -260,12 +260,20 @@ def readPoints(): global main_plc num_points = readTag(main_plc['address'], "Card_Past[1].Num_Points")[0] surf_pos = readArray(main_plc['address'], "Card_Past[1].Surface_Position", num_points + 1)[1:] + if len(surf_pos) > 1: + surf_pos = [round(i,2) for i in surf_pos] surf_pos.append(surf_pos[0]) surf_lod = readArray(main_plc['address'], "Card_Past[1].Surface_Load", num_points + 1)[1:] + if len(surf_lod) > 1: + surf_lod = [round(i,2) for i in surf_lod] surf_lod.append(surf_lod[0]) down_pos = readArray(main_plc['address'], "Card_Past[1].Downhole_Position", num_points + 1)[1:] + if len(down_pos) > 1: + down_pos = [round(i,2) for i in down_pos] down_pos.append(down_pos[0]) down_lod = readArray(main_plc['address'], "Card_Past[1].Downhole_Load", num_points + 1)[1:] + if len(down_pos) > 1: + down_pos = [round(i,2) for i in down_pos] down_lod.append(down_lod[0]) return([surf_pos, surf_lod, down_pos, down_lod])