Browse Source

Merge remote-tracking branch 'upstream/master' into dev

# Conflicts:
#	code/espurna/data/index.html.gz
#	code/espurna/static/index.html.gz.h
i18n
Stefano Cotterli 7 years ago
parent
commit
db408fbf95
39 changed files with 4529 additions and 3625 deletions
  1. +33
    -0
      CHANGELOG.md
  2. +5
    -3
      README.md
  3. +1
    -1
      code/build.sh
  4. +0
    -51
      code/core_version.py
  5. +15
    -8
      code/espurna/ascheduler.ino
  6. +2
    -1
      code/espurna/config/all.h
  7. +6
    -2
      code/espurna/config/arduino.h
  8. +51
    -6
      code/espurna/config/general.h
  9. +81
    -37
      code/espurna/config/hardware.h
  10. +0
    -7
      code/espurna/config/prototypes.h
  11. +42
    -13
      code/espurna/config/sensors.h
  12. +1
    -1
      code/espurna/config/version.h
  13. BIN
      code/espurna/data/index.html.gz
  14. +14
    -2
      code/espurna/domoticz.ino
  15. +3
    -14
      code/espurna/espurna.ino
  16. +1
    -1
      code/espurna/influxdb.ino
  17. +20
    -0
      code/espurna/led.ino
  18. +46
    -2
      code/espurna/light.ino
  19. +34
    -1
      code/espurna/migrate.ino
  20. +44
    -12
      code/espurna/mqtt.ino
  21. +68
    -55
      code/espurna/relay.ino
  22. +5
    -2
      code/espurna/rfbridge.ino
  23. +9
    -0
      code/espurna/sensor.ino
  24. +155
    -0
      code/espurna/sensors/BH1750Sensor.h
  25. +9
    -4
      code/espurna/sensors/DHTSensor.h
  26. +51
    -4
      code/espurna/sensors/EmonADC121Sensor.h
  27. +1
    -0
      code/espurna/sensors/SHT3XI2CSensor.h
  28. +3105
    -3092
      code/espurna/static/index.html.gz.h
  29. +44
    -0
      code/extra_scripts.py
  30. +2
    -2
      code/html/checkboxes.css
  31. +4
    -2
      code/html/custom.css
  32. +4
    -4
      code/html/custom.js
  33. +46
    -7
      code/html/index.html
  34. +250
    -0
      code/memanalyzer.py
  35. +210
    -0
      code/ota.py
  36. +0
    -207
      code/ota_flash.sh
  37. +0
    -74
      code/ota_list.sh
  38. +160
    -10
      code/platformio.ini
  39. +7
    -0
      code/requirements.txt

+ 33
- 0
CHANGELOG.md View File

@ -3,6 +3,39 @@
The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/).
## [1.11.3] 2018-01-02
### Fixed
- Fix uninitialized PWM channels bug (#356)
### Added
- Added memory analyzer
## [1.11.2] 2017-12-30
### Fixed
- Fix my92xx and pwm references for Arduino IDE (#346)
- Fix SHT3X I2C sensor magnitude count (#337)
- Fix timing for DHT11 sensors (#294)
- Fix overflow in relayParsePayload with long MQTT messages (#344)
- Fix loading of Dallas and DHT sensors for Sonoff TH images (#352)
- Subscribe to Domoticz MQTT topics only if Domotic< is enabled
### Added
- Added option to change MQTT retain flag, QoS and keepalive time from webUI (#321)
- Added LED modes "always off" and "always on" (#348)
- Defined new ESPurna switch (no HLW8012 support & touch button ready)
### Changed
- Stop requiring definition of boards in migrate module
## [1.11.1] 2017-12-29
### Fixed
- Fixed relay status on reboot
### Added
- Added support for Arilux AL-LC01 and AL-LC11
- Added support for BH1750 luminosity sensor
- Added automatic memory size identification in ota_flash script
## [1.11.0] 2017-12-28
### Fixed
- Fixed Arduino IDE compilation issues (#330)


+ 5
- 3
README.md View File

@ -4,7 +4,7 @@ ESPurna ("spark" in Catalan) is a custom firmware for ESP8266 based smart switch
It was originally developed with the **[IteadStudio Sonoff](https://www.itead.cc/sonoff-wifi-wireless-switch.html)** in mind but now it supports a growing number of ESP8266-based boards.
It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries.
> **Current Release Version is 1.11.0**, read the [changelog](https://bitbucket.org/xoseperez/espurna/src/master/CHANGELOG.md).
> **Current Release Version is 1.11.3**, read the [changelog](https://bitbucket.org/xoseperez/espurna/src/master/CHANGELOG.md).
> **NOTICE**: Default flash layout changed in 1.8.3, as an unpredicted consequence devices will not be able to persist/retrieve configuration if flashed with 1.8.3 via **OTA** from **PlatformIO**. Please check issue #187.
@ -50,10 +50,11 @@ It uses the Arduino Core for ESP8266 framework and a number of 3rd party librari
* **DHT11 / DHT22 / DHT21 / AM2301 / Itead's SI7021** (supports celsius & fahrenheit reporting)
* **BMP280** and **BME280** temperature, humidity (BME280) and pressure sensor by Bosch
* **SI7021** temperature and humidity sensor
* **SHT2X** temperature and humidity sensor over I2C (Wemos shield)
* **SHT3X** temperature and humidity sensor over I2C (Wemos shield)
* **Dallas OneWire sensors** like the DS18B20 (supports celsius & fahrenheit reporting)
* **MHZ19** CO2 sensor
* **PMSX003** dust sensor
* **BH1750** luminosity sensor
* Power monitoring
* **HLW8012** using the [HLW8012 Library](https://bitbucket.org/xoseperez/hlw8012) (Sonoff POW)
* Non-invasive **current sensor** using **internal ADC** or **ADC121** or **ADS1115**
@ -103,6 +104,7 @@ It uses the Arduino Core for ESP8266 framework and a number of 3rd party librari
* Double click to enter AP mode (only main button)
* Long click (>1 second) to reboot device (only main button)
* Extra long click (>10 seconds) to go back to factory settings (only main button)
* Specific definitions for touch button devices (ESPurna Switch, Sonoff Touch & T1)
## Documentation
@ -137,7 +139,7 @@ Here is the list of supported hardware. For more information please refer to the
|![EXS Wifi Relay v3.1](images/devices/exs-wifi-relay-v31.jpg)|||
|**EXS Wifi Relay v3.1**|||
**Other supported boards:** Itead Sonoff LED, Itead Sonoff Dual R2, Huacanxing H802, WiOn 50055, ManCaveMade ESP-Live, InterMitTech QuinLED 2.6, Arilux AL-LC06, Arilux E27 light bulb, Xenon SM-PW702U, Authometion LYT8266, YJZK 2-gang switch.
**Other supported boards:** Itead Sonoff LED, Itead Sonoff Dual R2, Huacanxing H802, WiOn 50055, ManCaveMade ESP-Live, InterMitTech QuinLED 2.6, Arilux AL-LC01, Arilux AL-LC06, Arilux AL-LC11, Arilux E27 light bulb, Xenon SM-PW702U, Authometion LYT8266, YJZK 2-gang switch.
## License


+ 1
- 1
code/build.sh View File

@ -45,7 +45,7 @@ echo "Building firmware images..."
mkdir -p firmware/espurna-$version
for environment in $environments; do
echo "* espurna-$version-$environment.bin"
platformio run -s -e $environment || exit
platformio run --silent --environment $environment || exit
mv .pioenvs/$environment/firmware.bin firmware/espurna-$version/espurna-$version-$environment.bin
done
echo "--------------------------------------------------------------"

+ 0
- 51
code/core_version.py View File

@ -1,51 +0,0 @@
#!/bin/python
import json
import commands
import subprocess
import os
import sys
def core_version(env):
# Get the core folder
fwdir = env["FRAMEWORK_ARDUINOESP8266_DIR"]
# Get the core version
with open(fwdir + '/package.json') as data_file:
data = json.load(data_file)
core_version = data["version"].upper().replace(".", "_").replace("-", "_")
print "CORE VERSION: %s" % core_version
# Get git version
pr = subprocess.Popen(
"git --git-dir .git rev-parse --short=8 HEAD 2>/dev/null || echo ffffffff",
cwd = fwdir,
shell = True, stdout = subprocess.PIPE, stderr = subprocess.PIPE )
(out, error) = pr.communicate()
git_version = str(out).replace('\n', "")
print "GIT VERSION: %s" % git_version
#env["BUILD_FLAGS"][0] += str(" -DARDUINO_ESP8266_RELEASE=" + core_version)
#env["BUILD_FLAGS"][0] += str(" -DARDUINO_ESP8266_RELEASE_" + core_version)
#env["BUILD_FLAGS"][0] += str(" -DARDUINO_ESP8266_GIT_VER=" + git_version)
with open('espurna/config/core_version.h', 'w') as the_file:
the_file.write('#define ARDUINO_ESP8266_RELEASE "%s"\n' % core_version)
the_file.write('#define ARDUINO_ESP8266_RELEASE_%s\n' % core_version)
the_file.write('#define ARDUINO_ESP8266_GIT_VER "%s"\n' % git_version)
#env.Append(
# CFLAGS = [
# str("-DARDUINO_ESP8266_RELEASE=" + core_version),
# str("-DARDUINO_ESP8266_RELEASE_" + core_version),
# str("-DARDUINO_ESP8266_GIT_VER=" + git_version)
# ]
#)
#print " -DARDUINO_ESP8266_RELEASE=" + core_version +
# " -DARDUINO_ESP8266_RELEASE_" + core_version +
# " -DARDUINO_ESP8266_GIT_VER=" + git_version
Import('env')
core_version(env)

+ 15
- 8
code/espurna/ascheduler.ino View File

@ -39,17 +39,23 @@ void schSetup(){
int sch_operation = getSetting("sch_operation" + String(i)).toInt();
int sch_hour = getSetting("sch_hour" + String(i)).toInt();
int sch_minute = getSetting("sch_minute" + String(i)).toInt();
DEBUG_MSG_P(PSTR("[SCH] Turn switch #%d %d AT %02d:%02d ON %s\n"), sch_switch, sch_operation, sch_hour, sch_minute, (char *)sch_weekdays.c_str());
DEBUG_MSG_P(PSTR("[SCH] Turn switch #%d %s at %02d:%02d on %s\n"), sch_switch, sch_operation ? "ON" : "OFF", sch_hour, sch_minute, (char *)sch_weekdays.c_str());
}
}
void schLoop(){
// Check if we should compare scheduled and actual times
// TODO (?) start every minute and 0 seconds
// Check if we should compare scheduled and actual times
static unsigned long last_update = 0;
static bool r_on = true;
if ((millis() - last_update > SCH_UPDATE_INTERVAL) || (last_update == 0)) {
static int sec = 0;
if ((millis() - last_update > ((SCH_UPDATE_SEC + 60 - sec)*1000)) || (last_update == 0)) {
last_update = millis();
if (!ntpConnected()){
DEBUG_MSG_P(PSTR("[SCH] no NTP\n"));
}
else {
// compare at next minute and SCH_UPDATE_SEC seconds
sec = NTP.getTimeDateString().substring(6, 8).toInt();
}
int i;
for (i = 0; i < MAX_SCHEDULED; i++) {
if (getSetting("sch_switch" + String(i)).length() == 0)
@ -60,15 +66,16 @@ void schLoop(){
int sch_operation = getSetting("sch_operation" + String(i)).toInt();
int sch_hour = getSetting("sch_hour" + String(i)).toInt();
int sch_minute = getSetting("sch_minute" + String(i)).toInt();
DEBUG_MSG_P(PSTR("[SCH] Today it will turn switch #%d %d @ %02d:%02d\n"), sch_switch, sch_operation, sch_hour, sch_minute);
//DEBUG_MSG_P(PSTR("[SCH] Today it will turn switch #%d %d @ %02d:%02d\n"), sch_switch, sch_operation, sch_hour, sch_minute);
int minToTrigger = diffTime(sch_hour, sch_minute);
if (minToTrigger == 0) {
relayStatus(sch_switch, sch_operation);
DEBUG_MSG_P(PSTR("[SCH] TRIGGERED!!\n"));
DEBUG_MSG_P(PSTR("[SCH] TRIGGERED!! switch #%d is %s\n"), sch_switch, sch_operation ? "ON" : "OFF");
}
if (minToTrigger < 0) {
//DEBUG_MSG_P(PSTR("[SCH] Time now: %s\n"), (char *)ntpDateTime().c_str()); // aaaa/mm/dd hh:mm:ss
DEBUG_MSG_P(PSTR("[SCH] Time now: %s, %d minutes to trigger %02d:%02d\n"), (char *)ntpDateTime().c_str(), minToTrigger, sch_hour, sch_minute);
DEBUG_MSG_P(PSTR("[SCH] Time now: %s, %d minutes to trigger %02d:%02d switch #%d %s\n"),
(char *)ntpDateTime().c_str(), -minToTrigger, sch_hour, sch_minute, sch_switch, sch_operation ? "ON" : "OFF");
}
}
}


+ 2
- 1
code/espurna/config/all.h View File

@ -2,8 +2,8 @@
#include "arduino.h"
#include "hardware.h"
#include "defaults.h"
#include "prototypes.h"
#include "general.h"
#include "prototypes.h"
#include "sensors.h"
#ifdef USE_CORE_VERSION_H
@ -20,6 +20,7 @@
(Define USE_CUSTOM_H on commandline for platformio:
export PLATFORMIO_BUILD_FLAGS="'-DUSE_CUSTOM_H'" )
*/
#ifdef USE_CUSTOM_H
#include "custom.h"
#endif

+ 6
- 2
code/espurna/config/arduino.h View File

@ -8,7 +8,7 @@
//--------------------------------------------------------------------------------
//#define NODEMCU_LOLIN
#define WEMOS_D1_MINI_RELAYSHIELD
//#define WEMOS_D1_MINI_RELAYSHIELD
//#define TINKERMAN_ESPURNA_H06
//#define TINKERMAN_ESPURNA_H08
//#define ITEAD_SONOFF_BASIC
@ -55,6 +55,8 @@
//#define XENON_SM_PW702U
//#define AUTHOMETION_LYT8266
//#define GENERIC_8CH
//#define ARILUX_AL_LC01
//#define ARILUX_AL_LC11
//--------------------------------------------------------------------------------
// Features (values below are non-default values)
@ -71,7 +73,9 @@
//#define IR_SUPPORT 1
//#define LLMNR_SUPPORT 1 // Only with Arduino Core 2.4.0
//#define MDNS_SUPPORT 0
//#define NOFUSS_SUPPORT 1 // Only with Arduino Core 2.4.0
//#define MQTT_SUPPORT 0
//#define NETBIOS_SUPPORT 1 // Only with Arduino Core 2.4.0
//#define NOFUSS_SUPPORT 1
//#define NTP_SUPPORT 0
//#define RF_SUPPORT 1
//#define SPIFFS_SUPPORT 1


+ 51
- 6
code/espurna/config/general.h View File

@ -66,6 +66,11 @@
#define DEBUG_TELNET_SUPPORT TELNET_SUPPORT // Enable telnet debug log if telnet is enabled too
#endif
#if DEBUG_TELNET_SUPPORT
#undef TELNET_SUPPORT
#define TELNET_SUPPORT 1
#endif
//------------------------------------------------------------------------------
// General debug options and macros
@ -203,7 +208,7 @@ PROGMEM const char* const custom_reset_string[] = {
#define RELAY_BOOT_OFF 0
#define RELAY_BOOT_ON 1
#define RELAY_BOOT_SAME 2
#define RELAY_BOOT_TOOGLE 3
#define RELAY_BOOT_TOGGLE 3
#define RELAY_TYPE_NORMAL 0
#define RELAY_TYPE_INVERSE 1
@ -264,6 +269,8 @@ PROGMEM const char* const custom_reset_string[] = {
#define LED_MODE_FOLLOW_INVERSE 3 // LED will follow the opposite state of linked relay (check RELAY#_LED)
#define LED_MODE_FINDME 4 // LED will be ON if all relays are OFF
#define LED_MODE_MIXED 5 // A mixed between WIFI and FINDME
#define LED_MODE_ON 6 // LED always ON
#define LED_MODE_OFF 7 // LED always OFF
// -----------------------------------------------------------------------------
// WIFI
@ -563,6 +570,11 @@ PROGMEM const char* const custom_reset_string[] = {
#define DOMOTICZ_SUPPORT MQTT_SUPPORT // Build with domoticz (if MQTT) support (1.72Kb)
#endif
#if DOMOTICZ_SUPPORT
#undef MQTT_SUPPORT
#define MQTT_SUPPORT 1 // If Domoticz enabled enable MQTT
#endif
#define DOMOTICZ_ENABLED 0 // Disable domoticz by default
#define DOMOTICZ_IN_TOPIC "domoticz/in" // Default subscription topic
#define DOMOTICZ_OUT_TOPIC "domoticz/out" // Default publication topic
@ -576,6 +588,11 @@ PROGMEM const char* const custom_reset_string[] = {
#define HOMEASSISTANT_SUPPORT MQTT_SUPPORT // Build with home assistant support (if MQTT, 1.64Kb)
#endif
#if HOMEASSISTANT_SUPPORT
#undef MQTT_SUPPORT
#define MQTT_SUPPORT 1 // If Home Assistant enabled enable MQTT
#endif
#define HOMEASSISTANT_ENABLED 0 // Integration not enabled by default
#define HOMEASSISTANT_PREFIX "homeassistant" // Default MQTT prefix
@ -664,6 +681,22 @@ PROGMEM const char* const custom_reset_string[] = {
#if IR_SUPPORT
#if IR_BUTTON_SET == 1
/*
+------+------+------+------+
| UP | Down | OFF | ON |
+------+------+------+------+
| R | G | B | W |
+------+------+------+------+
| 1 | 2 | 3 |FLASH |
+------+------+------+------+
| 4 | 5 | 6 |STROBE|
+------+------+------+------+
| 7 | 8 | 9 | FADE |
+------+------+------+------+
| 10 | 11 | 12 |SMOOTH|
+------+------+------+------+
*/
#define IR_BUTTON_COUNT 24
const unsigned long IR_BUTTON[IR_BUTTON_COUNT][3] PROGMEM = {
@ -705,6 +738,22 @@ PROGMEM const char* const custom_reset_string[] = {
//Remote Buttons SET 2 (another identical IR Remote shipped with another controller)
#if IR_BUTTON_SET == 2
/*
+------+------+------+------+
| UP | Down | OFF | ON |
+------+------+------+------+
| R | G | B | W |
+------+------+------+------+
| 1 | 2 | 3 |FLASH |
+------+------+------+------+
| 4 | 5 | 6 |STROBE|
+------+------+------+------+
| 7 | 8 | 9 | FADE |
+------+------+------+------+
| 10 | 11 | 12 |SMOOTH|
+------+------+------+------+
*/
#define IR_BUTTON_COUNT 24
const unsigned long IR_BUTTON[IR_BUTTON_COUNT][3] PROGMEM = {
@ -742,6 +791,7 @@ PROGMEM const char* const custom_reset_string[] = {
};
#endif
#endif // IR_SUPPORT
//--------------------------------------------------------------------------------
@ -760,8 +810,3 @@ PROGMEM const char* const custom_reset_string[] = {
#define RF_CHANNEL 31
#define RF_DEVICE 1
#define SCHEDULER_SUPPORT 1
#define SCH_UPDATE_INTERVAL 30000
#define MAX_SCHEDULED 10

+ 81
- 37
code/espurna/config/hardware.h View File

@ -23,7 +23,7 @@
// -----------------------------------------------------------------------------
// Development boards
// -----------------------------------------------------------------------------
#define NODEMCU_LOLIN
#if defined(NODEMCU_LOLIN)
// Info
@ -36,11 +36,15 @@
#define BUTTON1_RELAY 1
// Relays
#define RELAY1_PIN 12
#define RELAY1_PIN 5
#define RELAY1_TYPE RELAY_TYPE_NORMAL
#define RELAY2_PIN 4
#define RELAY2_TYPE RELAY_TYPE_NORMAL
#define RELAY3_PIN 12
#define RELAY3_TYPE RELAY_TYPE_NORMAL
#define SCHEDULER_SUPPORT 1
#define SCH_UPDATE_INTERVAL 30000
#define SCH_UPDATE_SEC 5 //scheduler perform switch at hh:mm:05
#define MAX_SCHEDULED 10
// LEDs
@ -82,23 +86,8 @@
#define BUTTON1_PIN 4
#define BUTTON1_RELAY 1
#ifdef USE_TOUCH_BUTTON
// Touch button
#define BUTTON1_MODE BUTTON_PUSHBUTTON
#define BUTTON1_PRESS BUTTON_MODE_TOGGLE
#define BUTTON1_CLICK BUTTON_MODE_NONE
#define BUTTON1_DBLCLICK BUTTON_MODE_NONE
#define BUTTON1_LNGCLICK BUTTON_MODE_NONE
#define BUTTON1_LNGLNGCLICK BUTTON_MODE_NONE
#else
// Normal pushbutton
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#endif
// Normal pushbutton
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Relays
#define RELAY1_PIN 12
@ -126,22 +115,8 @@
#define BUTTON1_PIN 4
#define BUTTON1_RELAY 1
#ifdef USE_TOUCH_BUTTON
// Touch button
#define BUTTON1_MODE BUTTON_PUSHBUTTON
#define BUTTON1_PRESS BUTTON_MODE_TOGGLE
#define BUTTON1_CLICK BUTTON_MODE_NONE
#define BUTTON1_DBLCLICK BUTTON_MODE_NONE
#define BUTTON1_LNGCLICK BUTTON_MODE_NONE
#define BUTTON1_LNGLNGCLICK BUTTON_MODE_NONE
#else
// Normal pushbutton
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#endif
// Normal pushbutton
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Relays
#define RELAY1_PIN 12
@ -159,6 +134,32 @@
#define HLW8012_CF1_PIN 13
#define HLW8012_CF_PIN 14
#elif defined(TINKERMAN_ESPURNA_SWITCH)
// Info
#define MANUFACTURER "TINKERMAN"
#define DEVICE "ESPURNA_SWITCH"
// Buttons
#define BUTTON1_PIN 4
#define BUTTON1_RELAY 1
// Touch button
#define BUTTON1_MODE BUTTON_PUSHBUTTON
#define BUTTON1_PRESS BUTTON_MODE_TOGGLE
#define BUTTON1_CLICK BUTTON_MODE_NONE
#define BUTTON1_DBLCLICK BUTTON_MODE_NONE
#define BUTTON1_LNGCLICK BUTTON_MODE_NONE
#define BUTTON1_LNGLNGCLICK BUTTON_MODE_NONE
// LEDs
#define LED1_PIN 2
#define LED1_PIN_INVERSE 0
// Relays
#define RELAY1_PIN 12
#define RELAY1_TYPE RELAY_TYPE_INVERSE
// -----------------------------------------------------------------------------
// Itead Studio boards
// -----------------------------------------------------------------------------
@ -735,7 +736,6 @@
// LEDs
#define LED1_PIN 13
#define LED1_PIN_INVERSE 0
#define LED_WIFI 0
// -----------------------------------------------------------------------------
@ -1169,6 +1169,27 @@
// Arilux AL-LC06
// -----------------------------------------------------------------------------
#elif defined(ARILUX_AL_LC01)
// Info
#define MANUFACTURER "ARILUX"
#define DEVICE "AL_LC01"
#define RELAY_PROVIDER RELAY_PROVIDER_LIGHT
#define LIGHT_PROVIDER LIGHT_PROVIDER_DIMMER
#define DUMMY_RELAY_COUNT 1
// Light
#define LIGHT_CHANNELS 4
#define LIGHT_CH1_PIN 5 // RED
#define LIGHT_CH2_PIN 12 // GREEN
#define LIGHT_CH3_PIN 13 // BLUE
#define LIGHT_CH4_PIN 14 // WHITE1
#define LIGHT_CH1_INVERSE 0
#define LIGHT_CH2_INVERSE 0
#define LIGHT_CH3_INVERSE 0
#define LIGHT_CH4_INVERSE 0
#elif defined(ARILUX_AL_LC06)
// Info
@ -1192,6 +1213,29 @@
#define LIGHT_CH5_INVERSE 0
#elif defined(ARILUX_AL_LC11)
// Info
#define MANUFACTURER "ARILUX"
#define DEVICE "AL_LC11"
#define RELAY_PROVIDER RELAY_PROVIDER_LIGHT
#define LIGHT_PROVIDER LIGHT_PROVIDER_DIMMER
#define DUMMY_RELAY_COUNT 1
// Light
#define LIGHT_CHANNELS 5
#define LIGHT_CH1_PIN 5 // RED
#define LIGHT_CH2_PIN 4 // GREEN
#define LIGHT_CH3_PIN 14 // BLUE
#define LIGHT_CH4_PIN 13 // WHITE1
#define LIGHT_CH5_PIN 12 // WHITE1
#define LIGHT_CH1_INVERSE 0
#define LIGHT_CH2_INVERSE 0
#define LIGHT_CH3_INVERSE 0
#define LIGHT_CH4_INVERSE 0
#define LIGHT_CH5_INVERSE 0
#elif defined(ARILUX_E27)
// Info


+ 0
- 7
code/espurna/config/prototypes.h View File

@ -81,13 +81,6 @@ template<typename T> void domoticzSend(const char * key, T nvalue, const char *
template<typename T> bool idbSend(const char * topic, T payload);
template<typename T> bool idbSend(const char * topic, unsigned char id, T payload);
// -----------------------------------------------------------------------------
// Light
// -----------------------------------------------------------------------------
#if LIGHT_PROVIDER == LIGHT_PROVIDER_MY92XX
#include <my92xx.h>
#endif
// -----------------------------------------------------------------------------
// Utils
// -----------------------------------------------------------------------------


+ 42
- 13
code/espurna/config/sensors.h View File

@ -2,7 +2,7 @@
// SENSORS - General data
// =============================================================================
#define SENSOR_DEBUG 0 // Debug sensors
#define SENSOR_DEBUG 1 // Debug sensors
#define SENSOR_READ_INTERVAL 6 // Read data from sensors every 6 seconds
#define SENSOR_READ_MIN_INTERVAL 6 // Minimum read interval
@ -57,6 +57,7 @@
#define SENSOR_MHZ19_ID 0x14
#define SENSOR_SI7021_ID 0x15
#define SENSOR_SHT3X_I2C_ID 0x16
#define SENSOR_BH1750_ID 0x17
//--------------------------------------------------------------------------------
// Magnitudes
@ -81,8 +82,9 @@
#define MAGNITUDE_PM2dot5 16
#define MAGNITUDE_PM10 17
#define MAGNITUDE_CO2 18
#define MAGNITUDE_LUX 19
#define MAGNITUDE_MAX 19
#define MAGNITUDE_MAX 20
// =============================================================================
// Specific data for each sensor
@ -102,6 +104,27 @@
#define ADC_VCC_ENABLED 0
#endif
//------------------------------------------------------------------------------
// BH1750
// Enable support by passing BH1750_SUPPORT=1 build flag
// http://www.elechouse.com/elechouse/images/product/Digital%20light%20Sensor/bh1750fvi-e.pdf
//------------------------------------------------------------------------------
#ifndef BH1750_SUPPORT
#define BH1750_SUPPORT 0
#endif
#ifndef BH1750_ADDRESS
#define BH1750_ADDRESS 0x00 // 0x00 means auto
#endif
#define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE
#if BH1750_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------
// BME280/BMP280
// Enable support by passing BMX280_SUPPORT=1 build flag
@ -135,7 +158,7 @@
#endif
#ifndef DALLAS_PIN
#define DALLAS_PIN 13
#define DALLAS_PIN 14
#endif
#define DALLAS_RESOLUTION 9 // Not used atm
@ -151,7 +174,7 @@
#endif
#ifndef DHT_PIN
#define DHT_PIN 13
#define DHT_PIN 14
#endif
#ifndef DHT_TYPE
@ -415,7 +438,7 @@
// Sensor helpers configuration
// =============================================================================
#if ANALOG_SUPPORT || BMX280_SUPPORT || DALLAS_SUPPORT \
#if ANALOG_SUPPORT || BH1750_SUPPORT || BMX280_SUPPORT || DALLAS_SUPPORT \
|| DHT_SUPPORT || DIGITAL_SUPPORT || ECH1560_SUPPORT \
|| EMON_ADC121_SUPPORT || EMON_ADS1X15_SUPPORT \
|| EMON_ANALOG_SUPPORT || EVENTS_SUPPORT || HLW8012_SUPPORT \
@ -474,7 +497,7 @@ PROGMEM const unsigned char magnitude_decimals[] = {
3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
0, 0, 0,
0
0, 0
};
PROGMEM const char magnitude_unknown_topic[] = "unknown";
@ -489,22 +512,23 @@ PROGMEM const char magnitude_reactive_power_topic[] = "reactive";
PROGMEM const char magnitude_power_factor_topic[] = "factor";
PROGMEM const char magnitude_energy_topic[] = "energy";
PROGMEM const char magnitude_energy_delta_topic[] = "energy_delta";
PROGMEM const char magnitude_pm1dot0_topic[] = "pm1dot0";
PROGMEM const char magnitude_pm2dot5_topic[] = "pm2dot5";
PROGMEM const char magnitude_pm10_topic[] = "pm10";
PROGMEM const char magnitude_analog_topic[] = "analog";
PROGMEM const char magnitude_digital_topic[] = "digital";
PROGMEM const char magnitude_events_topic[] = "events";
PROGMEM const char magnitude_pm1dot0_topic[] = "pm1dot0";
PROGMEM const char magnitude_pm2dot5_topic[] = "pm2dot5";
PROGMEM const char magnitude_pm10_topic[] = "pm10";
PROGMEM const char magnitude_co2_topic[] = "co2";
PROGMEM const char magnitude_lux_topic[] = "lux";
PROGMEM const char* const magnitude_topics[] = {
magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic,
magnitude_pressure_topic, magnitude_current_topic, magnitude_voltage_topic,
magnitude_active_power_topic, magnitude_apparent_power_topic, magnitude_reactive_power_topic,
magnitude_power_factor_topic, magnitude_energy_topic, magnitude_energy_delta_topic,
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic,
magnitude_co2_topic
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_co2_topic, magnitude_lux_topic
};
PROGMEM const char magnitude_empty[] = "";
@ -518,15 +542,16 @@ PROGMEM const char magnitude_watts[] = "W";
PROGMEM const char magnitude_joules[] = "J";
PROGMEM const char magnitude_ugm3[] = "µg/m3";
PROGMEM const char magnitude_ppm[] = "ppm";
PROGMEM const char magnitude_lux[] = "lux";
PROGMEM const char* const magnitude_units[] = {
magnitude_empty, magnitude_celsius, magnitude_percentage,
magnitude_hectopascals, magnitude_amperes, magnitude_volts,
magnitude_watts, magnitude_watts, magnitude_watts,
magnitude_percentage, magnitude_joules, magnitude_joules,
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_empty, magnitude_empty, magnitude_empty,
magnitude_ppm
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_ppm, magnitude_lux
};
#include "../sensors/BaseSensor.h"
@ -535,6 +560,10 @@ PROGMEM const char* const magnitude_units[] = {
#include "../sensors/AnalogSensor.h"
#endif
#if BH1750_SUPPORT
#include "../sensors/BH1750Sensor.h"
#endif
#if BMX280_SUPPORT
#include <SparkFunBME280.h>
#include "../sensors/BMX280Sensor.h"


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

@ -1,5 +1,5 @@
#define APP_NAME "ESPURNA"
#define APP_VERSION "1.11.0"
#define APP_VERSION "1.11.4a"
#define APP_AUTHOR "xose.perez@gmail.com"
#define APP_WEBSITE "http://tinkerman.cat"
#define CFG_VERSION 3

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


+ 14
- 2
code/espurna/domoticz.ino View File

@ -35,8 +35,21 @@ bool _domoticzSkip(unsigned long idx) {
return false;
}
void _domoticzMqttSubscribe(bool value) {
String dczTopicOut = getSetting("dczTopicOut", DOMOTICZ_OUT_TOPIC);
if (value) {
mqttSubscribeRaw(dczTopicOut.c_str());
} else {
mqttUnsubscribeRaw(dczTopicOut.c_str());
}
}
void _domoticzMqtt(unsigned int type, const char * topic, const char * payload) {
if (!_dcz_enabled) return;
String dczTopicOut = getSetting("dczTopicOut", DOMOTICZ_OUT_TOPIC);
if (type == MQTT_CONNECT_EVENT) {
@ -45,8 +58,6 @@ void _domoticzMqtt(unsigned int type, const char * topic, const char * payload)
if (type == MQTT_MESSAGE_EVENT) {
if (!_dcz_enabled) return;
// Check topic
if (dczTopicOut.equals(topic)) {
@ -107,6 +118,7 @@ void _domoticzWebSocketOnSend(JsonObject& root) {
void _domoticzConfigure() {
_dcz_enabled = getSetting("dczEnabled", DOMOTICZ_ENABLED).toInt() == 1;
_dcz_skip_time = 1000 * getSetting("dczSkip", DOMOTICZ_SKIP_TIME).toInt();
_domoticzMqttSubscribe(_dcz_enabled);
}
//------------------------------------------------------------------------------


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

@ -56,20 +56,9 @@ void hardwareSetup() {
void hardwareLoop() {
// Heartbeat
static unsigned long last_uptime = 0;
static bool on_connect = true;
bool send = (last_uptime == 0);
send = send || (millis() - last_uptime > HEARTBEAT_INTERVAL);
if (mqttConnected()) {
send = send || on_connect;
} else {
on_connect = true;
}
if (send) {
last_uptime = millis();
if (mqttConnected()) on_connect = false;
static unsigned long last = 0;
if ((last == 0) || (millis() - last > HEARTBEAT_INTERVAL)) {
last = millis();
heartbeat();
}


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

@ -78,7 +78,7 @@ template<typename T> bool idbSend(const char * topic, T payload) {
template<typename T> bool idbSend(const char * topic, unsigned char id, T payload) {
char measurement[64];
snprintf_P(measurement, sizeof(measurement), PSTR("%s,id=%d"), topic, id);
snprintf(measurement, sizeof(measurement), "%s,id=%d", topic, id);
return idbSend(topic, payload);
}


+ 20
- 0
code/espurna/led.ino View File

@ -18,6 +18,7 @@ typedef struct {
} led_t;
std::vector<led_t> _leds;
bool _led_update = false; // For relay-based modes
// -----------------------------------------------------------------------------
@ -115,10 +116,15 @@ void _ledConfigure() {
for (unsigned int i=0; i < _leds.size(); i++) {
_ledMode(i, getSetting("ledMode", i, _ledMode(i)).toInt());
}
_led_update = true;
}
// -----------------------------------------------------------------------------
void ledUpdate(bool value) {
_led_update = value;
}
void ledSetup() {
#ifdef LED1_PIN
@ -206,6 +212,9 @@ void ledLoop() {
}
// Relay-based modes, update only if relays have been updated
if (!_led_update) continue;
if (_ledMode(i) == LED_MODE_FOLLOW) {
_ledStatus(i, relayStatus(_leds[i].relay-1));
}
@ -225,5 +234,16 @@ void ledLoop() {
_ledStatus(i, status);
}
if (_ledMode(i) == LED_MODE_ON) {
_ledStatus(i, true);
}
if (_ledMode(i) == LED_MODE_OFF) {
_ledStatus(i, false);
}
}
_led_update = false;
}

+ 46
- 2
code/espurna/light.ino View File

@ -309,6 +309,17 @@ void _toLong(char * color, size_t len) {
_toLong(color, len, false);
}
void _toCSV(char * buffer, size_t len, bool applyBrightness) {
char num[10];
float b = applyBrightness ? (float) _light_brightness / LIGHT_MAX_BRIGHTNESS : 1;
for (unsigned char i=0; i<_light_channel.size(); i++) {
itoa(_light_channel[i].value * b, num, 10);
if (i>0) strncat(buffer, ",", len--);
strncat(buffer, num, len);
len = len - strlen(num);
}
}
// Thanks to Sacha Telgenhof for sharing this code in his AiLight library
// https://github.com/stelgenhof/AiLight
void _fromKelvin(unsigned long kelvin) {
@ -451,6 +462,7 @@ void _lightColorRestore() {
#if MQTT_SUPPORT
void _lightMQTTCallback(unsigned int type, const char * topic, const char * payload) {
String mqtt_group_color = getSetting("mqttGroupColor");
if (type == MQTT_CONNECT_EVENT) {
@ -463,6 +475,10 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
mqttSubscribe(MQTT_TOPIC_COLOR_HSV);
}
// Group color
if (mqtt_group_color.length() > 0) mqttSubscribeRaw(mqtt_group_color.c_str());
// Channels
char buffer[strlen(MQTT_TOPIC_CHANNEL) + 3];
snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_CHANNEL);
mqttSubscribe(buffer);
@ -471,6 +487,13 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
if (type == MQTT_MESSAGE_EVENT) {
// Group color
if ((mqtt_group_color.length() > 0) & (mqtt_group_color.equals(topic))) {
lightColor(payload, true);
lightUpdate(true, mqttForward(), false);
return;
}
// Match topic
String t = mqttSubtopic((char *) topic);
@ -478,28 +501,33 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
if (t.equals(MQTT_TOPIC_MIRED)) {
_fromMireds(atol(payload));
lightUpdate(true, mqttForward());
return;
}
// Color temperature in kelvins
if (t.equals(MQTT_TOPIC_KELVIN)) {
_fromKelvin(atol(payload));
lightUpdate(true, mqttForward());
return;
}
// Color
if (t.equals(MQTT_TOPIC_COLOR) || t.equals(MQTT_TOPIC_COLOR_RGB)) { // DEPRECATE MQTT_TOPIC_COLOR
lightColor(payload, true);
lightUpdate(true, mqttForward());
return;
}
if (t.equals(MQTT_TOPIC_COLOR_HSV)) {
lightColor(payload, false);
lightUpdate(true, mqttForward());
return;
}
// Brightness
if (t.equals(MQTT_TOPIC_BRIGHTNESS)) {
_light_brightness = constrain(atoi(payload), 0, LIGHT_MAX_BRIGHTNESS);
lightUpdate(true, mqttForward());
return;
}
// Channel
@ -511,6 +539,7 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
}
lightChannel(channelID, atoi(payload));
lightUpdate(true, mqttForward());
return;
}
}
@ -519,7 +548,7 @@ void _lightMQTTCallback(unsigned int type, const char * topic, const char * payl
void lightMQTT() {
char buffer[12];
char buffer[20];
if (_light_has_color) {
@ -548,6 +577,15 @@ void lightMQTT() {
}
void lightMQTTGroup() {
String mqtt_group_color = getSetting("mqttGroupColor");
if (mqtt_group_color.length()>0) {
char buffer[20];
_toCSV(buffer, sizeof(buffer), true);
mqttSendRaw(mqtt_group_color.c_str(), buffer);
}
}
#endif
// -----------------------------------------------------------------------------
@ -566,7 +604,7 @@ unsigned char lightWhiteChannels() {
return _light_channel.size() % 3;
}
void lightUpdate(bool save, bool forward) {
void lightUpdate(bool save, bool forward, bool group_forward) {
// Configure color transition
_light_steps_left = _light_use_transitions ? LIGHT_TRANSITION_STEPS : 1;
@ -575,6 +613,7 @@ void lightUpdate(bool save, bool forward) {
// Report color & brightness to MQTT broker
#if MQTT_SUPPORT
if (forward) lightMQTT();
if (group_forward) lightMQTTGroup();
#endif
// Report color to WS clients (using current brightness setting)
@ -589,6 +628,10 @@ void lightUpdate(bool save, bool forward) {
};
void lightUpdate(bool save, bool forward) {
lightUpdate(save, forward, true);
}
#if LIGHT_SAVE_ENABLED == 0
void lightSave() {
_lightColorSave();
@ -667,6 +710,7 @@ void lightBrightnessStep(int steps) {
void _lightWebSocketOnSend(JsonObject& root) {
root["colorVisible"] = 1;
root["mqttGroupColor"] = getSetting("mqttGroupColor");
root["useColor"] = _light_has_color;
root["useWhite"] = _light_use_white;
root["useGamma"] = _light_use_gamma;


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

@ -651,9 +651,42 @@ void migrate() {
setSetting("relayType", 6, RELAY_TYPE_NORMAL);
setSetting("relayType", 7, RELAY_TYPE_NORMAL);
#elif defined(ARILUX_AL_LC01)
setSetting("board", 50);
setSetting("relayProvider", RELAY_PROVIDER_LIGHT);
setSetting("lightProvider", LIGHT_PROVIDER_DIMMER);
setSetting("chGPIO", 0, 5);
setSetting("chGPIO", 1, 12);
setSetting("chGPIO", 2, 13);
setSetting("chGPIO", 3, 14);
setSetting("chLogic", 0, 0);
setSetting("chLogic", 1, 0);
setSetting("chLogic", 2, 0);
setSetting("chLogic", 3, 0);
setSetting("relays", 1);
#elif defined(ARILUX_AL_LC11)
setSetting("board", 51);
setSetting("relayProvider", RELAY_PROVIDER_LIGHT);
setSetting("lightProvider", LIGHT_PROVIDER_DIMMER);
setSetting("chGPIO", 0, 5);
setSetting("chGPIO", 1, 4);
setSetting("chGPIO", 2, 14);
setSetting("chGPIO", 3, 13);
setSetting("chGPIO", 4, 12);
setSetting("chLogic", 0, 0);
setSetting("chLogic", 1, 0);
setSetting("chLogic", 2, 0);
setSetting("chLogic", 3, 0);
setSetting("chLogic", 4, 0);
setSetting("relays", 1);
#else
#error "UNSUPPORTED HARDWARE!"
// Allow users to define new settings without migration config
//#error "UNSUPPORTED HARDWARE!"
#endif


+ 44
- 12
code/espurna/mqtt.ino View File

@ -35,6 +35,9 @@ WiFiClientSecure _mqtt_client_secure;
bool _mqtt_enabled = MQTT_ENABLED;
bool _mqtt_use_json = false;
unsigned long _mqtt_reconnect_delay = MQTT_RECONNECT_DELAY_MIN;
unsigned char _mqtt_qos = MQTT_QOS;
bool _mqtt_retain = MQTT_RETAIN;
unsigned char _mqtt_keepalive = MQTT_KEEPALIVE;
String _mqtt_topic;
String _mqtt_setter;
String _mqtt_getter;
@ -42,6 +45,7 @@ bool _mqtt_forward;
char *_mqtt_user = 0;
char *_mqtt_pass = 0;
char *_mqtt_will;
char *_mqtt_clientid;
#if MQTT_SKIP_RETAINED
unsigned long _mqtt_connected_at = 0;
#endif
@ -86,10 +90,10 @@ String mqttSubtopic(char * topic) {
void mqttSendRaw(const char * topic, const char * message) {
if (_mqtt.connected()) {
#if MQTT_USE_ASYNC
unsigned int packetId = _mqtt.publish(topic, MQTT_QOS, MQTT_RETAIN, message);
unsigned int packetId = _mqtt.publish(topic, _mqtt_qos, _mqtt_retain, message);
DEBUG_MSG_P(PSTR("[MQTT] Sending %s => %s (PID %d)\n"), topic, message, packetId);
#else
_mqtt.publish(topic, message, MQTT_RETAIN);
_mqtt.publish(topic, message, _mqtt_retain);
DEBUG_MSG_P(PSTR("[MQTT] Sending %s => %s\n"), topic, message);
#endif
}
@ -172,10 +176,10 @@ void mqttSend(const char * topic, unsigned int index, const char * message) {
void mqttSubscribeRaw(const char * topic) {
if (_mqtt.connected() && (strlen(topic) > 0)) {
#if MQTT_USE_ASYNC
unsigned int packetId = _mqtt.subscribe(topic, MQTT_QOS);
unsigned int packetId = _mqtt.subscribe(topic, _mqtt_qos);
DEBUG_MSG_P(PSTR("[MQTT] Subscribing to %s (PID %d)\n"), topic, packetId);
#else
_mqtt.subscribe(topic, MQTT_QOS);
_mqtt.subscribe(topic, _mqtt_qos);
DEBUG_MSG_P(PSTR("[MQTT] Subscribing to %s\n"), topic);
#endif
}
@ -206,6 +210,8 @@ void mqttRegister(mqtt_callback_f callback) {
// Callbacks
// -----------------------------------------------------------------------------
#if WEB_SUPPORT
void _mqttWebSocketOnSend(JsonObject& root) {
root["mqttVisible"] = 1;
root["mqttStatus"] = mqttConnected();
@ -213,7 +219,11 @@ void _mqttWebSocketOnSend(JsonObject& root) {
root["mqttServer"] = getSetting("mqttServer", MQTT_SERVER);
root["mqttPort"] = getSetting("mqttPort", MQTT_PORT);
root["mqttUser"] = getSetting("mqttUser");
root["mqttClientID"] = getSetting("mqttClientID");
root["mqttPassword"] = getSetting("mqttPassword");
root["mqttKeep"] = _mqtt_keepalive;
root["mqttRetain"] = _mqtt_retain;
root["mqttQoS"] = _mqtt_qos;
#if ASYNC_TCP_SSL_ENABLED
root["mqttsslVisible"] = 1;
root["mqttUseSSL"] = getSetting("mqttUseSSL", 0).toInt() == 1;
@ -223,12 +233,22 @@ void _mqttWebSocketOnSend(JsonObject& root) {
root["mqttUseJson"] = getSetting("mqttUseJson", MQTT_USE_JSON).toInt() == 1;
}
void _mqttConfigure() {
if (getSetting("mqttClientID").length() == 0) delSetting("mqttClientID");
}
#endif
void _mqttCallback(unsigned int type, const char * topic, const char * payload) {
if (type == MQTT_CONNECT_EVENT) {
// Subscribe to internal action topics
mqttSubscribe(MQTT_TOPIC_ACTION);
// Send heartbeat messages
heartbeat();
}
if (type == MQTT_MESSAGE_EVENT) {
@ -375,18 +395,22 @@ void mqttConnect() {
if (_mqtt_user) free(_mqtt_user);
if (_mqtt_pass) free(_mqtt_pass);
if (_mqtt_will) free(_mqtt_will);
if (_mqtt_clientid) free(_mqtt_clientid);
_mqtt_user = strdup(getSetting("mqttUser", MQTT_USER).c_str());
_mqtt_pass = strdup(getSetting("mqttPassword", MQTT_PASS).c_str());
_mqtt_will = strdup((_mqtt_topic + MQTT_TOPIC_STATUS).c_str());
_mqtt_clientid = strdup(getSetting("mqttClientID", getIdentifier()).c_str());
DEBUG_MSG_P(PSTR("[MQTT] Connecting to broker at %s:%d\n"), host, port);
#if MQTT_USE_ASYNC
_mqtt.setServer(host, port);
_mqtt.setKeepAlive(MQTT_KEEPALIVE).setCleanSession(false);
_mqtt.setWill(_mqtt_will, MQTT_QOS, MQTT_RETAIN, "0");
_mqtt.setClientId(_mqtt_clientid);
_mqtt.setKeepAlive(_mqtt_keepalive);
_mqtt.setCleanSession(false);
_mqtt.setWill(_mqtt_will, _mqtt_qos, _mqtt_retain, "0");
if ((strlen(_mqtt_user) > 0) && (strlen(_mqtt_pass) > 0)) {
DEBUG_MSG_P(PSTR("[MQTT] Connecting as user %s\n"), _mqtt_user);
_mqtt.setCredentials(_mqtt_user, _mqtt_pass);
@ -408,9 +432,10 @@ void mqttConnect() {
#endif // ASYNC_TCP_SSL_ENABLED
DEBUG_MSG_P(PSTR("[MQTT] Client ID: %s\n"), _mqtt_clientid);
DEBUG_MSG_P(PSTR("[MQTT] QoS: %d\n"), _mqtt_qos);
DEBUG_MSG_P(PSTR("[MQTT] Retain flag: %d\n"), _mqtt_retain ? 1 : 0);
DEBUG_MSG_P(PSTR("[MQTT] Will topic: %s\n"), _mqtt_will);
DEBUG_MSG_P(PSTR("[MQTT] QoS: %d\n"), MQTT_QOS);
DEBUG_MSG_P(PSTR("[MQTT] Retain flag: %d\n"), MQTT_RETAIN);
_mqtt.connect();
@ -459,14 +484,15 @@ void mqttConnect() {
if ((strlen(_mqtt_user) > 0) && (strlen(_mqtt_pass) > 0)) {
DEBUG_MSG_P(PSTR("[MQTT] Connecting as user %s\n"), _mqtt_user);
response = _mqtt.connect(getIdentifier().c_str(), _mqtt_user, _mqtt_pass, _mqtt_will, MQTT_QOS, MQTT_RETAIN, "0");
response = _mqtt.connect(_mqtt_clientid, _mqtt_user, _mqtt_pass, _mqtt_will, _mqtt_qos, _mqtt_retain, "0");
} else {
response = _mqtt.connect(getIdentifier().c_str(), _mqtt_will, MQTT_QOS, MQTT_RETAIN, "0");
response = _mqtt.connect(_mqtt_clientid, _mqtt_will, _mqtt_qos, _mqtt_retain, "0");
}
DEBUG_MSG_P(PSTR("[MQTT] Client ID: %s\n"), _mqtt_clientid);
DEBUG_MSG_P(PSTR("[MQTT] QoS: %d\n"), _mqtt_qos);
DEBUG_MSG_P(PSTR("[MQTT] Retain flag: %d\n"), _mqtt_retain ? 1 : 0);
DEBUG_MSG_P(PSTR("[MQTT] Will topic: %s\n"), _mqtt_will);
DEBUG_MSG_P(PSTR("[MQTT] QoS: %d\n"), MQTT_QOS);
DEBUG_MSG_P(PSTR("[MQTT] Retain flag: %d\n"), MQTT_RETAIN);
}
@ -494,6 +520,11 @@ void mqttConfigure() {
_mqtt_getter = getSetting("mqttGetter", MQTT_USE_GETTER);
_mqtt_forward = !_mqtt_getter.equals(_mqtt_setter);
// MQTT options
_mqtt_qos = getSetting("mqttQoS", MQTT_QOS).toInt();
_mqtt_retain = getSetting("mqttRetain", MQTT_RETAIN).toInt() == 1;
_mqtt_keepalive = getSetting("mqttKeep", MQTT_KEEPALIVE).toInt();
// Enable
if (getSetting("mqttServer", MQTT_SERVER).length() == 0) {
mqttEnabled(false);
@ -574,6 +605,7 @@ void mqttSetup() {
#if WEB_SUPPORT
wsOnSendRegister(_mqttWebSocketOnSend);
wsOnAfterParseRegister(_mqttConfigure);
#endif
}


+ 68
- 55
code/espurna/relay.ino View File

@ -276,16 +276,21 @@ unsigned char relayParsePayload(const char * payload) {
// Payload could be "OFF", "ON", "TOGGLE"
// or its number equivalents: 0, 1 or 2
if (payload[0] == '0') return 0;
if (payload[0] == '1') return 1;
if (payload[0] == '2') return 2;
// trim payload
char * p = ltrim((char *)payload);
// to lower
for (unsigned char i=0; i<strlen(p); i++) {
unsigned int l = strlen(p);
if (l>6) l=6;
for (unsigned char i=0; i<l; i++) {
p[i] = tolower(p[i]);
}
unsigned int value;
unsigned int value = 0xFF;
if (strcmp(p, "off") == 0) {
value = 0;
} else if (strcmp(p, "on") == 0) {
@ -294,12 +299,9 @@ unsigned char relayParsePayload(const char * payload) {
value = 2;
} else if (strcmp(p, "query") == 0) {
value = 3;
} else {
value = p[0] - '0';
}
if (0 <= value && value <=3) return value;
return 0xFF;
return value;
}
@ -335,30 +337,34 @@ void _relayBoot() {
DEBUG_MSG_P(PSTR("[RELAY] Retrieving mask: %d\n"), mask);
// Walk the relays
bool status = false;
for (unsigned int i=0; i<_relays.size(); i++) {
_relays[i].current_status = false;
_relays[i].target_status = false;
unsigned char boot_mode = getSetting("relayBoot", i, RELAY_BOOT_MODE).toInt();
DEBUG_MSG_P(PSTR("[RELAY] Relay #%d boot mode %d\n"), i, boot_mode);
switch (boot_mode) {
case RELAY_BOOT_OFF:
relayStatus(i, false);
break;
case RELAY_BOOT_ON:
relayStatus(i, true);
break;
case RELAY_BOOT_SAME:
relayStatus(i, (mask & bit) == bit);
status = ((mask & bit) == bit);
break;
case RELAY_BOOT_TOOGLE:
relayStatus(i, (mask & bit) != bit);
case RELAY_BOOT_TOGGLE:
status = ((mask & bit) != bit);
mask ^= bit;
trigger_save = true;
break;
case RELAY_BOOT_ON:
status = true;
break;
case RELAY_BOOT_OFF:
default:
status = false;
break;
}
_relays[i].current_status = !status;
_relays[i].target_status = status;
_relays[i].change_time = millis();
bit <<= 1;
}
// Save if there is any relay in the RELAY_BOOT_TOOGLE mode
// Save if there is any relay in the RELAY_BOOT_TOGGLE mode
if (trigger_save) {
EEPROM.write(EEPROM_RELAY_STATUS, mask);
EEPROM.commit();
@ -368,6 +374,15 @@ void _relayBoot() {
}
void _relayConfigure() {
for (unsigned int i=0; i<_relays.size(); i++) {
pinMode(_relays[i].pin, OUTPUT);
if (_relays[i].type == RELAY_TYPE_LATCHED) pinMode(_relays[i].reset_pin, OUTPUT);
_relays[i].pulse = getSetting("relayPulse", i, RELAY_PULSE_MODE).toInt();
_relays[i].pulse_ms = 1000 * getSetting("relayTime", i, RELAY_PULSE_MODE).toFloat();
}
}
//------------------------------------------------------------------------------
// WEBSOCKETS
//------------------------------------------------------------------------------
@ -448,15 +463,6 @@ void _relayWebSocketOnAction(const char * action, JsonObject& data) {
}
void _relayConfigure() {
for (unsigned int i=0; i<_relays.size(); i++) {
pinMode(_relays[i].pin, OUTPUT);
if (_relays[i].type == RELAY_TYPE_LATCHED) pinMode(_relays[i].reset_pin, OUTPUT);
_relays[i].pulse = getSetting("relayPulse", i, RELAY_PULSE_MODE).toInt();
_relays[i].pulse_ms = 1000 * getSetting("relayTime", i, RELAY_PULSE_MODE).toFloat();
}
}
void relaySetupWS() {
wsOnSendRegister(_relayWebSocketOnStart);
wsOnActionRegister(_relayWebSocketOnAction);
@ -579,43 +585,47 @@ void relayMQTTCallback(unsigned int type, const char * topic, const char * paylo
if (type == MQTT_MESSAGE_EVENT) {
// Get value
unsigned char value = relayParsePayload(payload);
if (value == 0xFF) {
DEBUG_MSG_P(PSTR("[RELAY] Wrong payload (%s)\n"), payload);
// Check relay topic
String t = mqttSubtopic((char *) topic);
if (t.startsWith(MQTT_TOPIC_RELAY)) {
// Get value
unsigned char value = relayParsePayload(payload);
if (value == 0xFF) return;
// Get relay ID
unsigned int id = t.substring(strlen(MQTT_TOPIC_RELAY)+1).toInt();
if (id >= relayCount()) {
DEBUG_MSG_P(PSTR("[RELAY] Wrong relayID (%d)\n"), id);
} else {
relayStatusWrap(id, value, false);
}
return;
}
// Check group topics
bool found = false;
for (unsigned int i=0; i < _relays.size(); i++) {
String t = getSetting("mqttGroup", i, "");
if (t.equals(topic)) {
unsigned char local_value = value;
if (getSetting("mqttGroupInv", i, 0).toInt() == 1) {
if (local_value < 2) local_value = 1 - local_value;
}
found = true;
DEBUG_MSG_P(PSTR("[RELAY] Matched group topic for relayID %d\n"), i);
relayStatusWrap(i, local_value, true);
}
}
// If found as group topic quit
if (found) return;
if ((t.length() > 0) && t.equals(topic)) {
// Else, try to match topic
String t = mqttSubtopic((char *) topic);
if (!t.startsWith(MQTT_TOPIC_RELAY)) return;
unsigned char value = relayParsePayload(payload);
if (value == 0xFF) return;
// Get relay ID
unsigned int id = t.substring(strlen(MQTT_TOPIC_RELAY)+1).toInt();
if (id >= relayCount()) {
DEBUG_MSG_P(PSTR("[RELAY] Wrong relayID (%d)\n"), id);
return;
}
if (value < 2) {
if (getSetting("mqttGroupInv", i, 0).toInt() == 1) {
value = 1 - value;
}
}
DEBUG_MSG_P(PSTR("[RELAY] Matched group topic for relayID %d\n"), i);
relayStatusWrap(i, value, true);
relayStatusWrap(id, value, false);
}
}
}
@ -737,6 +747,9 @@ void relayLoop(void) {
relayInfluxDB(id);
#endif
// Flag relay-based LEDs to update status
ledUpdate(true);
_relays[id].report = false;
_relays[id].group_report = false;


+ 5
- 2
code/espurna/rfbridge.ino View File

@ -252,11 +252,14 @@ void _rfbReceive() {
//DEBUG_MSG_P(PSTR("[RFBRIDGE] Received 0x%02X\n"), c);
if (receiving) {
if (c == RF_CODE_STOP) {
if (c == RF_CODE_STOP && (_uartpos == 1 || _uartpos == 10)) {
_rfbDecode();
receiving = false;
} else {
} else if (_uartpos < 10) {
_uartbuf[_uartpos++] = c;
} else {
// wrong message, should have received a RF_CODE_STOP
receiving = false;
}
} else if (c == RF_CODE_START) {
_uartpos = 0;


+ 9
- 0
code/espurna/sensor.ino View File

@ -210,6 +210,15 @@ void _sensorInit() {
}
#endif
#if BH1750_SUPPORT
{
BH1750Sensor * sensor = new BH1750Sensor();
sensor->setAddress(BH1750_ADDRESS);
sensor->setMode(BH1750_MODE);
_sensors.push_back(sensor);
}
#endif
#if BMX280_SUPPORT
{
BMX280Sensor * sensor = new BMX280Sensor();


+ 155
- 0
code/espurna/sensors/BH1750Sensor.h View File

@ -0,0 +1,155 @@
// -----------------------------------------------------------------------------
// BH1750 Liminosity sensor over I2C
// Copyright (C) 2017 by Xose Pérez <xose dot perez at gmail dot com>
// -----------------------------------------------------------------------------
#if SENSOR_SUPPORT && BH1750_SUPPORT
#pragma once
#include "Arduino.h"
#include "I2CSensor.h"
#if I2C_USE_BRZO
#include <brzo_i2c.h>
#else
#include <Wire.h>
#endif
#define BH1750_CONTINUOUS_HIGH_RES_MODE 0x10 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
#define BH1750_CONTINUOUS_HIGH_RES_MODE_2 0x11 // Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
#define BH1750_CONTINUOUS_LOW_RES_MODE 0x13 // Start measurement at 4lx resolution. Measurement time is approx 16ms.
#define BH1750_ONE_TIME_HIGH_RES_MODE 0x20 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_HIGH_RES_MODE_2 0x21 // Start measurement at 0.5lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
#define BH1750_ONE_TIME_LOW_RES_MODE 0x23 // Start measurement at 1lx resolution. Measurement time is approx 120ms.
// Device is automatically set to Power Down after measurement.
class BH1750Sensor : public I2CSensor {
public:
// ---------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------
BH1750Sensor(): I2CSensor() {
_sensor_id = SENSOR_BH1750_ID;
_count = 1;
}
// ---------------------------------------------------------------------
void setMode(unsigned char mode) {
if (_mode == mode) return;
_mode = mode;
_dirty = true;
}
// ---------------------------------------------------------------------
unsigned char getMode() {
return _mode;
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
// Initialization method, must be idempotent
void begin() {
if (!_dirty) return;
_dirty = false;
// I2C auto-discover
unsigned char addresses[] = {0x23, 0x5C};
_address = _begin_i2c(_address, sizeof(addresses), addresses);
if (_address == 0) return;
// Configure
_configure();
delay(10);
}
// Descriptive name of the sensor
String description() {
char buffer[25];
snprintf(buffer, sizeof(buffer), "BH1750 @ I2C (0x%02X)", _address);
return String(buffer);
}
// Type for slot # index
unsigned char type(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return MAGNITUDE_LUX;
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
if (index == 0) return _read();
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}
protected:
void _configure() {
#if I2C_USE_BRZO
uint8_t buffer[1] = {_mode};
brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY);
brzo_i2c_write(buffer, 1, false);
brzo_i2c_end_transaction();
#else
Wire.beginTransmission(_address);
Wire.write(_mode);
Wire.endTransmission();
#endif
}
double _read() {
double level;
uint8_t buffer[2];
// For one-shot modes reconfigure sensor & wait for conversion
if (_mode & 0x20) {
_configure();
// According to datasheet
// conversion time is ~16ms for low resolution
// and ~120 for high resolution
// but more time is needed
unsigned long wait = (_mode & 0x02) ? 24 : 180;
unsigned long start = millis();
while (millis() - start < wait) delay(1);
}
#if I2C_USE_BRZO
brzo_i2c_start_transaction(_address, I2C_SCL_FREQUENCY);
brzo_i2c_read(buffer, 2, false);
brzo_i2c_end_transaction();
#else
Wire.beginTransmission(_address);
Wire.requestFrom(_address, (unsigned char) 2);
buffer[0] = Wire.read();
buffer[1] = Wire.read();
Wire.endTransmission();
#endif
level = buffer[0] * 256 + buffer[1];
return level / 1.2;
}
unsigned char _mode;
};
#endif // SENSOR_SUPPORT && SI7021_SUPPORT

+ 9
- 4
code/espurna/sensors/DHTSensor.h View File

@ -137,23 +137,28 @@ class DHTSensor : public BaseSensor {
pinMode(_gpio, OUTPUT);
noInterrupts();
digitalWrite(_gpio, LOW);
delayMicroseconds(500);
if (_type == DHT_CHIP_DHT11) {
delay(20);
} else {
delayMicroseconds(500);
}
digitalWrite(_gpio, HIGH);
delayMicroseconds(40);
pinMode(_gpio, INPUT_PULLUP);
delayMicroseconds(10);
// No errors, read the 40 data bits
for( int k = 0; k < 41; k++ ) {
// Starts new data transmission with >50us low signal
low = _signal(56, LOW);
low = _signal(100, LOW);
if (low == 0) {
_error = SENSOR_ERROR_TIMEOUT;
return;
}
// Check to see if after >70us rx data is a 0 or a 1
high = _signal(75, HIGH);
high = _signal(100, HIGH);
if (high == 0) {
_error = SENSOR_ERROR_TIMEOUT;
return;
@ -219,7 +224,7 @@ class DHTSensor : public BaseSensor {
unsigned char _gpio;
unsigned char _previous = 0xFF;
unsigned char _type;
unsigned char _type = DHT_CHIP_DHT22;
unsigned long _last_ok = 0;
unsigned char _errors = 0;


+ 51
- 4
code/espurna/sensors/EmonADC121Sensor.h View File

@ -8,7 +8,7 @@
#pragma once
#include "Arduino.h"
#include "EmonAnalogSensor.h"
#include "EmonSensor.h"
#if I2C_USE_BRZO
#include <brzo_i2c.h>
@ -29,7 +29,7 @@
#define ADC121_RESOLUTION 12
#define ADC121_CHANNELS 1
class EmonADC121Sensor : public EmonAnalogSensor {
class EmonADC121Sensor : public EmonSensor {
public:
@ -37,7 +37,7 @@ class EmonADC121Sensor : public EmonAnalogSensor {
// Public
// ---------------------------------------------------------------------
EmonADC121Sensor(): EmonAnalogSensor() {
EmonADC121Sensor(): EmonSensor() {
_channels = ADC121_CHANNELS;
_sensor_id = SENSOR_EMON_ADC121_ID;
init();
@ -102,7 +102,54 @@ class EmonADC121Sensor : public EmonAnalogSensor {
return;
}
EmonAnalogSensor:pre();
_current[0] = read(0);
#if EMON_REPORT_ENERGY
static unsigned long last = 0;
if (last > 0) {
_energy[0] += (_current[0] * _voltage * (millis() - last) / 1000);
}
last = millis();
#endif
}
// Type for slot # index
unsigned char type(unsigned char index) {
_error = SENSOR_ERROR_OK;
unsigned char i=0;
#if EMON_REPORT_CURRENT
if (index == i++) return MAGNITUDE_CURRENT;
#endif
#if EMON_REPORT_POWER
if (index == i++) return MAGNITUDE_POWER_APPARENT;
#endif
#if EMON_REPORT_ENERGY
if (index == i) return MAGNITUDE_ENERGY;
#endif
_error = SENSOR_ERROR_OUT_OF_RANGE;
return MAGNITUDE_NONE;
}
// Current value for slot # index
double value(unsigned char index) {
_error = SENSOR_ERROR_OK;
unsigned char channel = index / _magnitudes;
unsigned char i=0;
#if EMON_REPORT_CURRENT
if (index == i++) return _current[channel];
#endif
#if EMON_REPORT_POWER
if (index == i++) return _current[channel] * _voltage;
#endif
#if EMON_REPORT_ENERGY
if (index == i) return _energy[channel];
#endif
_error = SENSOR_ERROR_OUT_OF_RANGE;
return 0;
}


+ 1
- 0
code/espurna/sensors/SHT3XI2CSensor.h View File

@ -25,6 +25,7 @@ class SHT3XI2CSensor : public I2CSensor {
SHT3XI2CSensor(): I2CSensor() {
_sensor_id = SENSOR_SHT3X_I2C_ID;
_count = 2;
}
// ---------------------------------------------------------------------


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


+ 44
- 0
code/extra_scripts.py View File

@ -0,0 +1,44 @@
#!/usr/bin/env python
Import("env")
# ------------------------------------------------------------------------------
# Utils
# ------------------------------------------------------------------------------
class Color:
BLACK = '\x1b[1;30m'
RED = '\x1b[1;31m'
GREEN = '\x1b[1;32m'
YELLOW = '\x1b[1;33m'
BLUE = '\x1b[1;34m'
MAGENTA = '\x1b[1;35m'
CYAN = '\x1b[1;36m'
WHITE = '\x1b[1;37m'
LIGHT_GREY = '\x1b[0;30m'
LIGHT_RED = '\x1b[0;31m'
LIGHT_GREEN = '\x1b[0;32m'
LIGHT_YELLOW = '\x1b[0;33m'
LIGHT_BLUE = '\x1b[0;34m'
LIGHT_MAGENTA = '\x1b[0;35m'
LIGHT_CYAN = '\x1b[0;36m'
LIGHT_WHITE = '\x1b[0;37m'
def clr(color, text):
return color + str(text) + '\x1b[0m'
# ------------------------------------------------------------------------------
# Callbacks
# ------------------------------------------------------------------------------
def check_size(source, target, env):
size = target[0].get_size()
print clr(Color.LIGHT_BLUE, "Binary size: %s bytes" % size)
if size > 512000:
print clr(Color.LIGHT_RED, "File too large for OTA!")
Exit(1)
# ------------------------------------------------------------------------------
# Hooks
# ------------------------------------------------------------------------------
env.AddPostAction("$BUILD_DIR/${PROGNAME}.bin", check_size)

+ 2
- 2
code/html/checkboxes.css View File

@ -1,10 +1,10 @@
.iPhoneCheckContainer {
-webkit-transform:translate3d(0,0,0);
position: relative;
height: 27px;
height: 30px;
cursor: pointer;
overflow: hidden;
margin-bottom: 10px;
margin: 5px 0 10px 0;
}
.iPhoneCheckContainer input {


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

@ -109,12 +109,14 @@ div.hint {
.break {
margin-top: 5px;
}
#networks .pure-g {
#networks .pure-g,
#schedules .pure-g {
padding: 10px 0 10px 0;
margin-bottom: 5px;
border-bottom: 2px dashed #e5e5e5;
}
#networks .more {
#networks .more,
#schedules .more {
display: none;
}
legend.module,


+ 4
- 4
code/html/custom.js View File

@ -34,7 +34,7 @@ function sensorName(id) {
"DHT", "Dallas", "Emon Analog", "Emon ADC121", "Emon ADS1X15",
"HLW8012", "V9261F", "ECH1560", "Analog", "Digital",
"Events", "PMSX003", "BMX280", "MHZ19", "SI7021",
"SHT3X I2C"
"SHT3X I2C", "BH1750"
];
if (1 <= id && id <= names.length) return names[id-1];
return null;
@ -44,9 +44,9 @@ function magnitudeType(type) {
var types = [
"Temperature", "Humidity", "Pressure",
"Current", "Voltage", "Active Power", "Apparent Power",
"Reactive Power", "Energy", "Energy (delta)", "Power Factor",
"Reactive Power", "Power Factor", "Energy", "Energy (delta)",
"Analog", "Digital", "Events",
"PM1.0", "PM2.5", "PM10", "CO2"
"PM1.0", "PM2.5", "PM10", "CO2", "Lux"
];
if (1 <= type && type <= types.length) return types[type-1];
return null;
@ -55,7 +55,7 @@ function magnitudeType(type) {
function magnitudeError(error) {
var errors = [
"OK", "Out of Range", "Warming Up", "Timeout", "Wrong ID",
"CRC Error", "I2C Error"
"CRC Error", "I2C Error", "GPIO Error"
];
if (0 <= error && error < errors.length) return errors[error];
return "Error " + error;


+ 46
- 7
code/html/index.html View File

@ -272,6 +272,8 @@
<option value="0">MQTT managed</option>
<option value="4">Find me</option>
<option value="5">Mixed</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>
@ -280,7 +282,8 @@
When in "WiFi status" it will blink at 1Hz when trying to connecting. If successfully connected if will briefly lit every 5 seconds if in STA mode or every second if in AP mode.<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 "Mixed" mode it will follow the WiFi status but will stay mostly on when relays are OFF, and mostly OFF when any of them is ON.
When in "Mixed" mode 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>
@ -400,6 +403,13 @@
<div class="pure-u-1 pure-u-lg-3-4 hint">If enabled color changes will be smoothed.</div>
</div>
<div class="pure-g">
<div class="pure-u-1 pure-u-lg-1-4"><label>MQTT group</label></div>
<div class="pure-u-1 pure-u-lg-3-4"><input name="mqttGroupColor" class="pure-u-1" tabindex="13" action="reconnect" /></div>
<div class="pure-u-0 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">Sync color between different lights.</div>
</div>
</fieldset>
</div>
</div>
@ -581,14 +591,43 @@
<input class="pure-u-1 pure-u-lg-1-4" name="mqttPassword" type="password" size="20" tabindex="24" placeholder="Leave blank if no pass" autocomplete="false" />
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">MQTT Client ID</label>
<input class="pure-u-1 pure-u-lg-1-4" name="mqttClientID" type="text" size="20" tabindex="25" />
<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">
If left empty the firmware will generate a client ID based on the serial number of the chip.
</div>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">MQTT QoS</label>
<select class="pure-u-1 pure-u-lg-1-4" name="mqttQoS" tabindex="26">
<option value="0">0: At most once</option>
<option value="1">1: At least once</option>
<option value="2">2: Exactly once</option>
</select>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">MQTT Retain</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="mqttRetain" tabindex="27" /></div>
</div>
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">MQTT Keep Alive</label>
<input class="pure-u-1 pure-u-lg-1-4" type="number" name="mqttKeep" min="10" max="60" tabindex="28" />
</div>
<div class="pure-g module module-mqttssl">
<div class="pure-u-1 pure-u-lg-1-4"><label>Use secure connection (SSL)</label></div>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="mqttUseSSL" tabindex="25" /></div>
<label class="pure-u-1 pure-u-lg-1-4">Use secure connection (SSL)</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="mqttUseSSL" tabindex="29" /></div>
</div>
<div class="pure-g module module-mqttssl">
<label class="pure-u-1 pure-u-lg-1-4">SSL Fingerprint</label>
<input class="pure-u-1 pure-u-lg-3-4" name="mqttFP" type="text" size="59" tabindex="26" />
<input class="pure-u-1 pure-u-lg-3-4" name="mqttFP" type="text" size="59" tabindex="30" />
<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 />
@ -600,7 +639,7 @@
<div class="pure-g">
<label class="pure-u-1 pure-u-lg-1-4">MQTT Root Topic</label>
<input class="pure-u-1 pure-u-lg-3-4" name="mqttTopic" type="text" size="20" tabindex="27" />
<input class="pure-u-1 pure-u-lg-3-4" name="mqttTopic" type="text" size="20" tabindex="31" />
<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 root topic for this device. A trailing slash will be added if not preset. The {identifier} placeholder will be replaced by the device hostname.<br />
@ -616,7 +655,7 @@
<div class="pure-g">
<div class="pure-u-1 pure-u-lg-1-4"><label>Use JSON payload</label></div>
<div class="pure-u-1 pure-u-lg-3-4"><input type="checkbox" name="mqttUseJson" tabindex="26" /></div>
<div class="pure-u-1 pure-u-lg-3-4"><input type="checkbox" name="mqttUseJson" tabindex="32" /></div>
<div class="pure-u-1 pure-u-lg-1-4"></div>
<div class="pure-u-1 pure-u-lg-3-4 hint">
All messages (except the device status) will be included in a JSON payload along with the timestamp and hostname
@ -1012,7 +1051,7 @@
<option value="0">Always OFF</option>
<option value="1">Always ON</option>
<option value="2">Same as before</option>
<option value="3">Toogle before</option>
<option value="3">Toggle before</option>
</select>
</div>
<div class="pure-g">


+ 250
- 0
code/memanalyzer.py View File

@ -0,0 +1,250 @@
#!/usr/bin/env python
#-------------------------------------------------------------------------------
# ESPurna module memory analyser
# xose.perez@gmail.com
#
# Based on:
# https://github.com/letscontrolit/ESPEasy/blob/mega/memanalyzer.py
# by psy0rz <edwin@datux.nl>
# https://raw.githubusercontent.com/SmingHub/Sming/develop/tools/memanalyzer.py
# by Slavey Karadzhov <slav@attachix.com>
# https://github.com/Sermus/ESP8266_memory_analyzer
# by Andrey Filimonov
#
#-------------------------------------------------------------------------------
from collections import OrderedDict
from sortedcontainers import SortedDict
import shlex
import commands
import subprocess
import sys
import os
import re
import argparse
#-------------------------------------------------------------------------------
TOTAL_IRAM = 32786;
TOTAL_DRAM = 81920;
env="esp8266-4m-ota"
objdump_binary = "xtensa-lx106-elf-objdump"
sections = OrderedDict([
("data", "Initialized Data (RAM)"),
("rodata", "ReadOnly Data (RAM)"),
("bss", "Uninitialized Data (RAM)"),
("text", "Cached Code (IRAM)"),
("irom0_text", "Uncached Code (SPI)")
])
description = "ESPurna Memory Analyzer v0.1"
#-------------------------------------------------------------------------------
def file_size(file):
try:
return os.stat(file).st_size
except:
return 0
def analyse_memory(elf_file):
command = "%s -t '%s' " % (objdump_binary, elf_file)
response = subprocess.check_output(shlex.split(command))
if isinstance(response, bytes):
response = response.decode('utf-8')
lines = response.split('\n')
# print("{0: >10}|{1: >30}|{2: >12}|{3: >12}|{4: >8}".format("Section", "Description", "Start (hex)", "End (hex)", "Used space"));
# print("------------------------------------------------------------------------------");
ret={}
usedRAM = 0
usedIRAM = 0
i = 0
for (id, descr) in list(sections.items()):
sectionStartToken = " _%s_start" % id
sectionEndToken = " _%s_end" % id
sectionStart = -1
sectionEnd = -1
for line in lines:
if sectionStartToken in line:
data = line.split(' ')
sectionStart = int(data[0], 16)
if sectionEndToken in line:
data = line.split(' ')
sectionEnd = int(data[0], 16)
if sectionStart != -1 and sectionEnd != -1:
break
sectionLength = sectionEnd - sectionStart
# if i < 3:
# usedRAM += sectionLength
# if i == 3:
# usedIRAM = TOTAL_IRAM - sectionLength;
ret[id]=sectionLength
# print("{0: >10}|{1: >30}|{2:12X}|{3:12X}|{4:8}".format(id, descr, sectionStart, sectionEnd, sectionLength))
# i += 1
# print("Total Used RAM : %d" % usedRAM)
# print("Free RAM : %d" % (TOTAL_DRAM - usedRAM))
# print("Free IRam : %d" % usedIRAM)
return(ret)
def run(env, modules):
flags = ""
for item in modules.items():
flags += "-D%s_SUPPORT=%d " % item
command = "export ESPURNA_BOARD=\"WEMOS_D1_MINI_RELAYSHIELD\"; export ESPURNA_FLAGS=\"%s\"; platformio run --silent --environment %s" % (flags, env)
subprocess.check_call(command, shell=True)
def modules_get():
modules = SortedDict()
for line in open("espurna/config/arduino.h"):
m = re.search(r'(\w*)_SUPPORT', line)
if m:
modules[m.group(1)] = 0
del modules['LLMNR']
del modules['NETBIOS']
return modules
try:
# Parse command line options
parser = argparse.ArgumentParser(description=description)
parser.add_argument("modules", nargs='*', help="Modules to test (use ALL to test them all)")
parser.add_argument("-c", "--core", help="use core as base configuration instead of default", default=0, action='count')
parser.add_argument("-l", "--list", help="list available modules", default=0, action='count')
args = parser.parse_args()
# Hello
print
print description
print
# Check xtensa-lx106-elf-objdump is in the path
status, result = commands.getstatusoutput(objdump_binary)
if status != 512:
print "xtensa-lx106-elf-objdump not found, please check it is in your PATH"
sys.exit(1)
# Load list of all modules
available_modules = modules_get()
if args.list > 0:
print "List of available modules:\n"
for key, value in available_modules.items():
print "* " + key
print
sys.exit(0)
# Which modules to test?
test_modules = []
if len(args.modules) > 0:
if "ALL" in args.modules:
test_modules = available_modules.keys()
else:
test_modules = args.modules
# Check test modules exist
for module in test_modules:
if module not in available_modules:
print "Module %s not found" % module
sys.exit(2)
# Define base configuration
if args.core == 0:
modules = SortedDict()
for m in test_modules:
modules[m] = 0
else:
modules = available_modules
# Show init message
if len(test_modules) > 0:
print "Analyzing module(s) %s on top of %s configuration\n" % (", ".join(test_modules), "CORE" if args.core > 0 else "DEFAULT")
else:
print "Analyzing %s configuration\n" % ("CORE" if args.core > 0 else "DEFAULT")
output_format="{:<20}|{:<11}|{:<11}|{:<11}|{:<11}|{:<11}|{:<12}"
print(output_format.format(
"Module",
"Cache IRAM",
"Init RAM",
"R.O. RAM",
"Uninit RAM",
"Flash ROM",
"Binary size"
))
# Build the core without modules to get base memory usage
run(env, modules)
base = analyse_memory(".pioenvs/%s/firmware.elf" % env)
base['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
print(output_format.format(
"CORE" if args.core == 1 else "DEFAULT",
base['text'],
base['data'],
base['rodata'],
base['bss'],
base['irom0_text'],
base['size'],
))
# Test each module
results = {}
for module in test_modules:
modules[module] = 1
run(env, modules)
results[module]=analyse_memory(".pioenvs/%s/firmware.elf" % env)
results[module]['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
modules[module] = 0
print(output_format.format(
module,
results[module]['text'] - base['text'],
results[module]['data'] - base['data'],
results[module]['rodata'] - base['rodata'],
results[module]['bss'] - base['bss'],
results[module]['irom0_text'] - base['irom0_text'],
results[module]['size'] - base['size'],
))
# Test all modules
if len(test_modules) > 0:
for module in test_modules:
modules[module] = 1
run(env, modules)
total = analyse_memory(".pioenvs/%s/firmware.elf" % env)
total['size'] = file_size(".pioenvs/%s/firmware.bin" % env)
if len(test_modules) > 1:
print(output_format.format(
"ALL MODULES",
total['text'] - base['text'],
total['data'] - base['data'],
total['rodata'] - base['rodata'],
total['bss'] - base['bss'],
total['irom0_text'] - base['irom0_text'],
total['size'] - base['size'],
))
print(output_format.format(
"TOTAL",
total['text'],
total['data'],
total['rodata'],
total['bss'],
total['irom0_text'],
total['size'],
))
except:
raise
subprocess.check_call("export ESPURNA_BOARD=\"\"; export ESPURNA_FLAGS=\"\"", shell=True)
print("\n")

+ 210
- 0
code/ota.py View File

@ -0,0 +1,210 @@
#!/usr/bin/env python
#-------------------------------------------------------------------------------
# ESPurna OTA manager
# xose.perez@gmail.com
#
# Requires PlatformIO Core
#-------------------------------------------------------------------------------
import sys
import re
import logging
import socket
import argparse
import subprocess
from time import sleep
from zeroconf import ServiceBrowser, ServiceStateChange, Zeroconf
#-------------------------------------------------------------------------------
devices = []
description = "ESPurna OTA Manager v0.1"
#-------------------------------------------------------------------------------
def on_service_state_change(zeroconf, service_type, name, state_change):
'''
Callback that adds discovered devices to "devices" list
'''
if state_change is ServiceStateChange.Added:
info = zeroconf.get_service_info(service_type, name)
if info:
hostname = info.server.split(".")[0]
device = {
'hostname': hostname.upper(),
'ip': socket.inet_ntoa(info.address)
}
device['app'] = info.properties.get('app_name', '')
device['version'] = info.properties.get('app_version', '')
device['device'] = info.properties.get('target_board', '')
device['mem_size'] = info.properties.get('mem_size', '')
device['sdk_size'] = info.properties.get('sdk_size', '')
devices.append(device)
def list():
'''
Shows the list of discovered devices
'''
output_format="{:>3} {:<25}{:<25}{:<15}{:<15}{:<30}{:<10}{:<10}"
print(output_format.format(
"#",
"HOSTNAME",
"IP",
"APP",
"VERSION",
"DEVICE",
"MEM_SIZE",
"SDK_SIZE",
))
print "-" * 135
index = 0
for device in devices:
index = index + 1
print(output_format.format(
index,
device.get('hostname', ''),
device.get('ip', ''),
device.get('app', ''),
device.get('version', ''),
device.get('device', ''),
device.get('mem_size', ''),
device.get('sdk_size', ''),
))
print
def get_boards():
'''
Grabs board types fro hardware.h file
'''
boards = []
for line in open("espurna/config/hardware.h"):
m = re.search(r'defined\((\w*)\)', line)
if m:
boards.append(m.group(1))
return sorted(boards)
def flash():
'''
Grabs info from the user about what device to flash
'''
# Choose the board
try:
index = int(input("Choose the board you want to flash (empty if none of these): "))
except:
index = 0
if index < 0 or len(devices) < index:
print "Board number must be between 1 and %s\n" % str(len(devices))
return None
board = {'board': '', 'ip': '', 'size': 0 , 'auth': '', 'flags': ''}
if index > 0:
device = devices[index-1]
board['board'] = device.get('device', '')
board['ip'] = device.get('ip', '')
board['size'] = int(device.get('mem_size', 0) if device.get('mem_size', 0) == device.get('sdk_size', 0) else 0) / 1024
# Choose board type if none before
if len(board['board']) == 0:
print
count = 1
boards = get_boards()
for name in boards:
print "%3d\t%s" % (count, name)
count = count + 1
print
try:
index = int(input("Choose the board type you want to flash: "))
except:
index = 0
if index < 1 or len(boards) < index:
print "Board number must be between 1 and %s\n" % str(len(boards))
return None
board['board'] = boards[index-1]
# Choose board size of none before
if board['size'] == 0:
try:
board['size'] = int(input("Board memory size (1 for 1M, 4 for 4M): "))
except:
print "Wrong memory size"
return None
# Choose IP of none before
if len(board['ip']) == 0:
try:
board['ip'] = raw_input("IP of the device to flash (empty for 192.168.4.1): ") or "192.168.4.1"
except:
print "Wrong IP"
return None
board['auth'] = raw_input("Authorization key of the device to flash: ")
board['flags'] = raw_input("Extra flags for the build: ")
return board
def run(device, env):
command = "export ESPURNA_IP=\"%s\"; export ESPURNA_BOARD=\"%s\"; export ESPURNA_AUTH=\"%s\"; export ESPURNA_FLAGS=\"%s\"; platformio run --silent --environment %s -t upload"
command = command % (device['ip'], device['board'], device['auth'], device['flags'], env)
subprocess.check_call(command, shell=True)
#-------------------------------------------------------------------------------
if __name__ == '__main__':
# Parse command line options
parser = argparse.ArgumentParser(description=description)
#parser.add_argument("-v", "--verbose", help="show verbose output", default=0, action='count')
parser.add_argument("-f", "--flash", help="flash device", default=0, action='count')
parser.add_argument("-s", "--sort", help="sort devices list by field", default='hostname')
args = parser.parse_args()
print
print description
print
# Enable logging if verbose
#logging.basicConfig(level=logging.DEBUG)
#logging.getLogger('zeroconf').setLevel(logging.DEBUG)
# Look for sevices
zeroconf = Zeroconf()
browser = ServiceBrowser(zeroconf, "_arduino._tcp.local.", handlers=[on_service_state_change])
sleep(1)
zeroconf.close()
# Sort list
field = args.sort.lower()
if field not in devices[0]:
print "Unknown field '%s'\n" % field
sys.exit(1)
devices = sorted(devices, key=lambda device: device.get(field, ''))
# List devices
list()
# Flash device
if args.flash > 0:
device = flash()
if device:
env = "esp8266-%sm-ota" % device['size']
# Summary
print
print "ESPURNA_IP = %s" % device['ip']
print "ESPURNA_BOARD = %s" % device['board']
print "ESPURNA_AUTH = %s" % device['auth']
print "ESPURNA_FLAGS = %s" % device['flags']
print "ESPURNA_ENV = %s" % env
response = raw_input("\nAre these values right [y/N]: ")
print
if response == "y":
run(device, env)

+ 0
- 207
code/ota_flash.sh View File

@ -1,207 +0,0 @@
#!/bin/bash
ip=
board=
auth=
flags=
export boards=()
ips=""
exists() {
command -v "$1" >/dev/null 2>&1
}
echo_pad() {
string=$1
pad=$2
printf '%s' "$string"
printf '%*s' $(( $pad - ${#string} ))
}
useAvahi() {
echo_pad "#" 4
echo_pad "HOSTNAME" 25
echo_pad "IP" 25
echo_pad "APP" 15
echo_pad "VERSION" 15
echo_pad "DEVICE" 30
echo_pad "MEM_SIZE" 10
echo_pad "SDK_SIZE" 10
echo
printf -v line '%*s\n' 134
echo ${line// /-}
counter=0
ip_file="/tmp/espurna.flash.ips"
board_file="/tmp/espurna.flash.boards"
count_file="/tmp/espurna.flash.count"
echo -n "" > $ip_file
echo -n "" > $board_file
echo -n "$counter" > $count_file
avahi-browse -t -r -p "_arduino._tcp" 2>/dev/null | grep ^= | sort -t ';' -k 3 | while read line; do
(( counter++ ))
echo "$counter" > $count_file
hostname=`echo $line | cut -d ';' -f4`
ip=`echo $line | cut -d ';' -f8`
txt=`echo $line | cut -d ';' -f10`
app_name=`echo $txt | sed -n "s/.*app_name=\([^\"]*\).*/\1/p"`
app_version=`echo $txt | sed -n "s/.*app_version=\([^\"]*\).*/\1/p"`
board=`echo $txt | sed -n "s/.*target_board=\([^\"]*\).*/\1/p"`
mem_size=`echo $txt | sed -n "s/.*mem_size=\([^\"]*\).*/\1/p"`
sdk_size=`echo $txt | sed -n "s/.*sdk_size=\([^\"]*\).*/\1/p"`
echo -n "$ip;" >> $ip_file
echo -n "$board;" >> $board_file
echo_pad "$counter" 4
echo_pad "$hostname" 25
echo_pad "http://$ip" 25
echo_pad "$app_name" 15
echo_pad "$app_version" 15
echo_pad "$board" 30
echo_pad "$mem_size" 10
echo_pad "$sdk_size" 10
echo
done
echo
read -p "Choose the board you want to flash (empty if none of these): " num
# None of these
if [ "$num" == "" ]; then
return
fi
# Check boundaries
counter=`cat $count_file`
if [ $num -lt 1 ] || [ $num -gt $counter ]; then
echo "Board number must be between 1 and $counter"
exit 1
fi
# Fill the fields
ip=`cat $ip_file | cut -d ';' -f$num`
board=`cat $board_file | cut -d ';' -f$num`
}
getBoard() {
boards=(`cat espurna/config/hardware.h | grep "defined" | sed "s/.*(\(.*\)).*/\1/" | sort`)
echo_pad "#" 4
echo_pad "DEVICE" 30
echo
printf -v line '%*s\n' 34
echo ${line// /-}
counter=0
for board in "${boards[@]}"; do
(( counter++ ))
echo_pad "$counter" 4
echo_pad "$board" 30
echo
done
echo
read -p "Choose the board you want to flash (empty if none of these): " num
# None of these
if [ "$num" == "" ]; then
return
fi
# Check boundaries
counter=${#boards[*]}
if [ $num -lt 1 ] || [ $num -gt $counter ]; then
echo "Board code must be between 1 and $counter"
exit 1
fi
# Fill the fields
(( num -- ))
board=${boards[$num]}
}
# ------------------------------------------------------------------------------
# Welcome
echo
echo "--------------------------------------------------------------"
echo "ESPURNA FIRMWARE OTA FLASHER"
# Get current version
version=`cat espurna/config/version.h | grep APP_VERSION | awk '{print $3}' | sed 's/"//g'`
echo "Building for version $version"
echo "--------------------------------------------------------------"
echo
if exists avahi-browse; then
useAvahi
fi
if [ "$board" == "" ]; then
getBoard
fi
if [ "$board" == "" ]; then
read -p "Board type of the device to flash: " -e -i "NODEMCU_LOLIN" board
fi
if [ "$board" == "" ]; then
echo "You must define the board type"
exit 2
fi
if [ "$ip" == "" ]; then
read -p "IP of the device to flash: " -e -i 192.168.4.1 ip
fi
if [ "$ip" == "" ]; then
echo "You must define the IP of the device"
exit 2
fi
if [ "$auth" == "" ]; then
read -p "Authorization key of the device to flash: " auth
fi
if [ "$flags" == "" ]; then
read -p "Extra flags for the build: " -e -i "" flags
fi
read -p "Environment to build: " -e -i "esp8266-1m-ota" env
echo
echo "ESPURNA_IP = $ip"
echo "ESPURNA_BOARD = $board"
echo "ESPURNA_AUTH = $auth"
echo "ESPURNA_FLAGS = $flags"
echo "ESPURNA_ENV = $env"
echo
echo -n "Are these values corrent [y/N]: "
read response
if [ "$response" != "y" ]; then
exit
fi
export ESPURNA_IP=$ip
export ESPURNA_BOARD=$board
export ESPURNA_AUTH=$auth
export ESPURNA_FLAGS=$flags
pio run -e $env -t upload

+ 0
- 74
code/ota_list.sh View File

@ -1,74 +0,0 @@
#!/bin/bash
exists() {
command -v "$1" >/dev/null 2>&1
}
echo_pad() {
string=$1
pad=$2
printf '%s' "$string"
printf '%*s' $(( $pad - ${#string} ))
}
useAvahi() {
echo_pad "#" 4
echo_pad "HOSTNAME" 25
echo_pad "IP" 25
echo_pad "APP" 15
echo_pad "VERSION" 15
echo_pad "DEVICE" 30
echo_pad "MEM_SIZE" 10
echo_pad "SDK_SIZE" 10
echo
printf -v line '%*s\n' 134
echo ${line// /-}
counter=0
avahi-browse -t -r -p "_arduino._tcp" 2>/dev/null | grep ^= | sort -t ';' -k 3 | while read line; do
(( counter++ ))
hostname=`echo $line | cut -d ';' -f4`
ip=`echo $line | cut -d ';' -f8`
txt=`echo $line | cut -d ';' -f10`
app_name=`echo $txt | sed -n "s/.*app_name=\([^\"]*\).*/\1/p"`
app_version=`echo $txt | sed -n "s/.*app_version=\([^\"]*\).*/\1/p"`
board=`echo $txt | sed -n "s/.*target_board=\([^\"]*\).*/\1/p"`
mem_size=`echo $txt | sed -n "s/.*mem_size=\([^\"]*\).*/\1/p"`
sdk_size=`echo $txt | sed -n "s/.*sdk_size=\([^\"]*\).*/\1/p"`
echo_pad "$counter" 4
echo_pad "$hostname" 25
echo_pad "http://$ip" 25
echo_pad "$app_name" 15
echo_pad "$app_version" 15
echo_pad "$board" 30
echo_pad "$mem_size" 10
echo_pad "$sdk_size" 10
echo
done
echo
}
# ------------------------------------------------------------------------------
# Welcome
echo
echo "--------------------------------------------------------------"
echo "OTA-UPDATABLE DEVICES"
echo "--------------------------------------------------------------"
echo
if exists avahi-browse; then
useAvahi
else
echo "Avahi not installed"
exit 1
fi

+ 160
- 10
code/platformio.ini View File

@ -4,8 +4,8 @@ src_dir = espurna
data_dir = espurna/data
[common]
platform = espressif8266
#platform = espressif8266_stage
#platform = espressif8266
platform = https://github.com/platformio/platform-espressif8266.git#v1.5.0
build_flags = -g -DMQTT_MAX_PACKET_SIZE=400 ${env.ESPURNA_FLAGS}
debug_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_SSL -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP_CLIENT -DDEBUG_ESP_HTTP_UPDATE -DDEBUG_ESP_HTTP_SERVER -DDEBUG_ESP_UPDATER -DDEBUG_ESP_OTA -DDEBUG_TLS_MEM
build_flags_512k = ${common.build_flags} -Wl,-Tesp8266.flash.512k0.ld
@ -33,8 +33,7 @@ lib_deps =
https://github.com/xoseperez/RemoteSwitch-arduino-library.git
https://github.com/markszabo/IRremoteESP8266#v2.2.0
lib_ignore =
#extra_scripts = post:core_version.py
extra_scripts =
extra_scripts = extra_scripts.py
# ------------------------------------------------------------------------------
@ -58,6 +57,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DWEMOS_D1_MINI_RELAYSHIELD -DDEBUG_FAUXMO=Serial -DNOWSAUTH -DASYNC_TCP_SSL_ENABLED=1
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wemos-d1mini-relayshield-ota]
platform = ${common.platform}
@ -69,6 +69,7 @@ build_flags = ${common.build_flags} -DWEMOS_D1_MINI_RELAYSHIELD -DDEBUG_FAUXMO=S
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
extra_scripts = ${common.extra_scripts}
[env:nodemcu-lolin]
platform = ${common.platform}
@ -79,6 +80,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DNODEMCU_LOLIN -DDEBUG_FAUXMO=Serial -DNOWSAUTH
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:nodemcu-lolin-ssl]
platform = espressif8266_stage
@ -89,6 +91,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DNODEMCU_LOLIN -DDEBUG_FAUXMO=Serial -DNOWSAUTH -DASYNC_TCP_SSL_ENABLED=1
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:nodemcu-lolin-ota]
platform = ${common.platform}
@ -101,6 +104,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
@ -112,6 +116,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DTINKERMAN_ESPURNA_H06
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:tinkerman-espurna-h06-ota]
platform = ${common.platform}
@ -124,6 +129,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:tinkerman-espurna-h08]
platform = ${common.platform}
@ -133,6 +139,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DTINKERMAN_ESPURNA_H08
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:tinkerman-espurna-h08-ota]
platform = ${common.platform}
@ -145,6 +152,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
@ -157,6 +165,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_BASIC
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-basic-ota]
platform = ${common.platform}
@ -170,8 +179,9 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-basic-dht22]
[env:itead-sonoff-basic-dht]
platform = ${common.platform}
framework = arduino
board = esp01_1m
@ -180,8 +190,9 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_BASIC -DDHT_SUPPORT=1
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-basic-dht22-ota]
[env:itead-sonoff-basic-dht-ota]
platform = ${common.platform}
framework = arduino
board = esp01_1m
@ -193,16 +204,18 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-basic-ds18b20]
[env:itead-sonoff-basic-dallas]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_BASIC -DDS18B20_SUPPORT=1
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_BASIC -DDALLAS_SUPPORT=1
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-rf]
platform = ${common.platform}
@ -213,6 +226,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_RF
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-rf-ota]
platform = ${common.platform}
@ -226,6 +240,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-th]
platform = ${common.platform}
@ -236,6 +251,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_TH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-th-ota]
platform = ${common.platform}
@ -249,6 +265,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-pow]
platform = ${common.platform}
@ -259,6 +276,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_POW
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-pow-ota]
platform = ${common.platform}
@ -272,6 +290,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-dual]
platform = ${common.platform}
@ -281,6 +300,7 @@ board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_DUAL
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-dual-ota]
platform = ${common.platform}
@ -293,6 +313,7 @@ build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_DUAL
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-dual-r2]
platform = ${common.platform}
@ -302,6 +323,7 @@ board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_DUAL_R2
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-dual-ota-r2]
platform = ${common.platform}
@ -314,6 +336,7 @@ build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_DUAL_R2
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-4ch]
platform = ${common.platform}
@ -324,6 +347,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_4CH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-4ch-ota]
platform = ${common.platform}
@ -337,6 +361,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-4ch-pro]
platform = ${common.platform}
@ -347,6 +372,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_4CH_PRO
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-4ch-pro-ota]
platform = ${common.platform}
@ -360,6 +386,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-touch]
platform = ${common.platform}
@ -370,6 +397,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_TOUCH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-touch-ota]
platform = ${common.platform}
@ -383,6 +411,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-b1]
platform = ${common.platform}
@ -393,6 +422,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_B1
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-b1-ota]
platform = ${common.platform}
@ -406,6 +436,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-t1-1ch]
platform = ${common.platform}
@ -416,6 +447,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_T1_1CH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-t1-1ch-ota]
platform = ${common.platform}
@ -429,6 +461,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-t1-2ch]
platform = ${common.platform}
@ -439,6 +472,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_T1_2CH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-t1-2ch-ota]
platform = ${common.platform}
@ -452,6 +486,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-t1-3ch]
platform = ${common.platform}
@ -462,6 +497,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_T1_3CH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-t1-3ch-ota]
platform = ${common.platform}
@ -475,6 +511,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-led]
platform = ${common.platform}
@ -485,6 +522,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_LED
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-led-ota]
platform = ${common.platform}
@ -498,6 +536,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-rfbridge]
platform = ${common.platform}
@ -508,6 +547,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_RFBRIDGE
monitor_baud = 19200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-rfbridge-ota]
platform = ${common.platform}
@ -521,6 +561,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=Algernon1 --port 8266
monitor_baud = 19200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
@ -533,6 +574,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SLAMPHER
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-slampher-ota]
platform = ${common.platform}
@ -546,6 +588,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-s20]
platform = ${common.platform}
@ -556,6 +599,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_S20
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-s20-ota]
platform = ${common.platform}
@ -569,6 +613,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-1ch-inching]
platform = ${common.platform}
@ -579,6 +624,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_1CH_INCHING
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-1ch-inching-ota]
platform = ${common.platform}
@ -592,6 +638,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-motor]
platform = ${common.platform}
@ -602,6 +649,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_MOTOR
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-motor-ota]
platform = ${common.platform}
@ -615,6 +663,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
@ -626,6 +675,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DELECTRODRAGON_WIFI_IOT -DDHT_SUPPORT=1
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:electrodragon-wifi-iot-ota]
platform = ${common.platform}
@ -638,6 +688,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:workchoice-ecoplug]
platform = ${common.platform}
@ -648,6 +699,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DWORKCHOICE_ECOPLUG
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:workchoice-ecoplug-ota]
platform = ${common.platform}
@ -661,6 +713,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:jangoe-wifi-relay]
platform = ${common.platform}
@ -670,6 +723,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DJANGOE_WIFI_RELAY_NC
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:jangoe-wifi-relay-ota]
platform = ${common.platform}
@ -682,6 +736,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:openenergymonitor-mqtt-relay]
platform = ${common.platform}
@ -689,8 +744,9 @@ framework = arduino
board = esp_wroom_02
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DOPENENERGYMONITOR_MQTT_RELAY -DDS18B20_SUPPORT=1
build_flags = ${common.build_flags} -DOPENENERGYMONITOR_MQTT_RELAY -DDALLAS_SUPPORT=1
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:openenergymonitor-mqtt-relay-ota]
platform = ${common.platform}
@ -698,11 +754,12 @@ framework = arduino
board = esp_wroom_02
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DOPENENERGYMONITOR_MQTT_RELAY -DDS18B20_SUPPORT=1
build_flags = ${common.build_flags} -DOPENENERGYMONITOR_MQTT_RELAY -DDALLAS_SUPPORT=1
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:jorgegarcia-wifi-relays]
platform = ${common.platform}
@ -712,6 +769,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DJORGEGARCIA_WIFI_RELAYS
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:jorgegarcia-wifi-relays-ota]
platform = ${common.platform}
@ -724,6 +782,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:aithinker-ai-light]
platform = ${common.platform}
@ -734,6 +793,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DAITHINKER_AI_LIGHT
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:aithinker-ai-light-ota]
platform = ${common.platform}
@ -747,6 +807,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:magichome-led-controller]
platform = ${common.platform}
@ -757,6 +818,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DMAGICHOME_LED_CONTROLLER
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:magichome-led-controller-ota]
platform = ${common.platform}
@ -770,6 +832,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:magichome-led-controller-20]
platform = ${common.platform}
@ -780,6 +843,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DMAGICHOME_LED_CONTROLLER_20
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:magichome-led-controller-20-ota]
platform = ${common.platform}
@ -792,6 +856,7 @@ build_flags = ${common.build_flags_1m} -DMAGICHOME_LED_CONTROLLER_20
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:huacanxing-h801]
platform = ${common.platform}
@ -802,6 +867,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DHUACANXING_H801
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:huacanxing-h801-ota]
platform = ${common.platform}
@ -815,6 +881,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:huacanxing-h802]
platform = ${common.platform}
@ -825,6 +892,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DHUACANXING_H802
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:huacanxing-h802-ota]
platform = ${common.platform}
@ -838,6 +906,32 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-al-lc01]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DARILUX_AL_LC01
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-al-lc01-ota]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DARILUX_AL_LC01
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-al-lc06]
platform = ${common.platform}
@ -848,6 +942,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DARILUX_AL_LC06
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-al-lc06-ota]
platform = ${common.platform}
@ -861,6 +956,32 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-al-lc11]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DARILUX_AL_LC11
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-al-lc11-ota]
platform = ${common.platform}
framework = arduino
board = esp01_1m
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DARILUX_AL_LC11
upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-e27]
platform = ${common.platform}
@ -871,6 +992,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = -g -Wl,-Tesp8266.flash.1m0.ld -DARILUX_E27
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:arilux-e27-ota]
platform = ${common.platform}
@ -884,6 +1006,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-bnsz01]
platform = ${common.platform}
@ -894,6 +1017,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_BNSZ01
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-bnsz01-ota]
platform = ${common.platform}
@ -907,6 +1031,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wion-50055]
platform = ${common.platform}
@ -917,6 +1042,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DWION_50055
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wion-50055-ota]
platform = ${common.platform}
@ -930,6 +1056,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:exs-wifi-relay-v31]
platform = ${common.platform}
@ -940,6 +1067,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DEXS_WIFI_RELAY_V31
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:exs-wifi-relay-v31-ota]
platform = ${common.platform}
@ -953,6 +1081,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wemos-v9261f]
platform = ${common.platform}
@ -963,6 +1092,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DGENERIC_V9261F
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wemos-v9261f-ota]
platform = ${common.platform}
@ -975,6 +1105,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:esp01-v9261f]
platform = ${common.platform}
@ -985,6 +1116,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DGENERIC_V9261F
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:esp01-v9261f-ota]
platform = ${common.platform}
@ -998,6 +1130,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wemos-ech1560]
platform = ${common.platform}
@ -1008,6 +1141,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DGENERIC_ECH1560
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:wemos-ech1560-ota]
platform = ${common.platform}
@ -1020,6 +1154,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:esp01-ech1560]
platform = ${common.platform}
@ -1030,6 +1165,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DGENERIC_ECH1560
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:esp01-ech1560-ota]
platform = ${common.platform}
@ -1043,6 +1179,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:mancavemade-esplive]
platform = ${common.platform}
@ -1053,6 +1190,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DMANCAVEMADE_ESPLIVE
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:mancavemade-esplive-ota]
platform = ${common.platform}
@ -1065,6 +1203,7 @@ upload_speed = 460800
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:intermittech-quinled]
platform = ${common.platform}
@ -1075,6 +1214,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DINTERMITTECH_QUINLED
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:intermittech-quinled-ota]
platform = ${common.platform}
@ -1088,6 +1228,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:xenon-sm-pw702u]
platform = ${common.platform}
@ -1098,6 +1239,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DXENON_SM_PW702U
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:xenon-sm-pw702u-ota]
platform = ${common.platform}
@ -1111,6 +1253,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:authometion-lyt8266]
platform = ${common.platform}
@ -1121,6 +1264,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DAUTHOMETION_LYT8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:authometion-lyt8266-ota]
platform = ${common.platform}
@ -1134,6 +1278,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:yjzk-switch-2ch]
platform = ${common.platform}
@ -1144,6 +1289,7 @@ lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DYJZK_SWITCH_2CH
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:yjzk-switch-2ch-ota]
platform = ${common.platform}
@ -1157,6 +1303,7 @@ upload_speed = 115200
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:generic-8ch]
platform = ${common.platform}
@ -1167,6 +1314,7 @@ lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags} -DGENERIC_8CH
upload_speed = 460800
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
# GENERIC OTA ENVIRONMENTS
@ -1183,6 +1331,7 @@ build_flags = ${common.build_flags_1m} -D${env.ESPURNA_BOARD}
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts}
[env:esp8266-4m-ota]
platform = ${common.platform}
@ -1195,3 +1344,4 @@ build_flags = ${common.build_flags} -D${env.ESPURNA_BOARD}
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts}

+ 7
- 0
code/requirements.txt View File

@ -0,0 +1,7 @@
enum-compat==0.0.2
enum34==1.1.6
netifaces==0.10.6
ordereddict==1.1
six==1.11.0
sortedcontainers==1.5.9
zeroconf==0.19.1

Loading…
Cancel
Save