Browse Source

Merge branch 'dev' into alexa

ech1560
Xose Pérez 6 years ago
parent
commit
7f2104baa7
38 changed files with 15601 additions and 15222 deletions
  1. +3
    -2
      code/espurna/api.ino
  2. +1
    -0
      code/espurna/config/all.h
  3. +9
    -2
      code/espurna/config/arduino.h
  4. +5
    -51
      code/espurna/config/dependencies.h
  5. +4
    -0
      code/espurna/config/general.h
  6. +41
    -1
      code/espurna/config/hardware.h
  7. +18
    -9
      code/espurna/config/progmem.h
  8. +11
    -3
      code/espurna/config/sensors.h
  9. +73
    -0
      code/espurna/config/webui.h
  10. BIN
      code/espurna/data/index.all.html.gz
  11. BIN
      code/espurna/data/index.light.html.gz
  12. BIN
      code/espurna/data/index.rfbridge.html.gz
  13. BIN
      code/espurna/data/index.rfm69.html.gz
  14. BIN
      code/espurna/data/index.sensor.html.gz
  15. BIN
      code/espurna/data/index.small.html.gz
  16. +3
    -1
      code/espurna/espurna.ino
  17. +40
    -0
      code/espurna/filters/LastFilter.h
  18. +10
    -3
      code/espurna/light.ino
  19. +19
    -0
      code/espurna/migrate.ino
  20. +5
    -3
      code/espurna/relay.ino
  21. +102
    -27
      code/espurna/sensor.ino
  22. +2
    -2
      code/espurna/sensors/CSE7766Sensor.h
  23. +15
    -0
      code/espurna/sensors/ECH1560Sensor.h
  24. +5
    -0
      code/espurna/sensors/EmonSensor.h
  25. +4
    -2
      code/espurna/sensors/HLW8012Sensor.h
  26. +12
    -1
      code/espurna/sensors/PZEM004TSensor.h
  27. +21
    -6
      code/espurna/sensors/V9261FSensor.h
  28. +3052
    -3045
      code/espurna/static/index.all.html.gz.h
  29. +2386
    -2386
      code/espurna/static/index.light.html.gz.h
  30. +2051
    -2050
      code/espurna/static/index.rfbridge.html.gz.h
  31. +3411
    -3410
      code/espurna/static/index.rfm69.html.gz.h
  32. +2210
    -2203
      code/espurna/static/index.sensor.html.gz.h
  33. +2008
    -2007
      code/espurna/static/index.small.html.gz.h
  34. +5
    -1
      code/espurna/utils.ino
  35. +6
    -0
      code/espurna/wifi.ino
  36. +19
    -7
      code/html/index.html
  37. +50
    -0
      code/platformio.ini
  38. BIN
      images/devices/blitzwolf-bw-shp2.jpg

+ 3
- 2
code/espurna/api.ino View File

@ -6,7 +6,7 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
*/
#if WEB_SUPPORT
#if API_SUPPORT
#include <ESPAsyncTCP.h>
#include <ESPAsyncWebServer.h>
@ -27,6 +27,7 @@ bool _apiWebSocketOnReceive(const char * key, JsonVariant& value) {
}
void _apiWebSocketOnSend(JsonObject& root) {
root["apiVisible"] = 1;
root["apiEnabled"] = getSetting("apiEnabled", API_ENABLED).toInt() == 1;
root["apiKey"] = getSetting("apiKey");
root["apiRealTime"] = getSetting("apiRealTime", API_REAL_TIME_VALUES).toInt() == 1;
@ -216,4 +217,4 @@ void apiSetup() {
webRequestRegister(_apiRequestCallback);
}
#endif // WEB_SUPPORT
#endif // API_SUPPORT

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

@ -32,6 +32,7 @@
#include "dependencies.h"
#include "prototypes.h"
#include "sensors.h"
#include "webui.h"
#include "progmem.h"
#include "debug.h"


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

@ -91,13 +91,17 @@
//#define BH_ONOFRE
//#define ITEAD_SONOFF_IFAN02
//#define GENERIC_AG_L4
//#define ALLTERCO_SHELLY1
//#define LOHAS_9W
//--------------------------------------------------------------------------------
// Features (values below are non-default values)
//--------------------------------------------------------------------------------
//#define ALEXA_SUPPORT 0
//#define API_SUPPORT 0
//#define BROKER_SUPPORT 0
//#define BUTTON_SUPPORT 0
//#define DEBUG_SERIAL_SUPPORT 0
//#define DEBUG_TELNET_SUPPORT 0
//#define DEBUG_UDP_SUPPORT 1
@ -107,15 +111,18 @@
//#define I2C_SUPPORT 1
//#define INFLUXDB_SUPPORT 1
//#define IR_SUPPORT 1
//#define LED_SUPPORT 0
//#define LLMNR_SUPPORT 1 // Only with Arduino Core 2.4.0
//#define MDNS_SERVER_SUPPORT 0
//#define MDNS_CLIENT_SUPPORT 1
//#define MDNS_SERVER_SUPPORT 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 RFM69_SUPPORT 1
//#define RF_SUPPORT 1
//#define SCHEDULER_SUPPORT 0
//#define SENSOR_SUPPORT 1
//#define SPIFFS_SUPPORT 1
//#define SSDP_SUPPORT 1
//#define TELNET_SUPPORT 0
@ -141,6 +148,7 @@
//#define EMON_ADS1X15_SUPPORT 1
//#define EMON_ANALOG_SUPPORT 1
//#define EVENTS_SUPPORT 1
//#define GEIGER_SUPPORT 1
//#define GUVAS12SD_SUPPORT 1
//#define HLW8012_SUPPORT 1
//#define MHZ19_SUPPORT 1
@ -152,4 +160,3 @@
//#define SONAR_SUPPORT 1
//#define TMP3X_SUPPORT 1
//#define V9261F_SUPPORT 1
//#define GEIGER_SUPPORT 1

+ 5
- 51
code/espurna/config/dependencies.h View File

@ -15,6 +15,11 @@
#define DEBUG_WEB_SUPPORT 0
#endif
#if not WEB_SUPPORT
#undef API_SUPPORT
#define API_SUPPORT 0 // API support requires web support
#endif
#if not WEB_SUPPORT
#undef SSDP_SUPPORT
#define SSDP_SUPPORT 0 // SSDP support requires web support
@ -48,54 +53,3 @@
#undef NTP_SUPPORT
#define NTP_SUPPORT 1 // Scheduler needs NTP
#endif
// -----------------------------------------------------------------------------
// WEB UI IMAGE
// -----------------------------------------------------------------------------
#define WEBUI_IMAGE_SMALL 0
#define WEBUI_IMAGE_LIGHT 1
#define WEBUI_IMAGE_SENSOR 2
#define WEBUI_IMAGE_RFBRIDGE 4
#define WEBUI_IMAGE_RFM69 8
#define WEBUI_IMAGE_FULL 15
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
#ifdef WEBUI_IMAGE
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#else
#define WEBUI_IMAGE WEBUI_IMAGE_LIGHT
#endif
#endif
#if SENSOR_SUPPORT == 1
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_SENSOR
#else
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#endif
#endif
#if defined(ITEAD_SONOFF_RFBRIDGE)
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_RFBRIDGE
#else
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#endif
#endif
#if RFM69_SUPPORT == 1
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_RFM69
#else
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#endif
#endif
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_SMALL
#endif

+ 4
- 0
code/espurna/config/general.h View File

@ -431,6 +431,10 @@
// API
// -----------------------------------------------------------------------------
#ifndef API_SUPPORT
#define API_SUPPORT 1 // API (REST & RPC) support built in
#endif
// This will only be enabled if WEB_SUPPORT is 1 (this is the default value)
#ifndef API_ENABLED
#define API_ENABLED 0 // Do not enable API by default


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

@ -2457,7 +2457,6 @@
#define HLW8012_POWER_RATIO 3414290
#define HLW8012_INTERRUPT_ON FALLING
// -----------------------------------------------------------------------------
// VANZAVANZU Smart Outlet Socket (based on BL0937 or HJL-01)
// https://www.amazon.com/Smart-Plug-Wifi-Mini-VANZAVANZU/dp/B078PHD6S5
@ -2503,6 +2502,8 @@
#define HLW8012_POWER_RATIO 3414290
#define HLW8012_INTERRUPT_ON FALLING
// -----------------------------------------------------------------------------
#elif defined(GENERIC_AG_L4)
// Info
@ -2547,6 +2548,45 @@
#define LIGHT_CH1_INVERSE 0
#define LIGHT_CH2_INVERSE 0
#define LIGHT_CH3_INVERSE 0
// -----------------------------------------------------------------------------
#elif defined(ALLTERCO_SHELLY1)
// Info
#define MANUFACTURER "ALLTERCO"
#define DEVICE "SHELLY1"
// Buttons
#define BUTTON1_PIN 5
#define BUTTON1_MODE BUTTON_SWITCH
#define BUTTON1_RELAY 1
// Relays
#define RELAY1_PIN 4
#define RELAY1_TYPE RELAY_TYPE_NORMAL
// -----------------------------------------------------------------------------
#elif defined(LOHAS_9W)
// Info
#define MANUFACTURER "LOHAS"
#define DEVICE "E27_9W"
#define RELAY_PROVIDER RELAY_PROVIDER_LIGHT
#define LIGHT_PROVIDER LIGHT_PROVIDER_MY92XX
#define DUMMY_RELAY_COUNT 1
// Light
#define LIGHT_CHANNELS 5
#define MY92XX_MODEL MY92XX_MODEL_MY9231
#define MY92XX_CHIPS 2
#define MY92XX_DI_PIN 13
#define MY92XX_DCKI_PIN 15
#define MY92XX_COMMAND MY92XX_COMMAND_DEFAULT
#define MY92XX_MAPPING 0, 1, 2, 3, 4
#define LIGHT_WHITE_FACTOR (0.1) // White LEDs are way more bright in the B1
// -----------------------------------------------------------------------------
// TEST boards (do not use!!)
// -----------------------------------------------------------------------------


+ 18
- 9
code/espurna/config/progmem.h View File

@ -31,9 +31,15 @@ PROGMEM const char espurna_modules[] =
#if ALEXA_SUPPORT
"ALEXA "
#endif
#if API_SUPPORT
"API "
#endif
#if BROKER_SUPPORT
"BROKER "
#endif
#if BUTTON_SUPPORT
"BUTTON "
#endif
#if DEBUG_SERIAL_SUPPORT
"DEBUG_SERIAL "
#endif
@ -61,15 +67,18 @@ PROGMEM const char espurna_modules[] =
#if IR_SUPPORT
"IR "
#endif
#if LED_SUPPORT
"LED "
#endif
#if LLMNR_SUPPORT
"LLMNR "
#endif
#if MDNS_SERVER_SUPPORT
"MDNS_SERVER "
#endif
#if MDNS_CLIENT_SUPPORT
"MDNS_CLIENT "
#endif
#if MDNS_SERVER_SUPPORT
"MDNS_SERVER "
#endif
#if MQTT_SUPPORT
"MQTT "
#endif
@ -82,12 +91,12 @@ PROGMEM const char espurna_modules[] =
#if NTP_SUPPORT
"NTP "
#endif
#if RF_SUPPORT
"RF "
#endif
#if RFM69_SUPPORT
"RFM69 "
#endif
#if RF_SUPPORT
"RF "
#endif
#if SCHEDULER_SUPPORT
"SCHEDULER "
#endif
@ -169,9 +178,6 @@ PROGMEM const char espurna_sensors[] =
#if GUVAS12SD_SUPPORT
"GUVAS12SD "
#endif
#if SONAR_SUPPORT
"SONAR "
#endif
#if HLW8012_SUPPORT
"HLW8012 "
#endif
@ -196,6 +202,9 @@ PROGMEM const char espurna_sensors[] =
#if SI7021_SUPPORT
"SI7021 "
#endif
#if SONAR_SUPPORT
"SONAR "
#endif
#if TMP3X_SUPPORT
"TMP3X "
#endif


+ 11
- 3
code/espurna/config/sensors.h View File

@ -36,6 +36,14 @@
#define HUMIDITY_MIN_CHANGE 0 // Minimum humidity change to report
#endif
#ifndef SENSOR_SAVE_EVERY
#define SENSOR_SAVE_EVERY 0 // Save accumulating values to EEPROM (atm only energy)
// A 0 means do not save and it's the default value
// A number different from 0 means it should store the value in EEPROM
// after these many reports
// Warning: this might wear out flash fast!
#endif
#define SENSOR_PUBLISH_ADDRESSES 0 // Publish sensor addresses
#define SENSOR_ADDRESS_TOPIC "address" // Topic to publish sensor addresses
@ -295,7 +303,7 @@
#endif
#ifndef EVENTS_INTERRUPT_MODE
#define EVENTS_INTERRUPT_MODE RISING // RISING, FALLING, BOTH
#define EVENTS_INTERRUPT_MODE RISING // RISING, FALLING, CHANGE
#endif
#define EVENTS_DEBOUNCE 50 // Do not register events within less than 50 millis
@ -318,7 +326,7 @@
#endif
#ifndef GEIGER_INTERRUPT_MODE
#define GEIGER_INTERRUPT_MODE RISING // RISING, FALLING, BOTH
#define GEIGER_INTERRUPT_MODE RISING // RISING, FALLING, CHANGE
#endif
#define GEIGER_DEBOUNCE 25 // Do not register events within less than 25 millis.
@ -534,7 +542,7 @@
//------------------------------------------------------------------------------
// SHT3X I2C (Wemos) temperature & humidity sensor
// Enable support by passing SHT3X_SUPPORT=1 build flag
// Enable support by passing SHT3X_I2C_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef SHT3X_I2C_SUPPORT


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

@ -0,0 +1,73 @@
// -----------------------------------------------------------------------------
// WEB UI IMAGE
// -----------------------------------------------------------------------------
#define WEBUI_IMAGE_SMALL 0
#define WEBUI_IMAGE_LIGHT 1
#define WEBUI_IMAGE_SENSOR 2
#define WEBUI_IMAGE_RFBRIDGE 4
#define WEBUI_IMAGE_RFM69 8
#define WEBUI_IMAGE_FULL 15
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
#ifdef WEBUI_IMAGE
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#else
#define WEBUI_IMAGE WEBUI_IMAGE_LIGHT
#endif
#endif
#if SENSOR_SUPPORT == 1
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_SENSOR
#else
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#endif
#endif
#if defined(ITEAD_SONOFF_RFBRIDGE)
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_RFBRIDGE
#else
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#endif
#endif
#if RFM69_SUPPORT == 1
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_RFM69
#else
#undef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_FULL
#endif
#endif
#ifndef WEBUI_IMAGE
#define WEBUI_IMAGE WEBUI_IMAGE_SMALL
#endif
#include <pgmspace.h>
PROGMEM const char espurna_webui[] =
#if WEBUI_IMAGE == WEBUI_IMAGE_SMALL
"SMALL"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_LIGHT
"LIGHT"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_SENSOR
"SENSOR"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_RFBRIDGE
"RFBRIDGE"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_RFM69
"RFM69"
#endif
#if WEBUI_IMAGE == WEBUI_IMAGE_FULL
"FULL"
#endif
"";

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


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


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


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


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


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


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

@ -87,11 +87,13 @@ void setup() {
#if WEB_SUPPORT
webSetup();
wsSetup();
apiSetup();
#if DEBUG_WEB_SUPPORT
debugWebSetup();
#endif
#endif
#if API_SUPPORT
apiSetup();
#endif
// lightSetup must be called before relaySetup
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE


+ 40
- 0
code/espurna/filters/LastFilter.h View File

@ -0,0 +1,40 @@
// -----------------------------------------------------------------------------
// Last Filter
// Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
// -----------------------------------------------------------------------------
#if SENSOR_SUPPORT
#pragma once
#include "BaseFilter.h"
class LastFilter : public BaseFilter {
public:
void add(double value) {
_value = value;
}
unsigned char count() {
return 1;
}
void reset() {
_value = 0;
}
double result() {
return _value;
}
void resize(unsigned char size) {}
protected:
double _value = 0;
};
#endif // SENSOR_SUPPORT

+ 10
- 3
code/espurna/light.ino View File

@ -282,7 +282,7 @@ void _fromHSV(const char * hsv) {
void _fromKelvin(unsigned long kelvin) {
if (!_light_has_color) return;
_light_mireds = constrain(round(1000000UL / kelvin), LIGHT_MIN_MIREDS, LIGHT_MAX_MIREDS);
if (_light_use_cct) {
@ -826,6 +826,10 @@ void _lightWebSocketOnAction(uint32_t client_id, const char * action, JsonObject
}
}
#endif
#if API_SUPPORT
void _lightAPISetup() {
// API entry points (protected with apikey)
if (_light_has_color) {
@ -896,7 +900,7 @@ void _lightAPISetup() {
}
}
#endif // WEB_SUPPORT
#endif // API_SUPPORT
#if TERMINAL_SUPPORT
@ -1069,7 +1073,6 @@ void lightSetup() {
_lightColorRestore();
#if WEB_SUPPORT
_lightAPISetup();
wsOnSendRegister(_lightWebSocketOnSend);
wsOnActionRegister(_lightWebSocketOnAction);
wsOnReceiveRegister(_lightWebSocketOnReceive);
@ -1081,6 +1084,10 @@ void lightSetup() {
});
#endif
#if API_SUPPORT
_lightAPISetup();
#endif
#if MQTT_SUPPORT
mqttRegister(_lightMQTTCallback);
#endif


+ 19
- 0
code/espurna/migrate.ino View File

@ -1087,6 +1087,25 @@ void migrate() {
setSetting("chLogic", 2, 0);
setSetting("relays", 1);
#elif defined(ALLTERCO_SHELLY1)
setSetting("board", 83);
setSetting("btnGPIO", 0, 5);
setSetting("btnRelay", 0, 0);
setSetting("relayGPIO", 0, 4);
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
#elif defined(LOHAS_9W)
setSetting("board", 84);
setSetting("relayProvider", RELAY_PROVIDER_LIGHT);
setSetting("lightProvider", LIGHT_PROVIDER_MY92XX);
setSetting("myModel", MY92XX_MODEL_MY9231);
setSetting("myChips", 2);
setSetting("myDIGPIO", 13);
setSetting("myDCKIGPIO", 15);
setSetting("relays", 1);
#else
// Allow users to define new settings without migration config


+ 5
- 3
code/espurna/relay.ino View File

@ -628,7 +628,7 @@ void relaySetupWS() {
// REST API
//------------------------------------------------------------------------------
#if WEB_SUPPORT
#if API_SUPPORT
void relaySetupAPI() {
@ -700,7 +700,7 @@ void relaySetupAPI() {
}
#endif // WEB_SUPPORT
#endif // API_SUPPORT
//------------------------------------------------------------------------------
// MQTT
@ -1007,9 +1007,11 @@ void relaySetup() {
espurnaRegisterLoop(_relayLoop);
#if WEB_SUPPORT
relaySetupAPI();
relaySetupWS();
#endif
#if API_SUPPORT
relaySetupAPI();
#endif
#if MQTT_SUPPORT
relaySetupMQTT();
#endif


+ 102
- 27
code/espurna/sensor.ino View File

@ -9,6 +9,7 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
#if SENSOR_SUPPORT
#include <vector>
#include "filters/LastFilter.h"
#include "filters/MaxFilter.h"
#include "filters/MedianFilter.h"
#include "filters/MovingAverageFilter.h"
@ -34,6 +35,7 @@ unsigned char _counts[MAGNITUDE_MAX];
bool _sensor_realtime = API_REAL_TIME_VALUES;
unsigned long _sensor_read_interval = 1000 * SENSOR_READ_INTERVAL;
unsigned char _sensor_report_every = SENSOR_REPORT_EVERY;
unsigned char _sensor_save_every = SENSOR_SAVE_EVERY;
unsigned char _sensor_power_units = SENSOR_POWER_UNITS;
unsigned char _sensor_energy_units = SENSOR_ENERGY_UNITS;
unsigned char _sensor_temperature_units = SENSOR_TEMPERATURE_UNITS;
@ -100,7 +102,7 @@ bool _sensorWebSocketOnReceive(const char * key, JsonVariant& value) {
if (strncmp(key, "sns", 3) == 0) return true;
if (strncmp(key, "tmp", 3) == 0) return true;
if (strncmp(key, "hum", 3) == 0) return true;
if (strncmp(key, "energy", 6) == 0) return true;
if (strncmp(key, "ene", 3) == 0) return true;
return false;
}
@ -127,8 +129,8 @@ void _sensorWebSocketSendData(JsonObject& root) {
element["error"] = magnitude.sensor->error();
if (magnitude.type == MAGNITUDE_ENERGY) {
if (_sensor_energy_reset_ts.length() == 0) _sensorReset();
element["description"] = magnitude.sensor->slot(magnitude.local) + _sensor_energy_reset_ts;
if (_sensor_energy_reset_ts.length() == 0) _sensorResetTS();
element["description"] = magnitude.sensor->slot(magnitude.local) + String(" (since ") + _sensor_energy_reset_ts + String(")");
} else {
element["description"] = magnitude.sensor->slot(magnitude.local);
}
@ -193,15 +195,16 @@ void _sensorWebSocketStart(JsonObject& root) {
}
if (_magnitudes.size() > 0) {
root["sensorsVisible"] = 1;
root["snsVisible"] = 1;
//root["apiRealTime"] = _sensor_realtime;
root["pwrUnits"] = _sensor_power_units;
root["energyUnits"] = _sensor_energy_units;
root["eneUnits"] = _sensor_energy_units;
root["tmpUnits"] = _sensor_temperature_units;
root["tmpCorrection"] = _sensor_temperature_correction;
root["humCorrection"] = _sensor_humidity_correction;
root["snsRead"] = _sensor_read_interval / 1000;
root["snsReport"] = _sensor_report_every;
root["snsSave"] = _sensor_save_every;
}
/*
@ -223,6 +226,10 @@ void _sensorWebSocketStart(JsonObject& root) {
}
#endif // WEB_SUPPORT
#if API_SUPPORT
void _sensorAPISetup() {
for (unsigned char magnitude_id=0; magnitude_id<_magnitudes.size(); magnitude_id++) {
@ -242,7 +249,8 @@ void _sensorAPISetup() {
}
}
#endif
#endif // API_SUPPORT
#if TERMINAL_SUPPORT
@ -288,11 +296,18 @@ void _sensorPost() {
}
}
void _sensorReset() {
void _sensorResetTS() {
#if NTP_SUPPORT
if (ntpSynced()) {
_sensor_energy_reset_ts = String(" (since ") + ntpDateTime() + String(")");
if (_sensor_energy_reset_ts.length() == 0) {
_sensor_energy_reset_ts = ntpDateTime(now() - millis() / 1000);
} else {
_sensor_energy_reset_ts = ntpDateTime(now());
}
} else {
_sensor_energy_reset_ts = String();
}
setSetting("snsResetTS", _sensor_energy_reset_ts);
#endif
}
@ -608,6 +623,7 @@ void _sensorCallback(unsigned char i, unsigned char type, double value) {
void _sensorInit() {
_sensors_ready = true;
_sensor_save_every = getSetting("snsSave", 0).toInt();
for (unsigned char i=0; i<_sensors.size(); i++) {
@ -637,9 +653,11 @@ void _sensorInit() {
new_magnitude.filtered = 0;
new_magnitude.reported = 0;
new_magnitude.min_change = 0;
if (type == MAGNITUDE_DIGITAL) {
if (MAGNITUDE_ENERGY == type) {
new_magnitude.filter = new LastFilter();
} else if (MAGNITUDE_DIGITAL == type) {
new_magnitude.filter = new MaxFilter();
} else if (type == MAGNITUDE_COUNT || type == MAGNITUDE_GEIGER_CPM|| type == MAGNITUDE_GEIGER_SIEVERT) { // For geiger counting moving average filter is the most appropriate if needed at all.
} else if (MAGNITUDE_COUNT == type || MAGNITUDE_GEIGER_CPM == type || MAGNITUDE_GEIGER_SIEVERT == type) { // For geiger counting moving average filter is the most appropriate if needed at all.
new_magnitude.filter = new MovingAverageFilter();
} else {
new_magnitude.filter = new MedianFilter();
@ -666,6 +684,8 @@ void _sensorInit() {
EmonAnalogSensor * sensor = (EmonAnalogSensor *) _sensors[i];
sensor->setCurrentRatio(0, getSetting("pwrRatioC", EMON_CURRENT_RATIO).toFloat());
sensor->setVoltage(getSetting("pwrVoltage", EMON_MAINS_VOLTAGE).toInt());
double value = (_sensor_save_every > 0) ? getSetting("eneTotal", 0).toInt() : 0;
if (value > 0) sensor->resetEnergy(0, value);
}
#endif // EMON_ANALOG_SUPPORT
@ -687,6 +707,9 @@ void _sensorInit() {
value = getSetting("pwrRatioP", HLW8012_POWER_RATIO).toFloat();
if (value > 0) sensor->setPowerRatio(value);
value = (_sensor_save_every > 0) ? getSetting("eneTotal", 0).toInt() : 0;
if (value > 0) sensor->resetEnergy(value);
}
#endif // HLW8012_SUPPORT
@ -708,6 +731,9 @@ void _sensorInit() {
value = getSetting("pwrRatioP", 0).toFloat();
if (value > 0) sensor->setPowerRatio(value);
value = (_sensor_save_every > 0) ? getSetting("eneTotal", 0).toInt() : 0;
if (value > 0) sensor->resetEnergy(value);
}
#endif // CSE7766_SUPPORT
@ -721,12 +747,14 @@ void _sensorConfigure() {
// General sensor settings
_sensor_read_interval = 1000 * constrain(getSetting("snsRead", SENSOR_READ_INTERVAL).toInt(), SENSOR_READ_MIN_INTERVAL, SENSOR_READ_MAX_INTERVAL);
_sensor_report_every = constrain(getSetting("snsReport", SENSOR_REPORT_EVERY).toInt(), SENSOR_REPORT_MIN_EVERY, SENSOR_REPORT_MAX_EVERY);
_sensor_save_every = getSetting("snsSave", SENSOR_SAVE_EVERY).toInt();
_sensor_realtime = getSetting("apiRealTime", API_REAL_TIME_VALUES).toInt() == 1;
_sensor_power_units = getSetting("pwrUnits", SENSOR_POWER_UNITS).toInt();
_sensor_energy_units = getSetting("energyUnits", SENSOR_ENERGY_UNITS).toInt();
_sensor_energy_units = getSetting("eneUnits", SENSOR_ENERGY_UNITS).toInt();
_sensor_temperature_units = getSetting("tmpUnits", SENSOR_TEMPERATURE_UNITS).toInt();
_sensor_temperature_correction = getSetting("tmpCorrection", SENSOR_TEMPERATURE_CORRECTION).toFloat();
_sensor_humidity_correction = getSetting("humCorrection", SENSOR_HUMIDITY_CORRECTION).toFloat();
_sensor_energy_reset_ts = getSetting("snsResetTS", "");
// Specific sensor settings
for (unsigned char i=0; i<_sensors.size(); i++) {
@ -750,7 +778,8 @@ void _sensorConfigure() {
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
_sensorReset();
delSetting("eneTotal");
_sensorResetTS();
}
sensor->setVoltage(getSetting("pwrVoltage", EMON_MAINS_VOLTAGE).toInt());
@ -764,7 +793,8 @@ void _sensorConfigure() {
EmonADC121Sensor * sensor = (EmonADC121Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
_sensorReset();
delSetting("eneTotal");
_sensorResetTS();
}
}
#endif
@ -774,7 +804,8 @@ void _sensorConfigure() {
EmonADS1X15Sensor * sensor = (EmonADS1X15Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
_sensorReset();
delSetting("eneTotal");
_sensorResetTS();
}
}
#endif
@ -804,7 +835,8 @@ void _sensorConfigure() {
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
_sensorReset();
delSetting("eneTotal");
_sensorResetTS();
}
if (getSetting("pwrResetCalibration", 0).toInt() == 1) {
@ -842,7 +874,8 @@ void _sensorConfigure() {
if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy();
_sensorReset();
delSetting("eneTotal");
_sensorResetTS();
}
if (getSetting("pwrResetCalibration", 0).toInt() == 1) {
@ -863,6 +896,11 @@ void _sensorConfigure() {
_magnitudes[i].filter->resize(_sensor_report_every);
}
// General processing
if (0 == _sensor_save_every) {
delSetting("eneTotal");
}
// Save settings
delSetting("pwrExpectedP");
delSetting("pwrExpectedC");
@ -1019,6 +1057,7 @@ void sensorSetup() {
// Backwards compatibility
moveSetting("powerUnits", "pwrUnits");
moveSetting("energyUnits", "eneUnits");
// Load sensors
_sensorLoad();
@ -1027,19 +1066,20 @@ void sensorSetup() {
// Configure stored values
_sensorConfigure();
// Websockets
#if WEB_SUPPORT
// Websockets
wsOnSendRegister(_sensorWebSocketStart);
wsOnReceiveRegister(_sensorWebSocketOnReceive);
wsOnSendRegister(_sensorWebSocketSendData);
wsOnAfterParseRegister(_sensorConfigure);
#endif
// API
// API
#if API_SUPPORT
_sensorAPISetup();
#endif
// Terminal
#if TERMINAL_SUPPORT
_sensorInitCommands();
#endif
@ -1068,6 +1108,7 @@ void sensorLoop() {
// Check if we should read new data
static unsigned long last_update = 0;
static unsigned long report_count = 0;
static unsigned long save_count = 0;
if (millis() - last_update > _sensor_read_interval) {
last_update = millis();
@ -1091,6 +1132,10 @@ void sensorLoop() {
if (magnitude.sensor->status()) {
// -------------------------------------------------------------
// Instant value
// -------------------------------------------------------------
current = magnitude.sensor->value(magnitude.local);
// Completely remove spurious values if relay is OFF
@ -1107,17 +1152,26 @@ void sensorLoop() {
}
#endif
// -------------------------------------------------------------
// Processing (filters)
// -------------------------------------------------------------
magnitude.filter->add(current);
// Special case
if (magnitude.type == MAGNITUDE_COUNT) {
// Special case for MovingAvergaeFilter
if (MAGNITUDE_COUNT == magnitude.type ||
MAGNITUDE_GEIGER_CPM ==magnitude. type ||
MAGNITUDE_GEIGER_SIEVERT == magnitude.type) {
current = magnitude.filter->result();
}
current = _magnitudeProcess(magnitude.type, current);
_magnitudes[i].current = current;
// -------------------------------------------------------------
// Debug
// -------------------------------------------------------------
#if SENSOR_DEBUG
{
char buffer[64];
@ -1131,8 +1185,12 @@ void sensorLoop() {
}
#endif // SENSOR_DEBUG
// Time to report (we do it every _sensor_report_every readings)
if (report_count == 0) {
// -------------------------------------------------------------
// Report
// (we do it every _sensor_report_every readings)
// -------------------------------------------------------------
if (0 == report_count) {
filtered = magnitude.filter->result();
magnitude.filter->reset();
@ -1141,13 +1199,30 @@ void sensorLoop() {
// Check if there is a minimum change threshold to report
if (fabs(filtered - magnitude.reported) >= magnitude.min_change) {
_magnitudes[i].reported = filtered;
_sensorReport(i, filtered);
} // if (fabs(filtered - magnitude.reported) >= magnitude.min_change)
// -------------------------------------------------------------
// Saving to EEPROM
// (we do it every _sensor_save_every readings)
// -------------------------------------------------------------
if (_sensor_save_every > 0) {
save_count = (save_count + 1) % _sensor_save_every;
if (0 == save_count) {
if (MAGNITUDE_ENERGY == magnitude.type) {
setSetting("eneTotal", current);
saveSettings();
}
} // if (0 == save_count)
} // if (_sensor_save_every > 0)
} // if (report_count == 0)
} // if (magnitude.sensor->status())
} // for (unsigned char i=0; i<_magnitudes.size(); i++)


+ 2
- 2
code/espurna/sensors/CSE7766Sensor.h View File

@ -102,8 +102,8 @@ class CSE7766Sensor : public BaseSensor {
_ratioC = _ratioV = _ratioP = 1.0;
}
void resetEnergy() {
_energy = 0;
void resetEnergy(double value = 0) {
_energy = value;
}
// ---------------------------------------------------------------------


+ 15
- 0
code/espurna/sensors/ECH1560Sensor.h View File

@ -59,6 +59,12 @@ class ECH1560Sensor : public BaseSensor {
return _inverted;
}
// ---------------------------------------------------------------------
void resetEnergy(double value = 0) {
_energy = value;
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
@ -106,6 +112,7 @@ class ECH1560Sensor : public BaseSensor {
if (index == 0) return MAGNITUDE_CURRENT;
if (index == 1) return MAGNITUDE_VOLTAGE;
if (index == 2) return MAGNITUDE_POWER_APPARENT;
if (index == 3) return MAGNITUDE_ENERGY;
return MAGNITUDE_NONE;
}
@ -114,6 +121,7 @@ class ECH1560Sensor : public BaseSensor {
if (index == 0) return _current;
if (index == 1) return _voltage;
if (index == 2) return _apparent;
if (index == 3) return _energy;
return 0;
}
@ -260,6 +268,12 @@ class ECH1560Sensor : public BaseSensor {
_apparent = ( (float) byte1 * 255 + (float) byte2 + (float) byte3 / 255.0) / 2;
_current = _apparent / _voltage;
static unsigned long last = 0;
if (last > 0) {
_energy += (_apparent * (millis() - last) / 1000);
}
last = millis();
_dosync = false;
}
@ -287,6 +301,7 @@ class ECH1560Sensor : public BaseSensor {
double _apparent = 0;
double _voltage = 0;
double _current = 0;
double _energy = 0;
unsigned char _data[24];


+ 5
- 0
code/espurna/sensors/EmonSensor.h View File

@ -55,6 +55,11 @@ class EmonSensor : public I2CSensor {
}
}
void resetEnergy(unsigned char channel, double value = 0) {
if (channel >= _channels) return;
_energy[channel] = value;
}
// ---------------------------------------------------------------------
void setVoltage(double voltage) {


+ 4
- 2
code/espurna/sensors/HLW8012Sensor.h View File

@ -48,7 +48,8 @@ class HLW8012Sensor : public BaseSensor {
_hlw8012->resetMultipliers();
}
void resetEnergy() {
void resetEnergy(double value = 0) {
_energy_offset = value;
_hlw8012->resetEnergy();
}
@ -200,7 +201,7 @@ class HLW8012Sensor : public BaseSensor {
if (index == 3) return _hlw8012->getReactivePower();
if (index == 4) return _hlw8012->getApparentPower();
if (index == 5) return 100 * _hlw8012->getPowerFactor();
if (index == 6) return _hlw8012->getEnergy();
if (index == 6) return (_energy_offset + _hlw8012->getEnergy());
return 0;
}
@ -261,6 +262,7 @@ class HLW8012Sensor : public BaseSensor {
unsigned char _cf = GPIO_NONE;
unsigned char _cf1 = GPIO_NONE;
bool _sel_current = true;
double _energy_offset = 0;
HLW8012 * _hlw8012 = NULL;


+ 12
- 1
code/espurna/sensors/PZEM004TSensor.h View File

@ -59,6 +59,16 @@ class PZEM004TSensor : public BaseSensor {
return _pin_tx;
}
// ---------------------------------------------------------------------
void resetEnergy(double value = 0) {
if (_ready) {
_energy_offset = value - (_pzem->energy(_ip) * 3600);
} else {
_energy_offset = value;
}
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
@ -117,7 +127,7 @@ class PZEM004TSensor : public BaseSensor {
if (index == 0) response = _pzem->current(_ip);
if (index == 1) response = _pzem->voltage(_ip);
if (index == 2) response = _pzem->power(_ip);
if (index == 3) response = _pzem->energy(_ip) * 3600;
if (index == 3) response = _energy_offset + (_pzem->energy(_ip) * 3600);
if (response < 0) response = 0;
return response;
}
@ -133,6 +143,7 @@ class PZEM004TSensor : public BaseSensor {
IPAddress _ip;
HardwareSerial * _serial = NULL;
PZEM004T * _pzem = NULL;
double _energy_offset = 0;
};


+ 21
- 6
code/espurna/sensors/V9261FSensor.h View File

@ -56,6 +56,12 @@ class V9261FSensor : public BaseSensor {
return _inverted;
}
// ---------------------------------------------------------------------
void resetEnergy(double value = 0) {
_energy = value;
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
@ -106,6 +112,7 @@ class V9261FSensor : public BaseSensor {
if (index == 3) return MAGNITUDE_POWER_REACTIVE;
if (index == 4) return MAGNITUDE_POWER_APPARENT;
if (index == 5) return MAGNITUDE_POWER_FACTOR;
if (index == 6) return MAGNITUDE_ENERGY;
return MAGNITUDE_NONE;
}
@ -117,6 +124,7 @@ class V9261FSensor : public BaseSensor {
if (index == 3) return _reactive;
if (index == 4) return _apparent;
if (index == 5) return _apparent > 0 ? 100 * _active / _apparent : 100;
if (index == 6) return _energy;
return 0;
}
@ -130,6 +138,7 @@ class V9261FSensor : public BaseSensor {
static unsigned char state = 0;
static unsigned long last = 0;
static unsigned long ts = 0;
static bool found = false;
static unsigned char index = 0;
@ -138,10 +147,10 @@ class V9261FSensor : public BaseSensor {
while (_serial->available()) {
_serial->flush();
found = true;
last = millis();
ts = millis();
}
if (found && (millis() - last > V9261F_SYNC_INTERVAL)) {
if (found && (millis() - ts > V9261F_SYNC_INTERVAL)) {
_serial->flush();
index = 0;
state = 1;
@ -164,7 +173,7 @@ class V9261FSensor : public BaseSensor {
_data[index] = _serial->read();
if (index++ >= 19) {
_serial->flush();
last = millis();
ts = millis();
state = 3;
}
}
@ -208,9 +217,14 @@ class V9261FSensor : public BaseSensor {
_apparent = fs_sqrt(_reactive * _reactive + _active * _active);
if (last > 0) {
_energy += (_active * (millis() - last) / 1000);
}
last = millis();
}
last = millis();
ts = millis();
index = 0;
state = 4;
@ -218,10 +232,10 @@ class V9261FSensor : public BaseSensor {
while (_serial->available()) {
_serial->flush();
last = millis();
ts = millis();
}
if (millis() - last > V9261F_SYNC_INTERVAL) {
if (millis() - ts > V9261F_SYNC_INTERVAL) {
state = 1;
}
@ -249,6 +263,7 @@ class V9261FSensor : public BaseSensor {
double _voltage = 0;
double _current = 0;
double _apparent = 0;
double _energy = 0;
double _ratioP = V9261F_POWER_FACTOR;
double _ratioC = V9261F_CURRENT_FACTOR;


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


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


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


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


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


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


+ 5
- 1
code/espurna/utils.ino View File

@ -74,6 +74,10 @@ String getEspurnaSensors() {
}
#endif
String getEspurnaWebUI() {
return FPSTR(espurna_webui);
}
String buildTime() {
const char time_now[] = __TIME__; // hh:mm:ss
@ -320,7 +324,7 @@ void info() {
#if SENSOR_SUPPORT
DEBUG_MSG_P(PSTR("[INIT] SENSORS: %s\n"), getEspurnaSensors().c_str());
#endif // SENSOR_SUPPORT
DEBUG_MSG_P(PSTR("[INIT] WEBUI IMAGE CODE: %u\n"), WEBUI_IMAGE);
DEBUG_MSG_P(PSTR("[INIT] WEBUI IMAGE: %s\n"), getEspurnaWebUI().c_str());
DEBUG_MSG_P(PSTR("\n"));
// -------------------------------------------------------------------------


+ 6
- 0
code/espurna/wifi.ino View File

@ -226,6 +226,7 @@ void _wifiCallback(justwifi_messages_t code, char * parameter) {
if (MESSAGE_WPS_ERROR == code || MESSAGE_SMARTCONFIG_ERROR == code) {
_wifi_wps_running = false;
_wifi_smartconfig_running = false;
jw.enableAP(true);
}
if (MESSAGE_WPS_SUCCESS == code || MESSAGE_SMARTCONFIG_SUCCESS == code) {
@ -249,6 +250,7 @@ void _wifiCallback(justwifi_messages_t code, char * parameter) {
_wifi_wps_running = false;
_wifi_smartconfig_running = false;
jw.enableAP(true);
}
@ -550,12 +552,16 @@ void wifiStartAP() {
#if defined(JUSTWIFI_ENABLE_WPS)
void wifiStartWPS() {
jw.enableAP(false);
jw.disconnect();
jw.startWPS();
}
#endif // defined(JUSTWIFI_ENABLE_WPS)
#if defined(JUSTWIFI_ENABLE_SMARTCONFIG)
void wifiStartSmartConfig() {
jw.enableAP(false);
jw.disconnect();
jw.startSmartConfig();
}
#endif // defined(JUSTWIFI_ENABLE_SMARTCONFIG)


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

@ -137,8 +137,8 @@
</li>
<!-- removeIf(!sensor) -->
<li class="pure-menu-item module module-sensors">
<a href="#" class="pure-menu-link" data="panel-sensors">SENSORS</a>
<li class="pure-menu-item module module-sns">
<a href="#" class="pure-menu-link" data="panel-sns">SENSORS</a>
</li>
<!-- endRemoveIf(!sensor) -->
@ -550,12 +550,12 @@
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="wsAuth" /></div>
</div>
<div class="pure-g">
<div class="pure-g module module-api">
<label class="pure-u-1 pure-u-lg-1-4">Enable HTTP API</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="apiEnabled" /></div>
</div>
<div class="pure-g">
<div class="pure-g module module-api">
<label class="pure-u-1 pure-u-lg-1-4">Real time API</label>
<div class="pure-u-1 pure-u-lg-1-4"><input type="checkbox" name="apiRealTime" /></div>
<div class="pure-u-0 pure-u-lg-1-2"></div>
@ -566,7 +566,7 @@
</div>
</div>
<div class="pure-g">
<div class="pure-g module module-api">
<label class="pure-u-1 pure-u-lg-1-4">HTTP API Key</label>
<input name="apiKey" class="pure-u-3-4 pure-u-lg-1-2" type="text" tabindex="14" />
<div class=" pure-u-1-4 pure-u-lg-1-4"><button class="pure-button button-apikey pure-u-23-24">Auto</button></div>
@ -1141,7 +1141,7 @@
</div>
<!-- removeIf(!sensor) -->
<div class="panel" id="panel-sensors">
<div class="panel" id="panel-sns">
<div class="header">
<h1>SENSOR CONFIGURATION</h1>
@ -1183,6 +1183,18 @@
</div>
</div>
<div class="pure-g module module-pwr">
<label class="pure-u-1 pure-u-lg-1-4">Save every</label>
<div class="pure-u-1 pure-u-lg-1-4"><input name="snsSave" class="pure-u-1" type="number" min="0" step="1" max="200" /></div>
<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">
Save aggregated data to EEPROM after these many reports. At the moment this only applies to total energy readings.
Please mind: saving data to EEPROM too often will wear out the flash memory quickly.
Set it to 0 to disable this feature (default value).
</div>
</div>
<div class="pure-g module module-pwr">
<label class="pure-u-1 pure-u-lg-1-4">Power units</label>
<select name="pwrUnits" tabindex="16" class="pure-u-1 pure-u-lg-1-4">
@ -1191,7 +1203,7 @@
</select>
</div>
<div class="pure-g module module-hlw module-cse module-emon module-pzem">
<div class="pure-g module module-pwr">
<label class="pure-u-1 pure-u-lg-1-4">Energy units</label>
<select name="energyUnits" tabindex="16" class="pure-u-1 pure-u-lg-1-4">
<option value="0">Joules (J)</option>


+ 50
- 0
code/platformio.ini View File

@ -2446,3 +2446,53 @@ upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
extra_scripts = ${common.extra_scripts}
[env:lohas-e27-9w]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DLOHAS_9W
monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts}
[env:lohas-e27-9w-ota]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DLOHAS_9W
upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts}
[env:allterco-sheely1]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DALLTERCO_SHELLY1
monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts}
[env:allterco-sheely1-ota]
platform = ${common.platform}
framework = ${common.framework}
board = ${common.board_1m}
board_build.flash_mode = ${common.flash_mode}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m0m} -DALLTERCO_SHELLY1
upload_speed = ${common.upload_speed}
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
monitor_speed = ${common.monitor_speed}
extra_scripts = ${common.extra_scripts}

BIN
images/devices/blitzwolf-bw-shp2.jpg View File

Before After
Width: 400  |  Height: 400  |  Size: 15 KiB Width: 400  |  Height: 400  |  Size: 28 KiB

Loading…
Cancel
Save