Switch modularized

*the switch is prepared to load different modules
*module database is implemented
*code cleanup
*config can load lists
*add global debug mode
*ems has a method to update the buffer
This commit is contained in:
Philipp Rauch 2013-11-28 12:41:01 +01:00
parent 8d56806c03
commit 0d0e49d684
9 changed files with 311 additions and 208 deletions

View file

@ -64,7 +64,8 @@ class Buffer(object):
'00_config' : conf,
'dc_labor' : dc_labor,
'dc_grid' : dc_grid,
'ac_grid' : ac_grid
'ac_grid' : ac_grid,
'request' : None
}
_instance = None
@ -152,7 +153,6 @@ class Buffer(object):
class API(object):
def __init__(self):
# Thread.__init__(self)
self.app = Flask(__name__)
### ADD URL RULES ###
@ -160,10 +160,8 @@ class API(object):
self.app.error_handler_spec[None][404] = not_found
self.app.error_handler_spec[None][405] = not_allowed
self.app.add_url_rule('/', 'get_root', get_root, methods = ['GET'])
self.app.add_url_rule('/<path:path>', 'get_catch_all', get_catch_all, methods = ['GET'])
# def run(self):
# self.app.run(host = conf['flask_server'], port = int(conf['flask_port']), debug = True)
self.app.add_url_rule('/<path:path>', 'get_catch_all',
get_catch_all, methods = ['GET'])
buf = Buffer()
@ -185,14 +183,14 @@ def get_root():
def get_catch_all(path):
l = path.split('/')
l.insert(0, Buffer.system)
if '' == l[-1]: # if last element of list is empty
del l[-1] # remove it
if '' == l[-1]: # if last element of list is empty
del l[-1] # remove it
out = 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 # 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 = buf.foo(l, args)
else:
out = buf.get_level(l)
@ -200,10 +198,13 @@ def get_catch_all(path):
def start():
api = API()
api.app.run(host = conf['flask_server'], port = int(conf['flask_port']), debug = conf['flask_debug'])
api.app.run(host = conf['flask_server'],
port = int(conf['flask_port']),
debug = conf['flask_debug'])
EMS = ems.ems(buf)
emsthread = EMS.start()
print 'EMS-Thread:\t', EMS
print '\tAPI:\t', buf
if conf['config_debug']:
print 'EMS-Thread:\t', EMS
print '\tAPI-BUFFER:\t', buf
start()

View file

@ -12,55 +12,52 @@ from datetime import datetime
from time import sleep
from threading import Thread
from Queue import Queue
from MySQLdb import connect
from config import Config
import database
debug = False
class CANFilter(Thread):
battery_current, battery_voltage, battery_capacity, battery_timestamp, test = [], [], [], [], [] #create tmp lists
battery_current, battery_voltage = [], []
battery_soc, battery_timestamp = [], [] #create tmp lists
### LOAD CONFIG ###
c = Config()
conf = c.readConf()
connection = connect(host = conf['mySQL_server'],
user = conf['mySQL_user'],
passwd = conf['mySQL_pass'],
db = conf['mySQL_database'],
port = int(conf['mySQL_port']))
cursor = connection.cursor()
cursor = database.setup(conf)
def __init__(self):
Thread.__init__(self)
self.queue = Queue()
self.pcan = PcanAdapter(PcanAdapter.Baudrate['250k'], debug = self.conf['config_debug'])
self.pcan = PcanAdapter(PcanAdapter.Baudrate[self.conf['can_baud']],
debug = self.conf['config_debug'])
self.pcan.initialize()
dc_battery = CanMessage(0x3A4, 8, 50, 'dc_battery')
dc_grid = CanMessage(0x3A5, 8, 50, 'dc_grid')
dc_pv = CanMessage(0x3A6, 8, 50, 'dc_pv')
dc_charging = CanMessage(0x3A7, 8, 50, 'dc_charging')
dc_charging = CanMessage(0x3A7, 8, 50, 'dc_charger')
self.pcan.addMessage(dc_battery)
self.pcan.addMessage(dc_grid)
self.pcan.addMessage(dc_pv)
self.pcan.addMessage(dc_charging)
current = CanSignal(0, 16, 0, 0.001, 0, 'current')
voltage = CanSignal(16, 16, 0, 0.01, 0, 'voltage')
capacity = CanSignal(32, 11, 0, 0.05, 0, 'capacity')
isMaster = CanSignal(56, 1, 0, 1, 0, 'isMaster')
isFeed = CanSignal(57, 1, 0, 1, 0, 'isFeed')
isCharging = CanSignal(57, 1, 0, 1, 0, 'isCharging')
isOn = CanSignal(58, 1, 0, 1, 0, 'isOn')
current = CanSignal(0, 16, 0, 0.001, 0, 'current')
voltage = CanSignal(16, 16, 0, 0.01, 0, 'voltage')
soc = CanSignal(32, 11, 0, 0.05, 0, 'soc')
isMaster = CanSignal(56, 1, 0, 1, 0, 'isMaster')
isFeed = CanSignal(57, 1, 0, 1, 0, 'isFeed')
isCharging = CanSignal(57, 1, 0, 1, 0, 'isCharging')
isOn = CanSignal(58, 1, 0, 1, 0, 'isOn')
self.pcan.Messages['dc_battery'].addSignal( current )
self.pcan.Messages['dc_battery'].addSignal( voltage )
self.pcan.Messages['dc_battery'].addSignal( capacity )
self.pcan.Messages['dc_battery'].addSignal( soc )
self.pcan.Messages['dc_battery'].addSignal( isMaster )
self.pcan.Messages['dc_battery'].addSignal( isCharging )
@ -84,29 +81,41 @@ class CANFilter(Thread):
receiveMessageId = self.pcan.receiveMessage()
if receiveMessageId == self.pcan.Messages['dc_battery'].Id:
self.battery_current.append(self.pcan.Messages['dc_battery'].Signals['current'].GetData())
self.battery_voltage.append(self.pcan.Messages['dc_battery'].Signals['voltage'].GetData())
self.battery_capacity.append(self.pcan.Messages['dc_battery'].Signals['capacity'].GetData())
self.battery_current.append(
self.pcan.Messages['dc_battery'].Signals['current'].GetData())
self.battery_voltage.append(
self.pcan.Messages['dc_battery'].Signals['voltage'].GetData())
self.battery_soc.append(
self.pcan.Messages['dc_battery'].Signals['soc'].GetData())
self.battery_timestamp.append(datetime.now())
if len(self.battery_timestamp) == 100:
if debug:
print 'current: ', self.mean(self.battery_current)
print 'voltage: ', self.mean(self.battery_voltage)
print 'SoC: ', self.mean(self.battery_capacity)
print 'SoC: ', self.mean(self.battery_soc)
print 'time: ', self.mean(self.battery_timestamp)
tabelle = 'battery'
# daten = [(tabelle, str(self.battery_timestamp[i]), str(self.battery_current[i]), str(self.battery_voltage[i]), str(self.battery_capacity[i])) for i in range(100)]
daten = (tabelle, str(self.battery_timestamp[50]), str(self.mean(self.battery_current)), str(self.mean(self.battery_voltage)), str(self.mean(self.battery_capacity)))
sql = "INSERT INTO %s VALUES (%s,%s,%s,%s)"
self.queue.put(daten[0])
list_daten = [(tabelle, str(self.battery_timestamp[i]),
str(self.battery_current[i]),
str(self.battery_voltage[i]),
str(self.battery_soc[i])) for i in range(100)]
# for i in daten:
# print sql % daten
self.cursor.execute("INSERT INTO %s VALUES (\'%s\',%s,%s,%s)" % daten)
mean_daten = (tabelle, str(self.battery_timestamp[50]),
str(self.mean(self.battery_current)),
str(self.mean(self.battery_voltage)),
str(self.mean(self.battery_soc)))
sql = "INSERT INTO %s VALUES (\'%s\',%s,%s,%s)"
self.queue.put(mean_daten[0])
self.cursor.execute(sql % mean_daten)
#self.cursor.executemany(sql, daten)
del self.battery_current[:], self.battery_voltage[:], self.battery_capacity[:], self.battery_timestamp[:] #clear tmp lists
## clear tmp lists ##
del self.battery_current[:], self.battery_voltage[:],
del self.battery_soc[:], self.battery_timestamp[:]
sleep(0.01)

View file

@ -12,7 +12,7 @@ class Config():
'mySQL_user': 'smoke',
'mySQL_pass': 'KiWujcafAlor',
'mySQL_database': 'smoke_test',
'mySQL_table': 'battery',
#'mySQL_table': 'battery',
'mySQL_speed' : '0.1',
'flask_server': '0.0.0.0',
'flask_port': '5000',
@ -34,11 +34,7 @@ class Config():
try:
confFile = open("config\ems.conf", "r")
error = False
except IOError:
error = True
if error:
self._confDic.update({'error' : 'config/ems.conf not found'})
return self._confDic
@ -48,13 +44,26 @@ class Config():
ident = line.split("=")
for i in range(len(ident)):
ident[i] = ident[i].strip()
val = ident[1].split("#") #cut off comments
val[0] = val[0].strip()
val[0] = True if val[0] == 'True' else val[0]
val[0] = False if val[0] == 'False' else val[0]
self._confDic[ident[0]] = val[0]
#comment is on val[1]
argument = str(val[0].strip()).split(',')
arg = []
for a in argument:
a.strip()
a = True if a == 'True' else a
a = False if a == 'False' else a
arg.append(a)
self._confDic[ident[0]] = arg if len(arg) > 1 else arg[0]
confFile.close()
self._confDic['config_read'] = True
if self._confDic['config_debug']:
print ('config:\t', self._confDic)
print 'config:\t{'
for x in self._confDic:
print ' ', x, '\t:', self._confDic[x]
print ' }'
return self._confDic
#c = Config()
#conf = c.readConf()

View file

@ -5,7 +5,7 @@ mySQL_port = 3306 # default 3306
mySQL_user = smoke
mySQL_pass = KiWujcafAlor
mySQL_database = smoke_test
mySQL_table = battery # only for debugging
mySQL_table = battery, grid, pv, charger
mySQL_speed = 0.1 # time between two query's in sec
#### FLASK ####
@ -16,4 +16,24 @@ flask_debug = True
#### CONFIG ####
config_debug = False
config_debug = True
#### CAN ####
#possible Baud Rates: 100k, 125k, 250k, 500k, 1000k
can_baud = 250k
#can_messages = dc_battery, dc_grid, dc_pv, dc_charger
#'dc_battery = id:0x3A4, length:8, time:50
#'dc_grid = id:0x3A5, length:8, time:50
#'dc_pv = id:0x3A6, length:8, time:50
#'dc_charger = id:0x3A7, length:8, time:50
#can_signales = current, voltage, capacity, isMaster, isFeed, isCharging, isOn
#'current = begin:0, length:16, offset:0, scaling:0.001, data:0
#'voltage = begin:16, length:16, offset:0, scaling:0.01, data:0
#'capacity = begin:32, length:11, offset:0, scaling:0.05, data:0
#'isMaster = begin:56, length:1, offset:0, scaling:1, data:0
#'isFeed = begin:57, length:1, offset:0, scaling:1, data:0
#'isCharging = begin:57, length:1, offset:0, scaling:1, data:0
#'isOn = begin:58, length:1, offset:0, scaling:1, data:0

View file

@ -5,39 +5,90 @@ Created on 15.11.2013
@version: 0.02
'''
from threading import Thread
#from Queue import Queue
from swich import Swich, MYSQL
#from CANFilter import CANFilter
from threading import Thread
from switch import Switch, MYSQL
from config import Config
#def startCANFilter():
# can = CANFilter()
# can.start()
# pass
### LOAD CONFIG ###
c = Config()
conf = c.readConf()
def startSwitch():
swich = Switch(MYSQL)
queue, query = swich.initialisiere()
if conf['config_debug']:
print 'SWITCH-Thread:\t', swich
print '\tEMS-QUERY:\t', query
print '\tEMS-QUEUE:\t', queue
def startSwich():
swich = Swich(MYSQL)
queue = swich.initialisiere()
print 'swich-Thread:\t', swich
print '\tEMS:\t', queue
swich.start()
return queue
def writeToBuffer():
#TODO
pass
return queue, query
class ems(Thread):
def __init__(self, buf):
Thread.__init__(self)
self.buffer = buf
self.queue = startSwich()
print '\tEMS:\t', buf
self.queue, self.query = startSwitch()
if conf['config_debug']:
print '\tEMS-BUFFER:\t', buf
def run(self):
alt = None
old = None
while True:
neu = self.queue.get()
if not alt == neu or True:
self.buffer.device.get('battery').update(neu)
alt = neu
new = self.getNewMsg(old)
if conf['config_debug']:
print 'GET:\t', new
self.updateBuffer(new)
old = new
def getNewMsg(self, old):
'''
A blocking Method to get a different Message from Queue
@param old: the old message
'''
tmp = self.queue.get()
while tmp == old:
tmp = self.queue.get()
return tmp
def updateBuffer(self, push):
'''
Method to update the Buffer on the given path
@param push: message to push in the buffer
construction: key is the path
value is the dict
'''
## Test of valid push message ##
if not isinstance(push, dict):
print 'error wrong parameter: Type', push.__class__.__name__, 'expect Type dict'
return
if len(push.keys()) not in [1]:
print 'error wrong number of arguments:', len(push.keys()), 'expect 1'
return
if not isinstance(push.get(push.keys()[0]) ,dict):
print 'error value is not dict'
return
key = push.keys()[0]
value = push[key]
path = key.split('/')
if path[0] == '':
path.remove('')
sys = self.buffer.system
for key in path:
try:
sys = sys[key]
except KeyError:
print 'error wrong path'
return
sys.update(value)
pass
def getRequest(self):
#TODO: get Request from buffer
#TODO: define a request in buffer
pass

43
scr/modules/database.py Normal file
View file

@ -0,0 +1,43 @@
'''
Created on 26.11.2013
@author: rauchp
'''
from MySQLdb import connect
def setup(conf):
connection = connect(host = conf['mySQL_server'],
user = conf['mySQL_user'],
passwd = conf['mySQL_pass'],
db = conf['mySQL_database'],
port = int(conf['mySQL_port']))
cursor = connection.cursor()
return cursor
def loop(cursor, item):
sql_values = 'SELECT * FROM %s ORDER BY timestamp DESC LIMIT 1'
sql_collums = 'SHOW COLUMNS FROM %s'
path = item.split('/')
if path[0] == '':
path.remove('')
collums = []
cursor.execute(sql_collums % path[len(path) -1])
for cul in cursor:
collums.append(cul[0])
cursor.execute(sql_values % path[len(path) -1])
for row in cursor:
values = row
result = {}
for i in range(len(collums)):
result[collums[i]] = values[i]
# for p in range(len(path)):
# result = { path.pop() : result }
result = {item : result}
return result

View file

@ -1,101 +0,0 @@
'''
Created on 15.11.2013
@author: Philipp Rauch
@version: 0.1
'''
from threading import Thread
from Queue import Queue
from time import sleep
from config import Config
from MySQLdb import connect
MYSQL = 0
CSV = 1
XML = 2
JSON = 3
### LOAD CONFIG ###
c = Config()
conf = c.readConf()
class Swich(Thread):
_isInit = False
def __init__(self, source = MYSQL):
Thread.__init__(self)
self.source = source
def __del__(self):
if self.source == MYSQL:
# self.CAN.join()
pass
def initialisiere(self):
if self.source == MYSQL:
_isInit = True
### connect to DB ###
self.connection = connect(host = conf['mySQL_server'],
user = conf['mySQL_user'],
passwd = conf['mySQL_pass'],
db = conf['mySQL_database'],
port = int(conf['mySQL_port']))
self.cursor = self.connection.cursor()
### init Queue ###
self.queue = Queue()
print '\tSWICH:\t', self.queue
return self.queue
elif self.source == CSV:
pass
elif self.source == XML:
pass
elif self.source == JSON:
pass
else:
return
def run(self):
###########################
# Imlementation for MYSQL #
###########################
while True:
sql_values = 'SELECT * FROM %s ORDER BY timestamp DESC LIMIT 1'
sql_collums = 'SHOW COLUMNS FROM %s'
item = conf['mySQL_table']
# Queue implementaion
# Queue contains the tablename for query
# item = query.get() #block = True
# query should be included in the result
collums = []
self.cursor.execute(sql_collums % item)
for cul in self.cursor:
collums.append(cul[0])
self.cursor.execute(sql_values % item)
for row in self.cursor:
values = row
result = {}
for i in range(len(collums)):
result[collums[i]] = values[i]
print 'PUT:\t%s' % result
self.setQueue(result)
sleep(float('mySQL_speed'))
def setQueue(self, item):
self.queue.put(item)
def getItem(self, block = False):
return self.queue.get(block)

69
scr/switch.py Normal file
View file

@ -0,0 +1,69 @@
'''
Created on 15.11.2013
@author: Philipp Rauch
@version: 0.1
'''
from threading import Thread
from Queue import Queue
from time import sleep
from config import Config
#import Module
import database
MYSQL = 0
CSV = 1
XML = 2
JSON = 3
### LOAD CONFIG ###
c = Config()
conf = c.readConf()
'''
TODO: comment :)
'''
class Switch(Thread):
def __init__(self, source = MYSQL):
Thread.__init__(self)
self.source = source
def initialisiere(self):
self.cursor = database.setup(conf)
### init Query ###
self.query = Queue()
if conf['config_debug']:
print '\tSWITCH-QUERY:\t', self.query
### init Queue ###
self.queue = Queue()
if conf['config_debug']:
print '\tSWITCH-QUEUE:\t', self.queue
return self.queue, self.query
def run(self):
while True:
# Queue implementaion
# Queue contains the tablename for query
# item = query.get() #block = True
# query should be included in the result
item = 'dc_labor/device/battery'
result = database.loop(self.cursor, item)
#print 'PUT:\t%s' % result
self.setQueue(result)
sleep(float(conf['mySQL_speed']))
def setQueue(self, item):
self.queue.put(item)
def getItem(self, block = False):
return self.queue.get(block)

View file

@ -3,34 +3,36 @@ Created on 21.11.2013
@author: rauchp
'''
#import CANFilter
# import ems
# import time
import swich
# from config import Config
#
# c = Config()
# conf = c.readConf()
import CANFilter
#import ems
#import time
#import switch
from config import Config
# buffer={}
# if conf['config_debug']:
# print 'starte CAN'
#can = CANFilter.CANFilter()
#can.start()
# if conf['config_debug']:
# print 'starte EMS'
### LOAD CONFIG ###
c = Config()
conf = c.readConf()
### CAN test ###
print 'starte CAN mit Baud von', conf['can_baud']
can = CANFilter.CANFilter()
can.start()
### EMS test ###
# buffer = {}
# print 'starte EMS'
# th = ems.ems(buffer)
# th.start()
# if conf['config_debug']:
# print 'alles gestartet'
# while True:
# print buffer
# time.sleep(1)
# sleep(0.1)
sw = swich.Swich(swich.MYSQL)
queue = sw.initialisiere()
sw.start()
print '\tTEST:\t', queue
while True:
print 'GET:\t%s' % queue.get()
### Switch test ###
# sw = switch.Switch(switch.MYSQL)
# queue = sw.initialisiere()
# sw.start()
# print '\tTEST:\t', queue
#
# while True:
# print 'GET:\t%s' % queue.get()