introduced logging with loggers
parent
28058f82d1
commit
8543c3c3f0
|
|
@ -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()
|
||||
|
||||
35
Logger.py
35
Logger.py
|
|
@ -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)
|
||||
|
||||
|
|
|
|||
|
|
@ -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
82
all.py
|
|
@ -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()
|
||||
|
||||
|
|
@ -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()
|
||||
|
||||
2
move.py
2
move.py
|
|
@ -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'
|
||||
|
||||
|
|
|
|||
38
settings.py
38
settings.py
|
|
@ -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')
|
||||
]
|
||||
|
||||
###########################
|
||||
|
|
|
|||
Loading…
Reference in New Issue