# Ventilation length predictor

The aim is to define a proper way of air change rate regulation. The regulation is ensured by natural ventilation that is energy efficient, requires little maintenance, has low initial costs, and is environmentally friendly. Natural ventilation should be used wherever and whenever is possible apart from areas where the quality of the air outside the house is worse than indoor air quality. A predictor enables to predict how long ventilation should be performed to decrease a given quantity to the required value.

The configuration parameters in the examples below can be changed in the configuration file `config.ini` that is described in section Configuration file.

## CO2

The predictor is based on the equation which can be used to calculate a decrease of a carbon dioxide concentration during a time interval.

### Initialize general models from local database

A local database was created for debugging purposes. The database includes pre-processed data that enables fast computing of required attributes. The example of a model created using data stored in the database follows.

    """Initialize general models from local database.
    """
    from os.path import dirname, abspath, join
    import sys
    sys.path.append(abspath(join(dirname(__file__), '../..', '')))

    from dm.models.ModelsUtil import ModelsUtil
    from dm.ConnectionUtil import ConnectionUtil as cu
    from dm.models.predictor.generic_training_file_from_local_db import training_file_co2

    if __name__ == '__main__':
        cu.setup_logging()

        no_event_shift = int(cu.predictor('attrs.no_event.time_shift'))

        data_co2 = training_file_co2(cu.package('co2.event_file.name'), no_event_shift)
        co2_filename = cu.predictor('generic.co2.model.name') + '_from_local_db.bin'
        ModelsUtil.write_model(data_co2, co2_filename, replace=ModelsUtil.replace_co2_ventilation_len)

It is required to create a dataset that contains the same number of events when a window was open and when it was closed. To select the events when the window was closed the variable `no_event_shift` is defined. Its value can be set using the parameter `attrs.no_event.time_shift`. A model is created using the function `training_file_co2` that uses `SVM` classifier (`sklearn` library). The created model is written to a binary file using the `write_model` function.

The example of a command which can be used to create a model using data stored in the database is below.

    python examples2/0302_ventilation_predictor/co2_init_general_models_from_local_db.py

### Initialize general models from a remote server

The example of a model created using data saved on the server follows.

    """Initialize general models from a remote server.
    """
    from os.path import dirname, abspath, join
    import sys
    sys.path.append(abspath(join(dirname(__file__), '../..', '')))

    from dm.models.ModelsUtil import ModelsUtil
    from dm.ConnectionUtil import ConnectionUtil as cu
    from dm.models.predictor.generic_training_file import training_file_co2
    from dm.WundergroundCom import WundergroundCom
    import json

    if __name__ == '__main__':
        cu.setup_logging()
        cls = cu.setup_clients()

        no_event_shift = int(cu.open_detector('attrs.no_event.time_shift'))

        # file with devices for training
        with open(cu.open_detector('generic.devices.path'), 'r') as f:
            devs = json.load(f)

        lat = 49.1649894
        lon = 16.562262499999974

        w = WundergroundCom()
        w.api_key = cu.wunderground_api_key()

        data_co2 = training_file_co2(cu.package('co2.event_file.name'), no_event_shift, cls, devs,
                                     lat, lon, w)
        co2_filename = cu.predictor('generic.co2.model.name')
        ModelsUtil.write_model(data_co2, co2_filename, replace=ModelsUtil.replace_co2_ventilation_len)

At first, it is necessary to set clients that can communicate with a remote server using the function `setup_clients`. Then it is required to create a dataset that contains the same number of events when a window was open and when it was closed. To select the events when the window was closed the variable `no_event_shift` is defined. Its value can be set using the parameter `attrs.no_event.time_shift`. Devices that were used to gather data are stored in the variable `devs`. Latitude and longitude that enable to get weather data according to a sensor position are stored in the variable `lat` and `lon`. The API key allows to get weather data from server and it is obtained by the function `wunderground_api_key`. A model is created using the function `training_file_co2` that uses `SVM` classifier (`sklearn` library). The created model is written to a binary file using the `write_model` function.

The example of a command which can be used to create a model using data saved on the remote server is below.

    python examples2/0302_ventilation_predictor/co2_init_general_models.py

### Predictor

The example of the model usage for predicting how long ventilation should be performed follows.

    """Predictor.
    """
    from os.path import dirname, abspath, join
    import sys
    sys.path.append(abspath(join(dirname(__file__), '../..', '')))

    from dm.ConnectionUtil import ConnectionUtil as cu
    from dm.models.ModelsUtil import ModelsUtil
    from dm.WundergroundCom import WundergroundCom
    from dm.DateTimeUtil import DateTimeUtil

    if __name__ == '__main__':
        cu.setup_logging()
        cls = cu.setup_clients()

        actual_time = int(DateTimeUtil.local_time_str_to_utc('2019/02/20 03:00:00').timestamp())
        lat = 49.1649894
        lon = 16.562262499999974

        w = WundergroundCom()
        w.api_key = cu.wunderground_api_key()

        devs = [
            {
                'db_column_name': 'co2_in_ppm',
                'gateway_id': '1816820318180747',
                'device_id': '0xa900811026800001',
                'module_id': 2,
                'server_name': 'ant-work',
            },
            {
                "db_column_name": "temperature_in_celsius",
                "gateway_id": "1816820318180747",
                "device_id": "0xa900811026800001",
                "module_id": 0,
                "server_name": "ant-work"
            },
            {
                "db_column_name": "rh_in_percentage",
                "gateway_id": "1816820318180747",
                "device_id": "0xa900811026800001",
                "module_id": 1,
                "server_name": "ant-work"
            }
        ]

        notification = ModelsUtil.predictor(devs, cls, lat, lon, actual_time, 'co2', w)
        ModelsUtil.json_to_file(notification, 'co2_notification.doc.json', log_notification=True)

It is necessary to set clients that can communicate with a remote server using the function `setup_clients`. Prediction is performed on the basis of data measured during a given time interval. Time that defines end of a time interval is stored in the variable `actual_time`. Latitude and longitude that enable to get weather data according to a sensor position are stored in the variable `lat` and `lon`. The API key allows to get weather data from server and it is obtained by the function `wunderground_api_key`. The sensors used to gather data are stored in the variable `devs`. Prediction how long ventilation should be performed to decrease the concentration of carbon dioxide to a given value is performed by the function `predictor` and the result is stored in the variable `notification`.

An output of the prediction is a notification that contains basic information described in the section Notifications and the following information:

- current_value - current value of CO2 [ppm],

- estimate_time - a time when a carbon dioxide concentration will reach a given value [min],

- final_value - value of CO2 that should be reached after ventilation [ppm],

- type - what quantity is used for prediction (carbon dioxide).

The example of a notification follows.

    {
        "data": {
            "current_value": 2000,
            "estimate_time": 9,
            "final_value": 400,
            "type": "co2_predictor"
        },
        "device_id": "0xa900811026800001",
        "event": "env-notification-pre",
        "gateway_id": "1816820318180747",
        "raise": true,
        "raise_catch": false,
        "readable": "2019-02-20 03:00:00",
        "timestamp": 1550628000
    }

The example of a command which can be used to the use of a model for prediction how long ventilation should be performed is below.

    python examples2/0302_ventilation_predictor/co2_predictor.py

## Temperature and humidity

The model for prediction is based on a decrease in humidity during ventilation for the selected time intervals. It was necessary to consider specific humidity that can be easily converted to relative humidity.

### Initialize general models from local database

A local database was created for debugging purposes. The database includes pre-processed data that enables fast computing of required attributes. The example of a model created using data stored in the database follows.

    """Initialize general models from local database.
    """
    from os.path import dirname, abspath, join
    import sys
    sys.path.append(abspath(join(dirname(__file__), '../..', '')))

    from dm.models.ModelsUtil import ModelsUtil
    from dm.ConnectionUtil import ConnectionUtil as cu
    from dm.models.predictor.generic_training_file_from_local_db import training_file_t_h

    if __name__ == '__main__':
        cu.setup_logging()

        no_event_shift = int(cu.predictor('attrs.no_event.time_shift'))

        data_t_h = training_file_t_h(cu.package('t_h.event_file.name'), no_event_shift)
        t_h_filename = cu.predictor('generic.t_h.model.name') + '_from_local_db.bin'
        ModelsUtil.write_model(data_t_h, t_h_filename, replace=ModelsUtil.replace_ventilation_length)

It is required to create a dataset that contains the same number of events when a window was open and when it was closed. To select the events when the window was closed the variable `no_event_shift` is defined. Its value can be set using the parameter `attrs.no_event.time_shift`. A model is created using the function `training_file_t_h` that uses `SVM` classifier (`sklearn` library). The created model is written to a binary file using the `write_model` function.

The example of a command which can be used to create a model using data stored in the database is below.

    python examples2/0302_ventilation_predictor/t_h_init_general_models_from_local_db.py

### Initialize general models from a remote server

The example of a model created using data saved on the server follows.

    """Initialize general models from a remote server.
    """
    from os.path import dirname, abspath, join
    import sys
    sys.path.append(abspath(join(dirname(__file__), '../..', '')))

    import json

    from dm.models.ModelsUtil import ModelsUtil
    from dm.ConnectionUtil import ConnectionUtil as cu
    from dm.models.predictor.generic_training_file import training_file_t_h
    from dm.WundergroundCom import WundergroundCom

    if __name__ == '__main__':
        cu.setup_logging()
        cls = cu.setup_clients()

        no_event_shift = int(cu.open_detector('attrs.no_event.time_shift'))

        # file with devices for training
        with open(cu.open_detector('generic.devices.path'), 'r') as f:
            devs = json.load(f)

        lat = 49.1649894
        lon = 16.562262499999974

        w = WundergroundCom()
        w.api_key = cu.wunderground_api_key()

        data_t_h = training_file_t_h(cu.package('t_h.event_file.name'), no_event_shift, cls, devs,
                                     lat, lon, w)
        t_h_filename = cu.predictor('generic.t_h.model.name')
        ModelsUtil.write_model(data_t_h, t_h_filename, replace=ModelsUtil.replace_ventilation_length)

At first, it is necessary to set clients that can communicate with a remote server using the function `setup_clients`. Then it is required to create a dataset that contains the same number of events when a window was open and when it was closed. To select the events when the window was closed the variable `no_event_shift` is defined. Its value can be set using the parameter `attrs.no_event.time_shift`. Devices that were used to gather data are stored in the variable `devs`. Latitude and longitude that enable to get weather data according to a sensor position are stored in the variable `lat` and `lon`. The API key allows to get weather data from server and it is obtained by the function `wunderground_api_key`. A model is created using the function `training_file_t_h` that uses `SVM` classifier (`sklearn` library). The created model is written to a binary file using the `write_model` function.

The example of a command which can be used to create a model using data saved on the remote server is below.

    python examples2/0302_ventilation_predictor/t_h_init_general_models.py

### Predictor

The example of the model usage for predicting how long ventilation should be performed follows.

    """Predictor.
    """
    from os.path import dirname, abspath, join
    import sys
    sys.path.append(abspath(join(dirname(__file__), '../..', '')))

    from dm.ConnectionUtil import ConnectionUtil as cu
    from dm.models.ModelsUtil import ModelsUtil
    from dm.WundergroundCom import WundergroundCom
    from dm.DateTimeUtil import DateTimeUtil

    if __name__ == '__main__':
        cu.setup_logging()
        cls = cu.setup_clients()

        actual_time = int(DateTimeUtil.local_time_str_to_utc('2019/02/20 03:00:00').timestamp())
        lat = 49.1649894
        lon = 16.562262499999974

        w = WundergroundCom()
        w.api_key = cu.wunderground_api_key()

        devs = [
            {
                'db_column_name': 'temperature_in2_celsius',
                'gateway_id': '1816820318180747',
                'device_id': '0xa900811026800001',
                'module_id': 0,
                'server_name': 'ant-work',
            },
            {
                'db_column_name': 'rh_in2_percentage',
                'gateway_id': '1816820318180747',
                'device_id': '0xa900811026800001',
                'module_id': 1,
                'server_name': 'ant-work',
            }
        ]

        notification = ModelsUtil.predictor(devs, cls, lat, lon, actual_time, 't_h', w, 40)
        ModelsUtil.json_to_file(notification, 't_h_notification.doc.json', log_notification=True)

It is necessary to set clients that can communicate with a remote server using the function `setup_clients`. Prediction is performed on the basis of data measured during a given time interval. Time that defines end of a time interval is stored in the variable `actual_time`. Latitude and longitude that enable to get weather data according to a sensor position are stored in the variable `lat` and `lon`. The API key allows to get weather data from server and it is obtained by the function `wunderground_api_key`. The sensors used to gather data are stored in the variable `devs`. Prediction how long ventilation should be performed to decrease humidity to a given value is performed by the function `predictor` and the result is stored in the variable `notification`.

An output of the prediction is a notification that contains basic information described in the section Notifications and the following information:

- current_value - current value of humidity [%],

- estimate_time - a time when humidity will reach a given value [min],

- final_value - value of humidity that should be reached after ventilation [%],

- type - what quantity is used for prediction (humidity).

The example of a notification follows.

    {
        "data": {
            "current_value": 41,
            "estimate_time": 10,
            "final_value": 40,
            "type": "t_h_predictor"
        },
        "device_id": "0xa900811026800001",
        "event": "env-notification-pre",
        "gateway_id": "1816820318180747",
        "raise": true,
        "raise_catch": false,
        "readable": "2019-02-20 03:00:00",
        "timestamp": 1550628000
    }

The example of a command which can be used to the use of a model for prediction how long ventilation should be performed is below.

    python examples2/0302_ventilation_predictor/t_h_predictor.py