Browse Source

Merge branch 'dev' into ESP_DIN

rfm69
Pavel Slama 6 years ago
committed by GitHub
parent
commit
7d720341c7
No known key found for this signature in database GPG Key ID: 4AEE18F83AFDEB23
55 changed files with 5524 additions and 4198 deletions
  1. +29
    -0
      CHANGELOG.md
  2. +6
    -4
      README.md
  3. +2
    -1
      code/build.sh
  4. +2
    -2
      code/espurna/api.ino
  5. +1
    -0
      code/espurna/button.ino
  6. +4
    -0
      code/espurna/config/all.h
  7. +8
    -0
      code/espurna/config/arduino.h
  8. +17
    -0
      code/espurna/config/debug.h
  9. +0
    -8
      code/espurna/config/defaults.h
  10. +50
    -0
      code/espurna/config/dependencies.h
  11. +212
    -341
      code/espurna/config/general.h
  12. +208
    -16
      code/espurna/config/hardware.h
  13. +106
    -0
      code/espurna/config/progmem.h
  14. +5
    -1
      code/espurna/config/prototypes.h
  15. +105
    -265
      code/espurna/config/sensors.h
  16. +283
    -0
      code/espurna/config/types.h
  17. +2
    -2
      code/espurna/config/version.h
  18. BIN
      code/espurna/data/index.html.gz
  19. +25
    -4
      code/espurna/debug.ino
  20. +6
    -1
      code/espurna/espurna.ino
  21. +11
    -0
      code/espurna/ir.ino
  22. +47
    -27
      code/espurna/libs/StreamInjector.h
  23. +1
    -1
      code/espurna/libs/WebSocketIncommingBuffer.h
  24. +49
    -1
      code/espurna/migrate.ino
  25. +10
    -2
      code/espurna/ntp.ino
  26. +123
    -47
      code/espurna/rfbridge.ino
  27. +21
    -11
      code/espurna/scheduler.ino
  28. +48
    -17
      code/espurna/sensor.ino
  29. +8
    -3
      code/espurna/sensors/AM2320Sensor.h
  30. +4
    -0
      code/espurna/sensors/AnalogSensor.h
  31. +3
    -0
      code/espurna/sensors/BH1750Sensor.h
  32. +3
    -0
      code/espurna/sensors/BMX280Sensor.h
  33. +0
    -9
      code/espurna/sensors/DallasSensor.h
  34. +0
    -4
      code/espurna/sensors/EmonADS1X15Sensor.h
  35. +4
    -0
      code/espurna/sensors/EmonAnalogSensor.h
  36. +4
    -0
      code/espurna/sensors/EmonSensor.h
  37. +5
    -1
      code/espurna/sensors/GUVAS12SDSensor.h
  38. +207
    -34
      code/espurna/sensors/PMSX003Sensor.h
  39. +4
    -0
      code/espurna/sensors/SHT3XI2CSensor.h
  40. +5
    -0
      code/espurna/sensors/SI7021Sensor.h
  41. +233
    -0
      code/espurna/sensors/SenseAirSensor.h
  42. +4
    -0
      code/espurna/sensors/TMP3XSensor.h
  43. +21
    -24
      code/espurna/settings.ino
  44. +3268
    -3265
      code/espurna/static/index.html.gz.h
  45. +17
    -13
      code/espurna/system.ino
  46. +9
    -0
      code/espurna/telnet.ino
  47. +5
    -1
      code/espurna/thinkspeak.ino
  48. +26
    -3
      code/espurna/utils.ino
  49. +30
    -0
      code/espurna/wifi.ino
  50. +3
    -1
      code/espurna/ws.ino
  51. +1
    -0
      code/html/custom.css
  52. +18
    -14
      code/html/custom.js
  53. +12
    -7
      code/html/index.html
  54. +144
    -9
      code/platformio.ini
  55. +105
    -59
      pre-commit

+ 29
- 0
CHANGELOG.md View File

@ -3,6 +3,35 @@
The format is based on [Keep a Changelog](http://keepachangelog.com/) The format is based on [Keep a Changelog](http://keepachangelog.com/)
and this project adheres to [Semantic Versioning](http://semver.org/). and this project adheres to [Semantic Versioning](http://semver.org/).
## [1.12.6] 2018-05-02
### Fixed
- Check NTP_SUPPORT for sensors (thanks to @mcspr)
- Fix AM2302 sensor
- Fix hostname truncated to 20 chars when advertised to DHCP ([#774](https://github.com/xoseperez/espurna/issues/774))
- Decouple Serial object from Terminal, Debug modules ([#787](https://github.com/xoseperez/espurna/issues/787))
- Fix Arilux LC-01 definitions ([#797](https://github.com/xoseperez/espurna/issues/797))
- Do not uppercase hostname in web interface ([#799](https://github.com/xoseperez/espurna/issues/799))
- Ensure scheduler has access to all channels independently of the color mode ([#807](https://github.com/xoseperez/espurna/issues/807))
### Added
- Support for IteadStudio Sonoff S31 ([#497](https://github.com/xoseperez/espurna/issues/497))
- Option to ignore daylight saving in scheduler ([#783](https://github.com/xoseperez/espurna/issues/783))
- Report last energy reset datetime in web interface ([#784](https://github.com/xoseperez/espurna/issues/784))
- Added captive portal in AP mode
- Support for IR toggle mode (thanks to @darshkpatel)
- Support for IteadStudio Sonoff POW R2 (thanks to @ColinShorts)
- Support for Luani HVIO (thanks to @wildwiz)
- Support for Zhilde ZLD-EU55-W power strip (thanks to @wildwiz)
- Support for RFB_DIRECT Sonoff Bridge EFM8BB1 bypass hack (thanks to @wildwiz)
- Support for SenseAir S8 CO2 sensor (thanks to @Yonsm)
- Support for PMS5003T/ST sensors (thanks to @Yonsm)
### Changed
- Updated JustWifi Library
- Some cleanup in the web interface
- Refactored configuration files (thanks to @lobradov, @mcspr)
- Changes pre-commit hook (thanks to @mcspr)
## [1.12.5] 2018-04-08 ## [1.12.5] 2018-04-08
### Fixed ### Fixed
- Fixed expected power calibration ([#676](https://github.com/xoseperez/espurna/issues/676)) - Fixed expected power calibration ([#676](https://github.com/xoseperez/espurna/issues/676))


+ 6
- 4
README.md View File

@ -3,8 +3,8 @@
ESPurna ("spark" in Catalan) is a custom firmware for ESP8285/ESP8266 based smart switches, lights and sensors. ESPurna ("spark" in Catalan) is a custom firmware for ESP8285/ESP8266 based smart switches, lights and sensors.
It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries. It uses the Arduino Core for ESP8266 framework and a number of 3rd party libraries.
[![version](https://img.shields.io/badge/version-1.12.6a-brightgreen.svg)](CHANGELOG.md)
![branch](https://img.shields.io/badge/branch-dev-orange.svg)
[![version](https://img.shields.io/badge/version-1.12.6-brightgreen.svg)](CHANGELOG.md)
[![branch](https://img.shields.io/badge/branch-dev-orange.svg)](https://github.org/xoseperez/espurna/tree/dev/)
[![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=dev)](https://travis-ci.org/xoseperez/espurna) [![travis](https://travis-ci.org/xoseperez/espurna.svg?branch=dev)](https://travis-ci.org/xoseperez/espurna)
[![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/dev.svg)](https://www.codacy.com/app/xoseperez/espurna/dashboard) [![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/dev.svg)](https://www.codacy.com/app/xoseperez/espurna/dashboard)
[![license](https://img.shields.io/github/license/xoseperez/espurna.svg)](LICENSE) [![license](https://img.shields.io/github/license/xoseperez/espurna.svg)](LICENSE)
@ -63,6 +63,7 @@ It uses the Arduino Core for ESP8266 framework and a number of 3rd party librari
* Multiple virtual switches (tested with up to 16) * Multiple virtual switches (tested with up to 16)
* MQTT-to-RF two-way bridge (no need to learn codes) * MQTT-to-RF two-way bridge (no need to learn codes)
* Support for [https://github.com/Portisch/RF-Bridge-EFM8BB1](https://github.com/Portisch/RF-Bridge-EFM8BB1) custom firmware * Support for [https://github.com/Portisch/RF-Bridge-EFM8BB1](https://github.com/Portisch/RF-Bridge-EFM8BB1) custom firmware
* Support for [direct control of the encoder/decoder bypassing the EFM8BB1](https://github.com/xoseperez/espurna/wiki/Hardware-Itead-Sonoff-RF-Bridge---Direct-Hack)
* Support for [different **sensors**](Sensors) * Support for [different **sensors**](Sensors)
* Environment * Environment
* **DHT11 / DHT22 / DHT21 / AM2301 / Itead's SI7021** * **DHT11 / DHT22 / DHT21 / AM2301 / Itead's SI7021**
@ -72,7 +73,8 @@ It uses the Arduino Core for ESP8266 framework and a number of 3rd party librari
* **AM2320** temperature and humidity sensor over I2C * **AM2320** temperature and humidity sensor over I2C
* **Dallas OneWire sensors** like the DS18B20 * **Dallas OneWire sensors** like the DS18B20
* **MHZ19** CO2 sensor * **MHZ19** CO2 sensor
* **PMSX003** dust sensor
* **SenseAir S8** CO2 sensor
* **PMSX003/PMS5003T/ST** dust sensors
* **BH1750** luminosity sensor * **BH1750** luminosity sensor
* **GUVAS12SD** UV sensor * **GUVAS12SD** UV sensor
* Power monitoring * Power monitoring
@ -243,7 +245,7 @@ Here is the list of supported hardware. For more information please refer to the
|**Generic DHT11 v1.0**|**Generic DS18B20 v1.0**|| |**Generic DHT11 v1.0**|**Generic DS18B20 v1.0**||
**Other supported boards:** **Other supported boards:**
*TODO*
IteadStudio Sonoff S31, IteadStudio Sonoff POW R2, Zhilde ZLD-EU55-W, Luani HVIO
## License ## License


+ 2
- 1
code/build.sh View File

@ -26,7 +26,8 @@ if [ $# -eq 0 ]; then
# Hook to build travis test envs # Hook to build travis test envs
if [[ "${TRAVIS_BRANCH}" != "" ]]; then if [[ "${TRAVIS_BRANCH}" != "" ]]; then
if [[ ${TRAVIS_BRANCH} != "master" ]]; then
re='^[0-9]+\.[0-9]+\.[0-9]+$'
if ! [[ ${TRAVIS_BRANCH} =~ $re ]]; then
environments=$travis environments=$travis
fi fi
fi fi


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

@ -88,11 +88,11 @@ ArRequestHandlerFunction _bindAPI(unsigned int apiID) {
} }
// Get response from callback // Get response from callback
char value[API_BUFFER_SIZE];
char value[API_BUFFER_SIZE] = {0};
(api.getFn)(value, API_BUFFER_SIZE); (api.getFn)(value, API_BUFFER_SIZE);
// The response will be a 404 NOT FOUND if the resource is not available // The response will be a 404 NOT FOUND if the resource is not available
if (!value) {
if (0 == value[0]) {
DEBUG_MSG_P(PSTR("[API] Sending 404 response\n")); DEBUG_MSG_P(PSTR("[API] Sending 404 response\n"));
request->send(404); request->send(404);
return; return;


+ 1
- 0
code/espurna/button.ino View File

@ -84,6 +84,7 @@ uint8_t mapEvent(uint8_t event, uint8_t count, uint16_t length) {
} }
if (count == 2) return BUTTON_EVENT_DBLCLICK; if (count == 2) return BUTTON_EVENT_DBLCLICK;
} }
return BUTTON_EVENT_NONE;
} }
void buttonEvent(unsigned int id, unsigned char event) { void buttonEvent(unsigned int id, unsigned char event) {


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

@ -24,12 +24,16 @@
#endif #endif
#include "version.h" #include "version.h"
#include "types.h"
#include "arduino.h" #include "arduino.h"
#include "hardware.h" #include "hardware.h"
#include "defaults.h" #include "defaults.h"
#include "general.h" #include "general.h"
#include "prototypes.h" #include "prototypes.h"
#include "sensors.h" #include "sensors.h"
#include "progmem.h"
#include "dependencies.h"
#include "debug.h"
#ifdef USE_CORE_VERSION_H #ifdef USE_CORE_VERSION_H
#include "core_version.h" #include "core_version.h"


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

@ -19,6 +19,7 @@
//#define ITEAD_S20 //#define ITEAD_S20
//#define ITEAD_SONOFF_TOUCH //#define ITEAD_SONOFF_TOUCH
//#define ITEAD_SONOFF_POW //#define ITEAD_SONOFF_POW
//#define ITEAD_SONOFF_POW_R2
//#define ITEAD_SONOFF_DUAL //#define ITEAD_SONOFF_DUAL
//#define ITEAD_SONOFF_DUAL_R2 //#define ITEAD_SONOFF_DUAL_R2
//#define ITEAD_SONOFF_4CH //#define ITEAD_SONOFF_4CH
@ -77,6 +78,9 @@
//#define GENERIC_ESP01S_DHT11_V10 //#define GENERIC_ESP01S_DHT11_V10
//#define GENERIC_ESP01S_DS18B20_V10 //#define GENERIC_ESP01S_DS18B20_V10
//#define HELTEC_TOUCHRELAY //#define HELTEC_TOUCHRELAY
//#define ZHILDE_EU44_W
//#define LUANI_HVIO
//#define ALLNET_4DUINO_IOT_WLAN_RELAIS
//#define PILOTAK_ESP_DIN_V1 //#define PILOTAK_ESP_DIN_V1
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
@ -88,6 +92,7 @@
//#define DEBUG_SERIAL_SUPPORT 0 //#define DEBUG_SERIAL_SUPPORT 0
//#define DEBUG_TELNET_SUPPORT 0 //#define DEBUG_TELNET_SUPPORT 0
//#define DEBUG_UDP_SUPPORT 1 //#define DEBUG_UDP_SUPPORT 1
//#define DEBUG_WEB_SUPPORT 0
//#define DOMOTICZ_SUPPORT 0 //#define DOMOTICZ_SUPPORT 0
//#define HOMEASSISTANT_SUPPORT 0 //#define HOMEASSISTANT_SUPPORT 0
//#define I2C_SUPPORT 1 //#define I2C_SUPPORT 1
@ -118,6 +123,7 @@
//#define ANALOG_SUPPORT 1 //#define ANALOG_SUPPORT 1
//#define BH1750_SUPPORT 1 //#define BH1750_SUPPORT 1
//#define BMX280_SUPPORT 1 //#define BMX280_SUPPORT 1
//#define CSE7766_SUPPORT 1
//#define DALLAS_SUPPORT 1 //#define DALLAS_SUPPORT 1
//#define DHT_SUPPORT 1 //#define DHT_SUPPORT 1
//#define DIGITAL_SUPPORT 1 //#define DIGITAL_SUPPORT 1
@ -127,10 +133,12 @@
//#define EMON_ANALOG_SUPPORT 1 //#define EMON_ANALOG_SUPPORT 1
//#define EVENTS_SUPPORT 1 //#define EVENTS_SUPPORT 1
//#define GUVAS12SD_SUPPORT 1 //#define GUVAS12SD_SUPPORT 1
//#define HCSR04_SUPPORT 1
//#define HLW8012_SUPPORT 1 //#define HLW8012_SUPPORT 1
//#define MHZ19_SUPPORT 1 //#define MHZ19_SUPPORT 1
//#define PMSX003_SUPPORT 1 //#define PMSX003_SUPPORT 1
//#define PZEM004T_SUPPORT 1 //#define PZEM004T_SUPPORT 1
//#define SHT3X_I2C_SUPPORT 1 //#define SHT3X_I2C_SUPPORT 1
//#define SI7021_SUPPORT 1 //#define SI7021_SUPPORT 1
//#define TMP3X_SUPPORT 1
//#define V9261F_SUPPORT 1 //#define V9261F_SUPPORT 1

+ 17
- 0
code/espurna/config/debug.h View File

@ -0,0 +1,17 @@
#pragma once
// -----------------------------------------------------------------------------
// Debug
// -----------------------------------------------------------------------------
#define DEBUG_SUPPORT DEBUG_SERIAL_SUPPORT || DEBUG_UDP_SUPPORT || DEBUG_TELNET_SUPPORT || DEBUG_WEB_SUPPORT
#if DEBUG_SUPPORT
#define DEBUG_MSG(...) debugSend(__VA_ARGS__)
#define DEBUG_MSG_P(...) debugSend_P(__VA_ARGS__)
#endif
#ifndef DEBUG_MSG
#define DEBUG_MSG(...)
#define DEBUG_MSG_P(...)
#endif

+ 0
- 8
code/espurna/config/defaults.h View File

@ -404,14 +404,6 @@
#define HOSTNAME "" #define HOSTNAME ""
#endif #endif
// Needed for ESP8285 boards under Windows using PlatformIO (?)
#ifndef BUTTON_PUSHBUTTON
#define BUTTON_PUSHBUTTON 0
#define BUTTON_SWITCH 1
#define BUTTON_DEFAULT_HIGH 2
#define BUTTON_SET_PULLUP 4
#endif
// Relay providers // Relay providers
#ifndef RELAY_PROVIDER #ifndef RELAY_PROVIDER
#define RELAY_PROVIDER RELAY_PROVIDER_RELAY #define RELAY_PROVIDER RELAY_PROVIDER_RELAY


+ 50
- 0
code/espurna/config/dependencies.h View File

@ -0,0 +1,50 @@
#pragma once
//------------------------------------------------------------------------------
// Do not change this file unless you know what you are doing
// Configuration settings are in the general.h file
//------------------------------------------------------------------------------
#if DEBUG_TELNET_SUPPORT
#undef TELNET_SUPPORT
#define TELNET_SUPPORT 1
#endif
#if not WEB_SUPPORT
#undef DEBUG_WEB_SUPPORT
#define DEBUG_WEB_SUPPORT 0
#endif
#if not WEB_SUPPORT
#undef SSDP_SUPPORT
#define SSDP_SUPPORT 0 // SSDP support requires web support
#endif
#if UART_MQTT_SUPPORT
#define MQTT_SUPPORT 1
#undef TERMINAL_SUPPORT
#define TERMINAL_SUPPORT 0
#undef DEBUG_SERIAL_SUPPORT
#define DEBUG_SERIAL_SUPPORT 0
#endif
#if DOMOTICZ_SUPPORT
#undef MQTT_SUPPORT
#define MQTT_SUPPORT 1 // If Domoticz enabled enable MQTT
#endif
#if HOMEASSISTANT_SUPPORT
#undef MQTT_SUPPORT
#define MQTT_SUPPORT 1 // If Home Assistant enabled enable MQTT
#endif
#ifndef ASYNC_TCP_SSL_ENABLED
#if THINGSPEAK_USE_SSL && THINGSPEAK_USE_ASYNC
#undef THINGSPEAK_SUPPORT // Thingspeak in ASYNC mode requires ASYNC_TCP_SSL_ENABLED
#endif
#endif
#if SCHEDULER_SUPPORT
#undef NTP_SUPPORT
#define NTP_SUPPORT 1 // Scheduler needs NTP
#endif

+ 212
- 341
code/espurna/config/general.h
File diff suppressed because it is too large
View File


+ 208
- 16
code/espurna/config/hardware.h View File

@ -379,6 +379,31 @@
#define HLW8012_CF1_PIN 13 #define HLW8012_CF1_PIN 13
#define HLW8012_CF_PIN 14 #define HLW8012_CF_PIN 14
#elif defined(ITEAD_SONOFF_POW_R2)
// Info
#define MANUFACTURER "ITEAD"
#define DEVICE "SONOFF_POW_R2"
// Buttons
#define BUTTON1_PIN 0
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#define BUTTON1_RELAY 1
// Relays
#define RELAY1_PIN 12
#define RELAY1_TYPE RELAY_TYPE_NORMAL
// LEDs
#define LED1_PIN 15
#define LED1_PIN_INVERSE 0
// CSE7766
#ifndef CSE7766_SUPPORT
#define CSE7766_SUPPORT 1
#endif
#define CSE7766_PIN 1
#elif defined(ITEAD_SONOFF_DUAL) #elif defined(ITEAD_SONOFF_DUAL)
// Info // Info
@ -388,7 +413,6 @@
#define RELAY_PROVIDER RELAY_PROVIDER_DUAL #define RELAY_PROVIDER RELAY_PROVIDER_DUAL
#define DUMMY_RELAY_COUNT 2 #define DUMMY_RELAY_COUNT 2
#define DEBUG_SERIAL_SUPPORT 0 #define DEBUG_SERIAL_SUPPORT 0
#define TERMINAL_SUPPORT 0
// Buttons // Buttons
#define BUTTON3_RELAY 1 #define BUTTON3_RELAY 1
@ -600,17 +624,13 @@
// Info // Info
#define MANUFACTURER "ITEAD" #define MANUFACTURER "ITEAD"
#define DEVICE "SONOFF_RFBRIDGE" #define DEVICE "SONOFF_RFBRIDGE"
#define SERIAL_BAUDRATE 19200
#define RELAY_PROVIDER RELAY_PROVIDER_RFBRIDGE #define RELAY_PROVIDER RELAY_PROVIDER_RFBRIDGE
// Number of virtual switches
#ifndef DUMMY_RELAY_COUNT #ifndef DUMMY_RELAY_COUNT
#define DUMMY_RELAY_COUNT 8 #define DUMMY_RELAY_COUNT 8
#endif #endif
// Remove UART noise on serial line
#define TERMINAL_SUPPORT 0
#define DEBUG_SERIAL_SUPPORT 0
// Buttons // Buttons
#define BUTTON1_PIN 0 #define BUTTON1_PIN 0
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH #define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
@ -619,6 +639,28 @@
#define LED1_PIN 13 #define LED1_PIN 13
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
// RFB Direct hack thanks to @wildwiz
// https://github.com/xoseperez/espurna/wiki/Hardware-Itead-Sonoff-RF-Bridge---Direct-Hack
#ifndef RFB_DIRECT
#define RFB_DIRECT 0
#endif
#ifndef RFB_RX_PIN
#define RFB_RX_PIN 4 // GPIO for RX when RFB_DIRECT
#endif
#ifndef RFB_TX_PIN
#define RFB_TX_PIN 5 // GPIO for TX when RFB_DIRECT
#endif
// When using un-modified harware, ESPurna communicates with the secondary
// MCU EFM8BB1 via UART at 19200 bps so we need to change the speed of
// the port and remove UART noise on serial line
#if not RFB_DIRECT
#define SERIAL_BAUDRATE 19200
#define DEBUG_SERIAL_SUPPORT 0
#endif
#elif defined(ITEAD_SONOFF_B1) #elif defined(ITEAD_SONOFF_B1)
// Info // Info
@ -789,7 +831,6 @@
#define LED1_PIN_INVERSE 1 #define LED1_PIN_INVERSE 1
// Disable UART noise // Disable UART noise
#define TERMINAL_SUPPORT 0
#define DEBUG_SERIAL_SUPPORT 0 #define DEBUG_SERIAL_SUPPORT 0
// CSE7766 // CSE7766
@ -1271,15 +1312,13 @@
#define DUMMY_RELAY_COUNT 1 #define DUMMY_RELAY_COUNT 1
// Light // Light
#define LIGHT_CHANNELS 4
#define LIGHT_CHANNELS 3
#define LIGHT_CH1_PIN 5 // RED #define LIGHT_CH1_PIN 5 // RED
#define LIGHT_CH2_PIN 12 // GREEN #define LIGHT_CH2_PIN 12 // GREEN
#define LIGHT_CH3_PIN 13 // BLUE #define LIGHT_CH3_PIN 13 // BLUE
#define LIGHT_CH4_PIN 14 // WHITE1
#define LIGHT_CH1_INVERSE 0 #define LIGHT_CH1_INVERSE 0
#define LIGHT_CH2_INVERSE 0 #define LIGHT_CH2_INVERSE 0
#define LIGHT_CH3_INVERSE 0 #define LIGHT_CH3_INVERSE 0
#define LIGHT_CH4_INVERSE 0
#elif defined(ARILUX_AL_LC02) #elif defined(ARILUX_AL_LC02)
@ -1554,7 +1593,6 @@
#define RELAY_PROVIDER RELAY_PROVIDER_STM #define RELAY_PROVIDER RELAY_PROVIDER_STM
// Remove UART noise on serial line // Remove UART noise on serial line
#define TERMINAL_SUPPORT 0
#define DEBUG_SERIAL_SUPPORT 0 #define DEBUG_SERIAL_SUPPORT 0
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1647,7 +1685,7 @@
#define MANUFACTURER "MAXCIO" #define MANUFACTURER "MAXCIO"
#define DEVICE "WUS002S" #define DEVICE "WUS002S"
// Buttons
// Buttons
#define BUTTON1_PIN 2 #define BUTTON1_PIN 2
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH #define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#define BUTTON1_RELAY 1 #define BUTTON1_RELAY 1
@ -1866,6 +1904,7 @@
// LEDs // LEDs
#define LED1_PIN 2 #define LED1_PIN 2
#define LED1_PIN_INVERSE 0
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1962,6 +2001,117 @@
#define RELAY1_PIN 12 #define RELAY1_PIN 12
#define RELAY1_TYPE RELAY_TYPE_NORMAL #define RELAY1_TYPE RELAY_TYPE_NORMAL
// -----------------------------------------------------------------------------
// Zhilde ZLD-EU44-W
// http://www.zhilde.com/product/60705150109-805652505/EU_WiFi_Surge_Protector_Extension_Socket_4_Outlets_works_with_Amazon_Echo_Smart_Power_Strip.html
// -----------------------------------------------------------------------------
#elif defined(ZHILDE_EU44_W)
// Info
#define MANUFACTURER "ZHILDE"
#define DEVICE "EU44_W"
// Based on the reporter, this product uses GPIO1 and 3 for the button
// and onboard LED, so hardware serial should be disabled...
#define DEBUG_SERIAL_SUPPORT 0
// Buttons
#define BUTTON1_PIN 3
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Relays
#define RELAY1_PIN 5
#define RELAY2_PIN 4
#define RELAY3_PIN 12
#define RELAY4_PIN 13
#define RELAY5_PIN 14
#define RELAY1_TYPE RELAY_TYPE_NORMAL
#define RELAY2_TYPE RELAY_TYPE_NORMAL
#define RELAY3_TYPE RELAY_TYPE_NORMAL
#define RELAY4_TYPE RELAY_TYPE_NORMAL
#define RELAY5_TYPE RELAY_TYPE_NORMAL
// LEDs
#define LED1_PIN 1
#define LED1_PIN_INVERSE 1
// -----------------------------------------------------------------------------
// Allnet 4duino ESP8266-UP-Relais
// http://www.allnet.de/de/allnet-brand/produkte/neuheiten/p/allnet-4duino-iot-wlan-relais-unterputz-esp8266-up-relais/
// https://shop.allnet.de/fileadmin/transfer/products/148814.pdf
// -----------------------------------------------------------------------------
#elif defined(ALLNET_4DUINO_IOT_WLAN_RELAIS)
// Info
#define MANUFACTURER "ALLNET"
#define DEVICE "4DUINO_IOT_WLAN_RELAIS"
// Relays
#define RELAY1_PIN 14
#define RELAY1_RESET_PIN 12
#define RELAY1_TYPE RELAY_TYPE_LATCHED
// LEDs
#define LED1_PIN 0
#define LED1_PIN_INVERSE 1
// Buttons
//#define BUTTON1_PIN 0
//#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Using pins labelled as SDA & SCL as buttons
#define BUTTON2_PIN 4
#define BUTTON2_MODE BUTTON_PUSHBUTTON
#define BUTTON2_PRESS BUTTON_MODE_TOGGLE
#define BUTTON2_CLICK BUTTON_MODE_NONE
#define BUTTON2_DBLCLICK BUTTON_MODE_NONE
#define BUTTON2_LNGCLICK BUTTON_MODE_NONE
#define BUTTON2_LNGLNGCLICK BUTTON_MODE_NONE
#define BUTTON3_PIN 5
#define BUTTON3_MODE BUTTON_PUSHBUTTON
// Using pins labelled as SDA & SCL for I2C
//#define I2C_SDA_PIN 4
//#define I2C_SCL_PIN 5
// -----------------------------------------------------------------------------
// Luani HVIO
// https://luani.de/projekte/esp8266-hvio/
// https://luani.de/blog/esp8266-230v-io-modul/
// -----------------------------------------------------------------------------
#elif defined(LUANI_HVIO)
// Info
#define MANUFACTURER "LUANI"
#define DEVICE "HVIO"
// Buttons
#define BUTTON1_PIN 12
#define BUTTON1_RELAY 1
#define BUTTON1_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
#define BUTTON1_DBLCLICK BUTTON_MODE_NONE
#define BUTTON2_PIN 13
#define BUTTON2_RELAY 2
#define BUTTON2_MODE BUTTON_PUSHBUTTON | BUTTON_DEFAULT_HIGH
// Relays
#define RELAY1_PIN 4
#define RELAY2_PIN 5
#define RELAY1_TYPE RELAY_TYPE_NORMAL
#define RELAY2_TYPE RELAY_TYPE_NORMAL
// LEDs
#define LED1_PIN 15
#define LED1_PIN_INVERSE 0
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// TEST boards (do not use!!) // TEST boards (do not use!!)
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -1996,6 +2146,7 @@
// We got silk sensor, velvet sensor, naugahyde sensor. We even got horse sensor, dog sensor, chicken sensor. // We got silk sensor, velvet sensor, naugahyde sensor. We even got horse sensor, dog sensor, chicken sensor.
// C'mon, you want sensor, come on in sensor lovers! // C'mon, you want sensor, come on in sensor lovers!
// If we dont got it, you don't want it! // If we dont got it, you don't want it!
#define AM2320_SUPPORT 1
#define BH1750_SUPPORT 1 #define BH1750_SUPPORT 1
#define BMX280_SUPPORT 1 #define BMX280_SUPPORT 1
#define SHT3X_I2C_SUPPORT 1 #define SHT3X_I2C_SUPPORT 1
@ -2041,11 +2192,11 @@
#define MANUFACTURER "TravisCI" #define MANUFACTURER "TravisCI"
#define DEVICE "Virtual board 02" #define DEVICE "Virtual board 02"
// A bit of DHT - pin 1
#ifndef DHT_SUPPORT
#define DHT_SUPPORT 1
// A bit of CSE7766 - pin 1
#ifndef CSE7766_SUPPORT
#define CSE7766_SUPPORT 1
#endif #endif
#define DHT_PIN 1
#define CSE7766_PIN 1
// Relay type dual - pins 2,3 // Relay type dual - pins 2,3
#define RELAY_PROVIDER RELAY_PROVIDER_DUAL #define RELAY_PROVIDER RELAY_PROVIDER_DUAL
@ -2059,6 +2210,42 @@
#define IR_PIN 4 #define IR_PIN 4
#define IR_BUTTON_SET 1 #define IR_BUTTON_SET 1
// A bit of DHT - pin 5
#ifndef DHT_SUPPORT
#define DHT_SUPPORT 1
#endif
#define DHT_PIN 5
// A bit of TMP3X (analog)
#define TMP3X_SUPPORT 1
// A bit of EVENTS - pin 10
#define EVENTS_SUPPORT 1
#define EVENTS_PIN 6
// HC-RS04
#define HCSR04_SUPPORT 1
#define HCSR04_TRIGGER 7
#define HCSR04_ECHO 8
// MHZ19
#define MHZ19_SUPPORT 1
#define MHZ19_RX_PIN 9
#define MHZ19_TX_PIN 10
// PZEM004T
#define PZEM004T_SUPPORT 0 // not working?
#define PZEM004T_RX_PIN 11
#define PZEM004T_TX_PIN 12
// V9261F
#define V9261F_SUPPORT 1
#define V9261F_PIN 13
// GUVAS12SD
#define GUVAS12SD_SUPPORT 1
#define GUVAS12SD_PIN 14
#elif defined(TRAVIS03) #elif defined(TRAVIS03)
// Relay provider light/my92XX // Relay provider light/my92XX
@ -2077,6 +2264,11 @@
#define MY92XX_COMMAND MY92XX_COMMAND_DEFAULT #define MY92XX_COMMAND MY92XX_COMMAND_DEFAULT
#define MY92XX_MAPPING 4, 3, 5, 0, 1 #define MY92XX_MAPPING 4, 3, 5, 0, 1
// A bit of Analog EMON (analog)
#ifndef EMON_ANALOG_SUPPORT
#define EMON_ANALOG_SUPPORT 1
#endif
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------


+ 106
- 0
code/espurna/config/progmem.h View File

@ -0,0 +1,106 @@
//--------------------------------------------------------------------------------
// PROGMEM definitions
//--------------------------------------------------------------------------------
//--------------------------------------------------------------------------------
// Reset reasons
//--------------------------------------------------------------------------------
PROGMEM const char custom_reset_hardware[] = "Hardware button";
PROGMEM const char custom_reset_web[] = "Reboot from web interface";
PROGMEM const char custom_reset_terminal[] = "Reboot from terminal";
PROGMEM const char custom_reset_mqtt[] = "Reboot from MQTT";
PROGMEM const char custom_reset_rpc[] = "Reboot from RPC";
PROGMEM const char custom_reset_ota[] = "Reboot after successful OTA update";
PROGMEM const char custom_reset_http[] = "Reboot from HTTP";
PROGMEM const char custom_reset_nofuss[] = "Reboot after successful NoFUSS update";
PROGMEM const char custom_reset_upgrade[] = "Reboot after successful web update";
PROGMEM const char custom_reset_factory[] = "Factory reset";
PROGMEM const char* const custom_reset_string[] = {
custom_reset_hardware, custom_reset_web, custom_reset_terminal,
custom_reset_mqtt, custom_reset_rpc, custom_reset_ota,
custom_reset_http, custom_reset_nofuss, custom_reset_upgrade,
custom_reset_factory
};
//--------------------------------------------------------------------------------
// Sensors
//--------------------------------------------------------------------------------
#if SENSOR_SUPPORT
PROGMEM const unsigned char magnitude_decimals[] = {
0,
1, 0, 2,
3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0, 3, 3
};
PROGMEM const char magnitude_unknown_topic[] = "unknown";
PROGMEM const char magnitude_temperature_topic[] = "temperature";
PROGMEM const char magnitude_humidity_topic[] = "humidity";
PROGMEM const char magnitude_pressure_topic[] = "pressure";
PROGMEM const char magnitude_current_topic[] = "current";
PROGMEM const char magnitude_voltage_topic[] = "voltage";
PROGMEM const char magnitude_active_power_topic[] = "power";
PROGMEM const char magnitude_apparent_power_topic[] = "apparent";
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_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 magnitude_uv_topic[] = "uv";
PROGMEM const char magnitude_distance_topic[] = "distance";
PROGMEM const char magnitude_hcho_topic[] = "hcho";
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_analog_topic, magnitude_digital_topic, magnitude_events_topic,
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_co2_topic, magnitude_lux_topic, magnitude_uv_topic,
magnitude_distance_topic, magnitude_hcho_topic
};
PROGMEM const char magnitude_empty[] = "";
PROGMEM const char magnitude_celsius[] = "°C";
PROGMEM const char magnitude_fahrenheit[] = "°F";
PROGMEM const char magnitude_percentage[] = "%";
PROGMEM const char magnitude_hectopascals[] = "hPa";
PROGMEM const char magnitude_amperes[] = "A";
PROGMEM const char magnitude_volts[] = "V";
PROGMEM const char magnitude_watts[] = "W";
PROGMEM const char magnitude_kw[] = "kW";
PROGMEM const char magnitude_joules[] = "J";
PROGMEM const char magnitude_kwh[] = "kWh";
PROGMEM const char magnitude_ugm3[] = "µg/m³";
PROGMEM const char magnitude_ppm[] = "ppm";
PROGMEM const char magnitude_lux[] = "lux";
PROGMEM const char magnitude_uv[] = "uv";
PROGMEM const char magnitude_distance[] = "m";
PROGMEM const char magnitude_mgm3[] = "mg/m³";
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_empty, magnitude_empty, magnitude_empty,
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_ppm, magnitude_lux, magnitude_uv,
magnitude_distance, magnitude_mgm3
};
#endif

+ 5
- 1
code/espurna/config/prototypes.h View File

@ -63,7 +63,7 @@ template<typename T> bool setSetting(const String& key, T value);
template<typename T> bool setSetting(const String& key, unsigned int index, T value); template<typename T> bool setSetting(const String& key, unsigned int index, T value);
template<typename T> String getSetting(const String& key, T defaultValue); template<typename T> String getSetting(const String& key, T defaultValue);
template<typename T> String getSetting(const String& key, unsigned int index, T defaultValue); template<typename T> String getSetting(const String& key, unsigned int index, T defaultValue);
bool settingsGetJson(JsonObject& data);
void settingsGetJson(JsonObject& data);
bool settingsRestoreJson(JsonObject& data); bool settingsRestoreJson(JsonObject& data);
void settingsRegisterCommand(const String& name, void (*call)(Embedis*)); void settingsRegisterCommand(const String& name, void (*call)(Embedis*));
void settingsInject(void *data, size_t len); void settingsInject(void *data, size_t len);
@ -77,6 +77,7 @@ bool i2cGetLock(unsigned char address);
bool i2cReleaseLock(unsigned char address); bool i2cReleaseLock(unsigned char address);
unsigned char i2cFindAndLock(size_t size, unsigned char * addresses); unsigned char i2cFindAndLock(size_t size, unsigned char * addresses);
void i2c_wakeup(uint8_t address);
uint8_t i2c_write_buffer(uint8_t address, uint8_t * buffer, size_t len); uint8_t i2c_write_buffer(uint8_t address, uint8_t * buffer, size_t len);
uint8_t i2c_write_uint8(uint8_t address, uint8_t value); uint8_t i2c_write_uint8(uint8_t address, uint8_t value);
uint8_t i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value); uint8_t i2c_write_uint8(uint8_t address, uint8_t reg, uint8_t value);
@ -116,3 +117,6 @@ template<typename T> void domoticzSend(const char * key, T nvalue, const char *
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
char * ltrim(char * s); char * ltrim(char * s);
void nice_delay(unsigned long ms); void nice_delay(unsigned long ms);
#define ARRAYINIT(type, name, ...) \
type name[] = {__VA_ARGS__};

+ 105
- 265
code/espurna/config/sensors.h View File

@ -36,40 +36,9 @@
#define HUMIDITY_MIN_CHANGE 0 // Minimum humidity change to report #define HUMIDITY_MIN_CHANGE 0 // Minimum humidity change to report
#endif #endif
// American Society of Heating, Refrigerating and Air-Conditioning Engineers suggests a range of 45% - 55% humidity to manage health effects and illnesses.
// Comfortable: 30% - 60%
// Recommended: 45% - 55%
// High : 55% - 80%
#define HUMIDITY_NORMAL 0 // > %30
#define HUMIDITY_COMFORTABLE 1 // > %45
#define HUMIDITY_DRY 2 // < %30
#define HUMIDITY_WET 3 // > %70
// United States Environmental Protection Agency - UV Index Scale
// One UV Index unit is equivalent to 25 milliWatts per square meter.
#define UV_INDEX_LOW 0 // 0 to 2 means low danger from the sun's UV rays for the average person.
#define UV_INDEX_MODERATE 1 // 3 to 5 means moderate risk of harm from unprotected sun exposure.
#define UV_INDEX_HIGH 2 // 6 to 7 means high risk of harm from unprotected sun exposure. Protection against skin and eye damage is needed.
#define UV_INDEX_VERY_HIGH 3 // 8 to 10 means very high risk of harm from unprotected sun exposure.
// Take extra precautions because unprotected skin and eyes will be damaged and can burn quickly.
#define UV_INDEX_EXTREME 4 // 11 or more means extreme risk of harm from unprotected sun exposure.
// Take all precautions because unprotected skin and eyes can burn in minutes.
#define SENSOR_PUBLISH_ADDRESSES 0 // Publish sensor addresses #define SENSOR_PUBLISH_ADDRESSES 0 // Publish sensor addresses
#define SENSOR_ADDRESS_TOPIC "address" // Topic to publish sensor addresses #define SENSOR_ADDRESS_TOPIC "address" // Topic to publish sensor addresses
//------------------------------------------------------------------------------
// UNITS
//------------------------------------------------------------------------------
#define POWER_WATTS 0
#define POWER_KILOWATTS 1
#define ENERGY_JOULES 0
#define ENERGY_KWH 1
#define TMP_CELSIUS 0
#define TMP_FAHRENHEIT 1
#ifndef SENSOR_TEMPERATURE_UNITS #ifndef SENSOR_TEMPERATURE_UNITS
#define SENSOR_TEMPERATURE_UNITS TMP_CELSIUS // Temperature units (TMP_CELSIUS | TMP_FAHRENHEIT) #define SENSOR_TEMPERATURE_UNITS TMP_CELSIUS // Temperature units (TMP_CELSIUS | TMP_FAHRENHEIT)
@ -83,68 +52,24 @@
#define SENSOR_POWER_UNITS POWER_WATTS // Power units (POWER_WATTS | POWER_KILOWATTS) #define SENSOR_POWER_UNITS POWER_WATTS // Power units (POWER_WATTS | POWER_KILOWATTS)
#endif #endif
//--------------------------------------------------------------------------------
// Sensor ID
// These should remain over time, do not modify them, only add new ones at the end
//--------------------------------------------------------------------------------
#define SENSOR_DHTXX_ID 0x01
#define SENSOR_DALLAS_ID 0x02
#define SENSOR_EMON_ANALOG_ID 0x03
#define SENSOR_EMON_ADC121_ID 0x04
#define SENSOR_EMON_ADS1X15_ID 0x05
#define SENSOR_HLW8012_ID 0x06
#define SENSOR_V9261F_ID 0x07
#define SENSOR_ECH1560_ID 0x08
#define SENSOR_ANALOG_ID 0x09
#define SENSOR_DIGITAL_ID 0x10
#define SENSOR_EVENTS_ID 0x11
#define SENSOR_PMSX003_ID 0x12
#define SENSOR_BMX280_ID 0x13
#define SENSOR_MHZ19_ID 0x14
#define SENSOR_SI7021_ID 0x15
#define SENSOR_SHT3X_I2C_ID 0x16
#define SENSOR_BH1750_ID 0x17
#define SENSOR_PZEM004T_ID 0x18
#define SENSOR_AM2320_ID 0x19
#define SENSOR_GUVAS12SD_ID 0x20
#define SENSOR_CSE7766_ID 0x21
#define SENSOR_TMP3X_ID 0x22
#define SENSOR_HCSR04_ID 0x23
//--------------------------------------------------------------------------------
// Magnitudes
//--------------------------------------------------------------------------------
#define MAGNITUDE_NONE 0
#define MAGNITUDE_TEMPERATURE 1
#define MAGNITUDE_HUMIDITY 2
#define MAGNITUDE_PRESSURE 3
#define MAGNITUDE_CURRENT 4
#define MAGNITUDE_VOLTAGE 5
#define MAGNITUDE_POWER_ACTIVE 6
#define MAGNITUDE_POWER_APPARENT 7
#define MAGNITUDE_POWER_REACTIVE 8
#define MAGNITUDE_POWER_FACTOR 9
#define MAGNITUDE_ENERGY 10
#define MAGNITUDE_ENERGY_DELTA 11
#define MAGNITUDE_ANALOG 12
#define MAGNITUDE_DIGITAL 13
#define MAGNITUDE_EVENTS 14
#define MAGNITUDE_PM1dot0 15
#define MAGNITUDE_PM2dot5 16
#define MAGNITUDE_PM10 17
#define MAGNITUDE_CO2 18
#define MAGNITUDE_LUX 19
#define MAGNITUDE_UV 20
#define MAGNITUDE_DISTANCE 21
#define MAGNITUDE_MAX 22
// ============================================================================= // =============================================================================
// Specific data for each sensor // Specific data for each sensor
// ============================================================================= // =============================================================================
//------------------------------------------------------------------------------
// AM2320 Humidity & Temperature sensor over I2C
// Enable support by passing AM2320_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef AM2320_SUPPORT
#define AM2320_SUPPORT 0
#endif
#ifndef AM2320_ADDRESS
#define AM2320_ADDRESS 0x00 // 0x00 means auto
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Analog sensor // Analog sensor
// Enable support by passing ANALOG_SUPPORT=1 build flag // Enable support by passing ANALOG_SUPPORT=1 build flag
@ -154,11 +79,6 @@
#define ANALOG_SUPPORT 0 #define ANALOG_SUPPORT 0
#endif #endif
#if ANALOG_SUPPORT
#undef ADC_VCC_ENABLED
#define ADC_VCC_ENABLED 0
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// BH1750 // BH1750
// Enable support by passing BH1750_SUPPORT=1 build flag // Enable support by passing BH1750_SUPPORT=1 build flag
@ -175,11 +95,6 @@
#define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE #define BH1750_MODE BH1750_CONTINUOUS_HIGH_RES_MODE
#if BH1750_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// BME280/BMP280 // BME280/BMP280
// Enable support by passing BMX280_SUPPORT=1 build flag // Enable support by passing BMX280_SUPPORT=1 build flag
@ -202,11 +117,6 @@
#define BMX280_HUMIDITY 1 // Oversampling for humidity (set to 0 to disable magnitude, only for BME280) #define BMX280_HUMIDITY 1 // Oversampling for humidity (set to 0 to disable magnitude, only for BME280)
#define BMX280_PRESSURE 1 // Oversampling for pressure (set to 0 to disable magnitude) #define BMX280_PRESSURE 1 // Oversampling for pressure (set to 0 to disable magnitude)
#if BMX280_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Dallas OneWire temperature sensors // Dallas OneWire temperature sensors
// Enable support by passing DALLAS_SUPPORT=1 build flag // Enable support by passing DALLAS_SUPPORT=1 build flag
@ -331,11 +241,6 @@
#define EMON_ADC121_I2C_ADDRESS 0x00 // 0x00 means auto #define EMON_ADC121_I2C_ADDRESS 0x00 // 0x00 means auto
#if EMON_ADC121_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Energy Monitor based on ADS1X15 // Energy Monitor based on ADS1X15
// Enable support by passing EMON_ADS1X15_SUPPORT=1 build flag // Enable support by passing EMON_ADS1X15_SUPPORT=1 build flag
@ -350,11 +255,6 @@
#define EMON_ADS1X15_GAIN ADS1X15_REG_CONFIG_PGA_4_096V #define EMON_ADS1X15_GAIN ADS1X15_REG_CONFIG_PGA_4_096V
#define EMON_ADS1X15_MASK 0x0F // A0=1 A1=2 A2=4 A3=8 #define EMON_ADS1X15_MASK 0x0F // A0=1 A1=2 A2=4 A3=8
#if EMON_ADS1X15_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Energy Monitor based on interval analog GPIO // Energy Monitor based on interval analog GPIO
// Enable support by passing EMON_ANALOG_SUPPORT=1 build flag // Enable support by passing EMON_ANALOG_SUPPORT=1 build flag
@ -364,11 +264,6 @@
#define EMON_ANALOG_SUPPORT 0 // Do not build support by default #define EMON_ANALOG_SUPPORT 0 // Do not build support by default
#endif #endif
#if EMON_ANALOG_SUPPORT
#undef ADC_VCC_ENABLED
#define ADC_VCC_ENABLED 0
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Counter sensor // Counter sensor
// Enable support by passing EVENTS_SUPPORT=1 build flag // Enable support by passing EVENTS_SUPPORT=1 build flag
@ -392,6 +287,19 @@
#define EVENTS_DEBOUNCE 50 // Do not register events within less than 10 millis #define EVENTS_DEBOUNCE 50 // Do not register events within less than 10 millis
//------------------------------------------------------------------------------
// GUVAS12SD UV Sensor (analog)
// Enable support by passing GUVAS12SD_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef GUVAS12SD_SUPPORT
#define GUVAS12SD_SUPPORT 0
#endif
#ifndef GUVAS12SD_PIN
#define GUVAS12SD_PIN 14
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// HC-SR04 // HC-SR04
// Enable support by passing HCSR04_SUPPORT=1 build flag // Enable support by passing HCSR04_SUPPORT=1 build flag
@ -457,11 +365,33 @@
#define MHZ19_SUPPORT 0 #define MHZ19_SUPPORT 0
#endif #endif
#ifndef MHZ19_RX_PIN
#define MHZ19_RX_PIN 13 #define MHZ19_RX_PIN 13
#endif
#ifndef MHZ19_TX_PIN
#define MHZ19_TX_PIN 15 #define MHZ19_TX_PIN 15
#endif
//------------------------------------------------------------------------------
// SenseAir CO2 sensor
// Enable support by passing SENSEAIR_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef SENSEAIR_SUPPORT
#define SENSEAIR_SUPPORT 0
#endif
#ifndef SENSEAIR_RX_PIN
#define SENSEAIR_RX_PIN 0
#endif
#ifndef SENSEAIR_TX_PIN
#define SENSEAIR_TX_PIN 2
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Particle Monitor based on Plantower PMSX003
// Particle Monitor based on Plantower PMS
// Enable support by passing PMSX003_SUPPORT=1 build flag // Enable support by passing PMSX003_SUPPORT=1 build flag
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -469,8 +399,24 @@
#define PMSX003_SUPPORT 0 #define PMSX003_SUPPORT 0
#endif #endif
#ifndef PMS_TYPE
#define PMS_TYPE PMS_TYPE_X003
#endif
// You can enable smart sleep (read 6-times then sleep on 24-reading-cycles) to extend PMS sensor's life.
// Otherwise the default lifetime of PMS sensor is about 8000-hours/1-years.
// The PMS's fan will stop working on sleeping cycle, and will wake up on reading cycle.
#ifndef PMS_SMART_SLEEP
#define PMS_SMART_SLEEP 0
#endif
#ifndef PMS_RX_PIN
#define PMS_RX_PIN 13 #define PMS_RX_PIN 13
#endif
#ifndef PMS_TX_PIN
#define PMS_TX_PIN 15 #define PMS_TX_PIN 15
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// PZEM004T based power monitor // PZEM004T based power monitor
@ -497,7 +443,6 @@
#define PZEM004T_HW_PORT Serial1 // Hardware serial port (if PZEM004T_USE_SOFT == 0) #define PZEM004T_HW_PORT Serial1 // Hardware serial port (if PZEM004T_USE_SOFT == 0)
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// SHT3X I2C (Wemos) temperature & humidity sensor // SHT3X I2C (Wemos) temperature & humidity sensor
// Enable support by passing SHT3X_SUPPORT=1 build flag // Enable support by passing SHT3X_SUPPORT=1 build flag
@ -511,11 +456,6 @@
#define SHT3X_I2C_ADDRESS 0x00 // 0x00 means auto #define SHT3X_I2C_ADDRESS 0x00 // 0x00 means auto
#endif #endif
#if SHT3X_I2C_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// SI7021 temperature & humidity sensor // SI7021 temperature & humidity sensor
// Enable support by passing SI7021_SUPPORT=1 build flag // Enable support by passing SI7021_SUPPORT=1 build flag
@ -529,11 +469,6 @@
#define SI7021_ADDRESS 0x00 // 0x00 means auto #define SI7021_ADDRESS 0x00 // 0x00 means auto
#endif #endif
#if SI7021_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// TMP3X analog temperature sensor // TMP3X analog temperature sensor
// Enable support by passing TMP3X_SUPPORT=1 build flag // Enable support by passing TMP3X_SUPPORT=1 build flag
@ -547,11 +482,6 @@
#define TMP3X_TYPE TMP3X_TMP35 #define TMP3X_TYPE TMP3X_TMP35
#endif #endif
#if TMP3X_SUPPORT
#undef ADC_VCC_ENABLED
#define ADC_VCC_ENABLED 0
#endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// V9261F based power sensor // V9261F based power sensor
// Enable support by passing SI7021_SUPPORT=1 build flag // Enable support by passing SI7021_SUPPORT=1 build flag
@ -578,54 +508,46 @@
#define V9261F_POWER_FACTOR 153699.0 #define V9261F_POWER_FACTOR 153699.0
#define V9261F_RPOWER_FACTOR V9261F_CURRENT_FACTOR #define V9261F_RPOWER_FACTOR V9261F_CURRENT_FACTOR
//------------------------------------------------------------------------------
// AM2320 Humidity & Temperature sensor over I2C
// Enable support by passing AM2320_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef AM2320_SUPPORT
#define AM2320_SUPPORT 0
#endif
#ifndef AM2320_ADDRESS
#define AM2320_ADDRESS 0x00 // 0x00 means auto
#endif
#if AM2320_SUPPORT
#undef I2C_SUPPORT
#define I2C_SUPPORT 1
#endif
//------------------------------------------------------------------------------
// GUVAS12SD UV Sensor (analog)
// Enable support by passing GUVAS12SD_SUPPORT=1 build flag
//------------------------------------------------------------------------------
#ifndef GUVAS12SD_SUPPORT
#define GUVAS12SD_SUPPORT 0
#endif
#ifndef GUVAS12SD_PIN
#define GUVAS12SD_PIN 14
#endif
// ============================================================================= // =============================================================================
// Sensor helpers configuration
// Sensor helpers configuration - can't move to dependencies.h
// ============================================================================= // =============================================================================
#ifndef SENSOR_SUPPORT #ifndef SENSOR_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 \
|| MHZ19_SUPPORT || PMSX003_SUPPORT || SHT3X_I2C_SUPPORT \
|| SI7021_SUPPORT || V9261F_SUPPORT || AM2320_SUPPORT \
|| GUVAS12SD_SUPPORT || CSE7766_SUPPORT || TMP3X_SUPPORT \
|| HCSR04_SUPPORT
#define SENSOR_SUPPORT 1
#else
#define SENSOR_SUPPORT 0
#define SENSOR_SUPPORT ( \
AM2320_SUPPORT || \
ANALOG_SUPPORT || \
BH1750_SUPPORT || \
BMX280_SUPPORT || \
CSE7766_SUPPORT || \
DALLAS_SUPPORT || \
DHT_SUPPORT || \
DIGITAL_SUPPORT || \
ECH1560_SUPPORT || \
EMON_ADC121_SUPPORT || \
EMON_ADS1X15_SUPPORT || \
EMON_ANALOG_SUPPORT || \
EVENTS_SUPPORT || \
GUVAS12SD_SUPPORT || \
HCSR04_SUPPORT || \
HLW8012_SUPPORT || \
MHZ19_SUPPORT || \
SENSEAIR_SUPPORT || \
PMSX003_SUPPORT || \
PZEM004T_SUPPORT || \
SHT3X_I2C_SUPPORT || \
SI7021_SUPPORT || \
TMP3X_SUPPORT || \
V9261F_SUPPORT \
)
#endif #endif
// -----------------------------------------------------------------------------
// ADC
// -----------------------------------------------------------------------------
// Default ADC mode is to monitor internal power supply
#ifndef ADC_MODE_VALUE
#define ADC_MODE_VALUE ADC_VCC
#endif #endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -651,98 +573,12 @@
#define I2C_CLEAR_BUS 0 // Clear I2C bus on boot #define I2C_CLEAR_BUS 0 // Clear I2C bus on boot
#define I2C_PERFORM_SCAN 1 // Perform a bus scan on boot #define I2C_PERFORM_SCAN 1 // Perform a bus scan on boot
//--------------------------------------------------------------------------------
// Internal power monitor
// Enable support by passing ADC_VCC_ENABLED=1 build flag
// Do not enable this if using the analog GPIO for any other thing
//--------------------------------------------------------------------------------
#ifndef ADC_VCC_ENABLED
#define ADC_VCC_ENABLED 1
#endif
#if ADC_VCC_ENABLED
ADC_MODE(ADC_VCC);
#endif
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Class loading // Class loading
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
#if SENSOR_SUPPORT #if SENSOR_SUPPORT
PROGMEM const unsigned char magnitude_decimals[] = {
0,
1, 0, 2,
3, 0, 0, 0, 0, 0, 0, 0,
0, 0, 0,
0, 0, 0,
0, 0,
2, 3
};
PROGMEM const char magnitude_unknown_topic[] = "unknown";
PROGMEM const char magnitude_temperature_topic[] = "temperature";
PROGMEM const char magnitude_humidity_topic[] = "humidity";
PROGMEM const char magnitude_pressure_topic[] = "pressure";
PROGMEM const char magnitude_current_topic[] = "current";
PROGMEM const char magnitude_voltage_topic[] = "voltage";
PROGMEM const char magnitude_active_power_topic[] = "power";
PROGMEM const char magnitude_apparent_power_topic[] = "apparent";
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_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 magnitude_uv_topic[] = "uv";
PROGMEM const char magnitude_distance_topic[] = "distance";
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_analog_topic, magnitude_digital_topic, magnitude_events_topic,
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_co2_topic, magnitude_lux_topic, magnitude_uv_topic,
magnitude_distance_topic
};
PROGMEM const char magnitude_empty[] = "";
PROGMEM const char magnitude_celsius[] = "C";
PROGMEM const char magnitude_fahrenheit[] = "F";
PROGMEM const char magnitude_percentage[] = "%";
PROGMEM const char magnitude_hectopascals[] = "hPa";
PROGMEM const char magnitude_amperes[] = "A";
PROGMEM const char magnitude_volts[] = "V";
PROGMEM const char magnitude_watts[] = "W";
PROGMEM const char magnitude_kw[] = "kW";
PROGMEM const char magnitude_joules[] = "J";
PROGMEM const char magnitude_kwh[] = "kWh";
PROGMEM const char magnitude_ugm3[] = "µg/m3";
PROGMEM const char magnitude_ppm[] = "ppm";
PROGMEM const char magnitude_lux[] = "lux";
PROGMEM const char magnitude_uv[] = "uv";
PROGMEM const char magnitude_distance[] = "m";
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_empty, magnitude_empty, magnitude_empty,
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_ppm, magnitude_lux, magnitude_uv,
magnitude_distance
};
#include "../sensors/BaseSensor.h" #include "../sensors/BaseSensor.h"
#if AM2320_SUPPORT #if AM2320_SUPPORT
@ -817,9 +653,13 @@ PROGMEM const char* const magnitude_units[] = {
#include "../sensors/MHZ19Sensor.h" #include "../sensors/MHZ19Sensor.h"
#endif #endif
#if SENSEAIR_SUPPORT
#include <SoftwareSerial.h>
#include "../sensors/SenseAirSensor.h"
#endif
#if PMSX003_SUPPORT #if PMSX003_SUPPORT
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
#include <PMS.h>
#include "../sensors/PMSX003Sensor.h" #include "../sensors/PMSX003Sensor.h"
#endif #endif


+ 283
- 0
code/espurna/config/types.h View File

@ -0,0 +1,283 @@
//------------------------------------------------------------------------------
// Type definitions
// Do not touch this definitions
//------------------------------------------------------------------------------
//------------------------------------------------------------------------------
// BUTTONS
//------------------------------------------------------------------------------
#define BUTTON_EVENT_NONE 0
#define BUTTON_EVENT_PRESSED 1
#define BUTTON_EVENT_RELEASED 2
#define BUTTON_EVENT_CLICK 2
#define BUTTON_EVENT_DBLCLICK 3
#define BUTTON_EVENT_LNGCLICK 4
#define BUTTON_EVENT_LNGLNGCLICK 5
#define BUTTON_MODE_NONE 0
#define BUTTON_MODE_TOGGLE 1
#define BUTTON_MODE_ON 2
#define BUTTON_MODE_OFF 3
#define BUTTON_MODE_AP 4
#define BUTTON_MODE_RESET 5
#define BUTTON_MODE_PULSE 6
#define BUTTON_MODE_FACTORY 7
// Needed for ESP8285 boards under Windows using PlatformIO (?)
#ifndef BUTTON_PUSHBUTTON
#define BUTTON_PUSHBUTTON 0
#define BUTTON_SWITCH 1
#define BUTTON_DEFAULT_HIGH 2
#define BUTTON_SET_PULLUP 4
#endif
//------------------------------------------------------------------------------
// RELAY
//------------------------------------------------------------------------------
#define RELAY_BOOT_OFF 0
#define RELAY_BOOT_ON 1
#define RELAY_BOOT_SAME 2
#define RELAY_BOOT_TOGGLE 3
#define RELAY_TYPE_NORMAL 0
#define RELAY_TYPE_INVERSE 1
#define RELAY_TYPE_LATCHED 2
#define RELAY_TYPE_LATCHED_INVERSE 3
#define RELAY_SYNC_ANY 0
#define RELAY_SYNC_NONE_OR_ONE 1
#define RELAY_SYNC_ONE 2
#define RELAY_SYNC_SAME 3
#define RELAY_PULSE_NONE 0
#define RELAY_PULSE_OFF 1
#define RELAY_PULSE_ON 2
#define RELAY_PROVIDER_RELAY 0
#define RELAY_PROVIDER_DUAL 1
#define RELAY_PROVIDER_LIGHT 2
#define RELAY_PROVIDER_RFBRIDGE 3
#define RELAY_PROVIDER_STM 4
//------------------------------------------------------------------------------
// UDP SYSLOG
//------------------------------------------------------------------------------
// Priority codes:
#define SYSLOG_EMERG 0 /* system is unusable */
#define SYSLOG_ALERT 1 /* action must be taken immediately */
#define SYSLOG_CRIT 2 /* critical conditions */
#define SYSLOG_ERR 3 /* error conditions */
#define SYSLOG_WARNING 4 /* warning conditions */
#define SYSLOG_NOTICE 5 /* normal but significant condition */
#define SYSLOG_INFO 6 /* informational */
#define SYSLOG_DEBUG 7 /* debug-level messages */
// Facility codes:
#define SYSLOG_KERN (0<<3) /* kernel messages */
#define SYSLOG_USER (1<<3) /* random user-level messages */
#define SYSLOG_MAIL (2<<3) /* mail system */
#define SYSLOG_DAEMON (3<<3) /* system daemons */
#define SYSLOG_AUTH (4<<3) /* security/authorization messages */
#define SYSLOG_SYSLOG (5<<3) /* messages generated internally by syslogd */
#define SYSLOG_LPR (6<<3) /* line printer subsystem */
#define SYSLOG_NEWS (7<<3) /* network news subsystem */
#define SYSLOG_UUCP (8<<3) /* UUCP subsystem */
#define SYSLOG_CRON (9<<3) /* clock daemon */
#define SYSLOG_AUTHPRIV (10<<3) /* security/authorization messages (private) */
#define SYSLOG_FTP (11<<3) /* ftp daemon */
#define SYSLOG_LOCAL0 (16<<3) /* reserved for local use */
#define SYSLOG_LOCAL1 (17<<3) /* reserved for local use */
#define SYSLOG_LOCAL2 (18<<3) /* reserved for local use */
#define SYSLOG_LOCAL3 (19<<3) /* reserved for local use */
#define SYSLOG_LOCAL4 (20<<3) /* reserved for local use */
#define SYSLOG_LOCAL5 (21<<3) /* reserved for local use */
#define SYSLOG_LOCAL6 (22<<3) /* reserved for local use */
#define SYSLOG_LOCAL7 (23<<3) /* reserved for local use */
//------------------------------------------------------------------------------
// MQTT
//------------------------------------------------------------------------------
// Internal MQTT events
#define MQTT_CONNECT_EVENT 0
#define MQTT_DISCONNECT_EVENT 1
#define MQTT_MESSAGE_EVENT 2
//------------------------------------------------------------------------------
// LED
//------------------------------------------------------------------------------
#define LED_MODE_MQTT 0 // LED will be managed from MQTT (OFF by default)
#define LED_MODE_WIFI 1 // LED will blink according to the WIFI status
#define LED_MODE_FOLLOW 2 // LED will follow state of linked relay (check RELAY#_LED)
#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_FINDME_WIFI 5 // A mixture between WIFI and FINDME
#define LED_MODE_ON 6 // LED always ON
#define LED_MODE_OFF 7 // LED always OFF
#define LED_MODE_RELAY 8 // If any relay is ON, LED will be ON, otherwise OFF
#define LED_MODE_RELAY_WIFI 9 // A mixture between WIFI and RELAY, the reverse of MIXED
// -----------------------------------------------------------------------------
// UI
// -----------------------------------------------------------------------------
#define UI_TAG_INPUT 0
#define UI_TAG_CHECKBOX 1
#define UI_TAG_SELECT 2
#define WEB_MODE_NORMAL 0
#define WEB_MODE_PASSWORD 1
// -----------------------------------------------------------------------------
// LIGHT
// -----------------------------------------------------------------------------
// Available light providers
#define LIGHT_PROVIDER_NONE 0
#define LIGHT_PROVIDER_MY92XX 1 // works with MY9291 and MY9231
#define LIGHT_PROVIDER_DIMMER 2
// -----------------------------------------------------------------------------
// SCHEDULER
// -----------------------------------------------------------------------------
#define SCHEDULER_TYPE_SWITCH 1
#define SCHEDULER_TYPE_DIM 2
// -----------------------------------------------------------------------------
// IR
// -----------------------------------------------------------------------------
// IR Button modes
#define IR_BUTTON_MODE_NONE 0
#define IR_BUTTON_MODE_RGB 1
#define IR_BUTTON_MODE_HSV 2
#define IR_BUTTON_MODE_BRIGHTER 3
#define IR_BUTTON_MODE_STATE 4
#define IR_BUTTON_MODE_EFFECT 5
#define IR_BUTTON_MODE_TOGGLE 6
#define LIGHT_EFFECT_SOLID 0
#define LIGHT_EFFECT_FLASH 1
#define LIGHT_EFFECT_STROBE 2
#define LIGHT_EFFECT_FADE 3
#define LIGHT_EFFECT_SMOOTH 4
//------------------------------------------------------------------------------
// RESET
//------------------------------------------------------------------------------
#define CUSTOM_RESET_HARDWARE 1 // Reset from hardware button
#define CUSTOM_RESET_WEB 2 // Reset from web interface
#define CUSTOM_RESET_TERMINAL 3 // Reset from terminal
#define CUSTOM_RESET_MQTT 4 // Reset via MQTT
#define CUSTOM_RESET_RPC 5 // Reset via RPC (HTTP)
#define CUSTOM_RESET_OTA 6 // Reset after successful OTA update
#define CUSTOM_RESET_HTTP 7 // Reset via HTTP GET
#define CUSTOM_RESET_NOFUSS 8 // Reset after successful NOFUSS update
#define CUSTOM_RESET_UPGRADE 9 // Reset after update from web interface
#define CUSTOM_RESET_FACTORY 10 // Factory reset from terminal
#define CUSTOM_RESET_MAX 10
//------------------------------------------------------------------------------
// ENVIRONMENTAL
//------------------------------------------------------------------------------
// American Society of Heating, Refrigerating and Air-Conditioning Engineers suggests a range of 45% - 55% humidity to manage health effects and illnesses.
// Comfortable: 30% - 60%
// Recommended: 45% - 55%
// High : 55% - 80%
#define HUMIDITY_NORMAL 0 // > %30
#define HUMIDITY_COMFORTABLE 1 // > %45
#define HUMIDITY_DRY 2 // < %30
#define HUMIDITY_WET 3 // > %70
// United States Environmental Protection Agency - UV Index Scale
// One UV Index unit is equivalent to 25 milliWatts per square meter.
#define UV_INDEX_LOW 0 // 0 to 2 means low danger from the sun's UV rays for the average person.
#define UV_INDEX_MODERATE 1 // 3 to 5 means moderate risk of harm from unprotected sun exposure.
#define UV_INDEX_HIGH 2 // 6 to 7 means high risk of harm from unprotected sun exposure. Protection against skin and eye damage is needed.
#define UV_INDEX_VERY_HIGH 3 // 8 to 10 means very high risk of harm from unprotected sun exposure.
// Take extra precautions because unprotected skin and eyes will be damaged and can burn quickly.
#define UV_INDEX_EXTREME 4 // 11 or more means extreme risk of harm from unprotected sun exposure.
// Take all precautions because unprotected skin and eyes can burn in minutes.
//------------------------------------------------------------------------------
// UNITS
//------------------------------------------------------------------------------
#define POWER_WATTS 0
#define POWER_KILOWATTS 1
#define ENERGY_JOULES 0
#define ENERGY_KWH 1
#define TMP_CELSIUS 0
#define TMP_FAHRENHEIT 1
#define TMP_KELVIN 2
//--------------------------------------------------------------------------------
// Sensor ID
// These should remain over time, do not modify them, only add new ones at the end
//--------------------------------------------------------------------------------
#define SENSOR_DHTXX_ID 0x01
#define SENSOR_DALLAS_ID 0x02
#define SENSOR_EMON_ANALOG_ID 0x03
#define SENSOR_EMON_ADC121_ID 0x04
#define SENSOR_EMON_ADS1X15_ID 0x05
#define SENSOR_HLW8012_ID 0x06
#define SENSOR_V9261F_ID 0x07
#define SENSOR_ECH1560_ID 0x08
#define SENSOR_ANALOG_ID 0x09
#define SENSOR_DIGITAL_ID 0x10
#define SENSOR_EVENTS_ID 0x11
#define SENSOR_PMSX003_ID 0x12
#define SENSOR_BMX280_ID 0x13
#define SENSOR_MHZ19_ID 0x14
#define SENSOR_SI7021_ID 0x15
#define SENSOR_SHT3X_I2C_ID 0x16
#define SENSOR_BH1750_ID 0x17
#define SENSOR_PZEM004T_ID 0x18
#define SENSOR_AM2320_ID 0x19
#define SENSOR_GUVAS12SD_ID 0x20
#define SENSOR_CSE7766_ID 0x21
#define SENSOR_TMP3X_ID 0x22
#define SENSOR_HCSR04_ID 0x23
#define SENSOR_SENSEAIR_ID 0x24
//--------------------------------------------------------------------------------
// Magnitudes
//--------------------------------------------------------------------------------
#define MAGNITUDE_NONE 0
#define MAGNITUDE_TEMPERATURE 1
#define MAGNITUDE_HUMIDITY 2
#define MAGNITUDE_PRESSURE 3
#define MAGNITUDE_CURRENT 4
#define MAGNITUDE_VOLTAGE 5
#define MAGNITUDE_POWER_ACTIVE 6
#define MAGNITUDE_POWER_APPARENT 7
#define MAGNITUDE_POWER_REACTIVE 8
#define MAGNITUDE_POWER_FACTOR 9
#define MAGNITUDE_ENERGY 10
#define MAGNITUDE_ENERGY_DELTA 11
#define MAGNITUDE_ANALOG 12
#define MAGNITUDE_DIGITAL 13
#define MAGNITUDE_EVENTS 14
#define MAGNITUDE_PM1dot0 15
#define MAGNITUDE_PM2dot5 16
#define MAGNITUDE_PM10 17
#define MAGNITUDE_CO2 18
#define MAGNITUDE_LUX 19
#define MAGNITUDE_UV 20
#define MAGNITUDE_DISTANCE 21
#define MAGNITUDE_HCHO 22
#define MAGNITUDE_MAX 23

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

@ -1,6 +1,6 @@
#define APP_NAME "ESPURNA" #define APP_NAME "ESPURNA"
#define APP_VERSION "1.12.6a"
#define APP_REVISION ""
#define APP_VERSION "1.12.6"
#define APP_REVISION "db84006"
#define APP_AUTHOR "xose.perez@gmail.com" #define APP_AUTHOR "xose.perez@gmail.com"
#define APP_WEBSITE "http://tinkerman.cat" #define APP_WEBSITE "http://tinkerman.cat"
#define CFG_VERSION 3 #define CFG_VERSION 3

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


+ 25
- 4
code/espurna/debug.ino View File

@ -19,6 +19,9 @@ extern "C" {
#if DEBUG_UDP_SUPPORT #if DEBUG_UDP_SUPPORT
#include <WiFiUdp.h> #include <WiFiUdp.h>
WiFiUDP _udp_debug; WiFiUDP _udp_debug;
#if DEBUG_UDP_PORT == 514
char _udp_syslog_header[40] = {0};
#endif
#endif #endif
void _debugSend(char * message) { void _debugSend(char * message) {
@ -42,12 +45,11 @@ void _debugSend(char * message) {
if (systemCheck()) { if (systemCheck()) {
#endif #endif
_udp_debug.beginPacket(DEBUG_UDP_IP, DEBUG_UDP_PORT); _udp_debug.beginPacket(DEBUG_UDP_IP, DEBUG_UDP_PORT);
#if DEBUG_ADD_TIMESTAMP
_udp_debug.write(timestamp);
#if DEBUG_UDP_PORT == 514
_udp_debug.write(_udp_syslog_header);
#endif #endif
_udp_debug.write(message); _udp_debug.write(message);
_udp_debug.endPacket(); _udp_debug.endPacket();
delay(1); // https://github.com/xoseperez/espurna/issues/438
#if SYSTEM_CHECK_ENABLED #if SYSTEM_CHECK_ENABLED
} }
#endif #endif
@ -117,7 +119,7 @@ void debugSend_P(PGM_P format_P, ...) {
#if DEBUG_WEB_SUPPORT #if DEBUG_WEB_SUPPORT
void debugSetup() {
void debugWebSetup() {
wsOnSendRegister([](JsonObject& root) { wsOnSendRegister([](JsonObject& root) {
root["dbgVisible"] = 1; root["dbgVisible"] = 1;
@ -132,10 +134,28 @@ void debugSetup() {
} }
}); });
#if DEBUG_UDP_SUPPORT
#if DEBUG_UDP_PORT == 514
snprintf_P(_udp_syslog_header, sizeof(_udp_syslog_header), PSTR("<%u>%s ESPurna[0]: "), DEBUG_UDP_FAC_PRI, getSetting("hostname").c_str());
#endif
#endif
} }
#endif // DEBUG_WEB_SUPPORT #endif // DEBUG_WEB_SUPPORT
void debugSetup() {
#if DEBUG_SERIAL_SUPPORT
DEBUG_PORT.begin(SERIAL_BAUDRATE);
#if DEBUG_ESP_WIFI
DEBUG_PORT.setDebugOutput(true);
#endif
#endif
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Save crash info // Save crash info
// Taken from krzychb EspSaveCrash // Taken from krzychb EspSaveCrash
@ -265,4 +285,5 @@ void debugDumpCrashInfo() {
DEBUG_MSG_P(PSTR("<<<stack<<<\n")); DEBUG_MSG_P(PSTR("<<<stack<<<\n"));
} }
#endif // DEBUG_SUPPORT #endif // DEBUG_SUPPORT

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

@ -42,6 +42,11 @@ void setup() {
// Basic modules, will always run // Basic modules, will always run
// ------------------------------------------------------------------------- // -------------------------------------------------------------------------
// Serial debug
#if DEBUG_SUPPORT
debugSetup();
#endif
// Init EEPROM, Serial, SPIFFS and system check // Init EEPROM, Serial, SPIFFS and system check
systemSetup(); systemSetup();
@ -81,7 +86,7 @@ void setup() {
wsSetup(); wsSetup();
apiSetup(); apiSetup();
#if DEBUG_WEB_SUPPORT #if DEBUG_WEB_SUPPORT
debugSetup();
debugWebSetup();
#endif #endif
#endif #endif


+ 11
- 0
code/espurna/ir.ino View File

@ -14,6 +14,7 @@ Copyright (C) 2017-2018 by François Déchery
IRrecv * _ir_recv; IRrecv * _ir_recv;
decode_results _ir_results; decode_results _ir_results;
unsigned long _ir_last_toggle = 0;
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PRIVATE // PRIVATE
@ -43,6 +44,16 @@ void _irProcessCode(unsigned long code) {
relayStatus(0, button_value); relayStatus(0, button_value);
} }
if (button_mode == IR_BUTTON_MODE_TOGGLE) {
if (millis() - _ir_last_toggle > 250){
relayToggle(button_value);
_ir_last_toggle = millis();
} else {
DEBUG_MSG_P(PSTR("[IR] Ignoring repeated code\n"));
}
}
#if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE #if LIGHT_PROVIDER != LIGHT_PROVIDER_NONE
if (button_mode == IR_BUTTON_MODE_BRIGHTER) { if (button_mode == IR_BUTTON_MODE_BRIGHTER) {


+ 47
- 27
code/espurna/libs/StreamInjector.h View File

@ -1,6 +1,23 @@
// -----------------------------------------------------------------------------
// Stream Injector
// -----------------------------------------------------------------------------
/*
StreamInjector
Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#pragma once #pragma once
@ -12,7 +29,7 @@ class StreamInjector : public Stream {
typedef std::function<void(uint8_t ch)> writeCallback; typedef std::function<void(uint8_t ch)> writeCallback;
StreamInjector(Stream& serial, size_t buflen = 128) : _stream(serial), _buffer_size(buflen) {
StreamInjector(size_t buflen = 128) : _buffer_size(buflen) {
_buffer = new char[buflen]; _buffer = new char[buflen];
} }
@ -20,28 +37,43 @@ class StreamInjector : public Stream {
delete[] _buffer; delete[] _buffer;
} }
// ---------------------------------------------------------------------
virtual uint8_t inject(char ch) {
_buffer[_buffer_write] = ch;
_buffer_write = (_buffer_write + 1) % _buffer_size;
return 1;
}
virtual uint8_t inject(char *data, size_t len) {
for (uint8_t i=0; i<len; i++) {
inject(data[i]);
}
return len;
}
virtual void callback(writeCallback c) { virtual void callback(writeCallback c) {
_callback = c; _callback = c;
} }
// ---------------------------------------------------------------------
virtual size_t write(uint8_t ch) { virtual size_t write(uint8_t ch) {
if (_callback) _callback(ch); if (_callback) _callback(ch);
return _stream.write(ch);
return 1;
} }
virtual int read() { virtual int read() {
int ch = _stream.read();
if (ch == -1) {
if (_buffer_read != _buffer_write) {
ch = _buffer[_buffer_read];
_buffer_read = (_buffer_read + 1) % _buffer_size;
}
int ch = -1;
if (_buffer_read != _buffer_write) {
ch = _buffer[_buffer_read];
_buffer_read = (_buffer_read + 1) % _buffer_size;
} }
return ch; return ch;
} }
virtual int available() { virtual int available() {
unsigned int bytes = _stream.available();
unsigned int bytes = 0;
if (_buffer_read > _buffer_write) { if (_buffer_read > _buffer_write) {
bytes += (_buffer_write - _buffer_read + _buffer_size); bytes += (_buffer_write - _buffer_read + _buffer_size);
} else if (_buffer_read < _buffer_write) { } else if (_buffer_read < _buffer_write) {
@ -51,35 +83,23 @@ class StreamInjector : public Stream {
} }
virtual int peek() { virtual int peek() {
int ch = _stream.peek();
if (ch == -1) {
if (_buffer_read != _buffer_write) {
ch = _buffer[_buffer_read];
}
int ch = -1;
if (_buffer_read != _buffer_write) {
ch = _buffer[_buffer_read];
} }
return ch; return ch;
} }
virtual void flush() { virtual void flush() {
_stream.flush();
_buffer_read = _buffer_write; _buffer_read = _buffer_write;
} }
virtual void inject(char *data, size_t len) {
for (int i=0; i<len; i++) {
_buffer[_buffer_write] = data[i];
_buffer_write = (_buffer_write + 1) % _buffer_size;
}
}
private: private:
Stream& _stream;
char * _buffer; char * _buffer;
unsigned char _buffer_size; unsigned char _buffer_size;
unsigned char _buffer_write = 0; unsigned char _buffer_write = 0;
unsigned char _buffer_read = 0; unsigned char _buffer_read = 0;
writeCallback _callback = NULL; writeCallback _callback = NULL;
}; };

+ 1
- 1
code/espurna/libs/WebSocketIncommingBuffer.h View File

@ -80,8 +80,8 @@ class WebSocketIncommingBuffer {
private: private:
AwsMessageHandler _cb; AwsMessageHandler _cb;
bool _cb_on_fragments;
bool _terminate_string; bool _terminate_string;
bool _cb_on_fragments;
std::vector<uint8_t> *_buffer; std::vector<uint8_t> *_buffer;
}; };

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

@ -888,6 +888,55 @@ void migrate() {
setSetting("board", 69); setSetting("board", 69);
#elif defined(ZHILDE_EU44_W)
setSetting("board", 70);
setSetting("btnGPIO", 0, 3);
setSetting("ledGPIO", 0, 1);
setSetting("ledLogic", 0, 1);
setSetting("relayGPIO", 0, 5);
setSetting("relayGPIO", 1, 4);
setSetting("relayGPIO", 2, 12);
setSetting("relayGPIO", 3, 13);
setSetting("relayGPIO", 4, 14);
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("relayType", 1, RELAY_TYPE_NORMAL);
setSetting("relayType", 2, RELAY_TYPE_NORMAL);
setSetting("relayType", 3, RELAY_TYPE_NORMAL);
setSetting("relayType", 4, RELAY_TYPE_NORMAL);
#elif defined(ITEAD_SONOFF_POW_R2)
setSetting("board", 71);
setSetting("ledGPIO", 0, 15);
setSetting("ledLogic", 0, 1);
setSetting("btnGPIO", 0, 0);
setSetting("btnRelay", 0, 0);
setSetting("relayGPIO", 0, 12);
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("selGPIO", 5);
setSetting("cf1GPIO", 13);
setSetting("cfGPIO", 14);
#elif defined(LUANI_HVIO)
setSetting("board", 72);
setSetting("ledGPIO", 0, 15);
setSetting("ledLogic", 0, 0);
setSetting("btnGPIO", 0, 12);
setSetting("btnRelay", 0, 0);
setSetting("relayGPIO", 0, 4);
setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("relayGPIO", 1, 5);
setSetting("relayType", 1, RELAY_TYPE_NORMAL);
#elif defined(ALLNET_4DUINO_IOT_WLAN_RELAIS)
setSetting("board", 73);
setSetting("relayGPIO", 0, 14);
setSetting("relayResetGPIO", 0, 12);
setSetting("relayType", 0, RELAY_TYPE_LATCHED);
#elif defined(PILOTAK_ESP_DIN_V1) #elif defined(PILOTAK_ESP_DIN_V1)
setSetting("board", 70); setSetting("board", 70);
@ -899,7 +948,6 @@ void migrate() {
setSetting("relayGPIO", 1, 5); setSetting("relayGPIO", 1, 5);
setSetting("relayType", 0, RELAY_TYPE_NORMAL); setSetting("relayType", 0, RELAY_TYPE_NORMAL);
setSetting("relayType", 1, RELAY_TYPE_NORMAL); setSetting("relayType", 1, RELAY_TYPE_NORMAL);
#else #else
// Allow users to define new settings without migration config // Allow users to define new settings without migration config


+ 10
- 2
code/espurna/ntp.ino View File

@ -88,8 +88,10 @@ void _ntpUpdate() {
wsSend(_ntpWebSocketOnSend); wsSend(_ntpWebSocketOnSend);
#endif #endif
if (strlen(ntpDateTime().c_str())) {
DEBUG_MSG_P(PSTR("[NTP] Time: %s\n"), (char *) ntpDateTime().c_str());
if (ntpSynced()) {
time_t t = now();
DEBUG_MSG_P(PSTR("[NTP] UTC Time : %s\n"), (char *) ntpDateTime(ntpLocal2UTC(t)).c_str());
DEBUG_MSG_P(PSTR("[NTP] Local Time: %s\n"), (char *) ntpDateTime(t).c_str());
} }
} }
@ -143,6 +145,12 @@ String ntpDateTime() {
return String(); return String();
} }
time_t ntpLocal2UTC(time_t local) {
int offset = getSetting("ntpOffset", NTP_TIME_OFFSET).toInt();
if (NTP.isSummerTime()) offset += 60;
return local - offset * 60;
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
void ntpSetup() { void ntpSetup() {


+ 123
- 47
code/espurna/rfbridge.ino View File

@ -11,6 +11,10 @@ Copyright (C) 2017-2018 by Xose Pérez <xose dot perez at gmail dot com>
#include <queue> #include <queue>
#include <Ticker.h> #include <Ticker.h>
#if RFB_DIRECT
#include <RCSwitch.h>
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// DEFINITIONS // DEFINITIONS
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -51,6 +55,11 @@ static std::queue<rfb_message_t> _rfb_message_queue;
Ticker _rfb_ticker; Ticker _rfb_ticker;
bool _rfb_ticker_active = false; bool _rfb_ticker_active = false;
#if RFB_DIRECT
RCSwitch * _rfModem;
bool _learning = false;
#endif
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PRIVATES // PRIVATES
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -105,24 +114,30 @@ void _rfbWebSocketOnAction(uint32_t client_id, const char * action, JsonObject&
} }
void _rfbAck() { void _rfbAck() {
DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending ACK\n"));
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_ACK);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
#if not RFB_DIRECT
DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending ACK\n"));
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_ACK);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
#endif
} }
void _rfbLearn() { void _rfbLearn() {
DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending LEARN\n"));
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_LEARN);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
#if RFB_DIRECT
DEBUG_MSG_P(PSTR("[RFBRIDGE] Entering LEARN mode\n"));
_learning = true;
#else
DEBUG_MSG_P(PSTR("[RFBRIDGE] Sending LEARN\n"));
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_LEARN);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
#endif
#if WEB_SUPPORT #if WEB_SUPPORT
char buffer[100]; char buffer[100];
@ -139,13 +154,25 @@ void _rfbSendRaw(const byte *message, const unsigned char n = RF_MESSAGE_SIZE) {
} }
void _rfbSend(byte * message) { void _rfbSend(byte * message) {
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_RFOUT);
_rfbSendRaw(message);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
#if RFB_DIRECT
unsigned int protocol = message[1];
unsigned int bitlength = message[4];
unsigned long rf_code =
(message[5] << 24) |
(message[6] << 16) |
(message[7] << 8) |
(message[8] << 0) ;
_rfModem->setProtocol(protocol);
_rfModem->send(rf_code, bitlength);
#else
Serial.println();
Serial.write(RF_CODE_START);
Serial.write(RF_CODE_RFOUT);
_rfbSendRaw(message);
Serial.write(RF_CODE_STOP);
Serial.flush();
Serial.println();
#endif
} }
void _rfbSend() { void _rfbSend() {
@ -301,33 +328,74 @@ void _rfbDecode() {
} }
void _rfbReceive() { void _rfbReceive() {
static bool receiving = false;
while (Serial.available()) {
yield();
byte c = Serial.read();
//DEBUG_MSG_P(PSTR("[RFBRIDGE] Received 0x%02X\n"), c);
if (receiving) {
if (c == RF_CODE_STOP && (_uartpos == 1 || _uartpos == RF_MESSAGE_SIZE + 1)) {
#if RFB_DIRECT
static long learn_start = 0;
if (!_learning && learn_start) {
learn_start = 0;
}
if (_learning) {
if (!learn_start) {
DEBUG_MSG_P(PSTR("[RFBRIDGE] arming learn timeout\n"));
learn_start = millis();
}
if (learn_start > 0 && millis() - learn_start > RF_LEARN_TIMEOUT) {
DEBUG_MSG_P(PSTR("[RFBRIDGE] learn timeout triggered\n"));
memset(_uartbuf, 0, sizeof(_uartbuf));
_uartbuf[0] = RF_CODE_LEARN_KO;
_rfbDecode(); _rfbDecode();
receiving = false;
} else if (_uartpos <= RF_MESSAGE_SIZE) {
_uartbuf[_uartpos++] = c;
} else {
// wrong message, should have received a RF_CODE_STOP
receiving = false;
_learning = false;
} }
} else if (c == RF_CODE_START) {
_uartpos = 0;
receiving = true;
} }
}
if (_rfModem->available()) {
static unsigned long last = 0;
if (millis() - last > RF_DEBOUNCE) {
last = millis();
unsigned long rf_code = _rfModem->getReceivedValue();
if ( rf_code > 0) {
DEBUG_MSG_P(PSTR("[RFBRIDGE] Received code: %08X\n"), rf_code);
memset(_uartbuf, 0, sizeof(_uartbuf));
unsigned char *msgbuf = _uartbuf + 1;
_uartbuf[0] = _learning ? RF_CODE_LEARN_OK: RF_CODE_RFIN;
msgbuf[0] = 0xC0;
msgbuf[1] = _rfModem->getReceivedProtocol();
msgbuf[4] = _rfModem->getReceivedBitlength();
msgbuf[5] = rf_code >> 24;
msgbuf[6] = rf_code >> 16;
msgbuf[7] = rf_code >> 8;
msgbuf[8] = rf_code >> 0;
_rfbDecode();
_learning = false;
}
}
_rfModem->resetAvailable();
}
#else
static bool receiving = false;
while (Serial.available()) {
yield();
byte c = Serial.read();
//DEBUG_MSG_P(PSTR("[RFBRIDGE] Received 0x%02X\n"), c);
if (receiving) {
if (c == RF_CODE_STOP && (_uartpos == 1 || _uartpos == RF_MESSAGE_SIZE + 1)) {
_rfbDecode();
receiving = false;
} else if (_uartpos <= RF_MESSAGE_SIZE) {
_uartbuf[_uartpos++] = c;
} else {
// wrong message, should have received a RF_CODE_STOP
receiving = false;
}
} else if (c == RF_CODE_START) {
_uartpos = 0;
receiving = true;
}
}
#endif
} }
bool _rfbCompare(const char * code1, const char * code2) { bool _rfbCompare(const char * code1, const char * code2) {
@ -346,9 +414,9 @@ void _rfbMqttCallback(unsigned int type, const char * topic, const char * payloa
snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_RFLEARN); snprintf_P(buffer, sizeof(buffer), PSTR("%s/+"), MQTT_TOPIC_RFLEARN);
mqttSubscribe(buffer); mqttSubscribe(buffer);
mqttSubscribe(MQTT_TOPIC_RFOUT); mqttSubscribe(MQTT_TOPIC_RFOUT);
#if RF_RAW_SUPPORT
mqttSubscribe(MQTT_TOPIC_RFRAW);
#endif
#if RF_RAW_SUPPORT
mqttSubscribe(MQTT_TOPIC_RFRAW);
#endif
} }
if (type == MQTT_MESSAGE_EVENT) { if (type == MQTT_MESSAGE_EVENT) {
@ -522,7 +590,15 @@ void rfbSetup() {
wsOnActionRegister(_rfbWebSocketOnAction); wsOnActionRegister(_rfbWebSocketOnAction);
#endif #endif
// Register oop
#if RFB_DIRECT
_rfModem = new RCSwitch();
_rfModem->enableReceive(RFB_RX_PIN);
_rfModem->enableTransmit(RFB_TX_PIN);
DEBUG_MSG_P(PSTR("[RFBRIDGE] RF receiver on GPIO %u\n"), RFB_RX_PIN);
DEBUG_MSG_P(PSTR("[RFBRIDGE] RF transmitter on GPIO %u\n"), RFB_TX_PIN);
#endif
// Register loop
espurnaRegisterLoop(rfbLoop); espurnaRegisterLoop(rfbLoop);
} }


+ 21
- 11
code/espurna/scheduler.ino View File

@ -35,6 +35,7 @@ void _schWebSocketOnSend(JsonObject &root){
scheduler["schType"] = getSetting("schType", i, 0).toInt(); scheduler["schType"] = getSetting("schType", i, 0).toInt();
scheduler["schHour"] = getSetting("schHour", i, 0).toInt(); scheduler["schHour"] = getSetting("schHour", i, 0).toInt();
scheduler["schMinute"] = getSetting("schMinute", i, 0).toInt(); scheduler["schMinute"] = getSetting("schMinute", i, 0).toInt();
scheduler["schUTC"] = getSetting("schUTC", i, 0).toInt() == 1;
scheduler["schWDs"] = getSetting("schWDs", i, ""); scheduler["schWDs"] = getSetting("schWDs", i, "");
} }
@ -64,22 +65,25 @@ void _schConfigure() {
delSetting("schMinute", i); delSetting("schMinute", i);
delSetting("schWDs", i); delSetting("schWDs", i);
delSetting("schType", i); delSetting("schType", i);
delSetting("schUTC", i);
} else { } else {
#if DEBUG_SUPPORT #if DEBUG_SUPPORT
int sch_enabled = getSetting("schEnabled", i, 1).toInt() == 1;
bool sch_enabled = getSetting("schEnabled", i, 1).toInt() == 1;
int sch_action = getSetting("schAction", i, 0).toInt(); int sch_action = getSetting("schAction", i, 0).toInt();
int sch_hour = getSetting("schHour", i, 0).toInt(); int sch_hour = getSetting("schHour", i, 0).toInt();
int sch_minute = getSetting("schMinute", i, 0).toInt(); int sch_minute = getSetting("schMinute", i, 0).toInt();
bool sch_utc = getSetting("schUTC", i, 0).toInt() == 1;
String sch_weekdays = getSetting("schWDs", i, ""); String sch_weekdays = getSetting("schWDs", i, "");
unsigned char sch_type = getSetting("schType", i, SCHEDULER_TYPE_SWITCH).toInt(); unsigned char sch_type = getSetting("schType", i, SCHEDULER_TYPE_SWITCH).toInt();
DEBUG_MSG_P( DEBUG_MSG_P(
PSTR("[SCH] Schedule #%d: %s #%d to %d at %02d:%02d on %s%s\n"),
PSTR("[SCH] Schedule #%d: %s #%d to %d at %02d:%02d %s on %s%s\n"),
i, SCHEDULER_TYPE_SWITCH == sch_type ? "switch" : "channel", sch_switch, i, SCHEDULER_TYPE_SWITCH == sch_type ? "switch" : "channel", sch_switch,
sch_action, sch_hour, sch_minute, (char *) sch_weekdays.c_str(),
sch_action, sch_hour, sch_minute, sch_utc ? "UTC" : "local time",
(char *) sch_weekdays.c_str(),
sch_enabled ? "" : " (disabled)" sch_enabled ? "" : " (disabled)"
); );
@ -91,24 +95,23 @@ void _schConfigure() {
} }
bool _schIsThisWeekday(String weekdays){
bool _schIsThisWeekday(time_t t, String weekdays){
// Convert from Sunday to Monday as day 1 // Convert from Sunday to Monday as day 1
int w = weekday(now()) - 1;
if (w == 0) w = 7;
int w = weekday(t) - 1;
if (0 == w) w = 7;
char pch; char pch;
char * p = (char *) weekdays.c_str(); char * p = (char *) weekdays.c_str();
unsigned char position = 0; unsigned char position = 0;
while (pch = p[position++]) {
while ((pch = p[position++])) {
if ((pch - '0') == w) return true; if ((pch - '0') == w) return true;
} }
return false; return false;
} }
int _schMinutesLeft(unsigned char schedule_hour, unsigned char schedule_minute){
time_t t = now();
int _schMinutesLeft(time_t t, unsigned char schedule_hour, unsigned char schedule_minute){
unsigned char now_hour = hour(t); unsigned char now_hour = hour(t);
unsigned char now_minute = minute(t); unsigned char now_minute = minute(t);
return (schedule_hour - now_hour) * 60 + schedule_minute - now_minute; return (schedule_hour - now_hour) * 60 + schedule_minute - now_minute;
@ -116,6 +119,9 @@ int _schMinutesLeft(unsigned char schedule_hour, unsigned char schedule_minute){
void _schCheck() { void _schCheck() {
time_t local_time = now();
time_t utc_time = ntpLocal2UTC(local_time);
// Check schedules // Check schedules
for (unsigned char i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) { for (unsigned char i = 0; i < SCHEDULER_MAX_SCHEDULES; i++) {
@ -125,12 +131,16 @@ void _schCheck() {
// Skip disabled schedules // Skip disabled schedules
if (getSetting("schEnabled", i, 1).toInt() == 0) continue; if (getSetting("schEnabled", i, 1).toInt() == 0) continue;
// Get the datetime used for the calculation
bool sch_utc = getSetting("schUTC", i, 0).toInt() == 1;
time_t t = sch_utc ? utc_time : local_time;
String sch_weekdays = getSetting("schWDs", i, ""); String sch_weekdays = getSetting("schWDs", i, "");
if (_schIsThisWeekday(sch_weekdays)) {
if (_schIsThisWeekday(t, sch_weekdays)) {
int sch_hour = getSetting("schHour", i, 0).toInt(); int sch_hour = getSetting("schHour", i, 0).toInt();
int sch_minute = getSetting("schMinute", i, 0).toInt(); int sch_minute = getSetting("schMinute", i, 0).toInt();
int minutes_to_trigger = _schMinutesLeft(sch_hour, sch_minute);
int minutes_to_trigger = _schMinutesLeft(t, sch_hour, sch_minute);
if (minutes_to_trigger == 0) { if (minutes_to_trigger == 0) {


+ 48
- 17
code/espurna/sensor.ino View File

@ -40,6 +40,8 @@ unsigned char _sensor_temperature_units = SENSOR_TEMPERATURE_UNITS;
double _sensor_temperature_correction = SENSOR_TEMPERATURE_CORRECTION; double _sensor_temperature_correction = SENSOR_TEMPERATURE_CORRECTION;
double _sensor_humidity_correction = SENSOR_HUMIDITY_CORRECTION; double _sensor_humidity_correction = SENSOR_HUMIDITY_CORRECTION;
String _sensor_energy_reset_ts = String();
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Private // Private
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -120,9 +122,15 @@ void _sensorWebSocketSendData(JsonObject& root) {
element["type"] = int(magnitude.type); element["type"] = int(magnitude.type);
element["value"] = String(buffer); element["value"] = String(buffer);
element["units"] = magnitudeUnits(magnitude.type); element["units"] = magnitudeUnits(magnitude.type);
element["description"] = magnitude.sensor->slot(magnitude.local);
element["error"] = magnitude.sensor->error(); 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;
} else {
element["description"] = magnitude.sensor->slot(magnitude.local);
}
if (magnitude.type == MAGNITUDE_TEMPERATURE) hasTemperature = true; if (magnitude.type == MAGNITUDE_TEMPERATURE) hasTemperature = true;
if (magnitude.type == MAGNITUDE_HUMIDITY) hasHumidity = true; if (magnitude.type == MAGNITUDE_HUMIDITY) hasHumidity = true;
@ -277,6 +285,14 @@ void _sensorPost() {
} }
} }
void _sensorReset() {
#if NTP_SUPPORT
if (ntpSynced()) {
_sensor_energy_reset_ts = String(" (since ") + ntpDateTime() + String(")");
}
#endif
}
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// Sensor initialization // Sensor initialization
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
@ -296,6 +312,14 @@ void _sensorLoad() {
*/ */
#if AM2320_SUPPORT
{
AM2320Sensor * sensor = new AM2320Sensor();
sensor->setAddress(AM2320_ADDRESS);
_sensors.push_back(sensor);
}
#endif
#if ANALOG_SUPPORT #if ANALOG_SUPPORT
{ {
AnalogSensor * sensor = new AnalogSensor(); AnalogSensor * sensor = new AnalogSensor();
@ -426,6 +450,14 @@ void _sensorLoad() {
} }
#endif #endif
#if GUVAS12SD_SUPPORT
{
GUVAS12SDSensor * sensor = new GUVAS12SDSensor();
sensor->setGPIO(GUVAS12SD_PIN);
_sensors.push_back(sensor);
}
#endif
#if HCSR04_SUPPORT #if HCSR04_SUPPORT
{ {
HCSR04Sensor * sensor = new HCSR04Sensor(); HCSR04Sensor * sensor = new HCSR04Sensor();
@ -455,11 +487,21 @@ void _sensorLoad() {
} }
#endif #endif
#if SENSEAIR_SUPPORT
{
SenseAirSensor * sensor = new SenseAirSensor();
sensor->setRX(SENSEAIR_RX_PIN);
sensor->setTX(SENSEAIR_TX_PIN);
_sensors.push_back(sensor);
}
#endif
#if PMSX003_SUPPORT #if PMSX003_SUPPORT
{ {
PMSX003Sensor * sensor = new PMSX003Sensor(); PMSX003Sensor * sensor = new PMSX003Sensor();
sensor->setRX(PMS_RX_PIN); sensor->setRX(PMS_RX_PIN);
sensor->setTX(PMS_TX_PIN); sensor->setTX(PMS_TX_PIN);
sensor->setType(PMS_TYPE);
_sensors.push_back(sensor); _sensors.push_back(sensor);
} }
#endif #endif
@ -510,22 +552,6 @@ void _sensorLoad() {
} }
#endif #endif
#if AM2320_SUPPORT
{
AM2320Sensor * sensor = new AM2320Sensor();
sensor->setAddress(AM2320_ADDRESS);
_sensors.push_back(sensor);
}
#endif
#if GUVAS12SD_SUPPORT
{
GUVAS12SDSensor * sensor = new GUVAS12SDSensor();
sensor->setGPIO(GUVAS12SD_PIN);
_sensors.push_back(sensor);
}
#endif
} }
void _sensorCallback(unsigned char i, unsigned char type, const char * payload) { void _sensorCallback(unsigned char i, unsigned char type, const char * payload) {
@ -677,6 +703,7 @@ void _sensorConfigure() {
if (getSetting("pwrResetE", 0).toInt() == 1) { if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy(); sensor->resetEnergy();
_sensorReset();
} }
sensor->setVoltage(getSetting("pwrVoltage", EMON_MAINS_VOLTAGE).toInt()); sensor->setVoltage(getSetting("pwrVoltage", EMON_MAINS_VOLTAGE).toInt());
@ -690,6 +717,7 @@ void _sensorConfigure() {
EmonADC121Sensor * sensor = (EmonADC121Sensor *) _sensors[i]; EmonADC121Sensor * sensor = (EmonADC121Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) { if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy(); sensor->resetEnergy();
_sensorReset();
} }
} }
#endif #endif
@ -699,6 +727,7 @@ void _sensorConfigure() {
EmonADS1X15Sensor * sensor = (EmonADS1X15Sensor *) _sensors[i]; EmonADS1X15Sensor * sensor = (EmonADS1X15Sensor *) _sensors[i];
if (getSetting("pwrResetE", 0).toInt() == 1) { if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy(); sensor->resetEnergy();
_sensorReset();
} }
} }
#endif #endif
@ -728,6 +757,7 @@ void _sensorConfigure() {
if (getSetting("pwrResetE", 0).toInt() == 1) { if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy(); sensor->resetEnergy();
_sensorReset();
} }
if (getSetting("pwrResetCalibration", 0).toInt() == 1) { if (getSetting("pwrResetCalibration", 0).toInt() == 1) {
@ -765,6 +795,7 @@ void _sensorConfigure() {
if (getSetting("pwrResetE", 0).toInt() == 1) { if (getSetting("pwrResetE", 0).toInt() == 1) {
sensor->resetEnergy(); sensor->resetEnergy();
_sensorReset();
} }
if (getSetting("pwrResetCalibration", 0).toInt() == 1) { if (getSetting("pwrResetCalibration", 0).toInt() == 1) {


+ 8
- 3
code/espurna/sensors/AM2320Sensor.h View File

@ -7,6 +7,9 @@
#pragma once #pragma once
#undef I2C_SUPPORT
#define I2C_SUPPORT 1 // Explicitly request I2C support.
#include "Arduino.h" #include "Arduino.h"
#include "I2CSensor.h" #include "I2CSensor.h"
@ -98,7 +101,7 @@ class AM2320Sensor : public I2CSensor {
// Get device model, version, device_id // Get device model, version, device_id
void _init() { void _init() {
i2c_wakeup();
i2c_wakeup(_address);
delayMicroseconds(800); delayMicroseconds(800);
unsigned char _buffer[11]; unsigned char _buffer[11];
@ -117,7 +120,9 @@ class AM2320Sensor : public I2CSensor {
*/ */
void _read() { void _read() {
i2c_wakeup();
i2c_wakeup(_address);
// waiting time of at least 800 μs, the maximum 3000 μs // waiting time of at least 800 μs, the maximum 3000 μs
delayMicroseconds(800); // just to be on safe side delayMicroseconds(800); // just to be on safe side
@ -125,7 +130,7 @@ class AM2320Sensor : public I2CSensor {
// 4 = number of bytes to read // 4 = number of bytes to read
if (i2c_write_uint8(_address, AM2320_I2C_READ_REGISTER_DATA, 0x00, 4) != I2C_TRANS_SUCCESS) { if (i2c_write_uint8(_address, AM2320_I2C_READ_REGISTER_DATA, 0x00, 4) != I2C_TRANS_SUCCESS) {
_error = SENSOR_ERROR_TIMEOUT; _error = SENSOR_ERROR_TIMEOUT;
return false;
return;
} }
unsigned char _buffer[8]; unsigned char _buffer[8];


+ 4
- 0
code/espurna/sensors/AnalogSensor.h View File

@ -7,6 +7,10 @@
#pragma once #pragma once
// Set ADC to TOUT pin
#undef ADC_MODE_VALUE
#define ADC_MODE_VALUE ADC_TOUT
#include "Arduino.h" #include "Arduino.h"
#include "BaseSensor.h" #include "BaseSensor.h"


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

@ -7,6 +7,9 @@
#pragma once #pragma once
#undef I2C_SUPPORT
#define I2C_SUPPORT 1 // Explicitly request I2C support.
#include "Arduino.h" #include "Arduino.h"
#include "I2CSensor.h" #include "I2CSensor.h"


+ 3
- 0
code/espurna/sensors/BMX280Sensor.h View File

@ -7,6 +7,9 @@
#pragma once #pragma once
#undef I2C_SUPPORT
#define I2C_SUPPORT 1 // Explicitly request I2C support.
#include "Arduino.h" #include "Arduino.h"
#include "I2CSensor.h" #include "I2CSensor.h"


+ 0
- 9
code/espurna/sensors/DallasSensor.h View File

@ -133,15 +133,6 @@ class DallasSensor : public BaseSensor {
data[i] = _wire->read(); data[i] = _wire->read();
} }
#if false
Serial.printf("[DS18B20] Data = ");
for (unsigned char i = 0; i < DS_DATA_SIZE; i++) {
Serial.printf("%02X ", data[i]);
}
Serial.printf(" CRC = %02X\n", OneWire::crc8(data, DS_DATA_SIZE-1));
#endif
if (_wire->reset() != 1) { if (_wire->reset() != 1) {
// Force a CRC check error // Force a CRC check error
_devices[index].data[0] = _devices[index].data[0] + 1; _devices[index].data[0] = _devices[index].data[0] + 1;


+ 0
- 4
code/espurna/sensors/EmonADS1X15Sensor.h View File

@ -301,10 +301,6 @@ class EmonADS1X15Sensor : public EmonSensor {
} }
config |= ((channel + 4) << 12); // Set single-ended input channel (0x4000 - 0x7000) config |= ((channel + 4) << 12); // Set single-ended input channel (0x4000 - 0x7000)
#if SENSOR_DEBUG
//Serial.printf("[EMON] ADS1X115 Config Registry: %04X\n", config);
#endif
// Write config register to the ADC // Write config register to the ADC
i2c_write_uint16(_address, ADS1X15_REG_POINTER_CONFIG, config); i2c_write_uint16(_address, ADS1X15_REG_POINTER_CONFIG, config);


+ 4
- 0
code/espurna/sensors/EmonAnalogSensor.h View File

@ -7,6 +7,10 @@
#pragma once #pragma once
// Set ADC to TOUT pin
#undef ADC_MODE_VALUE
#define ADC_MODE_VALUE ADC_TOUT
#include "Arduino.h" #include "Arduino.h"
#include "EmonSensor.h" #include "EmonSensor.h"


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

@ -7,6 +7,10 @@
#pragma once #pragma once
#undef I2C_SUPPORT
#define I2C_SUPPORT 1 // Explicitly request I2C support.
#include "Arduino.h" #include "Arduino.h"
#include "I2CSensor.h" #include "I2CSensor.h"


+ 5
- 1
code/espurna/sensors/GUVAS12SDSensor.h View File

@ -8,6 +8,10 @@
#pragma once #pragma once
// Set ADC to TOUT pin
#undef ADC_MODE_VALUE
#define ADC_MODE_VALUE ADC_TOUT
#include "Arduino.h" #include "Arduino.h"
#include "BaseSensor.h" #include "BaseSensor.h"
@ -118,6 +122,7 @@ class GUVAS12SDSensor : public BaseSensor {
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
void _read() { void _read() {
int _average = 0; int _average = 0;
#if UV_SAMPLE_RATE == 1 #if UV_SAMPLE_RATE == 1
@ -157,7 +162,6 @@ class GUVAS12SDSensor : public BaseSensor {
_uvindex = 10; _uvindex = 10;
} }
return _uvindex;
} }
unsigned char _gpio = GPIO_NONE; unsigned char _gpio = GPIO_NONE;


+ 207
- 34
code/espurna/sensors/PMSX003Sensor.h View File

@ -1,7 +1,8 @@
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
// PMSX003 Dust Sensor
// PMS Dust Sensor
// Uses SoftwareSerial library // Uses SoftwareSerial library
// Contribution by Òscar Rovira López // Contribution by Òscar Rovira López
// Refine to support PMS5003T/PMS5003ST by Yonsm Guo
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#if SENSOR_SUPPORT && PMSX003_SUPPORT #if SENSOR_SUPPORT && PMSX003_SUPPORT
@ -11,10 +12,141 @@
#include "Arduino.h" #include "Arduino.h"
#include "BaseSensor.h" #include "BaseSensor.h"
#include <PMS.h>
#include <SoftwareSerial.h> #include <SoftwareSerial.h>
class PMSX003Sensor : public BaseSensor {
// Type of sensor
#define PMS_TYPE_X003 0
#define PMS_TYPE_X003_9 1
#define PMS_TYPE_5003T 2
#define PMS_TYPE_5003ST 3
// Sensor type specified data
#define PMS_SLOT_MAX 4
#define PMS_DATA_MAX 17
const static struct {
const char *name;
unsigned char data_count;
unsigned char slot_count;
unsigned char slot_types[PMS_SLOT_MAX];
} pms_specs[] = {
{"PMSX003", 13, 3, {MAGNITUDE_PM1dot0, MAGNITUDE_PM2dot5, MAGNITUDE_PM10}},
{"PMSX003_9", 9, 3, {MAGNITUDE_PM1dot0, MAGNITUDE_PM2dot5, MAGNITUDE_PM10}},
{"PMS5003T", 13, 3, {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY}},
{"PMS5003ST", 17, 4, {MAGNITUDE_PM2dot5, MAGNITUDE_TEMPERATURE, MAGNITUDE_HUMIDITY, MAGNITUDE_HCHO}}
};
// [MAGIC][LEN][DATA9|13|17][SUM]
#define PMS_PACKET_SIZE(data_count) ((data_count + 3) * 2)
#define PMS_PAYLOAD_SIZE(data_count) ((data_count + 1) * 2)
// PMS sensor utils
// Command functions copied from: https://github.com/fu-hsi/PMS/blob/master/src/PMS.cpp
// Reading function is rewrited to support flexible reading for PMS5003T/PMS5003ST
class PMSX003 {
protected:
SoftwareSerial *_serial = NULL; // Should initialized by child class
public:
// Standby mode. For low power consumption and prolong the life of the sensor.
inline void sleep() {
uint8_t command[] = { 0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73 };
_serial->write(command, sizeof(command));
}
// Operating mode. Stable data should be got at least 30 seconds after the sensor wakeup from the sleep mode because of the fan's performance.
inline void wakeUp() {
uint8_t command[] = { 0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74 };
_serial->write(command, sizeof(command));
}
// Active mode. Default mode after power up. In this mode sensor would send serial data to the host automatically.
inline void activeMode() {
uint8_t command[] = { 0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71 };
_serial->write(command, sizeof(command));
}
// Passive mode. In this mode, sensor would send serial data to the host only for request.
inline void passiveMode() {
uint8_t command[] = { 0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70 };
_serial->write(command, sizeof(command));
}
// Request read, ONLY needed in Passive Mode!!
inline void requestRead() {
uint8_t command[] = { 0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71 };
_serial->write(command, sizeof(command));
}
// Read sensor's data
bool readData(uint16_t data[], unsigned char data_count) {
do {
int avail = _serial->available();
#if SENSOR_DEBUG
//debugSend("[SENSOR] PMS: Packet available = %d\n", avail);
#endif
if (avail < PMS_PACKET_SIZE(data_count)) {
break;
}
if (_serial->read() == 0x42 && _serial->read() == 0x4D) {
uint16_t sum = 0x42 + 0x4D;
uint16_t size = read16(sum);
if (size != PMS_PAYLOAD_SIZE(data_count)) {
#if SENSOR_DEBUG
debugSend(("[SENSOR] PMS: Payload size: %d != %d.\n"), size, PMS_PAYLOAD_SIZE(data_count));
#endif
break;
}
for (int i = 0; i < data_count; i++) {
data[i] = read16(sum);
#if SENSOR_DEBUG
//debugSend(("[SENSOR] PMS: data[%d] = %d\n"), i, data[i]);
#endif
}
uint16_t checksum = read16();
if (sum == checksum) {
return true;
} else {
#if SENSOR_DEBUG
debugSend(("[SENSOR] PMS checksum: %04X != %04X\n"), sum, checksum);
#endif
}
break;
}
} while (true);
return false;
}
private:
// Read 16-bit
inline uint16_t read16() {
return ((uint16_t) _serial->read()) << 8 | _serial->read();
}
// Read 16-bit and calculate checksum
uint16_t read16(uint16_t &checksum) {
uint8_t high = _serial->read();
uint8_t low = _serial->read();
checksum += high;
checksum += low;
return ((uint16_t) high) << 8 | low;
}
};
class PMSX003Sensor : public BaseSensor, PMSX003 {
public: public:
@ -23,13 +155,12 @@ class PMSX003Sensor : public BaseSensor {
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
PMSX003Sensor(): BaseSensor() { PMSX003Sensor(): BaseSensor() {
_count = 3;
_count = pms_specs[_type].slot_count;
_sensor_id = SENSOR_PMSX003_ID; _sensor_id = SENSOR_PMSX003_ID;
} }
~PMSX003Sensor() { ~PMSX003Sensor() {
if (_serial) delete _serial; if (_serial) delete _serial;
if (_pms) delete _pms;
} }
void setRX(unsigned char pin_rx) { void setRX(unsigned char pin_rx) {
@ -44,6 +175,12 @@ class PMSX003Sensor : public BaseSensor {
_dirty = true; _dirty = true;
} }
// Should call setType after constrcutor immediately to enable corresponding slot count
void setType(unsigned char type) {
_type = type;
_count = pms_specs[_type].slot_count;
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
unsigned char getRX() { unsigned char getRX() {
@ -54,6 +191,10 @@ class PMSX003Sensor : public BaseSensor {
return _pin_tx; return _pin_tx;
} }
unsigned char getType() {
return _type;
}
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
// Sensor API // Sensor API
// --------------------------------------------------------------------- // ---------------------------------------------------------------------
@ -64,13 +205,11 @@ class PMSX003Sensor : public BaseSensor {
if (!_dirty) return; if (!_dirty) return;
if (_serial) delete _serial; if (_serial) delete _serial;
if (_pms) delete _pms;
_serial = new SoftwareSerial(_pin_rx, _pin_tx, false, 32);
_serial = new SoftwareSerial(_pin_rx, _pin_tx, false, 64);
_serial->enableIntTx(false); _serial->enableIntTx(false);
_serial->begin(9600); _serial->begin(9600);
_pms = new PMS(* _serial);
_pms->passiveMode();
passiveMode();
_startTime = millis(); _startTime = millis();
_ready = true; _ready = true;
@ -81,16 +220,14 @@ class PMSX003Sensor : public BaseSensor {
// Descriptive name of the sensor // Descriptive name of the sensor
String description() { String description() {
char buffer[28]; char buffer[28];
snprintf(buffer, sizeof(buffer), "PMSX003 @ SwSerial(%u,%u)", _pin_rx, _pin_tx);
snprintf(buffer, sizeof(buffer), "%s @ SwSerial(%u,%u)", pms_specs[_type].name, _pin_rx, _pin_tx);
return String(buffer); return String(buffer);
} }
// Descriptive name of the slot # index // Descriptive name of the slot # index
String slot(unsigned char index) { String slot(unsigned char index) {
char buffer[36] = {0}; char buffer[36] = {0};
if (index == 0) snprintf(buffer, sizeof(buffer), "PM1.0 @ PMSX003 @ SwSerial(%u,%u)", _pin_rx, _pin_tx);
if (index == 1) snprintf(buffer, sizeof(buffer), "PM2.5 @ PMSX003 @ SwSerial(%u,%u)", _pin_rx, _pin_tx);
if (index == 2) snprintf(buffer, sizeof(buffer), "PM10 @ PMSX003 @ SwSerial(%u,%u)", _pin_rx, _pin_tx);
snprintf(buffer, sizeof(buffer), "%d @ %s @ SwSerial(%u,%u)", int(index + 1), pms_specs[_type].name, _pin_rx, _pin_tx);
return String(buffer); return String(buffer);
} }
@ -103,10 +240,7 @@ class PMSX003Sensor : public BaseSensor {
// Type for slot # index // Type for slot # index
unsigned char type(unsigned char index) { unsigned char type(unsigned char index) {
if (index == 0) return MAGNITUDE_PM1dot0;
if (index == 1) return MAGNITUDE_PM2dot5;
if (index == 2) return MAGNITUDE_PM10;
return MAGNITUDE_NONE;
return pms_specs[_type].slot_types[index];
} }
void pre() { void pre() {
@ -118,35 +252,74 @@ class PMSX003Sensor : public BaseSensor {
_error = SENSOR_ERROR_OK; _error = SENSOR_ERROR_OK;
if(_pms->read(_data)) {
_pm1dot0 = _data.PM_AE_UG_1_0;
_pm2dot5 = _data.PM_AE_UG_2_5;
_pm10 = _data.PM_AE_UG_10_0;
#if PMS_SMART_SLEEP
unsigned int readCycle;
if (_readCount++ > 30) {
readCycle = _readCount % 30;
if (readCycle == 0) {
#if SENSOR_DEBUG
debugSend("[SENSOR] %s: Wake up: %d\n", pms_specs[_type].name, _readCount);
#endif
wakeUp();
return;
} else if (readCycle == 1) {
requestRead();
} else if (readCycle > 6) {
return;
}
} else {
readCycle = -1;
}
#endif
uint16_t data[PMS_DATA_MAX];
if (readData(data, pms_specs[_type].data_count)) {
if (_type == PMS_TYPE_5003ST) {
_slot_values[0] = data[4];
_slot_values[1] = (double)data[13] / 10;
_slot_values[2] = (double)data[14] / 10;
_slot_values[3] = (double)data[12] / 1000;
} else if (_type == PMS_TYPE_5003T) {
_slot_values[0] = data[4];
_slot_values[1] = (double)data[10] / 10;
_slot_values[2] = (double)data[11] / 10;
} else {
_slot_values[0] = data[3];
_slot_values[1] = data[4];
_slot_values[2] = data[5];
}
} }
_pms->requestRead();
#if PMS_SMART_SLEEP
if (readCycle == 6) {
sleep();
#if SENSOR_DEBUG
debugSend("[SENSOR] %s: Enter sleep mode: %d\n", pms_specs[_type].name, _readCount);
#endif
return;
}
#endif
requestRead();
} }
// Current value for slot # index // Current value for slot # index
double value(unsigned char index) { double value(unsigned char index) {
if(index == 0) return _pm1dot0;
if(index == 1) return _pm2dot5;
if(index == 2) return _pm10;
return 0;
return _slot_values[index];
} }
protected: protected:
unsigned int _pm1dot0;
unsigned int _pm2dot5;
unsigned int _pm10;
unsigned int _pin_rx; unsigned int _pin_rx;
unsigned int _pin_tx; unsigned int _pin_tx;
unsigned long _startTime; unsigned long _startTime;
SoftwareSerial * _serial = NULL;
PMS * _pms = NULL;
PMS::DATA _data;
unsigned char _type = PMS_TYPE_X003;
double _slot_values[PMS_SLOT_MAX] = {0};
#if PMS_SMART_SLEEP
unsigned int _readCount = 0;
#endif
}; };
#endif // SENSOR_SUPPORT && PMSX003_SUPPORT
#endif // SENSOR_SUPPORT && PMS_SUPPORT

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

@ -7,6 +7,10 @@
#pragma once #pragma once
#undef I2C_SUPPORT
#define I2C_SUPPORT 1 // Explicitly request I2C support.
#include "Arduino.h" #include "Arduino.h"
#include "I2CSensor.h" #include "I2CSensor.h"


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

@ -7,6 +7,11 @@
#pragma once #pragma once
#undef I2C_SUPPORT
#define I2C_SUPPORT 1 // Explicitly request I2C support.
#include "Arduino.h" #include "Arduino.h"
#include "I2CSensor.h" #include "I2CSensor.h"


+ 233
- 0
code/espurna/sensors/SenseAirSensor.h View File

@ -0,0 +1,233 @@
// -----------------------------------------------------------------------------
// SenseAir S8 CO2 Sensor
// Uses SoftwareSerial library
// Contribution by Yonsm Guo
// -----------------------------------------------------------------------------
#if SENSOR_SUPPORT && SENSEAIR_SUPPORT
#pragma once
#include "Arduino.h"
#include "BaseSensor.h"
#include <SoftwareSerial.h>
// SenseAir sensor utils
class SenseAir
{
protected:
SoftwareSerial *_serial; // Should initialized by child class
public:
int sendCommand(byte command[]) {
byte recv_buf[7] = {0xff};
byte data_buf[2] = {0xff};
long value = -1;
_serial->write(command, 8); //Send the byte array
delay(50);
// Read answer from sensor
int ByteCounter = 0;
while(_serial->available()) {
recv_buf[ByteCounter] = _serial->read();
ByteCounter++;
}
data_buf[0] = recv_buf[3];
data_buf[1] = recv_buf[4];
value = (data_buf[0] << 8) | (data_buf[1]);
return value;
}
int readCo2(void) {
int co2 = 0;
byte frame[8] = {0};
buildFrame(0xFE, 0x04, 0x03, 1, frame);
co2 = sendCommand(frame);
return co2;
}
private:
// Compute the MODBUS RTU CRC
static unsigned int modRTU_CRC(byte buf[], int len, byte checkSum[2]) {
unsigned int crc = 0xFFFF;
for (int pos = 0; pos < len; pos++) {
crc ^= (unsigned int)buf[pos]; // XOR byte into least sig. byte of crc
for (int i = 8; i != 0; i--) { // Loop over each bit
if ((crc & 0x0001) != 0) { // If the LSB is set
crc >>= 1; // Shift right and XOR 0xA001
crc ^= 0xA001;
}
else // Else LSB is not set
crc >>= 1; // Just shift right
}
}
// Note, this number has low and high bytes swapped, so use it accordingly (or swap bytes)
checkSum[1] = (byte)((crc >> 8) & 0xFF);
checkSum[0] = (byte)(crc & 0xFF);
return crc;
}
static int getBitOfInt(int reg, int pos) {
// Create a mask
int mask = 0x01 << pos;
// Mask the status register
int masked_register = mask & reg;
// Shift the result of masked register back to position 0
int result = masked_register >> pos;
return result;
}
static void buildFrame(byte slaveAddress,
byte functionCode,
short startAddress,
short numberOfRegisters,
byte frame[8]) {
frame[0] = slaveAddress;
frame[1] = functionCode;
frame[2] = (byte)(startAddress >> 8);
frame[3] = (byte)(startAddress);
frame[4] = (byte)(numberOfRegisters >> 8);
frame[5] = (byte)(numberOfRegisters);
// CRC-calculation
byte checkSum[2] = {0};
modRTU_CRC(frame, 6, checkSum);
frame[6] = checkSum[0];
frame[7] = checkSum[1];
}
};
//
class SenseAirSensor : public BaseSensor, SenseAir {
public:
// ---------------------------------------------------------------------
// Public
// ---------------------------------------------------------------------
SenseAirSensor(): BaseSensor() {
_count = 1;
_co2 = 0;
_lastCo2 = 0;
_serial = NULL;
_sensor_id = SENSOR_SENSEAIR_ID;
}
~SenseAirSensor() {
if (_serial) delete _serial;
_serial = NULL;
}
void setRX(unsigned char pin_rx) {
if (_pin_rx == pin_rx) return;
_pin_rx = pin_rx;
_dirty = true;
}
void setTX(unsigned char pin_tx) {
if (_pin_tx == pin_tx) return;
_pin_tx = pin_tx;
_dirty = true;
}
// ---------------------------------------------------------------------
unsigned char getRX() {
return _pin_rx;
}
unsigned char getTX() {
return _pin_tx;
}
// ---------------------------------------------------------------------
// Sensor API
// ---------------------------------------------------------------------
// Initialization method, must be idempotent
void begin() {
if (!_dirty) return;
if (_serial) delete _serial;
_serial = new SoftwareSerial(_pin_rx, _pin_tx, false, 64);
_serial->enableIntTx(false);
_serial->begin(9600);
_serial->enableRx(true);
_startTime = 0;
_ready = true;
_dirty = false;
}
// Descriptive name of the sensor
String description() {
char buffer[28];
snprintf(buffer, sizeof(buffer), "SenseAir S8 @ SwSerial(%u,%u)", _pin_rx, _pin_tx);
return String(buffer);
}
// Descriptive name of the slot # index
String slot(unsigned char index) {
return description();
}
// Address of the sensor (it could be the GPIO or I2C address)
String address(unsigned char index) {
char buffer[6];
snprintf(buffer, sizeof(buffer), "%u:%u", _pin_rx, _pin_tx);
return String(buffer);
}
// Type for slot # index
unsigned char type(unsigned char index) {
return MAGNITUDE_CO2;
}
void pre() {
if (millis() - _startTime < 20000) {
_error = SENSOR_ERROR_WARM_UP;
return;
}
_error = SENSOR_ERROR_OK;
unsigned int co2 = readCo2();
if (co2 >= 5000 || co2 < 100)
{
_co2 = _lastCo2;
}
else
{
_co2 = (co2 > _lastCo2 + 2000) ? _lastCo2 : co2;
_lastCo2 = co2;
}
}
// Current value for slot # index
double value(unsigned char index) {
return _co2;
}
protected:
unsigned int _pin_rx;
unsigned int _pin_tx;
unsigned long _startTime;
unsigned int _co2;
unsigned int _lastCo2;
};
#endif // SENSOR_SUPPORT && SENSEAIR_SUPPORT

+ 4
- 0
code/espurna/sensors/TMP3XSensor.h View File

@ -7,6 +7,10 @@
#pragma once #pragma once
// Set ADC to TOUT pin
#undef ADC_MODE_VALUE
#define ADC_MODE_VALUE ADC_TOUT
#include "Arduino.h" #include "Arduino.h"
#include "BaseSensor.h" #include "BaseSensor.h"


+ 21
- 24
code/espurna/settings.ino View File

@ -10,21 +10,10 @@ Copyright (C) 2016-2018 by Xose Pérez <xose dot perez at gmail dot com>
#include <vector> #include <vector>
#include "libs/EmbedisWrap.h" #include "libs/EmbedisWrap.h"
#include <Stream.h> #include <Stream.h>
#include "libs/StreamInjector.h"
#ifdef DEBUG_PORT
#define EMBEDIS_PORT DEBUG_PORT
#else
#define EMBEDIS_PORT Serial
#endif
#if TELNET_SUPPORT
#include "libs/StreamInjector.h"
StreamInjector _serial = StreamInjector(EMBEDIS_PORT, TERMINAL_BUFFER_SIZE);
#undef EMBEDIS_PORT
#define EMBEDIS_PORT _serial
#endif
EmbedisWrap embedis(EMBEDIS_PORT, TERMINAL_BUFFER_SIZE);
StreamInjector _serial = StreamInjector(TERMINAL_BUFFER_SIZE);
EmbedisWrap embedis(_serial, TERMINAL_BUFFER_SIZE);
#if TERMINAL_SUPPORT #if TERMINAL_SUPPORT
#if SERIAL_RX_ENABLED #if SERIAL_RX_ENABLED
@ -360,11 +349,9 @@ void resetSettings() {
// Settings // Settings
// ----------------------------------------------------------------------------- // -----------------------------------------------------------------------------
#if TELNET_SUPPORT
void settingsInject(void *data, size_t len) {
_serial.inject((char *) data, len);
}
#endif
void settingsInject(void *data, size_t len) {
_serial.inject((char *) data, len);
}
size_t settingsMaxSize() { size_t settingsMaxSize() {
size_t size = EEPROM_SIZE; size_t size = EEPROM_SIZE;
@ -395,7 +382,7 @@ bool settingsRestoreJson(JsonObject& data) {
} }
bool settingsGetJson(JsonObject& root) {
void settingsGetJson(JsonObject& root) {
// Get sorted list of keys // Get sorted list of keys
std::vector<String> keys = _settingsKeys(); std::vector<String> keys = _settingsKeys();
@ -420,11 +407,14 @@ void settingsSetup() {
EEPROM.begin(SPI_FLASH_SEC_SIZE); EEPROM.begin(SPI_FLASH_SEC_SIZE);
#if TELNET_SUPPORT
_serial.callback([](uint8_t ch) {
_serial.callback([](uint8_t ch) {
#if TELNET_SUPPORT
telnetWrite(ch); telnetWrite(ch);
});
#endif
#endif
#if DEBUG_SERIAL_SUPPORT
DEBUG_PORT.write(ch);
#endif
});
Embedis::dictionary( F("EEPROM"), Embedis::dictionary( F("EEPROM"),
SPI_FLASH_SEC_SIZE, SPI_FLASH_SEC_SIZE,
@ -457,8 +447,15 @@ void settingsLoop() {
_settings_save = false; _settings_save = false;
} }
#if TERMINAL_SUPPORT #if TERMINAL_SUPPORT
#if DEBUG_SERIAL_SUPPORT
while (DEBUG_PORT.available()) {
_serial.inject(DEBUG_PORT.read());
}
#endif
embedis.process(); embedis.process();
#if SERIAL_RX_ENABLED #if SERIAL_RX_ENABLED


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


+ 17
- 13
code/espurna/system.ino View File

@ -130,19 +130,26 @@ void systemLoop() {
} }
void systemSetup() {
void _systemSetupSpecificHardware() {
EEPROM.begin(EEPROM_SIZE);
//The ESPLive has an ADC MUX which needs to be configured.
#if defined(MANCAVEMADE_ESPLIVE)
pinMode(16, OUTPUT);
digitalWrite(16, HIGH); //Defualt CT input (pin B, solder jumper B)
#endif
#if DEBUG_SERIAL_SUPPORT
DEBUG_PORT.begin(SERIAL_BAUDRATE);
#if DEBUG_ESP_WIFI
DEBUG_PORT.setDebugOutput(true);
#endif
#elif defined(SERIAL_BAUDRATE)
// These devices use the hardware UART
// to communicate to secondary microcontrollers
#if defined(ITEAD_SONOFF_RFBRIDGE) || defined(ITEAD_SONOFF_DUAL) || defined(STM_RELAY)
Serial.begin(SERIAL_BAUDRATE); Serial.begin(SERIAL_BAUDRATE);
#endif #endif
}
void systemSetup() {
EEPROM.begin(EEPROM_SIZE);
#if SPIFFS_SUPPORT #if SPIFFS_SUPPORT
SPIFFS.begin(); SPIFFS.begin();
#endif #endif
@ -152,11 +159,8 @@ void systemSetup() {
systemCheck(false); systemCheck(false);
#endif #endif
#if defined(ESPLIVE)
//The ESPLive has an ADC MUX which needs to be configured.
pinMode(16, OUTPUT);
digitalWrite(16, HIGH); //Defualt CT input (pin B, solder jumper B)
#endif
// Init device-specific hardware
_systemSetupSpecificHardware();
// Cache loop delay value to speed things (recommended max 250ms) // Cache loop delay value to speed things (recommended max 250ms)
_loop_delay = atol(getSetting("loopDelay", LOOP_DELAY_TIME).c_str()); _loop_delay = atol(getSetting("loopDelay", LOOP_DELAY_TIME).c_str());


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

@ -66,6 +66,15 @@ void _telnetData(unsigned char clientId, void *data, size_t len) {
// Capture close connection // Capture close connection
char * p = (char *) data; char * p = (char *) data;
// C-d is sent as two bytes (sometimes repeating)
if (len >= 2) {
if ((p[0] == 0xFF) && (p[1] == 0xEC)) {
_telnetClients[clientId]->close(true);
return;
}
}
if ((strncmp(p, "close", 5) == 0) || (strncmp(p, "quit", 4) == 0)) { if ((strncmp(p, "close", 5) == 0) || (strncmp(p, "quit", 4) == 0)) {
_telnetClients[clientId]->close(); _telnetClients[clientId]->close();
return; return;


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

@ -192,7 +192,7 @@ void _tspkPost(String data) {
#endif // THINGSPEAK_USE_ASYNC #endif // THINGSPEAK_USE_ASYNC
bool _tspkEnqueue(unsigned char index, char * payload) {
void _tspkEnqueue(unsigned char index, char * payload) {
DEBUG_MSG_P(PSTR("[THINGSPEAK] Enqueuing field #%d with value %s\n"), index, payload); DEBUG_MSG_P(PSTR("[THINGSPEAK] Enqueuing field #%d with value %s\n"), index, payload);
--index; --index;
if (_tspk_queue[index] != NULL) free(_tspk_queue[index]); if (_tspk_queue[index] != NULL) free(_tspk_queue[index]);
@ -230,7 +230,9 @@ bool tspkEnqueueRelay(unsigned char index, unsigned char status) {
char payload[3] = {0}; char payload[3] = {0};
itoa(status ? 1 : 0, payload, 10); itoa(status ? 1 : 0, payload, 10);
_tspkEnqueue(id, payload); _tspkEnqueue(id, payload);
return true;
} }
return false;
} }
bool tspkEnqueueMeasurement(unsigned char index, char * payload) { bool tspkEnqueueMeasurement(unsigned char index, char * payload) {
@ -238,7 +240,9 @@ bool tspkEnqueueMeasurement(unsigned char index, char * payload) {
unsigned char id = getSetting("tspkMagnitude", index, 0).toInt(); unsigned char id = getSetting("tspkMagnitude", index, 0).toInt();
if (id > 0) { if (id > 0) {
_tspkEnqueue(id, payload); _tspkEnqueue(id, payload);
return true;
} }
return false;
} }
void tspkFlush() { void tspkFlush() {


+ 26
- 3
code/espurna/utils.ino View File

@ -123,7 +123,7 @@ void heartbeat() {
if (serial) { if (serial) {
DEBUG_MSG_P(PSTR("[MAIN] Uptime: %lu seconds\n"), uptime_seconds); DEBUG_MSG_P(PSTR("[MAIN] Uptime: %lu seconds\n"), uptime_seconds);
DEBUG_MSG_P(PSTR("[MAIN] Free heap: %lu bytes\n"), free_heap); DEBUG_MSG_P(PSTR("[MAIN] Free heap: %lu bytes\n"), free_heap);
#if ADC_VCC_ENABLED
#if ADC_MODE_VALUE == ADC_VCC
DEBUG_MSG_P(PSTR("[MAIN] Power: %lu mV\n"), ESP.getVcc()); DEBUG_MSG_P(PSTR("[MAIN] Power: %lu mV\n"), ESP.getVcc());
#endif #endif
#if NTP_SUPPORT #if NTP_SUPPORT
@ -177,7 +177,7 @@ void heartbeat() {
lightMQTT(); lightMQTT();
#endif #endif
#if (HEARTBEAT_REPORT_VCC) #if (HEARTBEAT_REPORT_VCC)
#if ADC_VCC_ENABLED
#if ADC_MODE_VALUE == ADC_VCC
mqttSend(MQTT_TOPIC_VCC, String(ESP.getVcc()).c_str()); mqttSend(MQTT_TOPIC_VCC, String(ESP.getVcc()).c_str());
#endif #endif
#endif #endif
@ -278,6 +278,9 @@ void info() {
#if DEBUG_UDP_SUPPORT #if DEBUG_UDP_SUPPORT
DEBUG_MSG_P(PSTR(" DEBUG_UDP")); DEBUG_MSG_P(PSTR(" DEBUG_UDP"));
#endif #endif
#if DEBUG_WEB_SUPPORT
DEBUG_MSG_P(PSTR(" DEBUG_WEB"));
#endif
#if DOMOTICZ_SUPPORT #if DOMOTICZ_SUPPORT
DEBUG_MSG_P(PSTR(" DOMOTICZ")); DEBUG_MSG_P(PSTR(" DOMOTICZ"));
#endif #endif
@ -353,9 +356,15 @@ void info() {
#if ANALOG_SUPPORT #if ANALOG_SUPPORT
DEBUG_MSG_P(PSTR(" ANALOG")); DEBUG_MSG_P(PSTR(" ANALOG"));
#endif #endif
#if BH1750_SUPPORT
DEBUG_MSG_P(PSTR(" BH1750"));
#endif
#if BMX280_SUPPORT #if BMX280_SUPPORT
DEBUG_MSG_P(PSTR(" BMX280")); DEBUG_MSG_P(PSTR(" BMX280"));
#endif #endif
#if CSE7766_SUPPORT
DEBUG_MSG_P(PSTR(" CSE7766"));
#endif
#if DALLAS_SUPPORT #if DALLAS_SUPPORT
DEBUG_MSG_P(PSTR(" DALLAS")); DEBUG_MSG_P(PSTR(" DALLAS"));
#endif #endif
@ -383,6 +392,9 @@ void info() {
#if GUVAS12SD_SUPPORT #if GUVAS12SD_SUPPORT
DEBUG_MSG_P(PSTR(" GUVAS12SD")); DEBUG_MSG_P(PSTR(" GUVAS12SD"));
#endif #endif
#if HCSR04_SUPPORT
DEBUG_MSG_P(PSTR(" HCSR04"));
#endif
#if HLW8012_SUPPORT #if HLW8012_SUPPORT
DEBUG_MSG_P(PSTR(" HLW8012")); DEBUG_MSG_P(PSTR(" HLW8012"));
#endif #endif
@ -395,12 +407,18 @@ void info() {
#if PZEM004T_SUPPORT #if PZEM004T_SUPPORT
DEBUG_MSG_P(PSTR(" PZEM004T")); DEBUG_MSG_P(PSTR(" PZEM004T"));
#endif #endif
#if SENSEAIR_SUPPORT
DEBUG_MSG_P(PSTR(" SENSEAIR"));
#endif
#if SHT3X_I2C_SUPPORT #if SHT3X_I2C_SUPPORT
DEBUG_MSG_P(PSTR(" SHT3X_I2C")); DEBUG_MSG_P(PSTR(" SHT3X_I2C"));
#endif #endif
#if SI7021_SUPPORT #if SI7021_SUPPORT
DEBUG_MSG_P(PSTR(" SI7021")); DEBUG_MSG_P(PSTR(" SI7021"));
#endif #endif
#if TMP3X_SUPPORT
DEBUG_MSG_P(PSTR(" TMP3X"));
#endif
#if V9261F_SUPPORT #if V9261F_SUPPORT
DEBUG_MSG_P(PSTR(" V9261F")); DEBUG_MSG_P(PSTR(" V9261F"));
#endif #endif
@ -422,7 +440,7 @@ void info() {
DEBUG_MSG_P(PSTR("[INIT] Settings size: %u bytes\n"), settingsSize()); DEBUG_MSG_P(PSTR("[INIT] Settings size: %u bytes\n"), settingsSize());
DEBUG_MSG_P(PSTR("[INIT] Free heap: %u bytes\n"), getFreeHeap()); DEBUG_MSG_P(PSTR("[INIT] Free heap: %u bytes\n"), getFreeHeap());
#if ADC_VCC_ENABLED
#if ADC_MODE_VALUE == ADC_VCC
DEBUG_MSG_P(PSTR("[INIT] Power: %u mV\n"), ESP.getVcc()); DEBUG_MSG_P(PSTR("[INIT] Power: %u mV\n"), ESP.getVcc());
#endif #endif
@ -525,3 +543,8 @@ void nice_delay(unsigned long ms) {
unsigned long start = millis(); unsigned long start = millis();
while (millis() - start < ms) delay(1); while (millis() - start < ms) delay(1);
} }
// This method is called by the SDK to know where to connect the ADC
int __get_adc_mode() {
return (int) (ADC_MODE_VALUE);
}

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

@ -196,6 +196,27 @@ void _wifiInject() {
} }
} }
#if WIFI_AP_CAPTIVE
DNSServer _wifi_dnsServer;
void _wifiCaptivePortal(justwifi_messages_t code, char * parameter) {
if (MESSAGE_ACCESSPOINT_CREATED == code) {
_wifi_dnsServer.setErrorReplyCode(DNSReplyCode::NoError);
_wifi_dnsServer.start(53, "*", WiFi.softAPIP());
DEBUG_MSG_P(PSTR("[WIFI] Captive portal enabled\n"));
}
if (MESSAGE_CONNECTED == code) {
_wifi_dnsServer.stop();
DEBUG_MSG_P(PSTR("[WIFI] Captive portal disabled\n"));
}
}
#endif // WIFI_AP_CAPTIVE
#if DEBUG_SUPPORT #if DEBUG_SUPPORT
void _wifiDebug(justwifi_messages_t code, char * parameter) { void _wifiDebug(justwifi_messages_t code, char * parameter) {
@ -422,6 +443,9 @@ void wifiSetup() {
_wifiConfigure(); _wifiConfigure();
// Message callbacks // Message callbacks
#if WIFI_AP_CAPTIVE
wifiRegister(_wifiCaptivePortal);
#endif
#if DEBUG_SUPPORT #if DEBUG_SUPPORT
wifiRegister(_wifiDebug); wifiRegister(_wifiDebug);
#endif #endif
@ -446,6 +470,12 @@ void wifiLoop() {
jw.loop(); jw.loop();
#if WIFI_AP_CAPTIVE
if ((WiFi.getMode() & WIFI_AP) == WIFI_AP) {
_wifi_dnsServer.processNextRequest();
}
#endif
if (_wifi_scan_client_id > 0) { if (_wifi_scan_client_id > 0) {
_wifiScan(_wifi_scan_client_id); _wifiScan(_wifi_scan_client_id);
_wifi_scan_client_id = 0; _wifi_scan_client_id = 0;


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

@ -235,7 +235,9 @@ void _wsUpdate(JsonObject& root) {
root["uptime"] = getUptime(); root["uptime"] = getUptime();
root["rssi"] = WiFi.RSSI(); root["rssi"] = WiFi.RSSI();
root["loadaverage"] = systemLoadAverage(); root["loadaverage"] = systemLoadAverage();
root["vcc"] = ESP.getVcc();
#if ADC_MODE_VALUE == ADC_VCC
root["vcc"] = ESP.getVcc();
#endif
#if NTP_SUPPORT #if NTP_SUPPORT
if (ntpSynced()) root["now"] = now(); if (ntpSynced()) root["now"] = now();
#endif #endif


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

@ -6,6 +6,7 @@
font-size: 100%; font-size: 100%;
padding: .5em .5em; padding: .5em .5em;
white-space: normal; white-space: normal;
text-transform: initial;
} }
.pure-g { .pure-g {


+ 18
- 14
code/html/custom.js View File

@ -39,7 +39,7 @@ function sensorName(id) {
"HLW8012", "V9261F", "ECH1560", "Analog", "Digital", "HLW8012", "V9261F", "ECH1560", "Analog", "Digital",
"Events", "PMSX003", "BMX280", "MHZ19", "SI7021", "Events", "PMSX003", "BMX280", "MHZ19", "SI7021",
"SHT3X I2C", "BH1750", "PZEM004T", "AM2320 I2C", "GUVAS12SD", "SHT3X I2C", "BH1750", "PZEM004T", "AM2320 I2C", "GUVAS12SD",
"TMP3X", "HC-SR04"
"TMP3X", "HC-SR04", "SenseAir"
]; ];
if (1 <= id && id <= names.length) { if (1 <= id && id <= names.length) {
return names[id - 1]; return names[id - 1];
@ -53,7 +53,7 @@ function magnitudeType(type) {
"Current", "Voltage", "Active Power", "Apparent Power", "Current", "Voltage", "Active Power", "Apparent Power",
"Reactive Power", "Power Factor", "Energy", "Energy (delta)", "Reactive Power", "Power Factor", "Energy", "Energy (delta)",
"Analog", "Digital", "Events", "Analog", "Digital", "Events",
"PM1.0", "PM2.5", "PM10", "CO2", "Lux", "UV", "Distance"
"PM1.0", "PM2.5", "PM10", "CO2", "Lux", "UV", "Distance" , "HCHO"
]; ];
if (1 <= type && type <= types.length) { if (1 <= type && type <= types.length) {
return types[type - 1]; return types[type - 1];
@ -88,14 +88,17 @@ $.fn.enterKey = function (fnc) {
}; };
function keepTime() { function keepTime() {
$("span[name='ago']").html(ago);
ago++;
if (0 === now) { return; } if (0 === now) { return; }
var date = new Date(now * 1000); var date = new Date(now * 1000);
var text = date.toISOString().substring(0, 19).replace("T", " "); var text = date.toISOString().substring(0, 19).replace("T", " ");
$("input[name='now']").val(text); $("input[name='now']").val(text);
$("span[name='now']").html(text); $("span[name='now']").html(text);
$("span[name='ago']").html(ago);
now++; now++;
ago++;
} }
// http://www.the-art-of-web.com/javascript/validate-password/ // http://www.the-art-of-web.com/javascript/validate-password/
@ -179,7 +182,7 @@ function addValue(data, name, value) {
// These fields will always be a list of values // These fields will always be a list of values
var is_group = [ var is_group = [
"ssid", "pass", "gw", "mask", "ip", "dns", "ssid", "pass", "gw", "mask", "ip", "dns",
"schEnabled", "schSwitch","schAction","schType","schHour","schMinute","schWDs",
"schEnabled", "schSwitch","schAction","schType","schHour","schMinute","schWDs","schUTC",
"relayBoot", "relayPulse", "relayTime", "relayBoot", "relayPulse", "relayTime",
"mqttGroup", "mqttGroupInv", "relayOnDisc", "mqttGroup", "mqttGroupInv", "relayOnDisc",
"dczRelayIdx", "dczMagnitude", "dczRelayIdx", "dczMagnitude",
@ -858,13 +861,15 @@ function initChannels(num) {
var line = $(template).clone(); var line = $(template).clone();
$("span.slider", line).attr("data", channel_id); $("span.slider", line).attr("data", channel_id);
$("input.slider", line).attr("data", channel_id).on("change", onChannelSliderChange); $("input.slider", line).attr("data", channel_id).on("change", onChannelSliderChange);
$("label", line).html("Channel " + (channel_id + 1));
$("label", line).html("Channel #" + channel_id);
line.appendTo("#channels"); line.appendTo("#channels");
}
for (var i=0; i<num; i++) {
$("select.islight").append( $("select.islight").append(
$("<option></option>").attr("value",i).text("Channel #" + i)); $("<option></option>").attr("value",i).text("Channel #" + i));
} }
} }
@ -1032,7 +1037,9 @@ function processData(data) {
var text = (0 === error) ? var text = (0 === error) ?
magnitude.value + magnitude.units : magnitude.value + magnitude.units :
magnitudeError(error); magnitudeError(error);
$("input[name='magnitude'][data='" + i + "']").val(text);
var element = $("input[name='magnitude'][data='" + i + "']");
element.val(text);
$("div.hint", element.parent().parent()).html(magnitude.description);
} }
return; return;
} }
@ -1172,13 +1179,12 @@ function processData(data) {
var position = key.indexOf("Visible"); var position = key.indexOf("Visible");
if (position > 0 && position === key.length - 7) { if (position > 0 && position === key.length - 7) {
var module = key.slice(0,-7); var module = key.slice(0,-7);
$(".module-" + module).show();
$(".module-" + module).css("display", "inherit");
return; return;
} }
if ("now" === key) { if ("now" === key) {
now = value; now = value;
ago = 0;
return; return;
} }
@ -1187,9 +1193,6 @@ function processData(data) {
} }
// Pre-process // Pre-process
if ("network" === key) {
value = value.toUpperCase();
}
if ("mqttStatus" === key) { if ("mqttStatus" === key) {
value = value ? "CONNECTED" : "NOT CONNECTED"; value = value ? "CONNECTED" : "NOT CONNECTED";
} }
@ -1197,6 +1200,7 @@ function processData(data) {
value = value ? "SYNC'D" : "NOT SYNC'D"; value = value ? "SYNC'D" : "NOT SYNC'D";
} }
if ("uptime" === key) { if ("uptime" === key) {
ago = 0;
var uptime = parseInt(value, 10); var uptime = parseInt(value, 10);
var seconds = uptime % 60; uptime = parseInt(uptime / 60, 10); var seconds = uptime % 60; uptime = parseInt(uptime / 60, 10);
var minutes = uptime % 60; uptime = parseInt(uptime / 60, 10); var minutes = uptime % 60; uptime = parseInt(uptime / 60, 10);
@ -1303,7 +1307,7 @@ function initUrls(root) {
}); });
urls.ws.protocol = "ws"; urls.ws.protocol = "ws";
} }
function connectToURL(url) { function connectToURL(url) {


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

@ -209,8 +209,10 @@
<div class="pure-u-1-2">Firmware version</div> <div class="pure-u-1-2">Firmware version</div>
<div class="pure-u-11-24"><span class="right" name="app_version"></span></div> <div class="pure-u-11-24"><span class="right" name="app_version"></span></div>
<!--
<div class="pure-u-1-2">Firmware revision</div> <div class="pure-u-1-2">Firmware revision</div>
<div class="pure-u-11-24"><span class="right" name="app_revision"></span></div> <div class="pure-u-11-24"><span class="right" name="app_revision"></span></div>
-->
<div class="pure-u-1-2">Firmware build date</div> <div class="pure-u-1-2">Firmware build date</div>
<div class="pure-u-11-24"><span class="right" name="app_build"></span></div> <div class="pure-u-11-24"><span class="right" name="app_build"></span></div>
@ -247,16 +249,16 @@
<div class="pure-u-11-24"><span class="right" name="loadaverage"></span><span>%</span></div> <div class="pure-u-11-24"><span class="right" name="loadaverage"></span><span>%</span></div>
<div class="pure-u-1-2">VCC</div> <div class="pure-u-1-2">VCC</div>
<div class="pure-u-11-24"><span class="right" name="vcc"></span><span>mV</span></div>
<div class="pure-u-11-24"><span class="right" name="vcc">? </span><span>mV</span></div>
<div class="pure-u-1-2">MQTT Status</div>
<div class="pure-u-11-24"><span class="right" name="mqttStatus">NOT AVAILABLE</span></div>
<div class="pure-u-1-2 module module-mqtt">MQTT Status</div>
<div class="pure-u-11-24 module module-mqtt"><span class="right" name="mqttStatus"></span></div>
<div class="pure-u-1-2">NTP Status</div>
<div class="pure-u-11-24"><span class="right" name="ntpStatus">NOT AVAILABLE</span></div>
<div class="pure-u-1-2 module module-ntp">NTP Status</div>
<div class="pure-u-11-24 module module-ntp"><span class="right" name="ntpStatus"></span></div>
<div class="pure-u-1-2">Current time</div>
<div class="pure-u-11-24"><span class="right" name="now"></span></div>
<div class="pure-u-1-2 module module-ntp">Current time</div>
<div class="pure-u-11-24 module module-ntp"><span class="right" name="now"></span></div>
<div class="pure-u-1-2">Uptime</div> <div class="pure-u-1-2">Uptime</div>
<div class="pure-u-11-24"><span class="right" name="uptime"></span></div> <div class="pure-u-11-24"><span class="right" name="uptime"></span></div>
@ -1252,6 +1254,9 @@
</div> </div>
<div class="pure-u-0 pure-u-lg-1-3"></div> <div class="pure-u-0 pure-u-lg-1-3"></div>
<label class="pure-u-1 pure-u-lg-1-4">Use UTC time</label>
<div class="pure-u-1 pure-u-lg-3-4"><input type="checkbox" name="schUTC" /></div>
<label class="pure-u-1 pure-u-lg-1-4">And weekday is one of</label> <label class="pure-u-1 pure-u-lg-1-4">And weekday is one of</label>
<div class="pure-u-2-5 pure-u-lg-1-5"> <div class="pure-u-2-5 pure-u-lg-1-5">
<input class="pure-u-23-24 pure-u-lg-23-24" name="schWDs" type="text" maxlength="15" tabindex="0" value="1,2,3,4,5,6,7" /> <input class="pure-u-23-24 pure-u-lg-23-24" name="schWDs" type="text" maxlength="15" tabindex="0" value="1,2,3,4,5,6,7" />


+ 144
- 9
code/platformio.ini View File

@ -6,13 +6,16 @@ data_dir = espurna/data
[common] [common]
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
# PLATFORM: # PLATFORM:
# !! DO NOT confuse platformio's Esp8266 development platform with Arduino core for ESP8266
# !! DO NOT confuse platformio's ESP8266 development platform with Arduino core for ESP8266
# We use platformIO 1.5.0 as default
# #
# we use platformIO 1.5.0 as default
# platform 1.6.0 = arduino core 2.4.0 is required for newer features/boards
# platformIO 1.5.0 = arduino core 2.3.0
# platformIO 1.6.0 = arduino core 2.4.0
# platformIO 1.7.0 = arduino core 2.4.1
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
platform_150 = espressif8266@1.5.0 platform_150 = espressif8266@1.5.0
platform_160 = espressif8266@1.6.0 platform_160 = espressif8266@1.6.0
platform_170 = espressif8266@1.7.0
platform = ${common.platform_150} platform = ${common.platform_150}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
@ -26,8 +29,13 @@ debug_flags = -DDEBUG_ESP_CORE -DDEBUG_ESP_SSL -DDEBUG_ESP_WIFI -DDEBUG_ESP_HTTP
# build flags for 512k/1m ESP's are different because we use Linker Scripts to adjust flash split # build flags for 512k/1m ESP's are different because we use Linker Scripts to adjust flash split
# 512 KB = 487 KB sketch, 20 KB eeprom # 512 KB = 487 KB sketch, 20 KB eeprom
# 1 MB = 999 KB sketch, 20 KB eeprom # 1 MB = 999 KB sketch, 20 KB eeprom
#
# Available lwIP variants (macros):
# -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH v1.4 Higher Bandwidth (default)
# -DPIO_FRAMEWORK_ARDUINO_LWIP2_LOW_MEMORY v2 Lower Memory
# -DPIO_FRAMEWORK_ARDUINO_LWIP2_HIGHER_BANDWIDTH v2 Higher Bandwidth
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
build_flags = -g -DMQTT_MAX_PACKET_SIZE=400 ${env.ESPURNA_FLAGS}
build_flags = -g -DMQTT_MAX_PACKET_SIZE=400 ${env.ESPURNA_FLAGS} -DPIO_FRAMEWORK_ARDUINO_LWIP_HIGHER_BANDWIDTH
build_flags_512k = ${common.build_flags} -Wl,-Tesp8266.flash.512k0.ld build_flags_512k = ${common.build_flags} -Wl,-Tesp8266.flash.512k0.ld
build_flags_1m = ${common.build_flags} -Wl,-Tesp8266.flash.1m0.ld build_flags_1m = ${common.build_flags} -Wl,-Tesp8266.flash.1m0.ld
@ -50,19 +58,18 @@ lib_deps =
Brzo I2C Brzo I2C
https://bitbucket.org/xoseperez/debounceevent.git#2.0.1 https://bitbucket.org/xoseperez/debounceevent.git#2.0.1
Embedis Embedis
https://github.com/plerup/espsoftwareserial#7077979
https://github.com/plerup/espsoftwareserial#3.4.1
https://github.com/me-no-dev/ESPAsyncTCP#55cd520 https://github.com/me-no-dev/ESPAsyncTCP#55cd520
https://github.com/me-no-dev/ESPAsyncWebServer#232b87a https://github.com/me-no-dev/ESPAsyncWebServer#232b87a
https://bitbucket.org/xoseperez/fauxmoesp.git#2.4.2 https://bitbucket.org/xoseperez/fauxmoesp.git#2.4.2
https://github.com/xoseperez/hlw8012.git#1.1.0 https://github.com/xoseperez/hlw8012.git#1.1.0
https://github.com/markszabo/IRremoteESP8266#v2.2.0 https://github.com/markszabo/IRremoteESP8266#v2.2.0
https://bitbucket.org/xoseperez/justwifi.git#1.1.7
https://bitbucket.org/xoseperez/justwifi.git#1.1.8
https://github.com/madpilot/mDNSResolver#4cfcda1 https://github.com/madpilot/mDNSResolver#4cfcda1
https://github.com/xoseperez/my92xx#3.0.1 https://github.com/xoseperez/my92xx#3.0.1
https://bitbucket.org/xoseperez/nofuss.git#0.2.5 https://bitbucket.org/xoseperez/nofuss.git#0.2.5
https://github.com/xoseperez/NtpClient.git#0016a59 https://github.com/xoseperez/NtpClient.git#0016a59
OneWire OneWire
PMS Library
PZEM004T PZEM004T
PubSubClient PubSubClient
rc-switch rc-switch
@ -440,6 +447,31 @@ upload_flags = ${common.upload_flags}
monitor_baud = 115200 monitor_baud = 115200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-pow-r2]
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_POW_R2
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-pow-r2-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 = ${common.build_flags_1m} -DITEAD_SONOFF_POW_R2
upload_speed = 115200
upload_port = ${common.upload_port}
upload_flags = ${common.upload_flags}
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-dual] [env:itead-sonoff-dual]
platform = ${common.platform} platform = ${common.platform}
framework = arduino framework = arduino
@ -711,6 +743,31 @@ upload_flags = ${common.upload_flags}
monitor_baud = 19200 monitor_baud = 19200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-rfbridge-direct]
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_RFBRIDGE -DRFB_DIRECT
monitor_baud = 19200
extra_scripts = ${common.extra_scripts}
[env:itead-sonoff-rfbridge-direct-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 = ${common.build_flags_1m} -DITEAD_SONOFF_RFBRIDGE -DRFB_DIRECT
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 19200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
[env:itead-slampher] [env:itead-slampher]
@ -856,8 +913,8 @@ board_flash_mode = dout
lib_deps = ${common.lib_deps} lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore} lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_S31 build_flags = ${common.build_flags_1m} -DITEAD_SONOFF_S31
upload_port = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 115200 monitor_baud = 115200
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
@ -1874,6 +1931,60 @@ upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266 upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:zhilde-eu44-w]
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} -DZHILDE_EU44_W
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:zhilde-eu44-w-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 = ${common.build_flags_1m} -DZHILDE_EU44_W
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:luani-hvio]
platform = ${common.platform}
framework = arduino
board = esp07
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DLUANI_HVIO
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:luani-hvio-ota]
platform = ${common.platform}
framework = arduino
board = esp07
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DZLUANI_HVIO
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------
# GENERIC OTA ENVIRONMENTS
# ------------------------------------------------------------------------------
[env:generic-esp01s-relay-40] [env:generic-esp01s-relay-40]
platform = ${common.platform} platform = ${common.platform}
framework = arduino framework = arduino
@ -1994,6 +2105,30 @@ upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266 upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts} extra_scripts = ${common.extra_scripts}
[env:allnet-4duino-iot-wlan-relais]
platform = ${common.platform}
framework = arduino
board = esp12e
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DALLNET_4DUINO_IOT_WLAN_RELAIS
monitor_baud = 115200
extra_scripts = ${common.extra_scripts}
[env:allnet-4duino-iot-wlan-relais-ota]
platform = ${common.platform}
framework = arduino
board = esp12e
board_flash_mode = dout
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
build_flags = ${common.build_flags_1m} -DALLNET_4DUINO_IOT_WLAN_RELAIS
upload_speed = 115200
upload_port = "${env.ESPURNA_IP}"
upload_flags = --auth=${env.ESPURNA_AUTH} --port 8266
extra_scripts = ${common.extra_scripts}
[env:pilotak-esp-din-v1] [env:pilotak-esp-din-v1]
platform = ${common.platform} platform = ${common.platform}
framework = arduino framework = arduino


+ 105
- 59
pre-commit View File

@ -1,4 +1,4 @@
#!/usr/bin/python
#!/usr/bin/env python
""" """
Referencing current branch in github README.md [1] Referencing current branch in github README.md [1]
@ -17,61 +17,107 @@ Copy this file to .git/hooks/
import os import os
import sys import sys
import re import re
import subprocess
BASE = os.path.dirname(os.path.realpath(__file__)) + "/../../"
README = BASE + "README.md"
remote = subprocess.check_output(["git", "remote", "-v"]).strip().split('\n')[0]
parts = re.split('[/\.: ]', remote)
REPO = parts[ len(parts) - 3]
USER = parts[ len(parts) - 4]
BRANCH = subprocess.check_output(["git", "rev-parse", "--abbrev-ref", "HEAD"]).strip()
def getVersion():
file_name = BASE + "code/espurna/config/version.h"
lines = open(file_name).readlines()
for line in lines:
if "APP_VERSION" in line:
parts = line.split('"')
return parts[1]
return "unknown"
VERSION = getVersion()
version = "[![version](https://img.shields.io/badge/version-{VERSION}-brightgreen.svg)](CHANGELOG.md)\n".format(
VERSION = VERSION
)
branch = "![branch](https://img.shields.io/badge/branch-{BRANCH}-orange.svg)\n".format(
BRANCH = BRANCH
)
travis = "[![travis](https://travis-ci.org/{USER}/{REPO}.svg?branch={BRANCH})]" \
"(https://travis-ci.org/{USER}/{REPO})\n".format(
USER = USER,
REPO = REPO,
BRANCH = BRANCH
)
codacy = "[![codacy](https://img.shields.io/codacy/grade/{HASH}/{BRANCH}.svg)]" \
"(https://www.codacy.com/app/{USER}/{REPO}/dashboard)\n".format(
HASH = "c9496e25cf07434cba786b462cb15f49",
USER = USER,
REPO = REPO,
BRANCH = BRANCH
)
lines = open(README).readlines()
with open(README, "w") as fh:
for line in lines:
if "![travis]" in line:
fh.write(travis)
elif "![version]" in line:
fh.write(version)
elif "![branch]" in line:
fh.write(branch)
elif "![codacy]" in line:
fh.write(codacy)
else:
fh.write(line)
subprocess.check_output(["git", "add", README ])
from subprocess import call, check_output
try:
from urllib.parse import urlparse
except ImportError:
from urlparse import urlparse
from fileinput import FileInput
# https://github.com/python/cpython/commit/6cb7b659#diff-78790b53ff259619377058acd4f74672
if sys.version_info[0] < 3:
class FileInputCtx(FileInput):
def __enter__(self):
return self
def __exit__(self, type, value, traceback):
self.close()
FileInput = FileInputCtx
def run(cmd, cwd=None):
out = check_output(cmd, cwd=cwd)
out = out.decode("latin1").strip()
return out
def parse_h_string(define, r_quotes=re.compile("\"(.*)\"")):
string = r_quotes.search(define).group(1)
return string
def git_parse_remote(cwd=None, remote="origin"):
remote_url = run([
"git", "config", "--local",
"--get", "remote.{}.url".format(remote)], cwd)
if remote_url.startswith("git"):
_, _, repo = remote_url.partition(":")
path = repo.replace(".git", "")
elif remote_url.startswith("https"):
parsed = urlparse(remote_url)
path = parsed.path[1:]
return path.split("/")
def git_branch(cwd=None):
return run(["git", "rev-parse", "--abbrev-ref", "HEAD"], cwd)
def espurna_get_version(base, version_h="code/espurna/config/version.h"):
version = "unknown"
path = os.path.join(base, version_h)
with open(path, "r") as version_f:
for line in version_f:
if line.startswith("#define") and "APP_VERSION" in line:
version = parse_h_string(line)
break
return version
TEMPLATES = {
"![travis]": "[![travis](https://travis-ci.org/{USER}/{REPO}.svg?branch={BRANCH})]" \
"(https://travis-ci.org/{USER}/{REPO})\n",
"![version]": "[![version](https://img.shields.io/badge/version-{VERSION}-brightgreen.svg)](CHANGELOG.md)\n",
"![branch]": "[![branch](https://img.shields.io/badge/branch-{BRANCH}-orange.svg)]" \
"(https://github.org/{USER}/{REPO}/tree/{BRANCH}/)\n",
"![codacy]": "[![codacy](https://img.shields.io/codacy/grade/c9496e25cf07434cba786b462cb15f49/{BRANCH}.svg)]" \
"(https://www.codacy.com/app/{USER}/{REPO}/dashboard)\n"
}
README = "README.md"
if __name__ == "__main__":
base = os.getcwd()
user, repo = git_parse_remote()
fmt = {
"USER": user,
"REPO": repo,
"BRANCH": git_branch(),
"VERSION": espurna_get_version(base)
}
templates = [
(k, tmpl.format(**fmt))
for k, tmpl in TEMPLATES.items()
]
def fmt_line(line):
for match, tmpl in templates:
if match in line:
return tmpl
return line
path = os.path.join(base, README)
with FileInput(path, inplace=True) as readme:
for line in readme:
sys.stdout.write(fmt_line(line))
sys.exit(call(["git", "add", README]))

Loading…
Cancel
Save