From f0f94aaa0fbe7f347d29c7838be464a2e8c964d1 Mon Sep 17 00:00:00 2001 From: Patrick McDonagh Date: Thu, 7 Apr 2016 14:39:12 -0500 Subject: [PATCH] added Tag classes for MySQL and SQLite --- python/mysql_cfg.pickle | 14 ++++++ python/pickle_mysql_config.py | 10 +++++ python/tag_mysql.py | 82 +++++++++++++++++++++++++++++++++++ python/tag_sqlite.py | 79 +++++++++++++++++++++++++++++++++ python/tagserver_MySQL.py | 78 ++++++++++++--------------------- python/tagserver_SQLite.py | 10 ++--- 6 files changed, 218 insertions(+), 55 deletions(-) create mode 100644 python/mysql_cfg.pickle create mode 100644 python/pickle_mysql_config.py create mode 100644 python/tag_mysql.py create mode 100644 python/tag_sqlite.py diff --git a/python/mysql_cfg.pickle b/python/mysql_cfg.pickle new file mode 100644 index 0000000..b5c07ec --- /dev/null +++ b/python/mysql_cfg.pickle @@ -0,0 +1,14 @@ +(dp0 +S'host' +p1 +S'127.0.0.1' +p2 +sS'password' +p3 +S'henrypump' +p4 +sS'user' +p5 +S'website' +p6 +s. \ No newline at end of file diff --git a/python/pickle_mysql_config.py b/python/pickle_mysql_config.py new file mode 100644 index 0000000..bf2701d --- /dev/null +++ b/python/pickle_mysql_config.py @@ -0,0 +1,10 @@ +import pickle + +mysql_cfg = { + 'host':'127.0.0.1', + 'user':'website', + 'password':'henrypump' +} + +with open('mysql_cfg.pickle', 'wb') as pickleconfig: + pickle.dump(mysql_cfg, pickleconfig) diff --git a/python/tag_mysql.py b/python/tag_mysql.py new file mode 100644 index 0000000..aa84957 --- /dev/null +++ b/python/tag_mysql.py @@ -0,0 +1,82 @@ +#! /usr/bin/python + +from datetime import datetime +import time +import mysql.connector as mysqlcon +from pycomm.ab_comm.clx import Driver as ClxDriver +import micro800 as u800 +import traceback +import pickle + +with open('mysql_cfg.pickle', 'rb') as cfgFile: + mysql_cfg = pickle.load(cfgFile) + con = mysqlcon.connect(**mysql_cfg) + + +def readTag(addr, tag): + time.sleep(0.01) + c = ClxDriver() + if c.open(addr): + try: + v = c.read_tag(tag) + # print(v) + return v + except Exception: + print("ERROR RETRIEVING TAG: {}".format(tag)) + err = c.get_status() + c.close() + print err + pass + c.close() + +class Tag(): + global readTag, con + + def __init__(self, name, tag, data_type, change_threshold, guarantee_sec, mapFn=None, plc_type='CLK'): + self.name = name + self.tag = tag + self.data_type = data_type + self.value = None + self.last_value = None + self.guarantee_sec = guarantee_sec + self.chg_threshold = change_threshold + self.last_send_time = 0 + self.mapFn = mapFn + self.plc_type = plc_type + self.readFn = readTag + if self.plc_type == "u800": + self.readFn = u800.readTag + + def read(self, forceSend): + writeToDB = False + if self.tag: + v = readFn(PLC_IP_ADDRESS, self.tag) + if v: + if self.data_type == 'BOOL' or self.data_type == 'STRING': + val = v[0] + if self.mapFn: + val = self.mapFn[val] + if (self.last_send_time == 0) or (self.value is None) or not (self.value == val) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend): + self.last_value = self.value + self.value = val + writeToDB = True + else: + writeToDB = False + else: + if (self.last_send_time == 0) or (self.value is None) or (abs(self.value - v[0]) > self.chg_threshold) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend): + self.last_value = self.value + self.value = v[0] + writeToDB = True + else: + writeToDB = False + if writeToDB: + self.sendToDB() + + def sendToDB(self): + query = "INSERT INTO tag_vals (dtime, name, val) VALUES ({}, '{}', {})".format(time.time(), self.name, self.value) + print query + # TODO: CHECK ON THIS LOGIC -- with con: + cur = con.cursor() + cur.execute(query) + con.commit() + cur.close() diff --git a/python/tag_sqlite.py b/python/tag_sqlite.py new file mode 100644 index 0000000..ba7e5fc --- /dev/null +++ b/python/tag_sqlite.py @@ -0,0 +1,79 @@ +#! /usr/bin/python +from datetime import datetime +import time +import sqlite3 as lite +from pycomm.ab_comm.clx import Driver as ClxDriver +import micro800 as u800 +import traceback +import pickle + +con = lite.connect("/mnt/usb/data.db") +# con = lite.connect("/Users/patrickjmcd/Desktop/data.db") + + +def readTag(addr, tag): + time.sleep(0.01) + c = ClxDriver() + if c.open(addr): + try: + v = c.read_tag(tag) + return v + except Exception: + print("ERROR RETRIEVING TAG: {}".format(tag)) + err = c.get_status() + c.close() + print err + pass + c.close() + +class Tag(): + global readTag, con + + def __init__(self, name, tag, data_type, change_threshold, guarantee_sec, mapFn=None, plc_type='CLK'): + self.name = name + self.tag = tag + self.data_type = data_type + self.value = None + self.last_value = None + self.guarantee_sec = guarantee_sec + self.chg_threshold = change_threshold + self.last_send_time = 0 + self.mapFn = mapFn + self.plc_type = plc_type + self.readFn = readTag + if self.plc_type == "u800": + self.readFn = u800.readTag + + def read(self, forceSend): + writeToDB = False + if self.tag: + v = readFn(PLC_IP_ADDRESS, self.tag) + if v: + if self.data_type == 'BOOL' or self.data_type == 'STRING': + val = v[0] + if self.mapFn: + val = self.mapFn[val] + if (self.last_send_time == 0) or (self.value is None) or not (self.value == val) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend): + self.last_value = self.value + self.value = val + writeToDB = True + else: + writeToDB = False + else: + if (self.last_send_time == 0) or (self.value is None) or (abs(self.value - v[0]) > self.chg_threshold) or ((time.time() - self.last_send_time) > self.guarantee_sec) or (forceSend): + self.last_value = self.value + self.value = v[0] + writeToDB = True + else: + writeToDB = False + if writeToDB: + self.sendToDB() + + def sendToDB(self): + query = "INSERT INTO tag_vals (dtime, name, val) VALUES ({}, '{}', {})".format(time.time(), self.name, self.value) + print query + # TODO: CHECK ON THIS LOGIC -- with con: + cur = con.cursor() + cur.execute(query) + con.commit() + cur.close() diff --git a/python/tagserver_MySQL.py b/python/tagserver_MySQL.py index 48b7a18..0754035 100644 --- a/python/tagserver_MySQL.py +++ b/python/tagserver_MySQL.py @@ -1,70 +1,48 @@ #!/usr/bin/env python ''' -Created on Dec 8, 2015 - +MySQL Tag Server +Created on April 7, 2016 @author: Patrick McDonagh +@description: Continuously loops through a list of tags to store values from a PLC into a MySQL database ''' +import mysql.connector as mysqlcon +import pickle +from tag_mysql import Tag +import traceback +with open('mysql_cfg.pickle', 'rb') as pickleconfig: + mysql_cfg = pickle.load(pickleconfig) -from datetime import datetime -import sys -from random import randint -import time -import MySQLdb -import tuxeip - - -#TUXEIP Connection to PLC -from tuxeip import TuxEIP, LGX, LGX_REAL - - +if mysql_cfg: + db = mysqlcon.connect(**mysql_cfg) +tag_store = {} def main(): - - db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="TagData") + db.connect() cur = db.cursor() - query = "SELECT * FROM TagData.tags WHERE deleted = 0;" + query = "SELECT * FROM poconsole.tags" cur.execute(query) tags = cur.fetchall() - # ((1L, 'DC_Bus_Voltage', datetime.datetime(2015, 12, 8, 16, 2, 32), 'V', 0L), (2L, 'Output_Frequency', datetime.datetime(2015, 12, 8, 16, 31, 12), 'Hz', 0L)) - db.commit() - db.close() + #(1, u'card_type', 1, u'Card_Past[1].Card_Type', u'STRING', 0.0, 3600, u'card_type_map') + db.disconnect() + + for t in tags: + tag_store[t[1]] = Tag(t[1], t[2], t[3], t[4], t[5], mapFn=t[6]) + PLC_IP_ADDRESS = "10.10.10.3" # MAKE THIS A db VALUE scan_rate = 10 - tagList = []; - if len(tags) > 0: - for t in tags: - tagList.append({"id":int(t[0]), "name":t[1], "val":None, "lastVal":None}); + while True: + for tag in tag_store: + try: + tag_store[tag].read(False) + except: + print("ERROR EVALUATING {}".format(tag)) + traceback.print_exc() + time.sleep(scan_rate) - try: - tux = TuxEIP(libpath="/usr/lib/libtuxeip.so") - sess = tux.OpenSession(PLC_IP_ADDRESS) - reg = tux.RegisterSession(sess) - conn = tux.ConnectPLCOverCNET(sess, LGX, 1, 100, 123, randint(0,9999), 123, 321, 100, 5000, 1, '01') - - while True: - for r in tagList: - r["val"] = tux.ReadLGXDataAsFloat(sess, conn, r['name'], 1)[0] - print("{0} - {1}".format(r["name"], r["val"])) - if not r["val"] == r["lastVal"]: - db = MySQLdb.connect(host="127.0.0.1",user="website",passwd="henrypump",db="TagData") - cur = db.cursor() - aQuery = """INSERT INTO TagData.values (tagID, val) VALUES ('%d', '%f');"""%(r["id"], float(r["val"])) - print(aQuery) - storeVal = cur.execute(aQuery) - db.commit() - db.close() - r["lastVal"] = r["val"] - - time.sleep(10) - except Exception as err: - print err - pass - - if __name__ == '__main__': main() diff --git a/python/tagserver_SQLite.py b/python/tagserver_SQLite.py index 451db48..4989455 100644 --- a/python/tagserver_SQLite.py +++ b/python/tagserver_SQLite.py @@ -18,11 +18,11 @@ con = lite.connect('/mnt/usb/data.db') configProperties = {} def readTag(addr, tag): - logging.basicConfig( - filename="ClxDriver.log", - format="%(levelname)-10s %(asctime)s %(message)s", - level=logging.DEBUG - ) + # logging.basicConfig( + # filename="ClxDriver.log", + # format="%(levelname)-10s %(asctime)s %(message)s", + # level=logging.DEBUG + # ) c = ClxDriver() if c.open(addr):