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 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