mirror of
https://github.com/vakius/hassio-addon-lifepo4wered.git
synced 2026-08-01 20:44:12 +03:00
VOUT_MAX is the safety limit above which the UPS refuses to boot an externally-powered Pi, not an output voltage setting. Also clarify PI_RUNNING, WATCHDOG_GRACE and TOUCH_STATE names, and add documented units: timeouts and watchdog values are CLI-scaled seconds, AUTO_SHDN_TIME is minutes; SHDN_DELAY stays raw ticks. Co-Authored-By: Claude Fable 5 <noreply@anthropic.com>
109 lines
4.2 KiB
Python
109 lines
4.2 KiB
Python
import json
|
|
import os
|
|
import sys
|
|
import unittest
|
|
|
|
sys.path.insert(0, os.path.join(os.path.dirname(__file__), "..",
|
|
"hassio-addon-lifepo4wered"))
|
|
|
|
import lifepo4wered_monitor as mon
|
|
|
|
|
|
class ParseOutputTest(unittest.TestCase):
|
|
def test_parses_sample_output(self):
|
|
values = mon.parse_cli_output(mon.SAMPLE_OUTPUT)
|
|
self.assertEqual(values["VIN"], 4709)
|
|
self.assertEqual(values["VBAT"], 3233)
|
|
self.assertEqual(values["IOUT"], 1355)
|
|
self.assertEqual(values["PI_RUNNING"], 1)
|
|
self.assertEqual(len(values), 36)
|
|
|
|
def test_skips_malformed_lines(self):
|
|
values = mon.parse_cli_output("VIN = 5000\ngarbage line\nVBAT = abc\n")
|
|
self.assertEqual(values, {"VIN": 5000})
|
|
|
|
def test_handles_negative_values(self):
|
|
values = mon.parse_cli_output("IOUT_OFFSET = -12\n")
|
|
self.assertEqual(values["IOUT_OFFSET"], -12)
|
|
|
|
|
|
class DiscoveryTest(unittest.TestCase):
|
|
def setUp(self):
|
|
self.messages = dict(mon.discovery_messages(
|
|
discovery_prefix="homeassistant",
|
|
state_topic="lifepo4wered/state",
|
|
availability_topic="lifepo4wered/availability",
|
|
))
|
|
|
|
def test_main_voltage_sensor(self):
|
|
topic = "homeassistant/sensor/lifepo4wered/vin/config"
|
|
self.assertIn(topic, self.messages)
|
|
cfg = self.messages[topic]
|
|
self.assertEqual(cfg["device_class"], "voltage")
|
|
self.assertEqual(cfg["unit_of_measurement"], "V")
|
|
self.assertEqual(cfg["state_class"], "measurement")
|
|
self.assertIn("value_json.VIN", cfg["value_template"])
|
|
self.assertNotIn("entity_category", cfg)
|
|
|
|
def test_current_sensor(self):
|
|
cfg = self.messages["homeassistant/sensor/lifepo4wered/iout/config"]
|
|
self.assertEqual(cfg["device_class"], "current")
|
|
self.assertEqual(cfg["unit_of_measurement"], "A")
|
|
|
|
def test_external_power_binary_sensor(self):
|
|
topic = "homeassistant/binary_sensor/lifepo4wered/external_power/config"
|
|
self.assertIn(topic, self.messages)
|
|
cfg = self.messages[topic]
|
|
self.assertEqual(cfg["device_class"], "power")
|
|
self.assertIn("VIN_THRESHOLD", cfg["value_template"])
|
|
|
|
def test_diagnostic_entities_are_categorized(self):
|
|
cfg = self.messages["homeassistant/sensor/lifepo4wered/vbat_shdn/config"]
|
|
self.assertEqual(cfg["entity_category"], "diagnostic")
|
|
self.assertEqual(cfg["unit_of_measurement"], "V")
|
|
|
|
def test_timer_registers_have_documented_units(self):
|
|
for key, unit in (("pi_boot_to", "s"), ("pi_shdn_to", "s"),
|
|
("watchdog_grace", "s"), ("watchdog_timer", "s"),
|
|
("auto_shdn_time", "min")):
|
|
cfg = self.messages[
|
|
"homeassistant/sensor/lifepo4wered/%s/config" % key]
|
|
self.assertEqual(cfg["unit_of_measurement"], unit, key)
|
|
self.assertNotIn(
|
|
"unit_of_measurement",
|
|
self.messages["homeassistant/sensor/lifepo4wered/shdn_delay/config"])
|
|
|
|
def test_skipped_registers_have_no_entity(self):
|
|
for key in ("i2c_reg_ver", "dco_rsel", "vbat_offset", "cfg_write"):
|
|
self.assertNotIn(
|
|
"homeassistant/sensor/lifepo4wered/%s/config" % key,
|
|
self.messages)
|
|
|
|
def test_common_fields(self):
|
|
for topic, cfg in self.messages.items():
|
|
self.assertEqual(cfg["state_topic"], "lifepo4wered/state")
|
|
self.assertEqual(cfg["availability_topic"],
|
|
"lifepo4wered/availability")
|
|
self.assertTrue(cfg["unique_id"].startswith("lifepo4wered_"),
|
|
topic)
|
|
self.assertEqual(cfg["device"]["identifiers"], ["lifepo4wered_pi"])
|
|
json.dumps(cfg) # must be serializable
|
|
|
|
def test_unique_ids_are_unique(self):
|
|
ids = [cfg["unique_id"] for cfg in self.messages.values()]
|
|
self.assertEqual(len(ids), len(set(ids)))
|
|
|
|
|
|
class ReadValuesTest(unittest.TestCase):
|
|
def test_fake_mode(self):
|
|
os.environ["LIFEPO4WERED_FAKE"] = "1"
|
|
try:
|
|
values = mon.read_values()
|
|
finally:
|
|
del os.environ["LIFEPO4WERED_FAKE"]
|
|
self.assertEqual(values["VOUT"], 4993)
|
|
|
|
|
|
if __name__ == "__main__":
|
|
unittest.main()
|