diff --git a/scripts/tinyhouse/__main__.py b/scripts/tinyhouse/__main__.py index 0a2c8ed..ec9c8f0 100644 --- a/scripts/tinyhouse/__main__.py +++ b/scripts/tinyhouse/__main__.py @@ -383,6 +383,39 @@ def push(api: Api, flows: list[Flow]) -> None: print(f" dashboard '{name}': {len(widgets)} widgets, published") +#: Settings these flows depend on that a node type gained for this port. A node +#: type accepts an unknown setting and ignores it — which is right for a node +#: someone is editing and wrong here, where it would mean a rollershutter +#: running for the default minute instead of the twenty-six seconds it takes. +NEEDED = { + "trigger": { + "wait_port": "a shutter would run for the default wait, not its own", + "passthrough": "a motor would be commanded with 'true' rather than a direction", + }, + "mqtt": { + "json_key": "every Victron reading would arrive as an object, not a number", + }, + "http": { + "query": "the weather key would have to sit in the flow file in clear", + }, +} + + +def _engine_too_old(api: Api) -> list[tuple[str, str]]: + """Settings this installation's node types do not know about yet.""" + types = {t["type"]: t for t in api("GET", "/flows/node-types")} + stale = [] + for type_name, settings in NEEDED.items(): + schema = types.get(type_name, {}).get("params_schema") or {} + known = set(schema.get("properties") or {}) + if not known: + continue + for setting, why in settings.items(): + if setting not in known: + stale.append((f"{type_name}.{setting}", why)) + return stale + + def main(argv: list[str]) -> int: dry = "--dry" in argv h = house() @@ -401,6 +434,24 @@ def main(argv: list[str]) -> int: return 0 api = Api() + stale = _engine_too_old(api) + if stale: + print( + "\nThis installation's engine does not have what these flows need:", + file=sys.stderr, + ) + for setting, why in stale: + print(f" {setting} — {why}", file=sys.stderr) + print( + "\nAn unknown setting is accepted and ignored rather than refused, so\n" + "seeding now would look like it worked and run every shutter for a\n" + "minute. Rebuild the image first:\n" + ' docker compose -p fluksio-app --env-file "$PWD/.env" \\\n' + " -f docker/compose.yml up --build -d backend", + file=sys.stderr, + ) + return 1 + have = set(api("GET", "/secrets/")["data"]) missing = [name for name in SECRETS if name not in have] if missing: