Fix C1 (switch discovery), C2 (power write_fn), I2 (golden oracle)
C1: SwitchDesc MQTT discovery now emits payload_on/off='On'/'Off', state_on/off='On'/'Off', and a Jinja2 boolean-to-string value_template so HA can correctly interpret and command switch entities. C2: POWER write_fn corrected — path is ['power','vs','0'] segment list (not a single slash-prefixed string), and payload comparison is p == 'On' (not truthiness) so 'Off' can actually be sent. I2: Golden regression oracle strengthened to exact equality for both state_keys and discovery_unique_ids; prior subset-only check allowed over-production to go undetected. Two golden tests now fail revealing stale fixtures (dishwasher: +3 keys; refrigerator: +9 keys) — fixtures intentionally NOT updated, human review required.
This commit is contained in:
@@ -204,7 +204,11 @@ def _discovery_payloads(bound, topic_prefix, ha_prefix, device_name, model):
|
||||
cfg['options'] = list(opts) if isinstance(opts, (list, tuple)) else []
|
||||
elif isinstance(d, SwitchDesc):
|
||||
cfg['state_topic'] = state_topic
|
||||
cfg['value_template'] = f"{{{{ value_json.{key} }}}}"
|
||||
cfg['value_template'] = f"{{% if value_json.{key} %}}On{{% else %}}Off{{% endif %}}"
|
||||
cfg['state_on'] = 'On'
|
||||
cfg['state_off'] = 'Off'
|
||||
cfg['payload_on'] = 'On'
|
||||
cfg['payload_off'] = 'Off'
|
||||
cfg['command_topic'] = f"{topic_prefix}/cmd/{key}"
|
||||
elif isinstance(d, ButtonDesc):
|
||||
cfg['command_topic'] = f"{topic_prefix}/cmd/{key}"
|
||||
|
||||
@@ -74,7 +74,7 @@ POWER = Capability(
|
||||
SwitchDesc(key='power_switch', field='x.com.samsung.da.power',
|
||||
name='Power',
|
||||
value_fn=lambda v: v == 'On',
|
||||
write_fn=lambda p, rep: (['/power/vs/0'], {'x.com.samsung.da.power': 'On' if p else 'Off'})),
|
||||
write_fn=lambda p, rep: (['power', 'vs', '0'], {'x.com.samsung.da.power': 'On' if p == 'On' else 'Off'})),
|
||||
SensorDesc(key='power_state', field='x.com.samsung.da.power',
|
||||
name='Power state'),
|
||||
BinarySensorDesc(key='power_state_binary', field='x.com.samsung.da.power',
|
||||
|
||||
@@ -10,6 +10,11 @@ def _bound(resources):
|
||||
return discover(resources, reg)
|
||||
|
||||
|
||||
def _bound_with_power(resources):
|
||||
reg = {c.href: c for c in (common.KIDS_LOCK, common.ENERGY_METER, common.POWER)}
|
||||
return discover(resources, reg)
|
||||
|
||||
|
||||
def test_flatten_applies_value_fn(dishwasher_resources):
|
||||
rd = build_runtime_descriptor(
|
||||
_bound(dishwasher_resources), topic_prefix='t', ha_prefix='homeassistant',
|
||||
@@ -38,3 +43,17 @@ def test_discovery_payloads_have_unique_ids(dishwasher_resources):
|
||||
# payloads are JSON bytes carrying unique_id
|
||||
cfg = json.loads(next(p for t, p in rd.discovery_payloads if 'child_lock' in t))
|
||||
assert cfg['unique_id'] == 'samsung_dishwasher_child_lock'
|
||||
|
||||
|
||||
def test_switch_discovery_config_has_correct_payloads(dishwasher_resources):
|
||||
rd = build_runtime_descriptor(
|
||||
_bound_with_power(dishwasher_resources), topic_prefix='samsung_dishwasher',
|
||||
ha_prefix='homeassistant', device_name='Dishwasher', model='M',
|
||||
name='dishwasher', default_port=49154)
|
||||
cfg = json.loads(next(p for t, p in rd.discovery_payloads if 'power_switch' in t))
|
||||
assert cfg['payload_on'] == 'On'
|
||||
assert cfg['payload_off'] == 'Off'
|
||||
assert cfg['state_on'] == 'On'
|
||||
assert cfg['state_off'] == 'Off'
|
||||
assert 'On' in cfg['value_template']
|
||||
assert 'Off' in cfg['value_template']
|
||||
|
||||
@@ -26,6 +26,14 @@ def _new_state_and_uids(name, resources):
|
||||
def test_registry_reproduces_golden_state_keys(name, ip, request):
|
||||
resources = json.load(open(f'local-tools/dumps/{ip}.json'))['resources']
|
||||
golden = json.loads((GOLDEN / f'{name}.json').read_text())
|
||||
state_keys, _ = _new_state_and_uids(name, resources)
|
||||
missing = set(golden['state_keys']) - set(state_keys)
|
||||
assert not missing, f"registry missing state keys: {sorted(missing)}"
|
||||
state_keys, uids = _new_state_and_uids(name, resources)
|
||||
assert set(state_keys) == set(golden['state_keys']), (
|
||||
f"state_keys mismatch:\n"
|
||||
f" extra: {sorted(set(state_keys) - set(golden['state_keys']))}\n"
|
||||
f" missing: {sorted(set(golden['state_keys']) - set(state_keys))}"
|
||||
)
|
||||
assert set(uids) == set(golden['discovery_unique_ids']), (
|
||||
f"unique_ids mismatch:\n"
|
||||
f" extra: {sorted(set(uids) - set(golden['discovery_unique_ids']))}\n"
|
||||
f" missing: {sorted(set(golden['discovery_unique_ids']) - set(uids))}"
|
||||
)
|
||||
|
||||
Reference in New Issue
Block a user