2026-10-13 00:56:32 +02:00
|
|
|
#include "net/home_assistant.h"
|
|
|
|
|
|
|
|
|
|
#include <ArduinoHA.h>
|
|
|
|
|
#include <WiFi.h>
|
2026-10-13 01:05:06 +02:00
|
|
|
#include <string.h>
|
2026-10-13 00:56:32 +02:00
|
|
|
|
|
|
|
|
#include "config.h"
|
|
|
|
|
#include "credentials.h"
|
2026-10-13 01:21:04 +02:00
|
|
|
#include "system/boot_target.h"
|
2026-10-13 00:56:32 +02:00
|
|
|
|
|
|
|
|
static WiFiClient client;
|
|
|
|
|
static HADevice device(HA_DEVICE_ID, sizeof(HA_DEVICE_ID));
|
|
|
|
|
static HAMqtt mqtt(client, device);
|
|
|
|
|
|
|
|
|
|
// Unique ids: do not change, Home Assistant's entities are linked to them
|
|
|
|
|
static HASwitch clockSwitch("FlipDotDisplayClock");
|
|
|
|
|
static HASwitch powerSwitch("FlipDotDisplayPower");
|
2026-10-13 01:05:06 +02:00
|
|
|
static HASensor firmwareSensor("FlipDotDisplayFirmware");
|
2026-10-13 01:21:04 +02:00
|
|
|
static HAButton recoveryButton("FlipDotDisplayRecovery");
|
2026-10-13 01:05:06 +02:00
|
|
|
|
|
|
|
|
static char firmware_status[64] = "";
|
|
|
|
|
static bool firmware_status_sent = false;
|
2026-10-13 00:56:32 +02:00
|
|
|
|
|
|
|
|
static DisplayController *displayController = nullptr;
|
2026-10-13 01:52:34 +02:00
|
|
|
static bool enabled = false;
|
2026-10-13 00:56:32 +02:00
|
|
|
|
|
|
|
|
// The switches are not optimistic: the new state must be reported back to Home Assistant
|
|
|
|
|
static void onClockCommand(bool state, HASwitch *sender)
|
|
|
|
|
{
|
|
|
|
|
displayController->setClockEnabled(state);
|
|
|
|
|
sender->setState(state);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
static void onPowerCommand(bool state, HASwitch *sender)
|
|
|
|
|
{
|
|
|
|
|
displayController->setPowerEnabled(state);
|
|
|
|
|
sender->setState(state);
|
|
|
|
|
}
|
|
|
|
|
|
2026-10-13 01:52:34 +02:00
|
|
|
void homeAssistantBegin(DisplayController &controller, const HomeAssistantSettings &settings)
|
2026-10-13 00:56:32 +02:00
|
|
|
{
|
|
|
|
|
displayController = &controller;
|
2026-10-13 01:52:34 +02:00
|
|
|
enabled = settings.enabled;
|
|
|
|
|
if (!enabled)
|
|
|
|
|
{
|
|
|
|
|
Serial.println("Home Assistant disabled in the settings");
|
|
|
|
|
return;
|
|
|
|
|
}
|
2026-10-13 00:56:32 +02:00
|
|
|
|
|
|
|
|
device.setName(HA_DEVICE_NAME);
|
|
|
|
|
device.setSoftwareVersion(HA_SOFTWARE_VERSION);
|
|
|
|
|
|
|
|
|
|
clockSwitch.setName("FlipDot Display Clock");
|
|
|
|
|
clockSwitch.setIcon("mdi:lightbulb");
|
|
|
|
|
clockSwitch.setCurrentState(controller.clockEnabled());
|
|
|
|
|
clockSwitch.onCommand(onClockCommand);
|
|
|
|
|
|
|
|
|
|
powerSwitch.setName("FlipDot Display Power");
|
|
|
|
|
powerSwitch.setIcon("mdi:lightbulb");
|
|
|
|
|
powerSwitch.setCurrentState(controller.powerEnabled());
|
|
|
|
|
powerSwitch.onCommand(onPowerCommand);
|
|
|
|
|
|
2026-10-13 01:21:04 +02:00
|
|
|
recoveryButton.setName("FlipDot Display Recovery");
|
|
|
|
|
recoveryButton.setIcon("mdi:lifebuoy");
|
|
|
|
|
recoveryButton.onCommand([](HAButton *) { rebootToRecovery(RecoveryReason::Manual); });
|
|
|
|
|
|
2026-10-13 01:05:06 +02:00
|
|
|
firmwareSensor.setName("FlipDot Display Firmware");
|
|
|
|
|
firmwareSensor.setIcon("mdi:chip");
|
|
|
|
|
// The sensor doesn't resend its value on reconnect by itself
|
|
|
|
|
mqtt.onConnected([]() { firmware_status_sent = false; });
|
|
|
|
|
|
2026-10-13 01:52:34 +02:00
|
|
|
// settings must stay alive: the MQTT library keeps the pointers
|
|
|
|
|
if (settings.host[0])
|
|
|
|
|
mqtt.begin(settings.host, settings.port, settings.user[0] ? settings.user : nullptr,
|
|
|
|
|
settings.password[0] ? settings.password : nullptr);
|
|
|
|
|
else
|
|
|
|
|
mqtt.begin(BROKER_ADDR, settings.port, MQTT_USER, MQTT_PASSWORD); // secrets.h
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
bool homeAssistantConnected()
|
|
|
|
|
{
|
|
|
|
|
return enabled && mqtt.isConnected();
|
2026-10-13 00:56:32 +02:00
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void homeAssistantLoop()
|
|
|
|
|
{
|
2026-10-13 01:52:34 +02:00
|
|
|
if (!enabled)
|
|
|
|
|
return;
|
2026-10-13 00:56:32 +02:00
|
|
|
mqtt.loop();
|
2026-10-13 01:05:06 +02:00
|
|
|
if (!firmware_status_sent && firmware_status[0] && mqtt.isConnected())
|
|
|
|
|
firmware_status_sent = firmwareSensor.setValue(firmware_status);
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
void homeAssistantSetFirmwareStatus(const char *status)
|
|
|
|
|
{
|
|
|
|
|
if (strcmp(status, firmware_status) == 0)
|
|
|
|
|
return;
|
|
|
|
|
strncpy(firmware_status, status, sizeof(firmware_status) - 1);
|
|
|
|
|
firmware_status_sent = false;
|
2026-10-13 00:56:32 +02:00
|
|
|
}
|