def api_specific_energy_providers(id, db): """ Returns the current energy provider, or the specified energy provider. """ if id == "current": provider = (db.query(database.Provider) .filter_by(current=1) .first()) else: try: id = int(id) except ValueError: abort(400, "Invalid parameter.") provider = (db.query(database.Provider) .filter_by(id=id) .first()) if not provider: provider = None else: provider = tools.to_dict(provider) if provider["day_slope_watt_euros"] != provider["night_slope_watt_euros"]: session = session_manager.get_session() user = db.query(database.User).filter_by(login=session["login"]).first() start_night_rate = ("%02d" % (user.start_night_rate // 3600) + ":" + "%02d" % ((user.start_night_rate % 3600) // 60)) end_night_rate = ("%02d" % (user.end_night_rate // 3600) + ":" + "%02d" % ((user.end_night_rate % 3600) // 60)) provider["start_night_rate"] = start_night_rate provider["end_night_rate"] = end_night_rate return {"data": provider}
def api_get_id(sensor, id1, db): """ Returns measure with id <id1> associated to sensor <sensor>, in watts. If <id1> < 0, counts from the last measure, as in Python lists. If no matching data is found, returns null. """ if id1 >= 0: data = (db.query(database.Measures) .filter_by(sensor_id=sensor, id=id1) .first()) else: data = (db.query(database.Measures) .filter_by(sensor_id=sensor) .order_by(desc(database.Measures.timestamp)) .slice(-id1, -id1) .first()) if not data: data = None else: data = tools.to_dict(data) return {"data": data, "rate": get_rate_type(db)}
def do_cache_ids(sensor, watt_euros, id1, id2, db, force_refresh=False): """ Computes the cache (if needed) for the API call /api/<sensor:int>/get/<watt_euros:re:watts|kwatthours|euros>/by_id/<id1:int>/<id2:int> Returns the stored (or computed) data or None if parameters are invalid. """ r = redis.Redis(decode_responses=True) if not force_refresh: data = r.get(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2)) if data: # If found in cache, return it return json.loads(data) if id1 >= 0 and id2 >= 0 and id2 >= id1: data = (db.query(database.Measures).filter( database.Measures.sensor_id == sensor, database.Measures.id >= id1, database.Measures.id < id2).order_by( asc(database.Measures.timestamp)).all()) elif id1 <= 0 and id2 <= 0 and id2 >= id1: data = (db.query( database.Measures).filter_by(sensor_id=sensor).order_by( desc(database.Measures.timestamp)).slice(-id2, -id1).all()) data.reverse() else: return None if not data: data = None else: time1 = data[0].timestamp time2 = data[-1].timestamp if watt_euros == 'kwatthours' or watt_euros == 'euros': data = tools.energy(data) if watt_euros == 'euros': if data["night_rate"] != 0: night_rate = tools.watt_euros(0, 'night', data['night_rate'], db) else: night_rate = 0 if data["day_rate"] != 0: day_rate = tools.watt_euros(0, 'day', data['day_rate'], db) else: day_rate = 0 data = {"value": night_rate + day_rate} else: data = tools.to_dict(data) # Store in cache r.set( watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2), json.dumps(data), time2 - time1) return data
def do_cache_times(sensor, watt_euros, time1, time2, db, force_refresh=False): """ Computes the cache (if needed) for the API call /api/<sensor:int>/get/<watt_euros:re:watts|kwatthours|euros>/by_time/<time1:float>/<time2:float> Returns the stored (or computed) data. """ r = redis.Redis(decode_responses=True) if not force_refresh: data = r.get(watt_euros + "_" + str(sensor) + "_" + "by_time" + "_" + str(time1) + "_" + str(time2)) if data: # If found in cache, return it return json.loads(data) data = (db.query(database.Measure) .filter(database.Measure.sensor_id == sensor, database.Measure.timestamp >= time1, database.Measure.timestamp < time2) .order_by(asc(database.Measure.timestamp)) .all()) if not data: data = None else: if watt_euros == "kwatthours" or watt_euros == "euros": data = tools.energy(data) if watt_euros == "euros": data = {"value": (tools.watt_euros(0, 'night', data['night_rate'], db) + tools.watt_euros(0, 'day', data['day_rate'], db))} else: data = tools.to_dict(data) # Store in cache r.set(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(time1) + "_" + str(time2), json.dumps(data), int(time2) - int(time1)) return data
def api_get_time(sensor, time1, db): """ Returns measure at timestamp <time1> for sensor <sensor>, in watts. Returns null if no measure is found. """ if time1 < 0: abort(400, "Invalid timestamp.") data = (db.query(database.Measures).filter_by(sensor_id=sensor, timestamp=time1).first()) if not data: data = None else: data = tools.to_dict(data) return {"data": data, "rate": get_rate_type(db)}
def api_energy_providers(db): """Returns all the available energy providers or null if none found.""" providers = db.query(database.Provider).all() if not providers: providers = None else: providers = tools.to_dict(providers) for provider in providers: if provider["day_slope_watt_euros"] != provider["night_slope_watt_euros"]: session = session_manager.get_session() user = db.query(database.User).filter_by(login=session["login"]).first() start_night_rate = ("%02d" % (user.start_night_rate // 3600) + ":" + "%02d" % ((user.start_night_rate % 3600) // 60)) end_night_rate = ("%02d" % (user.end_night_rate // 3600) + ":" + "%02d" % ((user.end_night_rate % 3600) // 60)) provider["start_night_rate"] = start_night_rate provider["end_night_rate"] = end_night_rate return {"data": providers}
def api_get_time(sensor, time1, db): """ Returns measure at timestamp <time1> for sensor <sensor>, in watts. Returns null if no measure is found. """ if time1 < 0: abort(400, "Invalid timestamp.") data = (db.query(database.Measures) .filter_by(sensor_id=sensor, timestamp=time1) .first()) if not data: data = None else: data = tools.to_dict(data) return {"data": data, "rate": get_rate_type(db)}
def do_cache_times(sensor, watt_euros, time1, time2, db, force_refresh=False): """ Computes the cache (if needed) for the API call /api/<sensor:int>/get/<watt_euros:re:watts|kwatthours|euros>/by_time/<time1:float>/<time2:float> Returns the stored (or computed) data. """ r = redis.Redis(decode_responses=True) if not force_refresh: data = r.get(watt_euros + "_" + str(sensor) + "_" + "by_time" + "_" + str(time1) + "_" + str(time2)) if data: # If found in cache, return it return json.loads(data) data = (db.query(database.Measures).filter( database.Measures.sensor_id == sensor, database.Measures.timestamp >= time1, database.Measures.timestamp < time2).order_by( asc(database.Measures.timestamp)).all()) if not data: data = None else: if watt_euros == "kwatthours" or watt_euros == "euros": data = tools.energy(data) if watt_euros == "euros": data = { "value": (tools.watt_euros(0, 'night', data['night_rate'], db) + tools.watt_euros(0, 'day', data['day_rate'], db)) } else: data = tools.to_dict(data) # Store in cache r.set( watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(time1) + "_" + str(time2), json.dumps(data), int(time2) - int(time1)) return data
def update_providers(fetch, db): """Updates the available providers. Simply returns them without updating if fetch is False. """ try: assert (fetch) providers = requests.get(config.get("url_energy_providers")).json() except (requests.ConnectionError, AssertionError): providers = db.query(database.Provider).all() if not providers: providers = [] return tools.to_dict(providers) old_current = db.query(database.Provider).filter_by(current=1).first() db.query(database.Provider).delete() for provider in providers: type_id = (db.query(database.MeasureType).filter_by( name=provider["type_name"]).first()) if not type_id: type_db = database.MeasureType(name=provider["type_name"]) db.add(type_db) db.flush() type_id = database.MeasureType(name=provider["type_name"]).first() provider_db = database.Provider( name=provider["name"], day_constant_watt_euros=provider["day_constant_watt_euros"], day_slope_watt_euros=provider["day_slope_watt_euros"], night_constant_watt_euros=provider["night_constant_watt_euros"], night_slope_watt_euros=provider["night_slope_watt_euros"], type_id=type_id.id, current=(1 if old_current and old_current.name == provider["name"] else 0), threshold=int(provider["threshold"])) db.add(provider_db) return providers
def update_providers(fetch, db): """Updates the available providers. Simply returns them without updating if fetch is False. """ try: assert(fetch) providers = requests.get(config.get("url_energy_providers")).json() except (requests.ConnectionError, AssertionError): providers = db.query(database.Provider).all() if not providers: providers = [] return tools.to_dict(providers) old_current = db.query(database.Provider).filter_by(current=1).first() db.query(database.Provider).delete() for provider in providers: type_id = (db.query(database.MeasureType) .filter_by(name=provider["type_name"]) .first()) if not type_id: type_db = database.MeasureType(name=provider["type_name"]) db.add(type_db) db.flush() type_id = database.MeasureType(name=provider["type_name"]).first() provider_db = database.Provider(name=provider["name"], day_constant_watt_euros=provider["day_constant_watt_euros"], day_slope_watt_euros=provider["day_slope_watt_euros"], night_constant_watt_euros=provider["night_constant_watt_euros"], night_slope_watt_euros=provider["night_slope_watt_euros"], type_id=type_id.id, current=(1 if old_current and old_current.name == provider["name"] else 0), threshold=int(provider["threshold"])) db.add(provider_db) return providers
def do_cache_group_id(sensor, watt_euros, id1, id2, step, db, timestep=config.get("default_timestep"), force_refresh=False): """ Computes the cache (if needed) for the API call /api/<sensor:int>/get/<watt_euros:re:watts|kwatthours|euros>/by_id/<id1:int>/<id2:int>/<step:int> Returns the stored (or computed) data. """ r = redis.Redis(decode_responses=True) if not force_refresh: data = r.get(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2) + "_" + str(step) + "_" + str(timestep)) if data: # If found in cache, return it return json.loads(data) steps = [i for i in range(id1, id2, step)] steps.append(id2) if id1 >= 0 and id2 >= 0 and id2 >= id1: data = (db.query(database.Measure) .filter(database.Measure.sensor_id == sensor, database.Measure.id >= id1, database.Measure.id < id2) .order_by(asc(database.Measure.timestamp)) .all()) elif id1 <= 0 and id2 <= 0 and id2 >= id1: data = (db.query(database.Measure) .filter_by(sensor_id=sensor) .order_by(desc(database.Measure.timestamp)) .slice(-id2, -id1) .all()) data.reverse() else: raise ValueError time2 = None if not data: data = [None for i in range(len(steps) - 1)] else: time1 = data[0].timestamp time2 = data[-1].timestamp data_dict = tools.to_dict(data) tmp = [[] for i in range(len(steps) - 1)] for i in data_dict: tmp[bisect.bisect_left(steps, i["id"]) - 1].append(i) data = [] for i in tmp: if len(i) == 0: data.append(None) continue energy = tools.energy(i) if watt_euros == "watts": tmp_data = {"value": energy["value"] / (step * timestep) * 1000 * 3600, "day_rate": energy["day_rate"] / (step * timestep) * 1000 * 3600, "night_rate": energy["night_rate"] / (step * timestep) * 1000 * 3600} elif watt_euros == 'kwatthours': tmp_data = energy elif watt_euros == 'euros': if energy["night_rate"] != 0: night_rate = tools.watt_euros(0, 'night', energy['night_rate'], db) else: night_rate = 0 if energy["day_rate"] != 0: day_rate = tools.watt_euros(0, 'day', energy['day_rate'], db) else: day_rate = 0 tmp_data = {"value": night_rate + day_rate} data.append(tmp_data) if len(data) == 0: data = None if time2 is not None: # Store in cache if time2 < datetime.datetime.now().timestamp(): # If new measures are to come, short lifetime (basically timestep) r.set(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2) + "_" + str(step) + "_" + str(timestep), json.dumps(data), timestep) else: # Else, store for a greater lifetime (basically time2 - time1) r.set(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2) + "_" + str(step) + "_" + str(timestep), json.dumps(data), time2 - time1) return data
def do_cache_ids(sensor, watt_euros, id1, id2, db, force_refresh=False): """ Computes the cache (if needed) for the API call /api/<sensor:int>/get/<watt_euros:re:watts|kwatthours|euros>/by_id/<id1:int>/<id2:int> Returns the stored (or computed) data or None if parameters are invalid. """ r = redis.Redis(decode_responses=True) if not force_refresh: data = r.get(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2)) if data: # If found in cache, return it return json.loads(data) if id1 >= 0 and id2 >= 0 and id2 >= id1: data = (db.query(database.Measure) .filter(database.Measure.sensor_id == sensor, database.Measure.id >= id1, database.Measure.id < id2) .order_by(asc(database.Measure.timestamp)) .all()) elif id1 <= 0 and id2 <= 0 and id2 >= id1: data = (db.query(database.Measure) .filter_by(sensor_id=sensor) .order_by(desc(database.Measure.timestamp)) .slice(-id2, -id1) .all()) data.reverse() else: return None if not data: data = None else: time1 = data[0].timestamp time2 = data[-1].timestamp if watt_euros == 'kwatthours' or watt_euros == 'euros': data = tools.energy(data) if watt_euros == 'euros': if data["night_rate"] != 0: night_rate = tools.watt_euros(0, 'night', data['night_rate'], db) else: night_rate = 0 if data["day_rate"] != 0: day_rate = tools.watt_euros(0, 'day', data['day_rate'], db) else: day_rate = 0 data = {"value": night_rate + day_rate} else: data = tools.to_dict(data) # Store in cache r.set(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2), json.dumps(data), time2 - time1) return data
def do_cache_group_id(sensor, watt_euros, id1, id2, step, db, timestep=config.get("default_timestep"), force_refresh=False): """ Computes the cache (if needed) for the API call /api/<sensor:int>/get/<watt_euros:re:watts|kwatthours|euros>/by_id/<id1:int>/<id2:int>/<step:int> Returns the stored (or computed) data. """ r = redis.Redis(decode_responses=True) if not force_refresh: data = r.get(watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2) + "_" + str(step) + "_" + str(timestep)) if data: # If found in cache, return it return json.loads(data) steps = [i for i in range(id1, id2, step)] steps.append(id2) if id1 >= 0 and id2 >= 0 and id2 >= id1: data = (db.query(database.Measures).filter( database.Measures.sensor_id == sensor, database.Measures.id >= id1, database.Measures.id < id2).order_by( asc(database.Measures.timestamp)).all()) elif id1 <= 0 and id2 <= 0 and id2 >= id1: data = (db.query( database.Measures).filter_by(sensor_id=sensor).order_by( desc(database.Measures.timestamp)).slice(-id2, -id1).all()) data.reverse() else: raise ValueError time2 = None if not data: data = [None for i in range(len(steps) - 1)] else: time1 = data[0].timestamp time2 = data[-1].timestamp data_dict = tools.to_dict(data) tmp = [[] for i in range(len(steps) - 1)] for i in data_dict: tmp[bisect.bisect_left(steps, i["id"]) - 1].append(i) data = [] for i in tmp: if len(i) == 0: data.append(None) continue energy = tools.energy(i) if watt_euros == "watts": tmp_data = { "value": energy["value"] / (step * timestep) * 1000 * 3600, "day_rate": energy["day_rate"] / (step * timestep) * 1000 * 3600, "night_rate": energy["night_rate"] / (step * timestep) * 1000 * 3600 } elif watt_euros == 'kwatthours': tmp_data = energy elif watt_euros == 'euros': if energy["night_rate"] != 0: night_rate = tools.watt_euros(0, 'night', energy['night_rate'], db) else: night_rate = 0 if energy["day_rate"] != 0: day_rate = tools.watt_euros(0, 'day', energy['day_rate'], db) else: day_rate = 0 tmp_data = {"value": night_rate + day_rate} data.append(tmp_data) if len(data) == 0: data = None if time2 is not None: # Store in cache if time2 < datetime.datetime.now().timestamp(): # If new measures are to come, short lifetime (basically timestep) r.set( watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2) + "_" + str(step) + "_" + str(timestep), json.dumps(data), timestep) else: # Else, store for a greater lifetime (basically time2 - time1) r.set( watt_euros + "_" + str(sensor) + "_" + "by_id" + "_" + str(id1) + "_" + str(id2) + "_" + str(step) + "_" + str(timestep), json.dumps(data), time2 - time1) return data