mirror of
https://github.com/shadoll/helm-charts.git
synced 2026-08-28 03:27:08 +00:00
feat: Add broadlinkac2mqtt Helm chart with configuration and templates
This commit is contained in:
@@ -0,0 +1,2 @@
|
|||||||
|
test-values.yaml
|
||||||
|
*.tgz
|
||||||
@@ -0,0 +1,9 @@
|
|||||||
|
apiVersion: v2
|
||||||
|
name: broadlinkac2mqtt
|
||||||
|
description: Broadlink AC to MQTT bridge - control Broadlink AC units via MQTT
|
||||||
|
type: application
|
||||||
|
version: 0.1.0
|
||||||
|
appVersion: "1.5.5"
|
||||||
|
annotations:
|
||||||
|
version-source: github-release:ArtemVladimirov/broadlinkac2mqtt
|
||||||
|
version-pattern: "s|^v||"
|
||||||
@@ -0,0 +1,220 @@
|
|||||||
|
# Broadlink AC2MQTT Helm Chart
|
||||||
|
|
||||||
|
Bridge between Broadlink-based air conditioners and MQTT. Enables control of Broadlink AC units through MQTT, with Home Assistant auto-discovery support.
|
||||||
|
|
||||||
|
## Overview
|
||||||
|
|
||||||
|
- **Application**: [ArtemVladimirov/broadlinkac2mqtt](https://github.com/ArtemVladimirov/broadlinkac2mqtt)
|
||||||
|
- **Type**: MQTT bridge (no HTTP server)
|
||||||
|
- **Platform Support**: Multi-arch (amd64, arm64)
|
||||||
|
- **Image**: `ghcr.io/artemvladimirov/broadlinkac2mqtt`
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Control Broadlink AC units via MQTT
|
||||||
|
- Home Assistant MQTT Discovery support
|
||||||
|
- Multi-device support
|
||||||
|
- Configurable update intervals
|
||||||
|
- Automatic reconnection handling
|
||||||
|
- Health checks for container reliability
|
||||||
|
|
||||||
|
## Prerequisites
|
||||||
|
|
||||||
|
- Kubernetes cluster
|
||||||
|
- MQTT broker (e.g., Mosquitto)
|
||||||
|
- Broadlink AC units on your network
|
||||||
|
- Device IP addresses and MAC addresses
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Basic Installation
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm install broadlinkac2mqtt ./broadlinkac2mqtt \
|
||||||
|
--set config.mqtt.server="tcp://mqtt-broker:1883" \
|
||||||
|
--set config.mqtt.user="myuser" \
|
||||||
|
--set config.mqtt.password="mypassword"
|
||||||
|
```
|
||||||
|
|
||||||
|
### With Device Configuration
|
||||||
|
|
||||||
|
Create a `values-custom.yaml` file:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
config:
|
||||||
|
mqtt:
|
||||||
|
server: "tcp://mqtt.home.lan:1883"
|
||||||
|
user: "broadlink"
|
||||||
|
password: "secret"
|
||||||
|
discovery: true
|
||||||
|
discovery_prefix: "homeassistant"
|
||||||
|
|
||||||
|
devices:
|
||||||
|
- ip: "192.168.1.100"
|
||||||
|
mac: "AA:BB:CC:DD:EE:FF"
|
||||||
|
name: "Living Room AC"
|
||||||
|
port: 80
|
||||||
|
temp_unit: "C"
|
||||||
|
|
||||||
|
- ip: "192.168.1.101"
|
||||||
|
mac: "11:22:33:44:55:66"
|
||||||
|
name: "Bedroom AC"
|
||||||
|
port: 80
|
||||||
|
temp_unit: "F"
|
||||||
|
```
|
||||||
|
|
||||||
|
Install with custom values:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm install broadlinkac2mqtt ./broadlinkac2mqtt -f values-custom.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Using Existing Secret for MQTT Credentials
|
||||||
|
|
||||||
|
Create a secret:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl create secret generic broadlink-mqtt-creds \
|
||||||
|
--from-literal=MQTT_USER=myuser \
|
||||||
|
--from-literal=MQTT_PASSWORD=mypassword
|
||||||
|
```
|
||||||
|
|
||||||
|
Install referencing the secret:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
existingSecret: "broadlink-mqtt-creds"
|
||||||
|
secretKeys:
|
||||||
|
mqttUser: "MQTT_USER"
|
||||||
|
mqttPassword: "MQTT_PASSWORD"
|
||||||
|
|
||||||
|
config:
|
||||||
|
mqtt:
|
||||||
|
server: "tcp://mqtt.home.lan:1883"
|
||||||
|
# user and password will be read from secret
|
||||||
|
devices:
|
||||||
|
- ip: "192.168.1.100"
|
||||||
|
mac: "AA:BB:CC:DD:EE:FF"
|
||||||
|
name: "Living Room AC"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Configuration
|
||||||
|
|
||||||
|
### Service Settings
|
||||||
|
|
||||||
|
| Parameter | Description | Default |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `config.service.update_interval` | Seconds between device polls | `10` |
|
||||||
|
| `config.service.log_level` | Log level (debug/info/error/disabled) | `info` |
|
||||||
|
|
||||||
|
### MQTT Settings
|
||||||
|
|
||||||
|
| Parameter | Description | Default |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `config.mqtt.server` | MQTT broker URL | `tcp://mqtt-broker:1883` |
|
||||||
|
| `config.mqtt.user` | MQTT username | `""` |
|
||||||
|
| `config.mqtt.password` | MQTT password | `""` |
|
||||||
|
| `config.mqtt.client_id` | MQTT client ID | `broadlinkac2mqtt` |
|
||||||
|
| `config.mqtt.discovery` | Enable Home Assistant discovery | `true` |
|
||||||
|
| `config.mqtt.discovery_prefix` | HA discovery prefix | `homeassistant` |
|
||||||
|
| `config.mqtt.topic_prefix` | Base topic prefix | `broadlinkac2mqtt` |
|
||||||
|
|
||||||
|
### Device Configuration
|
||||||
|
|
||||||
|
Each device requires:
|
||||||
|
|
||||||
|
- `ip`: Device IP address (required)
|
||||||
|
- `mac`: Device MAC address in format AA:BB:CC:DD:EE:FF (required)
|
||||||
|
- `name`: Friendly name for the device (required)
|
||||||
|
- `port`: Device port (optional, default: 80)
|
||||||
|
- `temp_unit`: Temperature unit "C" or "F" (optional, default: C)
|
||||||
|
|
||||||
|
### Resource Configuration
|
||||||
|
|
||||||
|
| Parameter | Description | Default |
|
||||||
|
|-----------|-------------|---------|
|
||||||
|
| `resources.requests.cpu` | CPU request | `50m` |
|
||||||
|
| `resources.requests.memory` | Memory request | `64Mi` |
|
||||||
|
| `resources.limits.cpu` | CPU limit | `200m` |
|
||||||
|
| `resources.limits.memory` | Memory limit | `256Mi` |
|
||||||
|
|
||||||
|
## Health Checks
|
||||||
|
|
||||||
|
The chart includes comprehensive health checks:
|
||||||
|
|
||||||
|
- **Startup Probe**: Allows 60 seconds for MQTT connection and device authentication
|
||||||
|
- **Liveness Probe**: Verifies the main process is running every 30 seconds
|
||||||
|
- **Readiness Probe**: Checks config file presence and process health every 15 seconds
|
||||||
|
|
||||||
|
All probes use process-based checks since the application doesn't expose HTTP endpoints.
|
||||||
|
|
||||||
|
## Home Assistant Integration
|
||||||
|
|
||||||
|
When `config.mqtt.discovery` is enabled, devices automatically appear in Home Assistant as climate entities. The integration supports:
|
||||||
|
|
||||||
|
- Power on/off
|
||||||
|
- Mode selection (cool, heat, auto, fan, dry)
|
||||||
|
- Temperature setpoint
|
||||||
|
- Fan speed control
|
||||||
|
- Swing mode control
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Check pod status
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get pods -l app=broadlinkac2mqtt
|
||||||
|
kubectl logs -l app=broadlinkac2mqtt
|
||||||
|
```
|
||||||
|
|
||||||
|
### Verify configuration
|
||||||
|
|
||||||
|
```bash
|
||||||
|
kubectl get configmap broadlinkac2mqtt-config -o yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
### Common Issues
|
||||||
|
|
||||||
|
1. **Pod won't start**: Check MQTT broker connectivity
|
||||||
|
2. **Devices not discovered**: Verify IP addresses and MAC addresses are correct
|
||||||
|
3. **Connection timeouts**: Ensure devices are on the same network segment
|
||||||
|
4. **MQTT authentication failed**: Verify credentials in secret or config
|
||||||
|
|
||||||
|
## Version Management
|
||||||
|
|
||||||
|
The chart includes version tracking annotations compatible with automated version checking tools:
|
||||||
|
|
||||||
|
```yaml
|
||||||
|
annotations:
|
||||||
|
version-source: github-release:ArtemVladimirov/broadlinkac2mqtt
|
||||||
|
version-pattern: "s|^v||"
|
||||||
|
```
|
||||||
|
|
||||||
|
Check for updates:
|
||||||
|
```bash
|
||||||
|
# Using just (if in k3s repo)
|
||||||
|
just app check broadlinkac2mqtt
|
||||||
|
|
||||||
|
# Or manually check releases
|
||||||
|
curl -s https://api.github.com/repos/ArtemVladimirov/broadlinkac2mqtt/releases/latest | jq -r .tag_name
|
||||||
|
```
|
||||||
|
|
||||||
|
## Upgrading
|
||||||
|
|
||||||
|
Update the chart version:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm upgrade broadlinkac2mqtt ./broadlinkac2mqtt -f values-custom.yaml
|
||||||
|
```
|
||||||
|
|
||||||
|
## Uninstalling
|
||||||
|
|
||||||
|
```bash
|
||||||
|
helm uninstall broadlinkac2mqtt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Notes
|
||||||
|
|
||||||
|
- This is an MQTT-only application with no HTTP interface
|
||||||
|
- Only one replica should run to avoid conflicting device commands
|
||||||
|
- The application uses environment variable substitution for secrets in config.yml
|
||||||
|
- Config changes require pod restart to take effect
|
||||||
@@ -0,0 +1,51 @@
|
|||||||
|
apiVersion: v1
|
||||||
|
kind: ConfigMap
|
||||||
|
metadata:
|
||||||
|
name: {{ .Release.Name }}-config
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ .Chart.Name }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
data:
|
||||||
|
config.yml: |
|
||||||
|
service:
|
||||||
|
update_interval: {{ .Values.config.service.update_interval }}
|
||||||
|
log_level: {{ .Values.config.service.log_level }}
|
||||||
|
|
||||||
|
mqtt:
|
||||||
|
server: {{ .Values.config.mqtt.server | quote }}
|
||||||
|
{{- if .Values.existingSecret }}
|
||||||
|
user: ${MQTT_USER}
|
||||||
|
password: ${MQTT_PASSWORD}
|
||||||
|
{{- else }}
|
||||||
|
user: {{ .Values.config.mqtt.user | quote }}
|
||||||
|
password: {{ .Values.config.mqtt.password | quote }}
|
||||||
|
{{- end }}
|
||||||
|
client_id: {{ .Values.config.mqtt.client_id | quote }}
|
||||||
|
discovery: {{ .Values.config.mqtt.discovery }}
|
||||||
|
discovery_prefix: {{ .Values.config.mqtt.discovery_prefix | quote }}
|
||||||
|
topic_prefix: {{ .Values.config.mqtt.topic_prefix | quote }}
|
||||||
|
state_topic: {{ .Values.config.mqtt.state_topic | quote }}
|
||||||
|
command_topic: {{ .Values.config.mqtt.command_topic | quote }}
|
||||||
|
availability_topic: {{ .Values.config.mqtt.availability_topic | quote }}
|
||||||
|
{{- with .Values.config.mqtt.ca_cert }}
|
||||||
|
ca_cert: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.config.mqtt.client_cert }}
|
||||||
|
client_cert: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.config.mqtt.client_key }}
|
||||||
|
client_key: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
|
||||||
|
devices:
|
||||||
|
{{- range .Values.config.devices }}
|
||||||
|
- ip: {{ .ip | quote }}
|
||||||
|
mac: {{ .mac | quote }}
|
||||||
|
name: {{ .name | quote }}
|
||||||
|
{{- with .port }}
|
||||||
|
port: {{ . }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .temp_unit }}
|
||||||
|
temp_unit: {{ . | quote }}
|
||||||
|
{{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,97 @@
|
|||||||
|
apiVersion: apps/v1
|
||||||
|
kind: Deployment
|
||||||
|
metadata:
|
||||||
|
name: {{ .Release.Name }}
|
||||||
|
labels:
|
||||||
|
app.kubernetes.io/name: {{ .Chart.Name }}
|
||||||
|
app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
app.kubernetes.io/version: {{ .Chart.AppVersion | quote }}
|
||||||
|
app.kubernetes.io/component: mqtt-bridge
|
||||||
|
app.kubernetes.io/part-of: home-automation
|
||||||
|
annotations:
|
||||||
|
version-source: {{ index .Chart.Annotations "version-source" }}
|
||||||
|
version-pattern: {{ index .Chart.Annotations "version-pattern" | quote }}
|
||||||
|
spec:
|
||||||
|
replicas: 1
|
||||||
|
strategy:
|
||||||
|
type: Recreate # Only one instance should control the AC units
|
||||||
|
selector:
|
||||||
|
matchLabels:
|
||||||
|
app: {{ .Release.Name }}
|
||||||
|
template:
|
||||||
|
metadata:
|
||||||
|
labels:
|
||||||
|
app: {{ .Release.Name }}
|
||||||
|
annotations:
|
||||||
|
checksum/config: {{ include (print $.Template.BasePath "/configmap.yaml") . | sha256sum }}
|
||||||
|
spec:
|
||||||
|
{{- with .Values.nodeSelector }}
|
||||||
|
nodeSelector:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.tolerations }}
|
||||||
|
tolerations:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
{{- with .Values.affinity }}
|
||||||
|
affinity:
|
||||||
|
{{- toYaml . | nindent 8 }}
|
||||||
|
{{- end }}
|
||||||
|
containers:
|
||||||
|
- name: {{ .Chart.Name }}
|
||||||
|
image: "{{ .Values.image.repository }}:{{ .Values.image.tag | default .Chart.AppVersion }}"
|
||||||
|
imagePullPolicy: {{ .Values.image.pullPolicy }}
|
||||||
|
env:
|
||||||
|
- name: TZ
|
||||||
|
value: {{ .Values.timezone | quote }}
|
||||||
|
{{- if .Values.existingSecret }}
|
||||||
|
- name: MQTT_USER
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.existingSecret }}
|
||||||
|
key: {{ .Values.secretKeys.mqttUser }}
|
||||||
|
- name: MQTT_PASSWORD
|
||||||
|
valueFrom:
|
||||||
|
secretKeyRef:
|
||||||
|
name: {{ .Values.existingSecret }}
|
||||||
|
key: {{ .Values.secretKeys.mqttPassword }}
|
||||||
|
{{- end }}
|
||||||
|
volumeMounts:
|
||||||
|
- name: config
|
||||||
|
mountPath: /app/config
|
||||||
|
readOnly: true
|
||||||
|
resources:
|
||||||
|
{{- toYaml .Values.resources | nindent 12 }}
|
||||||
|
# Startup probe: give MQTT connection and device auth time to complete
|
||||||
|
startupProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- 'pgrep -f /main > /dev/null'
|
||||||
|
initialDelaySeconds: 5
|
||||||
|
periodSeconds: 5
|
||||||
|
failureThreshold: 12 # 60 seconds total startup time
|
||||||
|
# Liveness probe: verify process is still running
|
||||||
|
livenessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- 'pgrep -f /main > /dev/null'
|
||||||
|
initialDelaySeconds: 30
|
||||||
|
periodSeconds: 30
|
||||||
|
failureThreshold: 3
|
||||||
|
# Readiness probe: check config file is present and process is running
|
||||||
|
readinessProbe:
|
||||||
|
exec:
|
||||||
|
command:
|
||||||
|
- /bin/sh
|
||||||
|
- -c
|
||||||
|
- 'test -f /app/config/config.yml && pgrep -f /main > /dev/null'
|
||||||
|
initialDelaySeconds: 10
|
||||||
|
periodSeconds: 15
|
||||||
|
volumes:
|
||||||
|
- name: config
|
||||||
|
configMap:
|
||||||
|
name: {{ .Release.Name }}-config
|
||||||
@@ -0,0 +1,30 @@
|
|||||||
|
# Ingress is not applicable for broadlinkac2mqtt (MQTT-only application)
|
||||||
|
# This template is included for Helm chart consistency only
|
||||||
|
|
||||||
|
{{- range $name, $ingress := .Values.ingresses }}
|
||||||
|
# ---
|
||||||
|
# apiVersion: traefik.io/v1alpha1
|
||||||
|
# kind: IngressRoute
|
||||||
|
# metadata:
|
||||||
|
# name: {{ $.Release.Name }}-{{ $name }}
|
||||||
|
# labels:
|
||||||
|
# app.kubernetes.io/name: {{ $.Chart.Name }}
|
||||||
|
# app.kubernetes.io/instance: {{ $.Release.Name }}
|
||||||
|
# {{- with $ingress.annotations }}
|
||||||
|
# annotations:
|
||||||
|
# {{- toYaml . | nindent 4 }}
|
||||||
|
# {{- end }}
|
||||||
|
# spec:
|
||||||
|
# entryPoints:
|
||||||
|
# - websecure
|
||||||
|
# routes:
|
||||||
|
# - kind: Rule
|
||||||
|
# match: Host(`{{ $ingress.host }}`)
|
||||||
|
# services:
|
||||||
|
# - name: {{ $.Release.Name }}
|
||||||
|
# port: 80
|
||||||
|
# {{- with $ingress.tls }}
|
||||||
|
# tls:
|
||||||
|
# {{- toYaml . | nindent 4 }}
|
||||||
|
# {{- end }}
|
||||||
|
{{- end }}
|
||||||
@@ -0,0 +1,17 @@
|
|||||||
|
# This service is not used by broadlinkac2mqtt (MQTT-only application)
|
||||||
|
# Included for Helm chart consistency only
|
||||||
|
# apiVersion: v1
|
||||||
|
# kind: Service
|
||||||
|
# metadata:
|
||||||
|
# name: {{ .Release.Name }}
|
||||||
|
# labels:
|
||||||
|
# app.kubernetes.io/name: {{ .Chart.Name }}
|
||||||
|
# app.kubernetes.io/instance: {{ .Release.Name }}
|
||||||
|
# spec:
|
||||||
|
# type: ClusterIP
|
||||||
|
# selector:
|
||||||
|
# app: {{ .Release.Name }}
|
||||||
|
# ports:
|
||||||
|
# - protocol: TCP
|
||||||
|
# port: 80
|
||||||
|
# targetPort: 80
|
||||||
@@ -0,0 +1,79 @@
|
|||||||
|
# Default values for broadlinkac2mqtt Helm chart
|
||||||
|
# Bridge between Broadlink AC units and MQTT
|
||||||
|
|
||||||
|
image:
|
||||||
|
repository: ghcr.io/artemvladimirov/broadlinkac2mqtt
|
||||||
|
tag: "" # defaults to Chart.appVersion if empty
|
||||||
|
pullPolicy: IfNotPresent
|
||||||
|
|
||||||
|
# Timezone for the container
|
||||||
|
timezone: "Europe/Kyiv"
|
||||||
|
|
||||||
|
resources:
|
||||||
|
requests:
|
||||||
|
cpu: "50m"
|
||||||
|
memory: "64Mi"
|
||||||
|
limits:
|
||||||
|
cpu: "200m"
|
||||||
|
memory: "256Mi"
|
||||||
|
|
||||||
|
# Configuration for the application
|
||||||
|
# This will be mounted as /app/config/config.yml inside the container
|
||||||
|
config:
|
||||||
|
# Service configuration
|
||||||
|
service:
|
||||||
|
update_interval: 10 # seconds between device polls
|
||||||
|
log_level: "info" # debug, info, error, disabled
|
||||||
|
|
||||||
|
# MQTT broker configuration
|
||||||
|
mqtt:
|
||||||
|
server: "tcp://mqtt-broker:1883"
|
||||||
|
user: ""
|
||||||
|
password: ""
|
||||||
|
client_id: "broadlinkac2mqtt"
|
||||||
|
|
||||||
|
# Home Assistant MQTT Discovery
|
||||||
|
discovery: true
|
||||||
|
discovery_prefix: "homeassistant"
|
||||||
|
|
||||||
|
# Topic structure
|
||||||
|
topic_prefix: "broadlinkac2mqtt"
|
||||||
|
state_topic: "tele"
|
||||||
|
command_topic: "cmnd"
|
||||||
|
availability_topic: "avty"
|
||||||
|
|
||||||
|
# Optional: TLS/SSL configuration
|
||||||
|
# ca_cert: ""
|
||||||
|
# client_cert: ""
|
||||||
|
# client_key: ""
|
||||||
|
|
||||||
|
# Broadlink AC devices
|
||||||
|
# Each device needs: ip, mac, name, and optionally port and temp_unit
|
||||||
|
devices: []
|
||||||
|
# - ip: "192.168.1.100"
|
||||||
|
# mac: "AA:BB:CC:DD:EE:FF"
|
||||||
|
# name: "Living Room AC"
|
||||||
|
# port: 80
|
||||||
|
# temp_unit: "C" # C or F
|
||||||
|
# - ip: "192.168.1.101"
|
||||||
|
# mac: "11:22:33:44:55:66"
|
||||||
|
# name: "Bedroom AC"
|
||||||
|
# port: 80
|
||||||
|
# temp_unit: "C"
|
||||||
|
|
||||||
|
# Alternative: use existing secret for MQTT credentials
|
||||||
|
# If set, mqtt.user and mqtt.password from config above will be ignored
|
||||||
|
existingSecret: ""
|
||||||
|
secretKeys:
|
||||||
|
mqttUser: "MQTT_USER"
|
||||||
|
mqttPassword: "MQTT_PASSWORD"
|
||||||
|
|
||||||
|
# Node scheduling
|
||||||
|
nodeSelector: {}
|
||||||
|
|
||||||
|
tolerations: []
|
||||||
|
|
||||||
|
affinity: {}
|
||||||
|
|
||||||
|
# Ingress configuration (not used by this MQTT-only app, but kept for consistency)
|
||||||
|
ingresses: {}
|
||||||
Reference in New Issue
Block a user