diff --git a/ConnectionSetup.py b/ConnectionSetup.py
deleted file mode 100644
index a697143..0000000
--- a/ConnectionSetup.py
+++ /dev/null
@@ -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()
-
diff --git a/Logger.py b/Logger.py
index b6019d7..68c62ff 100644
--- a/Logger.py
+++ b/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)
diff --git a/SensorSetup.py b/Setup.py
similarity index 60%
rename from SensorSetup.py
rename to Setup.py
index ddd8ea3..5a86b78 100644
--- a/SensorSetup.py
+++ b/Setup.py
@@ -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
+
diff --git a/all.py b/all.py
deleted file mode 100644
index 546de80..0000000
--- a/all.py
+++ /dev/null
@@ -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("")
- 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()
-
diff --git a/main.py b/main.py
new file mode 100644
index 0000000..378df7d
--- /dev/null
+++ b/main.py
@@ -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("")
+ 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()
+
diff --git a/move.py b/move.py
index 4d4167d..c70df56 100644
--- a/move.py
+++ b/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'
diff --git a/settings.py b/settings.py
index 4944822..298145a 100644
--- a/settings.py
+++ b/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')
]
###########################