From 757172934e96e7464148b2257a5fb254d6e3bc8c Mon Sep 17 00:00:00 2001 From: Blaz Kristan Date: Sat, 1 May 2021 19:38:13 +0200 Subject: [PATCH] MultiRelay usermod. beta 2 --- package.json | 2 +- usermods/multi_relay/readme.md | 51 ++++ usermods/multi_relay/usermod_multi_relay.h | 278 +++++++++++++++++++++ wled00/const.h | 1 + wled00/data/settings_um.htm | 9 +- wled00/html_other.h | 2 +- wled00/html_settings.h | 4 +- wled00/usermods_list.cpp | 10 +- wled00/wled.cpp | 4 + wled00/wled.h | 2 +- 10 files changed, 353 insertions(+), 10 deletions(-) create mode 100644 usermods/multi_relay/readme.md create mode 100644 usermods/multi_relay/usermod_multi_relay.h diff --git a/package.json b/package.json index 8ac8318c..a06d7caa 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "wled", - "version": "0.12.2-bl1", + "version": "0.12.2-bl2", "description": "Tools for WLED project", "main": "tools/cdata.js", "directories": { diff --git a/usermods/multi_relay/readme.md b/usermods/multi_relay/readme.md new file mode 100644 index 00000000..3a471dac --- /dev/null +++ b/usermods/multi_relay/readme.md @@ -0,0 +1,51 @@ +# Multi Relay + +This usermod-v2 modification allows the connection of multiple relays each with individual delay and on/off mode. + +## Usermod installation + +1. Register the usermod by adding `#include "../usermods/multi_relay/usermod_multi_relay.h"` at the top and `usermods.add(new MultiRelay());` at the bottom of `usermods_list.cpp`. +or +2. Use `#define USERMOD_MULTI_RELAY` in wled.h or `-D USERMOD_MULTI_RELAY`in your platformio.ini + +You can override the default maximum number (4) of relays by defining MULTI_RELAY_MAX_RELAYS. + +Example **usermods_list.cpp**: + +```cpp +#include "wled.h" +/* + * Register your v2 usermods here! + * (for v1 usermods using just usermod.cpp, you can ignore this file) + */ + +/* + * Add/uncomment your usermod filename here (and once more below) + * || || || + * \/ \/ \/ + */ +//#include "usermod_v2_example.h" +//#include "usermod_temperature.h" +#include "../usermods/usermod_multi_relay.h" + +void registerUsermods() +{ + /* + * Add your usermod class name here + * || || || + * \/ \/ \/ + */ + //usermods.add(new MyExampleUsermod()); + //usermods.add(new UsermodTemperature()); + usermods.add(new MultiRelay()); + +} +``` + +## Configuration + +Usermod can be configured in Usermods settings page. + +If there is no MultiRelay section, just save current configuration and re-open Usermods settings page. + +Have fun - @blazoncek diff --git a/usermods/multi_relay/usermod_multi_relay.h b/usermods/multi_relay/usermod_multi_relay.h new file mode 100644 index 00000000..13514c00 --- /dev/null +++ b/usermods/multi_relay/usermod_multi_relay.h @@ -0,0 +1,278 @@ +#pragma once + +#include "wled.h" + +#ifndef MULTI_RELAY_MAX_RELAYS + #define MULTI_RELAY_MAX_RELAYS 4 +#endif + +/* + * This usermod handles multiple relay outputs. + * These outputs complement built-in relay output in a way that the activation can be delayed. + * They can also activate/deactivate in reverse logic independently. + */ + +class MultiRelay : public Usermod { + + private: + // pins + int8_t _relayPin[MULTI_RELAY_MAX_RELAYS]; + // delay (in seconds) before relay state changes + uint16_t _relayDelay[MULTI_RELAY_MAX_RELAYS]; + // activation mode (high/low) + bool _relayMode[MULTI_RELAY_MAX_RELAYS]; + // relay active state + bool _relayActive[MULTI_RELAY_MAX_RELAYS]; + + // switch timer start time + uint32_t _switchTimerStart = 0; + // old brightness + uint8_t _oldBrightness = 0; + + // usermod enabled + bool enabled = false; // needs to be configured (no default config) + // status of initialisation + bool initDone = false; + + // strings to reduce flash memory usage (used more than twice) + static const char _name[]; + static const char _enabled[]; + static const char _relay[]; + static const char _delay[]; + static const char _activeHigh[]; + + /** + * switch relay on/off + */ + void switchRelay(uint8_t relay) { + if (relay>=MULTI_RELAY_MAX_RELAYS || _relayPin[relay]<0) return; + pinMode(_relayPin[relay], OUTPUT); + bool mode = bri ? _relayMode[relay] : !_relayMode[relay]; + digitalWrite(_relayPin[relay], mode); + publishMqtt(mode ? "on" : "off", relay); + } + + + void publishMqtt(const char* state, int relay) { + //Check if MQTT Connected, otherwise it will crash the 8266 + if (WLED_MQTT_CONNECTED){ + char subuf[64]; + sprintf_P(subuf, PSTR("%s/relay/%d"), mqttDeviceTopic, relay); + mqtt->publish(subuf, 0, true, state); + } + } + + /** + * switch off the strip if the delay has elapsed + */ + void handleOffTimer() { + bool activeRelays = false; + for (uint8_t i=0; i 0 && millis() - _switchTimerStart > (_relayDelay[i]*1000)) { + switchRelay(i); // toggle relay + _relayActive[i] = false; + } + activeRelays = activeRelays || _relayActive[i]; + } + if (!activeRelays) _switchTimerStart = 0; + } + + public: + /** + * constructor + */ + MultiRelay() { + for (uint8_t i=0; i=0) _relayActive[i] = true; + } + } + + handleOffTimer(); + } + + /** + * addToJsonInfo() can be used to add custom entries to the /json/info part of the JSON API. + */ + void addToJsonInfo(JsonObject &root) { + if (enabled) { + uint8_t count = 0; + for (uint8_t i=0; i=0) count++; + + JsonObject user = root["u"]; + if (user.isNull()) + user = root.createNestedObject("u"); + + JsonArray infoArr = user.createNestedArray(F("Number of relays")); //name + infoArr.add(String(count)); + } + } + + /** + * addToJsonState() can be used to add custom entries to the /json/state part of the JSON API (state object). + * Values in the state object may be modified by connected clients + */ + void addToJsonState(JsonObject &root) { + } + + /** + * readFromJsonState() can be used to receive data clients send to the /json/state part of the JSON API (state object). + * Values in the state object may be modified by connected clients + */ + void readFromJsonState(JsonObject &root) { + } + + /** + * provide the changeable values + */ + void addToConfig(JsonObject &root) { + JsonObject top = root.createNestedObject(FPSTR(_name)); + + top[FPSTR(_enabled)] = enabled; + for (uint8_t i=0; i()) { + enabled = top[FPSTR(_enabled)].as(); // reading from cfg.json + } else { + // change from settings page + String str = top[FPSTR(_enabled)]; // checkbox -> off or on + enabled = (bool)(str!="off"); // off is guaranteed to be present + } + } + + for (uint8_t i=0; i())); + + if (top[parName+FPSTR(_activeHigh)] != nullptr) { + if (top[parName+FPSTR(_activeHigh)].is()) { + _relayMode[i] = top[parName+FPSTR(_activeHigh)].as(); // reading from cfg.json + } else { + // change from settings page + String str = top[parName+FPSTR(_activeHigh)]; // checkbox -> off or on + _relayMode[i] = (bool)(str!="off"); // off is guaranteed to be present + } + } + + _relayDelay[i] = min(600,max(0,abs(top[parName+FPSTR(_delay)].as()))); + } + + if (!initDone) { + // reading config prior to setup() + DEBUG_PRINTLN(F("MultiRelay config loaded.")); + } else { + // deallocate all pins 1st + for (uint8_t i=0; i=0) { + pinManager.deallocatePin(oldPin[i]); + } + // allocate new pins + for (uint8_t i=0; i=0 && pinManager.allocatePin(_relayPin[i],true)) { + switchRelay(i); + } else { + _relayPin[i] = -1; + } + _relayActive[i] = false; + } + DEBUG_PRINTLN(F("MultiRelay config (re)loaded.")); + } + } + + /** + * getId() allows you to optionally give your V2 usermod an unique ID (please define it in const.h!). + * This could be used in the future for the system to determine whether your usermod is installed. + */ + uint16_t getId() + { + return USERMOD_ID_MULTI_RELAY; + } +}; + +// strings to reduce flash memory usage (used more than twice) +const char MultiRelay::_name[] PROGMEM = "MultiRelay"; +const char MultiRelay::_enabled[] PROGMEM = "enabled"; +const char MultiRelay::_relay[] PROGMEM = "relay"; +const char MultiRelay::_delay[] PROGMEM = "delay-s"; +const char MultiRelay::_activeHigh[] PROGMEM = "active-high"; \ No newline at end of file diff --git a/wled00/const.h b/wled00/const.h index 9592127f..49d4e327 100644 --- a/wled00/const.h +++ b/wled00/const.h @@ -39,6 +39,7 @@ #define USERMOD_ID_DHT 10 //Usermod "usermod_dht.h" #define USERMOD_ID_MODE_SORT 11 //Usermod "usermod_v2_mode_sort.h" #define USERMOD_ID_VL53L0X 12 //Usermod "usermod_vl53l0x_gestures.h" +#define USERMOD_ID_MULTI_RELAY 101 //Usermod "usermod_multi_relay.h" //Access point behavior #define AP_BEHAVIOR_BOOT_NO_CONN 0 //Open AP when no connection after boot diff --git a/wled00/data/settings_um.htm b/wled00/data/settings_um.htm index 772a9844..302987e6 100644 --- a/wled00/data/settings_um.htm +++ b/wled00/data/settings_um.htm @@ -27,11 +27,11 @@ ldS(); } function check(o,k) { - var n = o.name.replace("[]","").substr(-4); - if (o.type=="number" && n.substr(0,4)=="_pin") { + var n = o.name.replace("[]","").substr(-3); + if (o.type=="number" && n.substr(0,3)=="pin") { for (var i=0; i39) { o.style.color="red"; break; } else o.style.color=o.value>33?"orange":"#fff"; } } } @@ -43,7 +43,7 @@ getPins(v); continue; } - if (k=="pin") { + if (k.replace("[]","").substr(-3)=="pin") { if (Array.isArray(v)) { for (var i=0; i=0) { pins.push(v[i]); pinO.push(owner); } } else { @@ -54,6 +54,7 @@ } } } + console.log(pins); } function addField(k,f,o,a=false) { if (isO(o)) { diff --git a/wled00/html_other.h b/wled00/html_other.h index 48916356..b58a3a57 100644 --- a/wled00/html_other.h +++ b/wled00/html_other.h @@ -42,7 +42,7 @@ function B(){window.history.back()}function U(){document.getElementById("uf").st .bt{background:#333;color:#fff;font-family:Verdana,sans-serif;border:.3ch solid #333;display:inline-block;font-size:20px;margin:8px;margin-top:12px}input[type=file]{font-size:16px}body{font-family:Verdana,sans-serif;text-align:center;background:#222;color:#fff;line-height:200%}#msg{display:none}

WLED Software Update

-Installed version: 0.12.2-bl1
Download the latest binary: Download the latest binary:

diff --git a/wled00/html_settings.h b/wled00/html_settings.h index ef499cfd..20e71380 100644 --- a/wled00/html_settings.h +++ b/wled00/html_settings.h @@ -381,7 +381,7 @@ HTTP traffic is unencrypted. An attacker in the same network can intercept form

Software Update


Enable ArduinoOTA:

About

WLED - version 0.12.2-bl1


Contributors, dependencies and special thanks
A huge thank you to everyone who helped me create WLED!

@@ -395,7 +395,7 @@ type="submit">Save & Reboot
)====="; // Autogenerated from wled00/data/settings_um.htm, do not edit!! const char PAGE_settings_um[] PROGMEM = R"=====(UI Settings%CSS%%SCSS%