Browse Source

Merge branch 'dev' of https://github.com/xoseperez/espurna into CCT_Support

rfm69
Niklas Wagner 6 years ago
parent
commit
ec9a9942f7
18 changed files with 4017 additions and 3403 deletions
  1. +1
    -0
      code/espurna/config/all.h
  2. +17
    -0
      code/espurna/config/debug.h
  3. +0
    -16
      code/espurna/config/dependencies.h
  4. +33
    -1
      code/espurna/config/general.h
  5. +24
    -5
      code/espurna/config/hardware.h
  6. +7
    -5
      code/espurna/config/progmem.h
  7. +35
    -2
      code/espurna/config/sensors.h
  8. +4
    -1
      code/espurna/config/types.h
  9. BIN
      code/espurna/data/index.html.gz
  10. +3
    -1
      code/espurna/ir.ino
  11. +122
    -46
      code/espurna/rfbridge.ino
  12. +10
    -0
      code/espurna/sensor.ino
  13. +207
    -34
      code/espurna/sensors/PMSX003Sensor.h
  14. +233
    -0
      code/espurna/sensors/SenseAirSensor.h
  15. +3278
    -3278
      code/espurna/static/index.html.gz.h
  16. +9
    -6
      code/html/custom.js
  17. +9
    -7
      code/html/index.html
  18. +25
    -1
      code/platformio.ini

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

@ -33,6 +33,7 @@
#include "sensors.h" #include "sensors.h"
#include "progmem.h" #include "progmem.h"
#include "dependencies.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"


+ 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
- 16
code/espurna/config/dependencies.h View File

@ -48,19 +48,3 @@
#undef NTP_SUPPORT #undef NTP_SUPPORT
#define NTP_SUPPORT 1 // Scheduler needs NTP #define NTP_SUPPORT 1 // Scheduler needs NTP
#endif #endif
// -----------------------------------------------------------------------------
// 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

+ 33
- 1
code/espurna/config/general.h View File

@ -128,7 +128,7 @@
#define SYSTEM_CHECK_ENABLED 1 // Enable crash check by default #define SYSTEM_CHECK_ENABLED 1 // Enable crash check by default
#endif #endif
#ifndef SYSTEM_CHECK_MAX
#ifndef SYSTEM_CHECK_TIME
#define SYSTEM_CHECK_TIME 60000 // The system is considered stable after these many millis #define SYSTEM_CHECK_TIME 60000 // The system is considered stable after these many millis
#endif #endif
@ -1144,6 +1144,38 @@
#endif #endif
//Remote Buttons SET 3 (samsung AA59-00608A 8 Toggle Buttons for generic 8CH module)
#if IR_BUTTON_SET == 3
/*
+------+------+------+
| 1 | 2 | 3 |
+------+------+------+
| 4 | 5 | 6 |
+------+------+------+
| 7 | 8 | 9 |
+------+------+------+
| | 0 | |
+------+------+------+
*/
#define IR_BUTTON_COUNT 10
const unsigned long IR_BUTTON[IR_BUTTON_COUNT][3] PROGMEM = {
{ 0xE0E020DF, IR_BUTTON_MODE_TOGGLE, 0 }, // Toggle Relay #0
{ 0xE0E0A05F, IR_BUTTON_MODE_TOGGLE, 1 }, // Toggle Relay #1
{ 0xE0E0609F, IR_BUTTON_MODE_TOGGLE, 2 }, // Toggle Relay #2
{ 0xE0E010EF, IR_BUTTON_MODE_TOGGLE, 3 }, // Toggle Relay #3
{ 0xE0E0906F, IR_BUTTON_MODE_TOGGLE, 4 }, // Toggle Relay #4
{ 0xE0E050AF, IR_BUTTON_MODE_TOGGLE, 5 }, // Toggle Relay #5
{ 0xE0E030CF, IR_BUTTON_MODE_TOGGLE, 6 }, // Toggle Relay #6
{ 0xE0E0B04F, IR_BUTTON_MODE_TOGGLE, 7 } // Toggle Relay #7
//{ 0xE0E0708F, IR_BUTTON_MODE_TOGGLE, 8 } //Extra Button
//{ 0xE0E08877, IR_BUTTON_MODE_TOGGLE, 9 } //Extra Button
};
#endif
#endif // IR_SUPPORT #endif // IR_SUPPORT
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------


+ 24
- 5
code/espurna/config/hardware.h View File

@ -599,16 +599,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 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
@ -617,6 +614,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
@ -1641,7 +1660,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


+ 7
- 5
code/espurna/config/progmem.h View File

@ -60,6 +60,7 @@ PROGMEM const char magnitude_co2_topic[] = "co2";
PROGMEM const char magnitude_lux_topic[] = "lux"; PROGMEM const char magnitude_lux_topic[] = "lux";
PROGMEM const char magnitude_uv_topic[] = "uv"; PROGMEM const char magnitude_uv_topic[] = "uv";
PROGMEM const char magnitude_distance_topic[] = "distance"; PROGMEM const char magnitude_distance_topic[] = "distance";
PROGMEM const char magnitude_hcho_topic[] = "hcho";
PROGMEM const char* const magnitude_topics[] = { PROGMEM const char* const magnitude_topics[] = {
magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic, magnitude_unknown_topic, magnitude_temperature_topic, magnitude_humidity_topic,
@ -69,12 +70,12 @@ PROGMEM const char* const magnitude_topics[] = {
magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic, magnitude_analog_topic, magnitude_digital_topic, magnitude_events_topic,
magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic, magnitude_pm1dot0_topic, magnitude_pm2dot5_topic, magnitude_pm10_topic,
magnitude_co2_topic, magnitude_lux_topic, magnitude_uv_topic, magnitude_co2_topic, magnitude_lux_topic, magnitude_uv_topic,
magnitude_distance_topic
magnitude_distance_topic, magnitude_hcho_topic
}; };
PROGMEM const char magnitude_empty[] = ""; PROGMEM const char magnitude_empty[] = "";
PROGMEM const char magnitude_celsius[] = "C";
PROGMEM const char magnitude_fahrenheit[] = "F";
PROGMEM const char magnitude_celsius[] = "°C";
PROGMEM const char magnitude_fahrenheit[] = "°F";
PROGMEM const char magnitude_percentage[] = "%"; PROGMEM const char magnitude_percentage[] = "%";
PROGMEM const char magnitude_hectopascals[] = "hPa"; PROGMEM const char magnitude_hectopascals[] = "hPa";
PROGMEM const char magnitude_amperes[] = "A"; PROGMEM const char magnitude_amperes[] = "A";
@ -83,11 +84,12 @@ PROGMEM const char magnitude_watts[] = "W";
PROGMEM const char magnitude_kw[] = "kW"; PROGMEM const char magnitude_kw[] = "kW";
PROGMEM const char magnitude_joules[] = "J"; PROGMEM const char magnitude_joules[] = "J";
PROGMEM const char magnitude_kwh[] = "kWh"; PROGMEM const char magnitude_kwh[] = "kWh";
PROGMEM const char magnitude_ugm3[] = "µg/m3";
PROGMEM const char magnitude_ugm3[] = "µg/m³";
PROGMEM const char magnitude_ppm[] = "ppm"; PROGMEM const char magnitude_ppm[] = "ppm";
PROGMEM const char magnitude_lux[] = "lux"; PROGMEM const char magnitude_lux[] = "lux";
PROGMEM const char magnitude_uv[] = "uv"; PROGMEM const char magnitude_uv[] = "uv";
PROGMEM const char magnitude_distance[] = "m"; PROGMEM const char magnitude_distance[] = "m";
PROGMEM const char magnitude_mgm3[] = "mg/m³";
PROGMEM const char* const magnitude_units[] = { PROGMEM const char* const magnitude_units[] = {
magnitude_empty, magnitude_celsius, magnitude_percentage, magnitude_empty, magnitude_celsius, magnitude_percentage,
@ -97,7 +99,7 @@ PROGMEM const char* const magnitude_units[] = {
magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty, magnitude_empty,
magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3, magnitude_ugm3,
magnitude_ppm, magnitude_lux, magnitude_uv, magnitude_ppm, magnitude_lux, magnitude_uv,
magnitude_distance
magnitude_distance, magnitude_mgm3
}; };


+ 35
- 2
code/espurna/config/sensors.h View File

@ -374,7 +374,24 @@
#endif #endif
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
// Particle Monitor based on Plantower PMSX003
// 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 PMS
// Enable support by passing PMSX003_SUPPORT=1 build flag // Enable support by passing PMSX003_SUPPORT=1 build flag
//------------------------------------------------------------------------------ //------------------------------------------------------------------------------
@ -382,6 +399,17 @@
#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 #ifndef PMS_RX_PIN
#define PMS_RX_PIN 13 #define PMS_RX_PIN 13
#endif #endif
@ -503,6 +531,7 @@
HCSR04_SUPPORT || \ HCSR04_SUPPORT || \
HLW8012_SUPPORT || \ HLW8012_SUPPORT || \
MHZ19_SUPPORT || \ MHZ19_SUPPORT || \
SENSEAIR_SUPPORT || \
PMSX003_SUPPORT || \ PMSX003_SUPPORT || \
PZEM004T_SUPPORT || \ PZEM004T_SUPPORT || \
SHT3X_I2C_SUPPORT || \ SHT3X_I2C_SUPPORT || \
@ -624,9 +653,13 @@
#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


+ 4
- 1
code/espurna/config/types.h View File

@ -159,6 +159,7 @@
#define IR_BUTTON_MODE_BRIGHTER 3 #define IR_BUTTON_MODE_BRIGHTER 3
#define IR_BUTTON_MODE_STATE 4 #define IR_BUTTON_MODE_STATE 4
#define IR_BUTTON_MODE_EFFECT 5 #define IR_BUTTON_MODE_EFFECT 5
#define IR_BUTTON_MODE_TOGGLE 6
#define LIGHT_EFFECT_SOLID 0 #define LIGHT_EFFECT_SOLID 0
#define LIGHT_EFFECT_FLASH 1 #define LIGHT_EFFECT_FLASH 1
@ -249,6 +250,7 @@
#define SENSOR_CSE7766_ID 0x21 #define SENSOR_CSE7766_ID 0x21
#define SENSOR_TMP3X_ID 0x22 #define SENSOR_TMP3X_ID 0x22
#define SENSOR_HCSR04_ID 0x23 #define SENSOR_HCSR04_ID 0x23
#define SENSOR_SENSEAIR_ID 0x24
//-------------------------------------------------------------------------------- //--------------------------------------------------------------------------------
// Magnitudes // Magnitudes
@ -276,5 +278,6 @@
#define MAGNITUDE_LUX 19 #define MAGNITUDE_LUX 19
#define MAGNITUDE_UV 20 #define MAGNITUDE_UV 20
#define MAGNITUDE_DISTANCE 21 #define MAGNITUDE_DISTANCE 21
#define MAGNITUDE_HCHO 22
#define MAGNITUDE_MAX 22
#define MAGNITUDE_MAX 23

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


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

@ -42,7 +42,9 @@ void _irProcessCode(unsigned long code) {
if (button_mode == IR_BUTTON_MODE_STATE) { if (button_mode == IR_BUTTON_MODE_STATE) {
relayStatus(0, button_value); relayStatus(0, button_value);
} }
if (button_mode == IR_BUTTON_MODE_TOGGLE) {
relayToggle(button_value);
}
#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) {


+ 122
- 46
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,6 +590,14 @@ void rfbSetup() {
wsOnActionRegister(_rfbWebSocketOnAction); wsOnActionRegister(_rfbWebSocketOnAction);
#endif #endif
#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 // Register loop
espurnaRegisterLoop(rfbLoop); espurnaRegisterLoop(rfbLoop);


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

@ -487,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


+ 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

+ 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

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


+ 9
- 6
code/html/custom.js View File

@ -40,7 +40,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];
@ -54,7 +54,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];
@ -89,14 +89,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/
@ -1207,13 +1210,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;
} }
@ -1229,6 +1231,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);


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

@ -211,8 +211,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>
@ -249,16 +251,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>


+ 25
- 1
code/platformio.ini View File

@ -70,7 +70,6 @@ lib_deps =
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
@ -719,6 +718,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 = "192.168.4.1"
upload_flags = --auth=fibonacci --port 8266
monitor_baud = 19200
extra_scripts = ${common.extra_scripts}
# ------------------------------------------------------------------------------ # ------------------------------------------------------------------------------
[env:itead-slampher] [env:itead-slampher]


Loading…
Cancel
Save