Merge pull request #2853 from Aircoookie/PIR-HA-discovery
Add HA discovery option to PIR sermod
This commit is contained in:
commit
7211e6b929
@ -22,36 +22,20 @@
|
|||||||
*
|
*
|
||||||
* v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example.
|
* v2 usermods are class inheritance based and can (but don't have to) implement more functions, each of them is shown in this example.
|
||||||
* Multiple v2 usermods can be added to one compilation easily.
|
* Multiple v2 usermods can be added to one compilation easily.
|
||||||
*
|
|
||||||
* Creating a usermod:
|
|
||||||
* This file serves as an example. If you want to create a usermod, it is recommended to use usermod_v2_empty.h from the usermods folder as a template.
|
|
||||||
* Please remember to rename the class and file to a descriptive name.
|
|
||||||
* You may also use multiple .h and .cpp files.
|
|
||||||
*
|
|
||||||
* Using a usermod:
|
|
||||||
* 1. Copy the usermod into the sketch folder (same folder as wled00.ino)
|
|
||||||
* 2. Register the usermod by adding #include "usermod_filename.h" in the top and registerUsermod(new MyUsermodClass()) in the bottom of usermods_list.cpp
|
|
||||||
*/
|
*/
|
||||||
|
|
||||||
class PIRsensorSwitch : public Usermod
|
class PIRsensorSwitch : public Usermod
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
/**
|
// constructor
|
||||||
* constructor
|
|
||||||
*/
|
|
||||||
PIRsensorSwitch() {}
|
PIRsensorSwitch() {}
|
||||||
/**
|
// destructor
|
||||||
* desctructor
|
|
||||||
*/
|
|
||||||
~PIRsensorSwitch() {}
|
~PIRsensorSwitch() {}
|
||||||
|
|
||||||
/**
|
//Enable/Disable the PIR sensor
|
||||||
* Enable/Disable the PIR sensor
|
|
||||||
*/
|
|
||||||
void EnablePIRsensor(bool en) { enabled = en; }
|
void EnablePIRsensor(bool en) { enabled = en; }
|
||||||
/**
|
|
||||||
* Get PIR sensor enabled/disabled state
|
// Get PIR sensor enabled/disabled state
|
||||||
*/
|
|
||||||
bool PIRsensorEnabled() { return enabled; }
|
bool PIRsensorEnabled() { return enabled; }
|
||||||
|
|
||||||
private:
|
private:
|
||||||
@ -78,6 +62,9 @@ private:
|
|||||||
bool m_offOnly = false;
|
bool m_offOnly = false;
|
||||||
bool m_offMode = offMode;
|
bool m_offMode = offMode;
|
||||||
|
|
||||||
|
// Home Assistant
|
||||||
|
bool HomeAssistantDiscovery = false; // is HA discovery turned on
|
||||||
|
|
||||||
// strings to reduce flash memory usage (used more than twice)
|
// strings to reduce flash memory usage (used more than twice)
|
||||||
static const char _name[];
|
static const char _name[];
|
||||||
static const char _switchOffDelay[];
|
static const char _switchOffDelay[];
|
||||||
@ -87,6 +74,7 @@ private:
|
|||||||
static const char _nightTime[];
|
static const char _nightTime[];
|
||||||
static const char _mqttOnly[];
|
static const char _mqttOnly[];
|
||||||
static const char _offOnly[];
|
static const char _offOnly[];
|
||||||
|
static const char _haDiscovery[];
|
||||||
static const char _notify[];
|
static const char _notify[];
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -167,7 +155,7 @@ private:
|
|||||||
void publishMqtt(const char* state)
|
void publishMqtt(const char* state)
|
||||||
{
|
{
|
||||||
//Check if MQTT Connected, otherwise it will crash the 8266
|
//Check if MQTT Connected, otherwise it will crash the 8266
|
||||||
if (WLED_MQTT_CONNECTED){
|
if (WLED_MQTT_CONNECTED) {
|
||||||
char subuf[64];
|
char subuf[64];
|
||||||
strcpy(subuf, mqttDeviceTopic);
|
strcpy(subuf, mqttDeviceTopic);
|
||||||
strcat_P(subuf, PSTR("/motion"));
|
strcat_P(subuf, PSTR("/motion"));
|
||||||
@ -175,6 +163,40 @@ private:
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Create an MQTT Binary Sensor for Home Assistant Discovery purposes, this includes a pointer to the topic that is published to in the Loop.
|
||||||
|
void publishHomeAssistantAutodiscovery()
|
||||||
|
{
|
||||||
|
if (WLED_MQTT_CONNECTED) {
|
||||||
|
StaticJsonDocument<600> doc;
|
||||||
|
char uid[24], json_str[1024], buf[128];
|
||||||
|
|
||||||
|
sprintf_P(buf, PSTR("%s Motion"), serverDescription); //max length: 33 + 7 = 40
|
||||||
|
doc[F("name")] = buf;
|
||||||
|
sprintf_P(buf, PSTR("%s/motion"), mqttDeviceTopic); //max length: 33 + 7 = 40
|
||||||
|
doc[F("stat_t")] = buf;
|
||||||
|
doc[F("pl_on")] = "on";
|
||||||
|
doc[F("pl_off")] = "off";
|
||||||
|
sprintf_P(uid, PSTR("%s_motion"), escapedMac.c_str());
|
||||||
|
doc[F("uniq_id")] = uid;
|
||||||
|
doc[F("dev_cla")] = F("motion");
|
||||||
|
doc[F("exp_aft")] = 1800;
|
||||||
|
|
||||||
|
JsonObject device = doc.createNestedObject(F("device")); // attach the sensor to the same device
|
||||||
|
device[F("name")] = serverDescription;
|
||||||
|
device[F("ids")] = String(F("wled-sensor-")) + mqttClientID;
|
||||||
|
device[F("mf")] = "WLED";
|
||||||
|
device[F("mdl")] = F("FOSS");
|
||||||
|
device[F("sw")] = versionString;
|
||||||
|
|
||||||
|
sprintf_P(buf, PSTR("homeassistant/binary_sensor/%s/config"), uid);
|
||||||
|
DEBUG_PRINTLN(buf);
|
||||||
|
size_t payload_size = serializeJson(doc, json_str);
|
||||||
|
DEBUG_PRINTLN(json_str);
|
||||||
|
|
||||||
|
mqtt->publish(buf, 0, true, json_str, payload_size); // do we really need to retain?
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Read and update PIR sensor state.
|
* Read and update PIR sensor state.
|
||||||
* Initilize/reset switch off timer
|
* Initilize/reset switch off timer
|
||||||
@ -251,6 +273,15 @@ public:
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/**
|
||||||
|
* onMqttConnect() is called when MQTT connection is established
|
||||||
|
*/
|
||||||
|
void onMqttConnect(bool sessionPresent) {
|
||||||
|
if (HomeAssistantDiscovery) {
|
||||||
|
publishHomeAssistantAutodiscovery();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
* loop() is called continuously. Here you can check for events, read sensors, etc.
|
||||||
*/
|
*/
|
||||||
@ -371,10 +402,17 @@ public:
|
|||||||
top[FPSTR(_nightTime)] = m_nightTimeOnly;
|
top[FPSTR(_nightTime)] = m_nightTimeOnly;
|
||||||
top[FPSTR(_mqttOnly)] = m_mqttOnly;
|
top[FPSTR(_mqttOnly)] = m_mqttOnly;
|
||||||
top[FPSTR(_offOnly)] = m_offOnly;
|
top[FPSTR(_offOnly)] = m_offOnly;
|
||||||
|
top[FPSTR(_haDiscovery)] = HomeAssistantDiscovery;
|
||||||
top[FPSTR(_notify)] = (NotifyUpdateMode != CALL_MODE_NO_NOTIFY);
|
top[FPSTR(_notify)] = (NotifyUpdateMode != CALL_MODE_NO_NOTIFY);
|
||||||
DEBUG_PRINTLN(F("PIR config saved."));
|
DEBUG_PRINTLN(F("PIR config saved."));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void appendConfigData()
|
||||||
|
{
|
||||||
|
oappend(SET_F("addInfo('PIRsensorSwitch:HA-discovery',1,'HA=Home Assistant');")); // 0 is field type, 1 is actual field
|
||||||
|
oappend(SET_F("addInfo('PIRsensorSwitch:notifications',1,'Periodic WS updates');")); // 0 is field type, 1 is actual field
|
||||||
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* restore the changeable values
|
* restore the changeable values
|
||||||
* readFromConfig() is called before setup() to populate properties from values stored in cfg.json
|
* readFromConfig() is called before setup() to populate properties from values stored in cfg.json
|
||||||
@ -407,6 +445,7 @@ public:
|
|||||||
m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly;
|
m_nightTimeOnly = top[FPSTR(_nightTime)] | m_nightTimeOnly;
|
||||||
m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly;
|
m_mqttOnly = top[FPSTR(_mqttOnly)] | m_mqttOnly;
|
||||||
m_offOnly = top[FPSTR(_offOnly)] | m_offOnly;
|
m_offOnly = top[FPSTR(_offOnly)] | m_offOnly;
|
||||||
|
HomeAssistantDiscovery = top[FPSTR(_haDiscovery)] | HomeAssistantDiscovery;
|
||||||
|
|
||||||
NotifyUpdateMode = top[FPSTR(_notify)] ? CALL_MODE_DIRECT_CHANGE : CALL_MODE_NO_NOTIFY;
|
NotifyUpdateMode = top[FPSTR(_notify)] ? CALL_MODE_DIRECT_CHANGE : CALL_MODE_NO_NOTIFY;
|
||||||
|
|
||||||
@ -435,7 +474,7 @@ public:
|
|||||||
DEBUG_PRINTLN(F(" config (re)loaded."));
|
DEBUG_PRINTLN(F(" config (re)loaded."));
|
||||||
}
|
}
|
||||||
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
// use "return !top["newestParameter"].isNull();" when updating Usermod with new features
|
||||||
return !top[FPSTR(_notify)].isNull();
|
return !top[FPSTR(_haDiscovery)].isNull();
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
@ -457,4 +496,5 @@ const char PIRsensorSwitch::_offPreset[] PROGMEM = "off-preset";
|
|||||||
const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only";
|
const char PIRsensorSwitch::_nightTime[] PROGMEM = "nighttime-only";
|
||||||
const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only";
|
const char PIRsensorSwitch::_mqttOnly[] PROGMEM = "mqtt-only";
|
||||||
const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";
|
const char PIRsensorSwitch::_offOnly[] PROGMEM = "off-only";
|
||||||
|
const char PIRsensorSwitch::_haDiscovery[] PROGMEM = "HA-discovery";
|
||||||
const char PIRsensorSwitch::_notify[] PROGMEM = "notifications";
|
const char PIRsensorSwitch::_notify[] PROGMEM = "notifications";
|
||||||
|
Loading…
Reference in New Issue
Block a user