A few fixes.

Added HA autodiscovery to Multi relay usermod.
This commit is contained in:
Blaz Kristan 2022-01-21 17:30:52 +01:00
parent ed2e083d13
commit 3332375d7c
6 changed files with 1628 additions and 1569 deletions

View File

@ -58,12 +58,12 @@ class MultiRelay : public Usermod {
static const char _button[]; static const char _button[];
static const char _broadcast[]; static const char _broadcast[];
void publishMqtt(const char* state, int relay) { void publishMqtt(int relay) {
//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];
sprintf_P(subuf, PSTR("%s/relay/%d"), mqttDeviceTopic, relay); sprintf_P(subuf, PSTR("%s/relay/%d"), mqttDeviceTopic, relay);
mqtt->publish(subuf, 0, false, state); mqtt->publish(subuf, 0, false, _relay[relay].state ? "on" : "off");
} }
} }
@ -78,7 +78,7 @@ class MultiRelay : public Usermod {
if (!_relay[i].external) toggleRelay(i); if (!_relay[i].external) toggleRelay(i);
_relay[i].active = false; _relay[i].active = false;
} else if (periodicBroadcastSec && now - lastBroadcast > (periodicBroadcastSec*1000)) { } else if (periodicBroadcastSec && now - lastBroadcast > (periodicBroadcastSec*1000)) {
if (_relay[i].pin>=0) publishMqtt(_relay[i].state ? "on" : "off", i); if (_relay[i].pin>=0) publishMqtt(i);
} }
activeRelays = activeRelays || _relay[i].active; activeRelays = activeRelays || _relay[i].active;
} }
@ -112,7 +112,7 @@ class MultiRelay : public Usermod {
for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (int i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
int value = getValue(p->value(), ',', i); int value = getValue(p->value(), ',', i);
if (value==-1) { if (value==-1) {
error = F("There must be as much arugments as relays"); error = F("There must be as many arguments as relays");
} else { } else {
// Switch // Switch
if (_relay[i].external) switchRelay(i, (bool)value); if (_relay[i].external) switchRelay(i, (bool)value);
@ -125,7 +125,7 @@ class MultiRelay : public Usermod {
for (int i=0;i<MULTI_RELAY_MAX_RELAYS;i++) { for (int i=0;i<MULTI_RELAY_MAX_RELAYS;i++) {
int value = getValue(p->value(), ',', i); int value = getValue(p->value(), ',', i);
if (value==-1) { if (value==-1) {
error = F("There must be as mutch arugments as relays"); error = F("There must be as many arguments as relays");
} else { } else {
// Toggle // Toggle
if (value && _relay[i].external) toggleRelay(i); if (value && _relay[i].external) toggleRelay(i);
@ -206,7 +206,7 @@ class MultiRelay : public Usermod {
_relay[relay].state = mode; _relay[relay].state = mode;
pinMode(_relay[relay].pin, OUTPUT); pinMode(_relay[relay].pin, OUTPUT);
digitalWrite(_relay[relay].pin, mode ? !_relay[relay].mode : _relay[relay].mode); digitalWrite(_relay[relay].pin, mode ? !_relay[relay].mode : _relay[relay].mode);
publishMqtt(mode ? "on" : "off", relay); publishMqtt(relay);
} }
/** /**
@ -259,6 +259,50 @@ class MultiRelay : public Usermod {
strcpy(subuf, mqttDeviceTopic); strcpy(subuf, mqttDeviceTopic);
strcat_P(subuf, PSTR("/relay/#")); strcat_P(subuf, PSTR("/relay/#"));
mqtt->subscribe(subuf, 0); mqtt->subscribe(subuf, 0);
publishHomeAssistantAutodiscovery();
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin<0) continue;
publishMqtt(i); //publish current state
}
}
}
void publishHomeAssistantAutodiscovery() {
for (uint8_t i = 0; i < MULTI_RELAY_MAX_RELAYS; i++) {
char uid[16], json_str[1024], buf[128];
size_t payload_size;
sprintf_P(uid, PSTR("%s_sw%d"), escapedMac.c_str(), i);
if (_relay[i].pin >= 0 && _relay[i].external) {
StaticJsonDocument<1024> json;
sprintf_P(buf, PSTR("%s Switch %d"), serverDescription, i); //max length: 33 + 8 + 3 = 44
json[F("name")] = buf;
sprintf_P(buf, PSTR("%s/relay/%d"), mqttDeviceTopic, i); //max length: 33 + 7 + 3 = 43
json["~"] = buf;
strcat_P(buf, PSTR("/command"));
mqtt->subscribe(buf, 0);
json[F("stat_t")] = "~";
json[F("cmd_t")] = F("~/command");
json[F("pl_off")] = F("off");
json[F("pl_on")] = F("on");
json[F("uniq_id")] = uid;
strcpy(buf, mqttDeviceTopic); //max length: 33 + 7 = 40
strcat_P(buf, PSTR("/status"));
json[F("avty_t")] = buf;
json[F("pl_avail")] = F("online");
json[F("pl_not_avail")] = F("offline");
//TODO: dev
payload_size = serializeJson(json, json_str);
} else {
//Unpublish disabled or internal relays
json_str[0] = 0;
payload_size = 0;
}
sprintf_P(buf, PSTR("homeassistant/switch/%s/config"), uid);
mqtt->publish(buf, 0, true, json_str, payload_size);
} }
} }
@ -320,13 +364,18 @@ class MultiRelay : public Usermod {
*/ */
bool handleButton(uint8_t b) { bool handleButton(uint8_t b) {
yield(); yield();
if (buttonType[b] == BTN_TYPE_NONE || buttonType[b] == BTN_TYPE_RESERVED || buttonType[b] == BTN_TYPE_PIR_SENSOR || buttonType[b] == BTN_TYPE_ANALOG || buttonType[b] == BTN_TYPE_ANALOG_INVERTED) { if (!enabled
|| buttonType[b] == BTN_TYPE_NONE
|| buttonType[b] == BTN_TYPE_RESERVED
|| buttonType[b] == BTN_TYPE_PIR_SENSOR
|| buttonType[b] == BTN_TYPE_ANALOG
|| buttonType[b] == BTN_TYPE_ANALOG_INVERTED) {
return false; return false;
} }
bool handled = false; bool handled = false;
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].button == b) { if (_relay[i].button == b && _relay[i].external) {
handled = true; handled = true;
} }
} }
@ -362,6 +411,8 @@ class MultiRelay : public Usermod {
buttonPressedBefore[b] = true; buttonPressedBefore[b] = true;
if (now - buttonPressedTime[b] > 600) { //long press if (now - buttonPressedTime[b] > 600) { //long press
//longPressAction(b); //not exposed
//handled = false; //use if you want to pass to default behaviour
buttonLongPressed[b] = true; buttonLongPressed[b] = true;
} }
@ -378,7 +429,8 @@ class MultiRelay : public Usermod {
if (!buttonLongPressed[b]) { //short press if (!buttonLongPressed[b]) { //short press
// if this is second release within 350ms it is a double press (buttonWaitTime!=0) // if this is second release within 350ms it is a double press (buttonWaitTime!=0)
if (doublePress) { if (doublePress) {
//doublePressAction(b); //doublePressAction(b); //not exposed
//handled = false; //use if you want to pass to default behaviour
} else { } else {
buttonWaitTime[b] = now; buttonWaitTime[b] = now;
} }
@ -386,9 +438,10 @@ class MultiRelay : public Usermod {
buttonPressedBefore[b] = false; buttonPressedBefore[b] = false;
buttonLongPressed[b] = false; buttonLongPressed[b] = false;
} }
// if 450ms elapsed since last press/release it is a short press // if 350ms elapsed since last press/release it is a short press
if (buttonWaitTime[b] && now - buttonWaitTime[b] > 350 && !buttonPressedBefore[b]) { if (buttonWaitTime[b] && now - buttonWaitTime[b] > 350 && !buttonPressedBefore[b]) {
buttonWaitTime[b] = 0; buttonWaitTime[b] = 0;
//shortPressAction(b); //not exposed
for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) { for (uint8_t i=0; i<MULTI_RELAY_MAX_RELAYS; i++) {
if (_relay[i].pin>=0 && _relay[i].button == b) { if (_relay[i].pin>=0 && _relay[i].button == b) {
toggleRelay(i); toggleRelay(i);

View File

@ -873,6 +873,8 @@ class FourLineDisplayUsermod : public Usermod {
if (now - buttonPressedTime > 600) { //long press if (now - buttonPressedTime > 600) { //long press
buttonLongPressed = true; buttonLongPressed = true;
longPressAction(0);
handled = true;
} }
} else if (!isButtonPressed(b) && buttonPressedBefore) { //released } else if (!isButtonPressed(b) && buttonPressedBefore) { //released
@ -902,6 +904,8 @@ class FourLineDisplayUsermod : public Usermod {
// if 450ms elapsed since last press/release it is a short press // if 450ms elapsed since last press/release it is a short press
if (buttonWaitTime && now - buttonWaitTime > 350 && !buttonPressedBefore) { if (buttonWaitTime && now - buttonWaitTime > 350 && !buttonPressedBefore) {
buttonWaitTime = 0; buttonWaitTime = 0;
shortPressAction(0);
handled = true;
} }
return handled; return handled;
} }

View File

@ -38,12 +38,12 @@
l.addEventListener('load', (e) => { l.addEventListener('load', (e) => {
// after rangetouch is loaded initialize global variable // after rangetouch is loaded initialize global variable
ranges = RangeTouch.setup('input[type="range"]', {}); ranges = RangeTouch.setup('input[type="range"]', {});
onLoad(); // start processing UI setTimeout(()=>{onLoad()},50); // start processing UI
}); });
//h.appendChild(l); // if this fires too quickly for ESP8266 use next line //h.appendChild(l); // if this fires too quickly for ESP8266 use next line
setTimeout(function(){h.appendChild(l)},50); setTimeout(()=>{h.appendChild(l)},50);
}); });
setTimeout(function(){h.appendChild(l)},50); setTimeout(()=>{h.appendChild(l)},50);
</script> </script>
<link rel="stylesheet" href="index.css"> <link rel="stylesheet" href="index.css">
</head> </head>

View File

@ -23,6 +23,8 @@ void updateBlynk();
//button.cpp //button.cpp
void shortPressAction(uint8_t b=0); void shortPressAction(uint8_t b=0);
void longPressAction(uint8_t b=0);
void doublePressAction(uint8_t b=0);
bool isButtonPressed(uint8_t b=0); bool isButtonPressed(uint8_t b=0);
void handleButton(); void handleButton();
void handleIO(); void handleIO();

File diff suppressed because it is too large Load Diff

View File

@ -8,7 +8,7 @@
*/ */
// version code in format yymmddb (b = daily build) // version code in format yymmddb (b = daily build)
#define VERSION 2201111 #define VERSION 2201211
//uncomment this if you have a "my_config.h" file you'd like to use //uncomment this if you have a "my_config.h" file you'd like to use
//#define WLED_USE_MY_CONFIG //#define WLED_USE_MY_CONFIG