#!/usr/bin/env python3

import json
import argparse
import re
import datetime
import paramiko
import requests

# cmd ['ssh', 'smart',
# 'mkdir -p /home/levabd/smart-home-temp-humidity-monitor;
# cat - > /home/levabd/smart-home-temp-humidity-monitor/lr.json']

from miio import chuangmi_plug
from btlewrap import available_backends, BluepyBackend
from mitemp_bt.mitemp_bt_poller import MiTempBtPoller, \
    MI_TEMPERATURE, MI_HUMIDITY, MI_BATTERY

state = {}
f = open('/home/pi/smart-climat-daemon/ac_state.json')
state = json.load(f)
plug_type = 'chuangmi.plug.m1'

def valid_mitemp_mac(mac, pat=re.compile(r"[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}")):
    """Check for valid mac addresses."""
    if not pat.match(mac.upper()):
        raise argparse.ArgumentTypeError(
            'The MAC address "{}" seems to be in the wrong format'.format(mac))
    return mac

def turn_on_humidifier():
    """Turn on humidifier on a first floor."""
    hummidifier_plug = chuangmi_plug.ChuangmiPlug(
        ip='192.168.19.59',
        token='14f5b868a58ef4ffaef6fece61c65b16',
        start_id=0,
        debug=1,
        lazy_discover=True,
        model=plug_type)
    hummidifier_plug.on()


def turn_off_humidifier():
    """Turn off humidifier on a first floor."""
    hummidifier_plug = chuangmi_plug.ChuangmiPlug(
        ip='192.168.19.59',
        token='14f5b868a58ef4ffaef6fece61c65b16',
        start_id=0,
        debug=1,
        lazy_discover=True,
        model=plug_type)
    hummidifier_plug.off()


def check_if_ac_off():
    """Check if AC is turned off."""
    status_url = 'http://smart.levabd.pp.ua:2002/status-bedroom?key=27fbc501b51b47663e77c46816a'
    response = requests.get(status_url, timeout=(20, 30))
    if ('address' not in response.json()) and ('name' not in response.json()):
        return None
    if ((response.json()['name'] == "08bc20043df8") and (response.json()['address'] == "192.168.19.54")):
        if response.json()['props']['boot'] == 0:
            return True
        return False
    return None

def check_if_ac_cool():
    """Check if AC is turned for a automate cooling."""
    status_url = 'http://smart.levabd.pp.ua:2002/status-bedroom?key=27fbc501b51b47663e77c46816a'
    response = requests.get(status_url, timeout=(20, 30))
    if ('address' not in response.json()) or ('name' not in response.json()):
        return None
    if ((response.json()['name'] == "08bc20043df8") and (response.json()['address'] == "192.168.19.54")):
        if not response.json()['props']['boot'] == 1:
            return False
        if not response.json()['props']['runMode'] == '001':
            return False
        if not response.json()['props']['wdNumber'] == 25:
            return False
        if not response.json()['props']['windLevel'] == '001':
            return False
        return True
    return None


def check_if_ac_heat():
    """Check if AC is turned for a automate heating."""
    status_url = 'http://smart.levabd.pp.ua:2003/status/key/27fbc501b51b47663e77c46816a'
    response = requests.get(status_url, timeout=(20, 30))
    if ('address' not in response.json()) and ('name' not in response.json()):
        return None
    if ((response.json()['name'] == "08bc20043df8") and (response.json()['address'] == "192.168.19.54")):
        if not response.json()['props']['boot'] == 1:
            return False
        if not response.json()['props']['runMode'] == '100':
            return False
        if not response.json()['props']['wdNumber'] == 23:
            return False
        if not response.json()['props']['windLevel'] == '001':
            return False
        return True
    return None


def turn_on_heat_ac():
    """Turn on AC on a first floor for a heating if it was not."""
    if (state['wasTurnedHeat'] == 1) and not state['triedTurnedHeat'] == 1:
        return
    heat_url = 'http://smart.levabd.pp.ua:2003/heat/key/27fbc501b51b47663e77c46816a'
    ac_heat = check_if_ac_heat()
    if ac_heat is not None:
        if not ac_heat:
            state['triedTurnedHeat'] = 1
            state['wasTurnedHeat'] = 0
            with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
                json.dump(state, file)
            response = requests.get(heat_url)
            print(response.json())
        else:
            if state['triedTurnedHeat'] == 1:
                state['triedTurnedOff'] = 0
                state['wasTurnedOff'] = 0
                state['triedTurnedCool'] = 0
                state['wasTurnedCool'] = 0
                state['triedTurnedHeat'] = 0
                state['wasTurnedHeat'] = 1
                with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
                    json.dump(state, file)


def turn_on_cool_ac():
    """Turn on AC on a first floor for a cooling if it was not."""
    if (state['wasTurnedCool'] == 1) and not state['triedTurnedCool'] == 1:
        return
    cool_url = 'http://smart.levabd.pp.ua:2003/cool/key/27fbc501b51b47663e77c46816a'
    ac_cool = check_if_ac_cool()
    if ac_cool is not None:
        if not ac_cool:
            state['triedTurnedCool'] = 1
            state['wasTurnedCool'] = 0
            with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
                json.dump(state, file)
            response = requests.get(cool_url)
            print(response.json())
        else:
            if state['triedTurnedCool'] == 1:
                state['triedTurnedOff'] = 0
                state['wasTurnedOff'] = 0
                state['triedTurnedCool'] = 0
                state['wasTurnedCool'] = 1
                state['triedTurnedHeat'] = 0
                state['wasTurnedHeat'] = 0
                with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
                    json.dump(state, file)


def turn_off_ac():
    """Turn off AC on a first floor."""
    if (state['wasTurnedOff'] == 1) and not state['triedTurnedOff'] == 1:
        return
    turn_url = 'http://smart.levabd.pp.ua:2003/power-off/key/27fbc501b51b47663e77c46816a'
    ac_off = check_if_ac_off()
    if ac_off is not None:
        if not ac_off:
            state['triedTurnedOff'] = 1
            state['wasTurnedOff'] = 0
            with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
                json.dump(state, file)
            response = requests.get(turn_url)
            print(response.json())
        else:
            if state['triedTurnedOff'] == 1:
                state['triedTurnedOff'] = 0
                state['wasTurnedOff'] = 1
                state['triedTurnedCool'] = 0
                state['wasTurnedCool'] = 0
                state['triedTurnedHeat'] = 0
                state['wasTurnedHeat'] = 0
                with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
                    json.dump(state, file)

def record_temp_humid(temperature, humidity):
    """Record temperature and humidity data for web interface monitor"""
    dicty = {
        "temperature": temperature,
        "humidity": humidity
        }

    ssh = paramiko.SSHClient()
    ssh.set_missing_host_key_policy(paramiko.AutoAddPolicy())
    ssh.connect('smart.levabd.pp.ua', port = 2001, username='levabd', password='vapipu280.')
    sftp = ssh.open_sftp()

    with sftp.open('smart-home-temp-humidity-monitor/lr.json', 'w') as outfile:
        json.dump(dicty, outfile)

    ssh.close()


def poll_temp_humidity():
    """Poll data frstate['triedTurnedOff']om the sensor."""
    today = datetime.datetime.today()
    backend = BluepyBackend
    poller = MiTempBtPoller('58:2d:34:38:c0:91', backend)
    temperature = poller.parameter_value(MI_TEMPERATURE)
    humidity = poller.parameter_value(MI_HUMIDITY)
    print("Month: {}".format(today.month))
    print("Getting data from Mi Temperature and Humidity Sensor")
    print("FW: {}".format(poller.firmware_version()))
    print("Name: {}".format(poller.name()))
    print("Battery: {}".format(poller.parameter_value(MI_BATTERY)))
    print("Temperature: {}".format(poller.parameter_value(MI_TEMPERATURE)))
    print("Humidity: {}".format(poller.parameter_value(MI_HUMIDITY)))
    return (today, temperature, humidity)

# scan(args):
#     """Scan for sensors."""
#     backend = _get_backend(args)
#     print('Scanning for 10 seconds...')
#     devices = mitemp_scanner.scan(backend, 10)
#     devices = []
#     print('Found {} devices:'.format(len(devices)))
#     for device in devices:
#         print('  {}'.format(device))


def list_backends(_):
    """List all available backends."""
    backends = [b.__name__ for b in available_backends()]
    print('\n'.join(backends))


def main():
    """Main function."""

    # check_if_ac_cool()
    (today, temperature, humidity) = poll_temp_humidity()
    # Record temperature and humidity for monitor
    record_temp_humid(temperature, humidity)

    try:
        if (humidity > 49) and (today.month < 10) and (today.month > 4):
            turn_off_humidifier()
        if (humidity < 31) and (today.month < 10) and (today.month > 4):
            turn_on_humidifier()
        if (humidity < 31) and ((today.month > 9) or (today.month < 5)):
            turn_on_humidifier()
        if (humidity > 49) and ((today.month > 9) or (today.month < 5)):
            turn_off_humidifier()

        # Prevent Sleep of Xiaomi Smart Plug
        hummidifier_plug = chuangmi_plug.ChuangmiPlug(
            ip='192.168.19.59',
            token='14f5b868a58ef4ffaef6fece61c65b16',
            start_id=0,
            debug=0,
            lazy_discover=True,
            model='chuangmi.plug.m1')
        print(hummidifier_plug.status())
    except Exception:
        print("Can not connect to humidifier")

    # clear env at night
    if today.hour == 4:
        state['triedTurnedOff'] = 0
        state['wasTurnedOff'] = 0
        state['triedTurnedCool'] = 0
        state['wasTurnedCool'] = 0
        state['triedTurnedHeat'] = 0
        state['wasTurnedHeat'] = 0
        with open('/home/pi/smart-climat-daemon/ac_state.json', 'w') as file:
            json.dump(state, file)

    if (today.hour > -1) and (today.hour < 7):
        turn_off_ac()
    if (temperature > 26.4) and (today.month < 6) and (today.month > 4) and (today.hour < 24) and (today.hour > 10):
        turn_on_cool_ac()
    if (temperature > 26.4) and (today.month < 10) and (today.month > 8) and (today.hour < 24) and (today.hour > 10):
        turn_on_cool_ac()
    if (temperature > 27.3) and (today.month < 9) and (today.month > 5) and (today.hour < 24) and (today.hour > 10):
        turn_on_cool_ac()
    if (temperature < 23.5) and (today.month < 10) and (today.month > 4):
        turn_off_ac()
    # _if (temperature < 20) and ((today.month > 9) or (today.month < 5)) and (today.hour < 24) and (today.hour > 9):
    #     turn_on_heat_ac()
    if (temperature > 22) and ((today.month > 9) or (today.month < 5)):
        turn_off_ac()


if __name__ == '__main__':
    main()

[((21, 8, 21, 20), 'json.load', 'json.load', ({(21, 18, 21, 19): 'f'}, {}), '(f)', False, 'import json\n'), ((24, 30, 24, 116), 're.compile', 're.compile', ({(24, 41, 24, 115): '"""[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}"""'}, {}), "(\n    '[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}:[0-9A-F]{2}')", False, 'import re\n'), ((33, 23, 39, 24), 'miio.chuangmi_plug.ChuangmiPlug', 'chuangmi_plug.ChuangmiPlug', (), '', False, 'from miio import chuangmi_plug\n'), ((45, 23, 51, 24), 'miio.chuangmi_plug.ChuangmiPlug', 'chuangmi_plug.ChuangmiPlug', (), '', False, 'from miio import chuangmi_plug\n'), ((58, 15, 58, 57), 'requests.get', 'requests.get', (), '', False, 'import requests\n'), ((70, 15, 70, 57), 'requests.get', 'requests.get', (), '', False, 'import requests\n'), ((89, 15, 89, 57), 'requests.get', 'requests.get', (), '', False, 'import requests\n'), ((189, 10, 189, 30), 'paramiko.SSHClient', 'paramiko.SSHClient', ({}, {}), '()', False, 'import paramiko\n'), ((202, 12, 202, 37), 'datetime.datetime.today', 'datetime.datetime.today', ({}, {}), '()', False, 'import datetime\n'), ((204, 13, 204, 57), 'mitemp_bt.mitemp_bt_poller.MiTempBtPoller', 'MiTempBtPoller', ({(204, 28, 204, 47): '"""58:2d:34:38:c0:91"""', (204, 49, 204, 56): 'backend'}, {}), "('58:2d:34:38:c0:91', backend)", False, 'from mitemp_bt.mitemp_bt_poller import MiTempBtPoller, MI_TEMPERATURE, MI_HUMIDITY, MI_BATTERY\n'), ((190, 36, 190, 60), 'paramiko.AutoAddPolicy', 'paramiko.AutoAddPolicy', ({}, {}), '()', False, 'import paramiko\n'), ((195, 8, 195, 33), 'json.dump', 'json.dump', ({(195, 18, 195, 23): 'dicty', (195, 25, 195, 32): 'outfile'}, {}), '(dicty, outfile)', False, 'import json\n'), ((252, 27, 258, 37), 'miio.chuangmi_plug.ChuangmiPlug', 'chuangmi_plug.ChuangmiPlug', (), '', False, 'from miio import chuangmi_plug\n'), ((117, 23, 117, 45), 'requests.get', 'requests.get', ({(117, 36, 117, 44): 'heat_url'}, {}), '(heat_url)', False, 'import requests\n'), ((143, 23, 143, 45), 'requests.get', 'requests.get', ({(143, 36, 143, 44): 'cool_url'}, {}), '(cool_url)', False, 'import requests\n'), ((169, 23, 169, 45), 'requests.get', 'requests.get', ({(169, 36, 169, 44): 'turn_url'}, {}), '(turn_url)', False, 'import requests\n'), ((229, 36, 229, 56), 'btlewrap.available_backends', 'available_backends', ({}, {}), '()', False, 'from btlewrap import available_backends, BluepyBackend\n'), ((272, 12, 272, 34), 'json.dump', 'json.dump', ({(272, 22, 272, 27): 'state', (272, 29, 272, 33): 'file'}, {}), '(state, file)', False, 'import json\n'), ((116, 16, 116, 38), 'json.dump', 'json.dump', ({(116, 26, 116, 31): 'state', (116, 33, 116, 37): 'file'}, {}), '(state, file)', False, 'import json\n'), ((142, 16, 142, 38), 'json.dump', 'json.dump', ({(142, 26, 142, 31): 'state', (142, 33, 142, 37): 'file'}, {}), '(state, file)', False, 'import json\n'), ((168, 16, 168, 38), 'json.dump', 'json.dump', ({(168, 26, 168, 31): 'state', (168, 33, 168, 37): 'file'}, {}), '(state, file)', False, 'import json\n'), ((128, 20, 128, 42), 'json.dump', 'json.dump', ({(128, 30, 128, 35): 'state', (128, 37, 128, 41): 'file'}, {}), '(state, file)', False, 'import json\n'), ((154, 20, 154, 42), 'json.dump', 'json.dump', ({(154, 30, 154, 35): 'state', (154, 37, 154, 41): 'file'}, {}), '(state, file)', False, 'import json\n'), ((180, 20, 180, 42), 'json.dump', 'json.dump', ({(180, 30, 180, 35): 'state', (180, 37, 180, 41): 'file'}, {}), '(state, file)', False, 'import json\n')]