From 16a70e2c04bfd5bd499aecf5ff532a7d1330ea2a Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Johan=20Nenz=C3=A9n?= Date: Tue, 19 Sep 2023 22:13:53 +0000 Subject: [PATCH] Make each button a seperate device (#8) --- custom_components/flichub/__init__.py | 29 +- custom_components/flichub/binary_sensor.py | 285 +++++++++++++++--- custom_components/flichub/config_flow.py | 5 +- custom_components/flichub/const.py | 10 +- custom_components/flichub/entity.py | 98 +++++- custom_components/flichub/manifest.json | 6 +- custom_components/flichub/sensor.py | 50 +++ .../flichub/translations/en.json | 4 +- manage/update_manifest.py | 6 +- 9 files changed, 414 insertions(+), 79 deletions(-) create mode 100644 custom_components/flichub/sensor.py diff --git a/custom_components/flichub/__init__.py b/custom_components/flichub/__init__.py index 9b43181..ba47dbf 100644 --- a/custom_components/flichub/__init__.py +++ b/custom_components/flichub/__init__.py @@ -19,8 +19,8 @@ from pyflichub.client import FlicHubTcpClient from pyflichub.command import Command from pyflichub.event import Event -from .const import CONF_PASSWORD, CLIENT_READY_TIMEOUT, EVENT_CLICK, EVENT_DATA_NAME, EVENT_DATA_CLICK_TYPE, \ - EVENT_DATA_SERIAL_NUMBER +from .const import CLIENT_READY_TIMEOUT, EVENT_CLICK, EVENT_DATA_NAME, EVENT_DATA_CLICK_TYPE, \ + EVENT_DATA_SERIAL_NUMBER, DATA_BUTTONS, DATA_HUB from .const import DOMAIN from .const import PLATFORMS @@ -28,6 +28,7 @@ _LOGGER: logging.Logger = logging.getLogger(__package__) + @dataclass class FlicHubEntryData: """Class for sharing data within the Nanoleaf integration.""" @@ -51,8 +52,19 @@ def on_event(button: FlicButton, event: Event): def on_commend(command: Command): _LOGGER.debug(f"Command: {command.data}") if command.command == "buttons": - coordinator.async_set_updated_data({button.serial_number : button for button in command.data }) - + coordinator.async_set_updated_data( + { + DATA_BUTTONS: {button.serial_number: button for button in command.data}, + DATA_HUB: coordinator.data.get(DATA_HUB, None) if coordinator.data else None + } + ) + if command.command == "network": + coordinator.async_set_updated_data( + { + DATA_BUTTONS: coordinator.data.get(DATA_BUTTONS, None) if coordinator.data else {}, + DATA_HUB: command.data + } + ) client = FlicHubTcpClient( ip=entry.data[CONF_IP_ADDRESS], @@ -65,7 +77,11 @@ def on_commend(command: Command): async def async_get_buttons() -> [FlicButton]: buttons = await client.get_buttons() - return {button.serial_number : button for button in buttons } + hub_info = await client.get_hubinfo() + return { + DATA_BUTTONS: {button.serial_number: button for button in buttons}, + DATA_HUB: hub_info + } def client_connected(): _LOGGER.debug("Connected!") @@ -113,13 +129,12 @@ def stop_client(event): async def async_unload_entry(hass: HomeAssistant, entry: ConfigEntry) -> bool: """Handle removal of an entry.""" - coordinator = hass.data[DOMAIN][entry.entry_id] + hass.data[DOMAIN][entry.entry_id].client.disconnect() unloaded = all( await asyncio.gather( *[ hass.config_entries.async_forward_entry_unload(entry, platform) for platform in PLATFORMS - if platform in coordinator.platforms ] ) ) diff --git a/custom_components/flichub/binary_sensor.py b/custom_components/flichub/binary_sensor.py index 8554046..b1d3852 100644 --- a/custom_components/flichub/binary_sensor.py +++ b/custom_components/flichub/binary_sensor.py @@ -1,17 +1,19 @@ """Binary sensor platform for Flic Hub.""" import logging +from homeassistant.helpers.entity import EntityCategory from homeassistant import core -from homeassistant.components.binary_sensor import BinarySensorEntity, ENTITY_ID_FORMAT +from homeassistant.components.binary_sensor import BinarySensorEntity, ENTITY_ID_FORMAT, BinarySensorDeviceClass from homeassistant.const import PERCENTAGE from homeassistant.core import HomeAssistant from pyflichub.button import FlicButton from pyflichub.event import Event +from pyflichub.flichub import FlicHubInfo from . import FlicHubEntryData from .const import DEFAULT_NAME, EVENT_CLICK, EVENT_DATA_CLICK_TYPE, \ - EVENT_DATA_SERIAL_NUMBER, EVENT_DATA_NAME + EVENT_DATA_SERIAL_NUMBER, EVENT_DATA_NAME, DATA_BUTTONS, DATA_HUB from .const import DOMAIN -from .entity import FlicHubEntity +from .entity import FlicHubButtonEntity, FlicHubEntity _LOGGER: logging.Logger = logging.getLogger(__package__) @@ -19,77 +21,268 @@ async def async_setup_entry(hass, entry, async_add_devices): """Setup binary_sensor platform.""" data_entry: FlicHubEntryData = hass.data[DOMAIN][entry.entry_id] - buttons = await data_entry.client.get_buttons() - for button in buttons: - async_add_devices([FlicHubBinarySensor(hass, data_entry.coordinator, entry, button)]) + buttons = data_entry.coordinator.data[DATA_BUTTONS] + flic_hub = data_entry.coordinator.data[DATA_HUB] + devices = [] + for serial_number, button in buttons.items(): + devices.extend([ + FlicHubButtonBinarySensor(hass, data_entry.coordinator, entry, button, flic_hub), + FlicHubButtonPassiveBinarySensor(data_entry.coordinator, entry, button, flic_hub), + FlicHubButtonActiveDisconnectBinarySensor(data_entry.coordinator, entry, button, flic_hub), + FlicHubButtonConnectedBinarySensor(data_entry.coordinator, entry, button, flic_hub), + FlicHubButtonReadyBinarySensor(data_entry.coordinator, entry, button, flic_hub) + ]) + devices.extend([ + FlicHubWifiBinarySensor(data_entry.coordinator, entry, flic_hub), + FlicHubEthernetBinarySensor(data_entry.coordinator, entry, flic_hub), + ]) + async_add_devices(devices) -class FlicHubBinarySensor(FlicHubEntity, BinarySensorEntity): - """flichub binary_sensor class.""" +class FlicHubWifiBinarySensor(FlicHubEntity, BinarySensorEntity): + """flichub sensor class.""" + _attr_entity_category = EntityCategory.DIAGNOSTIC + _attr_device_class = BinarySensorDeviceClass.CONNECTIVITY - def __init__(self, hass: HomeAssistant, coordinator, config_entry, button: FlicButton): - super().__init__(coordinator, config_entry, button.serial_number) - self.entity_id = ENTITY_ID_FORMAT.format(f"{DEFAULT_NAME}_{self.button.name}") - self._is_on = False - self._click_type = None - hass.bus.async_listen(EVENT_CLICK, self._event_callback) + def __init__(self, coordinator, config_entry, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, flic_hub) + self._attr_icon = "mdi:wifi" @property def name(self): """Return the name of the binary_sensor.""" - return self.button.name + return "Wifi" @property - def icon(self): - """Return the icon.""" - return 'mdi:hockey-puck' + def is_on(self): + """Return true if the binary_sensor is on.""" + return self.flic_hub.wifi.connected if self.flic_hub.has_wifi() else False + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.mac_address}-wifi" + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + return { + "mac_address": self.flic_hub.wifi.mac, + "ip_address": self.flic_hub.wifi.ip, + "state": self.flic_hub.wifi.state, + "ssid": self.flic_hub.wifi.ssid + } @property def available(self) -> bool: """Return True if entity is available.""" - return self.button.connected + return self.flic_hub.has_wifi() + + +class FlicHubEthernetBinarySensor(FlicHubEntity, BinarySensorEntity): + """flichub sensor class.""" + _attr_entity_category = EntityCategory.DIAGNOSTIC + _attr_device_class = BinarySensorDeviceClass.CONNECTIVITY + + def __init__(self, coordinator, config_entry, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, flic_hub) + self._attr_icon = "mdi:ethernet" + + @property + def name(self): + """Return the name of the binary_sensor.""" + return "Ethernet" @property def is_on(self): """Return true if the binary_sensor is on.""" - return self._is_on + return self.flic_hub.ethernet.connected if self.flic_hub.has_ethernet() else False @property - def should_poll(self): - """No polling needed.""" - return False + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.mac_address}-ethernet" @property def extra_state_attributes(self): """Return the state attributes.""" return { - "click_type": self._click_type, - "firmware": self.button.firmware_version, - "flic_version": self.button.flic_version, - "color": self.button.color, - "bluetooth_address": self.button.bdaddr, - "serial_number": self.button.serial_number, - "battery_status": f"{self.button.battery_status}{PERCENTAGE}", - "integration": DOMAIN, + "mac": self.flic_hub.ethernet.mac, + "ip": self.flic_hub.ethernet.ip } + @property + def available(self) -> bool: + """Return True if entity is available.""" + return self.flic_hub.has_ethernet() + + +class FlicHubButtonReadyBinarySensor(FlicHubButtonEntity, BinarySensorEntity): + """flichub sensor class.""" + + def __init__(self, coordinator, config_entry, button: FlicButton, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, button.serial_number, flic_hub) + + @property + def device_class(self) -> BinarySensorDeviceClass | None: + return BinarySensorDeviceClass.PROBLEM + + @property + def entity_category(self) -> EntityCategory | None: + return EntityCategory.DIAGNOSTIC + + @property + def name(self): + """Return the name of the binary_sensor.""" + return "Ready" + + @property + def is_on(self): + """Return true if the binary_sensor is on.""" + return not self.button.ready + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.serial_number}-ready" + + +class FlicHubButtonConnectedBinarySensor(FlicHubButtonEntity, BinarySensorEntity): + """flichub sensor class.""" + + def __init__(self, coordinator, config_entry, button: FlicButton, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, button.serial_number, flic_hub) + self.entity_id = ENTITY_ID_FORMAT.format(f"{DEFAULT_NAME}_{self.button.name}") + + @property + def device_class(self) -> BinarySensorDeviceClass | None: + return BinarySensorDeviceClass.CONNECTIVITY + + @property + def entity_category(self) -> EntityCategory | None: + return EntityCategory.DIAGNOSTIC + + @property + def name(self): + """Return the name of the binary_sensor.""" + return "Connected" + + @property + def is_on(self): + """Return true if the binary_sensor is on.""" + return self.button.connected + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.serial_number}-connected" + + +class FlicHubButtonPassiveBinarySensor(FlicHubButtonEntity, BinarySensorEntity): + """flichub sensor class.""" + + def __init__(self, coordinator, config_entry, button: FlicButton, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, button.serial_number, flic_hub) + + @property + def entity_category(self) -> EntityCategory | None: + return EntityCategory.CONFIG + + @property + def name(self): + """Return the name of the binary_sensor.""" + return "Passive Mode" + + @property + def is_on(self): + """Return true if the binary_sensor is on.""" + return self.button.passive_mode + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.serial_number}-passive_mode" + + +class FlicHubButtonActiveDisconnectBinarySensor(FlicHubButtonEntity, BinarySensorEntity): + """flichub sensor class.""" + + def __init__(self, coordinator, config_entry, button: FlicButton, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, button.serial_number, flic_hub) + + @property + def entity_category(self) -> EntityCategory | None: + return EntityCategory.CONFIG + + @property + def name(self): + """Return the name of the binary_sensor.""" + return "Active Disconnect" + + @property + def is_on(self): + """Return true if the binary_sensor is on.""" + return self.button.active_disconnect + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.serial_number}-active_disconnect" + + +class FlicHubButtonBinarySensor(FlicHubButtonEntity, BinarySensorEntity): + """flichub binary_sensor class.""" + _attr_has_entity_name = True + _attr_name = None + + def __init__(self, hass: HomeAssistant, coordinator, config_entry, button: FlicButton, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, button.serial_number, flic_hub) + self.entity_id = ENTITY_ID_FORMAT.format(f"{DEFAULT_NAME}_{self.button.name}") + self._is_on = False + self._click_type = None + hass.bus.async_listen(EVENT_CLICK, self._event_callback) + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.serial_number}-button" + + @property + def icon(self): + """Return the icon.""" + return 'mdi:hockey-puck' + + @property + def is_on(self): + """Return true if the binary_sensor is on.""" + return self._is_on + + @property + def extra_state_attributes(self): + """Return the state attributes.""" + attrs = {"click_type": self._click_type} + attrs.update(super().extra_state_attributes) + return attrs + def _event_callback(self, event: core.Event): serial_number = event.data[EVENT_DATA_SERIAL_NUMBER] + """Update the entity.""" + if self.serial_number != serial_number: + return + name = event.data[EVENT_DATA_NAME] click_type: Event = event.data[EVENT_DATA_CLICK_TYPE] - """Update the entity.""" _LOGGER.debug(f"Button {name} clicked: {click_type}") - if self.serial_number == serial_number: - if click_type == 'single': - self._click_type = click_type - elif click_type == 'double': - self._click_type = click_type - - if click_type == 'down': - self._is_on = True - if click_type == 'hold': - self._click_type = click_type - self._is_on = True - if click_type == 'up': - self._is_on = False - self.async_write_ha_state() + if click_type == 'single': + self._click_type = click_type + elif click_type == 'double': + self._click_type = click_type + + if click_type == 'down': + self._is_on = True + if click_type == 'hold': + self._click_type = click_type + self._is_on = True + if click_type == 'up': + self._is_on = False + self.async_write_ha_state() diff --git a/custom_components/flichub/config_flow.py b/custom_components/flichub/config_flow.py index 923657e..6fe5e1a 100644 --- a/custom_components/flichub/config_flow.py +++ b/custom_components/flichub/config_flow.py @@ -6,7 +6,7 @@ import voluptuous as vol from homeassistant import config_entries -from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT +from homeassistant.const import CONF_IP_ADDRESS, CONF_PORT, CONF_NAME from homeassistant.core import callback from pyflichub.client import FlicHubTcpClient from .const import CLIENT_READY_TIMEOUT @@ -63,7 +63,7 @@ async def _create_entry(self, user_input): ) await self.hass.config_entries.async_reload(existing_entry.entry_id) return self.async_abort(reason="reauth_successful") - return self.async_create_entry(title=user_input[CONF_IP_ADDRESS], data=user_input) + return self.async_create_entry(title=user_input[CONF_NAME], data=user_input) async def _show_config_form(self, user_input): # pylint: disable=unused-argument """Show the configuration form to edit location data.""" @@ -71,6 +71,7 @@ async def _show_config_form(self, user_input): # pylint: disable=unused-argumen step_id="user", data_schema=vol.Schema( { + vol.Required(CONF_NAME): str, vol.Required(CONF_IP_ADDRESS, default=self.ip_address): str, vol.Required(CONF_PORT): str } diff --git a/custom_components/flichub/const.py b/custom_components/flichub/const.py index a592bfe..9bb815f 100644 --- a/custom_components/flichub/const.py +++ b/custom_components/flichub/const.py @@ -14,6 +14,9 @@ # Icons ICON = "mdi:format-quote-close" +DATA_BUTTONS = "buttons" +DATA_HUB = "network" + # Device classes BINARY_SENSOR_DEVICE_CLASS = "connectivity" @@ -24,12 +27,7 @@ EVENT_DATA_SERIAL_NUMBER = "serial_number" # Platforms -PLATFORMS = [Platform.BINARY_SENSOR] - -# Configuration and options -CONF_ENABLED = "enabled" -CONF_IP_ADDRESS = "username" -CONF_PASSWORD = "password" +PLATFORMS = [Platform.BINARY_SENSOR, Platform.SENSOR] # Defaults DEFAULT_NAME = DOMAIN \ No newline at end of file diff --git a/custom_components/flichub/entity.py b/custom_components/flichub/entity.py index 2d2ecf9..240d86e 100644 --- a/custom_components/flichub/entity.py +++ b/custom_components/flichub/entity.py @@ -1,41 +1,111 @@ """FlicHubEntity class""" -from homeassistant.helpers import entity +from typing import Mapping, Any + +from homeassistant.const import CONF_IP_ADDRESS + +from homeassistant.helpers.device_registry import CONNECTION_BLUETOOTH, CONNECTION_NETWORK_MAC, format_mac + from homeassistant.helpers.update_coordinator import CoordinatorEntity from pyflichub.button import FlicButton +from pyflichub.flichub import FlicHubInfo -from .const import DOMAIN -from .const import NAME -from .const import VERSION +from .const import DOMAIN, DATA_BUTTONS, DATA_HUB -class FlicHubEntity(CoordinatorEntity): - def __init__(self, coordinator, config_entry, serial_number): +class FlicHubButtonEntity(CoordinatorEntity): + _attr_has_entity_name = True + + def __init__(self, coordinator, config_entry, serial_number, flic_hub: FlicHubInfo): super().__init__(coordinator) self.coordinator = coordinator self.serial_number = serial_number self.config_entry = config_entry + self.flic_hub = flic_hub @property - def unique_id(self): + def hub_mac_address(self): """Return a unique ID to use for this entity.""" - return self.serial_number + if self.flic_hub.has_ethernet(): + return format_mac(self.flic_hub.ethernet.mac) + if self.flic_hub.has_wifi(): + return format_mac(self.flic_hub.wifi.mac) + + @property + def mac_address(self): + return format_mac(self.button.bdaddr) @property def device_info(self): return { - "identifiers": {(DOMAIN, NAME)}, - "name": NAME, - "model": VERSION, - "manufacturer": NAME, + "identifiers": {(DOMAIN, self.serial_number)}, + "name": self.button.name, + "model": self.button.flic_version, + "connections": {(CONNECTION_BLUETOOTH, self.mac_address)}, + "sw_version": self.button.firmware_version, + "hw_version": self.button.flic_version, + "manufacturer": "Flic", + "via_device": (DOMAIN, self.hub_mac_address) } @property def button(self) -> FlicButton: - return self.coordinator.data[self.serial_number] + return self.coordinator.data[DATA_BUTTONS][self.serial_number] @property - def extra_state_attributes(self): + def extra_state_attributes(self) -> Mapping[str, Any] | None: """Return the state attributes.""" return { + "color": self.button.color, + "bluetooth_address": self.button.bdaddr, + "serial_number": self.button.serial_number, "integration": DOMAIN, } + + @property + def available(self) -> bool: + """Return True if entity is available.""" + return self.button.connected + + +class FlicHubEntity(CoordinatorEntity): + _attr_has_entity_name = True + + def __init__(self, coordinator, config_entry, flic_hub: FlicHubInfo): + super().__init__(coordinator) + self.coordinator = coordinator + self._flic_hub = flic_hub + self.config_entry = config_entry + + @property + def mac_address(self): + """Return a unique ID to use for this entity.""" + if self.flic_hub.has_ethernet(): + return format_mac(self.flic_hub.ethernet.mac) + if self.flic_hub.has_wifi(): + return format_mac(self.flic_hub.wifi.mac) + + @property + def device_info(self): + identifiers = set() + connections = set() + + if self.flic_hub.has_ethernet(): + identifiers.add((DOMAIN, format_mac(self.flic_hub.ethernet.mac))) + connections.add((DOMAIN, format_mac(self.flic_hub.ethernet.mac))) + if self.flic_hub.has_wifi(): + identifiers.add((DOMAIN, format_mac(self.flic_hub.wifi.mac))) + connections.add((DOMAIN, format_mac(self.flic_hub.wifi.mac))) + + return { + "identifiers": identifiers, + "name": "FlicHub", + "connections": connections, + "manufacturer": "Flic" + } + + @property + def flic_hub(self) -> FlicHubInfo: + if DATA_HUB not in self.coordinator.data: + return self._flic_hub + else: + return self.coordinator.data[DATA_HUB] diff --git a/custom_components/flichub/manifest.json b/custom_components/flichub/manifest.json index b81f2ad..6192caa 100644 --- a/custom_components/flichub/manifest.json +++ b/custom_components/flichub/manifest.json @@ -7,12 +7,16 @@ { "hostname": "flichub", "macaddress": "76EE2A*" + }, + { + "hostname": "flichub", + "macaddress": "36B5AD*" } ], "documentation": "https://github.com/JohNan/home-assistant-flichub", "iot_class": "local_push", "issue_tracker": "https://github.com/JohNan/home-assistant-flichub/issues", "loggers": ["pyflichub"], - "requirements": ["pyflichub-tcpclient==0.1.4"], + "requirements": ["pyflichub-tcpclient==0.1.5"], "version": "v0.0.0" } diff --git a/custom_components/flichub/sensor.py b/custom_components/flichub/sensor.py new file mode 100644 index 0000000..62e8d99 --- /dev/null +++ b/custom_components/flichub/sensor.py @@ -0,0 +1,50 @@ +"""Binary sensor platform for Flic Hub.""" +import logging +from homeassistant.helpers.device_registry import format_mac + +from homeassistant.helpers.update_coordinator import CoordinatorEntity + +from homeassistant.const import CONF_IP_ADDRESS, EntityCategory, CONF_NAME, PERCENTAGE + +from homeassistant.components.binary_sensor import ENTITY_ID_FORMAT +from homeassistant.components.sensor import SensorEntity, SensorDeviceClass, SensorStateClass +from pyflichub.button import FlicButton +from pyflichub.flichub import FlicHubInfo +from . import FlicHubEntryData +from .const import DEFAULT_NAME, DATA_BUTTONS, DATA_HUB +from .const import DOMAIN +from .entity import FlicHubButtonEntity, FlicHubEntity + +_LOGGER: logging.Logger = logging.getLogger(__package__) + + +async def async_setup_entry(hass, entry, async_add_devices): + """Setup binary_sensor platform.""" + data_entry: FlicHubEntryData = hass.data[DOMAIN][entry.entry_id] + buttons = data_entry.coordinator.data[DATA_BUTTONS] + flic_hub = data_entry.coordinator.data[DATA_HUB] + devices = [] + for serial_number, button in buttons.items(): + devices.append(FlicHubButtonBatterySensor(data_entry.coordinator, entry, button, flic_hub)) + async_add_devices(devices) + + +class FlicHubButtonBatterySensor(FlicHubButtonEntity, SensorEntity): + """flichub binary_sensor class.""" + _attr_native_unit_of_measurement = PERCENTAGE + _attr_device_class = SensorDeviceClass.BATTERY + _attr_entity_category = EntityCategory.DIAGNOSTIC + _attr_state_class = SensorStateClass.MEASUREMENT + + def __init__(self, coordinator, config_entry, button: FlicButton, flic_hub: FlicHubInfo): + super().__init__(coordinator, config_entry, button.serial_number, flic_hub) + + @property + def native_value(self): + """Return the state of the sensor.""" + return self.button.battery_status + + @property + def unique_id(self): + """Return a unique ID to use for this entity.""" + return f"{self.serial_number}-battery" diff --git a/custom_components/flichub/translations/en.json b/custom_components/flichub/translations/en.json index 0a64458..cd59514 100644 --- a/custom_components/flichub/translations/en.json +++ b/custom_components/flichub/translations/en.json @@ -5,6 +5,7 @@ "title": "Flic Hub", "description": "If you need help with the configuration have a look here: https://github.com/JohNan/flichub", "data": { + "name": "Name", "ip_address": "IP Address", "port": "Port" } @@ -31,8 +32,7 @@ "user": { "data": { "binary_sensor": "Binary sensor enabled", - "sensor": "Sensor enabled", - "switch": "Switch enabled" + "sensor": "Sensor enabled" } } } diff --git a/manage/update_manifest.py b/manage/update_manifest.py index 9fdf912..ef83aa2 100644 --- a/manage/update_manifest.py +++ b/manage/update_manifest.py @@ -19,7 +19,11 @@ def update_manifest(): with open( f"{os.getcwd()}/custom_components/flichub/manifest.json", "w" ) as manifestfile: - manifestfile.write(json.dumps(manifest, indent=4, sort_keys=True)) + manifestfile.write(json.dumps(manifest, indent=4, sort_keys=False)) + # print output + print("# generated manifest.json") + for key, value in manifest.items(): + print(f"{key}: {value}") update_manifest() \ No newline at end of file