seed: refuse an engine that would ignore what these flows rely on
A node type accepts a setting it does not know and ignores it, which is right for a node someone is editing and wrong here: seeded against the engine this installation is running today, every rollershutter would take the trigger's default minute instead of the twenty-six seconds it actually takes, and every Victron reading would arrive as an object where a number was declared. It would look like it had worked. So the seed asks what the node types know before it writes anything, and says which rebuild is missing. Co-Authored-By: Claude Opus 5 (1M context) <noreply@anthropic.com>
This commit is contained in:
@@ -383,6 +383,39 @@ def push(api: Api, flows: list[Flow]) -> None:
|
|||||||
print(f" dashboard '{name}': {len(widgets)} widgets, published")
|
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:
|
def main(argv: list[str]) -> int:
|
||||||
dry = "--dry" in argv
|
dry = "--dry" in argv
|
||||||
h = house()
|
h = house()
|
||||||
@@ -401,6 +434,24 @@ def main(argv: list[str]) -> int:
|
|||||||
return 0
|
return 0
|
||||||
|
|
||||||
api = Api()
|
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"])
|
have = set(api("GET", "/secrets/")["data"])
|
||||||
missing = [name for name in SECRETS if name not in have]
|
missing = [name for name in SECRETS if name not in have]
|
||||||
if missing:
|
if missing:
|
||||||
|
|||||||
Reference in New Issue
Block a user