diff --git a/k8s/README.md b/k8s/README.md index 1bb3069..83d3222 100644 --- a/k8s/README.md +++ b/k8s/README.md @@ -826,3 +826,18 @@ An autonomous AI agent platform. * **Encrypt**: Ensure the file is encrypted with `git crypt` before committing! 3. **Deploy**: `kubectl apply -f openclaw/openclaw.secret.yaml` 4. **Access**: `https://openclaw.haumdaucher.de` (Authentication required) + +## Zigbee2MQTT + +Zigbee2MQTT manages Zigbee devices via the SLZB-MR1U coordinator. It is deployed via the official Helm chart in the `zigbee` namespace. + +```bash +helm repo add zigbee2mqtt https://charts.zigbee2mqtt.io +helm repo update +# Apply the secrets first for the Traefik basic auth middleware +kubectl apply -f zigbee/zigbee2mqtt.secret.yaml +# Install or upgrade the release +helm upgrade --install zigbee2mqtt zigbee2mqtt/zigbee2mqtt --create-namespace -n zigbee -f zigbee/zigbee2mqtt.secret.values.yaml +``` + +To modify configurations (like `devices`, `throttle`, or `mqtt`), edit `zigbee/zigbee2mqtt.secret.values.yaml` and re-run the `helm upgrade` command. The chart automatically handles merging these values into the persistent volume on startup. diff --git a/k8s/monitoring/zigbee2mqtt.secret.yaml b/k8s/monitoring/zigbee2mqtt.secret.yaml deleted file mode 100644 index 9545396..0000000 Binary files a/k8s/monitoring/zigbee2mqtt.secret.yaml and /dev/null differ diff --git a/k8s/monitoring/zigbee2mqtt.yaml b/k8s/monitoring/zigbee2mqtt.yaml deleted file mode 100644 index 6997191..0000000 --- a/k8s/monitoring/zigbee2mqtt.yaml +++ /dev/null @@ -1,206 +0,0 @@ -apiVersion: v1 -kind: PersistentVolumeClaim -metadata: - name: zigbee2mqtt-pvc - namespace: monitoring -spec: - accessModes: - - ReadWriteOnce - resources: - requests: - storage: 1Gi ---- -apiVersion: v1 -kind: ConfigMap -metadata: - name: zigbee2mqtt-config-template - namespace: monitoring -data: - configuration.yaml: | - homeassistant: true - availability: - active: - timeout: 10 - permit_join: false - mqtt: - base_topic: zigbee2mqtt - server: mqtt://mosquitto.datalab.svc.cluster.local:1883 - user: sender - serial: - port: tcp://192.168.10.10:7638 - frontend: - port: 8080 - host: 0.0.0.0 - advanced: - network_key: GENERATE ---- -apiVersion: apps/v1 -kind: Deployment -metadata: - name: zigbee2mqtt - namespace: monitoring - labels: - app: zigbee2mqtt -spec: - replicas: 1 - selector: - matchLabels: - app: zigbee2mqtt - template: - metadata: - labels: - app: zigbee2mqtt - spec: - securityContext: - fsGroup: 1000 - runAsUser: 1000 - initContainers: - - name: init-config - image: busybox:latest - command: - - sh - - -c - - | - if [ ! -f /app/data/configuration.yaml ]; then - echo "Initializing configuration.yaml..." - cp /tmp/config/configuration.yaml /app/data/configuration.yaml - chmod 600 /app/data/configuration.yaml - else - echo "configuration.yaml already exists. Skipping initialization." - fi - securityContext: - runAsUser: 1000 - volumeMounts: - - name: data - mountPath: /app/data - - name: config-template - mountPath: /tmp/config - containers: - - name: zigbee2mqtt - image: koenkk/zigbee2mqtt:latest - env: - # Override MQTT credentials/settings using environment variables - - name: ZIGBEE2MQTT_CONFIG_MQTT_SERVER - value: "mqtt://mosquitto.datalab.svc.cluster.local:1883" - - name: ZIGBEE2MQTT_CONFIG_MQTT_USER - value: "sender" - - name: ZIGBEE2MQTT_CONFIG_MQTT_PASSWORD - valueFrom: - secretKeyRef: - name: zigbee2mqtt-secret - key: mqtt-password - # Override Zigbee Coordinator settings using environment variables - - name: ZIGBEE2MQTT_CONFIG_SERIAL_PORT - value: "tcp://192.168.10.10:7638" - - name: ZIGBEE2MQTT_CONFIG_SERIAL_ADAPTER - value: "zstack" - ports: - - name: http-frontend - containerPort: 8080 - resources: - requests: - cpu: 10m - memory: 64Mi - limits: - cpu: 200m - memory: 256Mi - volumeMounts: - - name: data - mountPath: /app/data - volumes: - - name: data - persistentVolumeClaim: - claimName: zigbee2mqtt-pvc - - name: config-template - configMap: - name: zigbee2mqtt-config-template ---- -apiVersion: v1 -kind: Service -metadata: - name: zigbee2mqtt - namespace: monitoring - labels: - app: zigbee2mqtt -spec: - ports: - - name: http-frontend - port: 8080 - targetPort: 8080 - protocol: TCP - selector: - app: zigbee2mqtt ---- -apiVersion: traefik.io/v1alpha1 -kind: Middleware -metadata: - name: zigbee2mqtt-auth - namespace: monitoring -spec: - basicAuth: - secret: zigbee2mqtt-auth-secret - removeHeader: true ---- -apiVersion: networking.k8s.io/v1 -kind: Ingress -metadata: - name: zigbee2mqtt - namespace: monitoring - annotations: - cert-manager.io/cluster-issuer: "letsencrypt-prod" - traefik.ingress.kubernetes.io/router.middlewares: monitoring-zigbee2mqtt-auth@kubernetescrd -spec: - ingressClassName: traefik - rules: - - host: zigbee2mqtt.moritzgraf.de - http: - paths: - - path: / - pathType: ImplementationSpecific - backend: - service: - name: zigbee2mqtt - port: - number: 8080 - tls: - - hosts: - - "zigbee2mqtt.moritzgraf.de" - secretName: zigbee2mqtt-tls ---- -apiVersion: monitoring.coreos.com/v1 -kind: PrometheusRule -metadata: - name: zigbee2mqtt-alerts - namespace: monitoring - labels: - release: prometheus-operator -spec: - groups: - - name: zigbee2mqtt.rules - rules: - - alert: Zigbee2MQTTDown - expr: kube_pod_container_status_ready{container="zigbee2mqtt", namespace="monitoring"} == 0 - for: 1h - labels: - severity: critical - annotations: - summary: "Zigbee2MQTT is down" - description: "The Zigbee2MQTT pod is not ready. This typically indicates a connection failure to the SLZB-MR1U coordinator host at 192.168.10.10:7638, or a crash within the Z2M application." - - alert: Zigbee2MQTTBridgeOffline - expr: homeassistant_binary_sensor_state{entity="binary_sensor.zigbee2mqtt_bridge_connection_state"} == 0 - for: 1h - labels: - severity: critical - annotations: - summary: "Zigbee2MQTT Bridge Connection Offline" - description: "The Zigbee2MQTT bridge connection is reported as offline. The bridge has lost communication with the MQTT broker or the Zigbee coordinator." - - alert: ShellyWS90MetricsStale - expr: absent(homeassistant_sensor_temperature_celsius{entity="sensor.shelly_ws90_temperatur"}) or (time() - homeassistant_last_updated_time_seconds{entity="sensor.shelly_ws90_temperatur"} > 0) - for: 1h - labels: - severity: warning - annotations: - summary: "Shelly WS90 Weather Station metrics are stale" - description: "No new metrics have been received from the Shelly WS90 weather station (sensor.shelly_ws90_temperatur) for over 1 hour. The device may be offline, out of range, or batteries might be depleted." - - diff --git a/k8s/zigbee/zigbee2mqtt.secret.values.yaml b/k8s/zigbee/zigbee2mqtt.secret.values.yaml new file mode 100644 index 0000000..5d2d728 --- /dev/null +++ b/k8s/zigbee/zigbee2mqtt.secret.values.yaml @@ -0,0 +1,121 @@ +configmap: + enabled: true + devices: + '0xfc4d6afffe246794': + friendly_name: Shelly WS90 + throttle: 30 + retain: true + qos: 1 + +statefulset: + storage: + enabled: true + size: 1Gi + storageClassName: openebs-hostpath + +ingress: + enabled: true + ingressClassName: traefik + annotations: + kubernetes.io/ingress.class: "traefik" + cert-manager.io/cluster-issuer: "letsencrypt-prod" + kubernetes.io/tls-acme: "true" + nginx.ingress.kubernetes.io/proxy-body-size: "0" + nginx.ingress.kubernetes.io/ssl-redirect: "true" + nginx.ingress.kubernetes.io/force-ssl-redirect: "true" + traefik.ingress.kubernetes.io/router.middlewares: zigbee-zigbee2mqtt-auth@kubernetescrd + hosts: + - host: zigbee2mqtt.moritzgraf.de + paths: + - path: / + pathType: Prefix + tls: + - secretName: zigbee2mqtt-moritzgraf-de + hosts: + - zigbee2mqtt.moritzgraf.de + +zigbee2mqtt: + homeassistant: + enabled: true + mqtt: + base_topic: zigbee2mqtt + server: mqtt://mosquitto.datalab.svc.cluster.local:1883 + user: sender + password: ahQueteiRietufeko8do + serial: + port: tcp://192.168.10.10:7638 + adapter: zstack + frontend: + enabled: true + port: 8080 + host: 0.0.0.0 + advanced: + network_key: + - 177 + - 180 + - 148 + - 63 + - 174 + - 86 + - 166 + - 83 + - 119 + - 36 + - 123 + - 147 + - 245 + - 85 + - 166 + - 74 + log_level: debug + log_directories_to_keep: 100 + adapter_concurrent: 8 + adapter_delay: 100 + transmit_power: 20 + device_options: {} + +extraResources: + - apiVersion: traefik.io/v1alpha1 + kind: Middleware + metadata: + name: zigbee2mqtt-auth + namespace: zigbee + spec: + basicAuth: + secret: zigbee2mqtt-auth-secret + removeHeader: true + - apiVersion: monitoring.coreos.com/v1 + kind: PrometheusRule + metadata: + name: zigbee2mqtt-alerts + namespace: zigbee + labels: + release: prometheus-operator + spec: + groups: + - name: zigbee2mqtt.rules + rules: + - alert: Zigbee2MQTTDown + expr: kube_pod_container_status_ready{container="zigbee2mqtt", namespace="zigbee"} == 0 + for: 1h + labels: + severity: critical + annotations: + summary: "Zigbee2MQTT is down" + description: "The Zigbee2MQTT pod is not ready. This typically indicates a connection failure to the SLZB-MR1U coordinator host at 192.168.10.10:7638, or a crash within the Z2M application." + - alert: Zigbee2MQTTBridgeOffline + expr: homeassistant_binary_sensor_state{entity="binary_sensor.zigbee2mqtt_bridge_connection_state"} == 0 + for: 1h + labels: + severity: critical + annotations: + summary: "Zigbee2MQTT Bridge Connection Offline" + description: "The Zigbee2MQTT bridge connection is reported as offline. The bridge has lost communication with the MQTT broker or the Zigbee coordinator." + - alert: ShellyWS90MetricsStale + expr: absent(homeassistant_sensor_temperature_celsius{entity="sensor.shelly_ws90_temperatur"}) or (time() - max(homeassistant_last_updated_time_seconds{entity=~"sensor.shelly_ws90_.*"}) > 3600) + for: 1h + labels: + severity: warning + annotations: + summary: "Shelly WS90 Weather Station metrics are stale" + description: "No new metrics have been received from the Shelly WS90 weather station (sensor.shelly_ws90_temperatur) for over 1 hour. The device may be offline, out of range, or batteries might be depleted." diff --git a/k8s/zigbee/zigbee2mqtt.secret.yaml b/k8s/zigbee/zigbee2mqtt.secret.yaml new file mode 100644 index 0000000..e31bef5 Binary files /dev/null and b/k8s/zigbee/zigbee2mqtt.secret.yaml differ