Example #1
0
    def process_hour_value(self, hour):
        day = DayModel.find_by_id(hour.day_id)
        after_datetime = (datetime.fromtimestamp(day.date_timestamp) + timedelta(hours=hour.hour))
        before_datetime = (datetime.fromtimestamp(day.date_timestamp) + timedelta(hours=hour.hour + 1))
        events = EventModel.filter(data_type=DataTypeEnum.WATER_USAGE.value,
                                   after_timestamp=after_datetime.timestamp(),
                                   before_timestamp=before_datetime.timestamp(),
                                   graph_id=2)
        total_water_usage = None
        if len(events) != 0 or datetime.now() > before_datetime:
            total_water_usage = 0
        for event in events:
            usage = UsageModel.find_by_id(event.usage_id)
            if usage.consumption_type.is_water_per_hour():
                if event.data == 'True':
                    # @todo: This now ignores the fact that a usage can be spread out over multiple hours and
                    # just adds it to the hour at wich the usage was initiated
                    start = event.timestamp
                    end = EventModel.find_next_false(event).timestamp

                    duration_in_seconds = end - start
                    duration_in_hours = duration_in_seconds / (60 * 60)
                    total_water_usage += duration_in_hours * int(usage.consumption_amount)

            elif usage.consumption_type.is_water_per_usage():
                total_water_usage += int(usage.consumption_amount)

        # is_final_value = before_datetime.timestamp() < datetime.now().timestamp()
        is_final_value = False
        if total_water_usage is not None:
            hour.update(total_water_usage, is_final_value)
Example #2
0
 def patch(self, usage_id, new_value):
     usage = UsageModel.find_by_id(usage_id)
     new_value = float(new_value)
     if usage.min_value > new_value or usage.max_value < new_value:
         return {
             "errors":
             Error(
                 "New value does not fall within the expected range. ({} - {})"
                 .format(usage.min_value, usage.max_value),
                 "{} is outside of ({} - {})".format(
                     new_value, usage.min_value,
                     usage.max_value), 422, "").to_json()
         }, 422
     print("url is: " + "{}/{}/{}".format(
         app.config['HOMELYNK_URI'], usage.external_item_id, new_value))
     response = requests.get(
         url="{}/{}/{}".format(app.config['HOMELYNK_URI'],
                               usage.external_item_id, int(new_value)))
     home_response = response.json()
     item = ItemModel.find_by_id(usage.item_id)
     item_in_json = item.to_json()
     fake_event = {
         'last_use_timestamp': datetime.now().timestamp(),
         'data_type': usage.unit.value,
         'data': float(home_response["current_value"]),
         'usage_id': usage.id
     }
     item_in_json['last_use'] = fake_event
     return item_in_json, 200
Example #3
0
    def get(self, item_id, usage_id):
        errors = validate(item_id=item_id, usage_id=usage_id)
        if len(errors) > 0:
            return {errors: [error.to_json() for error in errors]}, 404

        usage = UsageModel.find_by_id(usage_id)
        return {"usage": usage.to_json()}, 200
Example #4
0
 def find_by_id(cls, item_id):
     item = cls.query.filter_by(id=item_id).first()
     if not item:
         return item
     item.usages = UsageModel.find_all_by_item_id(item.id)
     item.groups = ItemGroup.ItemGroupModel.find_groups_by_item_id(item.id)
     item.fill_status()
     return item
Example #5
0
 def find_all(cls):
     items = cls.query.all()
     for item in items:
         item.usages = UsageModel.find_all_by_item_id(item.id)
         item.groups = ItemGroup.ItemGroupModel.find_groups_by_item_id(
             item.id)
         item.fill_status()
     return items
Example #6
0
 def set_value(self, value):
     usage = UsageModel.find_by_id(self.usage_id)
     if value < usage.min_value or value > usage.max_value:
         return 'Given usage value does not fall without range ({} - {}). ({} given.)' \
                 .format(usage.min_value, usage.max_value, value), 500
     else:
         self.value = value
         return self.to_json(), 200
Example #7
0
    def post(self, item_id):
        min_value = None
        max_value = None
        if 'external_item_id' in request.form.keys():
            external_item_id = request.form['external_item_id']
            consumption_type = request.form['consumption_type']
            consumption_amount = int(request.form['consumption_amount'])
            address = request.form['address']
            unit = request.form['unit']
            if 'min_value' in request.form.keys():
                min_value = request.form['min_value']
            if 'max_value' in request.form.keys():
                max_value = request.form['max_value']
        else:
            request_data = json.loads(request.data)

            external_item_id = request_data['external_item_id']
            consumption_type = request_data['consumption_type']
            consumption_amount = int(request_data['consumption_amount'])
            address = request_data['address']
            unit = request_data['unit']
            if 'min_value' in request_data.keys():
                min_value = request_data['min_value']
            if 'max_value' in request_data.keys():
                max_value = request_data['max_value']

        errors = validate(item_id=item_id,
                          usage_consumption_type=consumption_type,
                          usage_consumption_amount=consumption_amount,
                          usage_address=address,
                          usage_unit=unit,
                          usage_min_value=min_value,
                          usage_max_value=max_value)
        if len(errors) > 0:
            return {"errors": [error.to_json() for error in errors]}, 422

        consumption_type = UsageTypeEnum(consumption_type)
        unit = UnitEnum(unit)
        usage = UsageModel(item_id, external_item_id, consumption_type,
                           consumption_amount, address, unit, min_value,
                           max_value)
        usage.save_to_db()
        return usage.to_json(), 201
Example #8
0
    def patch(self, group_id, preset_id):
        errors = validate(group_id=group_id, preset_id=preset_id)
        if len(errors) > 0:
            return {"errors": [error.to_json for error in errors]}, 404

        preset = PresetModel.find_by_id(preset_id)
        responses = []
        for preset_action in preset.preset_actions:
            usage = UsageModel.find_by_id(preset_action.usage_id)
            response = requests.get(url="{}alias={}&value={}".format(
                app.config['HOMELYNK_URI'], usage.address,
                preset_action.value))
            responses.append(response)
        print(responses)
        return "Request has been accepted.", 202
Example #9
0
    def put(self, item_id, usage_id):
        min_value = None
        max_value = None
        if 'external_item_id' in request.form.keys():
            external_item_id = request.form['external_item_id']
            consumption_type = request.form['consumption_type']
            consumption_amount = int(request.form['consumption_amount'])
            address = request.form['address']
            unit = request.form['unit']
            if 'min_value' in request.form.keys():
                min_value = request.form['min_value']
            if 'max_value' in request.form.keys():
                max_value = request.form['max_value']
        else:
            request_data = json.loads(request.data)

            external_item_id = request_data['external_item_id']
            consumption_type = request_data['consumption_type']
            consumption_amount = int(request_data['consumption_amount'])
            address = request_data['address']
            unit = request_data['unit']
            if 'min_value' in request_data.keys():
                min_value = request_data['min_value']
            if 'max_value' in request_data.keys():
                max_value = request_data['max_value']

        errors = validate(item_id=item_id,
                          usage_id=usage_id,
                          usage_consumption_amount=consumption_amount,
                          usage_consumption_type=consumption_type,
                          usage_address=address,
                          usage_unit=unit,
                          usage_min_value=min_value,
                          usage_max_value=max_value)

        if len(errors) > 0:
            return {"errors": [error.to_json() for error in errors]}, 404

        usage = UsageModel.find_by_id(usage_id)
        usage = usage.update(external_item_id=external_item_id,
                             consumption_type=consumption_type,
                             consumption_amount=consumption_amount,
                             address=address,
                             unit=unit,
                             min_value=min_value,
                             max_value=max_value)
        return usage.to_json(), 202
Example #10
0
    def fill_status(self):
        last_event = None
        for usage in self.usages:
            event = EventModel.find_latest_by_usage_id(usage.id)
            if event is None:
                pass
            elif last_event is None:
                last_event = event
            elif last_event.timestamp > event:
                last_event = event

        if last_event is not None:
            usage = UsageModel.find_by_id(last_event.usage_id)
            self.last_use = {
                'last_use_timestamp': last_event.timestamp,
                'data_type': usage.unit.value,
                'data': float(last_event.data),
                'usage_id': last_event.usage_id
            }
Example #11
0
    def post(self):
        errors = []
        if 'usage_id' in request.form.keys():
            usage_id = request.form['usage_id']
            data_type = request.form['data_type']
            data = request.form['data']
        else:
            request_data = json.loads(request.data)
            usage_id = request_data['usage_id']
            data_type = request_data['data_type']
            data = request_data['data']

        usage = UsageModel.find_by_id(usage_id)
        if usage is None:
            errors.append(
                Error(
                    "Cannot find usage with id: {}".format(usage_id),
                    "UsageModel.find_by_id({}) returns None".format(usage_id),
                    404, "https://en.wikipedia.org/wiki/HTTP_404"))
        if UnitEnum.has_value(data_type):
            data_type = UnitEnum(data_type)
        else:
            errors.append(
                Error(
                    '"{}" is not a valid unit type.'.format(data_type),
                    "UnitEnum.has_value({}) returned False".format(data_type),
                    400, "https://en.wikipedia.org/wiki/HTTP_400"))

        if len(errors) > 0:
            all_errors_in_json = [error.to_json() for error in errors]
            return {"errors": all_errors_in_json}, 422

        if usage.unit != data_type:
            error = Error(
                'The unit type of the usage with id "{}" does not match the given "{}".'
                .format(usage_id,
                        data_type), "usage.unit does not equal data_type.",
                422, "https://en.wikipedia.org/wiki/HTTP_422")
            return {"errors": error.to_json()}, 422

        event = EventModel(usage_id, data, round(datetime.now().timestamp()))
        event.save_to_db()
        return event.to_json(), 201
Example #12
0
 def delete(self, item_id, usage_id):
     errors = validate(item_id=item_id, usage_id=usage_id)
     if len(errors) > 0:
         return {"errors": [error.to_json() for error in errors]}, 422
     usage = UsageModel.find_by_id(usage_id)
     usage.delete_from_db()
Example #13
0
def test_usage_resource():
    print("####################   TESTING USAGE RESOURCE   ####################")

    # GETTING ALL USAGES
    print("TEST_1 --- GETTING ALL USAGES")
    uri = "usages"
    expected_result = {
        "usages": []
    }
    expected_status = 200
    test_get(uri, expected_result, expected_status)

    # POSTING ONE USAGE
    print("TEST_2 --- POSTING ONE USAGE")
    item_1 = send_get('items/1')
    usage_1_item_id = item_1['id']
    usage_1_external_item_id = 1
    usage_1_consumption_type = UsageTypeEnum.KILOWATT
    usage_1_consumption_amount = 5
    usage_1_address = "http://127.0.0.1:5000/usages/1"
    usage_1_unit = UnitEnum.TOGGLE
    usage_1_min_value = 0
    usage_1_max_value = 1

    usage_1 = UsageModel(usage_1_item_id,
                         usage_1_external_item_id,
                         usage_1_consumption_type,
                         usage_1_consumption_amount,
                         usage_1_address,
                         usage_1_unit,
                         usage_1_min_value,
                         usage_1_max_value)
    body = {
        "item_id": usage_1_item_id,
        "external_item_id": usage_1_external_item_id,
        "consumption_type": usage_1_consumption_type.value,
        "consumption_amount": usage_1_consumption_amount,
        "address": usage_1_address,
        "unit": "TOGGLE",
        "min_value": usage_1_min_value,
        "max_value": usage_1_max_value
    }
    usage_1_json = usage_1.to_json()
    usage_1_json['id'] = 1
    usage_1_json['url'] = "127.0.0.1:5000/api/v1/usages/1"
    expected_result = usage_1_json
    expected_status = 201
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # GETTING ALL USAGES
    print("TEST_3 --- GETTING ALL USAGES")
    uri = "usages"
    expected_result = {
        "usages": [usage_1_json]
    }
    expected_status = 200
    test_get(uri, expected_result, expected_status)

    # GETTING ONE USAGE
    print("TEST_4 --- GETTING ONE USAGE")
    uri = "usages/1"
    expected_result = usage_1_json
    expected_status = 200
    test_get(uri, expected_result, expected_status)

    # UPDATING ONE USAGE
    print("TEST_5 --- UPDATING ONE USAGE")
    uri = 'usages/1'
    expected_result = usage_1_json
    expected_result['address'] = '127.0.0.1:5000/api/usages/7'
    body = expected_result
    expected_status = 200
    test_put(uri, body, expected_result, expected_status)
    usage_1_json['address'] = '127.0.0.1:5000/api/usages/7'

    # GETTING ONE USAGE
    print("TEST_6 --- GETTING ONE USAGE")
    uri = "usages/1"
    expected_result = usage_1_json
    expected_status = 200
    test_get(uri, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_7 --- POSTING ONE USAGE - BAD REQUEST")
    item_1 = send_get('items/1')
    usage_1_item_id = item_1['id']
    usage_1_external_item_id = item_1['id']
    usage_1_consumption_type = UsageTypeEnum.KILOWATT
    usage_1_consumption_amount = 5
    usage_1_address = "http://127.0.0.1:5000/usage/1"
    usage_1_min_value = 0
    usage_1_max_value = 1

    body = {
        "item_id": usage_1_item_id,
        "external_item_id": usage_1_external_item_id,
        "consumption_type": usage_1_consumption_type.value,
        "consumption_amount": usage_1_consumption_amount,
        "address": usage_1_address,
        "unit": "FOGGLE",
        "min_value": usage_1_min_value,
        "max_value": usage_1_max_value
    }
    expected_result = {"errors": [Error(
                "{} is not a valid unit option.".format("FOGGLE"),
                "UnitEnum.has_value({}) returned False".format("FOGGLE"),
                422,
                "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_8 --- POSTING ONE USAGE - BAD REQUEST")
    body['unit'] = usage_1_unit.value
    body['consumption_type'] = 'KILO WHAT?'
    expected_result = {"errors": [Error(
                "{} is not a valid consumption type.".format("KILO WHAT?"),
                "UsageTypeEnum.has_value({}) returned False".format("KILO WHAT?"),
                422,
                "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_9 --- POSTING ONE USAGE - BAD REQUEST")
    body['consumption_type'] = usage_1_consumption_type.value
    body['address'] = '12'
    expected_result = {"errors": [Error(
                "Address must be at least 4 characters long.",
                "address was {} characters long".format(len(body['address'])),
                422,
                "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_10 --- POSTING ONE USAGE - BAD REQUEST")
    body['address'] = "________________________________________________________________________________________" \
                      "________________________________________________________________________________________" \
                      "________________________________________________________________________________________" \
                      "________________________________________________________________________________________" \
                      "________________________________________________________________________________________" \
                      "________________________________________________________________________________________" \
                      "________________________________________________________________________________________"
    expected_result = {"errors": [Error(
                "Address cannot be longer than 255 characters.",
                "address was {} characters long".format(len(body['address'])),
                422,
                "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_11 --- POSTING ONE USAGE - BAD REQUEST")
    body['address'] = usage_1_address
    body['consumption_amount'] = -1
    expected_result = {"errors": [Error(
                "Consumption amount cannot be below 0.",
                "{} is below 0".format(-1),
                422,
                "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_12 --- POSTING ONE USAGE - BAD REQUEST")
    body['consumption_amount'] = usage_1_consumption_amount
    body['min_value'] = None
    expected_result = {"errors": [Error(
            "If either min or max value is given, both should be given.",
            "Either min or max was None while the other was not.",
            422,
            "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE - BAD REQUEST
    print("TEST_13 --- POSTING ONE USAGE - BAD REQUEST")
    body['min_value'] = usage_1_min_value
    body['max_value'] = None
    expected_result = {"errors": [Error(
            "If either min or max value is given, both should be given.",
            "Either min or max was None while the other was not.",
            422,
            "https://en.wikipedia.org/wiki/HTTP_422").to_json()]}
    expected_status = 422
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)

    # EXECUTING COMMAND - BAD REQUEST
    print("TEST 14 --- POSTING COMMAND - BAD REQUEST")
    body = {}
    uri = "usages/1/command/2"
    expected_result = {"errors": Error(
                "New value does not fall within the expected range. ({} - {})"
                    .format(usage_1_json["min_value"], usage_1_json['max_value']),
                "{} is outside of ({} - {})".format(2, usage_1_json["min_value"], usage_1_json['max_value']),
                422,
                ""
            ).to_json()}
    expected_status = 422
    test_patch(uri, body, expected_result, expected_status)

    # POSTING ONE USAGE
    print("TEST_15 --- POSTING ONE USAGE")
    item_2 = send_get('items/2')
    usage_2_item_id = item_2['id']
    usage_2_external_item_id = 1
    usage_2_consumption_type = UsageTypeEnum.KILOWATT
    usage_2_consumption_amount = 5
    usage_2_address = "http://127.0.0.1:5000/usages/2"
    usage_2_unit = UnitEnum.TOGGLE
    usage_2_min_value = 0
    usage_2_max_value = 1

    usage_2 = UsageModel(usage_2_item_id,
                         usage_2_external_item_id,
                         usage_2_consumption_type,
                         usage_2_consumption_amount,
                         usage_2_address,
                         usage_2_unit,
                         usage_2_min_value,
                         usage_2_max_value)
    body = {
        "item_id": usage_2_item_id,
        "external_item_id": usage_2_external_item_id,
        "consumption_type": usage_2_consumption_type.value,
        "consumption_amount": usage_2_consumption_amount,
        "address": usage_2_address,
        "unit": "TOGGLE",
        "min_value": usage_2_min_value,
        "max_value": usage_2_max_value
    }
    usage_2_json = usage_2.to_json()
    usage_2_json['id'] = 2
    usage_2_json['url'] = "127.0.0.1:5000/api/v1/usages/2"
    expected_result = usage_2_json
    expected_status = 201
    uri = "usages"
    test_post(uri, body, expected_result, expected_status)
Example #14
0
 def find_by_id_without_groups(cls, item_id):
     item = cls.query.filter_by(id=item_id).first()
     item.usages = UsageModel.find_all_by_item_id(item_id)
     item.fill_status()
     return item
Example #15
0
def seed_test_data():
    # @todo this doesn't work yet
    print('Seeding...')
    if not ItemModel.find_by_id(1):
        items = []

        # START CREATING ITEMS
        print('Creating items...')
        items.append(ItemModel('Heating', 'comment'))
        items.append(UsageModel(1, UsageTypeEnum.KILOWATT, 5, '127.0.0.1:5000/item/1', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('staande_lamp_1', 'staande lamp = beste lamp'))
        items.append(UsageModel(2, UsageTypeEnum.KILOWATT, 1, '127.0.0.1:5000/item/2', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('staande_lamp_2', 'staande lamp = beste lamp'))
        items.append(UsageModel(3, UsageTypeEnum.KILOWATT, 1, '127.0.0.1:5000/item/3', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('slaapkamer_verlichting', 'verlichting in de slaapkamer'))
        items.append(UsageModel(4, UsageTypeEnum.KILOWATT, 1, '127.0.0.1:5000/item/4', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('lamp_nachtkastje', 'lamp op nachtkastje'))
        items.append(UsageModel(5, UsageTypeEnum.KILOWATT, 1, '127.0.0.1:5000/item/5', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('toilet', 'toilet in badkamer'))
        items.append(UsageModel(6, UsageTypeEnum.WATER_PER_USAGE, 9,
                                '127.0.0.1:5000/item/6', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('douche', 'douche'))
        items.append(UsageModel(7, UsageTypeEnum.WATER_PER_HOUR, 9,
                                '127.0.0.1:5000/item/7', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('vaatwasser', ''))
        items.append(UsageModel(8, UsageTypeEnum.WATER_PER_USAGE, 10,
                                '127.0.0.1:5000/item/8', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('wasmachine', ''))
        items.append(UsageModel(9, UsageTypeEnum.WATER_PER_USAGE, 13,
                                '127.0.0.1:5000/item/9', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('droger', ''))
        items.append(UsageModel(10, UsageTypeEnum.KILOWATT, 9,
                                '127.0.0.1:5000/item/10', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        items.append(ItemModel('badkamer verlichting', ''))
        items.append(UsageModel(11, UsageTypeEnum.KILOWATT, 1,
                                '127.0.0.1:5000/item/11', UnitEnum(UnitEnum.TOGGLE), 0, 1))

        # START CREATING GROUPS
        print('Creating groups...')
        items.append(GroupModel('Huiskamer', True))
        items.append(GroupModel('Slaapkamer', True))
        items.append(GroupModel('Badkamer', True))
        items.append(GroupModel('Verlichting', False))

        # START ADDING ITEMS TO GROUPS
        print('Assigning items to groups...')
        items.append(ItemGroupModel(2, 1))
        items.append(ItemGroupModel(3, 1))
        items.append(ItemGroupModel(8, 1))
        items.append(ItemGroupModel(4, 2))
        items.append(ItemGroupModel(5, 2))
        items.append(ItemGroupModel(6, 3))
        items.append(ItemGroupModel(7, 3))
        items.append(ItemGroupModel(9, 3))
        items.append(ItemGroupModel(10, 3))
        items.append(ItemGroupModel(11, 3))
        items.append(ItemGroupModel(2, 4))
        items.append(ItemGroupModel(3, 4))
        items.append(ItemGroupModel(4, 4))
        items.append(ItemGroupModel(5, 4))
        items.append(ItemGroupModel(11, 4))

        items.append(GraphModel('AVERAGE_TEMPERATURE', DataTypeEnum(DataTypeEnum.TEMPERATURE)))
        items.append(GraphModel('AVERAGE_WATER_USAGE', DataTypeEnum(DataTypeEnum.WATER_USAGE)))

        print('inserting data into db, this may take a while...')
        current = 1
        total = len(items)
        for item in items:
            print('{} out of {}'.format(current, total))
            current += 1
            item.save_to_db()
Example #16
0
 def get(self):
     all_usages = UsageModel.find_all() or []
     all_in_json = [usage.to_json() for usage in all_usages]
     return {"usages": all_in_json}, 200
Example #17
0
 def __init__(self, name, comment):
     self.name = name
     self.comment = comment
     self.usages = UsageModel.find_all_by_item_id(self.id)
     self.fill_status()
     self.groups = ItemGroup.ItemGroupModel.find_groups_by_item_id(self.id)
Example #18
0
def validate(**kwargs):
    errors = []
    item = None
    usage = None
    group = None
    preset = None
    schedule = None
    scheduled_usage = None
    method = None
    if "method" in kwargs:
        method = kwargs.pop('method')

    # ITEM
    if "item_id" in kwargs:
        item_id = kwargs.pop("item_id")
        item = ItemModel.find_by_id(item_id)
        if item is None:
            errors.append(
                Error("Could not find item with id: {}".format(item_id),
                      "ItemMode.find_by_id({}) returned None".format(item_id),
                      404, "https://en.wikipedia.org/wiki/HTTP_404"))
    if "item_name" in kwargs:
        item_name = kwargs.pop("item_name")
        if len(item_name) < 3:
            errors.append(
                Error("Name must be at least 3 characters long.",
                      "Name parameter must be at least 3 characters long.",
                      400, "https://en.wikipedia.org/wiki/HTTP_400"))
        elif len(item_name) > 255:
            errors.append(
                Error("Name cannot be longer than 255 characters.",
                      "Name parameter cannot be longer than 255 characters.",
                      400, "https://en.wikipedia.org/wiki/HTTP_400"))
    if "item_comment" in kwargs:
        item_comment = kwargs.pop('item_comment')
        if len(item_comment) > 255:
            errors.append(
                Error("Comment cannot be longer than 255 characters.",
                      "Name parameter cannot be longer than 255 characters.",
                      400, "https://en.wikipedia.org/wiki/HTTP_400"))

    # USAGE
    if "usage_id" in kwargs:
        usage_id = kwargs.pop('usage_id')
        usage = UsageModel.find_by_id(usage_id)
        if usage is None:
            errors.append(
                Error(
                    "Could not find usage with id: {}".format(usage_id),
                    "UsageModel.find_by_id({}) returned None".format(usage_id),
                    404, "https://en.wikipedia.org/wiki/HTTP_404"))
        elif item is not None:
            if not item.has_usage(usage_id):
                errors.append(
                    Error(
                        "Item with id {} does not have usage with id: {}".
                        format(item.id, usage_id),
                        "UsageModel.find_by_id({}) returned None".format(
                            usage_id), 404,
                        "https://en.wikipedia.org/wiki/HTTP_404"))

    if "usage_value" in kwargs:
        usage_value = kwargs.pop("usage_value")
        if usage is None:
            pass
        elif usage_value < usage.min_value or usage_value > usage.max_value:
            errors.append(
                Error(
                    "Given value is not in range of Usage values. ({} - {}) ({} given)"
                    .format(usage.min_value, usage.max_value, usage_value),
                    "value is not within range. ({} - {}) ({} given)".format(
                        usage.min_value, usage.max_value, usage_value), 422,
                    "https://en.wikipedia.org/wiki/HTTP_404"))
    if "usage_consumption_type" in kwargs:
        usage_consumption_type = kwargs.pop('usage_consumption_type')
        if not UsageTypeEnum.has_value(usage_consumption_type):
            errors.append(
                Error(
                    "{} is not a valid consumption type.".format(
                        usage_consumption_type),
                    "UsageTypeEnum.has_value({}) returned False".format(
                        usage_consumption_type), 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))
    if "usage_unit" in kwargs:
        usage_unit = kwargs.pop('usage_unit')
        if not UnitEnum.has_value(usage_unit):
            errors.append(
                Error(
                    "{} is not a valid unit option.".format(usage_unit),
                    "UnitEnum.has_value({}) returned False".format(usage_unit),
                    422, "https://en.wikipedia.org/wiki/HTTP_422"))
    if "usage_address" in kwargs:
        usage_address = kwargs.pop('usage_address')
        if len(usage_address) < 3:
            errors.append(
                Error(
                    "Address must be at least 4 characters long.",
                    "address was {} characters long".format(
                        len(usage_address)), 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))
        if len(usage_address) > 255:
            errors.append(
                Error(
                    "Address cannot be longer than 255 characters.",
                    "address was {} characters long".format(
                        len(usage_address)), 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))
    if "usage_consumption_amount" in kwargs:
        usage_consumption_amount = kwargs.pop("usage_consumption_amount")
        if usage_consumption_amount < 0:
            errors.append(
                Error("Consumption amount cannot be below 0.",
                      "{} is below 0".format(usage_consumption_amount), 422,
                      "https://en.wikipedia.org/wiki/HTTP_422"))
    usage_min_value = None
    if "usage_min_value" in kwargs:
        usage_min_value = kwargs.pop("usage_min_value")
    usage_max_value = None
    if "usage_max_value" in kwargs:
        usage_max_value = kwargs.pop("usage_max_value")
    if (usage_min_value is None and usage_max_value is not None) or \
            (usage_min_value is not None and usage_max_value is None):
        errors.append(
            Error("If either min or max value is given, both should be given.",
                  "Either min or max was None while the other was not.", 422,
                  "https://en.wikipedia.org/wiki/HTTP_422"))
    elif usage_min_value is not None and usage_max_value is not None:
        if usage_min_value > usage_max_value:
            errors.append(
                Error("Min value should be lower than max value",
                      "min_value is higher than max_value", 422,
                      "https://en.wikipedia.org/wiki/HTTP_422"))

    # GROUP
    if "group_id" in kwargs:
        group_id = kwargs.pop("group_id")
        group = GroupModel.find_by_id(group_id)
        if group is None:
            errors.append(
                Error(
                    "Could not find group with id: {}".format(group_id),
                    "GroupModel.find_by_id({}) returned None".format(group_id),
                    404, "https://en.wikipedia.org/wiki/HTTP_404"))

    if "group_name" in kwargs:
        group_name = kwargs.pop("group_name")
        if len(group_name) < 3:
            errors.append(
                Error("Name must be at least 3 characters long.",
                      "Name parameter must be at least 3 characters long.",
                      400, "https://en.wikipedia.org/wiki/HTTP_400"))
        elif len(group_name) > 255:
            errors.append(
                Error("Name cannot be longer than 255 characters.",
                      "Name parameter cannot be longer than 255 characters.",
                      400, "https://en.wikipedia.org/wiki/HTTP_400"))

    # PRESET
    if "preset_id" in kwargs:
        preset_id = kwargs.pop("preset_id")
        preset = PresetModel.find_by_id(preset_id)
        if preset is None:
            errors.append(
                Error(
                    "Could not find preset with id: {}".format(preset_id),
                    "PresetModel.find_by_id({}) returned None".format(
                        preset_id), 404,
                    "https://en.wikipedia.org/wiki/HTTP_404"))
        elif preset.group_id != group.id:
            errors.append(
                Error("The given group id did not match the presets group id",
                      "preset.group_id != group.id", 422,
                      "https://en.wikipedia.org/wiki/HTTP_422"))

    if "preset_name" in kwargs:
        preset_name = kwargs.pop("preset_name")
        if len(preset_name) < 3:
            errors.append(
                Error("Name must be at least 3 characters long.",
                      "len(preset_name) < 3 returned True", 422,
                      "https://en.wikipedia.org/wiki/HTTP_422"))
        if len(preset_name) > 30:
            errors.append(
                Error("Name cannot be longer than 30 characters.",
                      "len(preset_name) > 30 returned True", 422,
                      "https://en.wikipedia.org/wiki/HTTP_422"))

    # PRESET_ACTION
    if "preset_action_id" in kwargs:
        preset_action_id = kwargs.pop("preset_action_id")
        preset_action = PresetActionModel.find_by_id(preset_action_id)
        if preset_action is None:
            errors.append(
                Error(
                    "Could not find preset action with id: {}".format(
                        preset_action_id),
                    "PresetActionModel.find_by_id({}) returned None".format(
                        preset_action_id), 404,
                    "https://en.wikipedia.org/wiki/HTTP_404"))
        elif preset is not None:
            if preset_action.preset_id != preset.id:
                errors.append(
                    Error(
                        "The given preset id did not match the presets actions preset id",
                        "preset_action.preset_id != preset.id", 422,
                        "https://en.wikipedia.org/wiki/HTTP_422"))

    # SCHEDULE
    if "schedule_id" in kwargs:
        schedule_id = kwargs.pop("schedule_id")
        schedule = ScheduleModel.find_by_id(schedule_id)
        if schedule is None:
            errors.append(
                Error(
                    "Could not find schedule with id: ".format(schedule_id),
                    "ScheduleModel.find_by_id({}) returned None".format(
                        schedule_id), 404,
                    "https://en.wikipedia.org/wiki/HTTP_404"))
    if "schedule_time" in kwargs:
        schedule_time = kwargs.pop("schedule_time")
        if len(schedule_time) != 8 or not datetime.strptime(
                schedule_time, "%H:%M:%S"):
            errors.append(
                Error(
                    "Invalid time format given, expected format is: '12:00:00'",
                    "Invalid time format, expected format is: '%H:%M:%S'", 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))
    if "schedule_days" in kwargs:
        schedule_days = kwargs.pop("schedule_days")
        if len(schedule_days) < 1:
            errors.append(
                Error("No schedule days given.", "Expecting array of days",
                      422, "https://en.wikipedia.org/wiki/HTTP_422"))
        else:
            seen_values = []
            for schedule_day in schedule_days:
                if int(schedule_day) < 0 or int(schedule_day) > 6:
                    errors.append(
                        Error(
                            "day should be in range 0 - 6, {} given".format(
                                int(schedule_day)),
                            "day should be in range 0 - 6, {} given".format(
                                int(schedule_day)), 422,
                            "https://en.wikipedia.org/wiki/HTTP_422"))
                if schedule_day in seen_values:
                    errors.append(
                        Error("Duplicate day entry. {}".format(schedule_day),
                              "Duplicate day entry. {}".format(schedule_day),
                              422, "https://en.wikipedia.org/wiki/HTTP_422"))
                seen_values.append(schedule_day)
    if "schedule_usages" in kwargs:
        schedule_usages = kwargs.pop("schedule_usages")
        if len(schedule_usages) < 1:
            errors.append(
                Error("No schedule usages given.", "Expecting array of usages",
                      422, "https://en.wikipedia.org/wiki/HTTP_422"))
        seen_values = []
        for scheduled_usage in schedule_usages:
            if scheduled_usage['usage_id'] is None:
                errors.append(
                    Error("Missing usage_id for a scheduled usage.",
                          "Missing usage_id for a scheduled usage.", 422,
                          "https://en.wikipedia.org/wiki/HTTP_422"))
            else:
                _usage = UsageModel.find_by_id(scheduled_usage['usage_id'])
                if _usage is None:
                    errors.append(
                        Error(
                            "Could not find item with id: ".format(usage_id),
                            "UsageModel.find_by_id({}) returned None".format(
                                usage_id), 404,
                            "https://en.wikipedia.org/wiki/HTTP_404"))
                else:
                    scheduled_usage_value = scheduled_usage['value']
                    if scheduled_usage_value < _usage.min_value or scheduled_usage_value > _usage.max_value:
                        errors.append(
                            Error(
                                "Given value is not in range of Usage values. ({} - {}) ({} given}"
                                .format(_usage.min_value, _usage.max_value,
                                        scheduled_usage_value),
                                "value is not within range. ({} - {}) ({} given}"
                                .format(_usage.min_value, _usage.max_value,
                                        scheduled_usage_value), 422,
                                "https://en.wikipedia.org/wiki/HTTP_404"))
                    if scheduled_usage['usage_id'] in seen_values:
                        errors.append(
                            Error(
                                "Duplicate usage entry. {}".format(
                                    scheduled_usage['usage_id']),
                                "Duplicate usage entry. {}".format(
                                    scheduled_usage['usage_id']), 422,
                                "https://en.wikipedia.org/wiki/HTTP_422"))
                    seen_values.append(scheduled_usage['usage_id'])

    if "schedule_day_number" in kwargs:
        schedule_day_number = kwargs.pop("schedule_day_number")
        if schedule is None:
            pass
        else:
            for schedule_day in schedule.schedule_days:
                if schedule_day.day == schedule_day_number:
                    errors.append(
                        Error(
                            "Given day ({}) is already being used by this schedule."
                            .format(schedule_day_number),
                            "Given day ({}) is already being used by this schedule."
                            .format(schedule_day_number), 422,
                            "https://en.wikipedia.org/wiki/HTTP_404"))
    if "schedule_day_id" in kwargs:
        schedule_day_id = kwargs.pop("schedule_day_id")
        schedule_day = ScheduleDayModel.find_by_id(schedule_day_id)
        if schedule_day is None:
            errors.append(
                Error(
                    "Could not find schedule day with id: ".format(
                        schedule_day_id),
                    "ScheduleDayModel.find_by_id({}) returned None".format(
                        schedule_day_id), 404,
                    "https://en.wikipedia.org/wiki/HTTP_404"))
        if schedule is None:
            pass
        elif schedule.id != schedule_day.schedule_id:
            errors.append(
                Error(
                    "The given schedule id did not match the days schedule id",
                    "schedule.id != schedule_day.schedule_id", 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))

    # SCHEDULED USAGE
    if "scheduled_usage_id" in kwargs:
        scheduled_usage_id = kwargs.pop("scheduled_usage_id")
        scheduled_usage = ScheduledUsageModel.find_by_id(scheduled_usage_id)
        if scheduled_usage is None:
            errors.append(
                Error(
                    "Could not find scheduled usage with id: ".format(
                        scheduled_usage_id),
                    "ScheduledUsageModel.find_by_id({}) returned None".format(
                        scheduled_usage_id), 404,
                    "https://en.wikipedia.org/wiki/HTTP_404"))
        elif scheduled_usage.schedule_id != schedule.id:
            errors.append(
                Error(
                    "The given schedule id did not match the scheduled usage schedule id",
                    "scheduled_usage.schedule_id != schedule.id", 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))
    if "scheduled_usage_value" in kwargs:
        scheduled_usage_value = kwargs.pop("scheduled_usage_value")
        if scheduled_usage is not None:
            _usage = UsageModel.find_by_id(scheduled_usage.usage_id)
            if _usage.min_value > scheduled_usage_value or _usage.max_value < scheduled_usage_value:
                errors.append(
                    Error(
                        "Given value is not in range of Usage values. ({} - {}) ({} given}"
                        .format(_usage.min_value, _usage.max_value,
                                scheduled_usage_value),
                        "value is not within range. ({} - {}) ({} given}".
                        format(_usage.min_value, _usage.max_value,
                               scheduled_usage_value), 422,
                        "https://en.wikipedia.org/wiki/HTTP_404"))

    # METHOD SPECIFIC
    if method == "GroupItemResource.get":
        if item is None or group is None:
            pass
        elif not item.is_in_this_group(group.id):
            errors.append(
                Error(
                    "Item with id {} is not in group with id {}".format(
                        item.id, group.id),
                    "item.is_in_this_group({}) returned False".format(
                        group.id), 422,
                    "https://en.wikipedia.org/wiki/HTTP_422"))
    elif method == "GroupItemsResource.post":
        if item is None or group is None:
            pass
        elif item.is_in_this_group(group.id):
            errors.append(
                Error(
                    "Item with id {} is already in group with id {}".format(
                        item.id, group.id), "item is already in this group",
                    422, "https://en.wikipedia.org/wiki/HTTP_422"))
        elif group.is_module is True:
            if item.is_in_module():
                errors.append(
                    Error("Item cannot be in two different modules",
                          "item.is_in_module() returned True", 422,
                          "https://en.wikipedia.org/wiki/HTTP_422"))
    elif method == "GroupItemResource.delete":
        if item is None or group is None:
            pass
        elif not item.is_in_this_group(group.id):
            errors.append(
                Error(
                    "Item with id {} is not in group with id {}".format(
                        item.id, group.id),
                    "item.is_in_this_group({}) returned False".format(
                        group.id), 400,
                    "https://en.wikipedia.org/wiki/HTTP_400"))
    elif method == "PresetActionsResource.post":
        if (group is not None) and (usage is not None):
            usage_is_in_group = False
            for item in group.items:
                if item.id == usage.item_id:
                    usage_is_in_group = True
            if not usage_is_in_group:
                errors.append(
                    Error(
                        "The item that usage with id {} is attached to does not belong to group with id {}."
                        .format(usage.id,
                                group.id), "Usage is not in this group", 422,
                        "https://en.wikipedia.org/wiki/HTTP_422"))
    elif method == "ScheduledUsagesResource.post":
        if schedule is None or usage is None:
            pass
        else:
            for scheduled_usage in schedule.scheduled_usages:
                if scheduled_usage.usage_id == usage.id:
                    errors.append(
                        Error(
                            "Given usage id is already being used by this schedule",
                            "usage id already in schedule", 422,
                            "https://en.wikipedia.org/wiki/HTTP_422"))

    assert len(kwargs) == 0, kwargs
    return errors
Example #19
0
def seed():
    print('Seeding...')
    db.init_app(app)
    if not ItemModel.find_by_id(1):
        items = []

        # START CREATING ITEMS
        print('Creating items...')
        items.append(ItemModel('Heating', 'comment'))
        items.append(
            UsageModel(1, 1, UsageTypeEnum.KILOWATT, 5,
                       '127.0.0.1:5000/item/1', 'PERCENTAGE', 0, 1))

        items.append(ItemModel('staande_lamp_1', 'staande lamp = beste lamp'))
        items.append(
            UsageModel(2, 2, UsageTypeEnum.KILOWATT, 1,
                       '127.0.0.1:5000/item/5', 'TOGGLE', 0, 1))

        items.append(ItemModel('staande_lamp_2', 'staande lamp = beste lamp'))
        items.append(
            UsageModel(3, 3, UsageTypeEnum.KILOWATT, 1,
                       '127.0.0.1:5000/item/3', 'TOGGLE', 0, 1))

        items.append(
            ItemModel('slaapkamer_verlichting',
                      'verlichting in de slaapkamer'))
        items.append(
            UsageModel(4, 4, UsageTypeEnum.KILOWATT, 1,
                       '127.0.0.1:5000/item/4', 'TOGGLE', 0, 1))

        items.append(ItemModel('lamp_nachtkastje', 'lamp op nachtkastje'))
        items.append(
            UsageModel(5, 5, UsageTypeEnum.KILOWATT, 1,
                       '127.0.0.1:5000/item/5', 'TOGGLE', 0, 1))

        items.append(ItemModel('toilet', 'toilet in badkamer'))
        items.append(
            UsageModel(6, 6, UsageTypeEnum.WATER_PER_USAGE, 9,
                       '127.0.0.1:5000/item/6', 'TOGGLE', 0, 1))

        items.append(ItemModel('douche', 'douche'))
        items.append(
            UsageModel(7, 7, UsageTypeEnum.WATER_PER_HOUR, 9,
                       '127.0.0.1:5000/item/7', 'TOGGLE', 0, 1))

        items.append(ItemModel('vaatwasser', ''))
        items.append(
            UsageModel(8, 8, UsageTypeEnum.WATER_PER_USAGE, 10,
                       '127.0.0.1:5000/item/8', 'TOGGLE', 0, 1))

        items.append(ItemModel('wasmachine', ''))
        items.append(
            UsageModel(9, 9, UsageTypeEnum.WATER_PER_USAGE, 13,
                       '127.0.0.1:5000/item/9', 'TOGGLE', 0, 1))

        items.append(ItemModel('droger', ''))
        items.append(
            UsageModel(10, 10, UsageTypeEnum.KILOWATT, 9,
                       '127.0.0.1:5000/item/10', 'TOGGLE', 0, 1))

        items.append(ItemModel('badkamer verlichting', ''))
        items.append(
            UsageModel(11, 11, UsageTypeEnum.KILOWATT, 1,
                       '127.0.0.1:5000/item/11', 'TOGGLE', 0, 1))

        # START CREATING GROUPS
        print('Creating groups...')
        items.append(GroupModel('Huiskamer', True))
        items.append(GroupModel('Slaapkamer', True))
        items.append(GroupModel('Badkamer', True))
        items.append(GroupModel('Verlichting', False))

        # START ADDING ITEMS TO GROUPS
        print('Assigning items to groups...')
        items.append(ItemGroupModel(2, 1))
        items.append(ItemGroupModel(3, 1))
        items.append(ItemGroupModel(8, 1))
        items.append(ItemGroupModel(4, 2))
        items.append(ItemGroupModel(5, 2))
        items.append(ItemGroupModel(6, 3))
        items.append(ItemGroupModel(7, 3))
        items.append(ItemGroupModel(9, 3))
        items.append(ItemGroupModel(10, 3))
        items.append(ItemGroupModel(11, 3))
        items.append(ItemGroupModel(2, 4))
        items.append(ItemGroupModel(3, 4))
        items.append(ItemGroupModel(4, 4))
        items.append(ItemGroupModel(5, 4))
        items.append(ItemGroupModel(11, 4))

        # START CREATING GRAPHS
        items.append(
            GraphModel('AVERAGE_TEMPERATURE', DataTypeEnum.TEMPERATURE))
        items.append(
            GraphModel('AVERAGE_WATER_USAGE', DataTypeEnum.WATER_USAGE))

        # START CREATING EVENTS
        print('Creating events')
        till_date = datetime.now().timestamp()
        about_one_month = (60 * 60 * 24 * 30)
        from_date = till_date - about_one_month

        # make sure the timestamps are never in the future
        limit_time = lambda timestamp: timestamp if timestamp < till_date else till_date

        keep_going = True
        while keep_going:
            for i in range(0, random.randint(1, 4)):
                toilet_break_timestamp = (
                    datetime.fromtimestamp(from_date) +
                    timedelta(hours=random.randint(5, 12),
                              minutes=random.randint(0, 60),
                              seconds=random.randint(0, 60))).timestamp()
                items.append(
                    EventModel(6, 'True', limit_time(toilet_break_timestamp),
                               2))

            for i in range(0, 4):
                daily_shower_start_timestamp = (
                    datetime.fromtimestamp(from_date) +
                    timedelta(hours=random.randint(5, 12),
                              minutes=random.randint(0, 60),
                              seconds=random.randint(0, 60))).timestamp()
                items.append(
                    EventModel(7, 'True',
                               limit_time(daily_shower_start_timestamp), 2))
                daily_shower_end_timestamp = (
                    datetime.fromtimestamp(daily_shower_start_timestamp) +
                    timedelta(minutes=random.randint(5, 15),
                              seconds=random.randint(0, 60))).timestamp()
                items.append(
                    EventModel(7, 'False',
                               limit_time(daily_shower_end_timestamp), 2))
            for i in range(0, 24):
                if not keep_going:
                    break

                for y in range(0, 10):
                    if from_date > till_date:
                        keep_going = False
                        break
                    temp = 0
                    if i in [1, 2, 3, 4, 5, 15]:
                        temp = 15
                    elif i in [0, 14]:
                        temp = 16
                    elif i in [6, 12, 24, 13]:
                        temp = 18
                    elif i in [7, 8, 9, 17, 18, 19, 20, 21, 22]:
                        temp = 21
                    elif i in [10, 23]:
                        temp = 20
                    elif i in [11, 16]:
                        temp = 19

                    items.append(
                        EventModel(1, temp * random.uniform(0.9, 1.1),
                                   from_date, 1))
                    from_date += 6 * 60

        print('inserting data into db, this may take a while...')
        current = 1
        total = len(items)

        # one last flush of the toilet at the current timestamp
        items.append(EventModel(6, 'True', till_date, 2))
        for item in items:
            print('{} out of {}'.format(current, total))
            item.save_to_db()
            current += 1