introduced logging with loggers

master
agp8x 2015-08-25 16:13:35 +02:00
parent 28058f82d1
commit 8543c3c3f0
7 changed files with 200 additions and 136 deletions

View File

@ -1,31 +0,0 @@
#!/usr/bin/python3
# -*- coding: utf-8 -*-
try:
from tinkerforge.ip_connection import IPConnection
except ImportError:
print("package 'tinkerforge' not installed, canceling")
raise
from SensorSetup import SensorSetup
class ConnectionSetup(object):
def setupConnection(self, host):
ipcon = IPConnection()
ipcon.connect(host['name'], host['port'])
return (ipcon)
def setupConnectionAndSensors(self, host, sensors, cbtimes, cb_generic):
hostname = host['name']
port = host['port']
ipcon = IPConnection()
ipcon.connect(hostname, port)
sensorSetup = SensorSetup(ipcon, sensors, cbtimes, cb_generic)
connectedSensors = sensorSetup.setupSensors()
return (ipcon, connectedSensors)
def disconnectAny(self, connections):
for connection in connections:
if not connection.get_connection_state() is IPConnection.CONNECTION_STATE_DISCONNECTED:
connection.disconnect()

View File

@ -5,6 +5,8 @@ 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
from timeFunctions import * from timeFunctions import *
from settings import SensorType from settings import SensorType
@ -21,13 +23,34 @@ class Logger(object):
self.log = log self.log = log
self.records = settings.records self.records = settings.records
self.units = settings.SENSOR_UNITS self.units = settings.SENSOR_UNITS
self.dataecho = self.setup_data_echo()
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, "records.log"))
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):
return True return True
if(((old-new) > self.temp_max_diff) or ((new-old) > self.temp_max_diff)): if(((old-new) > self.temp_max_diff) or ((new-old) > self.temp_max_diff)):
self.log.write('error checking ' + sensor + ';prev(' + str(old) + ');cur(' + str(new) + '); ... @' + time.ctime() + "\n") self.log.error('error checking ' + sensor + ';prev(' + str(old) + ');cur(' + str(new) + ');')
self.log.flush()
return False return False
else: else:
return True return True
@ -36,11 +59,12 @@ class Logger(object):
# common function to write value to file # # common function to write value to file #
########################################## ##########################################
def write_value(self, value, sensor): def write_value(self, value, sensor):
# TODO: catch IOError # TODO: replace with self.datalog
valuename = self.records + "/" + sensor + "_" + preptime() valuename = self.records + "/" + sensor + "_" + preptime()
valuelog=open(valuename, 'a') valuelog=open(valuename, 'a')
valuelog.write(str(value) + ';' + str( int(time.time()) ) + "\n") valuelog.write(str(value) + ';' + str( int(time.time()) ) + "\n")
valuelog.close() valuelog.close()
self.datalog.info('%s;%s;%s',value, int(time.time()), sensor)
########################################## ##########################################
# generic callback # # generic callback #
@ -57,7 +81,7 @@ class Logger(object):
self.write_value(value, sensor) self.write_value(value, sensor)
unit = self.units[type] unit = self.units[type]
if not supress: if not supress:
print(sensor + ': ' + str(value/unit[0]) + ' ' + unit[1] + ', ' + str(time.ctime()) ) self.dataecho.info(sensor + ': ' + str(value/unit[0]) + ' ' + unit[1])
########################################### ###########################################
# exception logging # # exception logging #
@ -70,7 +94,6 @@ class Logger(object):
root.append(new) root.append(new)
tree.write(settings.exceptionlog) tree.write(settings.exceptionlog)
message = 'an Exception happend @' + time.ctime()+"\n" message = 'an Exception happend @' + time.ctime()+"\n"
self.log.write(message) self.log.error(message)
self.log.flush()
print(message) print(message)

View File

@ -2,10 +2,12 @@
# -*- coding: utf-8 -*- # -*- coding: utf-8 -*-
try: try:
from tinkerforge.ip_connection import IPConnection
from tinkerforge.bricklet_temperature import Temperature from tinkerforge.bricklet_temperature import Temperature
from tinkerforge.bricklet_humidity import Humidity from tinkerforge.bricklet_humidity import Humidity
from tinkerforge.bricklet_ambient_light import AmbientLight from tinkerforge.bricklet_ambient_light import AmbientLight
from tinkerforge.bricklet_barometer import Barometer from tinkerforge.bricklet_barometer import Barometer
from tinkerforge.bricklet_temperature_ir import BrickletTemperatureIR
except ImportError: except ImportError:
print("package 'tinkerforge' not installed, canceling") print("package 'tinkerforge' not installed, canceling")
raise raise
@ -13,13 +15,37 @@ from functools import partial
import traceback import traceback
from settings import SensorType from settings import SensorType
class ConnectionSetup(object):
def __init__(self, log):
self.log = log
def setupConnection(self, host):
ipcon = IPConnection()
ipcon.connect(host['name'], host['port'])
return (ipcon)
def setupConnectionAndSensors(self, host, sensors, cbtimes, cb_generic):
hostname = host['name']
port = host['port']
ipcon = IPConnection()
ipcon.connect(hostname, port)
sensorSetup = SensorSetup(ipcon, sensors, cbtimes, cb_generic, self.log)
connectedSensors = sensorSetup.setupSensors()
return (ipcon, connectedSensors)
def disconnectAny(self, connections):
for connection in connections:
if not connection.get_connection_state() is IPConnection.CONNECTION_STATE_DISCONNECTED:
connection.disconnect()
class SensorSetup(object): class SensorSetup(object):
def __init__(self, connection, sensors, cbtimes, cb_generic): def __init__(self, connection, sensors, cbtimes, cb_generic, log):
self.connection = connection self.connection = connection
self.sensors = sensors self.sensors = sensors
self.cbtimes = cbtimes self.cbtimes = cbtimes
self.cb_generic = cb_generic self.cb_generic = cb_generic
self.log = log
def parametrizedCallback(self, name, type): def parametrizedCallback(self, name, type):
return partial(self.cb_generic, sensor=name, type=type) return partial(self.cb_generic, sensor=name, type=type)
@ -52,6 +78,20 @@ class SensorSetup(object):
cb = Barometer.CALLBACK_AIR_PRESSURE cb = Barometer.CALLBACK_AIR_PRESSURE
return obj, setcb, get, cb return obj, setcb, get, cb
def getIram(self):
obj = BrickletTemperatureIR # Object
setcb = obj.set_ambient_temperature_callback_period # set-callback-period-method-pointer
get = obj.get_ambient_temperature # value-get-method-pointer
cb = BrickletTemperatureIR.CALLBACK_AMBIENT_TEMPERATURE # callback identifier
return obj, setcb, get, cb
def getIrob(self):
obj = BrickletTemperatureIR # Object
setcb = obj.set_object_temperature_callback_period # set-callback-period-method-pointer
get = obj.get_object_temperature # value-get-method-pointer
cb = BrickletTemperatureIR.CALLBACK_OBJECT_TEMPERATURE # callback identifier
return obj, setcb, get, cb
#def getNew(self): #def getNew(self):
# obj = Bricklet # Object # obj = Bricklet # Object
# setcb = obj.set_XXX_callback_period # set-callback-period-method-pointer # setcb = obj.set_XXX_callback_period # set-callback-period-method-pointer
@ -79,14 +119,22 @@ class SensorSetup(object):
var = self.getAmbi() var = self.getAmbi()
elif sensor[1] is SensorType.baro: elif sensor[1] is SensorType.baro:
var = self.getBaro() var = self.getBaro()
elif sensor[1] is SensorType.iram:
var = self.getIram()
elif sensor[1] is SensorType.irob:
var = self.getIrob()
else:
self.log.error("FAILED TO LOAD "+name)
return None
try: try:
obj = self.__setupSensor__(callback, sensor[0], cbtime, var) obj = self.__setupSensor__(callback, sensor[0], cbtime, var)
status += "OK" status += "OK"
self.log.info(status)
except Exception as e: except Exception as e:
status += "FAIL" status += "FAIL"
#print(e) #print(e)
#print(traceback.format_exc()) #print(traceback.format_exc())
print(status) self.log.error(status)
return obj return obj
def setupSensors(self): def setupSensors(self):
@ -96,3 +144,4 @@ class SensorSetup(object):
obj = self.genericSensorSetup(name, sensor) obj = self.genericSensorSetup(name, sensor)
connected.append(obj) connected.append(obj)
return connected return connected

82
all.py
View File

@ -1,82 +0,0 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os.path
import os
import time
from Logger import Logger
from ConnectionSetup import ConnectionSetup
import settings
def check_dirs_and_files():
# log
if not os.path.exists(settings.logs):
os.mkdir(settings.logs, 0000755)
if not os.path.exists(settings.logname):
open(settings.logname, 'w').close()
if not os.path.exists(settings.exceptionlog):
file=open(settings.exceptionlog, 'w')
file.write("<exceptions></exceptions>")
file.close()
# lock
if not os.path.exists(settings.locks):
os.mkdir(settings.locks, 0000755)
# records
if not os.path.exists(settings.records):
os.mkdir(settings.records, 0000755)
def obtainLock(lockfile = settings.lockname):
if not os.path.exists(lockfile):
lock = open(lockfile, 'w')
lock.write( str(time.time()) )
lock.close()
return True
return False
def freeLock(lockfile = settings.lockname):
if os.path.exists(lockfile):
os.remove(lockfile)
def formatHost(host):
return "%s:%d" % (host['name'], host['port'])
if __name__ == "__main__":
check_dirs_and_files()
log=open(settings.logname, 'a')
try:
log.write("setting up all ... @" + time.ctime() + "\n")
while True:
if obtainLock():
logger = Logger(log)
try:
connections = []
connectedSensors = []
for con in settings.SENSORS:
con = settings.SENSORS[con]
conSetup = ConnectionSetup()
connection, sensors = conSetup.setupConnectionAndSensors(con['host'], con['sensors'], settings.TIMES, logger.cb_generic)
connections.append(connection)
connectedSensors.append(sensors)
log.write("started logging at " + formatHost(con['host']) + " ... @ " + time.ctime() + "\n")
log.flush()
raw_input("Press key to restart\n")
log.write("stop logging... @" + time.ctime() + "\n")
conSetup.disconnectAny(connections)
except Exception as inst:
#connection failed, log and exit
logger.printException(inst)
print(inst)
freeLock()
else:
print("lock file active!!")
log.write("lock collision: lock 'all' active @ " + time.ctime() + "\n")
print("wait for retry (" + str(settings.waitDelay) + ")")
time.sleep(settings.waitDelay)
except KeyboardInterrupt:
print(" Interrupted, cleaning up")
conSetup.disconnectAny(connections)
log.write("keyboard-interrupt happened @" + time.ctime() + "\n")
log.close()
freeLock()

95
main.py Normal file
View File

@ -0,0 +1,95 @@
#!/usr/bin/env python3
# -*- coding: utf-8 -*-
import os.path
import os
import time
import logging
from Logger import Logger
from Setup import ConnectionSetup
import settings
def setupLogger():
log = logging.getLogger("weatherstation")
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, "logging.log"))
fh.setFormatter(formatter)
log.addHandler(fh)
return log
logi = setupLogger()
def check_dirs_and_files():
# log
if not os.path.exists(settings.logs):
os.mkdir(settings.logs, 0000755)
#if not os.path.exists(settings.logname):
# open(settings.logname, 'w').close()
if not os.path.exists(settings.exceptionlog):
file=open(settings.exceptionlog, 'w')
file.write("<exceptions></exceptions>")
file.close()
# lock
if not os.path.exists(settings.locks):
os.mkdir(settings.locks, 0000755)
# records
if not os.path.exists(settings.records):
os.mkdir(settings.records, 0000755)
def obtainLock(lockfile = settings.lockname):
if not os.path.exists(lockfile):
lock = open(lockfile, 'w')
lock.write( str(time.time()) )
lock.close()
return True
return False
def freeLock(lockfile = settings.lockname):
if os.path.exists(lockfile):
os.remove(lockfile)
def formatHost(host):
return "%s:%d" % (host['name'], host['port'])
if __name__ == "__main__":
check_dirs_and_files()
try:
logi.info("setting up all sensors")
while True:
if obtainLock():
logger = Logger(logi)
connections = []
connectedSensors = []
for con in settings.SENSORS:
try:
logi.info("connecting to host '"+str(con)+"'")
con = settings.SENSORS[con]
conSetup = ConnectionSetup(logi)
connection, sensors = conSetup.setupConnectionAndSensors(con['host'], con['sensors'], settings.TIMES, logger.cb_generic)
connections.append(connection)
connectedSensors.append(sensors)
logi.info("started logging at " + formatHost(con['host']))
except Exception as inst:
#connection failed, log and exit
#TODO: logger.printException(inst)
logi.error("connection failed: "+str(inst))
raw_input("Press key to restart\n")
logi.info("stop logging... @" + time.ctime() + "\n")
conSetup.disconnectAny(connections)
freeLock()
else:
logi.critical("lock collision: lock 'all' active")
logi.info("wait for retry (" + str(settings.waitDelay) + ")")
time.sleep(settings.waitDelay)
except KeyboardInterrupt:
logi.info("keyboard-interrupt happened, cleaning up")
conSetup.disconnectAny(connections)
freeLock()

View File

@ -3,9 +3,9 @@
import time import time
import os import os
from shutil import move
from timeFunctions import * from timeFunctions import *
from settings import locks, logs from settings import locks, logs
from shutil import move
checkfile=locks+'/records_moved' checkfile=locks+'/records_moved'

View File

@ -4,19 +4,14 @@
#class SensorType(Enum): #class SensorType(Enum):
class SensorType: class SensorType:
none = 0 none = 0
temp = 1 temp = 1 # temperature bricklet
humi = 2 humi = 2 # humidity bricklet
ambi = 3 ambi = 3 # ambient light bricklet
baro = 4 baro = 4 # barometer bricklet
rain = 5 rain = 5 # IO4 #TODO
iram = 6 # temperature ir bricklet, ambient #TODO
irob = 7 # temperature ir bricklet, object #TODO
#HOST = "localhost" """
#HOST = "192.168.2.34"
HOST = "192.168.2.60"
PORT = 4223
SENSORS={
0: { 0: {
"host": { "host": {
"name": "192.168.2.60", "name": "192.168.2.60",
@ -32,6 +27,15 @@ SENSORS={
"temp3": ["8ms", SensorType.temp], "temp3": ["8ms", SensorType.temp],
"humi2": ["9V5", SensorType.humi], "humi2": ["9V5", SensorType.humi],
} }
},"""
SENSORS={
"irtest": {
"host":{"name": "localhost", "port":4223},
"sensors":{
"iram": ["c8w", SensorType.iram],
"iram2": ["c8ws", SensorType.iram],
"irob": ["c8w", SensorType.irob]
}
} }
} }
@ -40,6 +44,9 @@ TIMES={
SensorType.humi: 30000, SensorType.humi: 30000,
SensorType.ambi: 60000, SensorType.ambi: 60000,
SensorType.baro: 60000, SensorType.baro: 60000,
SensorType.rain: 60000,
SensorType.iram: 1000,
SensorType.irob: 1000,
} }
tempmaxdiff=200 # 200== 2.0 C tempmaxdiff=200 # 200== 2.0 C
@ -49,6 +56,7 @@ logs='logs'
locks='locks' locks='locks'
records='records' records='records'
#TODO: add move-log, move-lock, logging instead of writing to files
lockname=locks+"/all.lock" lockname=locks+"/all.lock"
logname=logs+"/all.log" logname=logs+"/all.log"
exceptionlog=logs+"/exceptions.xml" exceptionlog=logs+"/exceptions.xml"
@ -65,7 +73,9 @@ SENSOR_UNITS=[
(10.0, '%RH'), (10.0, '%RH'),
(10.0, 'Lux'), (10.0, 'Lux'),
(1000, 'mbar'), (1000, 'mbar'),
(2.5, 'l/qm') (2.5, 'l/qm'),
(10.0, '°C'),
(10.0, '°C')
] ]
########################### ###########################