Browse Source

Merge pull request #1468 from foxel/lightfox-dual

LightFox dual support
rules-rpn
Xose Pérez 5 years ago
committed by GitHub
parent
commit
9955a67dbb
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
30 changed files with 20899 additions and 17840 deletions
  1. +2
    -0
      code/.gitignore
  2. +37
    -2
      code/espurna/button.ino
  3. +1
    -0
      code/espurna/config/arduino.h
  4. +21
    -0
      code/espurna/config/hardware.h
  5. +11
    -0
      code/espurna/config/webui.h
  6. BIN
      code/espurna/data/index.all.html.gz
  7. BIN
      code/espurna/data/index.light.html.gz
  8. BIN
      code/espurna/data/index.lightfox.html.gz
  9. BIN
      code/espurna/data/index.rfbridge.html.gz
  10. BIN
      code/espurna/data/index.rfm69.html.gz
  11. BIN
      code/espurna/data/index.sensor.html.gz
  12. BIN
      code/espurna/data/index.small.html.gz
  13. +3
    -0
      code/espurna/espurna.ino
  14. +107
    -0
      code/espurna/lightfox.ino
  15. +11
    -1
      code/espurna/migrate.ino
  16. +2
    -0
      code/espurna/relay.ino
  17. +3154
    -3152
      code/espurna/static/index.all.html.gz.h
  18. +3031
    -3003
      code/espurna/static/index.light.html.gz.h
  19. +2595
    -0
      code/espurna/static/index.lightfox.html.gz.h
  20. +2632
    -2609
      code/espurna/static/index.rfbridge.html.gz.h
  21. +4112
    -4083
      code/espurna/static/index.rfm69.html.gz.h
  22. +2448
    -2420
      code/espurna/static/index.sensor.html.gz.h
  23. +2591
    -2563
      code/espurna/static/index.small.html.gz.h
  24. +1
    -1
      code/espurna/system.ino
  25. +2
    -0
      code/espurna/web.ino
  26. +6
    -0
      code/gulpfile.js
  27. +2
    -0
      code/html/custom.css
  28. +55
    -0
      code/html/custom.js
  29. +52
    -6
      code/html/index.html
  30. +23
    -0
      code/platformio.ini

+ 2
- 0
code/.gitignore View File

@ -11,3 +11,5 @@ custom.h
.vscode/.browse.c_cpp.db*
.vscode/c_cpp_properties.json
.vscode/launch.json
.pioenvs
.piolibdeps

+ 37
- 2
code/espurna/button.ino View File

@ -164,13 +164,25 @@ void buttonEvent(unsigned int id, unsigned char event) {
void buttonSetup() {
#ifdef ITEAD_SONOFF_DUAL
#if defined(ITEAD_SONOFF_DUAL)
unsigned int actions = buttonStore(BUTTON_MODE_NONE, BUTTON_MODE_TOGGLE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE);
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, 1});
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, 2});
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, BUTTON3_RELAY});
#elif defined(FOXEL_LIGHTFOX_DUAL)
unsigned int actions = buttonStore(BUTTON_MODE_NONE, BUTTON_MODE_TOGGLE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE, BUTTON_MODE_NONE);
unsigned int btn1Relay = getSetting("btnRelay", 0, BUTTON1_RELAY - 1).toInt() + 1;
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn1Relay});
unsigned int btn2Relay = getSetting("btnRelay", 1, BUTTON2_RELAY - 1).toInt() + 1;
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn2Relay});
unsigned int btn3Relay = getSetting("btnRelay", 2, BUTTON3_RELAY - 1).toInt() + 1;
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn3Relay});
unsigned int btn4Relay = getSetting("btnRelay", 3, BUTTON4_RELAY - 1).toInt() + 1;
_buttons.push_back({new DebounceEvent(0, BUTTON_PUSHBUTTON), actions, btn4Relay});
#else
unsigned long btnDelay = getSetting("btnDelay", BUTTON_DBLCLICK_DELAY).toInt();
@ -240,7 +252,7 @@ void buttonSetup() {
void buttonLoop() {
#ifdef ITEAD_SONOFF_DUAL
#if defined(ITEAD_SONOFF_DUAL)
if (Serial.available() >= 4) {
if (Serial.read() == 0xA0) {
@ -280,6 +292,29 @@ void buttonLoop() {
}
}
#elif defined(FOXEL_LIGHTFOX_DUAL)
if (Serial.available() >= 4) {
if (Serial.read() == 0xA0) {
if (Serial.read() == 0x04) {
unsigned char value = Serial.read();
if (Serial.read() == 0xA1) {
DEBUG_MSG_P(PSTR("[BUTTON] [LIGHTFOX] Received buttons mask: %d\n"), value);
for (unsigned int i=0; i<_buttons.size(); i++) {
bool clicked = (value & (1 << i)) > 0;
if (clicked) {
buttonEvent(i, BUTTON_EVENT_CLICK);
}
}
}
}
}
}
#else
for (unsigned int i=0; i < _buttons.size(); i++) {


+ 1
- 0
code/espurna/config/arduino.h View File

@ -117,6 +117,7 @@
//#define ARILUX_AL_LC02_V14
//#define BLITZWOLF_BWSHPX_V23
//#define DIGOO_NX_SP202
//#define FOXEL_LIGHTFOX_DUAL
//--------------------------------------------------------------------------------
// Features (values below are non-default values)


+ 21
- 0
code/espurna/config/hardware.h View File

@ -3438,6 +3438,27 @@
#define HLW8012_POWER_RATIO 3368471
#define HLW8012_INTERRUPT_ON FALLING
// -----------------------------------------------------------------------------
// Foxel's LightFox dual
// https://github.com/foxel/esp-dual-rf-switch
// -----------------------------------------------------------------------------
#elif defined(FOXEL_LIGHTFOX_DUAL)
// Info
#define MANUFACTURER "FOXEL"
#define DEVICE "LIGHTFOX_DUAL"
#define SERIAL_BAUDRATE 19200
#define RELAY_PROVIDER RELAY_PROVIDER_DUAL
#define DUMMY_RELAY_COUNT 2
#define DEBUG_SERIAL_SUPPORT 0
// Buttons
#define BUTTON1_RELAY 1
#define BUTTON2_RELAY 2
#define BUTTON3_RELAY 2
#define BUTTON4_RELAY 1
// -----------------------------------------------------------------------------
// TEST boards (do not use!!)
// -----------------------------------------------------------------------------


+ 11
- 0
code/espurna/config/webui.h View File

@ -7,6 +7,7 @@
#define WEBUI_IMAGE_SENSOR 2
#define WEBUI_IMAGE_RFBRIDGE 4
#define WEBUI_IMAGE_RFM69 8
#define WEBUI_IMAGE_LIGHTFOX 16
#define WEBUI_IMAGE_FULL 15
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
@ -45,6 +46,13 @@
#endif
#endif
#if defined(FOXEL_LIGHTFOX_DUAL)
#ifdef WEBUI_IMAGE
#undef WEBUI_IMAGE
#endif
#define WEBUI_IMAGE WEBUI_IMAGE_LIGHTFOX
#endif
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_SMALL
#endif
@ -67,6 +75,9 @@ PROGMEM const char espurna_webui[] =
#if WEBUI_IMAGE == WEBUI_IMAGE_RFM69
"RFM69"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_LIGHTFOX
"LIGHTFOX"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_FULL
"FULL"
#endif


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


+ 3
- 0
code/espurna/espurna.ino View File

@ -189,6 +189,9 @@ void setup() {
#if UART_MQTT_SUPPORT
uartmqttSetup();
#endif
#ifdef FOXEL_LIGHTFOX_DUAL
lightfoxSetup();
#endif
// 3rd party code hook


+ 107
- 0
code/espurna/lightfox.ino View File

@ -0,0 +1,107 @@
/*
LightFox module
Copyright (C) 2019 by Andrey F. Kupreychik <foxle@quickfox.ru>
*/
#ifdef FOXEL_LIGHTFOX_DUAL
// -----------------------------------------------------------------------------
// DEFINITIONS
// -----------------------------------------------------------------------------
#define LIGHTFOX_CODE_START 0xA0
#define LIGHTFOX_CODE_LEARN 0xF1
#define LIGHTFOX_CODE_CLEAR 0xF2
#define LIGHTFOX_CODE_STOP 0xA1
// -----------------------------------------------------------------------------
// PUBLIC
// -----------------------------------------------------------------------------
void lightfoxLearn() {
Serial.write(LIGHTFOX_CODE_START);
Serial.write(LIGHTFOX_CODE_LEARN);
Serial.write(0x00);
Serial.write(LIGHTFOX_CODE_STOP);
Serial.println();
Serial.flush();
DEBUG_MSG_P(PSTR("[LIGHTFOX] Learn comman sent\n"));
}
void lightfoxClear() {
Serial.write(LIGHTFOX_CODE_START);
Serial.write(LIGHTFOX_CODE_CLEAR);
Serial.write(0x00);
Serial.write(LIGHTFOX_CODE_STOP);
Serial.println();
Serial.flush();
DEBUG_MSG_P(PSTR("[LIGHTFOX] Clear comman sent\n"));
}
// -----------------------------------------------------------------------------
// WEB
// -----------------------------------------------------------------------------
#if WEB_SUPPORT
void _lightfoxWebSocketOnSend(JsonObject& root) {
root["lightfoxVisible"] = 1;
uint8_t buttonsCount = _buttons.size();
root["lightfoxRelayCount"] = relayCount();
JsonArray& rfb = root.createNestedArray("lightfoxButtons");
for (byte id=0; id<buttonsCount; id++) {
JsonObject& node = rfb.createNestedObject();
node["id"] = id;
node["relay"] = getSetting("btnRelay", id, "0");
}
}
void _lightfoxWebSocketOnAction(uint32_t client_id, const char * action, JsonObject& data) {
if (strcmp(action, "lightfoxLearn") == 0) lightfoxLearn();
if (strcmp(action, "lightfoxClear") == 0) lightfoxClear();
}
#endif
// -----------------------------------------------------------------------------
// TERMINAL
// -----------------------------------------------------------------------------
#if TERMINAL_SUPPORT
void _lightfoxInitCommands() {
terminalRegisterCommand(F("LIGHTFOX.LEARN"), [](Embedis* e) {
lightfoxLearn();
DEBUG_MSG_P(PSTR("+OK\n"));
});
terminalRegisterCommand(F("LIGHTFOX.CLEAR"), [](Embedis* e) {
lightfoxClear();
DEBUG_MSG_P(PSTR("+OK\n"));
});
}
#endif
// -----------------------------------------------------------------------------
// SETUP & LOOP
// -----------------------------------------------------------------------------
void lightfoxSetup() {
#if WEB_SUPPORT
wsOnSendRegister(_lightfoxWebSocketOnSend);
wsOnActionRegister(_lightfoxWebSocketOnAction);
#endif
#if TERMINAL_SUPPORT
_lightfoxInitCommands();
#endif
}
#endif

+ 11
- 1
code/espurna/migrate.ino View File

@ -1267,7 +1267,7 @@ void migrate() {
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("relayGPIO", 1, 15); // Left outlet
setSetting("relayType", 1, RELAY_TYPE_NORMAL);
#elif defined(DIGOO_NX_SP202)
setSetting("board", 95);
@ -1290,6 +1290,16 @@ void migrate() {
setSetting("hlwSelC", LOW);
setSetting("hlwIntM", FALLING);
#elif defined(FOXEL_LIGHTFOX_DUAL)
setSetting("board", 96);
setSetting("btnRelay", 0, 0);
setSetting("btnRelay", 1, 1);
setSetting("btnRelay", 2, 1);
setSetting("btnRelay", 3, 0);
setSetting("relayProvider", RELAY_PROVIDER_DUAL);
setSetting("relays", 2);
#else
// Allow users to define new settings without migration config


+ 2
- 0
code/espurna/relay.ino View File

@ -67,6 +67,8 @@ void _relayProviderStatus(unsigned char id, bool status) {
if (_relays[i].current_status) mask = mask + (1 << i);
}
DEBUG_MSG_P(PSTR("[RELAY] [DUAL] Sending relay mask: %d\n"), mask);
// Send it to F330
Serial.flush();
Serial.write(0xA0);


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


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


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


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


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


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


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


+ 1
- 1
code/espurna/system.ino View File

@ -170,7 +170,7 @@ void _systemSetupSpecificHardware() {
// These devices use the hardware UART
// to communicate to secondary microcontrollers
#if defined(ITEAD_SONOFF_RFBRIDGE) || defined(ITEAD_SONOFF_DUAL) || (RELAY_PROVIDER == RELAY_PROVIDER_STM)
#if defined(ITEAD_SONOFF_RFBRIDGE) || (RELAY_PROVIDER == RELAY_PROVIDER_DUAL) || (RELAY_PROVIDER == RELAY_PROVIDER_STM)
Serial.begin(SERIAL_BAUDRATE);
#endif


+ 2
- 0
code/espurna/web.ino View File

@ -27,6 +27,8 @@ Copyright (C) 2016-2019 by Xose Pérez <xose dot perez at gmail dot com>
#include "static/index.rfbridge.html.gz.h"
#elif WEBUI_IMAGE == WEBUI_IMAGE_RFM69
#include "static/index.rfm69.html.gz.h"
#elif WEBUI_IMAGE == WEBUI_IMAGE_LIGHTFOX
#include "static/index.lightfox.html.gz.h"
#elif WEBUI_IMAGE == WEBUI_IMAGE_FULL
#include "static/index.all.html.gz.h"
#endif


+ 6
- 0
code/gulpfile.js View File

@ -115,6 +115,7 @@ var buildWebUI = function(module) {
modules['sensor'] = true;
modules['rfbridge'] = true;
modules['rfm69'] = false; // we will never be adding this except when building RFM69GW
modules['lightfox'] = false; // we will never be adding this except when building lightfox
} else if ('small' !== module) {
modules[module] = true;
}
@ -186,6 +187,10 @@ gulp.task('webui_rfm69', function() {
return buildWebUI('rfm69');
});
gulp.task('webui_lightfox', function() {
return buildWebUI('lightfox');
});
gulp.task('webui_all', function() {
return buildWebUI('all');
});
@ -197,6 +202,7 @@ gulp.task('webui',
'webui_light',
'webui_rfbridge',
'webui_rfm69',
'webui_lightfox',
'webui_all'
)
);


+ 2
- 0
code/html/custom.css View File

@ -158,6 +158,7 @@ div.state {
.button-reconnect,
.button-ha-del,
.button-rfb-forget,
.button-lightfox-clear,
.button-del-network,
.button-del-mapping,
.button-del-schedule,
@ -176,6 +177,7 @@ div.state {
.button-add-mapping,
.button-upgrade-browse,
.button-rfb-learn,
.button-lightfox-learn,
.button-ha-add,
.button-ha-config,
.button-settings-backup,


+ 55
- 0
code/html/custom.js View File

@ -1159,6 +1159,48 @@ function addRfbNode() {
}
<!-- endRemoveIf(!rfbridge)-->
// -----------------------------------------------------------------------------
// LightFox
// -----------------------------------------------------------------------------
<!-- removeIf(!lightfox)-->
function lightfoxLearn() {
sendAction("lightfoxLearn", {});
}
function lightfoxClear() {
sendAction("lightfoxClear", {});
}
function initLightfox(data, relayCount) {
var numNodes = data.length;
var template = $("#lightfoxNodeTemplate").children();
var i, j;
for (i=0; i<numNodes; i++) {
var $line = $(template).clone();
$line.find("label > span").text(data[i]["id"]);
$line.find("select").each(function() {
$(this).attr("name", "btnRelay" + data[i]["id"]);
for (j=0; j < relayCount; j++) {
$(this).append($("<option >").attr("value", j).text("Switch #" + j));
}
$(this).val(data[i]["relay"]);
status = !status;
});
$line.appendTo("#lightfoxNodes");
}
var $panel = $("#panel-lightfox")
$(".button-lightfox-learn").off("click").click(lightfoxLearn);
$(".button-lightfox-clear").off("click").click(lightfoxClear);
}
<!-- endRemoveIf(!lightfox)-->
// -----------------------------------------------------------------------------
// Processing
// -----------------------------------------------------------------------------
@ -1236,6 +1278,19 @@ function processData(data) {
<!-- endRemoveIf(!rfbridge)-->
// ---------------------------------------------------------------------
// LightFox
// ---------------------------------------------------------------------
<!-- removeIf(!lightfox)-->
if ("lightfoxButtons" === key) {
initLightfox(data["lightfoxButtons"], data["lightfoxRelayCount"]);
return;
}
<!-- endRemoveIf(!rfbridge)-->
// ---------------------------------------------------------------------
// RFM69
// ---------------------------------------------------------------------


+ 52
- 6
code/html/index.html View File

@ -96,6 +96,12 @@
<a href="#" class="pure-menu-link" data="panel-general">GENERAL</a>
</li>
<!-- removeIf(!lightfox) -->
<li class="pure-menu-item module module-lightfox">
<a href="#" class="pure-menu-link" data="panel-lightfox">LIGHTFOX RF</a>
</li>
<!-- endRemoveIf(!lightfox) -->
<li class="pure-menu-item module module-dcz">
<a href="#" class="pure-menu-link" data="panel-domoticz">DOMOTICZ</a>
</li>
@ -183,9 +189,9 @@
<div class="footer">
&copy; 2016-2019<br />
Xose Pérez<br/>
<a href="https://twitter.com/xoseperez" target="_blank">@xoseperez</a><br/>
<a href="http://tinkerman.cat" target="_blank">http://tinkerman.cat</a><br/>
<a href="https://github.com/xoseperez/espurna" target="_blank">ESPurna @ GitHub</a><br/>
<a href="https://twitter.com/xoseperez" rel="noopener" target="_blank">@xoseperez</a><br/>
<a href="http://tinkerman.cat" rel="noopener" target="_blank">http://tinkerman.cat</a><br/>
<a href="https://github.com/xoseperez/espurna" rel="noopener" target="_blank">ESPurna @ GitHub</a><br/>
GPLv3 license<br/>
</div>
@ -661,7 +667,7 @@
<div class="pure-u-1-4 pure-u-lg-1-8"><button type="button" class="pure-button button-upgrade-browse pure-u-23-24">Browse</button></div>
<div class="pure-u-1-4 pure-u-lg-1-8"><button type="button" class="pure-button button-upgrade pure-u-23-24">Upgrade</button></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">The device has <span name="free_size"></span> bytes available for OTA updates. If your image is larger than this consider doing a <a href="https://github.com/xoseperez/espurna/wiki/TwoStepUpdates" target="_blank"><strong>two-step update</strong></a>.</div>
<div class="pure-u-1 pure-u-lg-3-4 hint">The device has <span name="free_size"></span> bytes available for OTA updates. If your image is larger than this consider doing a <a href="https://github.com/xoseperez/espurna/wiki/TwoStepUpdates" rel="noopener" target="_blank"><strong>two-step update</strong></a>.</div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4"><progress id="upgrade-progress"></progress></div>
<input name="upgrade" type="file" tabindex="17" />
@ -907,7 +913,7 @@
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
This is the fingerprint for the SSL certificate of the server.<br />
You can get it using <a href="https://www.grc.com/fingerprints.htm" target="_blank">https://www.grc.com/fingerprints.htm</a><br />
You can get it using <a href="https://www.grc.com/fingerprints.htm" rel="noopener" target="_blank">https://www.grc.com/fingerprints.htm</a><br />
or using openssl from a linux box by typing:<br />
<pre>$ openssl s_client -connect &lt;host&gt;:&lt;port&gt; &lt; /dev/null 2&gt;/dev/null | openssl x509 -fingerprint -noout -in /dev/stdin</pre>
</div>
@ -1457,7 +1463,7 @@
To learn a new code click <strong>LEARN</strong> (the Sonoff RFBridge will beep) then press a button on the remote, the new code should show up (and the RFBridge will double beep). If the device double beeps but the code does not update it has not been properly learnt. Keep trying.<br /><br />
Modify or create new codes manually and then click <strong>SAVE</strong> to store them in the device memory. If your controlled device uses the same code to switch ON and OFF, learn the code with the ON button and copy paste it to the OFF input box, then click SAVE on the last one to store the value.<br /><br />
Delete any code clicking the <strong>FORGET</strong> button.
<span class="module module-rfbraw"><br /><br />You can also specify 116-chars long RAW codes. Raw codes require a <a target="_blank" href="https://github.com/rhx/RF-Bridge-EFM8BB1">specific firmware for for the EFM8BB1</a>.</span>
<span class="module module-rfbraw"><br /><br />You can also specify 116-chars long RAW codes. Raw codes require a <a rel="noopener" target="_blank" href="https://github.com/rhx/RF-Bridge-EFM8BB1">specific firmware for for the EFM8BB1</a>.</span>
</h2>
</div>
@ -1471,6 +1477,35 @@
</form>
<!-- endRemoveIf(!rfbridge) -->
<!-- removeIf(!lightfox) -->
<form id="form-lightfox" class="pure-form form-settings">
<div class="panel" id="panel-lightfox">
<div class="header">
<h1>LIGHTFOX RF</h1>
<h2>
LightFox RF configuration<br /><br />
This page allows you to control LightFox RF receiver options.<br /><br />
To learn a new code click <strong>LEARN</strong>, wait for 3 seconds then press a button on the remote, one of the relays will toggle. If no device relay toggles the code has not been properly learnt. Keep trying.<br /><br />
Delete all the codes by clicking the <strong>CLEAR</strong> button and wait for 10 seconds.<br /><br />
You can also specify which RF button controls which relay using controls below.
</h2>
</div>
<div class="page">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">RF Actions</label>
<div class="pure-u-1-2 pure-u-lg-3-8"><button type="button" class="pure-button button-lightfox-learn pure-u-23-24">Learn</button></div>
<div class="pure-u-1-2 pure-u-lg-3-8"><button type="button" class="pure-button button-lightfox-clear pure-u-1">Clear</button></div>
</div>
<fieldset id="lightfoxNodes"></fieldset>
</div>
</div>
</form>
<!-- endRemoveIf(!lightfox) -->
</div> <!-- content -->
</div> <!-- layout -->
@ -1501,6 +1536,17 @@
</div>
<!-- endRemoveIf(!rfbridge) -->
<!-- removeIf(!lightfox) -->
<div id="lightfoxNodeTemplate" class="template">
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">Button #<span></span></label>
<select class="pure-u-1 pure-u-lg-3-4" name="btnRelay" action="reboot"></select>
</div>
</div>
<!-- endRemoveIf(!lightfox) -->
<div id="networkTemplate" class="template">
<div class="pure-g">


+ 23
- 0
code/platformio.ini View File

@ -399,6 +399,29 @@ extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
[env:foxel-lightfox-dual]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DFOXEL_LIGHTFOX_DUAL
extra_scripts = ${common.extra_scripts}
[env:foxel-lightfox-dual-ota]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DFOXEL_LIGHTFOX_DUAL
upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-basic]
platform = ${common.platform}
framework = ${common.framework}


Loading…
Cancel
Save