moved configuration to json-file

master
agp8x 2015-08-26 00:16:42 +02:00
parent 849cf7cb7d
commit dedd53bf6d
6 changed files with 188 additions and 143 deletions

View File

@ -5,12 +5,11 @@ import time
import sys import sys
import traceback import traceback
import xml.etree.ElementTree as ET import xml.etree.ElementTree as ET
import logging
import os import os
from timeFunctions import * from timeFunctions import *
from settings import SensorType from settings import SensorType, setup_data_echo, setup_data_log
import settings from settings import settings
class Logger(object): class Logger(object):
def __init__(self, log): def __init__(self, log):
@ -22,29 +21,8 @@ class Logger(object):
self.temp_max_diff = settings.tempmaxdiff self.temp_max_diff = settings.tempmaxdiff
self.log = log self.log = log
self.records = settings.records self.records = settings.records
self.units = settings.SENSOR_UNITS self.dataecho = setup_data_echo()
self.dataecho = self.setup_data_echo() self.datalog = setup_data_log()
self.datalog = self.setup_data_log()
def setup_data_log(self):
log = logging.getLogger("weatherstation.datalog")
log.setLevel(logging.INFO)
fh = logging.FileHandler(os.path.join(settings.records, settings.recordlog))
fformat = logging.Formatter()
fh.setFormatter(fformat)
log.addHandler(fh)
log.propagate = False
return log
def setup_data_echo(self):
log = logging.getLogger("weatherstation.data")
log.setLevel(logging.INFO)
ch = logging.StreamHandler()
formatter = logging.Formatter('%(asctime)s:[DATA] - %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)
log.propagate = False
return log
def temp_rise(self, old, new,sensor): def temp_rise(self, old, new,sensor):
if(old == self.temp_prev_default): if(old == self.temp_prev_default):
@ -79,16 +57,15 @@ class Logger(object):
return return
else: else:
self.write_value(value, sensor) self.write_value(value, sensor)
unit = self.units[type] unit = settings.sensor_properties[type]
if not supress: if not supress:
self.dataecho.info(sensor + ': ' + str(value/unit[0]) + ' ' + unit[1]) self.dataecho.info(sensor + ': ' + str(value/unit[1]) + ' ' + unit[2])
########################################### ###########################################
# exception logging # # exception logging #
########################################### ###########################################
def printException(self, inst): def printException(self, inst):
#TODO: LOG tree = ET.parse(os.path.join(settings.log,settings.exceptionlog))
tree = ET.parse(settings.exceptionlog)
root = tree.getroot() root = tree.getroot()
new = ET.Element('exception', {'class':str( type(inst) ).split("'")[1], 'date':str( time.ctime() ), 'time':str( int(time.time()) ), 'type':str(inst)}) new = ET.Element('exception', {'class':str( type(inst) ).split("'")[1], 'date':str( time.ctime() ), 'time':str( int(time.time()) ), 'type':str(inst)})
new.text = traceback.format_exc() new.text = traceback.format_exc()

View File

@ -14,6 +14,7 @@ except ImportError:
from functools import partial from functools import partial
import traceback import traceback
from settings import SensorType from settings import SensorType
from settings import settings
class ConnectionSetup(object): class ConnectionSetup(object):
def __init__(self, log): def __init__(self, log):
@ -24,12 +25,12 @@ class ConnectionSetup(object):
ipcon.connect(host['name'], host['port']) ipcon.connect(host['name'], host['port'])
return (ipcon) return (ipcon)
def setupConnectionAndSensors(self, host, sensors, cbtimes, cb_generic): def setupConnectionAndSensors(self, host, sensors, cb_generic):
hostname = host['name'] hostname = host['name']
port = host['port'] port = host['port']
ipcon = IPConnection() ipcon = IPConnection()
ipcon.connect(hostname, port) ipcon.connect(hostname, port)
sensorSetup = SensorSetup(ipcon, sensors, cbtimes, cb_generic, self.log) sensorSetup = SensorSetup(ipcon, sensors, cb_generic, self.log)
connectedSensors = sensorSetup.setupSensors() connectedSensors = sensorSetup.setupSensors()
return (ipcon, connectedSensors) return (ipcon, connectedSensors)
@ -40,10 +41,9 @@ class ConnectionSetup(object):
class SensorSetup(object): class SensorSetup(object):
def __init__(self, connection, sensors, cbtimes, cb_generic, log): def __init__(self, connection, sensors, cb_generic, log):
self.connection = connection self.connection = connection
self.sensors = sensors self.sensors = sensors
self.cbtimes = cbtimes
self.cb_generic = cb_generic self.cb_generic = cb_generic
self.log = log self.log = log
self._previous_sensors={} self._previous_sensors={}
@ -117,7 +117,7 @@ class SensorSetup(object):
def genericSensorSetup(self, name, sensor): def genericSensorSetup(self, name, sensor):
status = "setup device "+ sensor[0] +" ("+ name +"):" status = "setup device "+ sensor[0] +" ("+ name +"):"
callback = self.parametrizedCallback(name, type=sensor[1]) callback = self.parametrizedCallback(name, type=sensor[1])
cbtime = self.cbtimes[sensor[1]] cbtime = settings.sensor_properties[sensor[1]][0]
obj = None obj = None
if sensor[1] is SensorType.temp: if sensor[1] is SensorType.temp:
var = self.getTemp() var = self.getTemp()
@ -141,7 +141,7 @@ class SensorSetup(object):
obj = self.__setupSensor__(callback, sensor[0], cbtime, var) obj = self.__setupSensor__(callback, sensor[0], cbtime, var)
self.log.info("%s OK", status) self.log.info("%s OK", status)
except Exception as e: except Exception as e:
self.log.error("%s FAIL:: %s",status, e) self.log.error("%s FAIL:: %s (%s)",status, e,traceback.format_exc())
return obj return obj
def setupSensors(self): def setupSensors(self):

65
main.py
View File

@ -1,30 +1,15 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
import os.path
import os import os
import time import time
import logging
from Logger import Logger from Logger import Logger
from Setup import ConnectionSetup from Setup import ConnectionSetup
import settings from settings import settings, setupLogger
def setupLogger(): log = setupLogger()
log = logging.getLogger("weatherstation") lockpath=os.path.join(settings.locks,settings.lockname)
log.setLevel(logging.INFO)
ch = logging.StreamHandler()
ch.setLevel(logging.DEBUG)
#formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
formatter = logging.Formatter('%(asctime)s:[%(levelname)s] - %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)
fh = logging.FileHandler(os.path.join(settings.logs, settings.logname))
fh.setFormatter(formatter)
log.addHandler(fh)
return log
logi = setupLogger()
def check_dirs_and_files(): def check_dirs_and_files():
# log # log
@ -41,19 +26,17 @@ def check_dirs_and_files():
if not os.path.exists(settings.records): if not os.path.exists(settings.records):
os.mkdir(settings.records, 0o000755) os.mkdir(settings.records, 0o000755)
def obtainLock(lockfile = settings.lockname): def obtainLock():
#TODO: path if not os.path.exists(lockpath):
if not os.path.exists(lockfile): lock = open(lockpath, 'w')
lock = open(lockfile, 'w')
lock.write( str(time.time()) ) lock.write( str(time.time()) )
lock.close() lock.close()
return True return True
return False return False
def freeLock(lockfile = settings.lockname): def freeLock():
#TODO: path if os.path.exists(lockpath):
if os.path.exists(lockfile): os.remove(lockpath)
os.remove(lockfile)
def formatHost(host): def formatHost(host):
return "%s:%d" % (host['name'], host['port']) return "%s:%d" % (host['name'], host['port'])
@ -64,36 +47,36 @@ if __name__ == "__main__":
except NameError: except NameError:
pass pass
check_dirs_and_files() check_dirs_and_files()
conSetup = ConnectionSetup(log)
connectedSensors = []
connections = []
try: try:
logi.info("setting up all sensors") log.info("setting up all sensors")
while True: while True:
if obtainLock(): if obtainLock():
logger = Logger(logi) logger = Logger(log)
connections = [] for con in settings.hosts:
connectedSensors = []
for con in settings.SENSORS:
try: try:
logi.info("connecting to host '"+str(con)+"'") log.info("connecting to host '"+str(con)+"'")
con = settings.SENSORS[con] con = settings.hosts[con]
conSetup = ConnectionSetup(logi) connection, sensors = conSetup.setupConnectionAndSensors(con['host'], con['sensors'], logger.cb_generic)
connection, sensors = conSetup.setupConnectionAndSensors(con['host'], con['sensors'], settings.TIMES, logger.cb_generic)
connections.append(connection) connections.append(connection)
connectedSensors.append(sensors) connectedSensors.append(sensors)
logi.info("started logging at " + formatHost(con['host'])) log.info("started logging at " + formatHost(con['host']))
except Exception as inst: except Exception as inst:
#connection failed, log and exit #connection failed, log and exit
#TODO: logger.printException(inst) #TODO: logger.printException(inst)
logi.error("connection failed: "+str(inst)) log.error("connection failed: "+str(inst))
input("Press key to restart\n") input("Press key to restart\n")
logi.info("stop logging... @" + time.ctime() + "\n") log.info("stop logging... @" + time.ctime() + "\n")
conSetup.disconnectAny(connections) conSetup.disconnectAny(connections)
freeLock() freeLock()
else: else:
logi.critical("lock collision: lock 'all' active") log.critical("lock collision: lock 'all' active")
logi.info("wait for retry (" + str(settings.waitDelay) + ")") log.info("wait for retry (" + str(settings.waitDelay) + ")")
time.sleep(settings.waitDelay) time.sleep(settings.waitDelay)
except KeyboardInterrupt: except KeyboardInterrupt:
logi.info("keyboard-interrupt happened, cleaning up") log.info("keyboard-interrupt happened, cleaning up")
conSetup.disconnectAny(connections) conSetup.disconnectAny(connections)
freeLock() freeLock()

13
move.py
View File

@ -7,7 +7,8 @@ import logging
from shutil import move from shutil import move
from timeFunctions import * from timeFunctions import *
from settings import locks, logs, arch, records, movelog, movelock from settings import settings
#from settings import locks, logs, arch, records, movelog, movelock
def setupLogger(): def setupLogger():
log = logging.getLogger("weatherstation.move") log = logging.getLogger("weatherstation.move")
@ -17,26 +18,26 @@ def setupLogger():
formatter = logging.Formatter('%(asctime)s:[%(levelname)s] - %(message)s') formatter = logging.Formatter('%(asctime)s:[%(levelname)s] - %(message)s')
ch.setFormatter(formatter) ch.setFormatter(formatter)
log.addHandler(ch) log.addHandler(ch)
fh = logging.FileHandler(os.path.join(logs, movelog)) fh = logging.FileHandler(os.path.join(settings.logs, settings.movelog))
fh.setFormatter(formatter) fh.setFormatter(formatter)
log.addHandler(fh) log.addHandler(fh)
return log return log
log = setupLogger() log = setupLogger()
checkfile=os.path.join(locks,movelock) checkfile=os.path.join(settings.locks,settings.movelock)
if not os.path.exists(checkfile): if not os.path.exists(checkfile):
open(checkfile,'w').close() open(checkfile,'w').close()
if not os.path.exists(arch): if not os.path.exists(settings.arch):
os.mkdir(arch, 0o000755) os.mkdir(arch, 0o000755)
def mycopy(keep): def mycopy(keep):
names = os.listdir(records) names = os.listdir(settings.records)
for name in names: for name in names:
if keep in name: if keep in name:
continue continue
move(os.path.join(records, name), arch) move(os.path.join(settings.records, name), settings.arch)
check=open(checkfile,'r') check=open(checkfile,'r')
temp=check.read() temp=check.read()

40
set.json Normal file
View File

@ -0,0 +1,40 @@
{
"hosts": {
"irtest": {
"host":{
"name": "localhost",
"port":4223
},
"sensors":{
"iram": ["c8w", "SensorType.iram"],
"irob": ["c8w", "SensorType.irob"]
}
}
},
"sensor_properties":{
"SensorType.none": [0, 0, ""],
"SensorType.temp": [30000, 100.0, "°C"],
"SensorType.humi": [30000, 10.0, "%RH"],
"SensorType.ambi": [60000, 10.0, "Lux"],
"SensorType.baro": [60000, 1000, "mbar"],
"SensorType.rain": [0, 2.5, "l/qm"],
"SensorType.iram": [1000, 10.0, "°C"],
"SensorType.irob": [1000, 10.0, "°C"]
},
"tempmaxdiff": 200,
"prev_temps_default": 20000,
"logs": "logs",
"locks": "locks",
"records": "records",
"arch": "arch",
"lockname": "all.lock",
"logname": "logging.log",
"exceptionlog": "exceptions.xml",
"recordlog": "record.log",
"movelog": "move.log",
"movelock": "last_move",
"waitDelay" : 10,
"loglevel": "info",
"datalog": "info",
"dataecho": "info"
}

View File

@ -1,7 +1,10 @@
#!/usr/bin/env python3 #!/usr/bin/env python3
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
#class SensorType(Enum): import json
import logging
import os
class SensorType: class SensorType:
none = 0 none = 0
temp = 1 # temperature bricklet temp = 1 # temperature bricklet
@ -12,69 +15,110 @@ class SensorType:
iram = 6 # temperature ir bricklet, ambient iram = 6 # temperature ir bricklet, ambient
irob = 7 # temperature ir bricklet, object irob = 7 # temperature ir bricklet, object
SENSORS={ DEFAULTS ={
"irtest": { "hosts":{
"host":{"name": "localhost", "port":4223}, "HOSTDESC_i":{
"sensors":{ "host":{"name":"HOSTNAME_OR_IP","port":4223},
"iram": ["c8w", SensorType.iram], "sensors":{
"irob": ["c8w", SensorType.irob] "NAME":["UID", "SensorType.TYPE"]}
} }
} },
"sensor_properties":{
"SensorType.none": [0, 0, ""],
"SensorType.temp": [30000, 100.0, "°C"],
"SensorType.humi": [30000, 10.0, "%RH"],
"SensorType.ambi": [60000, 10.0, "Lux"],
"SensorType.baro": [60000, 1000, "mbar"],
"SensorType.rain": [0, 2.5, "l/qm"],
"SensorType.iram": [1000, 10.0, "°C"],
"SensorType.irob": [1000, 10.0, "°C"]},
"tempmaxdiff":200,
"prev_temps_default":20000,
"logs":'logs',
"locks":'locks',
"records":'records',
"arch":'arch',
"lockname":"all.lock",
"logname":"logging.log",
"exceptionlog":"exceptions.xml",
"recordlog":"record.log",
"movelog":"move.log",
"movelock":"last_move",
"waitDelay":10,
"tempSensors":0,
"loglevel": "info",
"datalog": "info",
"dataecho": "info"
} }
class Settings(dict):
def __getattr__(self,name):
if name in self:
return self[name]
return DEFAULTS[name]
def __setattr__(self,name,value):
self[name]=value
def __delattr__(self,name):
del self[name]
def load_json(filename="set.json"):
values=json.load(open('set.json'), object_hook=Settings)
sensors_name="hosts"
if sensors_name in values:
for host in values[sensors_name]:
for sensor in values[sensors_name][host]["sensors"]:
sensor = values[sensors_name][host]["sensors"][sensor]
sensor[1] = eval(sensor[1])
sensor_props = "sensor_properties"
if sensor_props in values:
new_units={}
for unit in values[sensor_props]:
new_units[eval(unit)] = values[sensor_props][unit]
values[sensor_props] = new_units
return values
def setupLogger():
level = getattr(logging, settings.loglevel.upper(), logging.INFO)
log = logging.getLogger("weatherstation")
log.setLevel(level)
ch = logging.StreamHandler()
#formatter = logging.Formatter('%(asctime)s - %(name)s - %(levelname)s - %(message)s')
formatter = logging.Formatter('%(asctime)s:[%(levelname)s] - %(message)s')
ch.setFormatter(formatter)
log.addHandler(ch)
fh = logging.FileHandler(os.path.join(settings.logs, settings.logname))
fh.setFormatter(formatter)
log.addHandler(fh)
return log
TIMES={ def setup_data_log():
SensorType.temp: 30000, level = getattr(logging, settings.datalog.upper(), logging.INFO)
SensorType.humi: 30000, log = logging.getLogger("weatherstation.datalog")
SensorType.ambi: 60000, log.setLevel(level)
SensorType.baro: 60000, fh = logging.FileHandler(os.path.join(settings.records, settings.recordlog))
SensorType.rain: 0, fformat = logging.Formatter()
SensorType.iram: 60000, fh.setFormatter(fformat)
SensorType.irob: 60000, log.addHandler(fh)
} log.propagate = False
return log
tempmaxdiff=200 # 200== 2.0 C def setup_data_echo():
prev_temps_default=20000 level = getattr(logging, settings.dataecho.upper(), logging.INFO)
log = logging.getLogger("weatherstation.data")
logs='logs' log.setLevel(level)
locks='locks' ch = logging.StreamHandler()
records='records' formatter = logging.Formatter('%(asctime)s:[DATA] - %(message)s')
arch='arch' ch.setFormatter(formatter)
log.addHandler(ch)
#TODO: lockname, exceptionslog: path.join log.propagate = False
lockname=locks+"/all.lock" return log
logname="logging.log"
exceptionlog=logs+"/exceptions.xml"
recordlog="record.log"
movelog="move.log"
movelock="last_move"
waitDelay = 10
########################################
# only change when new sensor is added #
########################################
SENSOR_UNITS=[
(0,''),
(100.0, '°C'),
(10.0, '%RH'),
(10.0, 'Lux'),
(1000, 'mbar'),
(2.5, 'l/qm'),
(10.0, '°C'),
(10.0, '°C')
]
###########################
# no manual change needed #
###########################
tempSensors=0
for i in SENSORS:
for j in SENSORS[i]['sensors']:
if SENSORS[i]['sensors'][j][1] == SensorType.temp:
tempSensors+=1
settings=load_json()
hosts_name = "hosts"
if hosts_name in settings:
tempSensors=0
for i in settings[hosts_name]:
for j in settings[hosts_name][i]['sensors']:
if settings[hosts_name][i]['sensors'][j][1] == SensorType.temp:
tempSensors+=1
settings.tempSensors=tempSensors
""" """
0: { 0: {
"host": { "host": {