diff --git a/README.md b/README.md index e372705..c3c2b43 100644 --- a/README.md +++ b/README.md @@ -44,7 +44,7 @@ If using [HomeAssistant], this is the preferred method. 1. In the HomeAssistant UI, enter **Supervisor → Add-on Store**. 1. Click **⋮ menu → Repositories**. -1. Add `https://github.com/deiger/AirCon` to the list. +1. Add `https://github.com/emoses/AirCon` to the list. 1. Choose **HiSense Air Conditioner** and install it. 1. Update the configuration as detailed within the add-on. 1. Start the add-on. Do not forget to enable **Start on boot** and **Watchdog**. @@ -71,10 +71,10 @@ Use this method if not using HomeAssistant, or if you prefer to set it up outsid journalctl CONTAINER_NAME=hisense_ac ``` -1. Profit! +1. Profit! The A/Cs should now be auto-discovered by [HomeAssistant] or [openHAB] (using the [HomeAssistant MQTT Components Binding](https://www.openhab.org/addons/bindings/mqtt.homeassistant/)). - [SmartThings] requires manual setup, using the [groovy file](devicetypes/deiger/hisense-air-conditioner.src/hisense-air-conditioner.groovy), see below. + [SmartThings] requires manual setup, using the [groovy file](devicetypes/emoses/hisense-air-conditioner.src/hisense-air-conditioner.groovy), see below. ## Run the A/C control server manually @@ -218,7 +218,7 @@ Listed here are the properties available through the API for standard A/Cs You will need a groovy script to enable SmartThings integration with the Air Conditioner, through the control server above. It currently implements the main functionality (turn on/off, AC mode, fan speed, dimmer etc.). -The groovy file is available [here](devicetypes/deiger/hisense-air-conditioner.src/hisense-air-conditioner.groovy), for download and installation through the [Groovy IDE](https://graph.api.smartthings.com). As I'm continuously improving this script, it would be more efficient to use the IDE's github integration, in order to stay up-to-date. +The groovy file is available [here](devicetypes/emoses/hisense-air-conditioner.src/hisense-air-conditioner.groovy), for download and installation through the [Groovy IDE](https://graph.api.smartthings.com). As I'm continuously improving this script, it would be more efficient to use the IDE's github integration, in order to stay up-to-date. HomeAsststant is now fully supported through [MQTT Discovery]. Properly configured devices are auto-configured and populated in the Lovelace dashboard. diff --git a/aircon/__main__.py b/aircon/__main__.py index d687431..0f8f932 100644 --- a/aircon/__main__.py +++ b/aircon/__main__.py @@ -210,7 +210,7 @@ async def run(parsed_args): 'topic': mqtt_topics['pub'].format(device.mac_address, 'available') }, ], - 'precision': 1.0, + 'precision': device.get_temp_precision(), 'temperature_unit': 'F' if device.is_fahrenheit else 'C' } topics = device.topics diff --git a/aircon/aircon.py b/aircon/aircon.py index 855c825..f4f04f0 100644 --- a/aircon/aircon.py +++ b/aircon/aircon.py @@ -2,6 +2,7 @@ from dataclasses import dataclass, field, fields import enum import logging +import numbers import random import re import string @@ -111,12 +112,20 @@ def get_property(self, name: str): def get_property_type(self, name: str): return self._properties.get_type(name) + def get_temp_precision(self) -> float: + """ This must be 1.0, 0.5, or 0.1 for HA MQTT precision """ + return float(self._properties.get_precision(self.topics['temp'])) + def update_property(self, name: str, value, notify_value=None) -> None: """Update the stored properties, if changed.""" - # Update value precision for value sent from the A/C - precision = self._properties.get_precision(name) - if precision != 1: - value = round(value * precision) + # Update value scale for value sent from the A/C + data_type = self._properties.get_type(name) + if data_type is int: + scale = self._properties.get_scale(name) + precision = self._properties.get_precision(name) + # Scale by scale, then round to precision + value = round(value * scale / precision) * precision + if notify_value is None: notify_value = value @@ -157,10 +166,19 @@ def queue_command(self, name: str, value) -> None: # Device mode is set using t_control_value if issubclass(data_type, enum.Enum): data_value = data_type[value] - elif data_type is int and type(value) is str and '.' in value: - # Round rather than fail if the input is a float. - # This is commonly the case for temperatures converted by HA from Celsius. - data_value = round(float(value)) + elif data_type is int: + # incoming data may be an int or float; it's likely to be a float for + # temperatures converted by HA to/from Celsius. + float_val = float(value) + + # Precision may be 0.5, in which case we round to the nearest 0.5, then apply scale + precision = self._properties.get_precision(name) + scale = self._properties.get_scale(name) + float_val = (round(float_val / precision) * precision) / scale + + # Update value scale for value to be sent to the A/C + # We assume that only int types have a scale value + data_value = round(float_val) else: data_value = data_type(value) @@ -174,11 +192,6 @@ def queue_command(self, name: str, value) -> None: data_value = data_value.value typed_value = data_type[value] - # Update value precision for value to be sent to the A/C - precision = self._properties.get_precision(name) - if precision != 1: - data_value = round(data_value / precision) - command = self._build_command(name, data_value) # There are (usually) no acks on commands, so also queue an update to the # property, to be run once the command is sent. diff --git a/aircon/properties.py b/aircon/properties.py index 0881205..a92aa92 100644 --- a/aircon/properties.py +++ b/aircon/properties.py @@ -152,7 +152,18 @@ def get_base_type(cls, attr: str): return cls._get_metadata(attr)['base_type'] @classmethod - def get_precision(cls, attr: str): + def get_scale(cls, attr: str) -> float: + """Scale affects int values; they will be divided by the scale to get a result that's + sent to the device, or multiplied when updating from the device. A typical value is 0.1. + """ + return cls._get_metadata(attr).get('scale', 1) + + @classmethod + def get_precision(cls, attr: str) -> float: + """Precision affects int values. Any incoming float value v will be rounded to the nearest + precision g by round(v/g) * g. A typical value is 0.5. Combined with a scale of 0.1, this + can convert an incoming value of 20.1 to 200, or 20.4 to 205. + """ return cls._get_metadata(attr).get('precision', 1) @classmethod @@ -403,13 +414,14 @@ class FglProperties(Properties): adjust_temperature: int = field(default=25, metadata={ 'base_type': 'integer', - 'precision': 0.1, + 'scale': 0.1, + 'precision': 0.5, 'read_only': False }) display_temperature: int = field(default=25, metadata={ 'base_type': 'integer', - 'precision': 0.1, + 'scale': 0.1, 'read_only': True }) af_vertical_direction: int = field(default=3, @@ -475,13 +487,13 @@ class FglBProperties(Properties): adjust_temperature: int = field(default=25, metadata={ 'base_type': 'integer', - 'precision': 0.1, + 'scale': 0.1, 'read_only': False }) display_temperature: int = field(default=25, metadata={ 'base_type': 'integer', - 'precision': 0.1, + 'scale': 0.1, 'read_only': True }) af_vertical_move_step1: int = field(default=3, diff --git a/docker-compose.yaml b/docker-compose.yaml index 92c2620..477e321 100644 --- a/docker-compose.yaml +++ b/docker-compose.yaml @@ -10,7 +10,7 @@ services: hisense_ac: depends_on: - copy_config - image: deiger/aircon:0.3.17 + image: emoses/aircon:0.3.17 container_name: hisense_ac healthcheck: disable: true diff --git a/hassio/DOCS.md b/hassio/DOCS.md index 9134144..d27099b 100644 --- a/hassio/DOCS.md +++ b/hassio/DOCS.md @@ -13,7 +13,7 @@ # Configuration 1. Find your application code from the list - [here](https://github.com/deiger/AirCon#prerequisites). + [here](https://github.com/emoses/AirCon#prerequisites). 1. Set the configuration as follows: ```yaml app: diff --git a/hassio/README.md b/hassio/README.md index 7482289..2fa74c6 100644 --- a/hassio/README.md +++ b/hassio/README.md @@ -4,7 +4,7 @@ ## About -Use this add-on to add support for Hisense Air Conditioners. See [here](https://github.com/deiger/AirCon) for more details. +Use this add-on to add support for Hisense Air Conditioners. See [here](https://github.com/emoses/AirCon) for more details. [aarch64-shield]: https://img.shields.io/badge/aarch64-yes-green.svg [amd64-shield]: https://img.shields.io/badge/amd64-yes-green.svg diff --git a/hassio/config.json b/hassio/config.json index faf7cab..e77a532 100644 --- a/hassio/config.json +++ b/hassio/config.json @@ -3,8 +3,8 @@ "version": "0.3.17", "slug": "hisense_ac", "description": "Interface for controlling Air Conditioners, e.g. with HiSense modules.", - "url": "https://github.com/deiger/AirCon", - "image": "deiger/aircon", + "url": "https://github.com/emoses/Aircon", + "image": "emoses/aircon", "arch": ["armhf", "armv7", "aarch64", "amd64", "i386"], "startup": "application", "boot": "auto", diff --git a/new_version.sh b/new_version.sh index f8dca2e..81ff3b7 100755 --- a/new_version.sh +++ b/new_version.sh @@ -1,5 +1,5 @@ #!/bin/bash -set -e +set -xeo pipefail git pull @@ -12,7 +12,7 @@ else fi git tag -a $NEW_VERSION -m "$NEW_VERSION_MSG" -auto-changelog +#auto-changelog for f in aircon/__init__.py hassio/config.json docker-compose.yaml; do sed -i "" -e "s/$OLD_VERSION/$NEW_VERSION/" $f @@ -23,6 +23,6 @@ git tag -d $NEW_VERSION git tag -a $NEW_VERSION -m "$NEW_VERSION_MSG" docker buildx rm --all-inactive --force docker buildx create --name multiarch --driver docker-container --use || true -docker buildx build --platform linux/arm/v7,linux/arm64,linux/amd64,linux/386 -t deiger/aircon:$NEW_VERSION --push . +docker buildx build --platform linux/arm/v7,linux/arm64,linux/amd64,linux/386 -t emoses/aircon:$NEW_VERSION --push . git push git push --tags diff --git a/repository.json b/repository.json index 8b470e1..0d4c23c 100644 --- a/repository.json +++ b/repository.json @@ -1,5 +1,5 @@ { "name": "Home Assistant Add-on: HiSense Air Conditioners", - "url": "https://github.com/deiger/AirCon", + "url": "https://github.com/emoses/AirCon", "maintainer": "Dror Eiger " } diff --git a/setup.py b/setup.py index 30cd5dc..7dd15af 100644 --- a/setup.py +++ b/setup.py @@ -13,7 +13,7 @@ description='Interface for controlling Air Conditioners, e.g. with HiSense modules.', long_description=long_description, long_description_content_type='text/markdown', - url='https://github.com/deiger/AirCon', + url='https://github.com/emoses/AirCon', author='Dror Eiger', author_email='droreiger@gmail.com', license='GPL 3.0',