feat(zigbee2mqtt): log in to MQTT by client certificate (REN-953)
Z2M, discovery-guard and interview-watch use the certificate of the register account zigbee2mqtt-bridge on the mTLS listener :8884 instead of the legacy password. Z2M gets server/ca/cert/key by env because its configuration.yaml on the PVC is never re-seeded. The init container no longer renders mqtt_password. The legacy broker user stays until a later broker roll. Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
This commit is contained in:
co-authored by
Claude Opus 5.5
parent
da3037cb24
commit
5be1d0a250
@@ -11,11 +11,11 @@ data:
|
||||
# config once the PVC has been seeded — change the on-PVC file (via the Z2M
|
||||
# frontend or an edit) instead. Kept here so a fresh PVC comes up configured.
|
||||
#
|
||||
# Secrets are NOT in this file: both the MQTT password and the Zigbee
|
||||
# network_key are quoted parseValueRefs (`"!secret <key>"`) resolved from
|
||||
# /app/data/secret.yaml, which the init container renders — the MQTT password
|
||||
# from the broker-credential Secret, and the network_key extracted from the
|
||||
# OpenBao coordinator backup. The non-secret network params (channel/pan_id/
|
||||
# Secrets are NOT in this file: the Zigbee network_key is a quoted
|
||||
# parseValueRef (`"!secret <key>"`) resolved from /app/data/secret.yaml,
|
||||
# which the init container renders from the OpenBao coordinator backup. MQTT
|
||||
# uses the client certificate mounted at /mqtt-tls (REN-953); the Deployment
|
||||
# also sets the mqtt server/ca/cert/key by env, which wins over this file. The non-secret network params (channel/pan_id/
|
||||
# ext_pan_id) are in `advanced` below.
|
||||
configuration.yaml: |
|
||||
# Home Assistant MQTT discovery — Z2M publishes device configs under the
|
||||
@@ -32,14 +32,12 @@ data:
|
||||
|
||||
mqtt:
|
||||
base_topic: zigbee2mqtt
|
||||
server: mqtt://mosquitto:1883
|
||||
user: zigbee2mqtt
|
||||
# MUST be a QUOTED string: Z2M reads secrets via parseValueRef on the
|
||||
# string value (regex `!<file> <key>`), NOT a YAML `!secret` tag. Unquoted
|
||||
# `!secret ...` is parsed as a tag and throws "unknown scalar tag
|
||||
# !<!secret>". The init container renders /app/data/secret.yaml with
|
||||
# `mqtt_password` from the broker-credential Secret.
|
||||
password: "!secret mqtt_password"
|
||||
# Mutual TLS: the broker takes the username from the certificate CN
|
||||
# (zigbee2mqtt-bridge), so no user or password here.
|
||||
server: mqtts://mosquitto:8884
|
||||
ca: /mqtt-tls/ca.crt
|
||||
cert: /mqtt-tls/tls.crt
|
||||
key: /mqtt-tls/tls.key
|
||||
|
||||
# SMLIGHT SLZB-06 (Texas Instruments CC2652, zigpy-znp under ZHA) reached
|
||||
# over TCP on the IoT VLAN — the SAME coordinator ZHA uses today
|
||||
|
||||
@@ -32,9 +32,11 @@ spec:
|
||||
# backup also handles the ZHA<->Z2M ext_pan_id byte-order reversal —
|
||||
# which is why we restore a backup rather than hand-set advanced.ext_pan_id).
|
||||
# Renders /app/data/secret.yaml (referenced by the config as quoted
|
||||
# "!secret" parseValueRefs) with the MQTT password AND the Zigbee
|
||||
# network_key, the latter extracted from the OpenBao coordinator backup
|
||||
# as a natural-byte-order int array.
|
||||
# "!secret" parseValueRefs) with the Zigbee network_key, extracted from
|
||||
# the OpenBao coordinator backup as a natural-byte-order int array. No
|
||||
# MQTT password since REN-953: `mqtt_password` is absent, so Z2M's
|
||||
# "!secret mqtt_password" resolves to nothing and it logs in by
|
||||
# certificate alone.
|
||||
- name: seed-data
|
||||
# Our own alpine + jq image, built by build-ci-images.yml. DATED tag,
|
||||
# never :latest — rebuilding this base for an unrelated consumer
|
||||
@@ -114,7 +116,6 @@ spec:
|
||||
# hex key "fe0b..2d" -> "0xfe,0x0b,..,0x2d" (natural order)
|
||||
NK=$(printf '%s' "$KEY" | sed 's/../0x&,/g; s/,$//')
|
||||
cat > /app/data/secret.yaml <<EOF
|
||||
mqtt_password: "${MQTT_PASSWORD}"
|
||||
network_key: [${NK}]
|
||||
EOF
|
||||
if [ ! -f /app/data/configuration.yaml ]; then
|
||||
@@ -139,12 +140,6 @@ spec:
|
||||
mkdir -p /app/data/external_converters
|
||||
cp /external-converters/*.js /app/data/external_converters/
|
||||
echo "copied external converters: $(ls /external-converters)"
|
||||
env:
|
||||
- name: MQTT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mosquitto-zigbee2mqtt-credentials
|
||||
key: password
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /app/data
|
||||
@@ -175,12 +170,29 @@ spec:
|
||||
value: Europe/Berlin
|
||||
- name: ZIGBEE2MQTT_DATA
|
||||
value: /app/data
|
||||
# MQTT by client certificate (register account zigbee2mqtt-bridge,
|
||||
# REN-953). Env, not the seed template: configuration.yaml on the
|
||||
# PVC is Z2M's own and is never re-seeded. Z2M copies env values
|
||||
# into that file on its next settings write, so a rollback must
|
||||
# set these to the old values, not just drop them. The file keeps
|
||||
# `user: zigbee2mqtt`; the broker ignores it and uses the CN.
|
||||
- name: ZIGBEE2MQTT_CONFIG_MQTT_SERVER
|
||||
value: mqtts://mosquitto:8884
|
||||
- name: ZIGBEE2MQTT_CONFIG_MQTT_CA
|
||||
value: /mqtt-tls/ca.crt
|
||||
- name: ZIGBEE2MQTT_CONFIG_MQTT_CERT
|
||||
value: /mqtt-tls/tls.crt
|
||||
- name: ZIGBEE2MQTT_CONFIG_MQTT_KEY
|
||||
value: /mqtt-tls/tls.key
|
||||
ports:
|
||||
- name: http
|
||||
containerPort: 8080
|
||||
volumeMounts:
|
||||
- name: data
|
||||
mountPath: /app/data
|
||||
- name: mqtt-tls
|
||||
mountPath: /mqtt-tls
|
||||
readOnly: true
|
||||
# The frontend only serves once Z2M has started its adapter+MQTT, so
|
||||
# an HTTP 200 on / is a decent liveness/readiness signal. Generous
|
||||
# startup budget covers coordinator connect + herdsman network adopt.
|
||||
@@ -239,19 +251,16 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: [sh, /script/watch.sh]
|
||||
env:
|
||||
- name: MQTT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mosquitto-zigbee2mqtt-credentials
|
||||
key: password
|
||||
# These three must track zigbee2mqtt-config.yaml: MQTT_HOST the
|
||||
# mosquitto Service name, MQTT_USER and BASE_TOPIC the mqtt.user and
|
||||
# mqtt.base_topic it connects with. Set explicitly rather than left
|
||||
# to the script's defaults so the coupling is visible here.
|
||||
# Must track the Z2M container: MQTT_HOST/MQTT_PORT the broker it
|
||||
# connects to, BASE_TOPIC its mqtt.base_topic. Set explicitly
|
||||
# rather than left to the script's defaults so the coupling is
|
||||
# visible here. Logs in with the pod's certificate (/mqtt-tls).
|
||||
- name: MQTT_HOST
|
||||
value: mosquitto
|
||||
- name: MQTT_USER
|
||||
value: zigbee2mqtt
|
||||
- name: MQTT_PORT
|
||||
value: "8884"
|
||||
- name: MQTT_TLS_DIR
|
||||
value: /mqtt-tls
|
||||
- name: BASE_TOPIC
|
||||
value: zigbee2mqtt
|
||||
- name: STATEDIR
|
||||
@@ -274,6 +283,9 @@ spec:
|
||||
- name: interview-watch-script
|
||||
mountPath: /script
|
||||
readOnly: true
|
||||
- name: mqtt-tls
|
||||
mountPath: /mqtt-tls
|
||||
readOnly: true
|
||||
# Cooldown stamps. An explicit emptyDir rather than the image's
|
||||
# /tmp, so it stays writable as non-root without depending on the
|
||||
# container filesystem.
|
||||
@@ -305,19 +317,16 @@ spec:
|
||||
imagePullPolicy: IfNotPresent
|
||||
command: [sh, /script/guard.sh]
|
||||
env:
|
||||
# Reuses the Z2M broker credential: its ACL is `readwrite
|
||||
# zigbee2mqtt/#`, which covers reading bridge/state/bridge/groups and
|
||||
# writing bridge/request/restart. No new broker user needed.
|
||||
- name: MQTT_PASSWORD
|
||||
valueFrom:
|
||||
secretKeyRef:
|
||||
name: mosquitto-zigbee2mqtt-credentials
|
||||
key: password
|
||||
# Must track zigbee2mqtt-config.yaml, same as interview-watch.
|
||||
# Shares the Z2M certificate: its ACL is `readwrite zigbee2mqtt/#`,
|
||||
# which covers reading bridge/state/bridge/groups and writing
|
||||
# bridge/request/restart. Must track the Z2M container, same as
|
||||
# interview-watch.
|
||||
- name: MQTT_HOST
|
||||
value: mosquitto
|
||||
- name: MQTT_USER
|
||||
value: zigbee2mqtt
|
||||
- name: MQTT_PORT
|
||||
value: "8884"
|
||||
- name: MQTT_TLS_DIR
|
||||
value: /mqtt-tls
|
||||
- name: BASE_TOPIC
|
||||
value: zigbee2mqtt
|
||||
- name: STATEDIR
|
||||
@@ -333,6 +342,9 @@ spec:
|
||||
- name: discovery-guard-script
|
||||
mountPath: /script
|
||||
readOnly: true
|
||||
- name: mqtt-tls
|
||||
mountPath: /mqtt-tls
|
||||
readOnly: true
|
||||
# Restart cooldown stamp. Its own emptyDir rather than the image's
|
||||
# /tmp, so it stays writable as non-root.
|
||||
- name: discovery-guard-state
|
||||
@@ -359,6 +371,15 @@ spec:
|
||||
- name: interview-watch-script
|
||||
configMap:
|
||||
name: zigbee2mqtt-interview-watch-script
|
||||
# Client certificate of the register account zigbee2mqtt-bridge,
|
||||
# issued by mqtt-account-controller. Not subPath, so a cert-manager
|
||||
# renewal reaches the files in place; Z2M reads them at connect, the
|
||||
# sidecars on every call. 0444 because the sidecars run as UID 1883
|
||||
# and Z2M as root; only this pod mounts it.
|
||||
- name: mqtt-tls
|
||||
secret:
|
||||
secretName: mqtt-zigbee2mqtt-bridge-tls
|
||||
defaultMode: 0444
|
||||
- name: interview-watch-state
|
||||
emptyDir:
|
||||
medium: Memory
|
||||
|
||||
@@ -61,16 +61,19 @@
|
||||
# herdsman-only restart. discover() republishes only configs that are missing or
|
||||
# whose payload changed, which after a wipe is all of them.
|
||||
#
|
||||
# Credentials: reuses the existing zigbee2mqtt broker user, whose ACL is
|
||||
# Credentials: the pod's client certificate (register account
|
||||
# zigbee2mqtt-bridge, REN-953) on the mTLS listener :8884. Its ACL is
|
||||
# `readwrite zigbee2mqtt/#` — enough to read bridge/state and bridge/groups and
|
||||
# to write bridge/request/restart. No new broker user, and no read grant on
|
||||
# homeassistant/# (checking for the discovery configs directly would have needed
|
||||
# one, which the ACL denies on purpose).
|
||||
# to write bridge/request/restart. No read grant on homeassistant/# (checking
|
||||
# for the discovery configs directly would have needed one, which the ACL
|
||||
# denies on purpose).
|
||||
set -eu
|
||||
|
||||
MQTT_HOST="${MQTT_HOST:-mosquitto}"
|
||||
MQTT_PORT="${MQTT_PORT:-1883}"
|
||||
MQTT_USER="${MQTT_USER:-zigbee2mqtt}"
|
||||
MQTT_PORT="${MQTT_PORT:-8884}"
|
||||
# ca.crt, tls.crt, tls.key of the client certificate. The broker takes the
|
||||
# username from the certificate CN.
|
||||
MQTT_TLS_DIR="${MQTT_TLS_DIR:-/mqtt-tls}"
|
||||
BASE_TOPIC="${BASE_TOPIC:-zigbee2mqtt}"
|
||||
# Poll cadence. Worst-case time-to-repair is CHECK_INTERVAL + CONFIRM_DELAY.
|
||||
CHECK_INTERVAL="${CHECK_INTERVAL:-300}"
|
||||
@@ -105,7 +108,7 @@ log() { echo "[$(date -u '+%Y-%m-%dT%H:%M:%SZ')] discovery-guard: $*"; }
|
||||
# ever paid when the topic is genuinely empty.
|
||||
retained() {
|
||||
timeout "$((READ_TIMEOUT + 5))" mosquitto_sub -h "$MQTT_HOST" -p "$MQTT_PORT" \
|
||||
-u "$MQTT_USER" -P "$MQTT_PASSWORD" \
|
||||
--cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" \
|
||||
-t "$1" -C 1 -W "$READ_TIMEOUT" 2>/dev/null || true
|
||||
}
|
||||
|
||||
@@ -152,7 +155,7 @@ while true; do
|
||||
|
||||
log "confirmed — requesting a Zigbee2MQTT restart to re-run discovery"
|
||||
if timeout "$PUB_TIMEOUT" mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" \
|
||||
-u "$MQTT_USER" -P "$MQTT_PASSWORD" \
|
||||
--cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" \
|
||||
-t "$BASE_TOPIC/bridge/request/restart" -m '' 2>/dev/null; then
|
||||
date -u +%s > "$STAMP"
|
||||
log "restart requested"
|
||||
|
||||
@@ -53,7 +53,10 @@ set -u
|
||||
DATA=/app/data
|
||||
DB="$DATA/database.db"
|
||||
MQTT_HOST=${MQTT_HOST:-mosquitto}
|
||||
MQTT_USER=${MQTT_USER:-zigbee2mqtt}
|
||||
MQTT_PORT=${MQTT_PORT:-8884}
|
||||
# ca.crt, tls.crt, tls.key of the pod's client certificate (register account
|
||||
# zigbee2mqtt-bridge, REN-953). The broker takes the username from its CN.
|
||||
MQTT_TLS_DIR=${MQTT_TLS_DIR:-/mqtt-tls}
|
||||
# Must track mqtt.base_topic in zigbee2mqtt-config.yaml. Overridable via env so
|
||||
# the two can be kept in step from the Deployment rather than by editing this
|
||||
# script; the MQTT ACL for this user is scoped to `zigbee2mqtt/#`, so a change
|
||||
@@ -219,10 +222,6 @@ while :; do
|
||||
fi
|
||||
|
||||
log "frame from $ieee (nwk=$nwk cluster=$cluster) while awake -> requesting interview"
|
||||
# NOTE: mosquitto_pub can only take a password via argv (-P, or an -L URL);
|
||||
# it has no --pw-file or env option, so this cannot be avoided with this
|
||||
# client. Not a cross-container exposure: the pod does not set
|
||||
# shareProcessNamespace, so /proc is not shared with the Z2M container.
|
||||
# Bounded with `timeout`, which also covers a TCP connect that hangs rather
|
||||
# than being refused. The read loop is single-threaded, so an unbounded
|
||||
# publish would stall it and miss other devices' wake windows.
|
||||
@@ -230,7 +229,8 @@ while :; do
|
||||
# NOT `mosquitto_pub -W`: that flag does not exist for mosquitto_pub (it is
|
||||
# a mosquitto_sub option), and passing it makes every publish fail on a
|
||||
# usage error — verified against the client in this image.
|
||||
if timeout "$PUB_TIMEOUT" mosquitto_pub -h "$MQTT_HOST" -u "$MQTT_USER" -P "$MQTT_PASSWORD" \
|
||||
if timeout "$PUB_TIMEOUT" mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" \
|
||||
--cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" \
|
||||
-t "$BASE_TOPIC/bridge/request/device/interview" \
|
||||
-m "{\"id\":\"$ieee\"}" 2>/dev/null; then
|
||||
# Stamp only on a SUCCESSFUL publish. Stamping unconditionally would burn
|
||||
|
||||
@@ -103,25 +103,25 @@ POD=$(kubectl get pod -n home-assistant -l app.kubernetes.io/name=zigbee2mqtt -o
|
||||
```
|
||||
|
||||
```sh
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msTemperatureMeasurement\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":10}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msTemperatureMeasurement\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":10}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msRelativeHumidity\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":50}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msRelativeHumidity\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":50}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msPressureMeasurement\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msPressureMeasurement\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msIlluminanceMeasurement\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":5}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"msIlluminanceMeasurement\",\"attribute\":\"measuredValue\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":5}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Wind\",\"attribute\":\"windSpeed\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Wind\",\"attribute\":\"windSpeed\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Wind\",\"attribute\":\"windDirection\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Wind\",\"attribute\":\"windDirection\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Wind\",\"attribute\":\"gustSpeed\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Wind\",\"attribute\":\"gustSpeed\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90UV\",\"attribute\":\"uvIndex\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90UV\",\"attribute\":\"uvIndex\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Rain\",\"attribute\":\"rainStatus\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Rain\",\"attribute\":\"rainStatus\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p 1883 -u "$MQTT_USER" -P "$MQTT_PASSWORD" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Rain\",\"attribute\":\"precipitation\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
kubectl exec -n home-assistant "$POD" -c discovery-guard -- sh -c 'mosquitto_pub -h "$MQTT_HOST" -p "$MQTT_PORT" --cafile "$MQTT_TLS_DIR/ca.crt" --cert "$MQTT_TLS_DIR/tls.crt" --key "$MQTT_TLS_DIR/tls.key" -t "$BASE_TOPIC/bridge/request/device/configure_reporting" -m "{\"id\":\"0xc02cedfffe958f40\",\"endpoint\":1,\"cluster\":\"shellyWS90Rain\",\"attribute\":\"precipitation\",\"minimum_report_interval\":5,\"maximum_report_interval\":3600,\"reportable_change\":1,\"options\":{\"manufacturerCode\":5264}}"'
|
||||
```
|
||||
|
||||
These are idempotent — re-sending a request that matches the current
|
||||
|
||||
Reference in New Issue
Block a user