#pragma once #include #include #include #include #include #include // One HA entity (docs/DESIGN.md, D23): the base class of every entity type. // It describes the entity for discovery, holds its current state, throttles // state changes (SEN-14) and knows whether it has a value (SEN-15: without // one, HA shows it as unavailable). // // It knows nothing about MQTT: HaDevice publishes what it reports. class HaEntity : public QObject { Q_OBJECT public: struct Description { // Topic level and suffix of the unique id, e.g. "uptime". QString id; // Name shown in HA, e.g. "Uptime". QString name; // Optional: HA device class, unit, entity category ("diagnostic", …). QString deviceClass; QString unit; QString category; // Minimum time between two published states (SEN-14). int throttleMs = 1000; }; // `platform`: the HA entity type, e.g. "sensor". HaEntity(QString platform, Description description, QObject* parent = nullptr); const QString& platform() const { return m_platform; } const Description& description() const { return m_description; } // The component for device-based discovery; topics are relative to the // device's base topic "~". `uniqueIdPrefix`: e.g. // "frameassistant_". virtual QJsonObject discoveryComponent(const QString& uniqueIdPrefix) const; // Topics relative to the device's base topic. QString stateTopic() const; QString availabilityTopic() const; bool hasValue() const { return m_hasValue; } // The state as published; empty without a value. QByteArray state() const { return m_hasValue ? m_state : QByteArray(); } signals: // A new state to publish, at most once per throttle interval (the newest // one wins). Emitted before availabilityChanged(true) for a first value. void stateChanged(const QByteArray& state); void availabilityChanged(bool available); protected: // For the concrete types: set or clear the state. void updateState(const QByteArray& state); void clearState(); private: void emitState(); const QString m_platform; const Description m_description; QByteArray m_state; bool m_hasValue = false; // The state last emitted, and when. QByteArray m_emittedState; QElapsedTimer m_sinceEmit; QTimer m_throttle; };