- neues Paket mqttheartbeat: Publisher mit paho, topic signage/screen/<id>/heartbeat,
payload {screen_id, ts, status, server_connectivity}, auto-reconnect bei Ausfall
- MORZ_INFOBOARD_MQTT_BROKER leer (Standard) -> MQTT komplett uebersprungen
- app.emitHeartbeat() publiziert bei jedem Tick per MQTT wenn Broker konfiguriert,
loggt Fehler und laeuft weiter (kein Stop bei MQTT-Ausfall)
- mqtt.Close() bei context.Done()
- MQTTBroker-Default von tcp://127.0.0.1:1883 auf "" geaendert
- erste externe Dep: github.com/eclipse/paho.mqtt.golang v1.5.1
Co-Authored-By: Claude Sonnet 4.6 <noreply@anthropic.com>
60 lines
1.7 KiB
Go
60 lines
1.7 KiB
Go
package mqttheartbeat
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestBuildPayloadContainsAllFields(t *testing.T) {
|
|
ts := time.Date(2026, 3, 22, 16, 9, 30, 0, time.UTC)
|
|
|
|
data, err := BuildPayload("info01-dev", "running", "online", ts)
|
|
if err != nil {
|
|
t.Fatalf("BuildPayload() error = %v", err)
|
|
}
|
|
|
|
var p struct {
|
|
ScreenID string `json:"screen_id"`
|
|
Timestamp string `json:"ts"`
|
|
Status string `json:"status"`
|
|
ServerConnectivity string `json:"server_connectivity"`
|
|
}
|
|
if err := json.Unmarshal(data, &p); err != nil {
|
|
t.Fatalf("Unmarshal() error = %v", err)
|
|
}
|
|
|
|
if got, want := p.ScreenID, "info01-dev"; got != want {
|
|
t.Errorf("screen_id = %q, want %q", got, want)
|
|
}
|
|
if got, want := p.Timestamp, "2026-03-22T16:09:30Z"; got != want {
|
|
t.Errorf("ts = %q, want %q", got, want)
|
|
}
|
|
if got, want := p.Status, "running"; got != want {
|
|
t.Errorf("status = %q, want %q", got, want)
|
|
}
|
|
if got, want := p.ServerConnectivity, "online"; got != want {
|
|
t.Errorf("server_connectivity = %q, want %q", got, want)
|
|
}
|
|
}
|
|
|
|
func TestBuildPayloadTimestampIsUTC(t *testing.T) {
|
|
loc := time.FixedZone("CET", 1*60*60)
|
|
ts := time.Date(2026, 3, 22, 17, 9, 30, 0, loc) // same moment, different zone
|
|
|
|
data, err := BuildPayload("screen-x", "running", "online", ts)
|
|
if err != nil {
|
|
t.Fatalf("BuildPayload() error = %v", err)
|
|
}
|
|
|
|
if !strings.Contains(string(data), "2026-03-22T16:09:30Z") {
|
|
t.Errorf("payload %s: expected UTC timestamp 2026-03-22T16:09:30Z", data)
|
|
}
|
|
}
|
|
|
|
func TestTopicFormat(t *testing.T) {
|
|
if got, want := Topic("info01-dev"), "signage/screen/info01-dev/heartbeat"; got != want {
|
|
t.Fatalf("Topic() = %q, want %q", got, want)
|
|
}
|
|
}
|