Compare commits

..

30 Commits

Author SHA1 Message Date
8fa81be750 new mtls approach
All checks were successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
2025-11-29 22:55:42 +01:00
205baa7e01 mtls fix 3
Some checks failed
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
2025-11-29 22:19:12 +01:00
f3f9238d5f mtls fix 2
Some checks failed
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/predeploy Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 22:02:11 +01:00
5decf79bee mTLS 2
Some checks failed
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 21:41:50 +01:00
be2654ac98 ignore ca
Some checks failed
ci/woodpecker/push/predeploy Pipeline is pending
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/push/build/2 Pipeline failed
2025-11-29 21:38:20 +01:00
bb27296310 mTLS
All checks were successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
2025-11-29 21:35:35 +01:00
63857671f9 add ingress cors fix
Some checks failed
ci/woodpecker/push/deploy/2 Pipeline is pending
ci/woodpecker/push/deploy/3 Pipeline is pending
ci/woodpecker/push/deploy/4 Pipeline is pending
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline failed
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 21:05:54 +01:00
d008c9fd5a add ingress 2
All checks were successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
2025-11-29 21:02:05 +01:00
1eb0f84659 add ingress
Some checks failed
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline failed
ci/woodpecker/push/deploy/3 Pipeline failed
ci/woodpecker/push/deploy/4 Pipeline failed
ci/woodpecker/push/deploy/2 Pipeline failed
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
2025-11-29 20:57:49 +01:00
51df63d9f2 config file fix
All checks were successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 20:49:48 +01:00
cdaa5deb58 load redis and mqtt only from env
All checks were successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
2025-11-29 20:44:17 +01:00
91ef285a6c fix cluster config
Some checks failed
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/predeploy Pipeline failed
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
2025-11-29 20:29:00 +01:00
9afa68a111 deployment 2
All checks were successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 20:22:40 +01:00
1119bb529f deployment
Some checks failed
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/predeploy Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline failed
ci/woodpecker/tag/deploy/1 Pipeline failed
ci/woodpecker/tag/deploy/2 Pipeline failed
ci/woodpecker/tag/deploy/3 Pipeline failed
2025-11-29 20:19:45 +01:00
26286ce194 ci debug 4
All checks were successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 19:56:31 +01:00
7913a0044d ci debug 3
Some checks failed
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/predeploy Pipeline failed
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline was successful
2025-11-29 19:39:26 +01:00
871d0dc890 ci debug 2
Some checks failed
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/tag/deploy/1 unknown status
ci/woodpecker/tag/deploy/2 unknown status
ci/woodpecker/tag/deploy/3 unknown status
ci/woodpecker/tag/deploy/4 unknown status
ci/woodpecker/tag/build/1 Pipeline failed
ci/woodpecker/tag/build/2 Pipeline failed
ci/woodpecker/tag/build/3 Pipeline failed
ci/woodpecker/tag/predeploy Pipeline failed
ci/woodpecker/tag/build/4 Pipeline failed
2025-11-29 19:38:00 +01:00
7409995780 ci debug
Some checks failed
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/deploy/1 unknown status
ci/woodpecker/push/deploy/2 unknown status
ci/woodpecker/push/deploy/4 unknown status
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/deploy/3 unknown status
ci/woodpecker/push/build/2 Pipeline failed
2025-11-29 19:37:12 +01:00
9d4f3ac560 cd 6
Some checks failed
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/push/deploy/1 Pipeline was successful
ci/woodpecker/push/deploy/2 Pipeline was successful
ci/woodpecker/push/deploy/3 Pipeline was successful
ci/woodpecker/push/deploy/4 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline is running
ci/woodpecker/tag/build/2 Pipeline is running
ci/woodpecker/tag/build/4 Pipeline is running
ci/woodpecker/tag/build/3 Pipeline is running
ci/woodpecker/tag/predeploy Pipeline is running
ci/woodpecker/tag/deploy/2 Pipeline was successful
ci/woodpecker/tag/deploy/1 Pipeline was successful
ci/woodpecker/tag/deploy/3 Pipeline was successful
ci/woodpecker/tag/deploy/4 Pipeline failed
2025-11-29 00:08:25 +01:00
bbbd01fbac cd 5
All checks were successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
ci/woodpecker/tag/build/1 Pipeline was successful
ci/woodpecker/tag/predeploy Pipeline was successful
ci/woodpecker/tag/build/4 Pipeline was successful
ci/woodpecker/tag/build/3 Pipeline was successful
ci/woodpecker/tag/build/2 Pipeline was successful
2025-11-29 00:06:13 +01:00
61134f8bfa cd 4 2025-11-29 00:04:26 +01:00
b12bbc1eb0 cd 3 2025-11-29 00:01:49 +01:00
8425dda177 cd 2 2025-11-28 23:59:32 +01:00
eddcd20d19 cd 2025-11-28 23:58:07 +01:00
28bbff16aa ci 5
All checks were successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
2025-11-28 11:11:52 +01:00
02fe11754c ci 4
All checks were successful
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/4 Pipeline was successful
ci/woodpecker/push/build/1 Pipeline was successful
ci/woodpecker/push/build/2 Pipeline was successful
ci/woodpecker/push/build/3 Pipeline was successful
2025-11-28 11:10:23 +01:00
59b2c566ad one line
Some checks failed
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
2025-11-28 11:04:39 +01:00
42d7aae10c ci 3
Some checks failed
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/2 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/build/3 Pipeline failed
2025-11-28 09:57:40 +01:00
83ab36884b ci 2
Some checks failed
ci/woodpecker/push/predeploy Pipeline was successful
ci/woodpecker/push/build/3 Pipeline failed
ci/woodpecker/push/build/4 Pipeline failed
ci/woodpecker/push/build/1 Pipeline failed
ci/woodpecker/push/build/2 Pipeline failed
2025-11-28 09:48:17 +01:00
4d6e1a9ffe ci 2025-11-28 09:46:43 +01:00
29 changed files with 512 additions and 3141 deletions

2
.gitignore vendored
View File

@@ -64,3 +64,5 @@ poetry.lock
apps/homekit/homekit.state apps/homekit/homekit.state
tools/ca/
tools/clients/

View File

@@ -1,49 +0,0 @@
matrix:
APP:
- ui
- api
- abstraction
- rules
env:
NAMESPACE: "homea2"
steps:
build:
image: plugins/kaniko
settings:
repo: ${FORGE_NAME}/${CI_REPO}/${APP}
registry:
from_secret: container_registry
auto_tag: true
username:
from_secret: container_registry_username
password:
from_secret: container_registry_password
dockerfile: apps/${APP}/Dockerfile
when:
event: [push, tag]
ref:
exclude:
- refs/tags/*-configchange
create_namespace:
image: quay.io/wollud1969/k8s-admin-helper:0.3.4
environment:
KUBE_CONFIG_CONTENT:
from_secret: kube_config
commands:
- kubectl create namespace ${NAMESPACE} || echo "Namespace ${NAMESPACE} already exists"
when:
- event: [tag]
configuration:
image: quay.io/wollud1969/k8s-admin-helper:0.3.4
environment:
KUBE_CONFIG_CONTENT:
from_secret: kube_config
commands:
when:
- event: [tag]

View File

@@ -6,38 +6,20 @@ matrix:
- rules - rules
steps: steps:
show: build-${APP}:
image: quay.io/wollud1969/networktools:latest
environment:
forge_name:
from_secret: forge_name
container_registry:
from_secret: container_registry
container_registry_username:
from_secret: container_registry_username
container_registry_password:
from_secret: container_registry_password
commands:
- echo $${forge_name} | base64
- echo $${container_registry} | base64
- echo $${container_registry_username} | base64
- echo $${container_registry_password} | base64
build:
image: plugins/kaniko image: plugins/kaniko
settings: settings:
registry:
from_secret: local_registry
username:
from_secret: local_username
password:
from_secret: local_password
repo: ${FORGE_NAME}/${CI_REPO}/${APP} repo: ${FORGE_NAME}/${CI_REPO}/${APP}
auto_tag: true auto_tag: true
dockerfile: apps/${APP}/Dockerfile dockerfile: apps/${APP}/Dockerfile
username:
from_secret: docker_hub_username
password:
from_secret: docker_hub_password
when: when:
event: [push, tag] event: [tag]
ref: ref:
exclude: exclude:
- refs/tags/*-configchange - refs/tags/*-configchange

29
.woodpecker/deploy.yml Normal file
View File

@@ -0,0 +1,29 @@
matrix:
APP:
- ui
- api
- abstraction
- rules
steps:
deploy-${APP}:
image: quay.io/wollud1969/k8s-admin-helper:0.3.4
environment:
KUBE_CONFIG_CONTENT:
from_secret: kube_config
NAMESPACE: "homea2"
IMAGE: "${FORGE_NAME}/${CI_REPO}/${APP}:${CI_COMMIT_TAG}"
commands:
- printf "$KUBE_CONFIG_CONTENT" > /tmp/kubeconfig
- export KUBECONFIG=/tmp/kubeconfig
- echo "Deploying application ${APP} ($IMAGE) to namespace $NAMESPACE"
- cat deployment/${APP}-deployment.yaml | sed "s,%IMAGE%,$IMAGE,g" | kubectl apply -n $NAMESPACE -f -
when:
event: [tag]
ref:
exclude:
- refs/tags/*-configchange
depends_on:
- build
- predeploy

View File

@@ -25,13 +25,14 @@ steps:
- printf "$KUBE_CONFIG_CONTENT" > /tmp/kubeconfig - printf "$KUBE_CONFIG_CONTENT" > /tmp/kubeconfig
- export KUBECONFIG=/tmp/kubeconfig - export KUBECONFIG=/tmp/kubeconfig
- kubectl create configmap home-automation-config - kubectl create configmap home-automation-config
--from-file=devices=config/devices.yaml --from-file=devices.yaml=config/devices.yaml
--from-file=groups=config/groups.yaml --from-file=groups.yaml=config/groups.yaml
--from-file=layout=config/layout.yaml --from-file=layout.yaml=config/layout.yaml
--from-file=rules=config/rules.yaml --from-file=rules.yaml=config/rules.yaml
--from-file=scenes=config/scenes.yaml --from-file=scenes.yaml=config/scenes.yaml
--namespace=$NAMESPACE --namespace=$NAMESPACE
--dry-run=client -o yaml | kubectl apply -f - --dry-run=client -o yaml | kubectl apply -f -
- kubectl apply -f deployment/configmap.yaml -n $NAMESPACE
when: when:
event: [tag] event: [tag]

View File

@@ -391,9 +391,19 @@ async def async_main() -> None:
validate_devices(devices) validate_devices(devices)
logger.info(f"Loaded {len(devices)} device(s) from configuration") logger.info(f"Loaded {len(devices)} device(s) from configuration")
# Get Redis URL from config or environment variable or use default # Build Redis URL from environment variables or config or use default
redis_host = os.environ.get("REDIS_HOST")
redis_port = os.environ.get("REDIS_PORT")
redis_db = os.environ.get("REDIS_DB")
if redis_host and redis_port and redis_db:
redis_url = f"redis://{redis_host}:{redis_port}/{redis_db}"
logger.info(f"Using Redis from environment variables: {redis_url}")
else:
# Fallback to config file
redis_config = config.get("redis", {}) redis_config = config.get("redis", {})
redis_url = redis_config.get("url") or os.environ.get("REDIS_URL", "redis://localhost:6379/0") redis_url = redis_config.get("url") or "redis://localhost:6379/0"
logger.info(f"Using Redis from config file: {redis_url}")
# Connect to Redis with retry # Connect to Redis with retry
redis_client = await get_redis_client(redis_url) redis_client = await get_redis_client(redis_url)

View File

@@ -67,6 +67,7 @@ app.add_middleware(
"http://localhost:8002", "http://localhost:8002",
"http://172.19.1.11:8002", "http://172.19.1.11:8002",
"http://127.0.0.1:8002", "http://127.0.0.1:8002",
"https://homea2.hottis.de"
], ],
allow_credentials=True, allow_credentials=True,
allow_methods=["*"], allow_methods=["*"],

View File

@@ -464,3 +464,4 @@
</script> </script>
</body> </body>
</html> </html>

View File

@@ -1,14 +1,4 @@
version: 1 version: 1
mqtt:
broker: "172.16.2.16"
port: 1883
client_id: "home-automation-abstraction"
username: null
password: null
keepalive: 60
redis:
url: "redis://172.23.1.116:6379/8"
channel: "ui:updates"
devices: devices:
- device_id: lampe_semeniere_wohnzimmer - device_id: lampe_semeniere_wohnzimmer
name: Semeniere name: Semeniere

View File

@@ -1,25 +0,0 @@
abstraction | 2025-11-18 12:04:42,875 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/42/1/SET_TEMPERATURE: 21
abstraction | 2025-11-18 12:04:42,914 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/45/1/SET_TEMPERATURE: 15
abstraction | 2025-11-18 12:04:42,950 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/46/1/SET_TEMPERATURE: 15
abstraction | 2025-11-18 12:04:42,987 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/39/1/SET_TEMPERATURE: 22
abstraction | 2025-11-18 12:04:43,029 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/41/1/SET_TEMPERATURE: 20
abstraction | 2025-11-18 12:04:43,071 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/48/1/SET_TEMPERATURE: 21
abstraction | 2025-11-18 12:04:43,108 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/52/1/STATE: false
abstraction | 2025-11-18 12:04:43,145 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/26/1/STATE: false
abstraction | 2025-11-18 12:04:43,182 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/27/1/STATE: false
abstraction | 2025-11-18 12:04:43,219 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/28/1/STATE: false
abstraction | 2025-11-18 12:04:43,256 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/29/1/STATE: false
abstraction | 2025-11-18 12:04:43,292 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/18/1/STATE: false
abstraction | 2025-11-18 12:04:43,331 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/22/1/STATE: false
abstraction | 2025-11-18 12:04:43,368 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/44/1/STATE: false
abstraction | 2025-11-18 12:04:48,498 - __main__ - DEBUG - MQTT message received on shellies/schrankesszimmer/relay/0: off
abstraction | 2025-11-18 12:04:52,989 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":55.04,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,024 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,061 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.4,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:05:03,058 - __main__ - DEBUG - MQTT message received on shellies/lichtterasse/relay/0: off
abstraction | 2025-11-18 12:05:08,209 - __main__ - DEBUG - MQTT message received on shellies/wohnzimmer-regal/relay/0: off
abstraction | 2025-11-18 12:05:10,881 - __main__ - DEBUG - MQTT message received on shellies/LightKitchenSink/relay/0: on
abstraction | 2025-11-18 12:05:12,622 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,656 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,690 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.7,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:18,507 - __main__ - DEBUG - MQTT message received on shellies/schrankesszimmer/relay/0: off

View File

@@ -1,261 +0,0 @@
abstraction | 2025-11-18 12:04:40,901 - asyncio - DEBUG - Using selector: EpollSelector
abstraction | 2025-11-18 12:04:40,952 - __main__ - INFO - Loaded configuration from /app/config/devices.yaml
abstraction | 2025-11-18 12:04:40,953 - __main__ - INFO - Loaded 64 device(s): lampe_semeniere_wohnzimmer, stehlampe_esszimmer_spiegel, stehlampe_esszimmer_schrank, grosse_lampe_wohnzimmer, lampe_naehtischchen_wohnzimmer, kleine_lampe_rechts_esszimmer, kleine_lampe_links_esszimmer, leselampe_esszimmer, medusalampe_schlafzimmer, sportlicht_am_fernseher_studierzimmer, deckenlampe_schlafzimmer, bettlicht_wolfgang, bettlicht_patty, schranklicht_hinten_patty, schranklicht_vorne_patty, leselampe_patty, deckenlampe_esszimmer, standlampe_esszimmer, haustuer, deckenlampe_flur_oben, kueche_deckenlampe, sportlicht_tisch, sportlicht_regal, licht_flur_oben_am_spiegel, experimentlabtest, thermostat_wolfgang, thermostat_kueche, thermostat_schlafzimmer, thermostat_esszimmer, thermostat_wohnzimmer, thermostat_patty, thermostat_bad_oben, thermostat_bad_unten, sterne_wohnzimmer, kontakt_schlafzimmer_strasse, kontakt_esszimmer_strasse_rechts, kontakt_esszimmer_strasse_links, kontakt_wohnzimmer_garten_rechts, kontakt_wohnzimmer_garten_links, kontakt_kueche_garten_fenster, kontakt_kueche_garten_tuer, kontakt_kueche_strasse_rechts, kontakt_kueche_strasse_links, kontakt_patty_garten_rechts, kontakt_patty_garten_links, kontakt_patty_strasse, kontakt_wolfgang_garten, kontakt_bad_oben_strasse, kontakt_bad_unten_strasse, sensor_schlafzimmer, sensor_wohnzimmer, sensor_kueche, sensor_arbeitszimmer_patty, sensor_arbeitszimmer_wolfgang, sensor_bad_oben, sensor_bad_unten, sensor_flur, sensor_waschkueche, sensor_sportzimmer, licht_spuele_kueche, licht_schrank_esszimmer, licht_regal_wohnzimmer, licht_flur_schrank, licht_terasse
abstraction | 2025-11-18 12:04:40,953 - __main__ - INFO - Loaded 64 device(s) from configuration
abstraction | 2025-11-18 12:04:41,003 - __main__ - INFO - Connected to Redis: redis://172.23.1.116:6379/8
abstraction | 2025-11-18 12:04:41,003 - __main__ - INFO - Abstraction worker started
abstraction | 2025-11-18 12:04:41,003 - __main__ - INFO - Connecting to MQTT broker: 172.23.1.102:1883
abstraction | 2025-11-18 12:04:41,053 - __main__ - INFO - Connected to MQTT broker as home-automation-abstraction-b39304
abstraction | 2025-11-18 12:04:41,072 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_semeniere_wohnzimmer/set
abstraction | 2025-11-18 12:04:41,091 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8000015480b
abstraction | 2025-11-18 12:04:41,107 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_spiegel/set
abstraction | 2025-11-18 12:04:41,125 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d06ea09
abstraction | 2025-11-18 12:04:41,141 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_schrank/set
abstraction | 2025-11-18 12:04:41,159 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d09176c
abstraction | 2025-11-18 12:04:41,176 - __main__ - INFO - Subscribed to abstract SET: home/relay/grosse_lampe_wohnzimmer/set
abstraction | 2025-11-18 12:04:41,192 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000151aca
abstraction | 2025-11-18 12:04:41,209 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_naehtischchen_wohnzimmer/set
abstraction | 2025-11-18 12:04:41,225 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffee560ee
abstraction | 2025-11-18 12:04:41,242 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_rechts_esszimmer/set
abstraction | 2025-11-18 12:04:41,259 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000156645
abstraction | 2025-11-18 12:04:41,276 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_links_esszimmer/set
abstraction | 2025-11-18 12:04:41,293 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000153099
abstraction | 2025-11-18 12:04:41,310 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_esszimmer/set
abstraction | 2025-11-18 12:04:41,327 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffe7b84f2
abstraction | 2025-11-18 12:04:41,344 - __main__ - INFO - Subscribed to abstract SET: home/relay/medusalampe_schlafzimmer/set
abstraction | 2025-11-18 12:04:41,361 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154c7c
abstraction | 2025-11-18 12:04:41,378 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_am_fernseher_studierzimmer/set
abstraction | 2025-11-18 12:04:41,395 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffe76a23a
abstraction | 2025-11-18 12:04:41,415 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_schlafzimmer/set
abstraction | 2025-11-18 12:04:41,432 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a406a7
abstraction | 2025-11-18 12:04:41,449 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_wolfgang/set
abstraction | 2025-11-18 12:04:41,466 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00178801081570bf
abstraction | 2025-11-18 12:04:41,484 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_patty/set
abstraction | 2025-11-18 12:04:41,500 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108158b32
abstraction | 2025-11-18 12:04:41,518 - __main__ - INFO - Subscribed to abstract SET: home/light/schranklicht_hinten_patty/set
abstraction | 2025-11-18 12:04:41,535 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880106e29571
abstraction | 2025-11-18 12:04:41,552 - __main__ - INFO - Subscribed to abstract SET: home/relay/schranklicht_vorne_patty/set
abstraction | 2025-11-18 12:04:41,569 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154cf5
abstraction | 2025-11-18 12:04:41,586 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_patty/set
abstraction | 2025-11-18 12:04:41,603 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010600ec9d
abstraction | 2025-11-18 12:04:41,620 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_esszimmer/set
abstraction | 2025-11-18 12:04:41,637 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a03e45
abstraction | 2025-11-18 12:04:41,655 - __main__ - INFO - Subscribed to abstract SET: home/light/standlampe_esszimmer/set
abstraction | 2025-11-18 12:04:41,674 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xbc33acfffe21f547
abstraction | 2025-11-18 12:04:41,692 - __main__ - INFO - Subscribed to abstract SET: home/light/haustuer/set
abstraction | 2025-11-18 12:04:41,711 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffea6a3da
abstraction | 2025-11-18 12:04:41,728 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_flur_oben/set
abstraction | 2025-11-18 12:04:41,746 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2123a7
abstraction | 2025-11-18 12:04:41,764 - __main__ - INFO - Subscribed to abstract SET: home/light/kueche_deckenlampe/set
abstraction | 2025-11-18 12:04:41,781 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2c40c4
abstraction | 2025-11-18 12:04:41,798 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_tisch/set
abstraction | 2025-11-18 12:04:41,814 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f31b
abstraction | 2025-11-18 12:04:41,831 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_regal/set
abstraction | 2025-11-18 12:04:41,848 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f569
abstraction | 2025-11-18 12:04:41,865 - __main__ - INFO - Subscribed to abstract SET: home/light/licht_flur_oben_am_spiegel/set
abstraction | 2025-11-18 12:04:41,883 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffefe4ba4
abstraction | 2025-11-18 12:04:41,899 - __main__ - INFO - Subscribed to abstract SET: home/light/experimentlabtest/set
abstraction | 2025-11-18 12:04:41,918 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000195038
abstraction | 2025-11-18 12:04:41,936 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wolfgang/set
abstraction | 2025-11-18 12:04:41,955 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x540f57fffe7e3cfe
abstraction | 2025-11-18 12:04:41,974 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_kueche/set
abstraction | 2025-11-18 12:04:41,991 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x94deb8fffe2e5c06
abstraction | 2025-11-18 12:04:42,008 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_schlafzimmer/set
abstraction | 2025-11-18 12:04:42,025 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/42/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,042 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_esszimmer/set
abstraction | 2025-11-18 12:04:42,059 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/45/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,080 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wohnzimmer/set
abstraction | 2025-11-18 12:04:42,097 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/46/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,114 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_patty/set
abstraction | 2025-11-18 12:04:42,131 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/39/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,150 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_oben/set
abstraction | 2025-11-18 12:04:42,171 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/41/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,189 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_unten/set
abstraction | 2025-11-18 12:04:42,207 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/48/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,224 - __main__ - INFO - Subscribed to abstract SET: home/relay/sterne_wohnzimmer/set
abstraction | 2025-11-18 12:04:42,240 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000155fc2
abstraction | 2025-11-18 12:04:42,240 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_schlafzimmer_strasse
abstraction | 2025-11-18 12:04:42,258 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/52/1/STATE
abstraction | 2025-11-18 12:04:42,258 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_rechts
abstraction | 2025-11-18 12:04:42,275 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/26/1/STATE
abstraction | 2025-11-18 12:04:42,275 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_links
abstraction | 2025-11-18 12:04:42,293 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/27/1/STATE
abstraction | 2025-11-18 12:04:42,293 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_rechts
abstraction | 2025-11-18 12:04:42,313 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/28/1/STATE
abstraction | 2025-11-18 12:04:42,313 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_links
abstraction | 2025-11-18 12:04:42,331 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/29/1/STATE
abstraction | 2025-11-18 12:04:42,331 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_fenster
abstraction | 2025-11-18 12:04:42,351 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332785
abstraction | 2025-11-18 12:04:42,351 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_tuer
abstraction | 2025-11-18 12:04:42,371 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332788
abstraction | 2025-11-18 12:04:42,371 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_rechts
abstraction | 2025-11-18 12:04:42,390 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b151803
abstraction | 2025-11-18 12:04:42,390 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_links
abstraction | 2025-11-18 12:04:42,408 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b331d0b
abstraction | 2025-11-18 12:04:42,408 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_rechts
abstraction | 2025-11-18 12:04:42,424 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/18/1/STATE
abstraction | 2025-11-18 12:04:42,424 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_links
abstraction | 2025-11-18 12:04:42,441 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/22/1/STATE
abstraction | 2025-11-18 12:04:42,441 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_strasse
abstraction | 2025-11-18 12:04:42,462 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000af457cf
abstraction | 2025-11-18 12:04:42,462 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wolfgang_garten
abstraction | 2025-11-18 12:04:42,479 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b3328da
abstraction | 2025-11-18 12:04:42,480 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_oben_strasse
abstraction | 2025-11-18 12:04:42,496 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b333aec
abstraction | 2025-11-18 12:04:42,496 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_unten_strasse
abstraction | 2025-11-18 12:04:42,513 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/44/1/STATE
abstraction | 2025-11-18 12:04:42,513 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_schlafzimmer
abstraction | 2025-11-18 12:04:42,532 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00043292dc
abstraction | 2025-11-18 12:04:42,532 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_wohnzimmer
abstraction | 2025-11-18 12:04:42,552 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0008975707
abstraction | 2025-11-18 12:04:42,552 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_kueche
abstraction | 2025-11-18 12:04:42,571 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00083299bb
abstraction | 2025-11-18 12:04:42,571 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_patty
abstraction | 2025-11-18 12:04:42,589 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0003f052b7
abstraction | 2025-11-18 12:04:42,589 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_wolfgang
abstraction | 2025-11-18 12:04:42,608 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000543fb99
abstraction | 2025-11-18 12:04:42,608 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_oben
abstraction | 2025-11-18 12:04:42,625 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e8987
abstraction | 2025-11-18 12:04:42,625 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_unten
abstraction | 2025-11-18 12:04:42,645 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e662a
abstraction | 2025-11-18 12:04:42,645 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_flur
abstraction | 2025-11-18 12:04:42,664 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000836ccc6
abstraction | 2025-11-18 12:04:42,664 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_waschkueche
abstraction | 2025-11-18 12:04:42,682 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000449f3bc
abstraction | 2025-11-18 12:04:42,682 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_sportzimmer
abstraction | 2025-11-18 12:04:42,699 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0009421422
abstraction | 2025-11-18 12:04:42,716 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_spuele_kueche/set
abstraction | 2025-11-18 12:04:42,734 - __main__ - INFO - Subscribed to vendor STATE: shellies/LightKitchenSink/relay/0
abstraction | 2025-11-18 12:04:42,751 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_schrank_esszimmer/set
abstraction | 2025-11-18 12:04:42,770 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankesszimmer/relay/0
abstraction | 2025-11-18 12:04:42,790 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_regal_wohnzimmer/set
abstraction | 2025-11-18 12:04:42,807 - __main__ - INFO - Subscribed to vendor STATE: shellies/wohnzimmer-regal/relay/0
abstraction | 2025-11-18 12:04:42,823 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_flur_schrank/set
abstraction | 2025-11-18 12:04:42,841 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankflur/relay/0
abstraction | 2025-11-18 12:04:42,858 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_terasse/set
abstraction | 2025-11-18 12:04:42,875 - __main__ - INFO - Subscribed to vendor STATE: shellies/lichtterasse/relay/0
abstraction | 2025-11-18 12:04:42,875 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/42/1/SET_TEMPERATURE: 21
abstraction | 2025-11-18 12:04:42,875 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=21
abstraction | 2025-11-18 12:04:42,876 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 21.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,876 - __main__ - INFO - ← abstract STATE thermostat_schlafzimmer: home/thermostat/thermostat_schlafzimmer/state → {"target": 21.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:42,897 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_schlafzimmer", "payload": {"target": 21.0, "mode": "heat"}, "ts": "2025-11-18T12:04:42.897310+00:00"}
abstraction | 2025-11-18 12:04:42,914 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/45/1/SET_TEMPERATURE: 15
abstraction | 2025-11-18 12:04:42,914 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 12:04:42,914 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,914 - __main__ - INFO - ← abstract STATE thermostat_esszimmer: home/thermostat/thermostat_esszimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:42,934 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_esszimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T12:04:42.934255+00:00"}
abstraction | 2025-11-18 12:04:42,950 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/46/1/SET_TEMPERATURE: 15
abstraction | 2025-11-18 12:04:42,950 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 12:04:42,950 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,951 - __main__ - INFO - ← abstract STATE thermostat_wohnzimmer: home/thermostat/thermostat_wohnzimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:42,970 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_wohnzimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T12:04:42.970936+00:00"}
abstraction | 2025-11-18 12:04:42,987 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/39/1/SET_TEMPERATURE: 22
abstraction | 2025-11-18 12:04:42,988 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=22
abstraction | 2025-11-18 12:04:42,988 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 22.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,988 - __main__ - INFO - ← abstract STATE thermostat_patty: home/thermostat/thermostat_patty/state → {"target": 22.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:43,009 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_patty", "payload": {"target": 22.0, "mode": "heat"}, "ts": "2025-11-18T12:04:43.009673+00:00"}
abstraction | 2025-11-18 12:04:43,029 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/41/1/SET_TEMPERATURE: 20
abstraction | 2025-11-18 12:04:43,029 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=20
abstraction | 2025-11-18 12:04:43,029 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 20.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:43,029 - __main__ - INFO - ← abstract STATE thermostat_bad_oben: home/thermostat/thermostat_bad_oben/state → {"target": 20.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:43,053 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_oben", "payload": {"target": 20.0, "mode": "heat"}, "ts": "2025-11-18T12:04:43.053895+00:00"}
abstraction | 2025-11-18 12:04:43,071 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/48/1/SET_TEMPERATURE: 21
abstraction | 2025-11-18 12:04:43,071 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=21
abstraction | 2025-11-18 12:04:43,071 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 21.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:43,072 - __main__ - INFO - ← abstract STATE thermostat_bad_unten: home/thermostat/thermostat_bad_unten/state → {"target": 21.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:43,092 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_unten", "payload": {"target": 21.0, "mode": "heat"}, "ts": "2025-11-18T12:04:43.092210+00:00"}
abstraction | 2025-11-18 12:04:43,108 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/52/1/STATE: false
abstraction | 2025-11-18 12:04:43,108 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,108 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,109 - __main__ - INFO - ← abstract STATE kontakt_schlafzimmer_strasse: home/contact/kontakt_schlafzimmer_strasse/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,128 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_schlafzimmer_strasse", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.128506+00:00"}
abstraction | 2025-11-18 12:04:43,145 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/26/1/STATE: false
abstraction | 2025-11-18 12:04:43,145 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,145 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,146 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_rechts: home/contact/kontakt_esszimmer_strasse_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,165 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.165958+00:00"}
abstraction | 2025-11-18 12:04:43,182 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/27/1/STATE: false
abstraction | 2025-11-18 12:04:43,182 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,183 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,183 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_links: home/contact/kontakt_esszimmer_strasse_links/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,202 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.202580+00:00"}
abstraction | 2025-11-18 12:04:43,219 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/28/1/STATE: false
abstraction | 2025-11-18 12:04:43,219 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,219 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,220 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_rechts: home/contact/kontakt_wohnzimmer_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,239 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.239653+00:00"}
abstraction | 2025-11-18 12:04:43,256 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/29/1/STATE: false
abstraction | 2025-11-18 12:04:43,256 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,256 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,257 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_links: home/contact/kontakt_wohnzimmer_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,275 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.275832+00:00"}
abstraction | 2025-11-18 12:04:43,292 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/18/1/STATE: false
abstraction | 2025-11-18 12:04:43,292 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,292 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,293 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_rechts: home/contact/kontakt_patty_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,314 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.314579+00:00"}
abstraction | 2025-11-18 12:04:43,331 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/22/1/STATE: false
abstraction | 2025-11-18 12:04:43,331 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,331 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,332 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_links: home/contact/kontakt_patty_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,351 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.351704+00:00"}
abstraction | 2025-11-18 12:04:43,368 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/44/1/STATE: false
abstraction | 2025-11-18 12:04:43,368 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,368 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,369 - __main__ - INFO - ← abstract STATE kontakt_bad_unten_strasse: home/contact/kontakt_bad_unten_strasse/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,388 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_bad_unten_strasse", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.388390+00:00"}
abstraction | 2025-11-18 12:04:48,498 - __main__ - DEBUG - MQTT message received on shellies/schrankesszimmer/relay/0: off
abstraction | 2025-11-18 12:04:48,498 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:04:48,498 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:04:48,498 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 12:04:48,518 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T12:04:48.518525+00:00"}
abstraction | 2025-11-18 12:04:52,989 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":55.04,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:52,989 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":100,"humidity":55.04,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:52,989 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 55.04, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1002.6, 'temperature': 22.13, 'voltage': 3015}
abstraction | 2025-11-18 12:04:52,989 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 55.04, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}
abstraction | 2025-11-18 12:04:53,009 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 55.04, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}, "ts": "2025-11-18T12:04:53.009776+00:00"}
abstraction | 2025-11-18 12:04:53,024 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,025 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,025 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.82, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1002.6, 'temperature': 22.13, 'voltage': 3015}
abstraction | 2025-11-18 12:04:53,025 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}
abstraction | 2025-11-18 12:04:53,044 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}, "ts": "2025-11-18T12:04:53.044379+00:00"}
abstraction | 2025-11-18 12:04:53,061 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.4,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,061 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.4,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,061 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.82, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1002.4, 'temperature': 22.13, 'voltage': 3015}
abstraction | 2025-11-18 12:04:53,061 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.4, "temperature": 22.13, "voltage": 3015}
abstraction | 2025-11-18 12:04:53,084 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.4, "temperature": 22.13, "voltage": 3015}, "ts": "2025-11-18T12:04:53.083988+00:00"}
abstraction | 2025-11-18 12:05:03,058 - __main__ - DEBUG - MQTT message received on shellies/lichtterasse/relay/0: off
abstraction | 2025-11-18 12:05:03,058 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:05:03,058 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:05:03,058 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 12:05:03,075 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T12:05:03.075262+00:00"}
abstraction | 2025-11-18 12:05:08,209 - __main__ - DEBUG - MQTT message received on shellies/wohnzimmer-regal/relay/0: off
abstraction | 2025-11-18 12:05:08,210 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:05:08,210 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:05:08,210 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 12:05:08,228 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T12:05:08.228758+00:00"}
abstraction | 2025-11-18 12:05:10,881 - __main__ - DEBUG - MQTT message received on shellies/LightKitchenSink/relay/0: on
abstraction | 2025-11-18 12:05:10,881 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 12:05:10,881 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 12:05:10,881 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 12:05:10,899 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T12:05:10.899207+00:00"}
abstraction | 2025-11-18 12:05:12,622 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,622 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,622 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 63, 'humidity': 47.69, 'linkquality': 87, 'power_outage_count': 4906, 'pressure': 1009.9, 'temperature': 19.74, 'voltage': 2945}
abstraction | 2025-11-18 12:05:12,622 - __main__ - INFO - ← abstract STATE sensor_kueche: home/temp_humidity/sensor_kueche/state → {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}
abstraction | 2025-11-18 12:05:12,640 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_kueche", "payload": {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}, "ts": "2025-11-18T12:05:12.640129+00:00"}
abstraction | 2025-11-18 12:05:12,656 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,656 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,656 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 63, 'humidity': 47.69, 'linkquality': 87, 'power_outage_count': 4906, 'pressure': 1009.9, 'temperature': 19.74, 'voltage': 2945}
abstraction | 2025-11-18 12:05:12,657 - __main__ - INFO - ← abstract STATE sensor_kueche: home/temp_humidity/sensor_kueche/state → {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}
abstraction | 2025-11-18 12:05:12,674 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_kueche", "payload": {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}, "ts": "2025-11-18T12:05:12.674372+00:00"}
abstraction | 2025-11-18 12:05:12,690 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.7,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,690 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.7,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,690 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 63, 'humidity': 47.69, 'linkquality': 87, 'power_outage_count': 4906, 'pressure': 1009.7, 'temperature': 19.74, 'voltage': 2945}
abstraction | 2025-11-18 12:05:12,690 - __main__ - INFO - ← abstract STATE sensor_kueche: home/temp_humidity/sensor_kueche/state → {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.7, "temperature": 19.74, "voltage": 2945}
abstraction | 2025-11-18 12:05:12,708 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_kueche", "payload": {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.7, "temperature": 19.74, "voltage": 2945}, "ts": "2025-11-18T12:05:12.708715+00:00"}
abstraction | 2025-11-18 12:05:18,507 - __main__ - DEBUG - MQTT message received on shellies/schrankesszimmer/relay/0: off
abstraction | 2025-11-18 12:05:18,508 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:05:18,508 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:05:18,508 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 12:05:18,526 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T12:05:18.525971+00:00"}

View File

@@ -1,311 +0,0 @@
rules | 2025-11-18 12:04:40,835 - asyncio - DEBUG - Using selector: EpollSelector
rules | 2025-11-18 12:04:40,835 - __main__ - INFO - ============================================================
rules | 2025-11-18 12:04:40,835 - __main__ - INFO - Rules Engine Starting
rules | 2025-11-18 12:04:40,835 - __main__ - INFO - ============================================================
rules | 2025-11-18 12:04:40,835 - __main__ - INFO - Config: /app/config/rules.yaml
rules | 2025-11-18 12:04:40,835 - __main__ - INFO - MQTT: 172.23.1.102:1883
rules | 2025-11-18 12:04:40,835 - __main__ - INFO - Redis: redis://172.23.1.116:6379/8
rules | 2025-11-18 12:04:40,836 - __main__ - INFO - ============================================================
rules | 2025-11-18 12:04:40,836 - __main__ - INFO - Loading rules configuration from /app/config/rules.yaml
rules | 2025-11-18 12:04:40,841 - __main__ - INFO - Loaded 6 rule(s) from configuration
rules | 2025-11-18 12:04:40,841 - __main__ - INFO - - window_setback_esszimmer (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 12:04:40,842 - __main__ - INFO - - window_setback_kueche (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 12:04:40,842 - __main__ - INFO - - window_setback_patty (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 12:04:40,842 - __main__ - INFO - - window_setback_schlafzimmer (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 12:04:40,842 - __main__ - INFO - - window_setback_wohnzimmer (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 12:04:40,846 - __main__ - INFO - - window_setback_wolfgang (type: window_setback@1.0)
rules | 2025-11-18 12:04:40,846 - __main__ - INFO - Successfully loaded 1 rule implementation(s) (5 disabled)
rules | 2025-11-18 12:04:40,846 - __main__ - INFO - Rule window_setback_wolfgang validated: 1 contacts, 1 thermostats
rules | 2025-11-18 12:04:40,846 - __main__ - DEBUG - Rule window_setback_wolfgang subscribes to 2 topic(s)
rules | 2025-11-18 12:04:40,847 - __main__ - INFO - Total MQTT subscriptions needed: 2
rules | 2025-11-18 12:04:40,847 - __main__ - INFO - Starting event processing loop
abstraction | 2025-11-18 12:04:40,901 - asyncio - DEBUG - Using selector: EpollSelector
abstraction | 2025-11-18 12:04:40,952 - __main__ - INFO - Loaded configuration from /app/config/devices.yaml
abstraction | 2025-11-18 12:04:40,953 - __main__ - INFO - Loaded 64 device(s): lampe_semeniere_wohnzimmer, stehlampe_esszimmer_spiegel, stehlampe_esszimmer_schrank, grosse_lampe_wohnzimmer, lampe_naehtischchen_wohnzimmer, kleine_lampe_rechts_esszimmer, kleine_lampe_links_esszimmer, leselampe_esszimmer, medusalampe_schlafzimmer, sportlicht_am_fernseher_studierzimmer, deckenlampe_schlafzimmer, bettlicht_wolfgang, bettlicht_patty, schranklicht_hinten_patty, schranklicht_vorne_patty, leselampe_patty, deckenlampe_esszimmer, standlampe_esszimmer, haustuer, deckenlampe_flur_oben, kueche_deckenlampe, sportlicht_tisch, sportlicht_regal, licht_flur_oben_am_spiegel, experimentlabtest, thermostat_wolfgang, thermostat_kueche, thermostat_schlafzimmer, thermostat_esszimmer, thermostat_wohnzimmer, thermostat_patty, thermostat_bad_oben, thermostat_bad_unten, sterne_wohnzimmer, kontakt_schlafzimmer_strasse, kontakt_esszimmer_strasse_rechts, kontakt_esszimmer_strasse_links, kontakt_wohnzimmer_garten_rechts, kontakt_wohnzimmer_garten_links, kontakt_kueche_garten_fenster, kontakt_kueche_garten_tuer, kontakt_kueche_strasse_rechts, kontakt_kueche_strasse_links, kontakt_patty_garten_rechts, kontakt_patty_garten_links, kontakt_patty_strasse, kontakt_wolfgang_garten, kontakt_bad_oben_strasse, kontakt_bad_unten_strasse, sensor_schlafzimmer, sensor_wohnzimmer, sensor_kueche, sensor_arbeitszimmer_patty, sensor_arbeitszimmer_wolfgang, sensor_bad_oben, sensor_bad_unten, sensor_flur, sensor_waschkueche, sensor_sportzimmer, licht_spuele_kueche, licht_schrank_esszimmer, licht_regal_wohnzimmer, licht_flur_schrank, licht_terasse
abstraction | 2025-11-18 12:04:40,953 - __main__ - INFO - Loaded 64 device(s) from configuration
rules | 2025-11-18 12:04:40,999 - __main__ - INFO - Connecting to MQTT broker 172.23.1.102:1883 (client_id=rule_engine-0d8cce)
abstraction | 2025-11-18 12:04:41,003 - __main__ - INFO - Connected to Redis: redis://172.23.1.116:6379/8
abstraction | 2025-11-18 12:04:41,003 - __main__ - INFO - Abstraction worker started
abstraction | 2025-11-18 12:04:41,003 - __main__ - INFO - Connecting to MQTT broker: 172.23.1.102:1883
rules | 2025-11-18 12:04:41,051 - __main__ - INFO - Connected to MQTT broker 172.23.1.102:1883
abstraction | 2025-11-18 12:04:41,053 - __main__ - INFO - Connected to MQTT broker as home-automation-abstraction-b39304
abstraction | 2025-11-18 12:04:41,072 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_semeniere_wohnzimmer/set
rules | 2025-11-18 12:04:41,084 - __main__ - INFO - Subscribed to 2 topic(s): home/thermostat/thermostat_wolfgang/state, home/contact/kontakt_wolfgang_garten/state
rules | 2025-11-18 12:04:41,085 - __main__ - DEBUG - Received event: {'topic': 'home/thermostat/thermostat_wolfgang/state', 'type': 'state', 'cap': 'thermostat', 'device_id': 'thermostat_wolfgang', 'payload': {'target': 23.0, 'current': 23.5, 'mode': 'heat'}, 'ts': '2025-11-18T12:04:41.085220'}
abstraction | 2025-11-18 12:04:41,091 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8000015480b
rules | 2025-11-18 12:04:41,085 - __main__ - DEBUG - Filtering for cap=thermostat, device_id=thermostat_wolfgang
rules | 2025-11-18 12:04:41,085 - __main__ - DEBUG - Rule window_setback_wolfgang: checking thermostats ['thermostat_wolfgang']
rules | 2025-11-18 12:04:41,086 - __main__ - INFO - Event thermostat/thermostat_wolfgang: 1 matching rule(s)
abstraction | 2025-11-18 12:04:41,107 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_spiegel/set
abstraction | 2025-11-18 12:04:41,125 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d06ea09
abstraction | 2025-11-18 12:04:41,141 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_schrank/set
abstraction | 2025-11-18 12:04:41,159 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d09176c
abstraction | 2025-11-18 12:04:41,176 - __main__ - INFO - Subscribed to abstract SET: home/relay/grosse_lampe_wohnzimmer/set
abstraction | 2025-11-18 12:04:41,192 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000151aca
rules | 2025-11-18 12:04:41,197 - __main__ - DEBUG - Rule window_setback_wolfgang: Updated current target for thermostat_wolfgang: 23.0°C
rules | 2025-11-18 12:04:41,197 - __main__ - DEBUG - Received event: {'topic': 'home/contact/kontakt_wolfgang_garten/state', 'type': 'state', 'cap': 'contact', 'device_id': 'kontakt_wolfgang_garten', 'payload': {'contact': 'closed', 'battery': 100, 'linkquality': 32, 'device_temperature': 28, 'voltage': 3025}, 'ts': '2025-11-18T12:04:41.197402'}
rules | 2025-11-18 12:04:41,198 - __main__ - DEBUG - Filtering for cap=contact, device_id=kontakt_wolfgang_garten
rules | 2025-11-18 12:04:41,198 - __main__ - DEBUG - Rule window_setback_wolfgang: checking contacts ['kontakt_wolfgang_garten']
rules | 2025-11-18 12:04:41,199 - __main__ - INFO - Event contact/kontakt_wolfgang_garten: 1 matching rule(s)
abstraction | 2025-11-18 12:04:41,209 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_naehtischchen_wohnzimmer/set
abstraction | 2025-11-18 12:04:41,225 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffee560ee
rules | 2025-11-18 12:04:41,233 - __main__ - INFO - Rule window_setback_wolfgang: Window closed, restoring 1 thermostats to previous temperatures
abstraction | 2025-11-18 12:04:41,242 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_rechts_esszimmer/set
rules | 2025-11-18 12:04:41,250 - __main__ - WARNING - No previous target found for thermostat_wolfgang, cannot restore
abstraction | 2025-11-18 12:04:41,259 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000156645
abstraction | 2025-11-18 12:04:41,276 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_links_esszimmer/set
abstraction | 2025-11-18 12:04:41,293 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000153099
abstraction | 2025-11-18 12:04:41,310 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_esszimmer/set
abstraction | 2025-11-18 12:04:41,327 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffe7b84f2
abstraction | 2025-11-18 12:04:41,344 - __main__ - INFO - Subscribed to abstract SET: home/relay/medusalampe_schlafzimmer/set
abstraction | 2025-11-18 12:04:41,361 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154c7c
abstraction | 2025-11-18 12:04:41,378 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_am_fernseher_studierzimmer/set
abstraction | 2025-11-18 12:04:41,395 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffe76a23a
abstraction | 2025-11-18 12:04:41,415 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_schlafzimmer/set
abstraction | 2025-11-18 12:04:41,432 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a406a7
abstraction | 2025-11-18 12:04:41,449 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_wolfgang/set
api | INFO: Started server process [1]
api | INFO: Waiting for application startup.
abstraction | 2025-11-18 12:04:41,466 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00178801081570bf
abstraction | 2025-11-18 12:04:41,484 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_patty/set
api | INFO: Application startup complete.
abstraction | 2025-11-18 12:04:41,500 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108158b32
api | INFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
abstraction | 2025-11-18 12:04:41,518 - __main__ - INFO - Subscribed to abstract SET: home/light/schranklicht_hinten_patty/set
abstraction | 2025-11-18 12:04:41,535 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880106e29571
abstraction | 2025-11-18 12:04:41,552 - __main__ - INFO - Subscribed to abstract SET: home/relay/schranklicht_vorne_patty/set
abstraction | 2025-11-18 12:04:41,569 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154cf5
abstraction | 2025-11-18 12:04:41,586 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_patty/set
abstraction | 2025-11-18 12:04:41,603 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010600ec9d
abstraction | 2025-11-18 12:04:41,620 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_esszimmer/set
abstraction | 2025-11-18 12:04:41,637 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a03e45
abstraction | 2025-11-18 12:04:41,655 - __main__ - INFO - Subscribed to abstract SET: home/light/standlampe_esszimmer/set
ui | UI using API_BASE: http://172.19.1.11:8001
ui | UI using BASE_PATH: /
ui | INFO: Started server process [1]
ui | INFO: Waiting for application startup.
ui | INFO: Application startup complete.
abstraction | 2025-11-18 12:04:41,674 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xbc33acfffe21f547
ui | INFO: Uvicorn running on http://0.0.0.0:8002 (Press CTRL+C to quit)
abstraction | 2025-11-18 12:04:41,692 - __main__ - INFO - Subscribed to abstract SET: home/light/haustuer/set
abstraction | 2025-11-18 12:04:41,711 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffea6a3da
abstraction | 2025-11-18 12:04:41,728 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_flur_oben/set
abstraction | 2025-11-18 12:04:41,746 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2123a7
abstraction | 2025-11-18 12:04:41,764 - __main__ - INFO - Subscribed to abstract SET: home/light/kueche_deckenlampe/set
abstraction | 2025-11-18 12:04:41,781 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2c40c4
abstraction | 2025-11-18 12:04:41,798 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_tisch/set
abstraction | 2025-11-18 12:04:41,814 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f31b
abstraction | 2025-11-18 12:04:41,831 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_regal/set
abstraction | 2025-11-18 12:04:41,848 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f569
abstraction | 2025-11-18 12:04:41,865 - __main__ - INFO - Subscribed to abstract SET: home/light/licht_flur_oben_am_spiegel/set
abstraction | 2025-11-18 12:04:41,883 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffefe4ba4
abstraction | 2025-11-18 12:04:41,899 - __main__ - INFO - Subscribed to abstract SET: home/light/experimentlabtest/set
abstraction | 2025-11-18 12:04:41,918 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000195038
abstraction | 2025-11-18 12:04:41,936 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wolfgang/set
abstraction | 2025-11-18 12:04:41,955 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x540f57fffe7e3cfe
abstraction | 2025-11-18 12:04:41,974 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_kueche/set
abstraction | 2025-11-18 12:04:41,991 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x94deb8fffe2e5c06
abstraction | 2025-11-18 12:04:42,008 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_schlafzimmer/set
abstraction | 2025-11-18 12:04:42,025 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/42/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,042 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_esszimmer/set
abstraction | 2025-11-18 12:04:42,059 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/45/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,080 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wohnzimmer/set
abstraction | 2025-11-18 12:04:42,097 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/46/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,114 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_patty/set
abstraction | 2025-11-18 12:04:42,131 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/39/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,150 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_oben/set
abstraction | 2025-11-18 12:04:42,171 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/41/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,189 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_unten/set
abstraction | 2025-11-18 12:04:42,207 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/48/1/SET_TEMPERATURE
abstraction | 2025-11-18 12:04:42,224 - __main__ - INFO - Subscribed to abstract SET: home/relay/sterne_wohnzimmer/set
abstraction | 2025-11-18 12:04:42,240 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000155fc2
abstraction | 2025-11-18 12:04:42,240 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_schlafzimmer_strasse
abstraction | 2025-11-18 12:04:42,258 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/52/1/STATE
abstraction | 2025-11-18 12:04:42,258 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_rechts
abstraction | 2025-11-18 12:04:42,275 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/26/1/STATE
abstraction | 2025-11-18 12:04:42,275 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_links
abstraction | 2025-11-18 12:04:42,293 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/27/1/STATE
abstraction | 2025-11-18 12:04:42,293 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_rechts
abstraction | 2025-11-18 12:04:42,313 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/28/1/STATE
abstraction | 2025-11-18 12:04:42,313 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_links
abstraction | 2025-11-18 12:04:42,331 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/29/1/STATE
abstraction | 2025-11-18 12:04:42,331 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_fenster
abstraction | 2025-11-18 12:04:42,351 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332785
abstraction | 2025-11-18 12:04:42,351 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_tuer
abstraction | 2025-11-18 12:04:42,371 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332788
abstraction | 2025-11-18 12:04:42,371 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_rechts
abstraction | 2025-11-18 12:04:42,390 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b151803
abstraction | 2025-11-18 12:04:42,390 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_links
abstraction | 2025-11-18 12:04:42,408 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b331d0b
abstraction | 2025-11-18 12:04:42,408 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_rechts
abstraction | 2025-11-18 12:04:42,424 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/18/1/STATE
abstraction | 2025-11-18 12:04:42,424 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_links
abstraction | 2025-11-18 12:04:42,441 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/22/1/STATE
abstraction | 2025-11-18 12:04:42,441 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_strasse
abstraction | 2025-11-18 12:04:42,462 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000af457cf
abstraction | 2025-11-18 12:04:42,462 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wolfgang_garten
abstraction | 2025-11-18 12:04:42,479 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b3328da
abstraction | 2025-11-18 12:04:42,480 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_oben_strasse
abstraction | 2025-11-18 12:04:42,496 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b333aec
abstraction | 2025-11-18 12:04:42,496 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_unten_strasse
abstraction | 2025-11-18 12:04:42,513 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/44/1/STATE
abstraction | 2025-11-18 12:04:42,513 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_schlafzimmer
abstraction | 2025-11-18 12:04:42,532 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00043292dc
abstraction | 2025-11-18 12:04:42,532 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_wohnzimmer
abstraction | 2025-11-18 12:04:42,552 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0008975707
abstraction | 2025-11-18 12:04:42,552 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_kueche
abstraction | 2025-11-18 12:04:42,571 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00083299bb
abstraction | 2025-11-18 12:04:42,571 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_patty
abstraction | 2025-11-18 12:04:42,589 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0003f052b7
abstraction | 2025-11-18 12:04:42,589 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_wolfgang
abstraction | 2025-11-18 12:04:42,608 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000543fb99
abstraction | 2025-11-18 12:04:42,608 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_oben
abstraction | 2025-11-18 12:04:42,625 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e8987
abstraction | 2025-11-18 12:04:42,625 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_unten
abstraction | 2025-11-18 12:04:42,645 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e662a
abstraction | 2025-11-18 12:04:42,645 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_flur
abstraction | 2025-11-18 12:04:42,664 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000836ccc6
abstraction | 2025-11-18 12:04:42,664 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_waschkueche
abstraction | 2025-11-18 12:04:42,682 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000449f3bc
abstraction | 2025-11-18 12:04:42,682 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_sportzimmer
abstraction | 2025-11-18 12:04:42,699 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0009421422
abstraction | 2025-11-18 12:04:42,716 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_spuele_kueche/set
abstraction | 2025-11-18 12:04:42,734 - __main__ - INFO - Subscribed to vendor STATE: shellies/LightKitchenSink/relay/0
abstraction | 2025-11-18 12:04:42,751 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_schrank_esszimmer/set
abstraction | 2025-11-18 12:04:42,770 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankesszimmer/relay/0
abstraction | 2025-11-18 12:04:42,790 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_regal_wohnzimmer/set
abstraction | 2025-11-18 12:04:42,807 - __main__ - INFO - Subscribed to vendor STATE: shellies/wohnzimmer-regal/relay/0
abstraction | 2025-11-18 12:04:42,823 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_flur_schrank/set
abstraction | 2025-11-18 12:04:42,841 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankflur/relay/0
abstraction | 2025-11-18 12:04:42,858 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_terasse/set
abstraction | 2025-11-18 12:04:42,875 - __main__ - INFO - Subscribed to vendor STATE: shellies/lichtterasse/relay/0
abstraction | 2025-11-18 12:04:42,875 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/42/1/SET_TEMPERATURE: 21
abstraction | 2025-11-18 12:04:42,875 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=21
abstraction | 2025-11-18 12:04:42,876 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 21.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,876 - __main__ - INFO - ← abstract STATE thermostat_schlafzimmer: home/thermostat/thermostat_schlafzimmer/state → {"target": 21.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:42,897 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_schlafzimmer", "payload": {"target": 21.0, "mode": "heat"}, "ts": "2025-11-18T12:04:42.897310+00:00"}
abstraction | 2025-11-18 12:04:42,914 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/45/1/SET_TEMPERATURE: 15
abstraction | 2025-11-18 12:04:42,914 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 12:04:42,914 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,914 - __main__ - INFO - ← abstract STATE thermostat_esszimmer: home/thermostat/thermostat_esszimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:42,934 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_esszimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T12:04:42.934255+00:00"}
abstraction | 2025-11-18 12:04:42,950 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/46/1/SET_TEMPERATURE: 15
abstraction | 2025-11-18 12:04:42,950 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 12:04:42,950 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,951 - __main__ - INFO - ← abstract STATE thermostat_wohnzimmer: home/thermostat/thermostat_wohnzimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:42,970 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_wohnzimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T12:04:42.970936+00:00"}
abstraction | 2025-11-18 12:04:42,987 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/39/1/SET_TEMPERATURE: 22
abstraction | 2025-11-18 12:04:42,988 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=22
abstraction | 2025-11-18 12:04:42,988 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 22.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:42,988 - __main__ - INFO - ← abstract STATE thermostat_patty: home/thermostat/thermostat_patty/state → {"target": 22.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:43,009 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_patty", "payload": {"target": 22.0, "mode": "heat"}, "ts": "2025-11-18T12:04:43.009673+00:00"}
abstraction | 2025-11-18 12:04:43,029 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/41/1/SET_TEMPERATURE: 20
abstraction | 2025-11-18 12:04:43,029 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=20
abstraction | 2025-11-18 12:04:43,029 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 20.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:43,029 - __main__ - INFO - ← abstract STATE thermostat_bad_oben: home/thermostat/thermostat_bad_oben/state → {"target": 20.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:43,053 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_oben", "payload": {"target": 20.0, "mode": "heat"}, "ts": "2025-11-18T12:04:43.053895+00:00"}
abstraction | 2025-11-18 12:04:43,071 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/48/1/SET_TEMPERATURE: 21
abstraction | 2025-11-18 12:04:43,071 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=21
abstraction | 2025-11-18 12:04:43,071 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 21.0, 'mode': 'heat'}
abstraction | 2025-11-18 12:04:43,072 - __main__ - INFO - ← abstract STATE thermostat_bad_unten: home/thermostat/thermostat_bad_unten/state → {"target": 21.0, "mode": "heat"}
abstraction | 2025-11-18 12:04:43,092 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_unten", "payload": {"target": 21.0, "mode": "heat"}, "ts": "2025-11-18T12:04:43.092210+00:00"}
abstraction | 2025-11-18 12:04:43,108 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/52/1/STATE: false
abstraction | 2025-11-18 12:04:43,108 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,108 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,109 - __main__ - INFO - ← abstract STATE kontakt_schlafzimmer_strasse: home/contact/kontakt_schlafzimmer_strasse/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,128 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_schlafzimmer_strasse", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.128506+00:00"}
abstraction | 2025-11-18 12:04:43,145 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/26/1/STATE: false
abstraction | 2025-11-18 12:04:43,145 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,145 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,146 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_rechts: home/contact/kontakt_esszimmer_strasse_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,165 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.165958+00:00"}
abstraction | 2025-11-18 12:04:43,182 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/27/1/STATE: false
abstraction | 2025-11-18 12:04:43,182 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,183 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,183 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_links: home/contact/kontakt_esszimmer_strasse_links/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,202 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.202580+00:00"}
abstraction | 2025-11-18 12:04:43,219 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/28/1/STATE: false
abstraction | 2025-11-18 12:04:43,219 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,219 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,220 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_rechts: home/contact/kontakt_wohnzimmer_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,239 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.239653+00:00"}
abstraction | 2025-11-18 12:04:43,256 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/29/1/STATE: false
abstraction | 2025-11-18 12:04:43,256 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,256 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,257 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_links: home/contact/kontakt_wohnzimmer_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,275 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.275832+00:00"}
abstraction | 2025-11-18 12:04:43,292 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/18/1/STATE: false
abstraction | 2025-11-18 12:04:43,292 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,292 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,293 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_rechts: home/contact/kontakt_patty_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,314 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.314579+00:00"}
abstraction | 2025-11-18 12:04:43,331 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/22/1/STATE: false
abstraction | 2025-11-18 12:04:43,331 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,331 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,332 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_links: home/contact/kontakt_patty_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,351 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.351704+00:00"}
abstraction | 2025-11-18 12:04:43,368 - __main__ - DEBUG - MQTT message received on homegear/instance1/plain/44/1/STATE: false
abstraction | 2025-11-18 12:04:43,368 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 12:04:43,368 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 12:04:43,369 - __main__ - INFO - ← abstract STATE kontakt_bad_unten_strasse: home/contact/kontakt_bad_unten_strasse/state → {"contact": "closed"}
abstraction | 2025-11-18 12:04:43,388 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_bad_unten_strasse", "payload": {"contact": "closed"}, "ts": "2025-11-18T12:04:43.388390+00:00"}
api | INFO: 172.16.3.98:60163 - "GET /realtime HTTP/1.1" 200 OK
ui | INFO: 127.0.0.1:35036 - "GET /health HTTP/1.1" 200 OK
api | INFO: 172.16.3.98:60172 - "GET /realtime HTTP/1.1" 200 OK
abstraction | 2025-11-18 12:04:48,498 - __main__ - DEBUG - MQTT message received on shellies/schrankesszimmer/relay/0: off
abstraction | 2025-11-18 12:04:48,498 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:04:48,498 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:04:48,498 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 12:04:48,518 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T12:04:48.518525+00:00"}
api | INFO: 172.16.3.98:60187 - "GET /realtime HTTP/1.1" 200 OK
abstraction | 2025-11-18 12:04:52,989 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":55.04,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:52,989 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":100,"humidity":55.04,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:52,989 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 55.04, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1002.6, 'temperature': 22.13, 'voltage': 3015}
abstraction | 2025-11-18 12:04:52,989 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 55.04, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}
abstraction | 2025-11-18 12:04:53,009 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 55.04, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}, "ts": "2025-11-18T12:04:53.009776+00:00"}
abstraction | 2025-11-18 12:04:53,024 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,025 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.6,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,025 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.82, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1002.6, 'temperature': 22.13, 'voltage': 3015}
abstraction | 2025-11-18 12:04:53,025 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}
abstraction | 2025-11-18 12:04:53,044 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.6, "temperature": 22.13, "voltage": 3015}, "ts": "2025-11-18T12:04:53.044379+00:00"}
abstraction | 2025-11-18 12:04:53,061 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d0003f052b7: {"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.4,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,061 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":100,"humidity":54.82,"linkquality":83,"power_outage_count":38416,"pressure":1002.4,"temperature":22.13,"voltage":3015}
abstraction | 2025-11-18 12:04:53,061 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.82, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1002.4, 'temperature': 22.13, 'voltage': 3015}
abstraction | 2025-11-18 12:04:53,061 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.4, "temperature": 22.13, "voltage": 3015}
abstraction | 2025-11-18 12:04:53,084 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.82, "linkquality": 83, "power_outage_count": 38416, "pressure": 1002.4, "temperature": 22.13, "voltage": 3015}, "ts": "2025-11-18T12:04:53.083988+00:00"}
abstraction | 2025-11-18 12:05:03,058 - __main__ - DEBUG - MQTT message received on shellies/lichtterasse/relay/0: off
abstraction | 2025-11-18 12:05:03,058 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:05:03,058 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:05:03,058 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 12:05:03,075 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T12:05:03.075262+00:00"}
abstraction | 2025-11-18 12:05:08,209 - __main__ - DEBUG - MQTT message received on shellies/wohnzimmer-regal/relay/0: off
abstraction | 2025-11-18 12:05:08,210 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:05:08,210 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:05:08,210 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 12:05:08,228 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T12:05:08.228758+00:00"}
abstraction | 2025-11-18 12:05:10,881 - __main__ - DEBUG - MQTT message received on shellies/LightKitchenSink/relay/0: on
abstraction | 2025-11-18 12:05:10,881 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 12:05:10,881 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 12:05:10,881 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 12:05:10,899 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T12:05:10.899207+00:00"}
abstraction | 2025-11-18 12:05:12,622 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,622 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,622 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 63, 'humidity': 47.69, 'linkquality': 87, 'power_outage_count': 4906, 'pressure': 1009.9, 'temperature': 19.74, 'voltage': 2945}
abstraction | 2025-11-18 12:05:12,622 - __main__ - INFO - ← abstract STATE sensor_kueche: home/temp_humidity/sensor_kueche/state → {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}
abstraction | 2025-11-18 12:05:12,640 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_kueche", "payload": {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}, "ts": "2025-11-18T12:05:12.640129+00:00"}
abstraction | 2025-11-18 12:05:12,656 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,656 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.9,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,656 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 63, 'humidity': 47.69, 'linkquality': 87, 'power_outage_count': 4906, 'pressure': 1009.9, 'temperature': 19.74, 'voltage': 2945}
abstraction | 2025-11-18 12:05:12,657 - __main__ - INFO - ← abstract STATE sensor_kueche: home/temp_humidity/sensor_kueche/state → {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}
abstraction | 2025-11-18 12:05:12,674 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_kueche", "payload": {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.9, "temperature": 19.74, "voltage": 2945}, "ts": "2025-11-18T12:05:12.674372+00:00"}
abstraction | 2025-11-18 12:05:12,690 - __main__ - DEBUG - MQTT message received on zigbee2mqtt/0x00158d00083299bb: {"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.7,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,690 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={"battery":63,"humidity":47.69,"linkquality":87,"power_outage_count":4906,"pressure":1009.7,"temperature":19.74,"voltage":2945}
abstraction | 2025-11-18 12:05:12,690 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 63, 'humidity': 47.69, 'linkquality': 87, 'power_outage_count': 4906, 'pressure': 1009.7, 'temperature': 19.74, 'voltage': 2945}
abstraction | 2025-11-18 12:05:12,690 - __main__ - INFO - ← abstract STATE sensor_kueche: home/temp_humidity/sensor_kueche/state → {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.7, "temperature": 19.74, "voltage": 2945}
abstraction | 2025-11-18 12:05:12,708 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_kueche", "payload": {"battery": 63, "humidity": 47.69, "linkquality": 87, "power_outage_count": 4906, "pressure": 1009.7, "temperature": 19.74, "voltage": 2945}, "ts": "2025-11-18T12:05:12.708715+00:00"}
ui | INFO: 127.0.0.1:35638 - "GET /health HTTP/1.1" 200 OK
abstraction | 2025-11-18 12:05:18,507 - __main__ - DEBUG - MQTT message received on shellies/schrankesszimmer/relay/0: off
abstraction | 2025-11-18 12:05:18,508 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 12:05:18,508 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 12:05:18,508 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 12:05:18,526 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T12:05:18.525971+00:00"}

View File

@@ -1,268 +0,0 @@
abstraction | 2025-11-18 10:23:59,179 - asyncio - DEBUG - Using selector: EpollSelector
abstraction | 2025-11-18 10:23:59,240 - __main__ - INFO - Loaded configuration from /app/config/devices.yaml
abstraction | 2025-11-18 10:23:59,240 - __main__ - INFO - Loaded 64 device(s): lampe_semeniere_wohnzimmer, stehlampe_esszimmer_spiegel, stehlampe_esszimmer_schrank, grosse_lampe_wohnzimmer, lampe_naehtischchen_wohnzimmer, kleine_lampe_rechts_esszimmer, kleine_lampe_links_esszimmer, leselampe_esszimmer, medusalampe_schlafzimmer, sportlicht_am_fernseher_studierzimmer, deckenlampe_schlafzimmer, bettlicht_wolfgang, bettlicht_patty, schranklicht_hinten_patty, schranklicht_vorne_patty, leselampe_patty, deckenlampe_esszimmer, standlampe_esszimmer, haustuer, deckenlampe_flur_oben, kueche_deckenlampe, sportlicht_tisch, sportlicht_regal, licht_flur_oben_am_spiegel, experimentlabtest, thermostat_wolfgang, thermostat_kueche, thermostat_schlafzimmer, thermostat_esszimmer, thermostat_wohnzimmer, thermostat_patty, thermostat_bad_oben, thermostat_bad_unten, sterne_wohnzimmer, kontakt_schlafzimmer_strasse, kontakt_esszimmer_strasse_rechts, kontakt_esszimmer_strasse_links, kontakt_wohnzimmer_garten_rechts, kontakt_wohnzimmer_garten_links, kontakt_kueche_garten_fenster, kontakt_kueche_garten_tuer, kontakt_kueche_strasse_rechts, kontakt_kueche_strasse_links, kontakt_patty_garten_rechts, kontakt_patty_garten_links, kontakt_patty_strasse, kontakt_wolfgang_garten, kontakt_bad_oben_strasse, kontakt_bad_unten_strasse, sensor_schlafzimmer, sensor_wohnzimmer, sensor_kueche, sensor_arbeitszimmer_patty, sensor_arbeitszimmer_wolfgang, sensor_bad_oben, sensor_bad_unten, sensor_flur, sensor_waschkueche, sensor_sportzimmer, licht_spuele_kueche, licht_schrank_esszimmer, licht_regal_wohnzimmer, licht_flur_schrank, licht_terasse
abstraction | 2025-11-18 10:23:59,241 - __main__ - INFO - Loaded 64 device(s) from configuration
abstraction | 2025-11-18 10:23:59,292 - __main__ - INFO - Connected to Redis: redis://172.23.1.116:6379/8
abstraction | 2025-11-18 10:23:59,292 - __main__ - INFO - Abstraction worker started
abstraction | 2025-11-18 10:23:59,293 - __main__ - INFO - Connecting to MQTT broker: 172.23.1.102:1883
abstraction | 2025-11-18 10:23:59,341 - __main__ - INFO - Connected to MQTT broker as home-automation-abstraction-2cfdfa
abstraction | 2025-11-18 10:23:59,359 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_semeniere_wohnzimmer/set
abstraction | 2025-11-18 10:23:59,377 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8000015480b
abstraction | 2025-11-18 10:23:59,394 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_spiegel/set
abstraction | 2025-11-18 10:23:59,411 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d06ea09
abstraction | 2025-11-18 10:23:59,428 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_schrank/set
abstraction | 2025-11-18 10:23:59,444 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d09176c
abstraction | 2025-11-18 10:23:59,460 - __main__ - INFO - Subscribed to abstract SET: home/relay/grosse_lampe_wohnzimmer/set
abstraction | 2025-11-18 10:23:59,477 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000151aca
abstraction | 2025-11-18 10:23:59,493 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_naehtischchen_wohnzimmer/set
abstraction | 2025-11-18 10:23:59,510 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffee560ee
abstraction | 2025-11-18 10:23:59,526 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_rechts_esszimmer/set
abstraction | 2025-11-18 10:23:59,543 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000156645
abstraction | 2025-11-18 10:23:59,560 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_links_esszimmer/set
abstraction | 2025-11-18 10:23:59,578 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000153099
abstraction | 2025-11-18 10:23:59,595 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_esszimmer/set
abstraction | 2025-11-18 10:23:59,612 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffe7b84f2
abstraction | 2025-11-18 10:23:59,630 - __main__ - INFO - Subscribed to abstract SET: home/relay/medusalampe_schlafzimmer/set
abstraction | 2025-11-18 10:23:59,647 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154c7c
abstraction | 2025-11-18 10:23:59,665 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_am_fernseher_studierzimmer/set
abstraction | 2025-11-18 10:23:59,682 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffe76a23a
abstraction | 2025-11-18 10:23:59,700 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_schlafzimmer/set
abstraction | 2025-11-18 10:23:59,717 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a406a7
abstraction | 2025-11-18 10:23:59,735 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_wolfgang/set
abstraction | 2025-11-18 10:23:59,753 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00178801081570bf
abstraction | 2025-11-18 10:23:59,770 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_patty/set
abstraction | 2025-11-18 10:23:59,788 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108158b32
abstraction | 2025-11-18 10:23:59,807 - __main__ - INFO - Subscribed to abstract SET: home/light/schranklicht_hinten_patty/set
abstraction | 2025-11-18 10:23:59,825 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880106e29571
abstraction | 2025-11-18 10:23:59,844 - __main__ - INFO - Subscribed to abstract SET: home/relay/schranklicht_vorne_patty/set
abstraction | 2025-11-18 10:23:59,862 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154cf5
abstraction | 2025-11-18 10:23:59,881 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_patty/set
abstraction | 2025-11-18 10:23:59,901 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010600ec9d
abstraction | 2025-11-18 10:23:59,920 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_esszimmer/set
abstraction | 2025-11-18 10:23:59,940 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a03e45
abstraction | 2025-11-18 10:23:59,959 - __main__ - INFO - Subscribed to abstract SET: home/light/standlampe_esszimmer/set
abstraction | 2025-11-18 10:23:59,979 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xbc33acfffe21f547
abstraction | 2025-11-18 10:23:59,999 - __main__ - INFO - Subscribed to abstract SET: home/light/haustuer/set
abstraction | 2025-11-18 10:24:00,016 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffea6a3da
abstraction | 2025-11-18 10:24:00,034 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_flur_oben/set
abstraction | 2025-11-18 10:24:00,053 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2123a7
abstraction | 2025-11-18 10:24:00,072 - __main__ - INFO - Subscribed to abstract SET: home/light/kueche_deckenlampe/set
abstraction | 2025-11-18 10:24:00,090 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2c40c4
abstraction | 2025-11-18 10:24:00,108 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_tisch/set
abstraction | 2025-11-18 10:24:00,127 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f31b
abstraction | 2025-11-18 10:24:00,145 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_regal/set
abstraction | 2025-11-18 10:24:00,163 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f569
abstraction | 2025-11-18 10:24:00,183 - __main__ - INFO - Subscribed to abstract SET: home/light/licht_flur_oben_am_spiegel/set
abstraction | 2025-11-18 10:24:00,201 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffefe4ba4
abstraction | 2025-11-18 10:24:00,218 - __main__ - INFO - Subscribed to abstract SET: home/light/experimentlabtest/set
abstraction | 2025-11-18 10:24:00,237 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000195038
abstraction | 2025-11-18 10:24:00,255 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wolfgang/set
abstraction | 2025-11-18 10:24:00,271 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x540f57fffe7e3cfe
abstraction | 2025-11-18 10:24:00,292 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_kueche/set
abstraction | 2025-11-18 10:24:00,313 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x94deb8fffe2e5c06
abstraction | 2025-11-18 10:24:00,334 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_schlafzimmer/set
abstraction | 2025-11-18 10:24:00,356 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/42/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,377 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_esszimmer/set
abstraction | 2025-11-18 10:24:00,398 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/45/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,420 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wohnzimmer/set
abstraction | 2025-11-18 10:24:00,440 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/46/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,457 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_patty/set
abstraction | 2025-11-18 10:24:00,475 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/39/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,493 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_oben/set
abstraction | 2025-11-18 10:24:00,509 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/41/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,530 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_unten/set
abstraction | 2025-11-18 10:24:00,551 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/48/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,572 - __main__ - INFO - Subscribed to abstract SET: home/relay/sterne_wohnzimmer/set
abstraction | 2025-11-18 10:24:00,593 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000155fc2
abstraction | 2025-11-18 10:24:00,593 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_schlafzimmer_strasse
abstraction | 2025-11-18 10:24:00,614 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/52/1/STATE
abstraction | 2025-11-18 10:24:00,614 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_rechts
abstraction | 2025-11-18 10:24:00,630 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/26/1/STATE
abstraction | 2025-11-18 10:24:00,630 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_links
abstraction | 2025-11-18 10:24:00,647 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/27/1/STATE
abstraction | 2025-11-18 10:24:00,647 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_rechts
abstraction | 2025-11-18 10:24:00,668 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/28/1/STATE
abstraction | 2025-11-18 10:24:00,668 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_links
abstraction | 2025-11-18 10:24:00,691 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/29/1/STATE
abstraction | 2025-11-18 10:24:00,691 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_fenster
abstraction | 2025-11-18 10:24:00,708 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332785
abstraction | 2025-11-18 10:24:00,708 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_tuer
abstraction | 2025-11-18 10:24:00,728 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332788
abstraction | 2025-11-18 10:24:00,728 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_rechts
abstraction | 2025-11-18 10:24:00,747 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b151803
abstraction | 2025-11-18 10:24:00,747 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_links
abstraction | 2025-11-18 10:24:00,767 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b331d0b
abstraction | 2025-11-18 10:24:00,767 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_rechts
abstraction | 2025-11-18 10:24:00,784 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/18/1/STATE
abstraction | 2025-11-18 10:24:00,784 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_links
abstraction | 2025-11-18 10:24:00,802 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/22/1/STATE
abstraction | 2025-11-18 10:24:00,802 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_strasse
abstraction | 2025-11-18 10:24:00,821 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000af457cf
abstraction | 2025-11-18 10:24:00,821 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wolfgang_garten
abstraction | 2025-11-18 10:24:00,838 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b3328da
abstraction | 2025-11-18 10:24:00,838 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_oben_strasse
abstraction | 2025-11-18 10:24:00,855 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b333aec
abstraction | 2025-11-18 10:24:00,855 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_unten_strasse
abstraction | 2025-11-18 10:24:00,872 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/44/1/STATE
abstraction | 2025-11-18 10:24:00,872 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_schlafzimmer
abstraction | 2025-11-18 10:24:00,891 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00043292dc
abstraction | 2025-11-18 10:24:00,891 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_wohnzimmer
abstraction | 2025-11-18 10:24:00,907 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0008975707
abstraction | 2025-11-18 10:24:00,907 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_kueche
abstraction | 2025-11-18 10:24:00,925 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00083299bb
abstraction | 2025-11-18 10:24:00,925 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_patty
abstraction | 2025-11-18 10:24:00,947 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0003f052b7
abstraction | 2025-11-18 10:24:00,947 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_wolfgang
abstraction | 2025-11-18 10:24:00,969 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000543fb99
abstraction | 2025-11-18 10:24:00,969 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_oben
abstraction | 2025-11-18 10:24:00,986 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e8987
abstraction | 2025-11-18 10:24:00,986 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_unten
abstraction | 2025-11-18 10:24:01,004 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e662a
abstraction | 2025-11-18 10:24:01,004 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_flur
abstraction | 2025-11-18 10:24:01,022 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000836ccc6
abstraction | 2025-11-18 10:24:01,022 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_waschkueche
abstraction | 2025-11-18 10:24:01,038 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000449f3bc
abstraction | 2025-11-18 10:24:01,038 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_sportzimmer
abstraction | 2025-11-18 10:24:01,058 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0009421422
abstraction | 2025-11-18 10:24:01,074 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_spuele_kueche/set
abstraction | 2025-11-18 10:24:01,090 - __main__ - INFO - Subscribed to vendor STATE: shellies/LightKitchenSink/relay/0
abstraction | 2025-11-18 10:24:01,107 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_schrank_esszimmer/set
abstraction | 2025-11-18 10:24:01,122 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankesszimmer/relay/0
abstraction | 2025-11-18 10:24:01,139 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_regal_wohnzimmer/set
abstraction | 2025-11-18 10:24:01,155 - __main__ - INFO - Subscribed to vendor STATE: shellies/wohnzimmer-regal/relay/0
abstraction | 2025-11-18 10:24:01,172 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_flur_schrank/set
abstraction | 2025-11-18 10:24:01,189 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankflur/relay/0
abstraction | 2025-11-18 10:24:01,205 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_terasse/set
abstraction | 2025-11-18 10:24:01,222 - __main__ - INFO - Subscribed to vendor STATE: shellies/lichtterasse/relay/0
abstraction | 2025-11-18 10:24:01,222 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=21
abstraction | 2025-11-18 10:24:01,222 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 21.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,222 - __main__ - INFO - ← abstract STATE thermostat_schlafzimmer: home/thermostat/thermostat_schlafzimmer/state → {"target": 21.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,243 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_schlafzimmer", "payload": {"target": 21.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.243641+00:00"}
abstraction | 2025-11-18 10:24:01,260 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 10:24:01,260 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,260 - __main__ - INFO - ← abstract STATE thermostat_esszimmer: home/thermostat/thermostat_esszimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,280 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_esszimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.280285+00:00"}
abstraction | 2025-11-18 10:24:01,296 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 10:24:01,296 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,296 - __main__ - INFO - ← abstract STATE thermostat_wohnzimmer: home/thermostat/thermostat_wohnzimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,317 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_wohnzimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.317708+00:00"}
abstraction | 2025-11-18 10:24:01,334 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=22
abstraction | 2025-11-18 10:24:01,334 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 22.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,334 - __main__ - INFO - ← abstract STATE thermostat_patty: home/thermostat/thermostat_patty/state → {"target": 22.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,357 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_patty", "payload": {"target": 22.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.357082+00:00"}
abstraction | 2025-11-18 10:24:01,373 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=20
abstraction | 2025-11-18 10:24:01,373 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 20.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,373 - __main__ - INFO - ← abstract STATE thermostat_bad_oben: home/thermostat/thermostat_bad_oben/state → {"target": 20.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,395 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_oben", "payload": {"target": 20.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.395470+00:00"}
abstraction | 2025-11-18 10:24:01,411 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=5
abstraction | 2025-11-18 10:24:01,411 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 5.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,411 - __main__ - INFO - ← abstract STATE thermostat_bad_unten: home/thermostat/thermostat_bad_unten/state → {"target": 5.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,431 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_unten", "payload": {"target": 5.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.431068+00:00"}
abstraction | 2025-11-18 10:24:01,448 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,448 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,449 - __main__ - INFO - ← abstract STATE kontakt_schlafzimmer_strasse: home/contact/kontakt_schlafzimmer_strasse/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,472 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_schlafzimmer_strasse", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.472456+00:00"}
abstraction | 2025-11-18 10:24:01,491 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,491 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,491 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_rechts: home/contact/kontakt_esszimmer_strasse_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,733 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.733873+00:00"}
abstraction | 2025-11-18 10:24:01,750 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,750 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,750 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_links: home/contact/kontakt_esszimmer_strasse_links/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,771 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.771380+00:00"}
abstraction | 2025-11-18 10:24:01,788 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,788 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,788 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_rechts: home/contact/kontakt_wohnzimmer_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,808 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.808516+00:00"}
abstraction | 2025-11-18 10:24:01,825 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,825 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,825 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_links: home/contact/kontakt_wohnzimmer_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,844 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.844046+00:00"}
abstraction | 2025-11-18 10:24:01,860 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,861 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,861 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_rechts: home/contact/kontakt_patty_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,881 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.881922+00:00"}
abstraction | 2025-11-18 10:24:01,898 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,898 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,898 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_links: home/contact/kontakt_patty_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,922 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.922254+00:00"}
abstraction | 2025-11-18 10:24:01,940 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=true
abstraction | 2025-11-18 10:24:01,940 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'open'}
abstraction | 2025-11-18 10:24:01,940 - __main__ - INFO - ← abstract STATE kontakt_bad_unten_strasse: home/contact/kontakt_bad_unten_strasse/state → {"contact": "open"}
abstraction | 2025-11-18 10:24:01,959 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_bad_unten_strasse", "payload": {"contact": "open"}, "ts": "2025-11-18T10:24:01.959678+00:00"}
abstraction | 2025-11-18 10:24:02,354 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:02,354 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:02,354 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:24:02,373 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:02.373461+00:00"}
abstraction | 2025-11-18 10:24:07,440 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:07,440 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:07,441 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:07,459 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:07.459082+00:00"}
abstraction | 2025-11-18 10:24:08,817 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.37, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,817 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.37, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,817 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.37, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}
abstraction | 2025-11-18 10:24:08,835 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.37, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}, "ts": "2025-11-18T10:24:08.835488+00:00"}
abstraction | 2025-11-18 10:24:08,852 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,852 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,852 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}
abstraction | 2025-11-18 10:24:08,870 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}, "ts": "2025-11-18T10:24:08.870674+00:00"}
abstraction | 2025-11-18 10:24:08,887 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1003.9, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,887 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1003.9, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,887 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1003.9, "temperature": 22.16, "voltage": 3015}
abstraction | 2025-11-18 10:24:08,907 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1003.9, "temperature": 22.16, "voltage": 3015}, "ts": "2025-11-18T10:24:08.907729+00:00"}
abstraction | 2025-11-18 10:24:10,178 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:24:10,178 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:24:10,178 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:24:10,196 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:24:10.196762+00:00"}
abstraction | 2025-11-18 10:24:17,815 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:17,815 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:17,815 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:17,834 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:17.834042+00:00"}
abstraction | 2025-11-18 10:24:32,370 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:32,370 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:32,370 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:24:32,405 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:32.405754+00:00"}
abstraction | 2025-11-18 10:24:37,447 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:37,447 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:37,447 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:37,465 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:37.465220+00:00"}
abstraction | 2025-11-18 10:24:40,188 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:24:40,189 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:24:40,189 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:24:40,207 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:24:40.207222+00:00"}
abstraction | 2025-11-18 10:24:47,833 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:47,833 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:47,833 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:47,868 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:47.868787+00:00"}
abstraction | 2025-11-18 10:25:02,363 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:02,363 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:02,363 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:25:02,381 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:02.381792+00:00"}
abstraction | 2025-11-18 10:25:07,447 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:07,448 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:07,448 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:07,465 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:07.465566+00:00"}
abstraction | 2025-11-18 10:25:10,185 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:25:10,185 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:25:10,185 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:25:10,202 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:25:10.202372+00:00"}
abstraction | 2025-11-18 10:25:17,820 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:17,820 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:17,820 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:17,838 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:17.838140+00:00"}
abstraction | 2025-11-18 10:25:32,361 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:32,361 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:32,361 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:25:32,379 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:32.379286+00:00"}
abstraction | 2025-11-18 10:25:37,455 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:37,455 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:37,455 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:37,473 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:37.473171+00:00"}
abstraction | 2025-11-18 10:25:40,193 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:25:40,194 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:25:40,194 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:25:40,211 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:25:40.211493+00:00"}
abstraction | 2025-11-18 10:25:47,821 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:47,821 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:47,821 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:47,838 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:47.838508+00:00"}

View File

@@ -1,332 +0,0 @@
✔ home-automation-abstraction Built 0.0s
✔ home-automation-api Built 0.0s
✔ home-automation-rules Built 0.0s
✔ home-automation-ui Built 0.0s
Attaching to abstraction, api, rules, ui
abstraction | 2025-11-18 10:23:59,179 - asyncio - DEBUG - Using selector: EpollSelector
rules | 2025-11-18 10:23:59,207 - asyncio - DEBUG - Using selector: EpollSelector
rules | 2025-11-18 10:23:59,208 - __main__ - INFO - ============================================================
rules | 2025-11-18 10:23:59,208 - __main__ - INFO - Rules Engine Starting
rules | 2025-11-18 10:23:59,209 - __main__ - INFO - ============================================================
rules | 2025-11-18 10:23:59,209 - __main__ - INFO - Config: /app/config/rules.yaml
rules | 2025-11-18 10:23:59,210 - __main__ - INFO - MQTT: 172.23.1.102:1883
rules | 2025-11-18 10:23:59,210 - __main__ - INFO - Redis: redis://172.23.1.116:6379/8
rules | 2025-11-18 10:23:59,210 - __main__ - INFO - ============================================================
rules | 2025-11-18 10:23:59,211 - __main__ - INFO - Loading rules configuration from /app/config/rules.yaml
rules | 2025-11-18 10:23:59,217 - __main__ - INFO - Loaded 6 rule(s) from configuration
rules | 2025-11-18 10:23:59,218 - __main__ - INFO - - window_setback_esszimmer (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 10:23:59,218 - __main__ - INFO - - window_setback_kueche (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 10:23:59,219 - __main__ - INFO - - window_setback_patty (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 10:23:59,219 - __main__ - INFO - - window_setback_schlafzimmer (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 10:23:59,220 - __main__ - INFO - - window_setback_wohnzimmer (type: window_setback@1.0) [DISABLED]
rules | 2025-11-18 10:23:59,225 - __main__ - INFO - - window_setback_wolfgang (type: window_setback@1.0)
rules | 2025-11-18 10:23:59,225 - __main__ - INFO - Successfully loaded 1 rule implementation(s) (5 disabled)
rules | 2025-11-18 10:23:59,226 - __main__ - INFO - Rule window_setback_wolfgang validated: 1 contacts, 1 thermostats
rules | 2025-11-18 10:23:59,226 - __main__ - DEBUG - Rule window_setback_wolfgang subscribes to 2 topic(s)
rules | 2025-11-18 10:23:59,227 - __main__ - INFO - Total MQTT subscriptions needed: 2
rules | 2025-11-18 10:23:59,227 - __main__ - INFO - Starting event processing loop
abstraction | 2025-11-18 10:23:59,240 - __main__ - INFO - Loaded configuration from /app/config/devices.yaml
abstraction | 2025-11-18 10:23:59,240 - __main__ - INFO - Loaded 64 device(s): lampe_semeniere_wohnzimmer, stehlampe_esszimmer_spiegel, stehlampe_esszimmer_schrank, grosse_lampe_wohnzimmer, lampe_naehtischchen_wohnzimmer, kleine_lampe_rechts_esszimmer, kleine_lampe_links_esszimmer, leselampe_esszimmer, medusalampe_schlafzimmer, sportlicht_am_fernseher_studierzimmer, deckenlampe_schlafzimmer, bettlicht_wolfgang, bettlicht_patty, schranklicht_hinten_patty, schranklicht_vorne_patty, leselampe_patty, deckenlampe_esszimmer, standlampe_esszimmer, haustuer, deckenlampe_flur_oben, kueche_deckenlampe, sportlicht_tisch, sportlicht_regal, licht_flur_oben_am_spiegel, experimentlabtest, thermostat_wolfgang, thermostat_kueche, thermostat_schlafzimmer, thermostat_esszimmer, thermostat_wohnzimmer, thermostat_patty, thermostat_bad_oben, thermostat_bad_unten, sterne_wohnzimmer, kontakt_schlafzimmer_strasse, kontakt_esszimmer_strasse_rechts, kontakt_esszimmer_strasse_links, kontakt_wohnzimmer_garten_rechts, kontakt_wohnzimmer_garten_links, kontakt_kueche_garten_fenster, kontakt_kueche_garten_tuer, kontakt_kueche_strasse_rechts, kontakt_kueche_strasse_links, kontakt_patty_garten_rechts, kontakt_patty_garten_links, kontakt_patty_strasse, kontakt_wolfgang_garten, kontakt_bad_oben_strasse, kontakt_bad_unten_strasse, sensor_schlafzimmer, sensor_wohnzimmer, sensor_kueche, sensor_arbeitszimmer_patty, sensor_arbeitszimmer_wolfgang, sensor_bad_oben, sensor_bad_unten, sensor_flur, sensor_waschkueche, sensor_sportzimmer, licht_spuele_kueche, licht_schrank_esszimmer, licht_regal_wohnzimmer, licht_flur_schrank, licht_terasse
abstraction | 2025-11-18 10:23:59,241 - __main__ - INFO - Loaded 64 device(s) from configuration
abstraction | 2025-11-18 10:23:59,292 - __main__ - INFO - Connected to Redis: redis://172.23.1.116:6379/8
abstraction | 2025-11-18 10:23:59,292 - __main__ - INFO - Abstraction worker started
abstraction | 2025-11-18 10:23:59,293 - __main__ - INFO - Connecting to MQTT broker: 172.23.1.102:1883
abstraction | 2025-11-18 10:23:59,341 - __main__ - INFO - Connected to MQTT broker as home-automation-abstraction-2cfdfa
abstraction | 2025-11-18 10:23:59,359 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_semeniere_wohnzimmer/set
abstraction | 2025-11-18 10:23:59,377 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8000015480b
rules | 2025-11-18 10:23:59,378 - __main__ - INFO - Connecting to MQTT broker 172.23.1.102:1883 (client_id=rule_engine-782522)
abstraction | 2025-11-18 10:23:59,394 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_spiegel/set
abstraction | 2025-11-18 10:23:59,411 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d06ea09
abstraction | 2025-11-18 10:23:59,428 - __main__ - INFO - Subscribed to abstract SET: home/light/stehlampe_esszimmer_schrank/set
rules | 2025-11-18 10:23:59,431 - __main__ - INFO - Connected to MQTT broker 172.23.1.102:1883
abstraction | 2025-11-18 10:23:59,444 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d09176c
abstraction | 2025-11-18 10:23:59,460 - __main__ - INFO - Subscribed to abstract SET: home/relay/grosse_lampe_wohnzimmer/set
rules | 2025-11-18 10:23:59,466 - __main__ - INFO - Subscribed to 2 topic(s): home/thermostat/thermostat_wolfgang/state, home/contact/kontakt_wolfgang_garten/state
rules | 2025-11-18 10:23:59,467 - __main__ - DEBUG - Received event: {'topic': 'home/thermostat/thermostat_wolfgang/state', 'type': 'state', 'cap': 'thermostat', 'device_id': 'thermostat_wolfgang', 'payload': {'target': 23.0, 'current': 22.5, 'mode': 'heat'}, 'ts': '2025-11-18T10:23:59.467177'}
rules | 2025-11-18 10:23:59,467 - __main__ - DEBUG - Filtering for cap=thermostat, device_id=thermostat_wolfgang
rules | 2025-11-18 10:23:59,468 - __main__ - DEBUG - Rule window_setback_wolfgang: checking thermostats ['thermostat_wolfgang']
rules | 2025-11-18 10:23:59,468 - __main__ - INFO - Event thermostat/thermostat_wolfgang: 1 matching rule(s)
abstraction | 2025-11-18 10:23:59,477 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000151aca
abstraction | 2025-11-18 10:23:59,493 - __main__ - INFO - Subscribed to abstract SET: home/relay/lampe_naehtischchen_wohnzimmer/set
abstraction | 2025-11-18 10:23:59,510 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffee560ee
abstraction | 2025-11-18 10:23:59,526 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_rechts_esszimmer/set
abstraction | 2025-11-18 10:23:59,543 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000156645
abstraction | 2025-11-18 10:23:59,560 - __main__ - INFO - Subscribed to abstract SET: home/relay/kleine_lampe_links_esszimmer/set
rules | 2025-11-18 10:23:59,572 - __main__ - DEBUG - Rule window_setback_wolfgang: Updated current target for thermostat_wolfgang: 23.0°C
rules | 2025-11-18 10:23:59,573 - __main__ - DEBUG - Received event: {'topic': 'home/contact/kontakt_wolfgang_garten/state', 'type': 'state', 'cap': 'contact', 'device_id': 'kontakt_wolfgang_garten', 'payload': {'contact': 'closed', 'battery': 100, 'linkquality': 32, 'device_temperature': 26, 'voltage': 3025}, 'ts': '2025-11-18T10:23:59.573073'}
rules | 2025-11-18 10:23:59,573 - __main__ - DEBUG - Filtering for cap=contact, device_id=kontakt_wolfgang_garten
rules | 2025-11-18 10:23:59,573 - __main__ - DEBUG - Rule window_setback_wolfgang: checking contacts ['kontakt_wolfgang_garten']
rules | 2025-11-18 10:23:59,574 - __main__ - INFO - Event contact/kontakt_wolfgang_garten: 1 matching rule(s)
abstraction | 2025-11-18 10:23:59,578 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000153099
abstraction | 2025-11-18 10:23:59,595 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_esszimmer/set
rules | 2025-11-18 10:23:59,610 - __main__ - INFO - Rule window_setback_wolfgang: Window closed, restoring 1 thermostats to previous temperatures
abstraction | 2025-11-18 10:23:59,612 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffe7b84f2
rules | 2025-11-18 10:23:59,627 - __main__ - WARNING - No previous target found for thermostat_wolfgang, cannot restore
abstraction | 2025-11-18 10:23:59,630 - __main__ - INFO - Subscribed to abstract SET: home/relay/medusalampe_schlafzimmer/set
abstraction | 2025-11-18 10:23:59,647 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154c7c
abstraction | 2025-11-18 10:23:59,665 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_am_fernseher_studierzimmer/set
abstraction | 2025-11-18 10:23:59,682 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffe76a23a
abstraction | 2025-11-18 10:23:59,700 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_schlafzimmer/set
abstraction | 2025-11-18 10:23:59,717 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a406a7
api | INFO: Started server process [1]
api | INFO: Waiting for application startup.
abstraction | 2025-11-18 10:23:59,735 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_wolfgang/set
api | INFO: Application startup complete.
abstraction | 2025-11-18 10:23:59,753 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00178801081570bf
api | INFO: Uvicorn running on http://0.0.0.0:8001 (Press CTRL+C to quit)
abstraction | 2025-11-18 10:23:59,770 - __main__ - INFO - Subscribed to abstract SET: home/light/bettlicht_patty/set
abstraction | 2025-11-18 10:23:59,788 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108158b32
abstraction | 2025-11-18 10:23:59,807 - __main__ - INFO - Subscribed to abstract SET: home/light/schranklicht_hinten_patty/set
abstraction | 2025-11-18 10:23:59,825 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880106e29571
abstraction | 2025-11-18 10:23:59,844 - __main__ - INFO - Subscribed to abstract SET: home/relay/schranklicht_vorne_patty/set
abstraction | 2025-11-18 10:23:59,862 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000154cf5
abstraction | 2025-11-18 10:23:59,881 - __main__ - INFO - Subscribed to abstract SET: home/light/leselampe_patty/set
abstraction | 2025-11-18 10:23:59,901 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010600ec9d
abstraction | 2025-11-18 10:23:59,920 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_esszimmer/set
abstraction | 2025-11-18 10:23:59,940 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x0017880108a03e45
abstraction | 2025-11-18 10:23:59,959 - __main__ - INFO - Subscribed to abstract SET: home/light/standlampe_esszimmer/set
abstraction | 2025-11-18 10:23:59,979 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xbc33acfffe21f547
ui | UI using API_BASE: http://172.19.1.11:8001
ui | UI using BASE_PATH: /
ui | INFO: Started server process [1]
ui | INFO: Waiting for application startup.
ui | INFO: Application startup complete.
abstraction | 2025-11-18 10:23:59,999 - __main__ - INFO - Subscribed to abstract SET: home/light/haustuer/set
ui | INFO: Uvicorn running on http://0.0.0.0:8002 (Press CTRL+C to quit)
abstraction | 2025-11-18 10:24:00,016 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xec1bbdfffea6a3da
abstraction | 2025-11-18 10:24:00,034 - __main__ - INFO - Subscribed to abstract SET: home/light/deckenlampe_flur_oben/set
abstraction | 2025-11-18 10:24:00,053 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2123a7
abstraction | 2025-11-18 10:24:00,072 - __main__ - INFO - Subscribed to abstract SET: home/light/kueche_deckenlampe/set
abstraction | 2025-11-18 10:24:00,090 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x001788010d2c40c4
abstraction | 2025-11-18 10:24:00,108 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_tisch/set
abstraction | 2025-11-18 10:24:00,127 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f31b
abstraction | 2025-11-18 10:24:00,145 - __main__ - INFO - Subscribed to abstract SET: home/light/sportlicht_regal/set
abstraction | 2025-11-18 10:24:00,163 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b8be2409f569
abstraction | 2025-11-18 10:24:00,183 - __main__ - INFO - Subscribed to abstract SET: home/light/licht_flur_oben_am_spiegel/set
abstraction | 2025-11-18 10:24:00,201 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x842e14fffefe4ba4
abstraction | 2025-11-18 10:24:00,218 - __main__ - INFO - Subscribed to abstract SET: home/light/experimentlabtest/set
abstraction | 2025-11-18 10:24:00,237 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000195038
abstraction | 2025-11-18 10:24:00,255 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wolfgang/set
abstraction | 2025-11-18 10:24:00,271 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x540f57fffe7e3cfe
abstraction | 2025-11-18 10:24:00,292 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_kueche/set
abstraction | 2025-11-18 10:24:00,313 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x94deb8fffe2e5c06
abstraction | 2025-11-18 10:24:00,334 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_schlafzimmer/set
abstraction | 2025-11-18 10:24:00,356 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/42/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,377 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_esszimmer/set
abstraction | 2025-11-18 10:24:00,398 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/45/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,420 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_wohnzimmer/set
abstraction | 2025-11-18 10:24:00,440 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/46/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,457 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_patty/set
abstraction | 2025-11-18 10:24:00,475 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/39/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,493 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_oben/set
abstraction | 2025-11-18 10:24:00,509 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/41/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,530 - __main__ - INFO - Subscribed to abstract SET: home/thermostat/thermostat_bad_unten/set
abstraction | 2025-11-18 10:24:00,551 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/48/1/SET_TEMPERATURE
abstraction | 2025-11-18 10:24:00,572 - __main__ - INFO - Subscribed to abstract SET: home/relay/sterne_wohnzimmer/set
abstraction | 2025-11-18 10:24:00,593 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0xf0d1b80000155fc2
abstraction | 2025-11-18 10:24:00,593 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_schlafzimmer_strasse
abstraction | 2025-11-18 10:24:00,614 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/52/1/STATE
abstraction | 2025-11-18 10:24:00,614 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_rechts
abstraction | 2025-11-18 10:24:00,630 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/26/1/STATE
abstraction | 2025-11-18 10:24:00,630 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_esszimmer_strasse_links
abstraction | 2025-11-18 10:24:00,647 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/27/1/STATE
abstraction | 2025-11-18 10:24:00,647 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_rechts
abstraction | 2025-11-18 10:24:00,668 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/28/1/STATE
abstraction | 2025-11-18 10:24:00,668 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wohnzimmer_garten_links
abstraction | 2025-11-18 10:24:00,691 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/29/1/STATE
abstraction | 2025-11-18 10:24:00,691 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_fenster
abstraction | 2025-11-18 10:24:00,708 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332785
abstraction | 2025-11-18 10:24:00,708 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_garten_tuer
abstraction | 2025-11-18 10:24:00,728 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b332788
abstraction | 2025-11-18 10:24:00,728 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_rechts
abstraction | 2025-11-18 10:24:00,747 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b151803
abstraction | 2025-11-18 10:24:00,747 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_kueche_strasse_links
abstraction | 2025-11-18 10:24:00,767 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b331d0b
abstraction | 2025-11-18 10:24:00,767 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_rechts
abstraction | 2025-11-18 10:24:00,784 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/18/1/STATE
abstraction | 2025-11-18 10:24:00,784 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_garten_links
abstraction | 2025-11-18 10:24:00,802 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/22/1/STATE
abstraction | 2025-11-18 10:24:00,802 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_patty_strasse
abstraction | 2025-11-18 10:24:00,821 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000af457cf
abstraction | 2025-11-18 10:24:00,821 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_wolfgang_garten
abstraction | 2025-11-18 10:24:00,838 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b3328da
abstraction | 2025-11-18 10:24:00,838 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_oben_strasse
abstraction | 2025-11-18 10:24:00,855 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d008b333aec
abstraction | 2025-11-18 10:24:00,855 - __main__ - INFO - Skipping SET subscription for read-only device: kontakt_bad_unten_strasse
api | INFO: 172.16.3.98:51428 - "GET /realtime HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:24:00,872 - __main__ - INFO - Subscribed to vendor STATE: homegear/instance1/plain/44/1/STATE
abstraction | 2025-11-18 10:24:00,872 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_schlafzimmer
abstraction | 2025-11-18 10:24:00,891 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00043292dc
abstraction | 2025-11-18 10:24:00,891 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_wohnzimmer
api | INFO: 172.16.3.98:51429 - "GET /realtime HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:24:00,907 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0008975707
abstraction | 2025-11-18 10:24:00,907 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_kueche
abstraction | 2025-11-18 10:24:00,925 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00083299bb
abstraction | 2025-11-18 10:24:00,925 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_patty
abstraction | 2025-11-18 10:24:00,947 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0003f052b7
abstraction | 2025-11-18 10:24:00,947 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_arbeitszimmer_wolfgang
abstraction | 2025-11-18 10:24:00,969 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000543fb99
abstraction | 2025-11-18 10:24:00,969 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_oben
abstraction | 2025-11-18 10:24:00,986 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e8987
abstraction | 2025-11-18 10:24:00,986 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_bad_unten
abstraction | 2025-11-18 10:24:01,004 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d00093e662a
abstraction | 2025-11-18 10:24:01,004 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_flur
abstraction | 2025-11-18 10:24:01,022 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000836ccc6
abstraction | 2025-11-18 10:24:01,022 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_waschkueche
abstraction | 2025-11-18 10:24:01,038 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d000449f3bc
abstraction | 2025-11-18 10:24:01,038 - __main__ - INFO - Skipping SET subscription for read-only device: sensor_sportzimmer
abstraction | 2025-11-18 10:24:01,058 - __main__ - INFO - Subscribed to vendor STATE: zigbee2mqtt/0x00158d0009421422
abstraction | 2025-11-18 10:24:01,074 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_spuele_kueche/set
abstraction | 2025-11-18 10:24:01,090 - __main__ - INFO - Subscribed to vendor STATE: shellies/LightKitchenSink/relay/0
abstraction | 2025-11-18 10:24:01,107 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_schrank_esszimmer/set
abstraction | 2025-11-18 10:24:01,122 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankesszimmer/relay/0
abstraction | 2025-11-18 10:24:01,139 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_regal_wohnzimmer/set
abstraction | 2025-11-18 10:24:01,155 - __main__ - INFO - Subscribed to vendor STATE: shellies/wohnzimmer-regal/relay/0
abstraction | 2025-11-18 10:24:01,172 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_flur_schrank/set
abstraction | 2025-11-18 10:24:01,189 - __main__ - INFO - Subscribed to vendor STATE: shellies/schrankflur/relay/0
abstraction | 2025-11-18 10:24:01,205 - __main__ - INFO - Subscribed to abstract SET: home/relay/licht_terasse/set
abstraction | 2025-11-18 10:24:01,222 - __main__ - INFO - Subscribed to vendor STATE: shellies/lichtterasse/relay/0
abstraction | 2025-11-18 10:24:01,222 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=21
abstraction | 2025-11-18 10:24:01,222 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 21.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,222 - __main__ - INFO - ← abstract STATE thermostat_schlafzimmer: home/thermostat/thermostat_schlafzimmer/state → {"target": 21.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,243 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_schlafzimmer", "payload": {"target": 21.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.243641+00:00"}
abstraction | 2025-11-18 10:24:01,260 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 10:24:01,260 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,260 - __main__ - INFO - ← abstract STATE thermostat_esszimmer: home/thermostat/thermostat_esszimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,280 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_esszimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.280285+00:00"}
abstraction | 2025-11-18 10:24:01,296 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=15
abstraction | 2025-11-18 10:24:01,296 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 15.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,296 - __main__ - INFO - ← abstract STATE thermostat_wohnzimmer: home/thermostat/thermostat_wohnzimmer/state → {"target": 15.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,317 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_wohnzimmer", "payload": {"target": 15.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.317708+00:00"}
abstraction | 2025-11-18 10:24:01,334 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=22
abstraction | 2025-11-18 10:24:01,334 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 22.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,334 - __main__ - INFO - ← abstract STATE thermostat_patty: home/thermostat/thermostat_patty/state → {"target": 22.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,357 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_patty", "payload": {"target": 22.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.357082+00:00"}
abstraction | 2025-11-18 10:24:01,373 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=20
abstraction | 2025-11-18 10:24:01,373 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 20.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,373 - __main__ - INFO - ← abstract STATE thermostat_bad_oben: home/thermostat/thermostat_bad_oben/state → {"target": 20.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,395 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_oben", "payload": {"target": 20.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.395470+00:00"}
abstraction | 2025-11-18 10:24:01,411 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=thermostat, tech=max, payload=5
abstraction | 2025-11-18 10:24:01,411 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=thermostat, tech=max, payload={'target': 5.0, 'mode': 'heat'}
abstraction | 2025-11-18 10:24:01,411 - __main__ - INFO - ← abstract STATE thermostat_bad_unten: home/thermostat/thermostat_bad_unten/state → {"target": 5.0, "mode": "heat"}
abstraction | 2025-11-18 10:24:01,431 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "thermostat_bad_unten", "payload": {"target": 5.0, "mode": "heat"}, "ts": "2025-11-18T10:24:01.431068+00:00"}
abstraction | 2025-11-18 10:24:01,448 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,448 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,449 - __main__ - INFO - ← abstract STATE kontakt_schlafzimmer_strasse: home/contact/kontakt_schlafzimmer_strasse/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,472 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_schlafzimmer_strasse", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.472456+00:00"}
abstraction | 2025-11-18 10:24:01,491 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,491 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,491 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_rechts: home/contact/kontakt_esszimmer_strasse_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,733 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.733873+00:00"}
abstraction | 2025-11-18 10:24:01,750 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,750 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,750 - __main__ - INFO - ← abstract STATE kontakt_esszimmer_strasse_links: home/contact/kontakt_esszimmer_strasse_links/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,771 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_esszimmer_strasse_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.771380+00:00"}
abstraction | 2025-11-18 10:24:01,788 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,788 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,788 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_rechts: home/contact/kontakt_wohnzimmer_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,808 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.808516+00:00"}
abstraction | 2025-11-18 10:24:01,825 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,825 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,825 - __main__ - INFO - ← abstract STATE kontakt_wohnzimmer_garten_links: home/contact/kontakt_wohnzimmer_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,844 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_wohnzimmer_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.844046+00:00"}
abstraction | 2025-11-18 10:24:01,860 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,861 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,861 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_rechts: home/contact/kontakt_patty_garten_rechts/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,881 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_rechts", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.881922+00:00"}
abstraction | 2025-11-18 10:24:01,898 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=false
abstraction | 2025-11-18 10:24:01,898 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'closed'}
abstraction | 2025-11-18 10:24:01,898 - __main__ - INFO - ← abstract STATE kontakt_patty_garten_links: home/contact/kontakt_patty_garten_links/state → {"contact": "closed"}
abstraction | 2025-11-18 10:24:01,922 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_patty_garten_links", "payload": {"contact": "closed"}, "ts": "2025-11-18T10:24:01.922254+00:00"}
abstraction | 2025-11-18 10:24:01,940 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=contact, tech=max, payload=true
abstraction | 2025-11-18 10:24:01,940 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=contact, tech=max, payload={'contact': 'open'}
abstraction | 2025-11-18 10:24:01,940 - __main__ - INFO - ← abstract STATE kontakt_bad_unten_strasse: home/contact/kontakt_bad_unten_strasse/state → {"contact": "open"}
abstraction | 2025-11-18 10:24:01,959 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "kontakt_bad_unten_strasse", "payload": {"contact": "open"}, "ts": "2025-11-18T10:24:01.959678+00:00"}
abstraction | 2025-11-18 10:24:02,354 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:02,354 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:02,354 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:24:02,373 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:02.373461+00:00"}
ui | INFO: 127.0.0.1:49192 - "GET /health HTTP/1.1" 200 OK
api | INFO: 172.16.3.98:51450 - "GET /realtime HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:24:07,440 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:07,440 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:07,441 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:07,459 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:07.459082+00:00"}
abstraction | 2025-11-18 10:24:08,817 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.37, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,817 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.37, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,817 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.37, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}
abstraction | 2025-11-18 10:24:08,835 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.37, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}, "ts": "2025-11-18T10:24:08.835488+00:00"}
abstraction | 2025-11-18 10:24:08,852 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,852 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1004.2, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,852 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}
abstraction | 2025-11-18 10:24:08,870 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1004.2, "temperature": 22.16, "voltage": 3015}, "ts": "2025-11-18T10:24:08.870674+00:00"}
abstraction | 2025-11-18 10:24:08,887 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1003.9, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,887 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=temp_humidity_sensor, tech=zigbee2mqtt, payload={'battery': 100, 'humidity': 54.22, 'linkquality': 83, 'power_outage_count': 38416, 'pressure': 1003.9, 'temperature': 22.16, 'voltage': 3015}
abstraction | 2025-11-18 10:24:08,887 - __main__ - INFO - ← abstract STATE sensor_arbeitszimmer_patty: home/temp_humidity/sensor_arbeitszimmer_patty/state → {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1003.9, "temperature": 22.16, "voltage": 3015}
abstraction | 2025-11-18 10:24:08,907 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "sensor_arbeitszimmer_patty", "payload": {"battery": 100, "humidity": 54.22, "linkquality": 83, "power_outage_count": 38416, "pressure": 1003.9, "temperature": 22.16, "voltage": 3015}, "ts": "2025-11-18T10:24:08.907729+00:00"}
abstraction | 2025-11-18 10:24:10,178 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:24:10,178 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:24:10,178 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:24:10,196 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:24:10.196762+00:00"}
abstraction | 2025-11-18 10:24:17,815 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:17,815 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:17,815 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:17,834 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:17.834042+00:00"}
abstraction | 2025-11-18 10:24:32,370 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:32,370 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:32,370 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:24:32,405 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:32.405754+00:00"}
ui | INFO: 127.0.0.1:39276 - "GET /health HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:24:37,447 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:37,447 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:37,447 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:37,465 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:37.465220+00:00"}
abstraction | 2025-11-18 10:24:40,188 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:24:40,189 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:24:40,189 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:24:40,207 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:24:40.207222+00:00"}
abstraction | 2025-11-18 10:24:47,833 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:24:47,833 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:24:47,833 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:24:47,868 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:24:47.868787+00:00"}
abstraction | 2025-11-18 10:25:02,363 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:02,363 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:02,363 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:25:02,381 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:02.381792+00:00"}
ui | INFO: 127.0.0.1:37108 - "GET /health HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:25:07,447 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:07,448 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:07,448 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:07,465 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:07.465566+00:00"}
abstraction | 2025-11-18 10:25:10,185 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:25:10,185 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:25:10,185 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:25:10,202 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:25:10.202372+00:00"}
abstraction | 2025-11-18 10:25:17,820 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:17,820 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:17,820 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:17,838 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:17.838140+00:00"}
api | INFO: 172.16.3.98:51763 - "GET /docs HTTP/1.1" 200 OK
api | /usr/local/lib/python3.14/site-packages/fastapi/openapi/utils.py:207: UserWarning: Duplicate Operation ID get_device_layout_devices__device_id__layout_get for function get_device_layout at /app/apps/api/main.py
api | warnings.warn(message, stacklevel=1)
api | /usr/local/lib/python3.14/site-packages/fastapi/openapi/utils.py:207: UserWarning: Duplicate Operation ID get_device_state_devices__device_id__state_get for function get_device_state at /app/apps/api/main.py
api | warnings.warn(message, stacklevel=1)
api | INFO: 172.16.3.98:51763 - "GET /openapi.json HTTP/1.1" 200 OK
api | INFO: 172.16.3.98:51763 - "GET /devices/states HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:25:32,361 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:32,361 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:32,361 - __main__ - INFO - ← abstract STATE licht_terasse: home/relay/licht_terasse/state → {"power": "off"}
abstraction | 2025-11-18 10:25:32,379 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_terasse", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:32.379286+00:00"}
ui | INFO: 127.0.0.1:41510 - "GET /health HTTP/1.1" 200 OK
abstraction | 2025-11-18 10:25:37,455 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:37,455 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:37,455 - __main__ - INFO - ← abstract STATE licht_regal_wohnzimmer: home/relay/licht_regal_wohnzimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:37,473 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_regal_wohnzimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:37.473171+00:00"}
abstraction | 2025-11-18 10:25:40,193 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=on
abstraction | 2025-11-18 10:25:40,194 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'on'}
abstraction | 2025-11-18 10:25:40,194 - __main__ - INFO - ← abstract STATE licht_spuele_kueche: home/relay/licht_spuele_kueche/state → {"power": "on"}
abstraction | 2025-11-18 10:25:40,211 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_spuele_kueche", "payload": {"power": "on"}, "ts": "2025-11-18T10:25:40.211493+00:00"}
abstraction | 2025-11-18 10:25:47,821 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract IN: type=relay, tech=shelly, payload=off
abstraction | 2025-11-18 10:25:47,821 - apps.abstraction.transformation - DEBUG - transform_vendor_to_abstract OUT: type=relay, tech=shelly, payload={'power': 'off'}
abstraction | 2025-11-18 10:25:47,821 - __main__ - INFO - ← abstract STATE licht_schrank_esszimmer: home/relay/licht_schrank_esszimmer/state → {"power": "off"}
abstraction | 2025-11-18 10:25:47,838 - __main__ - INFO - ← Redis PUBLISH ui:updates → {"type": "state", "device_id": "licht_schrank_esszimmer", "payload": {"power": "off"}, "ts": "2025-11-18T10:25:47.838508+00:00"}

View File

@@ -0,0 +1,73 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: abstraction
labels:
app: abstraction
component: home-automation
spec:
replicas: 1
selector:
matchLabels:
app: abstraction
template:
metadata:
annotations:
reloader.stakater.com/auto: "true"
configmap.reloader.stakater.com/reload: "home-automation-environment,home-automation-config"
labels:
app: abstraction
component: home-automation
spec:
containers:
- name: abstraction
image: %IMAGE%
env:
- name: MQTT_BROKER
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_MQTT_BROKER
- name: MQTT_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_MQTT_PORT
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_HOST
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_PORT
- name: REDIS_DB
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_DB
volumeMounts:
- name: config-volume
mountPath: /app/config
readOnly: true
livenessProbe:
exec:
command:
- /bin/sh
- -c
- "ps aux | grep -v grep | grep python"
initialDelaySeconds: 30
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
volumes:
- name: config-volume
configMap:
name: home-automation-config

View File

@@ -0,0 +1,102 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: api
namespace: homea2
labels:
app: api
component: home-automation
spec:
replicas: 1
selector:
matchLabels:
app: api
template:
metadata:
annotations:
reloader.stakater.com/auto: "true"
configmap.reloader.stakater.com/reload: "home-automation-environment,home-automation-config"
labels:
app: api
component: home-automation
spec:
containers:
- name: api
image: %IMAGE%
ports:
- containerPort: 8001
name: http
env:
- name: MQTT_BROKER
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_MQTT_BROKER
- name: MQTT_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_MQTT_PORT
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_HOST
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_PORT
- name: REDIS_DB
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_DB
- name: REDIS_CHANNEL
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: API_REDIS_CHANNEL
volumeMounts:
- name: config-volume
mountPath: /app/config
readOnly: true
livenessProbe:
httpGet:
path: /health
port: 8001
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /health
port: 8001
initialDelaySeconds: 5
periodSeconds: 5
resources:
limits:
cpu: 1000m
memory: 1Gi
requests:
cpu: 200m
memory: 256Mi
volumes:
- name: config-volume
configMap:
name: home-automation-config
---
apiVersion: v1
kind: Service
metadata:
name: api
labels:
app: api
component: home-automation
spec:
selector:
app: api
ports:
- port: 80
targetPort: 8001
name: http
type: ClusterIP

23
deployment/configmap.yaml Normal file
View File

@@ -0,0 +1,23 @@
apiVersion: v1
kind: ConfigMap
metadata:
name: home-automation-environment
namespace: homea2
data:
# Default environment variables
SHARED_MQTT_BROKER: "emqx01-anonymous-cluster-internal.broker.svc.cluster.local"
SHARED_MQTT_PORT: "1883"
SHARED_REDIS_HOST: "redis-master.redis.svc.cluster.local"
SHARED_REDIS_PORT: "6379"
SHARED_REDIS_DB: "8"
# UI specific environment variables
UI_UI_PORT: "8002"
UI_API_BASE: "https://homea2-api.hottis.de"
UI_BASE_PATH: "/"
# API specific environment variables
API_REDIS_CHANNEL: "ui:updates"
# Rules specific environment variables
RULES_RULES_CONFIG: "/app/config/rules.yaml"

View File

@@ -0,0 +1,78 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: rules
labels:
app: rules
component: home-automation
spec:
replicas: 1
selector:
matchLabels:
app: rules
template:
metadata:
annotations:
reloader.stakater.com/auto: "true"
configmap.reloader.stakater.com/reload: "home-automation-environment,home-automation-config"
labels:
app: rules
component: home-automation
spec:
containers:
- name: rules
image: %IMAGE%
env:
- name: MQTT_BROKER
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_MQTT_BROKER
- name: MQTT_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_MQTT_PORT
- name: REDIS_HOST
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_HOST
- name: REDIS_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_PORT
- name: REDIS_DB
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: SHARED_REDIS_DB
- name: RULES_CONFIG
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: RULES_RULES_CONFIG
volumeMounts:
- name: config-volume
mountPath: /app/config
readOnly: true
livenessProbe:
exec:
command:
- /bin/sh
- -c
- "ps aux | grep -v grep | grep python"
initialDelaySeconds: 30
periodSeconds: 10
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
volumes:
- name: config-volume
configMap:
name: home-automation-config

View File

@@ -0,0 +1,79 @@
apiVersion: apps/v1
kind: Deployment
metadata:
name: ui
namespace: homea2
labels:
app: ui
component: home-automation
spec:
replicas: 1
selector:
matchLabels:
app: ui
template:
metadata:
annotations:
reloader.stakater.com/auto: "true"
configmap.reloader.stakater.com/reload: "home-automation-environment"
labels:
app: ui
component: home-automation
spec:
containers:
- name: ui
image: %IMAGE%
ports:
- containerPort: 8002
name: http
env:
- name: UI_PORT
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: UI_UI_PORT
- name: API_BASE
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: UI_API_BASE
- name: BASE_PATH
valueFrom:
configMapKeyRef:
name: home-automation-environment
key: UI_BASE_PATH
livenessProbe:
httpGet:
path: /
port: 8002
initialDelaySeconds: 30
periodSeconds: 10
readinessProbe:
httpGet:
path: /
port: 8002
initialDelaySeconds: 5
periodSeconds: 5
resources:
limits:
cpu: 500m
memory: 512Mi
requests:
cpu: 100m
memory: 128Mi
---
apiVersion: v1
kind: Service
metadata:
name: ui
labels:
app: ui
component: home-automation
spec:
selector:
app: ui
ports:
- port: 80
targetPort: 8002
name: http
type: ClusterIP

View File

@@ -1,190 +0,0 @@
# Device Simulator
Unified MQTT device simulator für das Home Automation System.
## Übersicht
Dieser Simulator ersetzt die einzelnen Simulatoren (`sim_test_lampe.py`, `sim_thermo.py`) und vereint alle Device-Typen in einer einzigen Anwendung.
## Unterstützte Geräte
### Lampen (3 Geräte)
- `test_lampe_1` - Mit Power und Brightness
- `test_lampe_2` - Mit Power und Brightness
- `test_lampe_3` - Mit Power und Brightness
**Features:**
- `power`: "on" oder "off"
- `brightness`: 0-100
### Thermostaten (1 Gerät)
- `test_thermo_1` - Vollständiger Thermostat mit Temperatur-Simulation
**Features:**
- `mode`: "off", "heat", oder "auto"
- `target`: Soll-Temperatur (5.0-30.0°C)
- `current`: Ist-Temperatur (wird simuliert)
- `battery`: Batteriestand (90%)
- `window_open`: Fensterstatus (false)
**Temperatur-Simulation:**
- Alle 5 Sekunden wird die Ist-Temperatur angepasst
- **HEAT/AUTO Mode**: Drift zu `target` (+0.2°C pro Intervall)
- **OFF Mode**: Drift zu Ambient-Temperatur 18°C (-0.2°C pro Intervall)
## MQTT-Konfiguration
- **Broker**: 172.16.2.16:1883 (konfigurierbar via ENV)
- **QoS**: 1 für alle Publishes
- **Retained**: Ja für alle State-Messages
- **Client ID**: device_simulator
### Topics
Für jedes Gerät:
- Subscribe: `vendor/{device_id}/set` (QoS 1)
- Publish: `vendor/{device_id}/state` (QoS 1, retained)
## Verwendung
### Starten
```bash
poetry run python tools/device_simulator.py
```
Oder im Hintergrund:
```bash
poetry run python tools/device_simulator.py > /tmp/simulator.log 2>&1 &
```
### Umgebungsvariablen
```bash
export MQTT_BROKER="172.16.2.16" # MQTT Broker Host
export MQTT_PORT="1883" # MQTT Broker Port
```
## Testen
Ein umfassendes Test-Skript ist verfügbar:
```bash
./tools/test_device_simulator.sh
```
Das Test-Skript:
1. Stoppt alle laufenden Services
2. Startet Abstraction Layer, API und Simulator
3. Testet alle Lampen-Operationen
4. Testet alle Thermostat-Operationen
5. Verifiziert MQTT State Messages
6. Zeigt Simulator-Logs
## Beispiele
### Lampe einschalten
```bash
curl -X POST http://localhost:8001/devices/test_lampe_1/set \
-H "Content-Type: application/json" \
-d '{"type":"light","payload":{"power":"on"}}'
```
### Helligkeit setzen
```bash
curl -X POST http://localhost:8001/devices/test_lampe_1/set \
-H "Content-Type: application/json" \
-d '{"type":"light","payload":{"brightness":75}}'
```
### Thermostat Mode setzen
```bash
curl -X POST http://localhost:8001/devices/test_thermo_1/set \
-H "Content-Type: application/json" \
-d '{"type":"thermostat","payload":{"mode":"heat","target":22.5}}'
```
### State abfragen via MQTT
```bash
# Lampe
mosquitto_sub -h 172.16.2.16 -t 'vendor/test_lampe_1/state' -C 1
# Thermostat
mosquitto_sub -h 172.16.2.16 -t 'vendor/test_thermo_1/state' -C 1
```
## Architektur
```
Browser/API
↓ POST /devices/{id}/set
API Server (Port 8001)
↓ MQTT: home/{type}/{id}/set
Abstraction Layer
↓ MQTT: vendor/{id}/set
Device Simulator
↓ MQTT: vendor/{id}/state (retained)
Abstraction Layer
↓ MQTT: home/{type}/{id}/state (retained)
↓ Redis Pub/Sub: ui:updates
UI / Dashboard
```
## Logs
Der Simulator loggt alle Aktivitäten:
- Startup und MQTT-Verbindung
- Empfangene SET-Commands
- State-Änderungen
- Temperature-Drift (Thermostaten)
- Publizierte State-Messages
Log-Level: INFO
## Troubleshooting
### Simulator startet nicht
```bash
# Prüfe ob Port bereits belegt
lsof -ti:1883
# Prüfe MQTT Broker
mosquitto_sub -h 172.16.2.16 -t '#' -C 1
```
### Keine State-Updates
```bash
# Prüfe Simulator-Log
tail -f /tmp/simulator.log
# Prüfe MQTT Topics
mosquitto_sub -h 172.16.2.16 -t 'vendor/#' -v
```
### API antwortet nicht
```bash
# Prüfe ob API läuft
curl http://localhost:8001/devices
# Prüfe API-Log
tail -f /tmp/api.log
```
## Integration
Der Simulator integriert sich nahtlos in das Home Automation System:
1. **Abstraction Layer** empfängt Commands und sendet sie an Simulator
2. **Simulator** reagiert und publiziert neuen State
3. **Abstraction Layer** empfängt State und publiziert zu Redis
4. **UI** empfängt Updates via SSE und aktualisiert Dashboard
Alle Komponenten arbeiten vollständig asynchron über MQTT.

73
tools/create-client-cert.sh Executable file
View File

@@ -0,0 +1,73 @@
#!/bin/bash
set -e
# Check if client name is provided
if [ $# -eq 0 ]; then
echo "Usage: $0 <client-name>"
echo "Example: $0 john.doe"
exit 1
fi
CLIENT_NAME="$1"
# Check if CA exists
if [ ! -f "ca/ca.crt" ] || [ ! -f "ca/ca.key" ]; then
echo "Error: CA not found. Please run setup-ca.sh first."
exit 1
fi
echo "=== Creating Client Certificate ==="
echo "Client Name: $CLIENT_NAME"
# Create client directory
mkdir -p clients/$CLIENT_NAME
# Generate client private key
echo "Generating client private key..."
openssl genrsa -out clients/$CLIENT_NAME/$CLIENT_NAME.key 2048
# Generate client certificate signing request
echo "Generating client certificate signing request..."
openssl req -new -key clients/$CLIENT_NAME/$CLIENT_NAME.key \
-out clients/$CLIENT_NAME/$CLIENT_NAME.csr \
-subj "/DC=de/DC=hottis/DC=homea2/CN=$CLIENT_NAME"
# Sign the client certificate
echo "Signing client certificate..."
openssl x509 -req -in clients/$CLIENT_NAME/$CLIENT_NAME.csr \
-CA ca/ca.crt -CAkey ca/ca.key -CAcreateserial \
-out clients/$CLIENT_NAME/$CLIENT_NAME.crt \
-days 365 -sha256
# Create PKCS#12 bundle
echo "Creating PKCS#12 bundle..."
openssl pkcs12 -export \
-out clients/$CLIENT_NAME/$CLIENT_NAME.p12 \
-inkey clients/$CLIENT_NAME/$CLIENT_NAME.key \
-in clients/$CLIENT_NAME/$CLIENT_NAME.crt \
-certfile ca/ca.crt \
-name "$CLIENT_NAME Home Automation Client" \
-passout pass:
# Set appropriate permissions
chmod 400 clients/$CLIENT_NAME/$CLIENT_NAME.key
chmod 644 clients/$CLIENT_NAME/$CLIENT_NAME.crt
chmod 644 clients/$CLIENT_NAME/$CLIENT_NAME.p12
# Verify client certificate
echo "Verifying client certificate..."
openssl x509 -noout -text -in clients/$CLIENT_NAME/$CLIENT_NAME.crt
echo ""
echo "=== Client Certificate Created ==="
echo "Client Certificate: clients/$CLIENT_NAME/$CLIENT_NAME.crt"
echo "Client Private Key: clients/$CLIENT_NAME/$CLIENT_NAME.key"
echo "PKCS#12 Bundle: clients/$CLIENT_NAME/$CLIENT_NAME.p12"
echo ""
echo "Installation Instructions:"
echo "1. Import the PKCS#12 file into your browser/application"
echo "2. The bundle contains both the client certificate and CA certificate"
echo "3. No password is set for the PKCS#12 file (you can add one by modifying the -passout parameter)"
echo ""
echo "For testing with curl:"
echo "curl --cert clients/$CLIENT_NAME/$CLIENT_NAME.crt --key clients/$CLIENT_NAME/$CLIENT_NAME.key --cacert ca/ca.crt https://homea2.hottis.de/"

View File

@@ -1,291 +0,0 @@
#!/usr/bin/env python3
"""
Unified Device Simulator for Home Automation.
Simulates multiple device types:
- Lights (test_lampe_1, test_lampe_2, test_lampe_3)
- Thermostats (test_thermo_1)
Each device:
- Subscribes to vendor/{device_id}/set
- Maintains local state
- Publishes state changes to vendor/{device_id}/state (retained, QoS 1)
- Thermostats simulate temperature drift every 5 seconds
"""
import asyncio
import json
import logging
import os
import signal
import sys
import uuid
from datetime import datetime
from typing import Dict, Any
from aiomqtt import Client, MqttError
# Configure logging
logging.basicConfig(
level=logging.INFO,
format="%(asctime)s - %(name)s - %(levelname)s - %(message)s"
)
logger = logging.getLogger(__name__)
# Configuration
BROKER_HOST = os.getenv("MQTT_BROKER", "172.16.2.16")
BROKER_PORT = int(os.getenv("MQTT_PORT", "1883"))
DRIFT_INTERVAL = 5 # seconds for thermostat temperature drift
# Device configurations
LIGHT_DEVICES = ["test_lampe_1", "test_lampe_2", "test_lampe_3"]
THERMOSTAT_DEVICES = ["test_thermo_1"]
class DeviceSimulator:
"""Unified simulator for lights and thermostats."""
def __init__(self):
# Light states
self.light_states: Dict[str, Dict[str, Any]] = {
"test_lampe_1": {"power": "off", "brightness": 50},
"test_lampe_2": {"power": "off", "brightness": 50},
"test_lampe_3": {"power": "off", "brightness": 50}
}
# Thermostat states
self.thermostat_states: Dict[str, Dict[str, Any]] = {
"test_thermo_1": {
"mode": "auto",
"target": 21.0,
"current": 20.5,
"battery": 90,
"window_open": False
}
}
self.client = None
self.running = True
self.drift_task = None
async def publish_state(self, device_id: str, device_type: str):
"""Publish device state to MQTT (retained, QoS 1)."""
if not self.client:
return
if device_type == "light":
state = self.light_states.get(device_id)
elif device_type == "thermostat":
state = self.thermostat_states.get(device_id)
else:
logger.warning(f"Unknown device type: {device_type}")
return
if not state:
logger.warning(f"Unknown device: {device_id}")
return
state_topic = f"vendor/{device_id}/state"
payload = json.dumps(state)
await self.client.publish(
state_topic,
payload=payload,
qos=1,
retain=True
)
logger.info(f"[{device_id}] Published state: {payload}")
async def handle_light_set(self, device_id: str, payload: dict):
"""Handle SET command for light device."""
if device_id not in self.light_states:
logger.warning(f"Unknown light device: {device_id}")
return
state = self.light_states[device_id]
updated = False
if "power" in payload:
old_power = state["power"]
state["power"] = payload["power"]
if old_power != state["power"]:
updated = True
logger.info(f"[{device_id}] Power: {old_power} -> {state['power']}")
if "brightness" in payload:
old_brightness = state["brightness"]
state["brightness"] = int(payload["brightness"])
if old_brightness != state["brightness"]:
updated = True
logger.info(f"[{device_id}] Brightness: {old_brightness} -> {state['brightness']}")
if updated:
await self.publish_state(device_id, "light")
async def handle_thermostat_set(self, device_id: str, payload: dict):
"""Handle SET command for thermostat device."""
if device_id not in self.thermostat_states:
logger.warning(f"Unknown thermostat device: {device_id}")
return
state = self.thermostat_states[device_id]
updated = False
if "mode" in payload:
new_mode = payload["mode"]
if new_mode in ["off", "heat", "auto"]:
old_mode = state["mode"]
state["mode"] = new_mode
if old_mode != new_mode:
updated = True
logger.info(f"[{device_id}] Mode: {old_mode} -> {new_mode}")
else:
logger.warning(f"[{device_id}] Invalid mode: {new_mode}")
if "target" in payload:
try:
new_target = float(payload["target"])
if 5.0 <= new_target <= 30.0:
old_target = state["target"]
state["target"] = new_target
if old_target != new_target:
updated = True
logger.info(f"[{device_id}] Target: {old_target}°C -> {new_target}°C")
else:
logger.warning(f"[{device_id}] Target out of range: {new_target}")
except (ValueError, TypeError):
logger.warning(f"[{device_id}] Invalid target value: {payload['target']}")
if updated:
await self.publish_state(device_id, "thermostat")
def apply_temperature_drift(self, device_id: str):
"""
Simulate temperature drift for thermostat.
Max change: ±0.2°C per interval.
"""
if device_id not in self.thermostat_states:
return
state = self.thermostat_states[device_id]
if state["mode"] == "off":
# Drift towards ambient (18°C)
ambient = 18.0
diff = ambient - state["current"]
else:
# Drift towards target
diff = state["target"] - state["current"]
# Apply max ±0.2°C drift
if abs(diff) < 0.1:
state["current"] = round(state["current"] + diff, 1)
elif diff > 0:
state["current"] = round(state["current"] + 0.2, 1)
else:
state["current"] = round(state["current"] - 0.2, 1)
logger.info(f"[{device_id}] Temperature drift: current={state['current']}°C (target={state['target']}°C, mode={state['mode']})")
async def thermostat_drift_loop(self):
"""Background loop for thermostat temperature drift."""
while self.running:
await asyncio.sleep(DRIFT_INTERVAL)
for device_id in THERMOSTAT_DEVICES:
self.apply_temperature_drift(device_id)
await self.publish_state(device_id, "thermostat")
async def handle_message(self, message):
"""Handle incoming MQTT message."""
try:
# Extract device_id from topic (vendor/{device_id}/set)
topic_parts = message.topic.value.split('/')
if len(topic_parts) != 3 or topic_parts[0] != "vendor" or topic_parts[2] != "set":
logger.warning(f"Unexpected topic format: {message.topic}")
return
device_id = topic_parts[1]
payload = json.loads(message.payload.decode())
logger.info(f"[{device_id}] Received SET: {payload}")
# Determine device type and handle accordingly
if device_id in self.light_states:
await self.handle_light_set(device_id, payload)
elif device_id in self.thermostat_states:
await self.handle_thermostat_set(device_id, payload)
else:
logger.warning(f"Unknown device: {device_id}")
except json.JSONDecodeError as e:
logger.error(f"Invalid JSON: {e}")
except Exception as e:
logger.error(f"Error handling message: {e}")
async def run(self):
"""Main simulator loop."""
# Generate unique client ID to avoid collisions
base_client_id = "device_simulator"
client_suffix = os.environ.get("MQTT_CLIENT_ID_SUFFIX") or uuid.uuid4().hex[:6]
unique_client_id = f"{base_client_id}-{client_suffix}"
try:
async with Client(
hostname=BROKER_HOST,
port=BROKER_PORT,
identifier=unique_client_id
) as client:
self.client = client
logger.info(f"✅ Connected to MQTT broker {BROKER_HOST}:{BROKER_PORT}")
# Publish initial states
for device_id in LIGHT_DEVICES:
await self.publish_state(device_id, "light")
logger.info(f"💡 Light simulator started: {device_id}")
for device_id in THERMOSTAT_DEVICES:
await self.publish_state(device_id, "thermostat")
logger.info(f"🌡️ Thermostat simulator started: {device_id}")
# Subscribe to all SET topics
all_devices = LIGHT_DEVICES + THERMOSTAT_DEVICES
for device_id in all_devices:
set_topic = f"vendor/{device_id}/set"
await client.subscribe(set_topic, qos=1)
logger.info(f"👂 Subscribed to {set_topic}")
# Start thermostat drift loop
self.drift_task = asyncio.create_task(self.thermostat_drift_loop())
# Listen for messages
async for message in client.messages:
await self.handle_message(message)
# Cancel drift loop on disconnect
if self.drift_task:
self.drift_task.cancel()
except MqttError as e:
logger.error(f"❌ MQTT Error: {e}")
except KeyboardInterrupt:
logger.info("⚠️ Interrupted by user")
finally:
self.running = False
if self.drift_task:
self.drift_task.cancel()
logger.info("👋 Simulator stopped")
async def main():
"""Entry point."""
simulator = DeviceSimulator()
await simulator.run()
if __name__ == "__main__":
try:
asyncio.run(main())
except KeyboardInterrupt:
print("\n👋 Simulator terminated")
sys.exit(0)

24
tools/setup-ca.sh Executable file
View File

@@ -0,0 +1,24 @@
#!/bin/bash
set -e
echo "=== mTLS CA Setup ==="
# Create CA directory
mkdir -p ca
# Generate CA private key
echo "Generating CA private key..."
openssl genrsa -out ca/ca.key 2048
# Generate CA certificate
echo "Generating CA certificate..."
openssl req -new -x509 -days 3650 -key ca/ca.key -out ca/ca.crt \
-subj "/DC=de/DC=hottis/DC=homea2/CN=Home Automation CA"
echo ""
echo "=== CA Setup Complete ==="
echo "CA Certificate: ca/ca.crt"
echo "CA Private Key: ca/ca.key"
echo ""
echo "Deploy to Kubernetes:"
echo "kubectl create secret generic mtls-ca-cert --from-file=ca.crt=ca/ca.crt -n homea2"

View File

@@ -1,169 +0,0 @@
"""
Acceptance tests for API Client (fetch_devices).
Tests:
1. API running: fetch_devices() returns list with test_lampe_1, test_lampe_2
2. API down: fetch_devices() returns empty list without crash
"""
import sys
import time
import subprocess
from apps.ui.api_client import fetch_devices
def test_api_running():
"""Test 1: API is running -> fetch_devices() returns devices."""
print("Test 1: API running")
print("-" * 60)
devices = fetch_devices("http://localhost:8001")
if not devices:
print(" ✗ FAILED: Expected devices, got empty list")
return False
print(f" ✓ Received {len(devices)} devices")
# Check structure
for device in devices:
device_id = device.get("device_id")
device_type = device.get("type")
name = device.get("name")
if not device_id:
print(f" ✗ FAILED: Device missing 'device_id': {device}")
return False
if not device_type:
print(f" ✗ FAILED: Device missing 'type': {device}")
return False
if not name:
print(f" ✗ FAILED: Device missing 'name': {device}")
return False
print(f"{device_id} (type={device_type}, name={name})")
# Check for expected devices
device_ids = {d["device_id"] for d in devices}
expected = {"test_lampe_1", "test_lampe_2"}
if not expected.issubset(device_ids):
missing = expected - device_ids
print(f" ✗ FAILED: Missing devices: {missing}")
return False
print(" ✓ All expected devices present")
print()
return True
def test_api_down():
"""Test 2: API is down -> fetch_devices() returns empty list without crash."""
print("Test 2: API down (invalid port)")
print("-" * 60)
try:
devices = fetch_devices("http://localhost:9999")
if devices != []:
print(f" ✗ FAILED: Expected empty list, got {len(devices)} devices")
return False
print(" ✓ Returns empty list without crash")
print()
return True
except Exception as e:
print(f" ✗ FAILED: Exception raised: {e}")
print()
return False
def test_api_timeout():
"""Test 3: API timeout -> fetch_devices() returns empty list."""
print("Test 3: API timeout")
print("-" * 60)
# Use httpbin.org delay endpoint to simulate slow API
try:
start = time.time()
devices = fetch_devices("https://httpbin.org/delay/5") # 5s delay, but 3s timeout
elapsed = time.time() - start
if devices != []:
print(f" ✗ FAILED: Expected empty list, got {len(devices)} devices")
return False
if elapsed >= 4.0:
print(f" ✗ FAILED: Timeout not enforced (took {elapsed:.1f}s)")
return False
print(f" ✓ Returns empty list after timeout ({elapsed:.1f}s)")
print()
return True
except Exception as e:
print(f" ✗ FAILED: Exception raised: {e}")
print()
return False
def main():
"""Run all acceptance tests."""
print("=" * 60)
print("Testing API Client (fetch_devices)")
print("=" * 60)
print()
# Check if API is running
print("Prerequisites: Checking if API is running on port 8001...")
try:
devices = fetch_devices("http://localhost:8001")
if devices:
print(f"✓ API is running ({len(devices)} devices found)")
print()
else:
print("⚠ API might not be running (no devices returned)")
print(" Start API with: poetry run uvicorn apps.api.main:app --port 8001")
print()
except Exception as e:
print(f"✗ Cannot reach API: {e}")
print(" Start API with: poetry run uvicorn apps.api.main:app --port 8001")
print()
sys.exit(1)
results = []
# Test 1: API running
results.append(("API running", test_api_running()))
# Test 2: API down
results.append(("API down", test_api_down()))
# Test 3: Timeout
results.append(("API timeout", test_api_timeout()))
# Summary
print("=" * 60)
passed = sum(1 for _, result in results if result)
total = len(results)
print(f"Results: {passed}/{total} tests passed")
print("=" * 60)
for name, result in results:
status = "" if result else ""
print(f" {status} {name}")
if passed == total:
print()
print("All tests passed!")
sys.exit(0)
else:
print()
print("Some tests failed.")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -1,253 +0,0 @@
#!/usr/bin/env python3
"""Test configuration loader with different YAML formats."""
import sys
import tempfile
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from apps.abstraction.main import load_config, validate_devices
def test_device_id_format():
"""Test YAML with 'device_id' key."""
yaml_content = """version: 1
mqtt:
broker: "172.16.2.16"
port: 1883
client_id: "test"
redis:
url: "redis://localhost:6379/8"
channel: "ui:updates"
devices:
- device_id: test_lampe
type: light
cap_version: "light@1.2.0"
technology: zigbee2mqtt
features:
power: true
topics:
set: "vendor/test_lampe/set"
state: "vendor/test_lampe/state"
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
config = load_config(temp_path)
devices = config.get("devices", [])
validate_devices(devices)
print("✓ Test 1 passed: YAML with 'device_id' loaded successfully")
print(f" Device ID: {devices[0]['device_id']}")
return True
except Exception as e:
print(f"✗ Test 1 failed: {e}")
return False
finally:
temp_path.unlink()
def test_id_format():
"""Test YAML with 'id' key (legacy format)."""
yaml_content = """version: 1
mqtt:
broker: "172.16.2.16"
port: 1883
client_id: "test"
redis:
url: "redis://localhost:6379/8"
channel: "ui:updates"
devices:
- id: test_lampe
type: light
cap_version: "light@1.2.0"
technology: zigbee2mqtt
features:
power: true
topics:
set: "vendor/test_lampe/set"
state: "vendor/test_lampe/state"
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
config = load_config(temp_path)
devices = config.get("devices", [])
validate_devices(devices)
print("✓ Test 2 passed: YAML with 'id' loaded successfully")
print(f" Device ID: {devices[0]['device_id']}")
return True
except Exception as e:
print(f"✗ Test 2 failed: {e}")
return False
finally:
temp_path.unlink()
def test_missing_id():
"""Test YAML without 'id' or 'device_id' key."""
yaml_content = """version: 1
mqtt:
broker: "172.16.2.16"
port: 1883
devices:
- type: light
cap_version: "light@1.2.0"
technology: zigbee2mqtt
topics:
set: "vendor/test_lampe/set"
state: "vendor/test_lampe/state"
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
config = load_config(temp_path)
devices = config.get("devices", [])
validate_devices(devices)
print("✗ Test 3 failed: Should have raised ValueError for missing device_id")
return False
except ValueError as e:
if "requires 'id' or 'device_id'" in str(e):
print(f"✓ Test 3 passed: Correct error for missing device_id")
print(f" Error: {e}")
return True
else:
print(f"✗ Test 3 failed: Wrong error message: {e}")
return False
except Exception as e:
print(f"✗ Test 3 failed: Unexpected error: {e}")
return False
finally:
temp_path.unlink()
def test_missing_topics_set():
"""Test YAML without 'topics.set'."""
yaml_content = """version: 1
mqtt:
broker: "172.16.2.16"
port: 1883
devices:
- device_id: test_lampe
type: light
cap_version: "light@1.2.0"
technology: zigbee2mqtt
topics:
state: "vendor/test_lampe/state"
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
config = load_config(temp_path)
devices = config.get("devices", [])
validate_devices(devices)
print("✗ Test 4 failed: Should have raised ValueError for missing topics.set")
return False
except ValueError as e:
if "missing 'topics.set'" in str(e):
print(f"✓ Test 4 passed: Correct error for missing topics.set")
print(f" Error: {e}")
return True
else:
print(f"✗ Test 4 failed: Wrong error message: {e}")
return False
except Exception as e:
print(f"✗ Test 4 failed: Unexpected error: {e}")
return False
finally:
temp_path.unlink()
def test_missing_topics_state():
"""Test YAML without 'topics.state'."""
yaml_content = """version: 1
mqtt:
broker: "172.16.2.16"
port: 1883
devices:
- device_id: test_lampe
type: light
cap_version: "light@1.2.0"
technology: zigbee2mqtt
topics:
set: "vendor/test_lampe/set"
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
config = load_config(temp_path)
devices = config.get("devices", [])
validate_devices(devices)
print("✗ Test 5 failed: Should have raised ValueError for missing topics.state")
return False
except ValueError as e:
if "missing 'topics.state'" in str(e):
print(f"✓ Test 5 passed: Correct error for missing topics.state")
print(f" Error: {e}")
return True
else:
print(f"✗ Test 5 failed: Wrong error message: {e}")
return False
except Exception as e:
print(f"✗ Test 5 failed: Unexpected error: {e}")
return False
finally:
temp_path.unlink()
def main():
"""Run all tests."""
print("Testing Configuration Loader")
print("=" * 60)
tests = [
test_device_id_format,
test_id_format,
test_missing_id,
test_missing_topics_set,
test_missing_topics_state,
]
results = []
for test in tests:
results.append(test())
print()
print("=" * 60)
passed = sum(results)
total = len(results)
print(f"Results: {passed}/{total} tests passed")
return 0 if all(results) else 1
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1,210 +0,0 @@
"""
Acceptance tests for Dashboard Route.
Tests:
1. GET /dashboard loads without errors
2. Rooms are shown in layout.yaml order
3. Devices within each room are sorted by rank (ascending)
4. GET / redirects to dashboard
"""
import sys
import httpx
def test_dashboard_loads():
"""Test 1: Dashboard loads without errors."""
print("Test 1: Dashboard loads")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
# Check for essential elements
if "Home Automation" not in html:
print(" ✗ FAILED: Missing title 'Home Automation'")
return False
if "Wohnzimmer" not in html:
print(" ✗ FAILED: Missing room 'Wohnzimmer'")
return False
if "Schlafzimmer" not in html:
print(" ✗ FAILED: Missing room 'Schlafzimmer'")
return False
print(" ✓ Dashboard loads successfully")
print(" ✓ Contains expected rooms")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_room_order():
"""Test 2: Rooms appear in layout.yaml order."""
print("Test 2: Room order matches layout.yaml")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
# Find positions of room titles
wohnzimmer_pos = html.find('class="room-title">Wohnzimmer<')
schlafzimmer_pos = html.find('class="room-title">Schlafzimmer<')
if wohnzimmer_pos == -1:
print(" ✗ FAILED: Room 'Wohnzimmer' not found")
return False
if schlafzimmer_pos == -1:
print(" ✗ FAILED: Room 'Schlafzimmer' not found")
return False
# Wohnzimmer should appear before Schlafzimmer
if wohnzimmer_pos > schlafzimmer_pos:
print(" ✗ FAILED: Room order incorrect")
print(f" Wohnzimmer at position {wohnzimmer_pos}")
print(f" Schlafzimmer at position {schlafzimmer_pos}")
return False
print(" ✓ Rooms appear in correct order:")
print(" 1. Wohnzimmer")
print(" 2. Schlafzimmer")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_device_rank_sorting():
"""Test 3: Devices are sorted by rank (ascending)."""
print("Test 3: Devices sorted by rank")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
# In Wohnzimmer: Deckenlampe (rank=5) should come before Stehlampe (rank=10)
deckenlampe_pos = html.find('device-title">Deckenlampe<')
stehlampe_pos = html.find('device-title">Stehlampe<')
if deckenlampe_pos == -1:
print(" ✗ FAILED: Device 'Deckenlampe' not found")
return False
if stehlampe_pos == -1:
print(" ✗ FAILED: Device 'Stehlampe' not found")
return False
if deckenlampe_pos > stehlampe_pos:
print(" ✗ FAILED: Devices not sorted by rank")
print(f" Deckenlampe (rank=5) at position {deckenlampe_pos}")
print(f" Stehlampe (rank=10) at position {stehlampe_pos}")
return False
print(" ✓ Devices sorted by rank (ascending):")
print(" Wohnzimmer: Deckenlampe (rank=5) → Stehlampe (rank=10)")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_root_redirect():
"""Test 4: GET / shows dashboard."""
print("Test 4: Root path (/) shows dashboard")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/", timeout=5.0, follow_redirects=True)
response.raise_for_status()
html = response.text
# Should contain dashboard elements
if "Home Automation" not in html:
print(" ✗ FAILED: Root path doesn't show dashboard")
return False
if "Wohnzimmer" not in html:
print(" ✗ FAILED: Root path missing rooms")
return False
print(" ✓ Root path shows dashboard")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def main():
"""Run all acceptance tests."""
print("=" * 60)
print("Testing Dashboard Route")
print("=" * 60)
print()
# Check if UI is running
print("Prerequisites: Checking if UI is running on port 8002...")
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=3.0)
print("✓ UI is running")
print()
except Exception as e:
print(f"✗ Cannot reach UI: {e}")
print(" Start UI with: poetry run uvicorn apps.ui.main:app --port 8002")
print()
sys.exit(1)
results = []
# Run tests
results.append(("Dashboard loads", test_dashboard_loads()))
results.append(("Room order", test_room_order()))
results.append(("Device rank sorting", test_device_rank_sorting()))
results.append(("Root redirect", test_root_redirect()))
# Summary
print("=" * 60)
passed = sum(1 for _, result in results if result)
total = len(results)
print(f"Results: {passed}/{total} tests passed")
print("=" * 60)
for name, result in results:
status = "" if result else ""
print(f" {status} {name}")
if passed == total:
print()
print("All tests passed!")
sys.exit(0)
else:
print()
print("Some tests failed.")
sys.exit(1)
if __name__ == "__main__":
main()

View File

@@ -1,154 +0,0 @@
#!/bin/bash
# Test script for device_simulator.py
set -e # Exit on error
echo "=== Device Simulator Test Suite ==="
echo ""
# 1. Stop all running services
echo "1. Stoppe alle laufenden Services..."
pkill -f "device_simulator" 2>/dev/null || true
pkill -f "uvicorn apps" 2>/dev/null || true
pkill -f "apps.abstraction" 2>/dev/null || true
sleep 2
echo " ✓ Services gestoppt"
echo ""
# 2. Start services
echo "2. Starte Services..."
poetry run python -m apps.abstraction.main > /tmp/abstraction.log 2>&1 &
ABSTRACTION_PID=$!
echo " Abstraction Layer gestartet (PID: $ABSTRACTION_PID)"
sleep 2
poetry run uvicorn apps.api.main:app --host 0.0.0.0 --port 8001 > /tmp/api.log 2>&1 &
API_PID=$!
echo " API Server gestartet (PID: $API_PID)"
sleep 2
poetry run python tools/device_simulator.py > /tmp/simulator.log 2>&1 &
SIM_PID=$!
echo " Device Simulator gestartet (PID: $SIM_PID)"
sleep 2
echo " ✓ Alle Services laufen"
echo ""
# 3. Test API reachability
echo "3. Teste API Erreichbarkeit..."
if timeout 3 curl -s http://localhost:8001/devices > /dev/null; then
echo " ✓ API antwortet"
else
echo " ✗ API antwortet nicht!"
echo " API Log:"
tail -10 /tmp/api.log
exit 1
fi
echo ""
# 4. Test Light Operations
echo "4. Teste Lampen-Operationen..."
# 4.1 Power On
echo " 4.1 Lampe einschalten (test_lampe_1)..."
RESPONSE=$(timeout 3 curl -s -X POST http://localhost:8001/devices/test_lampe_1/set \
-H "Content-Type: application/json" \
-d '{"type":"light","payload":{"power":"on"}}')
echo " Response: $RESPONSE"
sleep 1
# 4.2 Check state via MQTT
echo " 4.2 Prüfe State via MQTT..."
STATE=$(timeout 2 mosquitto_sub -h 172.16.2.16 -t 'vendor/test_lampe_1/state' -C 1)
echo " State: $STATE"
if echo "$STATE" | grep -q '"power": "on"'; then
echo " ✓ Power ist ON"
else
echo " ✗ Power nicht ON!"
fi
# 4.3 Brightness
echo " 4.3 Helligkeit setzen (75%)..."
RESPONSE=$(timeout 3 curl -s -X POST http://localhost:8001/devices/test_lampe_1/set \
-H "Content-Type: application/json" \
-d '{"type":"light","payload":{"brightness":75}}')
echo " Response: $RESPONSE"
sleep 1
STATE=$(timeout 2 mosquitto_sub -h 172.16.2.16 -t 'vendor/test_lampe_1/state' -C 1)
echo " State: $STATE"
if echo "$STATE" | grep -q '"brightness": 75'; then
echo " ✓ Brightness ist 75"
else
echo " ✗ Brightness nicht 75!"
fi
echo ""
# 5. Test Thermostat Operations
echo "5. Teste Thermostat-Operationen..."
# 5.1 Set mode and target
echo " 5.1 Setze Mode HEAT und Target 22.5°C..."
RESPONSE=$(timeout 3 curl -s -X POST http://localhost:8001/devices/test_thermo_1/set \
-H "Content-Type: application/json" \
-d '{"type":"thermostat","payload":{"mode":"heat","target":22.5}}')
echo " Response: $RESPONSE"
sleep 1
STATE=$(timeout 2 mosquitto_sub -h 172.16.2.16 -t 'vendor/test_thermo_1/state' -C 1)
echo " State: $STATE"
if echo "$STATE" | grep -q '"mode": "heat"' && echo "$STATE" | grep -q '"target": 22.5'; then
echo " ✓ Mode ist HEAT, Target ist 22.5"
else
echo " ✗ Mode oder Target nicht korrekt!"
fi
# 5.2 Wait for temperature drift
echo " 5.2 Warte 6 Sekunden auf Temperature Drift..."
sleep 6
STATE=$(timeout 2 mosquitto_sub -h 172.16.2.16 -t 'vendor/test_thermo_1/state' -C 1)
echo " State: $STATE"
CURRENT=$(echo "$STATE" | grep -o '"current": [0-9.]*' | grep -o '[0-9.]*$')
echo " Current Temperature: ${CURRENT}°C"
if [ -n "$CURRENT" ]; then
echo " ✓ Temperature drift funktioniert"
else
echo " ✗ Temperature drift nicht sichtbar!"
fi
# 5.3 Set mode OFF
echo " 5.3 Setze Mode OFF..."
RESPONSE=$(timeout 3 curl -s -X POST http://localhost:8001/devices/test_thermo_1/set \
-H "Content-Type: application/json" \
-d '{"type":"thermostat","payload":{"mode":"off","target":22.5}}')
echo " Response: $RESPONSE"
sleep 1
STATE=$(timeout 2 mosquitto_sub -h 172.16.2.16 -t 'vendor/test_thermo_1/state' -C 1)
if echo "$STATE" | grep -q '"mode": "off"'; then
echo " ✓ Mode ist OFF"
else
echo " ✗ Mode nicht OFF!"
fi
echo ""
# 6. Check simulator log
echo "6. Simulator Log (letzte 20 Zeilen)..."
tail -20 /tmp/simulator.log
echo ""
# 7. Summary
echo "=== Test Summary ==="
echo "✓ Alle Tests abgeschlossen"
echo ""
echo "Laufende Prozesse:"
echo " Abstraction: PID $ABSTRACTION_PID"
echo " API: PID $API_PID"
echo " Simulator: PID $SIM_PID"
echo ""
echo "Logs verfügbar in:"
echo " /tmp/abstraction.log"
echo " /tmp/api.log"
echo " /tmp/simulator.log"

View File

@@ -1,288 +0,0 @@
#!/usr/bin/env python3
"""Test layout loader and models."""
import sys
import tempfile
from pathlib import Path
# Add parent directory to path
sys.path.insert(0, str(Path(__file__).parent.parent))
from packages.home_capabilities.layout import DeviceTile, Room, UiLayout, load_layout
def test_device_tile_creation():
"""Test DeviceTile model creation."""
print("Test 1: DeviceTile Creation")
tile = DeviceTile(
device_id="test_lamp",
title="Test Lamp",
icon="💡",
rank=10
)
assert tile.device_id == "test_lamp"
assert tile.title == "Test Lamp"
assert tile.icon == "💡"
assert tile.rank == 10
print(" ✓ DeviceTile created successfully")
return True
def test_room_creation():
"""Test Room model creation."""
print("\nTest 2: Room Creation")
tiles = [
DeviceTile(device_id="lamp1", title="Lamp 1", icon="💡", rank=1),
DeviceTile(device_id="lamp2", title="Lamp 2", icon="💡", rank=2)
]
room = Room(name="Living Room", devices=tiles)
assert room.name == "Living Room"
assert len(room.devices) == 2
assert room.devices[0].rank == 1
print(" ✓ Room with 2 devices created")
return True
def test_ui_layout_creation():
"""Test UiLayout model creation."""
print("\nTest 3: UiLayout Creation")
rooms = [
Room(
name="Room 1",
devices=[DeviceTile(device_id="d1", title="D1", icon="💡", rank=1)]
),
Room(
name="Room 2",
devices=[DeviceTile(device_id="d2", title="D2", icon="💡", rank=1)]
)
]
layout = UiLayout(rooms=rooms)
assert len(layout.rooms) == 2
assert layout.total_devices() == 2
print(" ✓ UiLayout with 2 rooms created")
print(f" ✓ Total devices: {layout.total_devices()}")
return True
def test_layout_validation_empty_rooms():
"""Test that layout validation rejects empty rooms list."""
print("\nTest 4: Validation - Empty Rooms")
try:
UiLayout(rooms=[])
print(" ✗ Should have raised ValueError")
return False
except ValueError as e:
if "at least one room" in str(e):
print(f" ✓ Correct validation error: {e}")
return True
else:
print(f" ✗ Wrong error message: {e}")
return False
def test_load_layout_from_file():
"""Test loading layout from YAML file."""
print("\nTest 5: Load Layout from YAML")
yaml_content = """
rooms:
- name: Wohnzimmer
devices:
- device_id: test_lampe_1
title: Stehlampe
icon: "💡"
rank: 10
- device_id: test_lampe_2
title: Tischlampe
icon: "💡"
rank: 20
- name: Schlafzimmer
devices:
- device_id: test_lampe_3
title: Nachttischlampe
icon: "🛏️"
rank: 5
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
layout = load_layout(str(temp_path))
assert len(layout.rooms) == 2
assert layout.rooms[0].name == "Wohnzimmer"
assert len(layout.rooms[0].devices) == 2
assert layout.total_devices() == 3
# Check device sorting by rank
wohnzimmer_devices = layout.rooms[0].devices
assert wohnzimmer_devices[0].rank == 10
assert wohnzimmer_devices[1].rank == 20
print(" ✓ Layout loaded from YAML")
print(f" ✓ Rooms: {len(layout.rooms)}")
print(f" ✓ Total devices: {layout.total_devices()}")
print(f" ✓ Room order preserved: {[r.name for r in layout.rooms]}")
return True
finally:
temp_path.unlink()
def test_load_layout_missing_file():
"""Test error handling for missing file."""
print("\nTest 6: Missing File Error")
try:
load_layout("/nonexistent/path/layout.yaml")
print(" ✗ Should have raised FileNotFoundError")
return False
except FileNotFoundError as e:
if "not found" in str(e):
print(f" ✓ Correct error for missing file")
return True
else:
print(f" ✗ Wrong error message: {e}")
return False
def test_load_layout_invalid_yaml():
"""Test error handling for invalid YAML."""
print("\nTest 7: Invalid YAML Error")
yaml_content = """
rooms:
- name: Room1
devices: [invalid yaml structure
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
load_layout(str(temp_path))
print(" ✗ Should have raised YAMLError")
temp_path.unlink()
return False
except Exception as e:
temp_path.unlink()
if "YAML" in str(type(e).__name__) or "parse" in str(e).lower():
print(f" ✓ Correct YAML parsing error")
return True
else:
print(f" ✗ Unexpected error: {type(e).__name__}: {e}")
return False
def test_load_layout_missing_required_fields():
"""Test validation for missing required fields."""
print("\nTest 8: Missing Required Fields")
yaml_content = """
rooms:
- name: Room1
devices:
- device_id: lamp1
title: Lamp
# Missing: icon, rank
"""
with tempfile.NamedTemporaryFile(mode='w', suffix='.yaml', delete=False) as f:
f.write(yaml_content)
temp_path = Path(f.name)
try:
load_layout(str(temp_path))
print(" ✗ Should have raised ValueError")
temp_path.unlink()
return False
except ValueError as e:
temp_path.unlink()
if "icon" in str(e) or "rank" in str(e) or "required" in str(e).lower():
print(f" ✓ Validation error for missing fields")
return True
else:
print(f" ✗ Wrong error: {e}")
return False
def test_load_default_layout():
"""Test loading default layout from workspace."""
print("\nTest 9: Load Default Layout (config/layout.yaml)")
try:
layout = load_layout()
print(f" ✓ Default layout loaded")
print(f" ✓ Rooms: {len(layout.rooms)} ({', '.join(r.name for r in layout.rooms)})")
print(f" ✓ Total devices: {layout.total_devices()}")
for room in layout.rooms:
print(f" - {room.name}: {len(room.devices)} devices")
for device in room.devices:
print(f"{device.title} (id={device.device_id}, rank={device.rank})")
return True
except FileNotFoundError:
print(" ⚠ Default layout.yaml not found (expected at config/layout.yaml)")
return True # Not a failure if file doesn't exist yet
except Exception as e:
print(f" ✗ Error loading default layout: {e}")
return False
def main():
"""Run all tests."""
print("=" * 60)
print("Testing Layout Loader and Models")
print("=" * 60)
tests = [
test_device_tile_creation,
test_room_creation,
test_ui_layout_creation,
test_layout_validation_empty_rooms,
test_load_layout_from_file,
test_load_layout_missing_file,
test_load_layout_invalid_yaml,
test_load_layout_missing_required_fields,
test_load_default_layout,
]
results = []
for test in tests:
try:
results.append(test())
except Exception as e:
print(f" ✗ Unexpected exception: {e}")
results.append(False)
print("\n" + "=" * 60)
passed = sum(results)
total = len(results)
print(f"Results: {passed}/{total} tests passed")
print("=" * 60)
return 0 if all(results) else 1
if __name__ == "__main__":
sys.exit(main())

View File

@@ -1,296 +0,0 @@
"""
Acceptance tests for Responsive Dashboard.
Tests:
1. Desktop: 4 columns grid
2. Tablet: 2 columns grid
3. Mobile: 1 column grid
4. POST requests work (via API check)
5. No horizontal scrolling on any viewport
"""
import sys
import httpx
from bs4 import BeautifulSoup
def test_dashboard_html_structure():
"""Test 1: Dashboard has correct HTML structure."""
print("Test 1: Dashboard HTML Structure")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
soup = BeautifulSoup(html, 'html.parser')
# Check for grid container
grid = soup.find('div', class_='devices-grid')
if not grid:
print(" ✗ FAILED: Missing .devices-grid container")
return False
# Check for device tiles
tiles = soup.find_all('div', class_='device-tile')
if len(tiles) < 2:
print(f" ✗ FAILED: Expected at least 2 device tiles, found {len(tiles)}")
return False
# Check for state spans
state_spans = soup.find_all('span', id=lambda x: x and x.startswith('state-'))
if len(state_spans) < 2:
print(f" ✗ FAILED: Expected state spans, found {len(state_spans)}")
return False
# Check for ON/OFF buttons
btn_on = soup.find_all('button', class_='btn-on')
btn_off = soup.find_all('button', class_='btn-off')
if not btn_on or not btn_off:
print(" ✗ FAILED: Missing ON/OFF buttons")
return False
print(f" ✓ Found {len(tiles)} device tiles")
print(f" ✓ Found {len(state_spans)} state indicators")
print(f" ✓ Found {len(btn_on)} ON buttons and {len(btn_off)} OFF buttons")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_responsive_css():
"""Test 2: CSS has responsive grid rules."""
print("Test 2: Responsive CSS")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/static/style.css", timeout=5.0)
response.raise_for_status()
css = response.text
# Check for desktop 4 columns
if 'grid-template-columns: repeat(4, 1fr)' not in css:
print(" ✗ FAILED: Missing desktop grid (4 columns)")
return False
# Check for tablet media query (2 columns)
if 'max-width: 1024px' not in css or 'repeat(2, 1fr)' not in css:
print(" ✗ FAILED: Missing tablet media query (2 columns)")
return False
# Check for mobile media query (1 column)
if 'max-width: 640px' not in css:
print(" ✗ FAILED: Missing mobile media query")
return False
print(" ✓ Desktop: 4 columns (grid-template-columns: repeat(4, 1fr))")
print(" ✓ Tablet: 2 columns (@media max-width: 1024px)")
print(" ✓ Mobile: 1 column (@media max-width: 640px)")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_javascript_functions():
"""Test 3: JavaScript POST function exists."""
print("Test 3: JavaScript POST Function")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
# Check for setDeviceState function
if 'function setDeviceState' not in html and 'async function setDeviceState' not in html:
print(" ✗ FAILED: Missing setDeviceState function")
return False
# Check for fetch POST call
if 'fetch(' not in html or 'method: \'POST\'' not in html:
print(" ✗ FAILED: Missing fetch POST call")
return False
# Check for correct API endpoint pattern
if '/devices/${deviceId}/set' not in html and '/devices/' not in html:
print(" ✗ FAILED: Missing correct API endpoint")
return False
# Check for JSON payload
if 'type: \'light\'' not in html and '"type":"light"' not in html:
print(" ✗ FAILED: Missing correct JSON payload")
return False
print(" ✓ setDeviceState function defined")
print(" ✓ Uses fetch with POST method")
print(" ✓ Correct endpoint: /devices/{deviceId}/set")
print(" ✓ Correct payload: {type:'light', payload:{power:...}}")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_device_controls():
"""Test 4: Devices have correct controls."""
print("Test 4: Device Controls")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
soup = BeautifulSoup(html, 'html.parser')
# Find device tiles
tiles = soup.find_all('div', class_='device-tile')
for tile in tiles:
device_id = tile.get('data-device-id')
# Check for device header
header = tile.find('div', class_='device-header')
if not header:
print(f" ✗ FAILED: Device {device_id} missing header")
return False
# Check for icon and title
icon = tile.find('div', class_='device-icon')
title = tile.find('h3', class_='device-title')
device_id_elem = tile.find('p', class_='device-id')
if not icon or not title or not device_id_elem:
print(f" ✗ FAILED: Device {device_id} missing icon/title/id")
return False
# Check for state indicator
state_span = tile.find('span', id=f'state-{device_id}')
if not state_span:
print(f" ✗ FAILED: Device {device_id} missing state indicator")
return False
print(f" ✓ All {len(tiles)} devices have:")
print(" • Icon, title, and device_id")
print(" • State indicator (span#state-{{device_id}})")
print(" • ON/OFF buttons (for lights with power feature)")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def test_rank_sorting():
"""Test 5: Devices sorted by rank."""
print("Test 5: Device Rank Sorting")
print("-" * 60)
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=5.0)
response.raise_for_status()
html = response.text
# In Wohnzimmer: Deckenlampe (rank=5) should come before Stehlampe (rank=10)
deckenlampe_pos = html.find('device-title">Deckenlampe<')
stehlampe_pos = html.find('device-title">Stehlampe<')
if deckenlampe_pos == -1 or stehlampe_pos == -1:
print(" INFO: Test devices not found (expected for test)")
print()
return True
if deckenlampe_pos > stehlampe_pos:
print(" ✗ FAILED: Devices not sorted by rank")
return False
print(" ✓ Devices sorted by rank (Deckenlampe before Stehlampe)")
print()
return True
except Exception as e:
print(f" ✗ FAILED: {e}")
print()
return False
def main():
"""Run all acceptance tests."""
print("=" * 60)
print("Testing Responsive Dashboard")
print("=" * 60)
print()
# Check if UI is running
print("Prerequisites: Checking if UI is running on port 8002...")
try:
response = httpx.get("http://localhost:8002/dashboard", timeout=3.0)
print("✓ UI is running")
print()
except Exception as e:
print(f"✗ Cannot reach UI: {e}")
print(" Start UI with: poetry run uvicorn apps.ui.main:app --port 8002")
print()
sys.exit(1)
results = []
# Run tests
results.append(("HTML Structure", test_dashboard_html_structure()))
results.append(("Responsive CSS", test_responsive_css()))
results.append(("JavaScript POST", test_javascript_functions()))
results.append(("Device Controls", test_device_controls()))
results.append(("Rank Sorting", test_rank_sorting()))
# Summary
print("=" * 60)
passed = sum(1 for _, result in results if result)
total = len(results)
print(f"Results: {passed}/{total} tests passed")
print("=" * 60)
for name, result in results:
status = "" if result else ""
print(f" {status} {name}")
print()
print("Manual Tests Required:")
print(" 1. Open http://localhost:8002/dashboard in browser")
print(" 2. Resize browser window to test responsive breakpoints:")
print(" - Desktop (>1024px): Should show 4 columns")
print(" - Tablet (640-1024px): Should show 2 columns")
print(" - Mobile (<640px): Should show 1 column")
print(" 3. Click ON/OFF buttons and check Network tab in DevTools")
print(" - Should see POST to http://localhost:8001/devices/.../set")
print(" - No JavaScript errors in Console")
print(" 4. Verify no horizontal scrolling at any viewport size")
if passed == total:
print()
print("All automated tests passed!")
sys.exit(0)
else:
print()
print("Some tests failed.")
sys.exit(1)
if __name__ == "__main__":
main()