#!/usr/bin/python3
# -*- coding: utf-8 -*-

import requests
import json
import time
import Adafruit_DHT

config = json.load(open("/etc/dht22_sensing.json"))


class Filter:
    def __init__(self, filter_length, max_mean_deviation):
        self._length = filter_length
        self.values = []
        self.max_mean_deviation = max_mean_deviation

    def mean(self):
        return sum(self.values) / len(self.values)

    def is_valid_value(self, val):
        if len(self.values) == 0:
            return True
        else:
            return abs(val - self.mean()) < self.max_mean_deviation

    def add_if_valid(self, val):
        if self.is_valid_value(val):
            self.values.append(val)
            if len(self.values) > self._length:
                self.values.pop(0)
            return True
        else:
            return False


def send_to_home_assistant(temperature, humidity):
    # print(f"Sending temperature {temperature}, humidity {humidity}")
    headers = {
        'x-ha-access': config['token'],
        'Authorization': "Bearer {}".format(config['token'])
    }

    temperature_url = "{}/api/states/sensor.{}".format(
        config['ha_url'], config['ha_temp_sensor_name'])
    temperatur_data = {
        "state": str(temperature),
        "attributes": {
            "device_class": "temperature",
            "friendly_name": config['ha_temp_friendly_name'],
            "unit_of_measurement": "°C"
        }
    }
    requests.post(temperature_url, json=temperatur_data, headers=headers)

    humidity_url = "{}/api/states/sensor.{}".format(
        config['ha_url'], config['ha_humidity_sensor_name'])
    humidity_data = {
        "state": str(humidity),
        "attributes": {
            "device_class": "humidity",
            "friendly_name": config['ha_humidity_friendly_name'],
            "unit_of_measurement": "%"
        }
    }
    requests.post(humidity_url, json=humidity_data, headers=headers)


last_values = []


def filter(value):
    last_values.append(value)


if __name__ == "__main__":
    temp_filter = Filter(10, 5)
    humidity_filter = Filter(10, 5)

    while True:
        sensor = Adafruit_DHT.DHT22
        humidity, temperature = Adafruit_DHT.read_retry(
            sensor, config['dht_pin'])

        temp_valid = temp_filter.add_if_valid(temperature)
        humidity_valid = humidity_filter.add_if_valid(humidity)
        if not (temp_valid and humidity_valid):
            print(
                f"Discarding value {temperature}C  / {humidity}%, because to far from means {temp_filter.mean()}C, {humidity_filter.mean()}%")
        else:
            try:
                send_to_home_assistant(temperature, humidity)
            except Exception as e:
                print("Failed sending to home assistant")
                print(e)

        time.sleep(float(config['polling_sleep_time_seconds']))
