def upload_map(map_id, sheet, config_type=1): """# upload_single: docstring args: re: --- arg returns: 0 --- """ result = [] iter_r = sheet.iter_rows() for i, row in enumerate(iter_r): if i == 0: continue if row[0].internal_value is None: break r = [] for cell in row: if cell.internal_value is None: break r.append(int(cell.internal_value)) result.append(r) c = ConfigManager.get_config_obj('map', config_type=config_type) if DEBUG or c.value.get(str(map_id)) != result: data = [(k, v) for k, v in c.value.iteritems()] data.sort(key=lambda x: x[0]) m_version = make_version(data) c.value[str(map_id)] = result c.version = m_version c.save() return m_version
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 __init__(self): config = ConfigManager.Instance() self.db = psycopg2.connect("dbname='" + config.get_dbname() + "' user='******' host='" + config.get_dbhost() + "' password='******'") self.db.autocommit = True # We might want to remove that and switch to transactions
def config_locations(self): data = { "locations": Locations().get_all(), "default_location": ConfigManager.Instance().get_location() } return self.get_view('config_location.html').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 trigger_pending(self): interval = ConfigManager.Instance().get_interval() if interval < 1: return [] # No valid interval specified sensors = self.get_pending() return self.__trigger(sensors, True)
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 _parse_template(self, data): if self.template is not None: template = self.template else: template = "default.html" return render_template(template, data=data, config=ConfigManager.Instance())
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 get_measurement(self): lid = ConfigManager.Instance().get_location() data = super().get_measurement() if lid is None or data is None: return None location = Locations().get(lid) if location is None or location.get_height() is None: return None value = location.get_height() - data.get_value() value = self.round(value) return SensorMeasurement(value, data.get_quality())
def send(self, notifier, subscriber, measurement): if measurement.get_quality() < 0.5: return # ignore measurements with a bad quality name = ConfigManager.Instance().get_name() fromAddr = notifier.get_setting("sender") self._send_mail( "New measurement notification from " + name, # ToDo: Better e-mail content "Device: " + name + "\r\nSensor: " + str(measurement.get_sensor()) + "\r\nMeasurement value: " + str(measurement.get_value()), subscriber.get_setting('email'), fromAddr)
def upload_box_reward(box_id, sheet, config_type=1): """# upload_single: docstring args: re: --- arg returns: 0 --- """ data = xls_convert.to_pyobj(sheet) str_config = xls_convert.to_config_string('box_reward', data) dict_config = eval(str_config) c = ConfigManager.get_config_obj('box_reward_new', config_type=config_type) if DEBUG or c.value.get(box_id) != dict_config: data = [(k, sorted(v.iteritems(), key=lambda x: x[1])) for k, v in c.value.iteritems()] data.sort(key=lambda x: x[0]) m_version = make_version(data) c.value[box_id] = dict_config c.version = m_version c.save() return m_version
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 get_measurement(self): if self.owm is None: api_key = self.get_setting("apikey") if api_key is None or len(api_key) < 1: return None self.owm = pyowm.OWM(api_key) lid = ConfigManager.Instance().get_location() if lid is None: return None location = Locations().get(lid) if location is None or location.get_latitude() is None or location.get_longitude() is None: return None obs = self.owm.weather_at_coords(location.get_latitude(), location.get_longitude()) w = obs.get_weather() vol_rain = w.get_rain() vol_snow = w.get_snow() value = None quality = 1.0 if '3h' in vol_rain and '3h' in vol_snow: value = vol_rain['3h'] + vol_snow['3h'] elif '3h' in vol_rain: value = vol_rain['3h'] quality = 0.5 elif '3h' in vol_snow: value = vol_snow['3h'] quality = 0.5 else: # Not sure whether this is true (API returns nothing when there is no rain/snow?) value = 0 quality = 0.0 if value is not None: value = self.round(value) return SensorMeasurement(value, quality) else: return None
def upload_guide(config_name, sheet, config_type=1): """分组新手引导步骤 args: config_name: 配置名字 sheet: xlsx sheet对象 """ data = xls_convert.to_pyobj(sheet) str_config = xls_convert.to_config_string(config_name, data) dict_config = eval(str_config) result = {} for guide_id, obj in dict_config.iteritems(): id_data = result.setdefault(obj['guide_team'], {}) id_data[guide_id] = obj c = ConfigManager.get_config_obj(config_name, config_type=config_type) if DEBUG or c.value != result: m_version = make_version(str_config) c.value = result c.version = m_version c.save() return m_version
def upload_middle_map_data(map_id, sheet, config_type=1): """# upload_middle_map_data: docstring args: map_id, sheet: --- arg returns: 0 --- """ result = [] iter_r = sheet.iter_rows() for i, row in enumerate(iter_r): if i == 0: continue if row[0].internal_value is None: break r = [] for cell in row: v = cell.internal_value if v is None: break try: v = int(v) r.append(xls_convert.mapping['int_list']("""[%d, 1]""" % v)) except ValueError: r.append(xls_convert.mapping['int_list'](v)) result.append(r) c = ConfigManager.get_config_obj('middle_map_data', config_type=config_type) if DEBUG or c.value.get(str(map_id)) != result: data = [(k, v) for k, v in c.value.iteritems()] data.sort(key=lambda x: x[0]) m_version = make_version(data) c.value[str(map_id)] = result c.version = m_version c.save() return m_version
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 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.config = ConfigManager.Instance() self.validate = Validate()
def config(self): data = { "config": ConfigManager.Instance(), "locations": Locations().get_all() } return self.get_view('config.html').data(data)
def __init__(self): super().__init__() self.config_manager = ConfigManager.Instance() self.unknownValue = "None"
try: data, done_list, need_private_city_test = trans_config( filename, cv, done_list, config_type=config_type) except Exception, e: etype, value, tb = sys.exc_info() line = traceback.format_exception_only(etype, value) line_str = '-'.join(line) return 100, line_str.replace('\\', '') # -99 用于配置表内容逻辑有误时的return code if done_list == 'bug': return -99, data for config_name, sheet_title, str_config in data: c = ConfigManager.get_config_obj(config_name, config_type=config_type) if DEBUG or c.value != str_config: m_version = make_version(str_config) c.value = str_config c.version = m_version c.save() cv.update_single(config_name, hex_version=m_version) sub_funcs = sub_config_name_list.get(config_name) for sub_func in sub_funcs: sub_func(config_name, sub_func.func_name, cv, force=True) print 'config: ', config_name, ' saved' done_list.append(sheet_title) cv.save()
@app.template_filter('json2table') def json2table(data): return JSON().to_table(data) @app.template_filter('json') def to_json(data): return JSON().build(data) @app.template_filter('nl2br') @evalcontextfilter def nl2br(eval_ctx, value): result = u'\n\n'.join(u'<p>%s</p>' % p.replace('\n', '<br>\n') \ for p in _paragraph_re.split(escape(value))) if eval_ctx.autoescape: result = Markup(result) return result @app.after_request def after_request(response): ThreadObserver.Instance().wait() return response if __name__ == '__main__': app.run(debug=True, host='0.0.0.0', port=ConfigManager.Instance().get_port())