reformatted using pyCharm
parent
bb840d46cf
commit
a508fb7269
|
|
@ -4,6 +4,7 @@ arch/
|
|||
locks/
|
||||
logs/
|
||||
records/
|
||||
.idea/
|
||||
bin/
|
||||
bin/*
|
||||
*~
|
||||
|
|
|
|||
127
Logger.py
127
Logger.py
|
|
@ -1,8 +1,6 @@
|
|||
#!/usr/bin/env python3
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import time
|
||||
import sys
|
||||
import traceback
|
||||
import xml.etree.ElementTree as ET
|
||||
import os
|
||||
|
|
@ -11,74 +9,69 @@ from timeFunctions import *
|
|||
from config import SensorType, setup_data_echo, setup_data_log
|
||||
from config import settings
|
||||
|
||||
|
||||
class Logger(object):
|
||||
def __init__(self, log):
|
||||
self.temp_prev_default = settings.prev_temps_default
|
||||
self.prev_temps = self.__build_prev_temps__()
|
||||
self.temp_max_diff = settings.tempmaxdiff
|
||||
self.log = log
|
||||
self.records = settings.records
|
||||
self.dataecho = setup_data_echo()
|
||||
self.datalog = setup_data_log()
|
||||
def __init__(self, log):
|
||||
self.temp_prev_default = settings.prev_temps_default
|
||||
self.prev_temps = self.__build_prev_temps__()
|
||||
self.temp_max_diff = settings.tempmaxdiff
|
||||
self.log = log
|
||||
self.records = settings.records
|
||||
self.dataecho = setup_data_echo()
|
||||
self.datalog = setup_data_log()
|
||||
|
||||
def __build_prev_temps__(self):
|
||||
prev_temps={}
|
||||
hosts_name = "hosts"
|
||||
if hosts_name in settings:
|
||||
for i in settings[hosts_name]:
|
||||
for j in settings[hosts_name][i]['sensors']:
|
||||
if settings[hosts_name][i]['sensors'][j][1] == SensorType.temp:
|
||||
prev_temps[j]=self.temp_prev_default
|
||||
return prev_temps
|
||||
def __build_prev_temps__(self):
|
||||
prev_temps = {}
|
||||
hosts_name = "hosts"
|
||||
if hosts_name in settings:
|
||||
for i in settings[hosts_name]:
|
||||
for j in settings[hosts_name][i]['sensors']:
|
||||
if settings[hosts_name][i]['sensors'][j][1] == SensorType.temp:
|
||||
prev_temps[j] = self.temp_prev_default
|
||||
return prev_temps
|
||||
|
||||
def temp_rise(self, new, sensor):
|
||||
old = self.prev_temps[sensor]
|
||||
if(old == self.temp_prev_default):
|
||||
return True
|
||||
if(((old-new) > self.temp_max_diff) or ((new-old) > self.temp_max_diff)):
|
||||
self.log.error('error checking ' + sensor + ';prev(' + str(old) + ');cur(' + str(new) + ');')
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
def temp_rise(self, new, sensor):
|
||||
old = self.prev_temps[sensor]
|
||||
if old == self.temp_prev_default:
|
||||
return True
|
||||
if ((old - new) > self.temp_max_diff) or ((new - old) > self.temp_max_diff):
|
||||
self.log.error('error checking ' + sensor + ';prev(' + str(old) + ');cur(' + str(new) + ');')
|
||||
return False
|
||||
else:
|
||||
return True
|
||||
|
||||
##########################################
|
||||
# common function to write value to file #
|
||||
##########################################
|
||||
def write_value(self, value, sensor):
|
||||
if settings.legacy_record:
|
||||
valuename = self.records + "/" + sensor + "_" + preptime()
|
||||
valuelog=open(valuename, 'a')
|
||||
valuelog.write(str(value) + ';' + str( int(time.time()) ) + "\n")
|
||||
valuelog.close()
|
||||
self.datalog.info('%s;%s;%s',value, int(time.time()), sensor)
|
||||
# common function to write value to file
|
||||
def write_value(self, value, sensor):
|
||||
if settings.legacy_record:
|
||||
valuename = self.records + "/" + sensor + "_" + preptime()
|
||||
valuelog = open(valuename, 'a')
|
||||
valuelog.write(str(value) + ';' + str(int(time.time())) + "\n")
|
||||
valuelog.close()
|
||||
self.datalog.info('%s;%s;%s', value, int(time.time()), sensor)
|
||||
|
||||
##########################################
|
||||
# generic callback #
|
||||
##########################################
|
||||
def cb_generic(self,value, sensor, type, supress = False):
|
||||
if type == SensorType.temp:
|
||||
if self.temp_rise(value, sensor):
|
||||
self.write_value(value, sensor)
|
||||
self.prev_temps[sensor] = value
|
||||
elif (type == SensorType.none):
|
||||
return
|
||||
else:
|
||||
self.write_value(value, sensor)
|
||||
unit = settings.sensor_properties[type]
|
||||
if not supress:
|
||||
self.dataecho.info(sensor + ': ' + str(value/unit[1]) + ' ' + unit[2])
|
||||
|
||||
###########################################
|
||||
# exception logging #
|
||||
###########################################
|
||||
def printException(self, inst):
|
||||
tree = ET.parse(os.path.join(settings.log,settings.exceptionlog))
|
||||
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.text = traceback.format_exc()
|
||||
root.append(new)
|
||||
tree.write(settings.exceptionlog)
|
||||
message = 'an Exception happend @' + time.ctime()+"\n"
|
||||
self.log.error(message)
|
||||
print(message)
|
||||
# generic callback
|
||||
def cb_generic(self, value, sensor, type, supress=False):
|
||||
if type == SensorType.temp:
|
||||
if self.temp_rise(value, sensor):
|
||||
self.write_value(value, sensor)
|
||||
self.prev_temps[sensor] = value
|
||||
elif type == SensorType.none:
|
||||
return
|
||||
else:
|
||||
self.write_value(value, sensor)
|
||||
unit = settings.sensor_properties[type]
|
||||
if not supress:
|
||||
self.dataecho.info(sensor + ': ' + str(value / unit[1]) + ' ' + unit[2])
|
||||
|
||||
# exception logging
|
||||
def print_exception(self, inst):
|
||||
tree = ET.parse(os.path.join(settings.log, settings.exceptionlog))
|
||||
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.text = traceback.format_exc()
|
||||
root.append(new)
|
||||
tree.write(settings.exceptionlog)
|
||||
message = 'an Exception happend @' + time.ctime() + "\n"
|
||||
self.log.error(message)
|
||||
print(message)
|
||||
|
|
|
|||
|
|
@ -49,3 +49,4 @@ Optional: Upload der Aufzeichnungen mit SFTP an einem Server (beinhaltet Archivi
|
|||
|
||||
# TODOS
|
||||
* TODOS ausdenken
|
||||
* rugged approach [http://www.tinkerforge.com/en/doc/Tutorials/Tutorial_Rugged/Tutorial.html](http://www.tinkerforge.com/en/doc/Tutorials/Tutorial_Rugged/Tutorial.html)
|
||||
|
|
|
|||
235
Setup.py
235
Setup.py
|
|
@ -5,135 +5,136 @@ from functools import partial
|
|||
import traceback
|
||||
|
||||
try:
|
||||
from tinkerforge.ip_connection import IPConnection
|
||||
from tinkerforge.bricklet_temperature import Temperature
|
||||
from tinkerforge.bricklet_humidity import Humidity
|
||||
from tinkerforge.bricklet_ambient_light import AmbientLight
|
||||
from tinkerforge.bricklet_barometer import Barometer
|
||||
from tinkerforge.bricklet_temperature_ir import BrickletTemperatureIR
|
||||
from tinkerforge.ip_connection import IPConnection
|
||||
from tinkerforge.bricklet_temperature import Temperature
|
||||
from tinkerforge.bricklet_humidity import Humidity
|
||||
from tinkerforge.bricklet_ambient_light import AmbientLight
|
||||
from tinkerforge.bricklet_barometer import Barometer
|
||||
from tinkerforge.bricklet_temperature_ir import BrickletTemperatureIR
|
||||
except ImportError:
|
||||
print("package 'tinkerforge' not installed, canceling")
|
||||
raise Exception("package 'tinkerforge' not installed, canceling")
|
||||
print("package 'tinkerforge' not installed, canceling")
|
||||
raise Exception("package 'tinkerforge' not installed, canceling")
|
||||
|
||||
from config import SensorType
|
||||
from config import settings
|
||||
|
||||
|
||||
class ConnectionSetup(object):
|
||||
def __init__(self, log):
|
||||
self.log = log
|
||||
def __init__(self, log):
|
||||
self.log = log
|
||||
|
||||
def setupConnection(self, host):
|
||||
ipcon = IPConnection()
|
||||
ipcon.connect(host['name'], host['port'])
|
||||
return (ipcon)
|
||||
def setup_connection(self, host):
|
||||
ipcon = IPConnection()
|
||||
try:
|
||||
ipcon.connect(host['name'], host['port'])
|
||||
self.log.info("connection to '%s:%s' established", host['name'], host['port'])
|
||||
except ConnectionError:
|
||||
self.log.error("connection to '%s:%s' failed", host['name'], host['port'])
|
||||
return ipcon
|
||||
|
||||
def setupConnectionAndSensors(self, host, sensors, cb_generic):
|
||||
hostname = host['name']
|
||||
port = host['port']
|
||||
ipcon = IPConnection()
|
||||
ipcon.connect(hostname, port)
|
||||
sensorSetup = SensorSetup(ipcon, sensors, cb_generic, self.log)
|
||||
connectedSensors = sensorSetup.setupSensors()
|
||||
return (ipcon, connectedSensors)
|
||||
def setup_connection_and_sensors(self, host, sensors, cb_generic):
|
||||
ipcon = self.setup_connection(host)
|
||||
sensor_setup = SensorSetup(ipcon, sensors, cb_generic, self.log)
|
||||
connected_sensors = sensor_setup.setup_sensors()
|
||||
return ipcon, connected_sensors
|
||||
|
||||
def disconnect_any(self, connections):
|
||||
for connection in connections:
|
||||
if not connection.get_connection_state() is IPConnection.CONNECTION_STATE_DISCONNECTED:
|
||||
self.log.debug("disconnecting (%s)", connection)
|
||||
connection.disconnect()
|
||||
|
||||
def disconnectAny(self, connections):
|
||||
for connection in connections:
|
||||
if not connection.get_connection_state() is IPConnection.CONNECTION_STATE_DISCONNECTED:
|
||||
connection.disconnect()
|
||||
|
||||
class SensorSetup(object):
|
||||
def __init__(self, connection, sensors, cb_generic, log):
|
||||
self.connection = connection
|
||||
self.sensors = sensors
|
||||
self.cb_generic = cb_generic
|
||||
self.log = log
|
||||
self._previous_sensors = {}
|
||||
self._configs = {
|
||||
# SensorType.none: {
|
||||
# 'obj': ,
|
||||
# 'setcb': ,
|
||||
# 'get': ,
|
||||
# 'cb':
|
||||
# },
|
||||
SensorType.temp: {
|
||||
'obj': Temperature,
|
||||
'setcb': Temperature.set_temperature_callback_period,
|
||||
'get': Temperature.get_temperature,
|
||||
'cb': Temperature.CALLBACK_TEMPERATURE
|
||||
},
|
||||
SensorType.humi: {
|
||||
'obj': Humidity,
|
||||
'setcb': Humidity.set_humidity_callback_period,
|
||||
'get': Humidity.get_humidity,
|
||||
'cb': Humidity.CALLBACK_HUMIDITY
|
||||
},
|
||||
SensorType.ambi: {
|
||||
'obj': AmbientLight,
|
||||
'setcb': AmbientLight.set_illuminance_callback_period,
|
||||
'get': AmbientLight.get_illuminance,
|
||||
'cb': AmbientLight.CALLBACK_ILLUMINANCE
|
||||
},
|
||||
SensorType.baro: {
|
||||
'obj': Barometer,
|
||||
'setcb': Barometer.get_air_pressure_callback_period,
|
||||
'get': Barometer.get_air_pressure,
|
||||
'cb': Barometer.CALLBACK_AIR_PRESSURE
|
||||
},
|
||||
SensorType.iram: {
|
||||
'obj': BrickletTemperatureIR,
|
||||
'setcb': BrickletTemperatureIR.set_ambient_temperature_callback_period,
|
||||
'get': BrickletTemperatureIR.get_ambient_temperature,
|
||||
'cb': BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE
|
||||
},
|
||||
SensorType.irob: {
|
||||
'obj': BrickletTemperatureIR,
|
||||
'setcb': BrickletTemperatureIR.set_object_temperature_callback_period,
|
||||
'get': BrickletTemperatureIR.get_object_temperature,
|
||||
'cb': BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE
|
||||
}
|
||||
}
|
||||
|
||||
def __init__(self, connection, sensors, cb_generic, log):
|
||||
self.connection = connection
|
||||
self.sensors = sensors
|
||||
self.cb_generic = cb_generic
|
||||
self.log = log
|
||||
self._previous_sensors={}
|
||||
self._configs={
|
||||
#SensorType.none: {
|
||||
# 'obj': ,
|
||||
# 'setcb': ,
|
||||
# 'get': ,
|
||||
# 'cb':
|
||||
#},
|
||||
SensorType.temp: {
|
||||
'obj': Temperature,
|
||||
'setcb': Temperature.set_temperature_callback_period,
|
||||
'get': Temperature.get_temperature,
|
||||
'cb': Temperature.CALLBACK_TEMPERATURE
|
||||
},
|
||||
SensorType.humi: {
|
||||
'obj': Humidity,
|
||||
'setcb': Humidity.set_humidity_callback_period,
|
||||
'get': Humidity.get_humidity,
|
||||
'cb': Humidity.CALLBACK_HUMIDITY
|
||||
},
|
||||
SensorType.ambi: {
|
||||
'obj': AmbientLight,
|
||||
'setcb': AmbientLight.set_illuminance_callback_period,
|
||||
'get': AmbientLight.get_illuminance,
|
||||
'cb': AmbientLight.CALLBACK_ILLUMINANCE
|
||||
},
|
||||
SensorType.baro: {
|
||||
'obj': Barometer,
|
||||
'setcb': Barometer.get_air_pressure_callback_period,
|
||||
'get': Barometer.get_air_pressure,
|
||||
'cb': Barometer.CALLBACK_AIR_PRESSURE
|
||||
},
|
||||
SensorType.iram: {
|
||||
'obj': BrickletTemperatureIR,
|
||||
'setcb': BrickletTemperatureIR.set_ambient_temperature_callback_period,
|
||||
'get': BrickletTemperatureIR.get_ambient_temperature,
|
||||
'cb': BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE
|
||||
},
|
||||
SensorType.irob: {
|
||||
'obj': BrickletTemperatureIR,
|
||||
'setcb': BrickletTemperatureIR.set_object_temperature_callback_period,
|
||||
'get': BrickletTemperatureIR.get_object_temperature,
|
||||
'cb': BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE
|
||||
}
|
||||
}
|
||||
def parametrized_callback(self, name, type):
|
||||
return partial(self.cb_generic, sensor=name, type=type)
|
||||
|
||||
def parametrizedCallback(self, name, type):
|
||||
return partial(self.cb_generic, sensor=name, type=type)
|
||||
def __setupSensor__(self, callback, id, cbtime, var):
|
||||
if id in self._previous_sensors:
|
||||
self.log.debug("reusing instance for %s", id)
|
||||
obj = self._previous_sensors[id] # restore instance for another callback
|
||||
else:
|
||||
self.log.debug("new instance for %s", id)
|
||||
obj = var['obj'](id, self.connection) # construct instance
|
||||
self._previous_sensors[id] = obj # save instance for multiple callbacks
|
||||
var['setcb'](obj, cbtime) # set callback period
|
||||
callback(var['get'](obj), supress=True) # execute callback with raw getter as value
|
||||
obj.register_callback(var['cb'], callback) # register callback
|
||||
return obj
|
||||
|
||||
def __setupSensor__(self, callback, id, cbtime, var):
|
||||
obj = None
|
||||
if id in self._previous_sensors:
|
||||
self.log.debug("reusing instance for %s", id)
|
||||
obj = self._previous_sensors[id] # restore instance for another callback
|
||||
else:
|
||||
self.log.debug("new instance for %s", id)
|
||||
obj = var['obj'](id, self.connection) # construct instance
|
||||
self._previous_sensors[id] = obj # save instance for multiple callbacks
|
||||
var['setcb'](obj, cbtime) # set callback period
|
||||
callback(var['get'](obj ), supress=True) # execute callback with raw getter as value
|
||||
obj.register_callback(var['cb'], callback) # register callback
|
||||
return obj
|
||||
|
||||
def genericSensorSetup(self, name, sensor):
|
||||
status = "setup device "+ sensor[0] +" ("+ name +"):"
|
||||
callback = self.parametrizedCallback(name, type=sensor[1])
|
||||
cbtime = settings.sensor_properties[sensor[1]][0]
|
||||
obj = None
|
||||
if sensor[1] is SensorType.rain:
|
||||
self.log.error("rain is not yet implemented (%s, %s)", sensor[0], name)
|
||||
return None
|
||||
elif not sensor[1] in self._configs:
|
||||
self.log.error("%s FAIL (unknown type)", status)
|
||||
return None
|
||||
try:
|
||||
obj = self.__setupSensor__(callback, sensor[0], cbtime, self._configs[sensor[1]])
|
||||
self.log.info("%s OK", status)
|
||||
except Exception as e:
|
||||
self.log.error("%s FAIL:: %s (%s)",status, e,traceback.format_exc())
|
||||
return obj
|
||||
|
||||
def setupSensors(self):
|
||||
connected=[]
|
||||
for name in self.sensors:
|
||||
sensor = self.sensors[name]
|
||||
obj = self.genericSensorSetup(name, sensor)
|
||||
connected.append(obj)
|
||||
return connected
|
||||
def generic_sensor_setup(self, name, sensor):
|
||||
status = "setup device " + sensor[0] + " (" + name + "):"
|
||||
callback = self.parametrized_callback(name, type=sensor[1])
|
||||
cbtime = settings.sensor_properties[sensor[1]][0]
|
||||
obj = None
|
||||
if sensor[1] is SensorType.rain:
|
||||
self.log.error("rain is not yet implemented (%s, %s)", sensor[0], name)
|
||||
return None
|
||||
elif not sensor[1] in self._configs:
|
||||
self.log.error("%s FAIL (unknown type)", status)
|
||||
return None
|
||||
try:
|
||||
obj = self.__setupSensor__(callback, sensor[0], cbtime, self._configs[sensor[1]])
|
||||
self.log.info("%s OK", status)
|
||||
except Exception as e:
|
||||
self.log.error("%s FAIL:: %s (%s)", status, e, traceback.format_exc())
|
||||
return obj
|
||||
|
||||
def setup_sensors(self):
|
||||
connected = []
|
||||
for name in self.sensors:
|
||||
sensor = self.sensors[name]
|
||||
obj = self.generic_sensor_setup(name, sensor)
|
||||
connected.append(obj)
|
||||
return connected
|
||||
|
|
|
|||
242
config.py
242
config.py
|
|
@ -5,128 +5,140 @@ import json
|
|||
import logging
|
||||
import os
|
||||
|
||||
class SensorType:
|
||||
none = 0
|
||||
temp = 1 # temperature bricklet
|
||||
humi = 2 # humidity bricklet
|
||||
ambi = 3 # ambient light bricklet
|
||||
baro = 4 # barometer bricklet
|
||||
rain = 5 # IO4 #TODO
|
||||
iram = 6 # temperature ir bricklet, ambient
|
||||
irob = 7 # temperature ir bricklet, object
|
||||
|
||||
DEFAULTS ={
|
||||
"hosts":{
|
||||
"HOSTDESC_i":{
|
||||
"host":{"name":"HOSTNAME_OR_IP","port":4223},
|
||||
"sensors":{
|
||||
"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",
|
||||
"legacy_record": True
|
||||
class SensorType:
|
||||
none = 0
|
||||
temp = 1 # temperature bricklet
|
||||
humi = 2 # humidity bricklet
|
||||
ambi = 3 # ambient light bricklet
|
||||
baro = 4 # barometer bricklet
|
||||
rain = 5 # IO4 #TODO
|
||||
iram = 6 # temperature ir bricklet, ambient
|
||||
irob = 7 # temperature ir bricklet, object
|
||||
|
||||
|
||||
DEFAULTS = {
|
||||
"hosts": {
|
||||
"HOSTDESC_i": {
|
||||
"host": {"name": "HOSTNAME_OR_IP", "port": 4223},
|
||||
"sensors": {
|
||||
"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",
|
||||
"legacy_record": True
|
||||
}
|
||||
|
||||
|
||||
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 __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="config.json"):
|
||||
values=json.load(open(filename), 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
|
||||
values = json.load(open(filename), 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 setup_logger():
|
||||
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
|
||||
|
||||
|
||||
def setup_data_log():
|
||||
level = getattr(logging, settings.datalog.upper(), logging.INFO)
|
||||
log = logging.getLogger("weatherstation.datalog")
|
||||
log.setLevel(level)
|
||||
fh = logging.FileHandler(os.path.join(settings.records, settings.recordlog))
|
||||
fformat = logging.Formatter()
|
||||
fh.setFormatter(fformat)
|
||||
log.addHandler(fh)
|
||||
log.propagate = False
|
||||
return log
|
||||
level = getattr(logging, settings.datalog.upper(), logging.INFO)
|
||||
log = logging.getLogger("weatherstation.datalog")
|
||||
log.setLevel(level)
|
||||
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():
|
||||
level = getattr(logging, settings.dataecho.upper(), logging.INFO)
|
||||
log = logging.getLogger("weatherstation.data")
|
||||
log.setLevel(level)
|
||||
ch = logging.StreamHandler()
|
||||
formatter = logging.Formatter('%(asctime)s:[DATA] - %(message)s')
|
||||
ch.setFormatter(formatter)
|
||||
log.addHandler(ch)
|
||||
log.propagate = False
|
||||
return log
|
||||
level = getattr(logging, settings.dataecho.upper(), logging.INFO)
|
||||
log = logging.getLogger("weatherstation.data")
|
||||
log.setLevel(level)
|
||||
ch = logging.StreamHandler()
|
||||
formatter = logging.Formatter('%(asctime)s:[DATA] - %(message)s')
|
||||
ch.setFormatter(formatter)
|
||||
log.addHandler(ch)
|
||||
log.propagate = False
|
||||
return log
|
||||
|
||||
settings=load_json()
|
||||
|
||||
settings = load_json()
|
||||
"""
|
||||
0: {
|
||||
"host": {
|
||||
"name": "192.168.2.60",
|
||||
"port": 4223
|
||||
},
|
||||
"sensors": {
|
||||
"temp1": ["7B5", SensorType.temp],
|
||||
"temp2": ["8js", SensorType.temp],
|
||||
"humi1": ["7RY", SensorType.humi],
|
||||
"ambi1": ["8Fw", SensorType.ambi],
|
||||
"ambi2": ["8DJ", SensorType.ambi],
|
||||
"baro1": ["bB7", SensorType.baro],
|
||||
"temp3": ["8ms", SensorType.temp],
|
||||
"humi2": ["9V5", SensorType.humi],
|
||||
}
|
||||
},"""
|
||||
|
||||
0: {
|
||||
"host": {
|
||||
"name": "192.168.2.60",
|
||||
"port": 4223
|
||||
},
|
||||
"sensors": {
|
||||
"temp1": ["7B5", SensorType.temp],
|
||||
"temp2": ["8js", SensorType.temp],
|
||||
"humi1": ["7RY", SensorType.humi],
|
||||
"ambi1": ["8Fw", SensorType.ambi],
|
||||
"ambi2": ["8DJ", SensorType.ambi],
|
||||
"baro1": ["bB7", SensorType.baro],
|
||||
"temp3": ["8ms", SensorType.temp],
|
||||
"humi2": ["9V5", SensorType.humi],
|
||||
}
|
||||
},"""
|
||||
|
|
|
|||
137
main.py
137
main.py
|
|
@ -6,77 +6,82 @@ import time
|
|||
|
||||
from Logger import Logger
|
||||
from Setup import ConnectionSetup
|
||||
from config import settings, setupLogger
|
||||
from config import settings, setup_logger
|
||||
|
||||
log = setup_logger()
|
||||
lockpath = os.path.join(settings.locks, settings.lockname)
|
||||
|
||||
log = setupLogger()
|
||||
lockpath=os.path.join(settings.locks,settings.lockname)
|
||||
|
||||
def check_dirs_and_files():
|
||||
# log
|
||||
if not os.path.exists(settings.logs):
|
||||
os.mkdir(settings.logs, 0o000755)
|
||||
if not os.path.exists(os.path.join(settings.logs,settings.exceptionlog)):
|
||||
file=open(os.path.join(settings.logs,settings.exceptionlog), 'w')
|
||||
file.write("<exceptions></exceptions>")
|
||||
file.close()
|
||||
# lock
|
||||
if not os.path.exists(settings.locks):
|
||||
os.mkdir(settings.locks, 0o000755)
|
||||
# records
|
||||
if not os.path.exists(settings.records):
|
||||
os.mkdir(settings.records, 0o000755)
|
||||
# log
|
||||
if not os.path.exists(settings.logs):
|
||||
os.mkdir(settings.logs, 0o000755)
|
||||
if not os.path.exists(os.path.join(settings.logs, settings.exceptionlog)):
|
||||
file = open(os.path.join(settings.logs, settings.exceptionlog), 'w')
|
||||
file.write("<exceptions></exceptions>")
|
||||
file.close()
|
||||
# lock
|
||||
if not os.path.exists(settings.locks):
|
||||
os.mkdir(settings.locks, 0o000755)
|
||||
# records
|
||||
if not os.path.exists(settings.records):
|
||||
os.mkdir(settings.records, 0o000755)
|
||||
|
||||
def obtainLock():
|
||||
if not os.path.exists(lockpath):
|
||||
lock = open(lockpath, 'w')
|
||||
lock.write( str(time.time()) )
|
||||
lock.close()
|
||||
return True
|
||||
return False
|
||||
|
||||
def freeLock():
|
||||
if os.path.exists(lockpath):
|
||||
os.remove(lockpath)
|
||||
def obtain_lock():
|
||||
if not os.path.exists(lockpath):
|
||||
lock = open(lockpath, 'w')
|
||||
lock.write(str(time.time()))
|
||||
lock.close()
|
||||
return True
|
||||
return False
|
||||
|
||||
|
||||
def free_lock():
|
||||
if os.path.exists(lockpath):
|
||||
os.remove(lockpath)
|
||||
|
||||
|
||||
def format_host(host):
|
||||
return "%s:%d" % (host['name'], host['port'])
|
||||
|
||||
def formatHost(host):
|
||||
return "%s:%d" % (host['name'], host['port'])
|
||||
|
||||
if __name__ == "__main__":
|
||||
try:
|
||||
input = raw_input
|
||||
except NameError:
|
||||
pass
|
||||
check_dirs_and_files()
|
||||
conSetup = ConnectionSetup(log)
|
||||
connectedSensors = []
|
||||
connections = []
|
||||
try:
|
||||
log.info("setting up all sensors")
|
||||
while True:
|
||||
if obtainLock():
|
||||
logger = Logger(log)
|
||||
for con in settings.hosts:
|
||||
try:
|
||||
log.info("connecting to host '"+str(con)+"'")
|
||||
con = settings.hosts[con]
|
||||
connection, sensors = conSetup.setupConnectionAndSensors(con['host'], con['sensors'], logger.cb_generic)
|
||||
connections.append(connection)
|
||||
connectedSensors.append(sensors)
|
||||
log.info("started logging at " + formatHost(con['host']))
|
||||
except Exception as inst:
|
||||
#connection failed, log and exit
|
||||
#TODO: logger.printException(inst)
|
||||
log.error("connection failed: "+str(inst))
|
||||
input("Press key to restart\n")
|
||||
log.info("stop logging... @" + time.ctime() + "\n")
|
||||
conSetup.disconnectAny(connections)
|
||||
freeLock()
|
||||
else:
|
||||
log.critical("lock collision: lock 'all' active")
|
||||
log.info("wait for retry (" + str(settings.waitDelay) + ")")
|
||||
time.sleep(settings.waitDelay)
|
||||
except KeyboardInterrupt:
|
||||
log.info("keyboard-interrupt happened, cleaning up")
|
||||
conSetup.disconnectAny(connections)
|
||||
freeLock()
|
||||
|
||||
try:
|
||||
input = raw_input
|
||||
except NameError:
|
||||
pass
|
||||
check_dirs_and_files()
|
||||
conSetup = ConnectionSetup(log)
|
||||
connectedSensors = []
|
||||
connections = []
|
||||
try:
|
||||
log.info("setting up all sensors")
|
||||
while True:
|
||||
if obtain_lock():
|
||||
logger = Logger(log)
|
||||
for con in settings.hosts:
|
||||
try:
|
||||
log.info("connecting to host '" + str(con) + "'")
|
||||
con = settings.hosts[con]
|
||||
connection, sensors = conSetup.setup_connection_and_sensors(con['host'], con['sensors'], logger.cb_generic)
|
||||
connections.append(connection)
|
||||
connectedSensors.append(sensors)
|
||||
log.info("started logging at " + format_host(con['host']))
|
||||
except Exception as inst:
|
||||
# connection failed, log and exit
|
||||
# TODO: logger.print_exception(inst)
|
||||
log.error("connection failed: " + str(inst))
|
||||
# noinspection PyUnboundLocalVariable
|
||||
input("Press key to restart\n")
|
||||
log.info("stop logging... @" + time.ctime() + "\n")
|
||||
conSetup.disconnect_any(connections)
|
||||
free_lock()
|
||||
else:
|
||||
log.critical("lock collision: lock 'all' active")
|
||||
log.info("wait for retry (" + str(settings.waitDelay) + ")")
|
||||
time.sleep(settings.waitDelay)
|
||||
except KeyboardInterrupt:
|
||||
log.info("keyboard-interrupt happened, cleaning up")
|
||||
conSetup.disconnect_any(connections)
|
||||
free_lock()
|
||||
|
|
|
|||
85
move.py
85
move.py
|
|
@ -1,7 +1,6 @@
|
|||
#!/usr/bin/env python
|
||||
# -*- coding: utf-8 -*-
|
||||
|
||||
import time
|
||||
import os
|
||||
import logging
|
||||
from shutil import move
|
||||
|
|
@ -9,53 +8,57 @@ from shutil import move
|
|||
from timeFunctions import *
|
||||
from config import settings
|
||||
|
||||
def setupLogger():
|
||||
log = logging.getLogger("weatherstation.move")
|
||||
log.setLevel(logging.INFO)
|
||||
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.movelog))
|
||||
fh.setFormatter(formatter)
|
||||
log.addHandler(fh)
|
||||
return log
|
||||
|
||||
log = setupLogger()
|
||||
def setup_logger():
|
||||
log = logging.getLogger("weatherstation.move")
|
||||
log.setLevel(logging.INFO)
|
||||
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.movelog))
|
||||
fh.setFormatter(formatter)
|
||||
log.addHandler(fh)
|
||||
return log
|
||||
|
||||
checkfile=os.path.join(settings.locks,settings.movelock)
|
||||
|
||||
log = setup_logger()
|
||||
|
||||
checkfile = os.path.join(settings.locks, settings.movelock)
|
||||
|
||||
if not os.path.exists(checkfile):
|
||||
open(checkfile,'w').close()
|
||||
open(checkfile, 'w').close()
|
||||
if not os.path.exists(settings.arch):
|
||||
os.mkdir(arch, 0o000755)
|
||||
os.mkdir(settings.arch, 0o000755)
|
||||
|
||||
|
||||
def mycopy(keep):
|
||||
names = os.listdir(settings.records)
|
||||
for name in names:
|
||||
if keep in name:
|
||||
continue
|
||||
move(os.path.join(settings.records, name), settings.arch)
|
||||
names = os.listdir(settings.records)
|
||||
for name in names:
|
||||
if keep in name:
|
||||
continue
|
||||
move(os.path.join(settings.records, name), settings.arch)
|
||||
|
||||
check=open(checkfile,'r')
|
||||
temp=check.read()
|
||||
if len(temp)<1:
|
||||
check.close()
|
||||
check=open(checkfile,'w')
|
||||
check.write(str(time.time()))
|
||||
check.flush()
|
||||
log.info("updated time since file was empty")
|
||||
|
||||
check = open(checkfile, 'r')
|
||||
temp = check.read()
|
||||
if len(temp) < 1:
|
||||
check.close()
|
||||
check = open(checkfile, 'w')
|
||||
check.write(str(time.time()))
|
||||
check.flush()
|
||||
log.info("updated time since file was empty")
|
||||
else:
|
||||
last=time.gmtime(float(temp))
|
||||
now=time.gmtime()
|
||||
if(prevday(last,now)):
|
||||
log.info("moving records")
|
||||
mycopy(preptime())
|
||||
check.close()
|
||||
check=open(checkfile,'w')
|
||||
check.write(str(time.time()))
|
||||
check.flush()
|
||||
else:
|
||||
log.info("records were moved today already")
|
||||
last = time.gmtime(float(temp))
|
||||
now = time.gmtime()
|
||||
if prevday(last, now):
|
||||
log.info("moving records")
|
||||
mycopy(preptime())
|
||||
check.close()
|
||||
check = open(checkfile, 'w')
|
||||
check.write(str(time.time()))
|
||||
check.flush()
|
||||
else:
|
||||
log.info("records were moved today already")
|
||||
check.close()
|
||||
|
|
|
|||
|
|
@ -3,27 +3,28 @@
|
|||
|
||||
import time
|
||||
|
||||
|
||||
def prevday(then, now):
|
||||
#ist "then" gestern (oder noch älter)?
|
||||
greaterDay = (then.tm_yday < now.tm_yday) and (then.tm_year == now.tm_year)
|
||||
if greaterDay:
|
||||
newYear = False
|
||||
else:
|
||||
newYear = then.tm_year < now.tm_year
|
||||
return greaterDay or newYear
|
||||
# ist "then" gestern (oder noch älter)?
|
||||
greater_day = (then.tm_yday < now.tm_yday) and (then.tm_year == now.tm_year)
|
||||
if greater_day:
|
||||
new_year = False
|
||||
else:
|
||||
new_year = then.tm_year < now.tm_year
|
||||
return greater_day or new_year
|
||||
|
||||
|
||||
def preptime():
|
||||
now = time.localtime()
|
||||
day = now.tm_mday
|
||||
month = now.tm_mon
|
||||
year = str(now.tm_year)
|
||||
if day < 10:
|
||||
day = "0" + str(day)
|
||||
else:
|
||||
day = str(day)
|
||||
if month < 10:
|
||||
month = "0" + str(month)
|
||||
else:
|
||||
month = str(month)
|
||||
return month + "." + day + "." + year
|
||||
|
||||
now = time.localtime()
|
||||
day = now.tm_mday
|
||||
month = now.tm_mon
|
||||
year = str(now.tm_year)
|
||||
if day < 10:
|
||||
day = "0" + str(day)
|
||||
else:
|
||||
day = str(day)
|
||||
if month < 10:
|
||||
month = "0" + str(month)
|
||||
else:
|
||||
month = str(month)
|
||||
return month + "." + day + "." + year
|
||||
|
|
|
|||
Loading…
Reference in New Issue