From 77082c62cab38dec8b80081567bfb01c255e7214 Mon Sep 17 00:00:00 2001 From: Philipp Rauch Date: Mon, 17 Mar 2014 17:25:53 +0100 Subject: [PATCH] commnets bugfix --- API/buffer.py | 2 +- API/service.py | 19 +-- CAN/Filter.py | 36 ++++-- Connector/modules/database.py | 4 +- Connector/modules/modbus.py | 8 +- Connector/switch.py | 2 - src/can.py | 4 + src/config/Symboldatei_multiport_neu.sym | 149 +++++++++++++++++++++++ src/config/ems.conf | 6 +- src/ems.py | 1 + src/pac.py | 105 +++++++++------- src/run.py | 32 +++-- 12 files changed, 293 insertions(+), 75 deletions(-) create mode 100644 src/config/Symboldatei_multiport_neu.sym diff --git a/API/buffer.py b/API/buffer.py index 4eae55a..84de45a 100644 --- a/API/buffer.py +++ b/API/buffer.py @@ -31,7 +31,7 @@ class Buffer(object): system = { '00_config' : conf, '0_request' : [], - '0_done' : [], + '0_result' : [], 'device' : {}, 'error' : error } diff --git a/API/service.py b/API/service.py index 18d1498..639e39d 100644 --- a/API/service.py +++ b/API/service.py @@ -22,7 +22,9 @@ api_url = 'http://%s:%s' % (api_host, conf['flask_port']) #buf = Buffer() class Request(object): - + ''' + request definition for buffer + ''' def __init__(self, path, time, req_id): self.content = path self.time = time @@ -86,10 +88,10 @@ class REST(object): del l[-1] # remove it out = self.buf.get_level(l) elif 'dyn' == l[-1]: - args = request.args # returns a dictionary with a list of values for each key - # each value and each key is represented as a string - # to convert it to a dictionary use to_dict(flat=False) - # to_dict(flat=True) returns the key and the first item of the value list. + args = request.args.to_dict(flat=False) # returns a dictionary with a list of values for each key + # each value and each key is represented as a string + # to convert it to a dictionary use to_dict(flat=False) + # to_dict(flat=True) returns the key and the first item of the value list. out = self.buf.foo(l, args) else: #req = add_reqest(path) @@ -103,17 +105,20 @@ class REST(object): return jsonify( out ) def add_reqest(self, path): + ''' + build a request and add it to list + ''' notinlist = False time = datetime.now() req_id = Buffer._id tmp = Request(path, time, req_id) try: - Buffer.system['request'].index(tmp) + Buffer.system['0_request'].index(tmp) except ValueError: notinlist = True if notinlist: - Buffer.system['request'].insert(0, tmp) + Buffer.system['0_request'].insert(0, tmp) return id else: return False diff --git a/CAN/Filter.py b/CAN/Filter.py index ca92a06..b2bf74c 100644 --- a/CAN/Filter.py +++ b/CAN/Filter.py @@ -19,11 +19,17 @@ debug = True intervall = 100 def CAN_start(conf): + ''' + start CAN communication + ''' print 'starte CAN mit Baud von', conf['can_baudrate'] can = CANFilter(conf) can.start() def get_DataFrameDict(symfile): + ''' + generate a from a symfile a dictionary with all messages and DataFrames + ''' mes = readSym(symfile) symDict = _get_easy_Dict_(mes) dfDict = {} @@ -33,16 +39,22 @@ def get_DataFrameDict(symfile): class CANFilter(Thread): - ### Lookup für CAN --> DB ### + ### Lookup for CAN --> DB ### lookup = { - 'U_IST_WERT' : 'GRIDManager_U_IST', - 'I_IST_WERT' : 'GRIDManager_I_IST', - 'TEMPEARTUR' : 'GRIDManager_Temperatur', - 'STATUS_FPGA' : 'GRIDManager_Status', - 'I_PH_WERT' : 'GRIDManager_I_PH' + 'U_IST_WERT' : 'U_IST', + 'I_IST_WERT' : 'I_IST', + 'TEMPEARTUR' : 'temperature', + 'STATUS_FPGA' : 'status', + 'I_PH_WERT' : 'I_PH' } + prefix = "GRIDManager_" + postfix = "_neu" def __init__(self, conf): + ''' + Initialize database and pcan adapter + and a list of DataFrameDicts + ''' Thread.__init__(self) self.conf = conf @@ -73,13 +85,16 @@ class CANFilter(Thread): Add2Adapter(self.pcan, sym) def run(self): + ''' + get message and write it to database + ''' while True: receiveMessageName = self.pcan.receiveMessage(block = True) try: - tablename = self.lookup[receiveMessageName] + tablename = "%s%s%s" % (self.prefix, self.lookup[receiveMessageName], self.postfix) except: - tablename = receiveMessageName + tablename = "%s%s%s" % (self.prefix, receiveMessageName, self.postfix) # if receiveMessageName is None or self.pcan.Messages[receiveMessageName].getFlag('RECEIVE'): # continue @@ -106,9 +121,8 @@ class CANFilter(Thread): #res.drop('isCharging', axis = 1, inplace = True) res['DateTime'] = datetime.now() - #self.db.writeDatabase(self.lookup[receiveMessageName], res) + #self.db.writeDatabase(strTable=self.lookup[receiveMessageName], dfData=res, bClear=False) self.db.writeDatabase(strTable=tablename, dfData=res, bClear=False) sym[receiveMessageName] = sym[receiveMessageName].drop(sym[receiveMessageName].index[:]) print "%s - Write to DB - %s" % (res['DateTime'][0], tablename) - - #sleep(0.01) + sleep(0.01) diff --git a/Connector/modules/database.py b/Connector/modules/database.py index 2ab99d6..f49c46e 100644 --- a/Connector/modules/database.py +++ b/Connector/modules/database.py @@ -5,6 +5,7 @@ Created on 26.11.2013 ''' from profile.database import Database +### Dict of Tables to sort after ### _sort_lookup = { 'EA_Last' : 'DateTime', 'GRIDManager_I_IST' : 'DateTime', 'GRIDManager_I_PH' : 'DateTime', @@ -32,7 +33,8 @@ def setup(conf): def loop(db, item): ''' - + get the last line of the table 'item' in database + and return it ''' path = item.split('/') if path[0] == '': diff --git a/Connector/modules/modbus.py b/Connector/modules/modbus.py index 483d2d0..06f4aaa 100644 --- a/Connector/modules/modbus.py +++ b/Connector/modules/modbus.py @@ -16,8 +16,10 @@ _csv_lookup = { 'offset' : 'offset', 'name' : 'Value name', 'time_offset' : 797} - def setup(conf): + ''' + load message definition and connect to all pacs + ''' PACS = [] csv = '%s/%s' % (conf['config_dictionary'], conf['pac_csvfile']) @@ -41,6 +43,10 @@ def setup(conf): return PACS def loop(PACS, item): + ''' + get value of message and convert it to the right datatype + return the result + ''' row = PACS[0][PACS[0][_csv_lookup['offset']] == item[1]] inx = row.index.values[0] diff --git a/Connector/switch.py b/Connector/switch.py index e857bfa..feb6921 100644 --- a/Connector/switch.py +++ b/Connector/switch.py @@ -37,8 +37,6 @@ class Switch(Thread): ''' initialize the swich with the given source and creates a sql_queue and a sql_query it calls the setup method from the submodule of the source - - @return: sql_queue and sql_query ''' try: self.cursor = self.source.setup(conf) diff --git a/src/can.py b/src/can.py index aa47bb2..a925233 100644 --- a/src/can.py +++ b/src/can.py @@ -10,4 +10,8 @@ from CAN.Filter import CAN_start c = config() conf = c.readConf() +''' +File to only start CAN communication. +''' + CAN_start(conf) \ No newline at end of file diff --git a/src/config/Symboldatei_multiport_neu.sym b/src/config/Symboldatei_multiport_neu.sym new file mode 100644 index 0000000..b62374a --- /dev/null +++ b/src/config/Symboldatei_multiport_neu.sym @@ -0,0 +1,149 @@ +FormatVersion=5.0 // Do not edit! +Title="Symboldatei_multiport" + +{ENUMS} +enum CTRL_MODE(1="LSI", 2="HSI", 4="HSU", 8="LSU", 0="OFF") +enum FF_MODE(0="HSU", 1="LSU", 2="HSI", 3="LSI") +enum PH_MODE(0="OFF", 1="REFA", 2="REFB") +enum ERROR_CODE(0="NO ERROR", 1="DCDC_LOCKED", + 10="ERR_HSUMAXUL_OUTOF_HWLIMITS", 11="ERR_HSUMINUL_OUTOF_HWLIMITS", + 12="ERR_LSUMAXUL_OUTOF_HWLIMITS", 13="ERR_LSUMINUL_OUTOF_HWLIMITS", + 14="ERR_LSIMAXUL_OUTOF_HWLIMITS", 15="ERR_LSIMINUL_OUTOF_HWLIMITS", + 16="ERR_HSIMAXUL_OUTOF_HWLIMITS", 17="ERR_HSIMINUL_OUTOF_HWLIMITS", + 50="ERR_HSUVALUE_OUTOF_ULIMITS", 51="ERR_LSUVALUE_OUTOF_ULIMITS", + 52="ERR_LSIVALUE_OUTOF_ULIMITS", 53="ERR_HSIVALUE_OUTOF_ULIMITS", + 60="ERR_WRONG_CTRL_MODE", 61="ERR_WRONG_PM", 62="ERR_WRONG_FEED_MODE", + 124="ERR_CONTROLMSG_NO_MODE_SELECTED") + +{SEND} + +[PH1_SOLL] +ID=040h +DLC=8 +CycleTime=100 +Var=PH1_CTRLMODE_S CTRL_MODE 0,4 +Var=PH1_SOLLWERT signed 8,16 +Var=PH1_SOLLGAIN signed 24,16 +Var=PH1_SOLLOFFSET signed 40,16 + +[PH2_SOLL] +ID=080h +DLC=8 +CycleTime=100 +Var=PH2_CTRLMODE_S CTRL_MODE 0,4 +Var=PH2_SOLLWERT signed 8,16 +Var=PH2_SOLLGAIN signed 24,16 +Var=PH2_SOLLOFFSET signed 40,16 + +[STATE] +ID=0C0h +DLC=8 +CycleTime=100 +Var=PH1_CTRLMODE CTRL_MODE 0,4 +Var=ENABLE unsigned 13,1 +Var=BOOST bit 14,1 +Var=BUCK bit 15,1 +Var=PH1_FFMODE FF_MODE 8,2 +Var=PH1_MODE PH_MODE 16,2 +Var=PH2_MODE PH_MODE 18,2 +Var=PH3_MODE PH_MODE 20,2 +Var=PH4_MODE PH_MODE 22,2 +Var=PH_WIRKUNG signed 24,16 /d:5000 +Var=PH_MAX signed 40,16 /d:10000 +Var=ph_config_apply unsigned 12,1 +Var=PH2_CTRLMODE CTRL_MODE 4,4 +Var=PH2_FFMODE FF_MODE 10,2 +Var=RESETERROR unsigned 56,8 + +[HS_LIMIT] +ID=100h +DLC=8 +CycleTime=100 +Var=HSI_MAX signed 0,16 /u:A /f:0.01 /d:10 +Var=HSI_MIN signed 16,16 /u:A /f:0.01 /d:-10 +Var=HSU_MAX signed 32,16 /u:V /f:0.1 /d:450 +Var=HSU_MIN signed 48,16 /u:V /f:0.1 /d:0 + +[LS_LIMIT] +ID=140h +DLC=8 +CycleTime=100 +Var=LSI_MAX signed 0,16 /u:A /f:0.01 /d:10 +Var=LSI_MIN signed 16,16 /u:A /f:0.01 /d:-10 +Var=LSU_MAX signed 32,16 /u:V /f:0.1 /d:420 +Var=LSU_MIN signed 48,16 /u:V /f:0.1 /d:0 + +[PIPARAMETER] +ID=180h +DLC=8 +CycleTime=100 +Var=UParameterI signed 0,16 /d:15 +Var=UParameterP signed 16,16 /d:3000 +Var=IParameterI signed 32,16 /d:30 +Var=IParameterP signed 48,16 /d:75 + +{RECEIVE} + +[U_IST_WERT] +ID=1C0h +DLC=8 +Var=HSU signed 0,16 /u:V /f:0.1 /d:0 +Var=PH1_LSU signed 16,16 /u:V /f:0.1 +Var=PH2_LSU signed 32,16 /u:V /f:0.1 + +[I_IST_WERT] +ID=200h +DLC=8 +CycleTime=10 +Var=PH1_LSI signed 0,16 /u:A /f:0.01 +Var=PH1_HSI signed 16,16 /u:A /f:0.01 +Var=PH2_LSI signed 32,16 /u:A /f:0.01 +Var=PH2_HSI signed 48,16 /u:A /f:0.01 + +[I_PH_WERT] +ID=280h +DLC=8 +Var=PH1_STROM signed 0,16 /u:A /f:0.001 +Var=PH2_STROM signed 16,16 /u:A /f:0.001 +Var=PH3_STROM signed 32,16 /u:A /f:0.001 +Var=PH4_STROM signed 48,16 /u:A /f:0.001 + +[TEMPEARTUR] +ID=2C0h +DLC=8 +Var=TEMP1 unsigned 0,8 /u:deg /o:-60 +Var=TEMP2 unsigned 8,8 /u:deg /o:-60 +Var=TEMP3 unsigned 16,8 /u:deg /o:-60 +Var=TEMP4 unsigned 24,8 /u:deg /o:-60 +Var=TEMP5 unsigned 32,8 /u:deg /o:-60 + +[STATUS_FPGA] +ID=240h +DLC=8 +Var=PH1_HSU_MAX_LIM unsigned 0,1 +Var=PH1_HSU_MIN_LIM unsigned 1,1 +Var=PH1_LSU_MAX_LIM unsigned 2,1 +Var=PH1_LSU_MIN_LIM unsigned 3,1 +Var=PH1_HSI_MAX_LIM unsigned 4,1 +Var=PH1_HSI_MIN_LIM unsigned 5,1 +Var=PH1_LSI_MAX_LIM unsigned 6,1 +Var=PH1_LSI_MIN_LIM unsigned 7,1 +Var=PH2_HSU_MAX_LIM unsigned 8,1 +Var=PH2_HSU_MIN_LIM unsigned 9,1 +Var=PH2_LSU_MAX_LIM unsigned 10,1 +Var=PH2_LSU_MIN_LIM unsigned 11,1 +Var=PH2_HSI_MAX_LIM unsigned 12,1 +Var=PH2_HSI_MIN_LIM unsigned 13,1 +Var=PH2_LSI_MAX_LIM unsigned 14,1 +Var=PH2_LSI_MIN_LIM unsigned 15,1 +Var=G_EN unsigned 16,1 +Var=USR_EN unsigned 17,1 +Var=INTERLOCK unsigned 18,1 +Var=LS_OV unsigned 19,1 +Var=HS_OV unsigned 20,1 +Var=PH1_OC unsigned 21,1 +Var=PH2_OC unsigned 22,1 +Var=PH3_OC unsigned 23,1 +Var=PH4_OC unsigned 24,1 +Var=ERROR unsigned 32,8 /e:ERROR_CODE + diff --git a/src/config/ems.conf b/src/config/ems.conf index 693850f..7b0bd95 100644 --- a/src/config/ems.conf +++ b/src/config/ems.conf @@ -16,9 +16,9 @@ config_debug = True # default False #### CAN #### ## possible Baud Rates: 100k, 125k, 250k, 500k, 1000k ## can_baudrate = 500k # default 500k -can_symfile = Symboldatei_multiport.sym #ems-test.sym +can_symfile = Symboldatei_multiport_neu.sym #ems-test.sym #### PAC #### -pac_ip = 10.2.6.6 # 10.2.6.5, 10.2.6.6, 10.2.6.7, 10.2.6.8 +pac_ip = 10.2.6.7 # 10.2.6.5, 10.2.6.6, 10.2.6.7, 10.2.6.8 pac_csvfile = pacs.csv # only one file allowed -pac_messages = 797, 1, 3, 5, 13, 15, 17, 25, 27, 29 #, 31, 33, 35 +pac_messages = 797, 1, 3, 5, 13, 15, 17, 25, 27, 29, 31, 33, 35 diff --git a/src/ems.py b/src/ems.py index 48ce85a..b1f66a0 100644 --- a/src/ems.py +++ b/src/ems.py @@ -86,6 +86,7 @@ class ems(Thread): def getRequest(self): ''' + get request and pass to database ''' try: req = self.buffer.system['request'].pop() diff --git a/src/pac.py b/src/pac.py index 2e56727..b2fdabf 100644 --- a/src/pac.py +++ b/src/pac.py @@ -3,57 +3,78 @@ Created on 21.11.2013 @author: Philipp Rauch ''' -from Config.parser import config + from Connector.switch import Switch, MODBUS -from time import sleep +#from time import sleep +from threading import Thread from datetime import datetime from profile.database import Database from profile.datasheet import Datasheet from pandas import DataFrame import numpy -### LOAD CONFIG ### -c = config() -conf = c.readConf() +def PAC_start(conf): + print 'starte PAC-Verbindung' + pac = modbus_pac(conf) + pac.start() -### LOAD DATABASE ### -db = Database() -db.loadDatabase(strHost = conf['mySQL_server'], - intPort = int(conf['mySQL_port']), - strUser = conf['mySQL_user'], - strPasswd = conf['mySQL_pass'], - strDatabase = conf['mySQL_database'], - strTable = None) +class modbus_pac(Thread): + def __init__(self, conf): + ''' + Initialize database and mask for res_data. + Generating modbus Object + ''' + Thread.__init__(self) + self.conf = conf -### READ CSV ### -csv = '%s/%s' % (conf['config_dictionary'], conf['pac_csvfile']) -pac_csv = Datasheet() -pac_csv.loadDatasheet(strFile = csv) -messages = pac_csv.readDatasheet() + ### LOAD DATABASE ### + self.db = Database() + self.db.loadDatabase(strHost = self.conf['mySQL_server'], + intPort = int(self.conf['mySQL_port']), + strUser = self.conf['mySQL_user'], + strPasswd = self.conf['mySQL_pass'], + strDatabase = self.conf['mySQL_database'], + strTable = None) -### GENERATE LIST OF COLUMNS ### -col = [] -for item in conf['pac_messages']: - row = messages[messages['offset'] == int(item)] - inx = row.index.values[0] - col.append(row.get('Value name')[inx]) + ### READ CSV ### + csv = '%s/%s' % (self.conf['config_dictionary'], self.conf['pac_csvfile']) + pac_csv = Datasheet() + pac_csv.loadDatasheet(strFile = csv) + messages = pac_csv.readDatasheet() -### CREATE DATAFRAME ### -tab = DataFrame(columns = col) -### Modbus ### -modbus = Switch(MODBUS) -modbus.initialisiere() -print '\tTEST-QUERY:\t', modbus.query -print '\tTEST-QUEUE:\t', modbus.queue -modbus.start() -while True: - res = {} - for mes in conf['pac_messages']: - modbus.query.put([1, int(mes)]) - res.update(modbus.queue.get()) + ### GENERATE LIST OF COLUMNS ### + self.col = [] + for item in self.conf['pac_messages']: + row = messages[messages['offset'] == int(item)] + inx = row.index.values[0] + self.col.append(row.get('Value name')[inx]) - print "%s - %s" % (datetime.now(), res.keys()) - res_data = tab.append(res, ignore_index=True) - res_data[col[1::]] = res_data[col[1::]].astype(numpy.float) #till now only float support - db.writeDatabase('PAC', res_data, bClear = False) - #sleep(0.6) + ### CREATE DATAFRAME ### + self.tab = DataFrame(columns = self.col) + + ### Modbus ### + self.modbus = Switch(MODBUS) + self.modbus.initialisiere() + print '\tTEST-QUERY:\t', self.modbus.query + print '\tTEST-QUEUE:\t', self.modbus.queue + self.modbus.start() + + def run(self): + ''' + Get all results form messages defined in ems.conf + and write it do database. + ''' + while True: + res = {} + ### Get result for all messages ### + for mes in self.conf['pac_messages']: + self.modbus.query.put([1, int(mes)]) + res.update(self.modbus.queue.get()) + + print "%s - %s" % (datetime.now(), res.keys()) + + ### save one line in res_data, use self.tab as mask### + res_data = self.tab.append(res, ignore_index=True) + res_data[self.col[1::]] = res_data[self.col[1::]].astype(numpy.float) #till now only float support + self.db.writeDatabase('PAC_neu', res_data, bClear = False) + #sleep(0.6) diff --git a/src/run.py b/src/run.py index 0a809be..734e9bb 100644 --- a/src/run.py +++ b/src/run.py @@ -3,15 +3,33 @@ Created on 29.01.2014 @author: Philipp Rauch ''' -from Config.parser import config -from API.service import REST_start -#from CAN.Filter import CAN_start -### LOAD CONFIG ### +############################################################# +######################## LOAD CONFIG ######################## +## Laden der Konfigurationsdatei +############################################################# +from Config.parser import config c = config() conf = c.readConf() -# TODO : Informationen, verweise -#CAN_start(conf) -REST_start() +############################################################# +## startet die Modbus Kommunikation +############################################################# +#from pac import PAC_start +#PAC_start(conf) + + +############################################################# +## startet die CAN Kommunikation +############################################################# +from CAN.Filter import CAN_start +CAN_start(conf) + + +############################################################# +## startet die API +## - muss als letztes ausgefuehrt werden, da blockiert. +############################################################# +#from API.service import REST_start +#REST_start()