def trigger(self): sensor = request.args.get('sensor') if Validate().integer(sensor): data = Sensors().trigger_one(sensor) else: data = Sensors().trigger_all() return self.get_view().data(data)
def is_due(self, minutes, interval): if minutes is None: # No measurement so far return True weatherSensor = Sensors().get_by_class('sensors.owmrain', 'OwmRainSnow') if weatherSensor is not None: weatherMeasurements = Measurements().get_last({ "sensor": [weatherSensor.get_id()], "limit": 1, "location": [ConfigManager.Instance().get_location()] }) new_interval = interval if len(weatherMeasurements) > 0: value = weatherMeasurements[0].get_value() if value > 30: new_interval = 2 # Measure every two minutes in case of heavy rain elif value > 0: new_interval = interval / 2 # Double the speed in case of light rain if new_interval < interval: interval = new_interval return (minutes >= interval)
def home(self): sensor_data = Sensors().get_all() sensor_id = None if sensor_data is not None and len(sensor_data) > 0: sensor_id = sensor_data[0].get_id() location = ConfigManager.Instance().get_location() locationObj = Locations().get(location) data = { 'setup': False, 'location': locationObj, 'default_sensor': sensor_id, 'sensors': {}, 'now': datetime.datetime.utcnow().strftime("%a %b %d %Y %H:%M:%S") } if locationObj is None or sensor_id is None: data['setup'] = True for sensor in sensor_data: sensor_id = sensor.get_id() last = self.__getlastvalue(location, sensor_id) data['sensors'][sensor_id] = { 'sensor': sensor, 'hourly': self.__getminmaxavgvalue(time.strftime('%Y-%m-%dT%H:00:00Z'), location, sensor), 'daily': self.__getminmaxavgvalue(time.strftime('%Y-%m-%dT00:00:00Z'), location, sensor), 'monthly': self.__getminmaxavgvalue(time.strftime('%Y-%m-01T00:00:00Z'), location, sensor), 'yearly': self.__getminmaxavgvalue(time.strftime('%Y-01-01T00:00:00Z'), location, sensor), 'accum': self.__getminmaxavgvalue('2015-01-01T00:00:00Z', location, sensor), 'last': last['last'], 'datetime': last['datetime'], 'trend': Measurements().calc_trend(sensor_id, location)['description'] } return self.get_view('index.html').data(data)
def subscription(self): input = request.get_json() if input is None: return self.get_view().bad_request('Expected json') if 'notifier' in input and 'sensor' in input and 'settings' in input: notifier = Notifiers().get(input['notifier']) if notifier is None or not notifier.is_public(): return self.get_view().bad_request('Not a valid notifier') sensor = Sensors().get(input['sensor']) if sensor is None: return self.get_view().bad_request('Not a valid sensor') subscription = Subscribers().create() try: subscription.set_notifier(int(input['notifier'])) subscription.set_sensor(int(input['sensor'])) # ToDo: Validate subscription settings subscription.set_settings(input['settings']) if not subscription.create(): return self.get_view().bad_request( 'The subscription you are trying to create does not exist try to create it instead' ) except ValueError: return self.get_view().bad_request( 'input not in the right format') else: return self.get_view().bad_request('not all necessary field set') return self.get_view().success()
def data(self): data = { 'locations': Locations().get_all(), 'sensors': Sensors().get_all(), 'timerange': Measurements().get_time_range(), 'location': ConfigManager.Instance().get_location() } return self.get_view('data.html').data(data)
def subscriptions_add(self, id): notifier = Notifiers().get(id) data = { "notifier": notifier, "notifier_impl": notifier.get_notifier_impl(), "sensors": Sensors().get_all() } return self.get_view('subscriptions_add.html').data(data)
def config_sensors_change(self, mode, id): if mode == 'add' and 'module' not in request.args: if request.method == 'POST': filename = OS().upload_file('sensors/', 'file'); return self._get_module_chooser("Add Sensor", "/config/sensors/add", "sensors", "Sensor") data = { "edit": (mode == 'edit'), "mode": mode, "sensor": None, "sensor_impl": None, "sensor_module": None, "modules": OS().get_classes("sensors", "Sensor") } if mode == 'edit' and id is not None: sensor = Sensors().get(id) data['sensor'] = sensor data['sensor_module'] = sensor.get_classpath() data['sensor_impl'] = sensor.get_sensor_impl() elif mode == 'add': data['sensor_module'] = request.args.get('module') data['sensor_impl'] = OS().create_object(data['sensor_module']) return self.get_view('config_sensor_change.html').data(data)
def config_subscriptions_change(self, mode, nid, sid): data = { "edit": (mode == 'edit'), "mode": mode, "subscriber": None, "notifier": None, "notifier_impl": None, "sensors": Sensors().get_all() } if mode == 'edit' and nid is not None: subscriber = Subscribers().get(sid) data['subscriber'] = subscriber data['notifier'] = subscriber.get_notifier_object() elif mode == 'add': data['notifier'] = Notifiers().get(nid) data["notifier_impl"] = data['notifier'].get_notifier_impl() return self.get_view('config_subscriptions_change.html').data(data)
def prepare(self): location = ConfigManager.Instance().get_location() sensors = Sensors().get_all() for sensor in sensors: self.trend_data[sensor.get_id()] = Measurements().calc_trend( sensor.get_id(), location)
#!/usr/bin/python3 # Sensor trigger executed by cron job import sys assert sys.version_info >= (3, 0) from utils.utils import OS from models.sensors import Sensors from views.json import JSON from utils.utils import ThreadObserver if __name__ == '__main__': OS().cwd(__file__) # Trigger sensors and save all sensor readings sensors = Sensors() data = sensors.trigger_pending() # Send json to cmd line for debugging json = JSON() print(json.build(data)) ThreadObserver.Instance().wait()
def calc_trend(self, sensor, location = None): data = { "since": None, "until": None, "timedelta": None, "change_abs": 0, "change_perhour": 0, "description": "No change computable" } if location is None: location = ConfigManager.Instance().get_location() from models.sensors import Sensors sensorObj = Sensors().get(sensor) if sensorObj is None: return None t = Transform() precision = 2 high_precision = 3 sensor_impl = sensorObj.get_sensor_impl() if sensor_impl is not None: precision = sensor_impl.low_precision() high_precision = sensor_impl.high_precision() last = self.get_last({ "sensor": [sensor], "location": [location], "limit": 1000, "quality": 0.5 }) if len(last) < 3: return data # Not enough data for calculation # Calculate whether its ascending or descending direction = 0 old = t.round(last[0].get_value(), precision) older = t.round(last[1].get_value(), precision) oldest = t.round(last[2].get_value(), precision) if oldest > older and older > old and old != oldest: direction = -1 # descending if oldest <= older and older <= old and old != oldest: direction = 1 # ascending if direction == 0: return data # No trend # Find how long the trend is outliers = 0 pivot = 0 prev_is_outlier = False i = 0 # Iterate over all elements until we have two outliers in a row, elements are getting older with increasing index while i < len(last)-1 and outliers < 2: i += 1 this = t.round(last[i-1].get_value(), precision) prev = t.round(last[i].get_value(), precision) # Check whether values are equal or are getting smaller/larger if (direction == 1 and prev <= this) or (direction == -1 and prev >= this): # If the elemts are equal... if (prev == this): # check if the previous entry was an outlier and if this one is the same value, end loop as we reached two outliers if prev_is_outlier is True: break # Value is smaller or larger else: pivot = i # If previous element was not an outlier, we can decrease the number of outliers if prev_is_outlier is False: outliers -= 1 # We detected an outlier else: outliers += 1 prev_is_outlier = True newest = last[0] oldest = last[pivot] data['oldest'] = oldest data['newest'] = newest data['timedelta'] = newest.get_datetime() - oldest.get_datetime() hourdelta = data['timedelta'].total_seconds() / (60*60) hours = int(hourdelta) minutes = int((hourdelta - hours) * 60) data['change_abs'] = t.round(abs(newest.get_value() - oldest.get_value()) * direction, high_precision) data['change_perhour'] = t.round(data['change_abs'] / hourdelta, high_precision) if direction == -1: data['description'] = 'Descreasing' else: data['description'] = 'Increasing' data['description'] += ' since ' if hours > 0: data['description'] += str(hours) + ' hours ' data['description'] += str(minutes) + ' minutes by ' + str(abs(data['change_perhour'])) + ' ' + sensorObj.get_unit() + '/h' return data
def sensor(self, id): if (request.method == 'DELETE'): sensor = Sensors().get(id) if sensor is None: return self.get_view().bad_request('Location does not exist') if sensor.delete(): return self.get_view().success() else: return self.get_view().error() elif (request.method == 'PUT'): input = request.get_json() if(input is None): return self.get_view().bad_request('expected json') if('id' in input): try: sensor = Sensors().get(int(input['id'])) if sensor is None: return self.get_view().bad_request('The sensor you are trying to update does not exist try to create it instead') if 'module' in input: sensor.set_module(str(input['module'])) if 'class_name' in input: sensor.set_class(str(input['class_name'])) if 'description' in input: sensor.set_description(str(input['description'])) if 'settings' in input: if not self.__validate_sensor_settings(sensor, input['settings']): return self.get_view().bad_request('Settings not in the right format') else: sensor.set_settings(input['settings']) if 'active' in input: sensor.set_active(bool(input['active'])) if not sensor.update(): return self.get_view().bad_request('The sensor you are trying to update does not exist try to create it instead') except ValueError: return self.get_view().bad_request('input not in the right format') else: return self.get_view().bad_request('not all necessary field set') return self.get_view().success() elif (request.method == 'POST'): input = request.get_json() if(input is None): return self.get_view().bad_request('expected json') if ('description' in input and 'module' in input and 'class_name' in input and 'active' in input and 'settings' in input): sensor = Sensors().create() try: sensor.set_module(str(input['module'])) sensor.set_class(str(input['class_name'])) sensor.set_description(str(input['description'])) sensor.set_active(bool(input['active'])) if not self.__validate_sensor_settings(sensor, input['settings']): return self.get_view().bad_request('Settings not in the right format') else: sensor.set_settings(input['settings']) if not sensor.create(): return self.get_view().bad_request('The sensor you are trying to create does not exist') except ValueError: return self.get_view().bad_request('input not in the right format') else: return self.get_view().bad_request('not all necessary field set') return self.get_view().success()
#!/usr/bin/python3 # Sensor trigger executed by cron job import sys assert sys.version_info >= (3,0) from utils.utils import OS from models.sensors import Sensors from views.json import JSON from utils.utils import ThreadObserver if __name__ == '__main__': OS().cwd(__file__) # Trigger sensors and save all sensor readings sensors = Sensors() data = sensors.trigger_pending() # Send json to cmd line for debugging json = JSON() print(json.build(data)) ThreadObserver.Instance().wait()
def get_sensor_object(self): from models.sensors import Sensors return Sensors().get(self.sensor)
def sensor(self, id): if (request.method == 'DELETE'): sensor = Sensors().get(id) if sensor is None: return self.get_view().bad_request('Location does not exist') if sensor.delete(): return self.get_view().success() else: return self.get_view().error() elif (request.method == 'PUT'): input = request.get_json() if (input is None): return self.get_view().bad_request('expected json') if ('id' in input): try: sensor = Sensors().get(int(input['id'])) if sensor is None: return self.get_view().bad_request( 'The sensor you are trying to update does not exist try to create it instead' ) if 'module' in input: sensor.set_module(str(input['module'])) if 'class_name' in input: sensor.set_class(str(input['class_name'])) if 'description' in input: sensor.set_description(str(input['description'])) if 'settings' in input: if not self.__validate_sensor_settings( sensor, input['settings']): return self.get_view().bad_request( 'Settings not in the right format') else: sensor.set_settings(input['settings']) if 'active' in input: sensor.set_active(bool(input['active'])) if not sensor.update(): return self.get_view().bad_request( 'The sensor you are trying to update does not exist try to create it instead' ) except ValueError: return self.get_view().bad_request( 'input not in the right format') else: return self.get_view().bad_request( 'not all necessary field set') return self.get_view().success() elif (request.method == 'POST'): input = request.get_json() if (input is None): return self.get_view().bad_request('expected json') if ('description' in input and 'module' in input and 'class_name' in input and 'active' in input and 'settings' in input): sensor = Sensors().create() try: sensor.set_module(str(input['module'])) sensor.set_class(str(input['class_name'])) sensor.set_description(str(input['description'])) sensor.set_active(bool(input['active'])) if not self.__validate_sensor_settings( sensor, input['settings']): return self.get_view().bad_request( 'Settings not in the right format') else: sensor.set_settings(input['settings']) if not sensor.create(): return self.get_view().bad_request( 'The sensor you are trying to create does not exist' ) except ValueError: return self.get_view().bad_request( 'input not in the right format') else: return self.get_view().bad_request( 'not all necessary field set') return self.get_view().success()
def list(self): data = Sensors().get_all() return self.get_view().data(data)
def config_sensors(self): data = {"sensors": Sensors().get_all()} return self.get_view('config_sensor.html').data(data)