Browse Source

Allow to configure all LEDs from UI (#1429)

rules-rpn
Xose Pérez 5 years ago
parent
commit
0987e01950
18 changed files with 19366 additions and 19199 deletions
  1. +1
    -1
      code/espurna/config/hardware.h
  2. BIN
      code/espurna/data/index.all.html.gz
  3. BIN
      code/espurna/data/index.light.html.gz
  4. BIN
      code/espurna/data/index.lightfox.html.gz
  5. BIN
      code/espurna/data/index.rfbridge.html.gz
  6. BIN
      code/espurna/data/index.rfm69.html.gz
  7. BIN
      code/espurna/data/index.sensor.html.gz
  8. BIN
      code/espurna/data/index.small.html.gz
  9. +33
    -15
      code/espurna/led.ino
  10. +3167
    -3154
      code/espurna/static/index.all.html.gz.h
  11. +2605
    -2593
      code/espurna/static/index.light.html.gz.h
  12. +2199
    -2188
      code/espurna/static/index.lightfox.html.gz.h
  13. +2235
    -2223
      code/espurna/static/index.rfbridge.html.gz.h
  14. +4127
    -4115
      code/espurna/static/index.rfm69.html.gz.h
  15. +2706
    -2695
      code/espurna/static/index.sensor.html.gz.h
  16. +2199
    -2188
      code/espurna/static/index.small.html.gz.h
  17. +35
    -1
      code/html/custom.js
  18. +59
    -26
      code/html/index.html

+ 1
- 1
code/espurna/config/hardware.h View File

@ -125,7 +125,7 @@
#define RELAY1_PIN 5 #define RELAY1_PIN 5
#define RELAY1_TYPE RELAY_TYPE_NORMAL #define RELAY1_TYPE RELAY_TYPE_NORMAL
// Light RGBW
// LED
#define LED1_PIN 2 #define LED1_PIN 2
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1


BIN
code/espurna/data/index.all.html.gz View File


BIN
code/espurna/data/index.light.html.gz View File


BIN
code/espurna/data/index.lightfox.html.gz View File


BIN
code/espurna/data/index.rfbridge.html.gz View File


BIN
code/espurna/data/index.rfm69.html.gz View File


BIN
code/espurna/data/index.sensor.html.gz View File


BIN
code/espurna/data/index.small.html.gz View File


+ 33
- 15
code/espurna/led.ino View File

@ -51,6 +51,16 @@ void _ledMode(unsigned char id, unsigned char mode) {
_leds[id].mode = mode; _leds[id].mode = mode;
} }
unsigned char _ledRelay(unsigned char id) {
if (id >= _ledCount()) return false;
return _leds[id].relay;
}
void _ledRelay(unsigned char id, unsigned char relay) {
if (id >= _ledCount()) return;
_leds[id].relay = relay;
}
void _ledBlink(unsigned char id, unsigned long delayOff, unsigned long delayOn) { void _ledBlink(unsigned char id, unsigned long delayOff, unsigned long delayOn) {
if (id >= _ledCount()) return; if (id >= _ledCount()) return;
static unsigned long next = millis(); static unsigned long next = millis();
@ -68,7 +78,12 @@ bool _ledWebSocketOnReceive(const char * key, JsonVariant& value) {
void _ledWebSocketOnSend(JsonObject& root) { void _ledWebSocketOnSend(JsonObject& root) {
if (_ledCount() == 0) return; if (_ledCount() == 0) return;
root["ledVisible"] = 1; root["ledVisible"] = 1;
root["ledMode0"] = _ledMode(0);
JsonArray& leds = root.createNestedArray("ledConfig");
for (byte i=0; i<_ledCount(); i++) {
JsonObject& led = leds.createNestedObject();
led["mode"] = getSetting("ledMode", i, "").toInt();
led["relay"] = getSetting("ledRelay", i, "").toInt();
}
} }
#endif #endif
@ -133,6 +148,7 @@ unsigned char _ledCount() {
void _ledConfigure() { void _ledConfigure() {
for (unsigned int i=0; i < _leds.size(); i++) { for (unsigned int i=0; i < _leds.size(); i++) {
_ledMode(i, getSetting("ledMode", i, _ledMode(i)).toInt()); _ledMode(i, getSetting("ledMode", i, _ledMode(i)).toInt());
_ledRelay(i, getSetting("ledRelay", i, _ledRelay(i)).toInt());
} }
_led_update = true; _led_update = true;
} }
@ -146,32 +162,34 @@ void ledUpdate(bool value) {
void ledSetup() { void ledSetup() {
#if LED1_PIN != GPIO_NONE #if LED1_PIN != GPIO_NONE
_leds.push_back((led_t) { LED1_PIN, LED1_PIN_INVERSE, LED1_MODE, LED1_RELAY });
_leds.push_back((led_t) { LED1_PIN, LED1_PIN_INVERSE, LED1_MODE, LED1_RELAY - 1 });
#endif #endif
#if LED2_PIN != GPIO_NONE #if LED2_PIN != GPIO_NONE
_leds.push_back((led_t) { LED2_PIN, LED2_PIN_INVERSE, LED2_MODE, LED2_RELAY });
_leds.push_back((led_t) { LED2_PIN, LED2_PIN_INVERSE, LED2_MODE, LED2_RELAY - 1 });
#endif #endif
#if LED3_PIN != GPIO_NONE #if LED3_PIN != GPIO_NONE
_leds.push_back((led_t) { LED3_PIN, LED3_PIN_INVERSE, LED3_MODE, LED3_RELAY });
_leds.push_back((led_t) { LED3_PIN, LED3_PIN_INVERSE, LED3_MODE, LED3_RELAY - 1 });
#endif #endif
#if LED4_PIN != GPIO_NONE #if LED4_PIN != GPIO_NONE
_leds.push_back((led_t) { LED4_PIN, LED4_PIN_INVERSE, LED4_MODE, LED4_RELAY });
_leds.push_back((led_t) { LED4_PIN, LED4_PIN_INVERSE, LED4_MODE, LED4_RELAY - 1 });
#endif #endif
#if LED5_PIN != GPIO_NONE #if LED5_PIN != GPIO_NONE
_leds.push_back((led_t) { LED5_PIN, LED5_PIN_INVERSE, LED5_MODE, LED5_RELAY });
_leds.push_back((led_t) { LED5_PIN, LED5_PIN_INVERSE, LED5_MODE, LED5_RELAY - 1 });
#endif #endif
#if LED6_PIN != GPIO_NONE #if LED6_PIN != GPIO_NONE
_leds.push_back((led_t) { LED6_PIN, LED6_PIN_INVERSE, LED6_MODE, LED6_RELAY });
_leds.push_back((led_t) { LED6_PIN, LED6_PIN_INVERSE, LED6_MODE, LED6_RELAY - 1 });
#endif #endif
#if LED7_PIN != GPIO_NONE #if LED7_PIN != GPIO_NONE
_leds.push_back((led_t) { LED7_PIN, LED7_PIN_INVERSE, LED7_MODE, LED7_RELAY });
_leds.push_back((led_t) { LED7_PIN, LED7_PIN_INVERSE, LED7_MODE, LED7_RELAY - 1 });
#endif #endif
#if LED8_PIN != GPIO_NONE #if LED8_PIN != GPIO_NONE
_leds.push_back((led_t) { LED8_PIN, LED8_PIN_INVERSE, LED8_MODE, LED8_RELAY });
_leds.push_back((led_t) { LED8_PIN, LED8_PIN_INVERSE, LED8_MODE, LED8_RELAY - 1 });
#endif #endif
for (unsigned int i=0; i < _leds.size(); i++) { for (unsigned int i=0; i < _leds.size(); i++) {
pinMode(_leds[i].pin, OUTPUT); pinMode(_leds[i].pin, OUTPUT);
setSetting("ledMode", i, _leds[i].mode);
setSetting("ledRelay", i, _leds[i].relay);
_ledStatus(i, false); _ledStatus(i, false);
} }
@ -225,13 +243,13 @@ void ledLoop() {
if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) { if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) {
_ledBlink(i, 100, 100); _ledBlink(i, 100, 100);
} else if (wifi_state & WIFI_STATE_STA) { } else if (wifi_state & WIFI_STATE_STA) {
if (relayStatus(_leds[i].relay-1)) {
if (relayStatus(_leds[i].relay)) {
_ledBlink(i, 4900, 100); _ledBlink(i, 4900, 100);
} else { } else {
_ledBlink(i, 100, 4900); _ledBlink(i, 100, 4900);
} }
} else if (wifi_state & WIFI_STATE_AP) { } else if (wifi_state & WIFI_STATE_AP) {
if (relayStatus(_leds[i].relay-1)) {
if (relayStatus(_leds[i].relay)) {
_ledBlink(i, 900, 100); _ledBlink(i, 900, 100);
} else { } else {
_ledBlink(i, 100, 900); _ledBlink(i, 100, 900);
@ -247,13 +265,13 @@ void ledLoop() {
if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) { if (wifi_state & WIFI_STATE_WPS || wifi_state & WIFI_STATE_SMARTCONFIG) {
_ledBlink(i, 100, 100); _ledBlink(i, 100, 100);
} else if (wifi_state & WIFI_STATE_STA) { } else if (wifi_state & WIFI_STATE_STA) {
if (relayStatus(_leds[i].relay-1)) {
if (relayStatus(_leds[i].relay)) {
_ledBlink(i, 100, 4900); _ledBlink(i, 100, 4900);
} else { } else {
_ledBlink(i, 4900, 100); _ledBlink(i, 4900, 100);
} }
} else if (wifi_state & WIFI_STATE_AP) { } else if (wifi_state & WIFI_STATE_AP) {
if (relayStatus(_leds[i].relay-1)) {
if (relayStatus(_leds[i].relay)) {
_ledBlink(i, 100, 900); _ledBlink(i, 100, 900);
} else { } else {
_ledBlink(i, 900, 100); _ledBlink(i, 900, 100);
@ -268,11 +286,11 @@ void ledLoop() {
if (!_led_update) continue; if (!_led_update) continue;
if (_ledMode(i) == LED_MODE_FOLLOW) { if (_ledMode(i) == LED_MODE_FOLLOW) {
_ledStatus(i, relayStatus(_leds[i].relay-1));
_ledStatus(i, relayStatus(_leds[i].relay));
} }
if (_ledMode(i) == LED_MODE_FOLLOW_INVERSE) { if (_ledMode(i) == LED_MODE_FOLLOW_INVERSE) {
_ledStatus(i, !relayStatus(_leds[i].relay-1));
_ledStatus(i, !relayStatus(_leds[i].relay));
} }
if (_ledMode(i) == LED_MODE_FINDME) { if (_ledMode(i) == LED_MODE_FINDME) {


+ 3167
- 3154
code/espurna/static/index.all.html.gz.h
File diff suppressed because it is too large
View File


+ 2605
- 2593
code/espurna/static/index.light.html.gz.h
File diff suppressed because it is too large
View File


+ 2199
- 2188
code/espurna/static/index.lightfox.html.gz.h
File diff suppressed because it is too large
View File


+ 2235
- 2223
code/espurna/static/index.rfbridge.html.gz.h
File diff suppressed because it is too large
View File


+ 4127
- 4115
code/espurna/static/index.rfm69.html.gz.h
File diff suppressed because it is too large
View File


+ 2706
- 2695
code/espurna/static/index.sensor.html.gz.h
File diff suppressed because it is too large
View File


+ 2199
- 2188
code/espurna/static/index.small.html.gz.h
File diff suppressed because it is too large
View File


+ 35
- 1
code/html/custom.js View File

@ -249,7 +249,7 @@ function addValue(data, name, value) {
"mqttGroup", "mqttGroupSync", "relayOnDisc", "mqttGroup", "mqttGroupSync", "relayOnDisc",
"dczRelayIdx", "dczMagnitude", "dczRelayIdx", "dczMagnitude",
"tspkRelay", "tspkMagnitude", "tspkRelay", "tspkMagnitude",
"ledMode",
"ledMode", "ledRelay",
"adminPass", "adminPass",
"node", "key", "topic" "node", "key", "topic"
]; ];
@ -974,6 +974,27 @@ function initRelayConfig(data) {
// Sensors & Magnitudes // Sensors & Magnitudes
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
function initLeds(data) {
var current = $("#ledConfig > div").length;
if (current > 0) { return; }
var size = data.length;
var template = $("#ledConfigTemplate").children();
for (var i=0; i<size; ++i) {
var line = $(template).clone();
$("span.id", line).html(i);
$("select", line).attr("data", i);
$("input", line).attr("data", i);
line.appendTo("#ledConfig");
}
}
// -----------------------------------------------------------------------------
// Sensors & Magnitudes
// -----------------------------------------------------------------------------
<!-- removeIf(!sensor)--> <!-- removeIf(!sensor)-->
function initMagnitudes(data) { function initMagnitudes(data) {
@ -1493,6 +1514,19 @@ function processData(data) {
return; return;
} }
// ---------------------------------------------------------------------
// LEDs
// ---------------------------------------------------------------------
if ("ledConfig" === key) {
initLeds(value);
for (var i=0; i<value.length; ++i) {
$("select[name='ledMode'][data='" + i + "']", line).val(value[i].mode);
$("input[name='ledRelay'][data='" + i + "']", line).val(value[i].relay);
}
return;
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Domoticz // Domoticz
// --------------------------------------------------------------------- // ---------------------------------------------------------------------


+ 59
- 26
code/html/index.html View File

@ -114,6 +114,10 @@
<a href="#" class="pure-menu-link" data="panel-idb">INFLUXDB</a> <a href="#" class="pure-menu-link" data="panel-idb">INFLUXDB</a>
</li> </li>
<li class="pure-menu-item module module-led">
<a href="#" class="pure-menu-link" data="panel-led">LED</a>
</li>
<!-- removeIf(!light) --> <!-- removeIf(!light) -->
<li class="pure-menu-item module module-color"> <li class="pure-menu-item module module-color">
<a href="#" class="pure-menu-link" data="panel-color">LIGHTS</a> <a href="#" class="pure-menu-link" data="panel-color">LIGHTS</a>
@ -373,42 +377,51 @@
</div> </div>
</div> </div>
<div class="pure-g module module-led">
<label class="pure-u-1 pure-u-lg-1-4">LED mode</label>
<select name="ledMode0" class="pure-u-1 pure-u-lg-1-4" tabindex="7">
<option value="1">WiFi status</option>
<option value="8">Relay status</option>
<option value="0">MQTT managed</option>
<option value="4">Find me</option>
<option value="9">Relay &amp; WiFi</option>
<option value="5">Find me &amp; WiFi</option>
<option value="6">Always ON</option>
<option value="7">Always OFF</option>
</select>
<div class="pure-u-0 pure-u-lg-1-2"></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
This setting defines the behaviour of the main LED in the board.<br />
When in "WiFi status" it will blink at 1Hz when trying to connect. If successfully connected it will briefly blink every 5 seconds if in STA mode or every second if in AP mode.<br />
When in "Relay status" mode the LED will be ON whenever any relay is ON, and OFF otherwise. This is global status notification.<br />
When in "MQTT managed" mode you will be able to set the LED state sending a message to "&lt;base_topic&gt;/led/0/set" with a payload of 0, 1 or 2 (to toggle it).<br />
When in "Find me" mode the LED will be ON when all relays are OFF. This is meant to locate switches at night.<br />
When in "Relay &amp; WiFi" mode it will follow the WiFi status but will stay mostly off when relays are OFF, and mostly ON when any of them is ON.<br />
When in "Find me &amp; WiFi" mode is the opposite of the "Relay &amp; WiFi", it will follow the WiFi status but will stay mostly on when relays are OFF, and mostly OFF when any of them is ON.<br />
"Always ON" and "Always OFF" modes are self-explanatory.
</div>
</div>
<div class="pure-g module module-alexa"> <div class="pure-g module module-alexa">
<label class="pure-u-1 pure-u-lg-1-4">Alexa integration</label> <label class="pure-u-1 pure-u-lg-1-4">Alexa integration</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="alexaEnabled" /></div> <div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="alexaEnabled" /></div>
</div> </div>
</fieldset> </fieldset>
</div> </div>
</div> </div>
</form> </form>
<form id="form-led" class="pure-form form-settings">
<div class="panel" id="panel-led">
<div class="header">
<h1>LED</h1>
<h2>Notification LED configuration</h2>
</div>
<div class="page">
<fieldset>
<div class="pure-g module module-led">
<div class="pure-u-0 pure-u-lg-1-4">Modes</div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
<li><strong>WiFi status</strong> will blink at 1Hz when trying to connect. If successfully connected it will briefly blink every 5 seconds if in STA mode or every second if in AP mode.</li>
<li><strong>Follow switch</strong> will force the LED to follow the status of a given switch (you must define which switch to follow in the side field).</li>
<li><strong>Inverse switch</strong> will force the LED to not-follow the status of a given switch (you must define which switch to follow in the side field).</li>
<li><strong>Find me</strong> will turn the LED ON when all switches are OFF. This is meant to locate switches at night.</li>
<li><strong>Find me &amp; WiFi</strong> will follow the WiFi status but will stay mostly on when switches are OFF, and mostly OFF when any of them is ON.</li>
<li><strong>Switches status</strong> will turn the LED ON whenever any switch is ON, and OFF otherwise. This is global status notification.</li>
<li><strong>Switches status &amp; WiFi</strong> will follow the WiFi status but will stay mostly off when switches are OFF, and mostly ON when any of them is ON.</li>
<li><strong>MQTT managed</strong> will let you manage the LED status via MQTT by sending a message to "&lt;base_topic&gt;/led/0/set" with a payload of 0, 1 or 2 (to toggle it).</li>
<li><strong>Always ON</strong> and <strong>Always OFF</strong> modes are self-explanatory.</li>
</div>
</div>
<div id="ledConfig"></div>
</fieldset>
</div>
</div>
</form>
<form id="form-relay" class="pure-form form-settings"> <form id="form-relay" class="pure-form form-settings">
<div class="panel" id="panel-relay"> <div class="panel" id="panel-relay">
@ -1512,6 +1525,26 @@
<!-- Templates --> <!-- Templates -->
<div id="ledConfigTemplate" class="template">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">LED #<span class="id"></span> mode</label>
<select name="ledMode" class="pure-u-1-4">
<option value="1">WiFi status</option>
<option value="2">Follow switch #</option>
<option value="3">Inverse switch #</option>
<option value="4">Find me</option>
<option value="5">Find me &amp; WiFi</option>
<option value="8">Switches status</option>
<option value="9">Switches &amp; WiFi</option>
<option value="0">MQTT managed</option>
<option value="6">Always ON</option>
<option value="7">Always OFF</option>
</select>
&nbsp;
<div class="pure-u-1-4"><input class="pure-u-23-24" name="ledRelay" type="number" min="0" data="0" /></div>
</div>
</div>
<!-- removeIf(!rfbridge) --> <!-- removeIf(!rfbridge) -->
<div id="rfbNodeTemplate" class="template"> <div id="rfbNodeTemplate" class="template">


Loading…
Cancel
Save