#!/usr/bin/env python3 """ hier die verbindungen zu HA aufbauen etc außerdem das vergleichen der werte und dass anstoßen der updates """ import asyncio import os from typing import Dict from fritzbox import FritzBox from homeassistant import HomeAssistantAPI import logging import json sensor_mappings = {} thermostate_mappings = {} async def handle_event(idx: int): logging.debug(f"Wait for events for {idx}") while event := await ha.events[idx].get(): entity_id = event["data"]["entity_id"] if entity_id in sensor_mappings.keys() or entity_id in thermostate_mappings.keys(): state = await ha.get_device_state(entity_id) new_state = event["data"]["new_state"] logging.info(f"received changed state from {entity_id}") if entity_id in thermostate_mappings.keys() and state["state"] != "unavailable": therm_temp = new_state["attributes"]["current_temperature"] therm_name = new_state["attributes"]["friendly_name"] sensor = thermostate_mappings[entity_id] sensor_state = await ha.get_device_state(sensor) sensor_temp = round(float(sensor_state["attributes"]["temperature"]) * 2) / 2 if therm_temp != sensor_temp: logging.info(f"{therm_name}: {therm_temp}") logging.info(f"{sensor}: {sensor_state['attributes']['temperature']} ({sensor_temp})") fb.correct_offset(therm_name, sensor_temp) elif entity_id in sensor_mappings.keys(): sensor_temp = round(float(new_state["attributes"]["temperature"]) * 2) / 2 """ fb.login() logged = False """ for thermostate in sensor_mappings[entity_id]: therm_state = await ha.get_device_state(thermostate) if therm_state["state"] == "unavailable": continue therm_temp = float(therm_state["attributes"]["current_temperature"]) therm_name = therm_state["attributes"]["friendly_name"] if therm_temp != sensor_temp: logging.info(f"{therm_name}: {therm_temp}") logging.info(f"{entity_id}: {new_state['attributes']['temperature']} ({sensor_temp})") fb.correct_offset(therm_name, sensor_temp) """ current_temp, current_offset, id, name = fb.get_device_data(name=thermostate) if not logged: logging.info( f"Current measurement from {entity_id}: {new_state['attributes']['temperature']} ({rounded})") logged = True logging.info(f"Current measurement from {thermostate}: {current_temp}") new_offset = current_offset + rounded - current_temp if new_offset != current_offset: old_offset = current_offset logging.debug(f"Set offset for {thermostate} from {current_offset} to {new_offset}") fb.set_offset(current_temp, new_offset, id, name) current_temp, current_offset, id, name = fb.get_device_data(name=thermostate) logging.debug(f"Target: {new_offset} ; Set: {current_offset}") if new_offset == current_offset: logging.info(f"Adjustet offset from {old_offset} to {new_offset}") else: logging.warning(f"Failed to adjust offset from {old_offset} to {new_offset}") fb.logout() """ async def init(ha: HomeAssistantAPI): await ha.connect() logging.debug("Subscribe") state_changed_id = await ha.subscribe_event("state_changed") logging.debug(state_changed_id) asyncio.create_task(handle_event(state_changed_id)) fb.login() await ha.wait_for_close() logging.info("Websocket closed, shutting down..") asyncio.get_running_loop().stop() async def migrate_config(config_path: str, ha: HomeAssistantAPI): config = json.load(open(config_path)) therm_ids = {} for state in await ha.get_states(): if state["entity_id"].startswith("climate.") and "friendly_name" in state["attributes"].keys(): therm_ids[state["attributes"]["friendly_name"]] = state["entity_id"] mappings = [] for mapping in config["mappings"]: if not mapping["thermostate"].startswith("climate."): mapping["thermostate"] = therm_ids[mapping["thermostate"]] mappings.append(mapping) config["mappings"] = mappings json.dump(open(config_path), config) return config logging.basicConfig(level=logging.INFO, format="[%(asctime)s] [%(levelname)s] %(message)s") config_path = "/data/options.json" config_path = "options.json" config = json.load(open(config_path)) logging.debug(config) loop = asyncio.get_event_loop() fb = FritzBox(config["fritzbox"]["url"], config["fritzbox"]["password"]) supervisor_url = "ws://supervisor/core/websocket" supervisor_url = "ws://192.168.124.187:8123/api/websocket" ha = HomeAssistantAPI(os.environ["SUPERVISOR_TOKEN"], supervisor_url) if '"thermostate": "climate.' not in open(config_path).read(): config = loop.run_until_complete(migrate_config(config_path, ha)) logging.info(config) exit() for mapping in config["mappings"]: if mapping["sensor"] not in sensor_mappings.keys(): sensor_mappings[mapping["sensor"]] = [] sensor_mappings[mapping["sensor"]].append(mapping["thermostate"]) thermostate_mappings[mapping["thermostate"]] = mapping["sensor"] loop.create_task(init(ha)) try: loop.run_forever() except KeyboardInterrupt: pass