Compare commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
fb73daef62 | ||
|
|
96a5cd4ee1 | ||
|
|
5204c165d8 | ||
|
|
869f80314b | ||
|
|
9ec0b539e1 | ||
|
|
8912a0bd08 | ||
|
|
db0147e7c1 | ||
|
|
c5f985b5f6 | ||
|
|
63f798ca5a | ||
|
|
483ca4049d | ||
|
|
de1ca78c90 | ||
|
|
a72f42eb4a | ||
|
|
6ce8f24477 | ||
|
|
28cd715327 | ||
|
|
49c1409656 | ||
|
|
d61459c011 |
No files matched your search
@@ -0,0 +1,3 @@
|
|||||||
|
*/__pycache__/
|
||||||
|
*.pyc
|
||||||
|
.DS_Store
|
||||||
@@ -0,0 +1,22 @@
|
|||||||
|
name: Unittests
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
pull_request:
|
||||||
|
# Allows you to run this workflow manually from the Actions tab
|
||||||
|
workflow_dispatch:
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- uses: actions/checkout@v4
|
||||||
|
- name: Set up Python
|
||||||
|
uses: actions/setup-python@v3
|
||||||
|
with:
|
||||||
|
python-version: '3.x'
|
||||||
|
- name: Install dependencies
|
||||||
|
run: |
|
||||||
|
python -m pip install --upgrade pip
|
||||||
|
pip install -r requirements.txt
|
||||||
|
- name: Run unittests
|
||||||
|
run: python3 -m unittest discover -s tests -p "*_test.py"
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
FROM python:3
|
||||||
|
|
||||||
|
COPY requirements.txt .
|
||||||
|
RUN pip install -r requirements.txt
|
||||||
|
|
||||||
|
COPY tests ./tests
|
||||||
|
COPY custom_components ./custom_components
|
||||||
|
|
||||||
|
RUN python3 -m unittest discover -s tests -p "*_test.py"
|
||||||
@@ -0,0 +1,8 @@
|
|||||||
|
"""Elite 30 V2 fields."""
|
||||||
|
|
||||||
|
from ..base_devices.ProtocolV2Device import ProtocolV2Device
|
||||||
|
|
||||||
|
|
||||||
|
class EL30V2(ProtocolV2Device):
|
||||||
|
def __init__(self, address: str, sn: str):
|
||||||
|
super().__init__(address, "EL30V2", sn)
|
||||||
@@ -17,9 +17,10 @@ from ..devices.ep500p import EP500P
|
|||||||
from ..devices.ep600 import EP600
|
from ..devices.ep600 import EP600
|
||||||
from ..devices.ep760 import EP760
|
from ..devices.ep760 import EP760
|
||||||
from ..devices.ep800 import EP800
|
from ..devices.ep800 import EP800
|
||||||
|
from ..devices.el30v2 import EL30V2
|
||||||
|
|
||||||
DEVICE_NAME_RE = re.compile(
|
DEVICE_NAME_RE = re.compile(
|
||||||
r"^(AC60|AC70|AC70P|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|EL30V2)(\d+)$"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
@@ -55,6 +56,8 @@ def build_device(address: str, name: str):
|
|||||||
return EP760(address, match[2])
|
return EP760(address, match[2])
|
||||||
if match[1] == "EP800":
|
if match[1] == "EP800":
|
||||||
return EP800(address, match[2])
|
return EP800(address, match[2])
|
||||||
|
if match[1] == "EL30V2":
|
||||||
|
return EL30V2(address, match[2])
|
||||||
|
|
||||||
|
|
||||||
def get_type_by_bt_name(bt_name: str):
|
def get_type_by_bt_name(bt_name: str):
|
||||||
|
|||||||
@@ -130,7 +130,7 @@ class OptionsFlowHandler(config_entries.OptionsFlow):
|
|||||||
|
|
||||||
def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
|
def __init__(self, config_entry: config_entries.ConfigEntry) -> None:
|
||||||
"""Initialize options flow."""
|
"""Initialize options flow."""
|
||||||
self.config_entry = config_entry
|
super().__init__()
|
||||||
|
|
||||||
async def async_step_init(
|
async def async_step_init(
|
||||||
self, user_input: dict[str, Any] | None = None
|
self, user_input: dict[str, Any] | None = None
|
||||||
|
|||||||
@@ -14,7 +14,8 @@
|
|||||||
{ "local_name": "EP600*" },
|
{ "local_name": "EP600*" },
|
||||||
{ "local_name": "EP760*" },
|
{ "local_name": "EP760*" },
|
||||||
{ "local_name": "EP800*" },
|
{ "local_name": "EP800*" },
|
||||||
{ "local_name": "PBOX*" }
|
{ "local_name": "PBOX*" },
|
||||||
|
{ "local_name": "EL30V2*" }
|
||||||
],
|
],
|
||||||
"codeowners": ["@Patrick762"],
|
"codeowners": ["@Patrick762"],
|
||||||
"config_flow": true,
|
"config_flow": true,
|
||||||
@@ -24,5 +25,5 @@
|
|||||||
"iot_class": "local_polling",
|
"iot_class": "local_polling",
|
||||||
"issue_tracker": "https://github.com/Patrick762/hassio-bluetti-bt/issues",
|
"issue_tracker": "https://github.com/Patrick762/hassio-bluetti-bt/issues",
|
||||||
"requirements": [],
|
"requirements": [],
|
||||||
"version": "0.1.4"
|
"version": "0.1.5"
|
||||||
}
|
}
|
||||||
+7
-1
@@ -2,4 +2,10 @@ homeassistant
|
|||||||
bleak_retry_connector
|
bleak_retry_connector
|
||||||
pyserial
|
pyserial
|
||||||
bluetooth_auto_recovery
|
bluetooth_auto_recovery
|
||||||
crcmod
|
crcmod
|
||||||
|
typing
|
||||||
|
asyncio
|
||||||
|
logging
|
||||||
|
bleak
|
||||||
|
async_timeout
|
||||||
|
aiousbwatcher
|
||||||
@@ -1,4 +1,4 @@
|
|||||||
#!/bin/sh
|
#!/bin/sh
|
||||||
|
|
||||||
# Execute unittests of python library
|
# Execute unittests of python library inside docker
|
||||||
python3 -m unittest discover -s tests -p "*_test.py"
|
sudo docker build --progress=plain -t bluetti-bt-tests .
|
||||||
@@ -8,6 +8,7 @@ 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.ac70p import AC70P
|
||||||
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac180 import AC180
|
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.ac180p import AC180P
|
||||||
|
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac200l import AC200L
|
||||||
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac200m import AC200M
|
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac200m import AC200M
|
||||||
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac300 import AC300
|
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac300 import AC300
|
||||||
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac500 import AC500
|
from custom_components.bluetti_bt.bluetti_bt_lib.devices.ac500 import AC500
|
||||||
@@ -66,6 +67,14 @@ class TestDeviceBuilder(unittest.TestCase):
|
|||||||
self.assertIsInstance(built, AC180P)
|
self.assertIsInstance(built, AC180P)
|
||||||
self.assertEqual(built.address, bt_addr)
|
self.assertEqual(built.address, bt_addr)
|
||||||
|
|
||||||
|
def test_build_ac200l(self):
|
||||||
|
bt_addr = "aa:bb:cc:dd:ee:ff"
|
||||||
|
bt_name = "AC200L56786746478"
|
||||||
|
built = build_device(bt_addr, bt_name)
|
||||||
|
|
||||||
|
self.assertIsInstance(built, AC200L)
|
||||||
|
self.assertEqual(built.address, bt_addr)
|
||||||
|
|
||||||
def test_build_ac200m(self):
|
def test_build_ac200m(self):
|
||||||
bt_addr = "aa:bb:cc:dd:ee:ff"
|
bt_addr = "aa:bb:cc:dd:ee:ff"
|
||||||
bt_name = "AC200M56786746478"
|
bt_name = "AC200M56786746478"
|
||||||
|
|||||||
@@ -0,0 +1,24 @@
|
|||||||
|
"""Unittest for device struct."""
|
||||||
|
|
||||||
|
import unittest
|
||||||
|
|
||||||
|
from custom_components.bluetti_bt.bluetti_bt_lib.utils.commands import ReadHoldingRegisters
|
||||||
|
from custom_components.bluetti_bt.bluetti_bt_lib.utils.struct import DeviceStruct
|
||||||
|
|
||||||
|
class TestDeviceStruct(unittest.TestCase):
|
||||||
|
def test_get_read_holding_registers(self):
|
||||||
|
struct = DeviceStruct()
|
||||||
|
|
||||||
|
struct.add_swap_string_field("device_type", 110, 6)
|
||||||
|
struct.add_sn_field("serial_number", 116)
|
||||||
|
struct.add_decimal_field(
|
||||||
|
"power_generation", 154, 1
|
||||||
|
)
|
||||||
|
struct.add_uint_field("total_battery_percent", 102)
|
||||||
|
|
||||||
|
registers = struct.get_read_holding_registers()
|
||||||
|
|
||||||
|
self.assertGreater(len(registers), 0)
|
||||||
|
|
||||||
|
for reg in registers:
|
||||||
|
self.assertIsInstance(reg, ReadHoldingRegisters)
|
||||||
Reference in new issue
Block a user