This commit is contained in:
Mateusz Gruszczyński committed 2026-09-23 13:41:34 +02:00
1 parent abfbf0dd68
commit aa1cb05b2f
24 files changed
+750 -71

No files matched your search

+3 -3
View File
@@ -1,5 +1,5 @@
#!/usr/bin/env python3
"""Developer smoke/integration tests for GREE Controller API 0.15.19.
"""Developer smoke/integration tests for GREE Controller API 0.15.20.
Default mode is read-only and safe to run against a real controller.
Use --settings-write to additionally round-trip all split settings resources and
@@ -26,7 +26,7 @@ from typing import Any, Callable, Iterable, Optional
DEFAULT_BASE_URL = os.environ.get("GREE_API_URL", "http://127.0.0.1:8787")
DEFAULT_TOKEN = os.environ.get("GREE_API_TOKEN", "")
DEFAULT_EXPECTED_VERSION = "0.15.19"
DEFAULT_EXPECTED_VERSION = "0.15.20"
SETTINGS_PATHS: dict[str, set[str]] = {
"/api/settings/application": {"simulator_enabled"},
@@ -599,7 +599,7 @@ def run_suite(args: argparse.Namespace) -> int:
print(f"Settings write tests: {'ENABLED' if args.settings_write else 'disabled'}\n")
runner.run("public health", lambda: test_health(client, args.expected_version))
runner.run("OpenAPI 0.15.19 contract", lambda: test_openapi(client, args.expected_version))
runner.run("OpenAPI 0.15.20 contract", lambda: test_openapi(client, args.expected_version))
runner.run("bootstrap snapshot contract", lambda: test_bootstrap_contract(client))
runner.run("protected API requires auth", lambda: test_protected_auth(client))
+25
View File
@@ -3,6 +3,10 @@ set -Eeuo pipefail
ROOT="$(cd "$(dirname "${BASH_SOURCE[0]}")/.." && pwd)"
cd "$ROOT"
# Keep Flow metadata and the user-visible block palette in sync.
grep -q 'heating_curve:.*flow.node.heatingCurve' web/js-dynamic/flows.js
grep -q 'data-flow-add="heating_curve".*data-i18n="flow.node.heatingCurve"' web/index.html
BINARY="${GREE_CONTROLLER_TEST_BINARY:-$ROOT/target/debug/gree-controller}"
[[ -x "$BINARY" ]] || cargo build >/dev/null
TMP="$(mktemp -d)"
@@ -128,6 +132,27 @@ json.dump({"flow":flow,"flow_id":sys.argv[3],"at":datetime.datetime.now(datetime
PYFLOW
curl -fsS -X POST -H 'Content-Type: application/json' --data-binary @"$TMP/flow-simulate.json" "http://127.0.0.1:$PORT/api/flows/simulate" >"$TMP/flow-dry-run.json"
grep -q '"dry_run":true' "$TMP/flow-dry-run.json"
# Heating curve is a numeric Flow source: it interpolates X/Y and binds the result to the
# downstream thermostat setpoint without turning the graph into a native fixed schedule.
cat >"$TMP/flow-heating-curve.json" <<EOF
{"flow":{"name":"Heating curve","enabled":true,"nodes":[{"id":"curve","kind":"heating_curve","x":20,"y":20,"config":{"source":"outdoor_temperature","points":[{"x":-20,"y":30},{"x":0,"y":25},{"x":20,"y":19}]}},{"id":"action","kind":"zone_thermostat","x":300,"y":20,"config":{"zone_id":"$ZONE_ID","preset":"comfort","mode":"auto","cooldown_seconds":60}}],"edges":[{"id":"e1","from":"curve","to":"action"}]},"overrides":{"curve":0},"log":false}
EOF
curl -fsS -X POST -H 'Content-Type: application/json' --data-binary @"$TMP/flow-heating-curve.json" \
"http://127.0.0.1:$PORT/api/flows/simulate" >"$TMP/flow-heating-curve-result.json"
python3 - "$TMP/flow-heating-curve-result.json" <<'PYFLOW'
import json,sys
result=json.load(open(sys.argv[1]))
assert result["compiled"] == {"schedules": 0, "automations": 1}, result
action=result["actions"][0]
assert action["matched"] is True, action
assert action["dynamic_value"] == 25.0, action
assert action["dynamic_value_target"] == "setpoint", action
trace={item["node_id"]:item for item in action["trace"]}
assert trace["curve"]["actual"]["input"] == 0.0, trace
assert trace["curve"]["actual"]["output"] == 25.0, trace
PYFLOW
curl -fsS "http://127.0.0.1:$PORT/api/flows/$FLOW_ID/export" >"$TMP/flow-export.json"
grep -q '"format":"gree-controller-flow"' "$TMP/flow-export.json"
curl -fsS -X POST -H 'Content-Type: application/json' --data-binary @"$TMP/flow-export.json" "http://127.0.0.1:$PORT/api/flows/import" >"$TMP/flow-import.json"