def __getaggregatevalue(self, start, location, sensor, type='avg'): filterObj = { 'start': start, 'location': [str(location)], 'sensor': [str(sensor.get_id())], 'limit': 1, 'quality': 0.5 } multi_model = Measurements() if type == 'min': mlist = multi_model.get_min(filterObj) elif type == 'max': mlist = multi_model.get_max(filterObj) else: avg_obj = multi_model.get_avg(filterObj) mlist = [avg_obj] if len(mlist) == 0: return self.unknownValue else: value = mlist[0].get_value() if value is not None: impl = sensor.get_sensor_impl() if impl is not None: value = impl.round(value) return str(value) else: return self.unknownValue
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 __trigger(self, sensors, pending=False): data = [] interval = None if pending is True: interval = ConfigManager.Instance().get_interval() if interval < 1: return [] # No valid interval specified location = Locations().get(ConfigManager.Instance().get_location()) if location is None: return data # No location found for this id measurements = Measurements() for sensor in sensors: # Sensor is disabled, ignore it if not sensor.is_active(): continue # Ignore the sensor if no implementation can be found impl = sensor.get_sensor_impl() if impl is None: continue # If we want to trigger only pending sensors, check that and ignore sensors that are not pending to their rules if pending is True and impl.is_due(sensor.get_extra('pending'), interval) is False: continue measurementObj = None try: measurementObj = impl.get_measurement() except: print("Could not take a measurement for sensor " + str(sensor.get_id())) if measurementObj is not None: measurement = measurements.create() measurement.set_value(measurementObj.get_value()) measurement.set_quality(measurementObj.get_quality()) measurement.set_sensor(sensor) measurement.set_location(location) measurement.create() data.append(measurement) Notifiers().notify(measurement) return data
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 __trigger(self, sensors, pending = False): data = [] interval = None if pending is True: interval = ConfigManager.Instance().get_interval() if interval < 1: return [] # No valid interval specified location = Locations().get(ConfigManager.Instance().get_location()) if location is None: return data # No location found for this id measurements = Measurements() for sensor in sensors: # Sensor is disabled, ignore it if not sensor.is_active(): continue # Ignore the sensor if no implementation can be found impl = sensor.get_sensor_impl() if impl is None: continue # If we want to trigger only pending sensors, check that and ignore sensors that are not pending to their rules if pending is True and impl.is_due(sensor.get_extra('pending'), interval) is False: continue measurementObj = None try: measurementObj = impl.get_measurement() except: print("Could not take a measurement for sensor " + str(sensor.get_id())) if measurementObj is not None: measurement = measurements.create() measurement.set_value(measurementObj.get_value()) measurement.set_quality(measurementObj.get_quality()) measurement.set_sensor(sensor) measurement.set_location(location) measurement.create() data.append(measurement) Notifiers().notify(measurement) return data
def read_data(): # Here a call to the modbus must happen to fetch the data timestamp = datetime.datetime.now().strftime("%Y-%-m-%-d %H:%M:%S.%f %Z%z") volts = readModbus(config['DEFAULT']['METER_HOST'], config['DEFAULT']['METER_PORT'], 13312, 3, 0.1) amperes = readModbus(config['DEFAULT']['METER_HOST'], config['DEFAULT']['METER_PORT'], 13318, 3, 0.1) kWh = readModbus(config['DEFAULT']['METER_HOST'], config['DEFAULT']['METER_PORT'], 13324, 3, 0.001) return Measurements(timestamp, "no failure", volts, amperes, kWh)
def __getlastvalue(self, location, sensor): filterObj = { 'location': [str(location)], 'sensor': [str(sensor)], 'limit': 1 } mlist = Measurements().get_last(filterObj) if len(mlist) > 0: value = mlist[0].get_value() if value is not None: return {'last': str(value), 'datetime': mlist[0].datetime.strftime("%a %b %d %Y %H:%M:%S")} return {'last': self.unknownValue, 'datetime': self.unknownValue}
def send(self, notifier, subscriber, measurement): print("EmailTrend") if measurement.get_sensor() not in self.trend_data: return limit = self.get_setting("limit") critical = Measurements().reaches_limit_in_time( limit, self.hour_limit, self.trend_data[measurement.get_sensor()]) if critical is False: return name = ConfigManager.Instance().get_name() fromAddr = self.get_setting("sender") self._send_mail( "Warning from " + name, # ToDo: Better e-mail content "Limit " + str(limit) + " might be reached in " + str(self.hour_limit) + " hours. \r\nDevice: " + name + "\r\nSensor: " + str(measurement.get_sensor()) + "\r\nMeasurement value: " + str(measurement.get_value()), subscriber.get_setting('email'), fromAddr)
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)
def __init__(self): super().__init__() self.multi_model = Measurements()
class DataController(BaseController): def __init__(self): super().__init__() self.multi_model = Measurements() 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 last(self): data = self.multi_model.get_last(self._get_filter()) return self.get_view().data(data) def list(self): data = self.multi_model.get_all(self._get_filter()) return self.get_view().data(data) def min(self): data = self.multi_model.get_min(self._get_filter()) return self.get_view().data(data) def max(self): data = self.multi_model.get_max(self._get_filter()) return self.get_view().data(data) def avg(self): data = self.multi_model.get_avg(self._get_filter()) return self.get_view().data(data) def trend(self): valid = Validate() data = None location = request.args.get('location') if not valid.integer(location): location = None sensor = request.args.get('sensor') if valid.integer(sensor): data = self.multi_model.calc_trend(sensor, location) if data is None: return self.get_view().bad_request("No valid sensor id specified.") else: return self.get_view().data(data) def _get_filter(self): valid = Validate() args = {} start = request.args.get('start') if valid.iso_timestamp(start): args['start'] = start end = request.args.get('end') if valid.iso_timestamp(end): args['end'] = end location = request.args.get('location') if valid.comma_separated_numbers(location): args['location'] = location.split(',') sensor = request.args.get('sensor') if valid.comma_separated_numbers(sensor): args['sensor'] = sensor.split(',') geometry = request.args.get('geometry') if valid.wkt(geometry): args['geometry'] = geometry quality = request.args.get('quality') if valid.floating(quality) and float(quality) >= 0.0 and float(quality) <= 1.0: args['quality'] = float(quality) limit = request.args.get('limit') if valid.integer(limit) and int(limit) > 0: args['limit'] = int(limit) if args['limit'] > 10000: args['limit'] = 10000 page = request.args.get('page') if valid.integer(page) and int(page) > 0: args['page'] = int(page) return args
class DataController(BaseController): def __init__(self): super().__init__() self.multi_model = Measurements() 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 last(self): data = self.multi_model.get_last(self._get_filter()) return self.get_view().data(data) def list(self): data = self.multi_model.get_all(self._get_filter()) return self.get_view().data(data) def min(self): data = self.multi_model.get_min(self._get_filter()) return self.get_view().data(data) def max(self): data = self.multi_model.get_max(self._get_filter()) return self.get_view().data(data) def avg(self): data = self.multi_model.get_avg(self._get_filter()) return self.get_view().data(data) def trend(self): valid = Validate() data = None location = request.args.get('location') if not valid.integer(location): location = None sensor = request.args.get('sensor') if valid.integer(sensor): data = self.multi_model.calc_trend(sensor, location) if data is None: return self.get_view().bad_request("No valid sensor id specified.") else: return self.get_view().data(data) def _get_filter(self): valid = Validate() args = {} start = request.args.get('start') if valid.iso_timestamp(start): args['start'] = start end = request.args.get('end') if valid.iso_timestamp(end): args['end'] = end location = request.args.get('location') if valid.comma_separated_numbers(location): args['location'] = location.split(',') sensor = request.args.get('sensor') if valid.comma_separated_numbers(sensor): args['sensor'] = sensor.split(',') geometry = request.args.get('geometry') if valid.wkt(geometry): args['geometry'] = geometry quality = request.args.get('quality') if valid.floating( quality) and float(quality) >= 0.0 and float(quality) <= 1.0: args['quality'] = float(quality) limit = request.args.get('limit') if valid.integer(limit) and int(limit) > 0: args['limit'] = int(limit) if args['limit'] > 10000: args['limit'] = 10000 page = request.args.get('page') if valid.integer(page) and int(page) > 0: args['page'] = int(page) return args