Esempio n. 1
0
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}
Esempio n. 2
0
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)}
Esempio n. 3
0
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
Esempio n. 4
0
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
Esempio n. 5
0
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)}
Esempio n. 6
0
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}
Esempio n. 7
0
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)}
Esempio n. 8
0
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
Esempio n. 9
0
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
Esempio n. 10
0
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
Esempio n. 11
0
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
Esempio n. 12
0
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
Esempio n. 13
0
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