diff --git a/README.md b/README.md index 1807142..b716e93 100644 --- a/README.md +++ b/README.md @@ -17,6 +17,8 @@ After the installation, you can use this button to install the integration: ### Supported devices: - AC60 +- AC70 (basic data) +- AC70P (untested) - AC180 (basic data) - AC180P (basic data) - AC200L (untested) diff --git a/custom_components/bluetti_bt/bluetti_bt_lib/devices/ac70.py b/custom_components/bluetti_bt/bluetti_bt_lib/devices/ac70.py new file mode 100644 index 0000000..5db6a9d --- /dev/null +++ b/custom_components/bluetti_bt/bluetti_bt_lib/devices/ac70.py @@ -0,0 +1,8 @@ +"""AC70 fields.""" + +from ..base_devices.ProtocolV2Device import ProtocolV2Device + + +class AC70(ProtocolV2Device): + def __init__(self, address: str, sn: str): + super().__init__(address, "AC70", sn) diff --git a/custom_components/bluetti_bt/bluetti_bt_lib/devices/ac70p.py b/custom_components/bluetti_bt/bluetti_bt_lib/devices/ac70p.py new file mode 100644 index 0000000..81d77ff --- /dev/null +++ b/custom_components/bluetti_bt/bluetti_bt_lib/devices/ac70p.py @@ -0,0 +1,8 @@ +"""AC70P fields.""" + +from ..base_devices.ProtocolV2Device import ProtocolV2Device + + +class AC70P(ProtocolV2Device): + def __init__(self, address: str, sn: str): + super().__init__(address, "AC70P", sn) diff --git a/custom_components/bluetti_bt/bluetti_bt_lib/utils/device_builder.py b/custom_components/bluetti_bt/bluetti_bt_lib/utils/device_builder.py index ed912b2..37cae52 100644 --- a/custom_components/bluetti_bt/bluetti_bt_lib/utils/device_builder.py +++ b/custom_components/bluetti_bt/bluetti_bt_lib/utils/device_builder.py @@ -3,6 +3,8 @@ import re from ..devices.ac60 import AC60 +from ..devices.ac70 import AC70 +from ..devices.ac70p import AC70P from ..devices.ac180 import AC180 from ..devices.ac180p import AC180P from ..devices.ac200l import AC200L @@ -17,7 +19,7 @@ from ..devices.ep760 import EP760 from ..devices.ep800 import EP800 DEVICE_NAME_RE = re.compile( - r"^(AC60|AC180|AC180P|AC200L|AC200M|AC300|AC500|EB3A|EP500|EP500P|EP600|EP760|EP800)(\d+)$" + r"^(AC60|AC70|AC70P|AC180|AC180P|AC200L|AC200M|AC300|AC500|EB3A|EP500|EP500P|EP600|EP760|EP800)(\d+)$" ) @@ -25,6 +27,10 @@ def build_device(address: str, name: str): match = DEVICE_NAME_RE.match(name) if match[1] == "AC60": return AC60(address, match[2]) + if match[1] == "AC70": + return AC70(address, match[2]) + if match[1] == "AC70P": + return AC70P(address, match[2]) if match[1] == "AC180": return AC180(address, match[2]) if match[1] == "AC180P": diff --git a/custom_components/bluetti_bt/bluetti_bt_lib/utils/struct.py b/custom_components/bluetti_bt/bluetti_bt_lib/utils/struct.py index a4987a1..3990739 100644 --- a/custom_components/bluetti_bt/bluetti_bt_lib/utils/struct.py +++ b/custom_components/bluetti_bt/bluetti_bt_lib/utils/struct.py @@ -92,7 +92,7 @@ class DecimalField(DeviceField): def parse(self, data: bytes) -> Decimal: val = Decimal(struct.unpack("!H", data)[0]) - return (val / 10 ** self.scale) * self.multiplier + return (val / 10 ** self.scale) * Decimal(self.multiplier) def in_range(self, val: Decimal) -> bool: if self.range is None: diff --git a/custom_components/bluetti_bt/manifest.json b/custom_components/bluetti_bt/manifest.json index c81c315..a85f6cf 100644 --- a/custom_components/bluetti_bt/manifest.json +++ b/custom_components/bluetti_bt/manifest.json @@ -23,5 +23,5 @@ "iot_class": "local_polling", "issue_tracker": "https://github.com/Patrick762/hassio-bluetti-bt/issues", "requirements": [], - "version": "0.1.1" + "version": "0.1.2" } diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..76f0ada --- /dev/null +++ b/requirements.txt @@ -0,0 +1,5 @@ +homeassistant +bleak_retry_connector +pyserial +bluetooth_auto_recovery +crcmod \ No newline at end of file diff --git a/tests/device_builder_test.py b/tests/device_builder_test.py index 705596d..3613834 100644 --- a/tests/device_builder_test.py +++ b/tests/device_builder_test.py @@ -4,6 +4,8 @@ import unittest from custom_components.bluetti_bt.bluetti_bt_lib.utils.device_builder import build_device from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac60 import AC60 +from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac70 import AC70 +from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac70p import AC70P from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac180 import AC180 from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac180p import AC180P from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac200m import AC200M @@ -32,6 +34,22 @@ class TestDeviceBuilder(unittest.TestCase): self.assertIsInstance(built, AC60) self.assertEqual(built.address, bt_addr) + def test_build_ac70(self): + bt_addr = "aa:bb:cc:dd:ee:ff" + bt_name = "AC7056786746478" + built = build_device(bt_addr, bt_name) + + self.assertIsInstance(built, AC70) + self.assertEqual(built.address, bt_addr) + + def test_build_ac70p(self): + bt_addr = "aa:bb:cc:dd:ee:ff" + bt_name = "AC70P56786746478" + built = build_device(bt_addr, bt_name) + + self.assertIsInstance(built, AC70P) + self.assertEqual(built.address, bt_addr) + def test_build_ac180(self): bt_addr = "aa:bb:cc:dd:ee:ff" bt_name = "AC18056786746478"