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 traceback
import xml.etree.ElementTree as ET
import logging
import os
from timeFunctions import *
from settings import SensorType
@ -21,13 +23,34 @@ class Logger(object):
self.log = log
self.records = settings.records
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):
if(old == self.temp_prev_default):
return True
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.flush()
self.log.error('error checking ' + sensor + ';prev(' + str(old) + ');cur(' + str(new) + ');')
return False
else:
return True
@ -36,11 +59,12 @@ class Logger(object):
# common function to write value to file #
##########################################
def write_value(self, value, sensor):
# TODO: catch IOError
# TODO: replace with self.datalog
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 #
@ -57,7 +81,7 @@ class Logger(object):
self.write_value(value, sensor)
unit = self.units[type]
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 #
@ -70,7 +94,6 @@ class Logger(object):
root.append(new)
tree.write(settings.exceptionlog)
message = 'an Exception happend @' + time.ctime()+"\n"
self.log.write(message)
self.log.flush()
self.log.error(message)
print(message)

View File

@ -2,10 +2,12 @@
# -*- coding: utf-8 -*-
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
except ImportError:
print("package 'tinkerforge' not installed, canceling")
raise
@ -13,13 +15,37 @@ from functools import partial
import traceback
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):
def __init__(self, connection, sensors, cbtimes, cb_generic):
def __init__(self, connection, sensors, cbtimes, cb_generic, log):
self.connection = connection
self.sensors = sensors
self.cbtimes = cbtimes
self.cb_generic = cb_generic
self.log = log
def parametrizedCallback(self, name, type):
return partial(self.cb_generic, sensor=name, type=type)
@ -52,6 +78,20 @@ class SensorSetup(object):
cb = Barometer.CALLBACK_AIR_PRESSURE
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):
# obj = Bricklet # Object
# setcb = obj.set_XXX_callback_period # set-callback-period-method-pointer
@ -79,14 +119,22 @@ class SensorSetup(object):
var = self.getAmbi()
elif sensor[1] is SensorType.baro:
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:
obj = self.__setupSensor__(callback, sensor[0], cbtime, var)
status += "OK"
self.log.info(status)
except Exception as e:
status += "FAIL"
#print(e)
#print(traceback.format_exc())
print(status)
self.log.error(status)
return obj
def setupSensors(self):
@ -96,3 +144,4 @@ class SensorSetup(object):
obj = self.genericSensorSetup(name, sensor)
connected.append(obj)
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 os
from shutil import move
from timeFunctions import *
from settings import locks, logs
from shutil import move
checkfile=locks+'/records_moved'

View File

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