mirror of
https://github.com/alexhopeoconnor/arduino-home-assistant.git
synced 2026-10-04 02:48:13 +10:00
Per-entity availability, deferred discovery publish, suggested precision
- Add HAAvailabilityConfig for per-entity availability_topic and payloads - Defer discovery until MQTT connected; publish availability after discovery - HASensor/HANumber: optional suggested_display_precision in discovery - HASerializer/HADictionary: extend for new keys; update device types and mocks - Docs and examples reflect availability and precision usage - Tests updated for discovery and availability behavior - Ignore .cursor/ in repo root
This commit is contained in:
@@ -13,6 +13,8 @@ Represents the physical board in Home Assistant: one device can expose multiple
|
||||
**Optional metadata** (each costs some RAM/flash; skip on tiny MCUs unless needed):
|
||||
|
||||
- `setName`, `setSoftwareVersion`, `setManufacturer`, `setModel`, `setConfigurationUrl`
|
||||
- `setModelId`, `setHardwareVersion`, `setSerialNumber`, `setSuggestedArea`, `setViaDevice`
|
||||
- `addConnection("mac", "aa:bb:cc:dd:ee:ff")` or `setConnectionsJson("[[\"mac\",\"aa:bb:cc:dd:ee:ff\"]]")`
|
||||
|
||||
String setters take **pointers whose contents are not copied** — use literals or storage that outlives the call.
|
||||
|
||||
@@ -41,8 +43,28 @@ mqtt.setDataPrefix("myDataPrefix");
|
||||
- **Default:** one retained discovery topic per entity (single-component discovery).
|
||||
- **Optional:** call `HAMqtt::enableDeviceDiscovery()` to publish a single **device** discovery payload with components under `cmps` (see project README for migration notes).
|
||||
|
||||
Device discovery can also publish richer origin/device metadata, for example:
|
||||
|
||||
```cpp
|
||||
device.setModelId("esp32-s3-devkit");
|
||||
device.setHardwareVersion("rev-b");
|
||||
device.setSerialNumber("SN-00042");
|
||||
device.setSuggestedArea("Garage");
|
||||
device.setViaDevice("main_gateway");
|
||||
device.addConnection("mac", "AA:BB:CC:DD:EE:FF");
|
||||
mqtt.setOriginSupportUrl("https://example.com/device-help");
|
||||
```
|
||||
|
||||
For entity identifiers in Home Assistant, prefer **`setDefaultEntityId()`** over legacy **`setObjectId()`**.
|
||||
|
||||
Common entity discovery metadata can be configured on most entity types via:
|
||||
|
||||
- `setEnabledByDefault(bool)`
|
||||
- `setEntityPicture(const char*)`
|
||||
- `setQos(uint8_t)`
|
||||
- `setEncoding(const char*)`
|
||||
- `setEntityCategory(const char*)`
|
||||
|
||||
### Runtime discovery changes
|
||||
|
||||
After changing discovery-related settings at runtime:
|
||||
|
||||
@@ -46,12 +46,70 @@ mqtt.publish("customTopic", "payload", true); // retained
|
||||
|
||||
```cpp
|
||||
device.enableSharedAvailability();
|
||||
device.setPayloadAvailable("up");
|
||||
device.setPayloadNotAvailable("down");
|
||||
device.enableLastWill(); // broker publishes offline when TCP drops
|
||||
// device.setAvailability(false); // optional: start as offline
|
||||
```
|
||||
|
||||
**Per-entity availability:** call `someEntity.setAvailability(true/false)` on each type. Does not use LWT the same way as shared mode; see examples under `examples/availability/`.
|
||||
|
||||
Custom per-entity payloads are supported:
|
||||
|
||||
```cpp
|
||||
sensor.setPayloadAvailable("ready");
|
||||
sensor.setPayloadNotAvailable("lost");
|
||||
```
|
||||
|
||||
For multi-topic availability discovery, add full MQTT topics and a mode:
|
||||
|
||||
```cpp
|
||||
sensor.setAvailabilityMode("all");
|
||||
sensor.addAvailabilityEntry("bridge/status");
|
||||
sensor.addAvailabilityEntry("sensor/status", "{{ value_json.state }}");
|
||||
```
|
||||
|
||||
## Discovery helpers by entity
|
||||
|
||||
Common entity discovery metadata is available on most entity classes:
|
||||
|
||||
```cpp
|
||||
entity.setEnabledByDefault(false);
|
||||
entity.setEntityPicture("https://example.com/entity.png");
|
||||
entity.setQos(1);
|
||||
entity.setEncoding("utf-8");
|
||||
entity.setEntityCategory("diagnostic");
|
||||
```
|
||||
|
||||
Read-only sensor presentation/template helpers:
|
||||
|
||||
```cpp
|
||||
sensor.setSuggestedDisplayPrecision(2);
|
||||
sensor.setValueTemplate("{{ value_json.temperature }}");
|
||||
sensor.setJsonAttributesTemplate("{{ value_json.attrs | tojson }}");
|
||||
sensor.setLastResetValueTemplate("{{ value_json.last_reset }}");
|
||||
sensor.setDeviceClass("enum");
|
||||
sensor.setOptions("idle;charging;discharging;fault");
|
||||
```
|
||||
|
||||
Writable entity template/payload helpers:
|
||||
|
||||
```cpp
|
||||
mySwitch.setPayloadOn("ENABLE");
|
||||
mySwitch.setPayloadOff("DISABLE");
|
||||
mySwitch.setStateOn("running");
|
||||
mySwitch.setStateOff("stopped");
|
||||
mySwitch.setValueTemplate("{{ value_json.state }}");
|
||||
mySwitch.setCommandTemplate("{{ value_json.command }}");
|
||||
|
||||
myNumber.setPayloadReset("RESET");
|
||||
myNumber.setCommandTemplate("{{ value | float | round(1) }}");
|
||||
|
||||
mySelect.setCommandTemplate("{{ value_json.choice }}");
|
||||
myText.setCommandTemplate("{{ value_json.text }}");
|
||||
myButton.setPayloadPress("PRESS");
|
||||
```
|
||||
|
||||
## Compiler macros
|
||||
|
||||
Defined in `ArduinoHADefines.h` or via build flags.
|
||||
|
||||
Reference in New Issue
Block a user