Merge branch 'development' into pre-release

This commit is contained in:
Theo Arends 2020-04-12 14:54:28 +02:00
commit 1972f85616
40 changed files with 464 additions and 193 deletions

View File

@ -66,6 +66,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
- Add Zigbee command ``ZbRestore`` to restore device configuration dumped with ``ZbStatus 2``
- Add Zigbee command ``ZbUnbind``
- Add Zigbee command ``ZbBindState`` and ``manuf``attribute
- Add Zigbee command ``ZbConfig`` and configuration in Settings
- Add commands ``CounterDebounceLow`` and ``CounterDebounceHigh`` to control debouncing (#8021)
- Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075)
- Add command ``SetOption41 <x>`` to force sending gratuitous ARP every <x> seconds
@ -73,6 +74,7 @@ The following binary downloads have been compiled with ESP8266/Arduino library c
- Add command ``SetOption91 1`` to enable fading at startup / power on
- Add command ``Sensor10 0/1/2`` to control BH1750 resolution - 0 = High (default), 1 = High2, 2 = Low (#8016)
- Add command ``Sensor10 31..254`` to control BH1750 measurement time which defaults to 69 (#8016)
- Add command ``Sensor18 0..32000`` to control PMS5003 sensor interval to extend lifetime by Gene Ruebsamen (#8128)
- Add command ``DevGroupName`` to specify up to four Device Group Names (#8087)
- Add command ``DevGroupSend`` to send an update to a Device Group (#8093)
- Add command ``Ping`` (#7176)

View File

@ -66,9 +66,13 @@ RA8876::RA8876(int8_t cs,int8_t mosi,int8_t miso,int8_t sclk,int8_t bp) : Render
//#define RA8876_CS_LOW digitalWrite(m_csPin, LOW)
//#define RA8876_CS_HIGH digitalWrite(m_csPin, HIGH)
#ifdef ESP8266
#define RA8876_CS_LOW GPOC=(1<<m_csPin);
#define RA8876_CS_HIGH GPOS=(1<<m_csPin);
#else
#define RA8876_CS_LOW digitalWrite(1<<m_csPin,0);
#define RA8876_CS_HIGH digitalWrite(1<<m_csPin,1);
#endif
/*
extern void ICACHE_RAM_ATTR RA8876_digitalWrite(uint8_t pin, uint8_t val) {
//stopWaveform(pin);

View File

@ -84,7 +84,7 @@ extra_scripts = ${common.extra_scripts}
build_flags =
-D BUFFER_LENGTH=128
-D MQTT_MAX_PACKET_SIZE=1000
-D MQTT_MAX_PACKET_SIZE=1200
-D uint32=uint32_t
-D uint16=uint16_t
-D uint8=uint8_t

View File

@ -16,11 +16,13 @@
- Fix Zigbee crash with Occupancy sensor (#8089)
- Add support for longer template names
- Add Zigbee command ``ZbBindState`` and ``manuf``attribute
- Add Zigbee command ``ZbConfig`` and configuration in Settings
- Add commands ``CounterDebounceLow`` and ``CounterDebounceHigh`` to control debouncing (#8021)
- Add commands ``NrfPage``, ``NrfIgnore``, ``NrfScan`` and ``NrfBeacon`` to NRF24 Bluetooth driver (#8075)
- Add command ``SetOption90 1`` to disable non-json MQTT messages (#8044)
- Add command ``Sensor10 0/1/2`` to control BH1750 resolution - 0 = High (default), 1 = High2, 2 = Low (#8016)
- Add command ``Sensor10 31..254`` to control BH1750 measurement time which defaults to 69 (#8016)
- Add command ``Sensor18 0..32000`` to control PMS5003 sensor interval to extend lifetime by Gene Ruebsamen (#8128)
- Add command ``SetOption91 1`` to enable fading at startup / power on
- Add command ``SetOption41 <x>`` to force sending gratuitous ARP every <x> seconds
- Add command ``DevGroupName`` to specify up to four Device Group Names (#8087)

View File

@ -522,6 +522,8 @@
#define D_CMND_ZIGBEE_LIGHT "Light"
#define D_JSON_ZIGBEE_LIGHT "Light"
#define D_CMND_ZIGBEE_RESTORE "Restore"
#define D_CMND_ZIGBEE_CONFIG "Config"
#define D_JSON_ZIGBEE_CONFIG "Config"
// Commands xdrv_25_A4988_Stepper.ino
#define D_CMND_MOTOR "MOTOR"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Подсветка"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "RétroÉcl"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 RX"
#define D_SENSOR_SDS0X1_TX "SDS0X1 TX"
#define D_SENSOR_HPMA_RX "HPMA RX"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Háttérfény"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI - MOSI"
#define D_SENSOR_SPI_CLK "SPI - CLK"
#define D_SENSOR_BACKLIGHT "Retroilluminazione"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 - RX"
#define D_SENSOR_SDS0X1_TX "SDS0X1 - TX"
#define D_SENSOR_HPMA_RX "HPMA - RX"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Podświetlanie"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Luz de fundo"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Luz fundo"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "OLED Light"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -567,7 +567,8 @@
#define D_SENSOR_SPI_MOSI "SPI MOSI"
#define D_SENSOR_SPI_CLK "SPI CLK"
#define D_SENSOR_BACKLIGHT "Backlight"
#define D_SENSOR_PMS5003 "PMS5003"
#define D_SENSOR_PMS5003_TX "PMS5003 Tx"
#define D_SENSOR_PMS5003_RX "PMS5003 Rx"
#define D_SENSOR_SDS0X1_RX "SDS0X1 Rx"
#define D_SENSOR_SDS0X1_TX "SDS0X1 Tx"
#define D_SENSOR_HPMA_RX "HPMA Rx"

View File

@ -627,7 +627,6 @@
#define USE_ZIGBEE_CHANNEL 11 // Zigbee Channel (11-26)
#define USE_ZIGBEE_PRECFGKEY_L 0x0F0D0B0907050301L // note: changing requires to re-pair all devices
#define USE_ZIGBEE_PRECFGKEY_H 0x0D0C0A0806040200L // note: changing requires to re-pair all devices
#define USE_ZIGBEE_PERMIT_JOIN false // don't allow joining by default
#define USE_ZIGBEE_COALESCE_ATTR_TIMER 350 // timer to coalesce attribute values (in ms)
// -- Other sensors/drivers -----------------------

View File

@ -505,8 +505,9 @@ struct PACKED SYSCFG {
uint16_t zb_pan_id; // F30
uint8_t zb_channel; // F32
uint8_t zb_free_byte; // F33
uint16_t pms_wake_interval; // F34
uint8_t free_f18[132]; // F34
uint8_t free_f36[130]; // F36
uint16_t pulse_counter_debounce_low; // FB8
uint16_t pulse_counter_debounce_high; // FBA

View File

@ -1332,6 +1332,7 @@ void SettingsDelta(void)
}
if (Settings.version < 0x08020003) {
SettingsUpdateText(SET_TEMPLATE_NAME, Settings.user_template_name);
Settings.zb_channel = 0; // set channel to zero to force reinit of zigbee parameters
}
#endif // ESP8266

View File

@ -1778,7 +1778,7 @@ void AddLogSerial(uint32_t loglevel)
AddLogBuffer(loglevel, (uint8_t*)serial_in_buffer, serial_in_byte_counter);
}
void AddLogMissed(char *sensor, uint32_t misses)
void AddLogMissed(const char *sensor, uint32_t misses)
{
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("SNS: %s missed %d"), sensor, SENSOR_MAX_MISS - misses);
}

View File

@ -93,7 +93,7 @@ enum UserSelectablePins {
GPIO_SPI_CS, // SPI Chip Select
GPIO_SPI_DC, // SPI Data Direction
GPIO_BACKLIGHT, // Display backlight control
GPIO_PMS5003, // Plantower PMS5003 Serial interface
GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface
GPIO_SDS0X1_RX, // Nova Fitness SDS011 Serial interface
GPIO_SBR_TX, // Serial Bridge Serial interface
GPIO_SBR_RX, // Serial Bridge Serial interface
@ -227,6 +227,7 @@ enum UserSelectablePins {
GPIO_HRXL_RX, // Data from MaxBotix HRXL sonar range sensor
GPIO_ELECTRIQ_MOODL_TX, // ElectriQ iQ-wifiMOODL Serial TX
GPIO_AS3935,
GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface
GPIO_SENSOR_END };
// Programmer selectable GPIO functionality
@ -260,7 +261,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_PZEM0XX_TX "|" D_SENSOR_PZEM004_RX "|"
D_SENSOR_SAIR_TX "|" D_SENSOR_SAIR_RX "|"
D_SENSOR_SPI_CS "|" D_SENSOR_SPI_DC "|" D_SENSOR_BACKLIGHT "|"
D_SENSOR_PMS5003 "|" D_SENSOR_SDS0X1_RX "|"
D_SENSOR_PMS5003_RX "|" D_SENSOR_SDS0X1_RX "|"
D_SENSOR_SBR_TX "|" D_SENSOR_SBR_RX "|"
D_SENSOR_SR04_TRIG "|" D_SENSOR_SR04_ECHO "|"
D_SENSOR_SDM120_TX "|" D_SENSOR_SDM120_RX "|"
@ -314,7 +315,7 @@ const char kSensorNames[] PROGMEM =
D_SENSOR_CC1101_GDO0 "|" D_SENSOR_CC1101_GDO2 "|"
D_SENSOR_HRXL_RX "|"
D_SENSOR_ELECTRIQ_MOODL "|"
D_SENSOR_AS3935
D_SENSOR_AS3935 "|" D_SENSOR_PMS5003_TX
;
const char kSensorNamesFixed[] PROGMEM =
@ -582,7 +583,8 @@ const uint8_t kGpioNiceList[] PROGMEM = {
GPIO_HPMA_RX, // Honeywell HPMA115S0 Serial interface
#endif
#ifdef USE_PMS5003
GPIO_PMS5003, // Plantower PMS5003 Serial interface
GPIO_PMS5003_TX, // Plantower PMS5003 Serial interface
GPIO_PMS5003_RX, // Plantower PMS5003 Serial interface
#endif
#if defined(USE_TX20_WIND_SENSOR) || defined(USE_TX23_WIND_SENSOR)
GPIO_TX2X_TXD_BLACK, // TX20/TX23 Transmission Pin

View File

@ -17,6 +17,7 @@
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifdef USE_SCRIPT
#ifndef USE_RULES
/*********************************************************************************************\
@ -60,6 +61,10 @@ keywords if then else endif, or, and are better readable for beginners (others m
#define SCRIPT_MAXPERM (PMEM_SIZE)-4/sizeof(float)
#define MAX_SCRIPT_SIZE MAX_RULE_SIZE*MAX_RULE_SETS
uint32_t EncodeLightId(uint8_t relay_id);
uint32_t DecodeLightId(uint32_t hue_id);
// offsets epoch readings by 1.1.2019 00:00:00 to fit into float with second resolution
#define EPOCH_OFFSET 1546300800
@ -2028,6 +2033,7 @@ char *getop(char *lp, uint8_t *operand) {
}
#ifdef ESP8266
#if defined(ARDUINO_ESP8266_RELEASE_2_3_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_0) || defined(ARDUINO_ESP8266_RELEASE_2_4_1)
// All version before core 2.4.2
// https://github.com/esp8266/Arduino/issues/2557
@ -2050,6 +2056,12 @@ uint16_t GetStack(void) {
return (4 * (sp - g_pcont->stack));
}
#endif
#else
uint16_t GetStack(void) {
register uint8_t *sp asm("a1");
return (sp - pxTaskGetStackStart(NULL));
}
#endif
char *GetStringResult(char *lp,uint8_t lastop,char *cp,JsonObject *jo) {
uint8_t operand=0;

View File

@ -148,6 +148,9 @@ SBuffer *zigbee_buffer = nullptr;
#define Z_B7(a) (uint8_t)( ((a) >> 56) & 0xFF )
// Macro to define message to send and receive
#define ZBM(n, x...) const uint8_t n[] PROGMEM = { x };
// For commands that need to be changed with configuration, ZBR stores in RAM, and ZBW write new values
#define ZBR(n, x...) uint8_t n[] = { x }; // same but in RAM to be modified
#define ZBW(n, x...) { const uint8_t n##t[] = { x }; memcpy(n, n##t, sizeof(n)); } // re-write content in RAM
#define USE_ZIGBEE_CHANNEL_MASK (1 << (USE_ZIGBEE_CHANNEL))
@ -165,24 +168,24 @@ ZBM(ZBR_ZNPHC, Z_SRSP | Z_SYS, SYS_OSAL_NV_READ, Z_SUCCESS, 0x01 /* len */, 0x55
// If not set, the response is 61-08-02-00 = Z_SRSP | Z_SYS, SYS_OSAL_NV_READ, Z_INVALIDPARAMETER, 0x00 /* len */
ZBM(ZBS_PAN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PANID ) // 260483
ZBM(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */,
ZBR(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */,
Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 6604008302xxxx
ZBM(ZBS_EXTPAN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_EXTENDED_PAN_ID ) // 26042D
ZBM(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID,
ZBR(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID,
0x08 /* len */,
Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID),
Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID),
) // 6604002D08xxxxxxxxxxxxxxxx
ZBM(ZBS_CHANN, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_CHANLIST ) // 260484
ZBM(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIST,
ZBR(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIST,
0x04 /* len */,
Z_B0(USE_ZIGBEE_CHANNEL_MASK), Z_B1(USE_ZIGBEE_CHANNEL_MASK), Z_B2(USE_ZIGBEE_CHANNEL_MASK), Z_B3(USE_ZIGBEE_CHANNEL_MASK),
) // 6604008404xxxxxxxx
ZBM(ZBS_PFGK, Z_SREQ | Z_SAPI, SAPI_READ_CONFIGURATION, CONF_PRECFGKEY ) // 260462
ZBM(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY,
ZBR(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY,
0x10 /* len */,
Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L),
Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L),
@ -203,20 +206,20 @@ ZBM(ZBR_WNV_OK, Z_SRSP | Z_SYS, SYS_OSAL_NV_WRITE, Z_SUCCESS ) // 610900 - NV
// Factory reset
ZBM(ZBS_FACTRES, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_STARTUP_OPTION, 0x01 /* len */, 0x02 ) // 2605030102
// Write PAN ID
ZBM(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 26058302xxxx
ZBR(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(USE_ZIGBEE_PANID), Z_B1(USE_ZIGBEE_PANID) ) // 26058302xxxx
// Write EXT PAN ID
ZBM(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */,
ZBR(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */,
Z_B0(USE_ZIGBEE_EXTPANID), Z_B1(USE_ZIGBEE_EXTPANID), Z_B2(USE_ZIGBEE_EXTPANID), Z_B3(USE_ZIGBEE_EXTPANID),
Z_B4(USE_ZIGBEE_EXTPANID), Z_B5(USE_ZIGBEE_EXTPANID), Z_B6(USE_ZIGBEE_EXTPANID), Z_B7(USE_ZIGBEE_EXTPANID)
) // 26052D086263151D004B1200
// Write Channel ID
ZBM(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */,
ZBR(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */,
Z_B0(USE_ZIGBEE_CHANNEL_MASK), Z_B1(USE_ZIGBEE_CHANNEL_MASK), Z_B2(USE_ZIGBEE_CHANNEL_MASK), Z_B3(USE_ZIGBEE_CHANNEL_MASK),
/*0x00, 0x08, 0x00, 0x00*/ ) // 26058404xxxxxxxx
// Write Logical Type = 00 = coordinator
ZBM(ZBS_W_LOGTYP, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_LOGICAL_TYPE, 0x01 /* len */, 0x00 ) // 2605870100
// Write precfgkey
ZBM(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY,
ZBR(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY,
0x10 /* len */,
Z_B0(USE_ZIGBEE_PRECFGKEY_L), Z_B1(USE_ZIGBEE_PRECFGKEY_L), Z_B2(USE_ZIGBEE_PRECFGKEY_L), Z_B3(USE_ZIGBEE_PRECFGKEY_L),
Z_B4(USE_ZIGBEE_PRECFGKEY_L), Z_B5(USE_ZIGBEE_PRECFGKEY_L), Z_B6(USE_ZIGBEE_PRECFGKEY_L), Z_B7(USE_ZIGBEE_PRECFGKEY_L),
@ -301,6 +304,53 @@ ZBM(ZBS_PERMITJOINREQ_CLOSE, Z_SREQ | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_REQ, 0x02 /* A
ZBM(ZBR_PERMITJOINREQ, Z_SRSP | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_REQ, Z_SUCCESS) // 653600
ZBM(ZBR_PERMITJOIN_AREQ_RSP, Z_AREQ | Z_ZDO, ZDO_MGMT_PERMIT_JOIN_RSP, 0x00, 0x00 /* srcAddr*/, Z_SUCCESS ) // 45B6000000
// Update the relevant commands with Settings
void Z_UpdateConfig(uint8_t zb_channel, uint16_t zb_pan_id, uint64_t zb_ext_panid, uint64_t zb_precfgkey_l, uint64_t zb_precfgkey_h) {
uint32_t zb_channel_mask = (1 << zb_channel);
ZBW(ZBR_PAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PANID, 0x02 /* len */,
Z_B0(zb_pan_id), Z_B1(zb_pan_id) ) // 6604008302xxxx
ZBW(ZBR_EXTPAN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_EXTENDED_PAN_ID,
0x08 /* len */,
Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid),
Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid),
) // 6604002D08xxxxxxxxxxxxxxxx
ZBW(ZBR_CHANN, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_CHANLIST,
0x04 /* len */,
Z_B0(zb_channel_mask), Z_B1(zb_channel_mask), Z_B2(zb_channel_mask), Z_B3(zb_channel_mask),
) // 6604008404xxxxxxxx
ZBW(ZBR_PFGK, Z_SRSP | Z_SAPI, SAPI_READ_CONFIGURATION, Z_SUCCESS, CONF_PRECFGKEY,
0x10 /* len */,
Z_B0(zb_precfgkey_l), Z_B1(zb_precfgkey_l), Z_B2(zb_precfgkey_l), Z_B3(zb_precfgkey_l),
Z_B4(zb_precfgkey_l), Z_B5(zb_precfgkey_l), Z_B6(zb_precfgkey_l), Z_B7(zb_precfgkey_l),
Z_B0(zb_precfgkey_h), Z_B1(zb_precfgkey_h), Z_B2(zb_precfgkey_h), Z_B3(zb_precfgkey_h),
Z_B4(zb_precfgkey_h), Z_B5(zb_precfgkey_h), Z_B6(zb_precfgkey_h), Z_B7(zb_precfgkey_h),
/*0x01, 0x03, 0x05, 0x07, 0x09, 0x0B, 0x0D, 0x0F,
0x00, 0x02, 0x04, 0x06, 0x08, 0x0A, 0x0C, 0x0D*/ ) // 660400621001030507090B0D0F00020406080A0C0D
ZBW(ZBS_W_PAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PANID, 0x02 /* len */, Z_B0(zb_pan_id), Z_B1(zb_pan_id) ) // 26058302xxxx
// Write EXT PAN ID
ZBW(ZBS_W_EXTPAN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_EXTENDED_PAN_ID, 0x08 /* len */,
Z_B0(zb_ext_panid), Z_B1(zb_ext_panid), Z_B2(zb_ext_panid), Z_B3(zb_ext_panid),
Z_B4(zb_ext_panid), Z_B5(zb_ext_panid), Z_B6(zb_ext_panid), Z_B7(zb_ext_panid)
) // 26052D086263151D004B1200
// Write Channel ID
ZBW(ZBS_W_CHANN, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_CHANLIST, 0x04 /* len */,
Z_B0(zb_channel_mask), Z_B1(zb_channel_mask), Z_B2(zb_channel_mask), Z_B3(zb_channel_mask),
/*0x00, 0x08, 0x00, 0x00*/ ) // 26058404xxxxxxxx
// Write precfgkey
ZBW(ZBS_W_PFGK, Z_SREQ | Z_SAPI, SAPI_WRITE_CONFIGURATION, CONF_PRECFGKEY,
0x10 /* len */,
Z_B0(zb_precfgkey_l), Z_B1(zb_precfgkey_l), Z_B2(zb_precfgkey_l), Z_B3(zb_precfgkey_l),
Z_B4(zb_precfgkey_l), Z_B5(zb_precfgkey_l), Z_B6(zb_precfgkey_l), Z_B7(zb_precfgkey_l),
Z_B0(zb_precfgkey_h), Z_B1(zb_precfgkey_h), Z_B2(zb_precfgkey_h), Z_B3(zb_precfgkey_h),
Z_B4(zb_precfgkey_h), Z_B5(zb_precfgkey_h), Z_B6(zb_precfgkey_h), Z_B7(zb_precfgkey_h),
) // 2605621001030507090B0D0F00020406080A0C0D
}
const char kCheckingDeviceConfiguration[] PROGMEM = D_LOG_ZIGBEE "checking device configuration";
const char kConfigured[] PROGMEM = "Configured, starting coordinator";
const char kStarted[] PROGMEM = "Started";

View File

@ -35,7 +35,8 @@ const char kZbCommands[] PROGMEM = D_PRFX_ZB "|" // prefix
D_CMND_ZIGBEE_PROBE "|" D_CMND_ZIGBEE_READ "|" D_CMND_ZIGBEEZNPRECEIVE "|"
D_CMND_ZIGBEE_FORGET "|" D_CMND_ZIGBEE_SAVE "|" D_CMND_ZIGBEE_NAME "|"
D_CMND_ZIGBEE_BIND "|" D_CMND_ZIGBEE_UNBIND "|" D_CMND_ZIGBEE_PING "|" D_CMND_ZIGBEE_MODELID "|"
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE
D_CMND_ZIGBEE_LIGHT "|" D_CMND_ZIGBEE_RESTORE "|" D_CMND_ZIGBEE_BIND_STATE "|"
D_CMND_ZIGBEE_CONFIG
;
void (* const ZigbeeCommand[])(void) PROGMEM = {
@ -45,6 +46,7 @@ void (* const ZigbeeCommand[])(void) PROGMEM = {
&CmndZbForget, &CmndZbSave, &CmndZbName,
&CmndZbBind, &CmndZbUnbind, &CmndZbPing, &CmndZbModelId,
&CmndZbLight, &CmndZbRestore, &CmndZbBindState,
&CmndZbConfig,
};
//
@ -145,6 +147,19 @@ void ZigbeeInputLoop(void)
// Initialize internal structures
void ZigbeeInit(void)
{
// Check if settings if Flash are set
if (0 == Settings.zb_channel) {
AddLog_P2(LOG_LEVEL_INFO, PSTR(D_LOG_ZIGBEE "Initializing Zigbee parameters from defaults"));
Settings.zb_ext_panid = USE_ZIGBEE_EXTPANID;
Settings.zb_precfgkey_l = USE_ZIGBEE_PRECFGKEY_L;
Settings.zb_precfgkey_h = USE_ZIGBEE_PRECFGKEY_H;
Settings.zb_pan_id = USE_ZIGBEE_PANID;
Settings.zb_channel = USE_ZIGBEE_CHANNEL;
Settings.zb_free_byte = 0;
}
// update commands with the current settings
Z_UpdateConfig(Settings.zb_channel, Settings.zb_pan_id, Settings.zb_ext_panid, Settings.zb_precfgkey_l, Settings.zb_precfgkey_h);
// AddLog_P2(LOG_LEVEL_INFO, PSTR("ZigbeeInit Mem1 = %d"), ESP.getFreeHeap());
zigbee.active = false;
if ((pin[GPIO_ZIGBEE_RX] < 99) && (pin[GPIO_ZIGBEE_TX] < 99)) {
@ -1007,6 +1022,79 @@ void CmndZbStatus(void) {
}
}
//
// Command `ZbConfig`
//
void CmndZbConfig(void) {
// ZbConfig
// ZbConfig {"Channel":11,"PanID":"0x1A63","ExtPanID":"0xCCCCCCCCCCCCCCCC","KeyL":"0x0F0D0B0907050301L","KeyH":"0x0D0C0A0806040200L"}
uint8_t zb_channel = Settings.zb_channel;
uint16_t zb_pan_id = Settings.zb_pan_id;
uint64_t zb_ext_panid = Settings.zb_ext_panid;
uint64_t zb_precfgkey_l = Settings.zb_precfgkey_l;
uint64_t zb_precfgkey_h = Settings.zb_precfgkey_h;
// if (zigbee.init_phase) { ResponseCmndChar_P(PSTR(D_ZIGBEE_NOT_STARTED)); return; }
RemoveAllSpaces(XdrvMailbox.data);
if (strlen(XdrvMailbox.data) > 0) {
DynamicJsonBuffer jsonBuf;
const JsonObject &json = jsonBuf.parseObject((const char*) XdrvMailbox.data);
if (!json.success()) { ResponseCmndChar_P(PSTR(D_JSON_INVALID_JSON)); return; }
// Channel
const JsonVariant &val_channel = getCaseInsensitive(json, PSTR("Channel"));
if (nullptr != &val_channel) { zb_channel = strToUInt(val_channel); }
if (zb_channel < 11) { zb_channel = 11; }
if (zb_channel > 26) { zb_channel = 26; }
// PanID
const JsonVariant &val_pan_id = getCaseInsensitive(json, PSTR("PanID"));
if (nullptr != &val_pan_id) { zb_pan_id = strToUInt(val_pan_id); }
// ExtPanID
const JsonVariant &val_ext_pan_id = getCaseInsensitive(json, PSTR("ExtPanID"));
if (nullptr != &val_ext_pan_id) { zb_ext_panid = strtoull(val_ext_pan_id.as<const char*>(), nullptr, 0); }
// KeyL
const JsonVariant &val_key_l = getCaseInsensitive(json, PSTR("KeyL"));
if (nullptr != &val_key_l) { zb_precfgkey_l = strtoull(val_key_l.as<const char*>(), nullptr, 0); }
// KeyH
const JsonVariant &val_key_h = getCaseInsensitive(json, PSTR("KeyH"));
if (nullptr != &val_key_h) { zb_precfgkey_h = strtoull(val_key_h.as<const char*>(), nullptr, 0); }
// Check if a parameter was changed after all
if ( (zb_channel != Settings.zb_channel) ||
(zb_pan_id != Settings.zb_pan_id) ||
(zb_ext_panid != Settings.zb_ext_panid) ||
(zb_precfgkey_l != Settings.zb_precfgkey_l) ||
(zb_precfgkey_h != Settings.zb_precfgkey_h) ) {
Settings.zb_channel = zb_channel;
Settings.zb_pan_id = zb_pan_id;
Settings.zb_ext_panid = zb_ext_panid;
Settings.zb_precfgkey_l = zb_precfgkey_l;
Settings.zb_precfgkey_h = zb_precfgkey_h;
restart_flag = 2; // save and reboot
}
}
// display the current or new configuration
char hex_ext_panid[20] = "0x";
Uint64toHex(zb_ext_panid, &hex_ext_panid[2], 64);
char hex_precfgkey_l[20] = "0x";
Uint64toHex(zb_precfgkey_l, &hex_precfgkey_l[2], 64);
char hex_precfgkey_h[20] = "0x";
Uint64toHex(zb_precfgkey_h, &hex_precfgkey_h[2], 64);
// {"ZbConfig":{"Channel":11,"PanID":"0x1A63","ExtPanID":"0xCCCCCCCCCCCCCCCC","KeyL":"0x0F0D0B0907050301L","KeyH":"0x0D0C0A0806040200L"}}
Response_P(PSTR("{\"" D_PRFX_ZB D_JSON_ZIGBEE_CONFIG "\":{"
"\"Channel\":%d"
",\"PanID\":\"0x%04X\""
",\"ExtPanID\":\"%s\""
",\"KeyL\":\"%s\""
",\"KeyH\":\"%s\""
"}}"),
zb_channel, zb_pan_id,
hex_ext_panid,
hex_precfgkey_l, hex_precfgkey_h);
}
/*********************************************************************************************\
* Interface
\*********************************************************************************************/

View File

@ -845,6 +845,10 @@ void CmndShutterPosition(void)
CmndShutterClose();
return;
}
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_TOGGLE)) {
CmndShutterToggle();
return;
}
if (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOP) || ((Shutter.direction[index]) && (!strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPOPEN) || !strcasecmp(XdrvMailbox.data,D_CMND_SHUTTER_STOPCLOSE)))) {
XdrvMailbox.payload = -99;
CmndShutterStop();

View File

@ -32,10 +32,40 @@
#include <TasmotaSerial.h>
#ifndef WARMUP_PERIOD
#define WARMUP_PERIOD 30 // Turn on PMSX003 XX-seconds before read in passive mode
#endif
#ifndef MIN_INTERVAL_PERIOD
#define MIN_INTERVAL_PERIOD 60 // minimum interval period in seconds required for passive mode
#endif
TasmotaSerial *PmsSerial;
uint8_t pms_type = 1;
uint8_t pms_valid = 0;
struct PMS5003 {
uint16_t time = 0;
uint8_t type = 1;
uint8_t valid = 0;
uint8_t wake_mode = 1;
uint8_t ready = 1;
} Pms;
enum PmsCommands
{
CMD_MODE_ACTIVE,
CMD_SLEEP,
CMD_WAKEUP,
CMD_MODE_PASSIVE,
CMD_READ_DATA
};
const uint8_t kPmsCommands[][7] PROGMEM = {
// 0 1 2 3 4 5 6
{0x42, 0x4D, 0xE1, 0x00, 0x01, 0x01, 0x71}, // pms_set_active_mode
{0x42, 0x4D, 0xE4, 0x00, 0x00, 0x01, 0x73}, // pms_sleep
{0x42, 0x4D, 0xE4, 0x00, 0x01, 0x01, 0x74}, // pms_wake
{0x42, 0x4D, 0xE1, 0x00, 0x00, 0x01, 0x70}, // pms_set_passive_mode
{0x42, 0x4D, 0xE2, 0x00, 0x00, 0x01, 0x71}}; // pms_passive_mode_read
struct pmsX003data {
uint16_t framelen;
@ -52,6 +82,13 @@ struct pmsX003data {
/*********************************************************************************************/
size_t PmsSendCmd(uint8_t command_id)
{
return PmsSerial->write(kPmsCommands[command_id], sizeof(kPmsCommands[command_id]));
}
/*********************************************************************************************/
bool PmsReadData(void)
{
if (! PmsSerial->available()) {
@ -117,7 +154,42 @@ bool PmsReadData(void)
#else
memcpy((void *)&pms_data, (void *)buffer_u16, 30);
#endif // PMS_MODEL_PMS3003
pms_valid = 10;
Pms.valid = 10;
return true;
}
/*********************************************************************************************\
* Command Sensor18
*
* Warmup time for sensor is 30 seconds, therfore setting interval time to less than 60
* seconds doesn't really make sense.
*
* 0 - 59 - Active Mode (continuous sensor readings)
* 60 .. 65535 - Passive Mode (read sensor every x seconds)
\*********************************************************************************************/
bool PmsCommandSensor(void)
{
if ((pin[GPIO_PMS5003_TX] < 99) && (XdrvMailbox.payload >= 0) && (XdrvMailbox.payload < 32001)) {
if (XdrvMailbox.payload < MIN_INTERVAL_PERIOD) {
// Set Active Mode if interval is less than 60 seconds
Settings.pms_wake_interval = 0;
Pms.wake_mode = 1;
Pms.ready = 1;
PmsSendCmd(CMD_MODE_ACTIVE);
PmsSendCmd(CMD_WAKEUP);
} else {
// Set Passive Mode and schedule read once per interval time
Settings.pms_wake_interval = XdrvMailbox.payload;
PmsSendCmd(CMD_MODE_PASSIVE);
PmsSendCmd(CMD_SLEEP);
Pms.wake_mode = 0;
Pms.ready = 0;
}
}
Response_P(S_JSON_SENSOR_INDEX_NVALUE, XSNS_18, Settings.pms_wake_interval);
return true;
}
@ -126,11 +198,38 @@ bool PmsReadData(void)
void PmsSecond(void) // Every second
{
if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) {
// Passive Mode
Pms.time++;
if ((Settings.pms_wake_interval - Pms.time <= WARMUP_PERIOD) && !Pms.wake_mode) {
// wakeup sensor WARMUP_PERIOD before read interval
Pms.wake_mode = 1;
PmsSendCmd(CMD_WAKEUP);
}
if (Pms.time >= Settings.pms_wake_interval) {
// sensor is awake and warmed up, set up for reading
PmsSendCmd(CMD_READ_DATA);
Pms.ready = 1;
Pms.time = 0;
}
}
if (Pms.ready) {
if (PmsReadData()) {
pms_valid = 10;
Pms.valid = 10;
if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) {
PmsSendCmd(CMD_SLEEP);
Pms.wake_mode = 0;
Pms.ready = 0;
}
} else {
if (pms_valid) {
pms_valid--;
if (Pms.valid) {
Pms.valid--;
if (Settings.pms_wake_interval >= MIN_INTERVAL_PERIOD) {
PmsSendCmd(CMD_READ_DATA);
Pms.ready = 1;
}
}
}
}
}
@ -139,12 +238,18 @@ void PmsSecond(void) // Every second
void PmsInit(void)
{
pms_type = 0;
if (pin[GPIO_PMS5003] < 99) {
PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003], -1, 1);
Pms.type = 0;
if (pin[GPIO_PMS5003_RX] < 99) {
PmsSerial = new TasmotaSerial(pin[GPIO_PMS5003_RX], (pin[GPIO_PMS5003_TX] < 99) ? pin[GPIO_PMS5003_TX] : -1, 1);
if (PmsSerial->begin(9600)) {
if (PmsSerial->hardwareSerial()) { ClaimSerial(); }
pms_type = 1;
if (99 == pin[GPIO_PMS5003_TX]) { // setting interval not supported if TX pin not connected
Settings.pms_wake_interval = 0;
Pms.ready = 1;
}
Pms.type = 1;
}
}
}
@ -177,7 +282,7 @@ const char HTTP_PMS5003_SNS[] PROGMEM =
void PmsShow(bool json)
{
if (pms_valid) {
if (Pms.valid) {
if (json) {
#ifdef PMS_MODEL_PMS3003
ResponseAppend_P(PSTR(",\"PMS3003\":{\"CF1\":%d,\"CF2.5\":%d,\"CF10\":%d,\"PM1\":%d,\"PM2.5\":%d,\"PM10\":%d}"),
@ -222,7 +327,7 @@ bool Xsns18(uint8_t function)
{
bool result = false;
if (pms_type) {
if (Pms.type) {
switch (function) {
case FUNC_INIT:
PmsInit();
@ -230,6 +335,11 @@ bool Xsns18(uint8_t function)
case FUNC_EVERY_SECOND:
PmsSecond();
break;
case FUNC_COMMAND_SENSOR:
if (XSNS_18 == XdrvMailbox.index) {
result = PmsCommandSensor();
}
break;
case FUNC_JSON_APPEND:
PmsShow(1);
break;

View File

@ -39,18 +39,18 @@
#define XSNS_27 27
#define XI2C_21 21 // See I2CDEVICES.md
#if defined(USE_SHT) || defined(USE_VEML6070) || defined(USE_TSL2561)
#warning **** Turned off conflicting drivers SHT and VEML6070 ****
#ifdef USE_SHT
#undef USE_SHT // SHT-Driver blocks gesture sensor
#endif
#ifdef USE_VEML6070
#undef USE_VEML6070 // address conflict on the I2C-bus
#endif
#ifdef USE_TSL2561
#undef USE_TSL2561 // possible address conflict on the I2C-bus
#endif
#endif
// #if defined(USE_SHT) || defined(USE_VEML6070) || defined(USE_TSL2561)
// #warning **** Turned off conflicting drivers SHT and VEML6070 ****
// #ifdef USE_SHT
// #undef USE_SHT // SHT-Driver blocks gesture sensor
// #endif
// #ifdef USE_VEML6070
// #undef USE_VEML6070 // address conflict on the I2C-bus
// #endif
// #ifdef USE_TSL2561
// #undef USE_TSL2561 // possible address conflict on the I2C-bus
// #endif
// #endif
#define APDS9960_I2C_ADDR 0x39

View File

@ -20,6 +20,8 @@
--------------------------------------------------------------------------------------------
Version yyyymmdd Action Description
--------------------------------------------------------------------------------------------
0.9.3.1 20200412 added - clean ups, code shrink, battery bugfix
---
0.9.3.0 20200322 added - multi page web view, command HM10PAGE, polling for MJ_HT_V1,
more stable readings, internal refactoring
---
@ -211,10 +213,10 @@ enum HM10_awaitData: uint8_t {
#define TASK_HM10_FEEDBACK 9 // get device response
#define TASK_HM10_DISCONN 10 // disconnect
#define TASK_HM10_SUB_L3 11 // subscribe to service handle 37
#define TASK_HM10_READ_HT 12 // read from handle 36 -> Hum & Temp
#define TASK_HM10_SCAN9 13 // longest discovery scan possible
#define TASK_HM10_UN_L3 14 // unsubscribe service handle 37
#define TASK_HM10_DELAY_SUB_LY 15 // start reading from subscription delayed
#define TASK_HM10_READ_BT_L3 16 // read from handle 3A -> Battery
#define TASK_HM10_SUB_L2 17 // subscribe to service handle 3C
#define TASK_HM10_UN_L2 18 // unsubscribe service handle 3C
@ -227,7 +229,7 @@ enum HM10_awaitData: uint8_t {
#define TASK_HM10_SUB_HT_CGD1 25 // subscribe to service handle 4b
#define TASK_HM10_UN_HT_CGD1 26 // unsubscribe service handle 4b
#define TASK_HM10_READ_B_CGD1 27 // read service handle 11
#define TASK_HM10_DELAY_SUB_CGD1 28 // start reading from subscription delayed
#define TASK_HM10_READ_B_MJ 29 // read service handle 18
#define TASK_HM10_SUB_HT_MJ 30 // subscribe to service handle 0f
@ -356,14 +358,14 @@ uint32_t MIBLEgetSensorSlot(uint8_t (&_serial)[6], uint16_t _type){
DEBUG_SENSOR_LOG(PSTR("%s: vector size %u"),D_CMND_HM10, MIBLEsensors.size());
for(uint32_t i=0; i<MIBLEsensors.size(); i++){
if(memcmp(_serial,MIBLEsensors.at(i).serial,sizeof(_serial))==0){
if(memcmp(_serial,MIBLEsensors[i].serial,sizeof(_serial))==0){
DEBUG_SENSOR_LOG(PSTR("%s: known sensor at slot: %u"),D_CMND_HM10, i);
if(MIBLEsensors.at(i).showedUp < 4){ // if we got an intact packet, the sensor should show up several times
MIBLEsensors.at(i).showedUp++; // count up to the above number ... now we are pretty sure
if(MIBLEsensors[i].showedUp < 4){ // if we got an intact packet, the sensor should show up several times
MIBLEsensors[i].showedUp++; // count up to the above number ... now we are pretty sure
}
return i;
}
DEBUG_SENSOR_LOG(PSTR("%s: i: %x %x %x %x %x %x"),D_CMND_HM10, MIBLEsensors.at(i).serial[5], MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[0]);
DEBUG_SENSOR_LOG(PSTR("%s: i: %x %x %x %x %x %x"),D_CMND_HM10, MIBLEsensors[i].serial[5], MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[2],MIBLEsensors[i].serial[1],MIBLEsensors[i].serial[0]);
DEBUG_SENSOR_LOG(PSTR("%s: n: %x %x %x %x %x %x"),D_CMND_HM10, _serial[5], _serial[4], _serial[3],_serial[2],_serial[1],_serial[0]);
}
DEBUG_SENSOR_LOG(PSTR("%s: found new sensor"),D_CMND_HM10);
@ -422,7 +424,7 @@ void HM10SerialInit(void) {
void HM10parseMiBeacon(char * _buf, uint32_t _slot){
float _tempFloat;
mi_beacon_t _beacon;
if (MIBLEsensors.at(_slot).type==2){
if (MIBLEsensors[_slot].type==MJ_HT_V1 || MIBLEsensors[_slot].type==CGG1){
memcpy((uint8_t*)&_beacon+1,(uint8_t*)_buf, sizeof(_beacon)); // shift by one byte for the MJ_HT_V1
memcpy((uint8_t*)&_beacon.Mac,(uint8_t*)&_beacon.Mac+1,6); // but shift back the MAC
}
@ -430,29 +432,29 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){
memcpy((void*)&_beacon,(void*)_buf, sizeof(_beacon));
}
HM10_ReverseMAC(_beacon.Mac);
if(memcmp(_beacon.Mac,MIBLEsensors.at(_slot).serial,sizeof(_beacon.Mac))!=0){
if (MIBLEsensors.at(_slot).showedUp>3) return; // probably false alarm from a damaged packet
if(memcmp(_beacon.Mac,MIBLEsensors[_slot].serial,sizeof(_beacon.Mac))!=0){
if (MIBLEsensors[_slot].showedUp>3) return; // probably false alarm from a damaged packet
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: remove garbage sensor"),D_CMND_HM10);
DEBUG_SENSOR_LOG(PSTR("%s i: %x %x %x %x %x %x"),D_CMND_HM10, MIBLEsensors.at(_slot).serial[5], MIBLEsensors.at(_slot).serial[4],MIBLEsensors.at(_slot).serial[3],MIBLEsensors.at(_slot).serial[2],MIBLEsensors.at(_slot).serial[1],MIBLEsensors.at(_slot).serial[0]);
DEBUG_SENSOR_LOG(PSTR("%s i: %x %x %x %x %x %x"),D_CMND_HM10, MIBLEsensors[_slot].serial[5], MIBLEsensors[_slot].serial[4],MIBLEsensors[_slot].serial[3],MIBLEsensors[_slot].serial[2],MIBLEsensors[_slot].serial[1],MIBLEsensors[_slot].serial[0]);
DEBUG_SENSOR_LOG(PSTR("%s n: %x %x %x %x %x %x"),D_CMND_HM10, _beacon.Mac[5], _beacon.Mac[4], _beacon.Mac[3],_beacon.Mac[2],_beacon.Mac[1],_beacon.Mac[0]);
MIBLEsensors.erase(MIBLEsensors.begin()+_slot);
return;
}
if (MIBLEsensors.at(_slot).showedUp<4) MIBLEsensors.at(_slot).showedUp++;
if (MIBLEsensors[_slot].showedUp<4) MIBLEsensors[_slot].showedUp++;
DEBUG_SENSOR_LOG(PSTR("MiBeacon type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[0],(uint8_t)_buf[1],(uint8_t)_buf[2],(uint8_t)_buf[3],(uint8_t)_buf[4],(uint8_t)_buf[5],(uint8_t)_buf[6],(uint8_t)_buf[7]);
DEBUG_SENSOR_LOG(PSTR(" type:%02x: %02x %02x %02x %02x %02x %02x %02x %02x"),_beacon.type, (uint8_t)_buf[8],(uint8_t)_buf[9],(uint8_t)_buf[10],(uint8_t)_buf[11],(uint8_t)_buf[12],(uint8_t)_buf[13],(uint8_t)_buf[14],(uint8_t)_buf[15]);
if(MIBLEsensors.at(_slot).type==4 || MIBLEsensors.at(_slot).type==6){
DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors.at(_slot).type);
if(MIBLEsensors[_slot].type==4 || MIBLEsensors[_slot].type==6){
DEBUG_SENSOR_LOG(PSTR("LYWSD03 and CGD1 no support for MiBeacon, type %u"),MIBLEsensors[_slot].type);
return;
}
DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kHM10SlaveType[MIBLEsensors.at(_slot).type-1],_slot);
DEBUG_SENSOR_LOG(PSTR("%s at slot %u"), kHM10SlaveType[MIBLEsensors[_slot].type-1],_slot);
switch(_beacon.type){
case 0x04:
_tempFloat=(float)(_beacon.temp)/10.0f;
if(_tempFloat<60){
MIBLEsensors.at(_slot).temp=_tempFloat;
MIBLEsensors[_slot].temp=_tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode 4: temp updated"));
}
DEBUG_SENSOR_LOG(PSTR("Mode 4: U16: %u Temp"), _beacon.temp );
@ -460,19 +462,19 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){
case 0x06:
_tempFloat=(float)(_beacon.hum)/10.0f;
if(_tempFloat<101){
MIBLEsensors.at(_slot).hum=_tempFloat;
MIBLEsensors[_slot].hum=_tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode 6: hum updated"));
}
DEBUG_SENSOR_LOG(PSTR("Mode 6: U16: %u Hum"), _beacon.hum);
break;
case 0x07:
MIBLEsensors.at(_slot).lux=_beacon.lux & 0x00ffffff;
MIBLEsensors[_slot].lux=_beacon.lux & 0x00ffffff;
DEBUG_SENSOR_LOG(PSTR("Mode 7: U24: %u Lux"), _beacon.lux & 0x00ffffff);
break;
case 0x08:
_tempFloat =(float)_beacon.moist;
if(_tempFloat<100){
MIBLEsensors.at(_slot).moisture=_tempFloat;
MIBLEsensors[_slot].moisture=_tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode 8: moisture updated"));
}
DEBUG_SENSOR_LOG(PSTR("Mode 8: U8: %u Moisture"), _beacon.moist);
@ -480,14 +482,14 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){
case 0x09:
_tempFloat=(float)(_beacon.fert);
if(_tempFloat<65535){ // ???
MIBLEsensors.at(_slot).fertility=_tempFloat;
MIBLEsensors[_slot].fertility=_tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode 9: fertility updated"));
}
DEBUG_SENSOR_LOG(PSTR("Mode 9: U16: %u Fertility"), _beacon.fert);
break;
case 0x0a:
if(_beacon.bat<101){
MIBLEsensors.at(_slot).bat = _beacon.bat;
MIBLEsensors[_slot].bat = _beacon.bat;
DEBUG_SENSOR_LOG(PSTR("Mode a: bat updated"));
}
DEBUG_SENSOR_LOG(PSTR("Mode a: U8: %u %%"), _beacon.bat);
@ -495,12 +497,12 @@ void HM10parseMiBeacon(char * _buf, uint32_t _slot){
case 0x0d:
_tempFloat=(float)(_beacon.HT.temp)/10.0f;
if(_tempFloat<60){
MIBLEsensors.at(_slot).temp = _tempFloat;
MIBLEsensors[_slot].temp = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode d: temp updated"));
}
_tempFloat=(float)(_beacon.HT.hum)/10.0f;
if(_tempFloat<100){
MIBLEsensors.at(_slot).hum = _tempFloat;
MIBLEsensors[_slot].hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("Mode d: hum updated"));
}
DEBUG_SENSOR_LOG(PSTR("Mode d: U16: %x Temp U16: %x Hum"), _beacon.HT.temp, _beacon.HT.hum);
@ -553,7 +555,7 @@ void HM10ParseResponse(char *buf, uint16_t bufsize) {
void HM10readHT_LY(char *_buf){
DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]);
if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return; // "OK+"
if(_buf[0]==0x4f && _buf[1]==0x4b) return; // "OK"
if(_buf[0] != 0 && _buf[1] != 0){
memcpy(&LYWSD0x_HT,(void *)_buf,3);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: T * 100: %u, H: %u"),D_CMND_HM10,LYWSD0x_HT.temp,LYWSD0x_HT.hum);
@ -563,14 +565,14 @@ void HM10readHT_LY(char *_buf){
static float _tempFloat;
_tempFloat=(float)(LYWSD0x_HT.temp)/100.0f;
if(_tempFloat<60){
MIBLEsensors.at(_slot).temp=_tempFloat;
MIBLEsensors[_slot].temp=_tempFloat;
HM10.mode.awaiting = none;
HM10.current_task_delay = 0;
MIBLEsensors.at(_slot).showedUp=255; // this sensor is real
MIBLEsensors[_slot].showedUp=255; // this sensor is real
}
_tempFloat=(float)LYWSD0x_HT.hum;
if(_tempFloat<100){
MIBLEsensors.at(_slot).hum = _tempFloat;
MIBLEsensors[_slot].hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("LYWSD0x: hum updated"));
}
}
@ -578,7 +580,7 @@ void HM10readHT_LY(char *_buf){
void HM10readHT_CGD1(char *_buf){
DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]);
if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return; // "OK+"
if(_buf[0]==0x4f && _buf[1]==0x4b) return; // "OK"
if(_buf[0] == 0){
if(_buf[1]==0 && _buf[2]==0 && _buf[3]==0 && _buf[4]==0) return;
memcpy(&CGD1_HT,(void *)_buf,5);
@ -589,14 +591,14 @@ void HM10readHT_CGD1(char *_buf){
static float _tempFloat;
_tempFloat=(float)(CGD1_HT.temp)/100.0f;
if(_tempFloat<60){
MIBLEsensors.at(_slot).temp=_tempFloat;
MIBLEsensors[_slot].temp=_tempFloat;
HM10.mode.awaiting = none;
HM10.current_task_delay = 0;
MIBLEsensors.at(_slot).showedUp=255; // this sensor is real
MIBLEsensors[_slot].showedUp=255; // this sensor is real
}
_tempFloat=(float)CGD1_HT.hum/100.0f;
if(_tempFloat<100){
MIBLEsensors.at(_slot).hum = _tempFloat;
MIBLEsensors[_slot].hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("CGD1: hum updated"));
}
}
@ -616,21 +618,21 @@ void HM10readHT_MJ_HT_V1(char *_buf){
static float _tempFloat;
_tempFloat=(float)_temp/10.0f;
if(_tempFloat<60){
MIBLEsensors.at(_slot).temp=_tempFloat;
MIBLEsensors[_slot].temp=_tempFloat;
HM10.mode.awaiting = none;
HM10.current_task_delay = 0;
MIBLEsensors.at(_slot).showedUp=255; // this sensor is real
MIBLEsensors[_slot].showedUp=255; // this sensor is real
}
_tempFloat=(float)_hum/10.0f;
if(_tempFloat<100){
MIBLEsensors.at(_slot).hum = _tempFloat;
MIBLEsensors[_slot].hum = _tempFloat;
DEBUG_SENSOR_LOG(PSTR("MJ_HT_V1: hum updated"));
}
}
void HM10readTLMF(char *_buf){
DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]);
if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return; // "OK+"
if(_buf[0]==0x4f && _buf[1]==0x4b) return; // "OK"
if(_buf[0] != 0 || _buf[1] != 0){ // this will lose 0.0 degree, but it is not possible to measure a successful reading
memcpy(&Flora_TLMF,(void *)_buf,10);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: T * 10: %u, L: %u, M: %u, F: %u"),D_CMND_HM10,Flora_TLMF.temp,Flora_TLMF.lux,Flora_TLMF.moist,Flora_TLMF.fert);
@ -640,16 +642,16 @@ void HM10readTLMF(char *_buf){
static float _tempFloat;
_tempFloat=(float)(Flora_TLMF.temp)/10.0f;
if(_tempFloat<60){
MIBLEsensors.at(_slot).temp=_tempFloat;
MIBLEsensors.at(_slot).showedUp=255; // this sensor is real
MIBLEsensors[_slot].temp=_tempFloat;
MIBLEsensors[_slot].showedUp=255; // this sensor is real
}
MIBLEsensors.at(_slot).lux = Flora_TLMF.lux;
MIBLEsensors[_slot].lux = Flora_TLMF.lux;
_tempFloat=(float)Flora_TLMF.moist;
if(_tempFloat<100){
MIBLEsensors.at(_slot).moisture = _tempFloat;
MIBLEsensors[_slot].moisture = _tempFloat;
}
MIBLEsensors.at(_slot).fertility = (float)Flora_TLMF.fert;
MIBLEsensors[_slot].fertility = (float)Flora_TLMF.fert;
HM10.mode.awaiting = none;
HM10.current_task_delay = 0;
@ -658,14 +660,14 @@ void HM10readTLMF(char *_buf){
bool HM10readBat(char *_buf){
DEBUG_SENSOR_LOG(PSTR("%s: raw data: %x%x%x%x%x%x%x"),D_CMND_HM10,_buf[0],_buf[1],_buf[2],_buf[3],_buf[4],_buf[5],_buf[6]);
if(_buf[0]==0x4f && _buf[1]==0x4b && _buf[2]==0x2b) return false; // "OK+"
if(_buf[0]==0x4f && _buf[1]==0x4b) return false; // "OK"
if(_buf[0] != 0){
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s: Battery: %u"),D_CMND_HM10,_buf[0]);
uint32_t _slot = HM10.state.sensor;
DEBUG_SENSOR_LOG(PSTR("MIBLE: Sensor slot: %u"), _slot);
if(_buf[0]<101){
MIBLEsensors.at(_slot).bat=_buf[0];
MIBLEsensors.at(_slot).showedUp=255; // this sensor is real
MIBLEsensors[_slot].bat=_buf[0];
MIBLEsensors[_slot].showedUp=255; // this sensor is real
return true;
}
}
@ -780,7 +782,7 @@ void HM10_TaskEvery100ms(){
break;
case TASK_HM10_CONN:
char _con[20];
sprintf_P(_con,"AT+CON%02x%02x%02x%02x%02x%02x",MIBLEsensors.at(HM10.state.sensor).serial[0],MIBLEsensors.at(HM10.state.sensor).serial[1],MIBLEsensors.at(HM10.state.sensor).serial[2],MIBLEsensors.at(HM10.state.sensor).serial[3],MIBLEsensors.at(HM10.state.sensor).serial[4],MIBLEsensors.at(HM10.state.sensor).serial[5]);
sprintf_P(_con,"AT+CON%02x%02x%02x%02x%02x%02x",MIBLEsensors[HM10.state.sensor].serial[0],MIBLEsensors[HM10.state.sensor].serial[1],MIBLEsensors[HM10.state.sensor].serial[2],MIBLEsensors[HM10.state.sensor].serial[3],MIBLEsensors[HM10.state.sensor].serial[4],MIBLEsensors[HM10.state.sensor].serial[5]);
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: connect %s"),D_CMND_HM10, _con);
HM10.current_task_delay = 2; // set task delay
HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i);
@ -806,7 +808,8 @@ void HM10_TaskEvery100ms(){
case TASK_HM10_SUB_L3:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: subscribe"),D_CMND_HM10);
HM10.current_task_delay = 25; // set task delay
HM10_TaskReplaceInSlot(TASK_HM10_DELAY_SUB_LY,i);
HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i);
HM10.mode.awaiting = tempHumLY;
runningTaskLoop = false;
HM10Serial->write("AT+NOTIFY_ON0037");
break;
@ -821,7 +824,8 @@ void HM10_TaskEvery100ms(){
case TASK_HM10_SUB_L2:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: subscribe"),D_CMND_HM10);
HM10.current_task_delay = 25; // set task delay
HM10_TaskReplaceInSlot(TASK_HM10_DELAY_SUB_LY,i);
HM10.mode.awaiting = tempHumLY;
HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i);
runningTaskLoop = false;
HM10Serial->write("AT+NOTIFY_ON003C");
break;
@ -844,14 +848,6 @@ void HM10_TaskEvery100ms(){
HM10Serial->write(Rtc.time_timezone / 60);
AddLog_P2(LOG_LEVEL_DEBUG,PSTR("%s Time-string: %x%x%x%x%x"),D_CMND_HM10, HM10.timebuf[0],HM10.timebuf[1],HM10.timebuf[2],HM10.timebuf[3],(Rtc.time_timezone /60));
break;
case TASK_HM10_READ_HT:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: read handle 0036"),D_CMND_HM10);
HM10.current_task_delay = 0; // set task delay
HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i);
runningTaskLoop = false;
HM10Serial->write("AT+READDATA0036?");
HM10.mode.awaiting = tempHumLY;
break;
case TASK_HM10_READ_BT_L3:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: read handle 003A"),D_CMND_HM10);
HM10.current_task_delay = 2; // set task delay
@ -905,9 +901,9 @@ void HM10_TaskEvery100ms(){
case TASK_HM10_SUB_HT_CGD1:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: subscribe 4b"),D_CMND_HM10);
HM10.current_task_delay = 5; // set task delay
HM10_TaskReplaceInSlot(TASK_HM10_DELAY_SUB_CGD1,i);
HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i);
runningTaskLoop = false;
HM10.mode.awaiting = none;
HM10.mode.awaiting = tempHumCGD1;
HM10Serial->write("AT+NOTIFY_ON004b");
break;
case TASK_HM10_UN_HT_CGD1:
@ -938,7 +934,6 @@ void HM10_TaskEvery100ms(){
HM10.current_task_delay = 10; // set task delay
HM10_TaskReplaceInSlot(TASK_HM10_FEEDBACK,i);
runningTaskLoop = false;
HM10.mode.awaiting = none;
HM10Serial->write("AT+NOTIFY_ON000F");
HM10.mode.awaiting = tempHumMJ;
break;
@ -949,22 +944,6 @@ void HM10_TaskEvery100ms(){
HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset
runningTaskLoop = false;
break;
case TASK_HM10_DELAY_SUB_LY:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: start reading"),D_CMND_HM10);
HM10SerialHandleFeedback();
HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay
HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset
HM10.mode.awaiting = tempHumLY;
runningTaskLoop = false;
break;
case TASK_HM10_DELAY_SUB_CGD1:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: start reading"),D_CMND_HM10);
HM10SerialHandleFeedback();
HM10.current_task_delay = HM10_TASK_LIST[i+1][1];; // set task delay
HM10_TASK_LIST[i][0] = TASK_HM10_DONE; // no feedback for reset
HM10.mode.awaiting = tempHumCGD1;
runningTaskLoop = false;
break;
case TASK_HM10_STATUS_EVENT:
AddLog_P2(LOG_LEVEL_DEBUG, PSTR("%s: show status"),D_CMND_HM10);
HM10StatusInfo();
@ -1037,11 +1016,11 @@ void HM10EverySecond(bool restart){
HM10.state.sensor = _nextSensorSlot;
_nextSensorSlot++;
HM10.mode.pending_task = 1;
switch(MIBLEsensors.at(HM10.state.sensor).type){
switch(MIBLEsensors[HM10.state.sensor].type){
case FLORA:
HM10_Read_Flora();
break;
case MJ_HT_V1:
case MJ_HT_V1: case CGG1:
HM10_Read_MJ_HT_V1();
break;
case LYWSD02:
@ -1125,7 +1104,7 @@ bool HM10Cmd(void) {
case CMND_HM10_TIME:
if (XdrvMailbox.data_len > 0) {
if(MIBLEsensors.size()>XdrvMailbox.payload){
if(MIBLEsensors.at(XdrvMailbox.payload).type == LYWSD02){
if(MIBLEsensors[XdrvMailbox.payload].type == LYWSD02){
HM10.state.sensor = XdrvMailbox.payload;
HM10_Time_LYWSD02();
}
@ -1173,7 +1152,7 @@ bool HM10Cmd(void) {
const char HTTP_HM10[] PROGMEM = "{s}HM10 V%u{m}%u%s / %u{e}";
const char HTTP_HM10_SERIAL[] PROGMEM = "{s}%s %s{m}%02x:%02x:%02x:%02x:%02x:%02x%{e}";
const char HTTP_BATTERY[] PROGMEM = "{s}%s" " Battery" "{m}%u%%{e}";
const char HTTP_HM10_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%sus/cm{e}";
const char HTTP_HM10_FLORA_DATA[] PROGMEM = "{s}%s" " Fertility" "{m}%uus/cm{e}";
const char HTTP_HM10_HL[] PROGMEM = "{s}<hr>{m}<hr>{e}";
void HM10Show(bool json)
@ -1181,41 +1160,35 @@ void HM10Show(bool json)
if (json) {
for (uint32_t i = 0; i < MIBLEsensors.size(); i++) {
char slave[33];
sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors.at(i).type-1],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]);
sprintf_P(slave,"%s-%02x%02x%02x",kHM10SlaveType[MIBLEsensors[i].type-1],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]);
ResponseAppend_P(PSTR(",\"%s\":{"),slave);
if (MIBLEsensors.at(i).type==FLORA){
if(!isnan(MIBLEsensors.at(i).temp)){ // this is the error code -> no temperature
if (MIBLEsensors[i].type==FLORA){
if(!isnan(MIBLEsensors[i].temp)){ // this is the error code -> no temperature
char temperature[FLOATSZ]; // all sensors have temperature
dtostrfd(MIBLEsensors.at(i).temp, Settings.flag2.temperature_resolution, temperature);
dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature);
ResponseAppend_P(PSTR("\"" D_JSON_TEMPERATURE "\":%s"), temperature);
}
else {
ResponseAppend_P(PSTR("}"));
continue;
}
char lux[FLOATSZ];
char moisture[FLOATSZ];
char fertility[FLOATSZ];
dtostrfd((float)MIBLEsensors.at(i).lux, 0, lux);
dtostrfd(MIBLEsensors.at(i).moisture, 0, moisture);
dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility);
if(MIBLEsensors.at(i).lux!=0x0ffffff){ // this is the error code -> no temperature
ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%s"), lux);
if(MIBLEsensors[i].lux!=0x0ffffff){ // this is the error code -> no lux
ResponseAppend_P(PSTR(",\"" D_JSON_ILLUMINANCE "\":%u"), MIBLEsensors[i].lux);
}
if(!isnan(MIBLEsensors.at(i).moisture)){ // this is the error code -> no moisture
ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%s"), moisture);
if(!isnan(MIBLEsensors[i].moisture)){
ResponseAppend_P(PSTR(",\"" D_JSON_MOISTURE "\":%d"), MIBLEsensors[i].moisture);
}
if(!isnan(MIBLEsensors.at(i).fertility)){ // this is the error code -> no fertility
ResponseAppend_P(PSTR(",\"Fertility\":%s"), fertility);
if(!isnan(MIBLEsensors[i].fertility)){
ResponseAppend_P(PSTR(",\"Fertility\":%d"), MIBLEsensors[i].fertility);
}
}
if (MIBLEsensors.at(i).type>FLORA){
if(!isnan(MIBLEsensors.at(i).hum) && !isnan(MIBLEsensors.at(i).temp)){ // this is the error code -> no humidity nor temp
ResponseAppendTHD(MIBLEsensors.at(i).temp, MIBLEsensors.at(i).hum);
if (MIBLEsensors[i].type>FLORA){
if(!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)){
ResponseAppendTHD(MIBLEsensors[i].temp, MIBLEsensors[i].hum);
}
}
if(MIBLEsensors.at(i).bat!=0x00){ // this is the error code -> no battery
ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors.at(i).bat);
if(MIBLEsensors[i].bat!=0x00){ // this is the error code -> no battery
ResponseAppend_P(PSTR(",\"Battery\":%u"), MIBLEsensors[i].bat);
}
ResponseAppend_P(PSTR("}"));
}
@ -1237,32 +1210,30 @@ void HM10Show(bool json)
WSContentSend_PD(HTTP_HM10, HM10.firmware, i+1,stemp,MIBLEsensors.size());
for (i; i<j; i++) {
WSContentSend_PD(HTTP_HM10_HL);
WSContentSend_PD(HTTP_HM10_SERIAL, kHM10SlaveType[MIBLEsensors.at(i).type-1], D_MAC_ADDRESS, MIBLEsensors.at(i).serial[0], MIBLEsensors.at(i).serial[1],MIBLEsensors.at(i).serial[2],MIBLEsensors.at(i).serial[3],MIBLEsensors.at(i).serial[4],MIBLEsensors.at(i).serial[5]);
if (MIBLEsensors.at(i).type==FLORA){
if(!isnan(MIBLEsensors.at(i).temp)){
WSContentSend_PD(HTTP_HM10_SERIAL, kHM10SlaveType[MIBLEsensors[i].type-1], D_MAC_ADDRESS, MIBLEsensors[i].serial[0], MIBLEsensors[i].serial[1],MIBLEsensors[i].serial[2],MIBLEsensors[i].serial[3],MIBLEsensors[i].serial[4],MIBLEsensors[i].serial[5]);
if (MIBLEsensors[i].type==FLORA){
if(!isnan(MIBLEsensors[i].temp)){
char temperature[FLOATSZ];
dtostrfd(MIBLEsensors.at(i).temp, Settings.flag2.temperature_resolution, temperature);
WSContentSend_PD(HTTP_SNS_TEMP, kHM10SlaveType[MIBLEsensors.at(i).type-1], temperature, TempUnit());
dtostrfd(MIBLEsensors[i].temp, Settings.flag2.temperature_resolution, temperature);
WSContentSend_PD(HTTP_SNS_TEMP, kHM10SlaveType[MIBLEsensors[i].type-1], temperature, TempUnit());
}
if(MIBLEsensors.at(i).lux!=0x00ffffff){ // this is the error code -> no valid value
WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).lux);
if(MIBLEsensors[i].lux!=0x00ffffff){ // this is the error code -> no valid value
WSContentSend_PD(HTTP_SNS_ILLUMINANCE, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].lux);
}
if(!isnan(MIBLEsensors.at(i).moisture)){ // this is the error code -> no valid value
WSContentSend_PD(HTTP_SNS_MOISTURE, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).moisture);
if(!isnan(MIBLEsensors[i].moisture)){
WSContentSend_PD(HTTP_SNS_MOISTURE, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].moisture);
}
if(!isnan(MIBLEsensors.at(i).fertility)){ // this is the error code -> no valid value
char fertility[FLOATSZ];
dtostrfd(MIBLEsensors.at(i).fertility, 0, fertility);
WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors.at(i).type-1], fertility);
if(!isnan(MIBLEsensors[i].fertility)){
WSContentSend_PD(HTTP_HM10_FLORA_DATA, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].fertility);
}
}
if (MIBLEsensors.at(i).type>FLORA){ // everything "above" Flora
if(!isnan(MIBLEsensors.at(i).hum) && !isnan(MIBLEsensors.at(i).temp)){
WSContentSend_THD(kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).temp, MIBLEsensors.at(i).hum);
if (MIBLEsensors[i].type>FLORA){ // everything "above" Flora
if(!isnan(MIBLEsensors[i].hum) && !isnan(MIBLEsensors[i].temp)){
WSContentSend_THD(kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].temp, MIBLEsensors[i].hum);
}
}
if(MIBLEsensors.at(i).bat!=0x00){
WSContentSend_PD(HTTP_BATTERY, kHM10SlaveType[MIBLEsensors.at(i).type-1], MIBLEsensors.at(i).bat);
if(MIBLEsensors[i].bat!=0x00){
WSContentSend_PD(HTTP_BATTERY, kHM10SlaveType[MIBLEsensors[i].type-1], MIBLEsensors[i].bat);
}
}
_counter++;