v5.9.0a - Add Sensor Service and Fix config download

5.9.0a
* Add external sensor function pointer interface to enable easy sensor
addition
* Fix Backup Configuration file download failure by defining proper file
size (#1115)
This commit is contained in:
arendst 2017-11-03 18:07:25 +01:00
parent d5cf0fc57f
commit 68cdc6130c
19 changed files with 713 additions and 402 deletions

View File

@ -1,7 +1,7 @@
## Sonoff-Tasmota
Provide ESP8266 based Sonoff by [iTead Studio](https://www.itead.cc/) and ElectroDragon IoT Relay with Serial, Web and MQTT control allowing 'Over the Air' or OTA firmware updates using Arduino IDE.
Current version is **5.8.0q** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
Current version is **5.9.0a** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### ATTENTION All versions

View File

@ -1,91 +1,11 @@
/* 5.8.0q
* Shrink code by 4k using command lookup tables
* Add retry counter to DHT11/21/22 sensors (#1082)
* Add commands RfSync, RfLow, RfHigh, RfHost and RfCode to allow sending custom RF codes (#1001)
/* 5.9.0a
* Add external sensor function pointer interface to enable easy sensor addition
* Fix Backup Configuration file download failure by defining proper file size (#1115)
*
* 5.8.0p
* Fix initial PwmFrequency and PwmRange
* Add support for Arilux AL-LC01 RGB Led controller (#370)
* Add light turn Off Fade (#925)
* Change IrSend Panasonic command to IrSend {"Protocol":"Panasonic", "Bits":16388, "Data":<Panasonic data>}
* where 16388 is 0x4004 hexadecimal (#1014)
*
* 5.8.0o
* Remove max string length of 14 for Domoticz sensor descriptions
* Add light scheme options (Color cycle Up, Down, Random) and moving WS2812 schemes up by 3
* Add support for VEML6070 I2C Ultra Violet level sensor (#1053)
*
* 5.8.0n
* Fix minimum TelePeriod of 10 seconds set by web page
* Shrink information web page by 1k code space
* Removed Arduino IDE version too low warning as it interferes with platformio.ini platform = espressif8266_stage
* Add commands Color2, Color3, Color4, Width2, Width3, Width4 and SetOption16 to set Ws2812 Clock parameters (#1019)
* Fix Color3 and Color4 (#1019)
* Add Polish language file (#1044, #1047)
* Add support for KMC 70011 Power Monitoring Smart Plug (#1045)
* Corrected German language file (#1054)
*
* 5.8.0m
* 5.9.0 20171030
* Rewrite code (partly) using Google C++ Style Guide (https://google.github.io/styleguide/cppguide.html)
* Allow empty MqttHost name by using option 0
* Allow Mqtt server mDNS lookup only when MqttHost name is empty (#1026)
* Change Ws2812 clock with more flexible version (#1019)
* Add German language file (#1022)
* Support connecting to MQTT brokers without userid and/or password (#1023)
* Add commands PwmRange 1,255..1023 and PwmFrequency 1,100..4000 (#1025)
*
* 5.8.0l
* Update HTML/CSS to enable nicer form field entry
* Fix inverted relay status after restart or power on as regression from 5.8.0d (#909)
* Add send protocol Panasonic to IRsend (#1014)
* Fix relay power control when light power control is also configured as regression from 5.8.0 (#1016)
*
* 5.8.0k
* Add support for up to 8 relays (#995)
* Fix Blocked Loop when erasing large flash using command reset 2 (#1002)
* Add retain to ENERGY messages controlled by command SensorRetain (#1013)
*
* 5.8.0j
* Set default altitude to 0 to be used with pressure sensors
* Document flash settings area for future use
* Prepare for 32-bit power control (#995)
* Introduce sonoff.h master header
* Fix TLS MQTT SSL fingerprint test (#808, #970)
* Fix pressure calculation for some BMP versions regression introduced with version 5.8.0i (#974)
* Fix Domoticz Dimmer set to same level not powering on (#945)
*
* 5.8.0i
* Add Domoticz counter sensor to IrReceive representing Received IR Protocol and Data
* Fix Southern Hemisphere TIME_STD/TIME_DST (#968)
* Add Sea level pressure calculation (#974)
* Fix virtual relay status message used with Color/Dimmer control (#989)
* Fix command IRSend and IRHvac case sensitive parameter regression introduced with version 5.8.0 (#993)
*
* 5.8.0h
* Rename command IRRemote to IRSend (#956)
* Add IR Receiver support. Disable in user_config.h (#956)
* Change default PWM assignment for Witty Cloud to support optional Color/Dimmer control (#976)
* GPIO12 (Green) from GPIO_PWM4 to GPIO_PWM2
* GPIO13 (Blue) from GPIO_PWM5 to GPIO_PWM3
* GPIO15 (Red) from GPIO_PWM3 to GPIO_PWM1
*
* 5.8.0g
* Fix inverted PWM index (#960)
* Fix some PWM related issues (#967)
* Fix timezone range from -12/12 to -13/13 (#968)
*
* 5.8.0f
* Set all saved power settings to Off when SetOption0 (SaveState) = 0 (#955)
* Allow PWM initialization after restart (#955)
* Add support for inverted PWM (#960)
*
* 5.8.0e
* Add Domoticz counter sensor to Sonoff Bridge representing Received RF code (#943)
* Add support for Luani HVIO board (https://luani.de/projekte/esp8266-hvio/) (#953)
*
* 5.8.0d
* Remove previous GPIO configuration when another module is selected
* Fix inverted relay power on state (#909)
* Rewrite code by using command lookup tables and javascript (client side) web page expansions
* Change HTML/CSS to enable nicer form field entry
* Change default PWM assignments for H801 RGB(CW) led controller to support optional Color/Dimmer control
* GPIO04 (W2) from GPIO_PWM2 to GPIO_USER to be user configurable for GPIO_PWM5 (second White - Warm if W1 is Cold)
* GPIO12 (Blue) GPIO_PWM3 no change
@ -97,26 +17,66 @@
* GPIO12 (Blue) from GPIO_PWM5 to GPIO_PWM3
* GPIO13 (White) GPIO_USER to be user configurable for GPIO_PWM4 (White - Cold or Warm)
* GPIO14 (Red) from GPIO_PWM3 to GPIO_PWM1
* Add command SetOption15 0 (default) for command PWM control or SetOption15 1 for commands Color/Dimmer control to PWM RGB(CW) leds (#941)
*
* 5.8.0c
* Add warning to webpage when USE_MINIMAL is selected (#929)
* Fix compile error when DOMOTICZ_UPDATE_TIMER is not defined (#930)
* Fix alignment of web page items in some browsers (#935)
* Add smoother movement of hour hand in WS2812 led clock (#936)
* Add support for Magic Home RGBW and some Arilux Led controllers (#940)
*
* 5.8.0b
* Change default PWM assignment for Witty Cloud to support optional Color/Dimmer control (#976)
* GPIO12 (Green) from GPIO_PWM4 to GPIO_PWM2
* GPIO13 (Blue) from GPIO_PWM5 to GPIO_PWM3
* GPIO15 (Red) from GPIO_PWM3 to GPIO_PWM1
* Change when another module is selected now all GPIO user configuration is removed
* Change command name IRRemote to IRSend (#956)
* Remove Arduino IDE version too low warning as it interferes with platformio.ini platform = espressif8266_stage
* Fix command FullTopic entry when using serial or console interface
* Fix possible UDP syslog blocking
* Fix minimum TelePeriod of 10 seconds set by web page
* Fix command GPIOx JSON response (#897)
* Fix inverted relay power on state (#909)
* Fix compile error when DOMOTICZ_UPDATE_TIMER is not defined (#930)
* Fix alignment of web page items in some browsers (#935)
* Fix setting all saved power settings to Off when SetOption0 (SaveState) = 0 (#955)
* Fix timezone range from -12/12 to -13/13 (#968)
* Fix Southern Hemisphere TIME_STD/TIME_DST (#968)
* Fix TLS MQTT SSL fingerprint test (#970, #808)
* Fix virtual relay status message used with Color/Dimmer control (#989)
* Fix command IRSend and IRHvac case sensitive parameter regression introduced with version 5.8.0 (#993)
* Fix pressure calculation for some BMP versions regression introduced with version 5.8.0i (#974)
* Fix Domoticz Dimmer set to same level not powering on (#945)
* Fix Blocked Loop when erasing large flash using command reset 2 (#1002)
* Fix relay power control when light power control is also configured as regression from 5.8.0 (#1016)
* Fix Mqtt server mDNS lookup only when MqttHost name is empty (#1026)
* Add debug information to MQTT subscribe
* Add Domoticz sensors for Voltage and Current (#903)
*
* 5.8.0a
* Add translations to I2Cscan
* Add translation to BH1750 unit lx
* Set default WS2812 pixel count to WS2812_LEDS
* Fix command GPIOx JSON response (#897)
* Add light scheme options (Color cycle Up, Down, Random) and moving WS2812 schemes up by 3
* Add Domoticz counter sensor to IrReceive representing Received IR Protocol and Data
* Add option 0 to MqttHost to allow empty Mqtt host name
* Add support for Arilux AL-LC01 RGB Led controller (#370)
* Add esp8266 de-blocking to PubSubClient library (#790)
* Add Domoticz sensors for Voltage and Current (#903)
* Add platformio OTA upload support (#928, #934)
* Add warning to webpage when USE_MINIMAL is selected (#929)
* Add smoother movement of hour hand in WS2812 led clock (#936)
* Add support for Magic Home RGBW and some Arilux Led controllers (#940)
* Add command SetOption15 0 (default) for command PWM control or SetOption15 1 for commands Color/Dimmer control to PWM RGB(CW) leds (#941)
* Add Domoticz counter sensor to Sonoff Bridge representing Received RF code (#943)
* Add support for Luani HVIO board (https://luani.de/projekte/esp8266-hvio/) (#953)
* Add PWM initialization after restart (#955)
* Add IR Receiver support. Disable in user_config.h (#956)
* Add support for inverted PWM (#960)
* Add Sea level pressure calculation and Provide command Altitude (#974)
* Add support for up to 8 relays (#995)
* Add commands RfSync, RfLow, RfHigh, RfHost and RfCode to allow sending custom RF codes (#1001)
* Add retain to ENERGY messages controlled by command SensorRetain (#1013)
* Add commands Color2, Color3, Color4, Width2, Width3, Width4 and SetOption16 to set Ws2812 Clock parameters (#1019)
* Add German language file (#1022)
* Add support for connecting to MQTT brokers without userid and/or password (#1023)
* Add support for esp8266 core v2.4.0-rc2 (#1024)
* Add commands PwmRange 1,255..1023 and PwmFrequency 1,100..4000 (#1025)
* Add Polish language file (#1044, #1047)
* Add support for KMC 70011 Power Monitoring Smart Plug (#1045)
* Add support for VEML6070 I2C Ultra Violet level sensor (#1053)
* Add light turn Off Fade (#925)
* Add IrSend command option Panasonic as IrSend {"Protocol":"Panasonic", "Bits":16388, "Data":<Panasonic data>}
* where 16388 is 0x4004 hexadecimal (#1014)
* Add retry counter to DHT11/21/22 sensors (#1082)
*
* 5.8.0 20170918
* Remove the need for NeoPixelBus library for Hue support

View File

@ -90,6 +90,8 @@ typedef unsigned long power_t; // Power (Relay) type
#define APP_BAUDRATE 115200 // Default serial baudrate
#define MAX_STATUS 11 // Max number of status lines
#define XSNS_MAX 20 // Max number of allowed Xsns External Sensors (Update xsns_interface.ino if changed)
/*********************************************************************************************\
* Enumeration
\*********************************************************************************************/
@ -110,6 +112,7 @@ enum Ws2812Color {WS_RED, WS_GREEN, WS_BLUE};
enum LightTypes {LT_BASIC, LT_PWM1, LT_PWM2, LT_PWM3, LT_PWM4, LT_PWM5, LT_PWM6, LT_PWM7, LT_NU8, LT_NU9, LT_NU10, LT_WS2812, LT_RGBW, LT_RGBWC};
enum LichtSubtypes {LST_NONE, LST_SINGLE, LST_COLDWARM, LST_RGB, LST_RGBW, LST_RGBWC};
enum LichtSchemes {LS_POWER, LS_WAKEUP, LS_CYCLEUP, LS_CYCLEDN, LS_RANDOM, LS_MAX};
enum XsnsFunctions {FUNC_XSNS_INIT, FUNC_XSNS_PREP, FUNC_XSNS_JSON, FUNC_XSNS_WEB};
const uint8_t kDefaultRfCode[9] PROGMEM = { 0x21, 0x16, 0x01, 0x0E, 0x03, 0x48, 0x2E, 0x1A, 0x00 };

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/
#define VERSION 0x05080011 // 5.8.0q
#define VERSION 0x05090001 // 5.9.0a
// Location specific includes
#include "sonoff.h" // Enumaration used in user_config.h
@ -183,6 +183,7 @@ uint8_t light_type = 0; // Light types
boolean mdns_begun = false;
boolean (*xsns_func_ptr[XSNS_MAX])(byte); // External Sensor Function Pointers for simple implementation of sensors
char version[16]; // Version string from VERSION define
char my_hostname[33]; // Composed Wifi hostname
char mqtt_client[33]; // Composed MQTT Clientname
@ -1757,9 +1758,8 @@ void PublishStatus(uint8_t payload)
}
if ((0 == payload) || (10 == payload)) {
uint8_t djson = 0;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":"));
MqttShowSensor(&djson);
MqttShowSensor();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
MqttPublishPrefixTopic_P(option, PSTR(D_CMND_STATUS "10"));
}
@ -1789,62 +1789,26 @@ void MqttShowState()
mqtt_data, Settings.sta_active +1, Settings.sta_ssid[Settings.sta_active], WifiGetRssiAsQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
}
void MqttShowSensor(uint8_t* djson)
boolean MqttShowSensor()
{
boolean json_data_available = false;
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{\"" D_TIME "\":\"%s\""), mqtt_data, GetDateAndTime().c_str());
for (byte i = 0; i < MAX_SWITCHES; i++) {
if (pin[GPIO_SWT1 +i] < 99) {
boolean swm = ((FOLLOW_INV == Settings.switchmode[i]) || (PUSHBUTTON_INV == Settings.switchmode[i]) || (PUSHBUTTONHOLD_INV == Settings.switchmode[i]));
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_SWITCH "%d\":\"%s\""), mqtt_data, i +1, GetStateText(swm ^ lastwallswitch[i]));
*djson = 1;
json_data_available = true;
}
}
MqttShowCounter(djson);
#ifndef USE_ADC_VCC
if (pin[GPIO_ADC0] < 99) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_ANALOG_INPUT0 "\":%d"), mqtt_data, GetAdc0());
*djson = 1;
if (XsnsCall(FUNC_XSNS_JSON)) {
json_data_available = true;
}
#endif
if (SONOFF_SC == Settings.module) {
MqttShowSonoffSC(djson);
}
if (pin[GPIO_DSB] < 99) {
#ifdef USE_DS18B20
MqttShowDs18b20(djson);
#endif // USE_DS18B20
#ifdef USE_DS18x20
MqttShowDs18x20(djson);
#endif // USE_DS18x20
}
#ifdef USE_DHT
if (dht_flg) {
MqttShowDht(djson);
}
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_SHT
MqttShowSht(djson);
#endif // USE_SHT
#ifdef USE_HTU
MqttShowHtu(djson);
#endif // USE_HTU
#ifdef USE_BMP
MqttShowBmp(djson);
#endif // USE_BMP
#ifdef USE_BH1750
MqttShowBh1750(djson);
#endif // USE_BH1750
#ifdef USE_VEML6070
MqttShowVeml6070(djson);
#endif // USE_VEML6070
}
#endif // USE_I2C
if (strstr_P(mqtt_data, PSTR(D_TEMPERATURE))) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE_UNIT "\":\"%c\""), mqtt_data, TempUnit());
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
return json_data_available;
}
/********************************************************************************************/
@ -1897,39 +1861,7 @@ void PerformEverySecond()
if (Settings.tele_period) {
tele_period++;
if (tele_period == Settings.tele_period -1) {
if (pin[GPIO_DSB] < 99) {
#ifdef USE_DS18B20
Ds18b20ReadTempPrep();
#endif // USE_DS18B20
#ifdef USE_DS18x20
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
#endif // USE_DS18x20
}
#ifdef USE_DHT
if (dht_flg) {
DhtReadPrep();
}
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_SHT
ShtDetect();
#endif // USE_SHT
#ifdef USE_HTU
HtuDetect();
#endif // USE_HTU
#ifdef USE_BMP
BmpDetect();
#endif // USE_BMP
#ifdef USE_BH1750
Bh1750Detect();
#endif // USE_BH1750
#ifdef USE_VEML6070
Veml6070Detect();
#endif // USE_VEML6070
}
#endif // USE_I2C
XsnsCall(FUNC_XSNS_PREP);
}
if (tele_period >= Settings.tele_period) {
tele_period = 0;
@ -1938,10 +1870,8 @@ void PerformEverySecond()
MqttShowState();
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_STATE));
uint8_t djson = 0;
mqtt_data[0] = '\0';
MqttShowSensor(&djson);
if (djson) {
if (MqttShowSensor()) {
MqttPublishPrefixTopic_P(2, PSTR(D_RSLT_SENSOR), Settings.flag.mqtt_sensor_retain);
}
@ -2684,24 +2614,9 @@ void GpioInit()
#endif // USE_IR_RECEIVE
#endif // USE_IR_REMOTE
CounterInit();
hlw_flg = ((pin[GPIO_HLW_SEL] < 99) && (pin[GPIO_HLW_CF1] < 99) && (pin[GPIO_HLW_CF] < 99));
if (hlw_flg) {
HlwInit();
}
#ifdef USE_DHT
if (dht_flg) {
DhtInit();
}
#endif // USE_DHT
#ifdef USE_DS18x20
if (pin[GPIO_DSB] < 99) {
Ds18x20Init();
}
#endif // USE_DS18x20
XSnsInit();
}
extern "C" {

View File

@ -1136,16 +1136,6 @@ char TempUnit()
return (Settings.flag.temperature_conversion) ? 'F' : 'C';
}
uint16_t GetAdc0()
{
uint16_t alr = 0;
for (byte i = 0; i < 32; i++) {
alr += analogRead(A0);
delay(1);
}
return alr >> 5;
}
double FastPrecisePow(double a, double b)
{
// https://martin.ankerl.com/2012/01/25/optimized-approximative-pow-in-c-and-cpp/
@ -1233,8 +1223,72 @@ int GetCommandCode(char* destination, size_t destination_size, const char* needl
return result;
}
#ifndef USE_ADC_VCC
/*********************************************************************************************\
* ADC support
\*********************************************************************************************/
uint16_t GetAdc0()
{
uint16_t alr = 0;
for (byte i = 0; i < 32; i++) {
alr += analogRead(A0);
delay(1);
}
return alr >> 5;
}
boolean MqttShowAdc()
{
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_ANALOG_INPUT0 "\":%d"), mqtt_data, GetAdc0());
return true;
}
#ifdef USE_WEBSERVER
void WebShowAdc()
{
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}" D_ANALOG_INPUT0 "{m}%d{e}"), mqtt_data, GetAdc0());
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_02
boolean Xsns02(byte function)
{
boolean result = false;
if (pin[GPIO_ADC0] < 99) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
// case FUNC_XSNS_PREP:
// break;
case FUNC_XSNS_JSON:
result = MqttShowAdc();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowAdc();
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_ADC_VCC
/*********************************************************************************************\
* Syslog
*
* Example:
* snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_LOG "Any value %d"), value);
* AddLog(LOG_LEVEL_DEBUG);
*
\*********************************************************************************************/
void Syslog()

View File

@ -197,4 +197,4 @@
#error "Select either USE_MQTT_TLS or USE_WEBSERVER as there is just not enough memory to play with"
#endif
#endif // _USER_CONFIG_H_
#endif // _USER_CONFIG_H_

View File

@ -274,25 +274,19 @@ const char HTTP_TABLE100[] PROGMEM =
"<table style='width:100%'>";
const char HTTP_COUNTER[] PROGMEM =
"<br/><div id='t' name='t' style='text-align:center;'></div>";
const char HTTP_SNS_TEMP[] PROGMEM =
"<tr><th>%s " D_TEMPERATURE "</th><td>%s&deg;%c</td></tr>";
const char HTTP_SNS_HUM[] PROGMEM =
"<tr><th>%s " D_HUMIDITY "</th><td>%s%</td></tr>";
const char HTTP_SNS_PRESSURE[] PROGMEM =
"<tr><th>%s " D_PRESSURE "</th><td>%s " D_UNIT_PRESSURE "</td></tr>";
const char HTTP_SNS_PRESSUREATSEALEVEL[] PROGMEM =
"<tr><th>%s " D_PRESSUREATSEALEVEL "</th><td>%s " D_UNIT_PRESSURE "</td></tr>";
const char HTTP_SNS_LIGHT[] PROGMEM =
"<tr><th>%s " D_LIGHT "</th><td>%d%</td></tr>";
const char HTTP_SNS_NOISE[] PROGMEM =
"<tr><th>%s " D_NOISE "</th><td>%d%</td></tr>";
const char HTTP_SNS_DUST[] PROGMEM =
"<tr><th>%s " D_AIR_QUALITY "</th><td>%d%</td></tr>";
const char HTTP_END[] PROGMEM =
"</div>"
"</body>"
"</html>";
const char HTTP_ROW_START[] PROGMEM = "<tr><th>"; // Replaces {s}
const char HTTP_ROW_MIDDLE[] PROGMEM = "</th><td>"; // Replases {m}
const char HTTP_ROW_END[] PROGMEM = "</td></tr>"; // Replaces {e}
const char HTTP_SNS_TEMP[] PROGMEM = "%s{s}%s " D_TEMPERATURE "{m}%s&deg;%c{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_HUM[] PROGMEM = "%s{s}%s " D_HUMIDITY "{m}%s%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_PRESSURE[] PROGMEM = "%s{s}%s " D_PRESSURE "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HTTP_SNS_SEAPRESSURE[] PROGMEM = "%s{s}%s " D_PRESSUREATSEALEVEL "{m}%s " D_UNIT_PRESSURE "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
const char HDR_CTYPE_PLAIN[] PROGMEM = "text/plain";
const char HDR_CTYPE_HTML[] PROGMEM = "text/html";
const char HDR_CTYPE_XML[] PROGMEM = "text/xml";
@ -520,54 +514,13 @@ void HandleAjaxStatusRefresh()
ExecuteCommand(svalue);
}
String tpage = "";
tpage += WebShowCounter();
#ifndef USE_ADC_VCC
if (pin[GPIO_ADC0] < 99) {
snprintf_P(svalue, sizeof(svalue), PSTR("<tr><th>" D_ANALOG_INPUT0 "</th><td>%d</td></tr>"), GetAdc0());
tpage += svalue;
}
#endif
if (hlw_flg) {
tpage += WebShowHlw();
}
if (SONOFF_SC == Settings.module) {
tpage += WebShowSonoffSc();
}
#ifdef USE_DS18B20
if (pin[GPIO_DSB] < 99) {
tpage += WebShowDs18b20();
}
#endif // USE_DS18B20
#ifdef USE_DS18x20
if (pin[GPIO_DSB] < 99) {
tpage += WebShowDs18x20();
}
#endif // USE_DS18x20
#ifdef USE_DHT
if (dht_flg) {
tpage += WebShowDht();
}
#endif // USE_DHT
#ifdef USE_I2C
if (i2c_flg) {
#ifdef USE_SHT
tpage += WebShowSht();
#endif
#ifdef USE_HTU
tpage += WebShowHtu();
#endif
#ifdef USE_BMP
tpage += WebShowBmp();
#endif
#ifdef USE_BH1750
tpage += WebShowBh1750();
#endif
#ifdef USE_VEML6070
tpage += WebShowVeml6070();
#endif
}
#endif // USE_I2C
mqtt_data[0] = '\0';
XsnsCall(FUNC_XSNS_WEB);
String tpage = mqtt_data;
tpage.replace(F("{s}"), FPSTR(HTTP_ROW_START)); // = <tr><th>
tpage.replace(F("{m}"), FPSTR(HTTP_ROW_MIDDLE)); // = </th><td>
tpage.replace(F("{e}"), FPSTR(HTTP_ROW_END)); // = </td></tr>
String page = "";
if (tpage.length() > 0) {
page += FPSTR(HTTP_TABLE100);
@ -978,14 +931,14 @@ void HandleBackupConfiguration()
uint8_t buffer[sizeof(Settings)];
WiFiClient myClient = WebServer->client();
WebServer->setContentLength(4096);
WebServer->setContentLength(sizeof(buffer));
char attachment[100];
snprintf_P(attachment, sizeof(attachment), PSTR("attachment; filename=Config_%s_%s.dmp"),
Settings.friendlyname[0], version);
WebServer->sendHeader(F("Content-Disposition"), attachment);
WebServer->send(200, FPSTR(HDR_CTYPE_STREAM), "");
memcpy(buffer, &Settings, sizeof(Settings));
memcpy(buffer, &Settings, sizeof(buffer));
buffer[0] = CONFIG_FILE_SIGN;
buffer[1] = (!CONFIG_FILE_XOR)?0:1;
if (buffer[1]) {

View File

@ -85,9 +85,10 @@ void CounterInit()
* Presentation
\*********************************************************************************************/
void MqttShowCounter(uint8_t* djson)
boolean MqttShowCounter()
{
char stemp[16];
boolean json_data_available = false;
byte dsxflg = 0;
for (byte i = 0; i < MAX_COUNTERS; i++) {
@ -99,7 +100,7 @@ void MqttShowCounter(uint8_t* djson)
dtostrfd(RtcSettings.pulse_counter[i], 0, stemp);
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_COUNTER "%d\":%s"), mqtt_data, i +1, stemp);
*djson = 1;
json_data_available = true;
#ifdef USE_DOMOTICZ
if (1 == dsxflg) {
DomoticzSensor(DZ_COUNT, RtcSettings.pulse_counter[i]);
@ -108,17 +109,16 @@ void MqttShowCounter(uint8_t* djson)
#endif // USE_DOMOTICZ
}
}
return json_data_available;
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_COUNTER[] PROGMEM =
"<tr><th>" D_COUNTER "%d</th><td>%s%s</td></tr>";
"%s{s}" D_COUNTER "%d{m}%s%s{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
String WebShowCounter()
void WebShowCounter()
{
String page = "";
char stemp[16];
char sensor[80];
for (byte i = 0; i < MAX_COUNTERS; i++) {
if (pin[GPIO_CNTR1 +i] < 99) {
@ -127,11 +127,36 @@ String WebShowCounter()
} else {
dtostrfi(RtcSettings.pulse_counter[i], 0, stemp);
}
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_COUNTER, i+1, stemp, (bitRead(Settings.pulse_counter_type, i)) ? " " D_UNIT_SECOND : "");
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_COUNTER, mqtt_data, i +1, stemp, (bitRead(Settings.pulse_counter_type, i)) ? " " D_UNIT_SECOND : "");
}
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_01
boolean Xsns01(byte function)
{
boolean result = false;
switch (function) {
case FUNC_XSNS_INIT:
CounterInit();
break;
// case FUNC_XSNS_PREP:
// break;
case FUNC_XSNS_JSON:
result = MqttShowCounter();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowCounter();
break;
#endif // USE_WEBSERVER
}
return result;
}

View File

@ -718,15 +718,15 @@ void HlwMqttStatus()
#ifdef USE_WEBSERVER
const char HTTP_ENERGY_SNS[] PROGMEM =
"<tr><th>" D_VOLTAGE "</th><td>%s " D_UNIT_VOLT "</td></tr>"
"<tr><th>" D_CURRENT "</th><td>%s " D_UNIT_AMPERE "</td></tr>"
"<tr><th>" D_POWERUSAGE "</th><td>%s " D_UNIT_WATT "</td></tr>"
"<tr><th>" D_POWER_FACTOR "</th><td>%s</td></tr>"
"<tr><th>" D_ENERGY_TODAY "</th><td>%s " D_UNIT_KILOWATTHOUR "</td></tr>"
"<tr><th>" D_ENERGY_YESTERDAY "</th><td>%s " D_UNIT_KILOWATTHOUR "</td></tr>"
"<tr><th>" D_ENERGY_TOTAL "</th><td>%s " D_UNIT_KILOWATTHOUR "</td></tr>";
"{s}" D_VOLTAGE "{m}%s " D_UNIT_VOLT "{e}"
"{s}" D_CURRENT "{m}%s " D_UNIT_AMPERE "{e}"
"{s}" D_POWERUSAGE "{m}%s " D_UNIT_WATT "{e}"
"{s}" D_POWER_FACTOR "{m}%s{e}"
"{s}" D_ENERGY_TODAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}" D_ENERGY_YESTERDAY "{m}%s " D_UNIT_KILOWATTHOUR "{e}"
"{s}" D_ENERGY_TOTAL "{m}%s " D_UNIT_KILOWATTHOUR "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
String WebShowHlw()
void WebShowHlw()
{
float total_energy;
float daily_energy;
@ -742,7 +742,6 @@ String WebShowHlw()
char scurrent[10];
char spower_factor[10];
char syesterday_energy[10];
char sensor[400];
HlwReadEnergy(0, total_energy, daily_energy, energy, watts, voltage, current, power_factor);
dtostrfi(total_energy, Settings.flag.energy_resolution, stotal_energy);
@ -752,7 +751,36 @@ String WebShowHlw()
dtostrfi(current, 3, scurrent);
dtostrfi(power_factor, 2, spower_factor);
dtostrfi((float)Settings.hlw_kWhyesterday / 100000000, Settings.flag.energy_resolution, syesterday_energy);
snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, svoltage, scurrent, swatts, spower_factor, sdaily_energy, syesterday_energy, stotal_energy);
return String(sensor);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_ENERGY_SNS, svoltage, scurrent, swatts, spower_factor, sdaily_energy, syesterday_energy, stotal_energy);
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_03
boolean Xsns03(byte function)
{
boolean result = false;
if (hlw_flg) {
switch (function) {
case FUNC_XSNS_INIT:
HlwInit();
break;
// case FUNC_XSNS_PREP:
// break;
// case FUNC_XSNS_JSON:
// result = MqttShowHlw();
// break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowHlw();
break;
#endif // USE_WEBSERVER
}
}
return result;
}

View File

@ -105,8 +105,10 @@ void SonoffScSerialInput(char *rcvstat)
* Presentation
\*********************************************************************************************/
void MqttShowSonoffSC(uint8_t* djson)
boolean MqttShowSonoffSC()
{
boolean json_data_available = false;
if (sc_value[0] > 0) {
char stemp1[10];
char stemp2[10];
@ -117,40 +119,62 @@ void MqttShowSonoffSC(uint8_t* djson)
dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"),
mqtt_data, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]);
*djson = 1;
json_data_available = true;
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(stemp1, stemp2);
DomoticzSensor(DZ_ILLUMINANCE, sc_value[2]);
#endif // USE_DOMOTICZ
}
return json_data_available;
}
#ifdef USE_WEBSERVER
String WebShowSonoffSc()
{
String page = "";
const char HTTP_SNS_SCPLUS[] PROGMEM = "%s"
"{s}" D_LIGHT "{m}%d%{e}"
"{s}" D_NOISE "{m}%d%{e}"
"{s}" D_AIR_QUALITY "{m}%d%{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
void WebShowSonoffSc()
{
if (sc_value[0] > 0) {
char stemp[10];
char sensor[80];
char scstype[] = "";
float t = ConvertTemp(sc_value[1]);
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, TempUnit());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "", stemp, TempUnit());
float h = sc_value[0];
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, scstype, stemp);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_LIGHT, scstype, sc_value[2]);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_NOISE, scstype, sc_value[3]);
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_DUST, scstype, sc_value[4]);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, "", stemp);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SCPLUS, mqtt_data, sc_value[2], sc_value[3], sc_value[4]);
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_04
boolean Xsns04(byte function)
{
boolean result = false;
if (SONOFF_SC == Settings.module) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
// case FUNC_XSNS_PREP:
// break;
case FUNC_XSNS_JSON:
result = MqttShowSonoffSC();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowSonoffSc();
break;
#endif // USE_WEBSERVER
}
}
return result;
}

View File

@ -185,38 +185,66 @@ boolean Ds18b20ReadTemperature(float &t)
* Presentation
\*********************************************************************************************/
void MqttShowDs18b20(uint8_t* djson)
boolean MqttShowDs18b20()
{
char stemp1[10];
float t;
boolean json_data_available = false;
if (Ds18b20ReadTemperature(t)) { // Check if read failed
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), mqtt_data, stemp1);
*djson = 1;
json_data_available = true;
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_TEMP, stemp1);
#endif // USE_DOMOTICZ
}
return json_data_available;
}
#ifdef USE_WEBSERVER
String WebShowDs18b20()
void WebShowDs18b20()
{
// Needs TelePeriod to refresh data (Do not do it here as it takes too much time)
String page = "";
float st;
if (Ds18b20ReadTemperature(st)) { // Check if read failed
char stemp[10];
char sensor[80];
dtostrfi(st, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, TempUnit());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "DS18B20", stemp, TempUnit());
}
Ds18b20ReadTempPrep();
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_05
boolean Xsns05(byte function)
{
boolean result = false;
if (pin[GPIO_DSB] < 99) {
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Ds18b20ReadTempPrep();
break;
case FUNC_XSNS_JSON:
result = MqttShowDs18b20();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowDs18b20();
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_DS18B20

View File

@ -163,11 +163,12 @@ void Ds18x20Type(uint8_t sensor)
}
}
void MqttShowDs18x20(uint8_t* djson)
boolean MqttShowDs18x20()
{
char stemp1[10];
char stemp2[10];
float t;
boolean json_data_available = false;
byte dsxflg = 0;
for (byte i = 0; i < Ds18x20Sensors(); i++) {
@ -176,7 +177,7 @@ void MqttShowDs18x20(uint8_t* djson)
dtostrfd(t, Settings.flag.temperature_resolution, stemp2);
if (!dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"DS18x20\":{"), mqtt_data);
*djson = 1;
json_data_available = true;
stemp1[0] = '\0';
}
dsxflg++;
@ -193,15 +194,14 @@ void MqttShowDs18x20(uint8_t* djson)
if (dsxflg) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s}"), mqtt_data);
}
return json_data_available;
}
#ifdef USE_WEBSERVER
String WebShowDs18x20()
void WebShowDs18x20()
{
String page = "";
char stemp[10];
char stemp2[16];
char sensor[80];
float t;
for (byte i = 0; i < Ds18x20Sensors(); i++) {
@ -209,13 +209,44 @@ String WebShowDs18x20()
Ds18x20Type(i);
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(stemp2, sizeof(stemp2), PSTR("%s-%d"), ds18x20_types, i +1);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, TempUnit());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, stemp2, stemp, TempUnit());
}
}
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_05
boolean Xsns05(byte function)
{
boolean result = false;
if (pin[GPIO_DSB] < 99) {
switch (function) {
case FUNC_XSNS_INIT:
Ds18x20Init();
break;
case FUNC_XSNS_PREP:
Ds18x20Search(); // Check for changes in sensors number
Ds18x20Convert(); // Start Conversion, takes up to one second
break;
case FUNC_XSNS_JSON:
result = MqttShowDs18x20();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowDs18x20();
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_DS18x20

View File

@ -222,12 +222,13 @@ void DhtInit()
* Presentation
\*********************************************************************************************/
void MqttShowDht(uint8_t* djson)
boolean MqttShowDht()
{
char stemp1[10];
char stemp2[10];
float t;
float h;
boolean json_data_available = false;
byte dsxflg = 0;
for (byte i = 0; i < dht_sensors; i++) {
@ -235,7 +236,7 @@ void MqttShowDht(uint8_t* djson)
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, Dht[i].stype, stemp1, stemp2);
*djson = 1;
json_data_available = true;
#ifdef USE_DOMOTICZ
if (!dsxflg) {
DomoticzTempHumSensor(stemp1, stemp2);
@ -244,28 +245,56 @@ void MqttShowDht(uint8_t* djson)
#endif // USE_DOMOTICZ
}
}
return json_data_available;
}
#ifdef USE_WEBSERVER
String WebShowDht()
void WebShowDht()
{
String page = "";
char stemp[10];
char sensor[80];
float t;
float h;
for (byte i = 0; i < dht_sensors; i++) {
if (DhtReadTempHum(i, t, h)) {
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, Dht[i].stype, stemp, TempUnit());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, Dht[i].stype, stemp, TempUnit());
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, Dht[i].stype, stemp);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, Dht[i].stype, stemp);
}
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_06
boolean Xsns06(byte function)
{
boolean result = false;
if (dht_flg) {
switch (function) {
case FUNC_XSNS_INIT:
DhtInit();
break;
case FUNC_XSNS_PREP:
DhtReadPrep();
break;
case FUNC_XSNS_JSON:
result = MqttShowDht();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowDht();
break;
#endif // USE_WEBSERVER
}
}
return result;
}
#endif // USE_DHT

View File

@ -184,12 +184,13 @@ boolean ShtDetect()
* Presentation
\*********************************************************************************************/
void MqttShowSht(uint8_t* djson)
boolean MqttShowSht()
{
if (!sht_type) {
return;
return false;
}
boolean json_data_available = false;
float t;
float h;
@ -200,36 +201,60 @@ void MqttShowSht(uint8_t* djson)
dtostrfd(t, Settings.flag.temperature_resolution, stemp);
dtostrfd(h, Settings.flag.humidity_resolution, shum);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, "SHT1X", stemp, shum);
*djson = 1;
json_data_available = true;
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(stemp, shum);
#endif // USE_DOMOTICZ
}
return json_data_available;
}
#ifdef USE_WEBSERVER
String WebShowSht()
void WebShowSht()
{
float t;
float h;
String page = "";
if (sht_type) {
if (ShtReadTempHum(t, h)) {
char stemp[10];
char shum[10];
char sensor[80];
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
dtostrfi(h, Settings.flag.humidity_resolution, shum);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "SHT1X", stemp, TempUnit());
page += sensor;
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, "SHT1X", shum);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, "SHT1X", stemp, TempUnit());
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, "SHT1X", stemp);
}
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_07
boolean Xsns07(byte function)
{
boolean result = false;
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
ShtDetect();
break;
case FUNC_XSNS_JSON:
result = MqttShowSht();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowSht();
break;
#endif // USE_WEBSERVER
}
return result;
}
#endif // USE_SHT
#endif // USE_I2C

View File

@ -255,10 +255,10 @@ uint8_t HtuDetect()
* Presentation
\*********************************************************************************************/
void MqttShowHtu(uint8_t* djson)
boolean MqttShowHtu()
{
if (!htu_type) {
return;
return false;
}
char stemp1[10];
@ -270,33 +270,57 @@ void MqttShowHtu(uint8_t* djson)
dtostrfd(t, Settings.flag.temperature_resolution, stemp1);
dtostrfd(h, Settings.flag.humidity_resolution, stemp2);
snprintf_P(mqtt_data, sizeof(mqtt_data), JSON_SNS_TEMPHUM, mqtt_data, htu_types, stemp1, stemp2);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzTempHumSensor(stemp1, stemp2);
#endif // USE_DOMOTICZ
return true;
}
#ifdef USE_WEBSERVER
String WebShowHtu()
void WebShowHtu()
{
String page = "";
if (htu_type) {
char stemp[10];
char sensor[80];
float t_htu21 = HtuReadTemperature();
float h_htu21 = HtuReadHumidity();
h_htu21 = HtuCompensatedHumidity(h_htu21, t_htu21);
dtostrfi(t_htu21, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htu_types, stemp, TempUnit());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, htu_types, stemp, TempUnit());
dtostrfi(h_htu21, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, htu_types, stemp);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, htu_types, stemp);
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_08
boolean Xsns08(byte function)
{
boolean result = false;
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
HtuDetect();
break;
case FUNC_XSNS_JSON:
result = MqttShowHtu();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowHtu();
break;
#endif // USE_WEBSERVER
}
return result;
}
#endif // USE_HTU
#endif // USE_I2C

View File

@ -411,10 +411,10 @@ boolean BmpDetect()
* Presentation
\*********************************************************************************************/
void MqttShowBmp(uint8_t *djson)
boolean MqttShowBmp()
{
if (!bmp_type) {
return;
return false;
}
char temperature[10];
@ -440,42 +440,64 @@ void MqttShowBmp(uint8_t *djson)
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s%s}"),
mqtt_data, bmp_types, temperature, pressure, (Settings.altitude != 0) ? sealevel : "");
}
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzTempHumPressureSensor(temperature, humidity, pressure);
#endif // USE_DOMOTICZ
return true;
}
#ifdef USE_WEBSERVER
String WebShowBmp()
void WebShowBmp()
{
String page = "";
if (bmp_type) {
char stemp[10];
char sensor[80];
double t = BmpReadTemperature();
double p = BmpReadPressure();
double h = BmpReadHumidity();
dtostrfi(t, Settings.flag.temperature_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmp_types, stemp, TempUnit());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, bmp_types, stemp, TempUnit());
if (BME280_CHIPID == bmp_type) {
dtostrfi(h, Settings.flag.humidity_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, bmp_types, stemp);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, bmp_types, stemp);
}
dtostrfi(p, Settings.flag.pressure_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSURE, bmp_types, stemp);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, bmp_types, stemp);
if (Settings.altitude != 0) {
dtostrfi(bmp_sealevel, Settings.flag.pressure_resolution, stemp);
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSUREATSEALEVEL, bmp_types, stemp);
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, bmp_types, stemp);
}
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_09
boolean Xsns09(byte function)
{
boolean result = false;
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
BmpDetect();
break;
case FUNC_XSNS_JSON:
result = MqttShowBmp();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowBmp();
break;
#endif // USE_WEBSERVER
}
return result;
}
#endif // USE_BMP
#endif // USE_I2C

View File

@ -78,35 +78,59 @@ boolean Bh1750Detect()
* Presentation
\*********************************************************************************************/
void MqttShowBh1750(uint8_t* djson)
boolean MqttShowBh1750()
{
if (!bh1750_type) {
return;
return false;
}
uint16_t l = Bh1750ReadLux();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_ILLUMINANCE "\":%d}"), mqtt_data, bh1750_types, l);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, l);
#endif // USE_DOMOTICZ
return true;
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_ILLUMINANCE[] PROGMEM =
"<tr><th>BH1750 " D_ILLUMINANCE "</th><td>%d " D_UNIT_LUX "</td></tr>";
"%s{s}BH1750 " D_ILLUMINANCE "{m}%d " D_UNIT_LUX "{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
String WebShowBh1750()
void WebShowBh1750()
{
String page = "";
if (bh1750_type) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_ILLUMINANCE, Bh1750ReadLux());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ILLUMINANCE, mqtt_data, Bh1750ReadLux());
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_10
boolean Xsns10(byte function)
{
boolean result = false;
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Bh1750Detect();
break;
case FUNC_XSNS_JSON:
result = MqttShowBh1750();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowBh1750();
break;
#endif // USE_WEBSERVER
}
return result;
}
#endif // USE_BH1750
#endif // USE_I2C

View File

@ -44,7 +44,7 @@ uint16_t Veml6070ReadUv()
}
uvi |= Wire.read();
return uvi;
return uvi;
}
boolean Veml6070Detect()
@ -79,35 +79,60 @@ boolean Veml6070Detect()
* Presentation
\*********************************************************************************************/
void MqttShowVeml6070(uint8_t* djson)
boolean MqttShowVeml6070()
{
if (!veml6070_type) {
return;
return false;
}
uint16_t uv = Veml6070ReadUv();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s, \"%s\":{\"" D_UV_LEVEL "\":%d}"), mqtt_data, veml6070_types, uv);
*djson = 1;
#ifdef USE_DOMOTICZ
DomoticzSensor(DZ_ILLUMINANCE, uv);
#endif // USE_DOMOTICZ
return true;
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_ULTRAVIOLET[] PROGMEM =
"<tr><th>VEML6070 " D_UV_LEVEL "</th><td>%d</td></tr>";
String WebShowVeml6070()
"%s{s}VEML6070 " D_UV_LEVEL "{m}%d{e}"; // {s} = <tr><th>, {m} = </th><td>, {e} = </td></tr>
void WebShowVeml6070()
{
String page = "";
if (veml6070_type) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_ULTRAVIOLET, Veml6070ReadUv());
page += sensor;
snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_ULTRAVIOLET, mqtt_data, Veml6070ReadUv());
}
return page;
}
#endif // USE_WEBSERVER
/*********************************************************************************************\
* Interface
\*********************************************************************************************/
#define XSNS_11
boolean Xsns11(byte function)
{
boolean result = false;
switch (function) {
// case FUNC_XSNS_INIT:
// break;
case FUNC_XSNS_PREP:
Veml6070Detect();
break;
case FUNC_XSNS_JSON:
result = MqttShowVeml6070();
break;
#ifdef USE_WEBSERVER
case FUNC_XSNS_WEB:
WebShowVeml6070();
break;
#endif // USE_WEBSERVER
}
return result;
}
#endif // USE_VEML6070
#endif // USE_I2C

141
sonoff/xsns_interface.ino Normal file
View File

@ -0,0 +1,141 @@
/*
xsns_interface.ino - External sensor interface support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends inspired by ESPEasy
This program is free software: you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation, either version 3 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
void XSnsInit()
{
byte x;
for (x = 0; x < XSNS_MAX; x++) {
xsns_func_ptr[x] = NULL;
}
x = 0;
#ifdef XSNS_01
xsns_func_ptr[x++] = &Xsns01;
#endif
#ifdef XSNS_02
xsns_func_ptr[x++] = &Xsns02;
#endif
#ifdef XSNS_03
xsns_func_ptr[x++] = &Xsns03;
#endif
#ifdef XSNS_04
xsns_func_ptr[x++] = &Xsns04;
#endif
#ifdef XSNS_05
xsns_func_ptr[x++] = &Xsns05;
#endif
#ifdef XSNS_06
xsns_func_ptr[x++] = &Xsns06;
#endif
#ifdef XSNS_07
xsns_func_ptr[x++] = &Xsns07;
#endif
#ifdef XSNS_08
xsns_func_ptr[x++] = &Xsns08;
#endif
#ifdef XSNS_09
xsns_func_ptr[x++] = &Xsns09;
#endif
#ifdef XSNS_10
xsns_func_ptr[x++] = &Xsns10;
#endif
#ifdef XSNS_11
xsns_func_ptr[x++] = &Xsns11;
#endif
#ifdef XSNS_12
xsns_func_ptr[x++] = &Xsns12;
#endif
#ifdef XSNS_13
xsns_func_ptr[x++] = &Xsns13;
#endif
#ifdef XSNS_14
xsns_func_ptr[x++] = &Xsns14;
#endif
#ifdef XSNS_15
xsns_func_ptr[x++] = &Xsns15;
#endif
#ifdef XSNS_16
xsns_func_ptr[x++] = &Xsns16;
#endif
#ifdef XSNS_17
xsns_func_ptr[x++] = &Xsns17;
#endif
#ifdef XSNS_18
xsns_func_ptr[x++] = &Xsns18;
#endif
#ifdef XSNS_19
xsns_func_ptr[x++] = &Xsns19;
#endif
#ifdef XSNS_20
xsns_func_ptr[x++] = &Xsns20;
#endif
XsnsCall(FUNC_XSNS_INIT);
}
/*********************************************************************************************\
* Function call to all or specific xsns
\*********************************************************************************************/
boolean XsnsCall(byte Function)
{
boolean result = false;
switch (Function) {
case FUNC_XSNS_INIT:
case FUNC_XSNS_PREP:
case FUNC_XSNS_WEB:
for (byte x = 0; x < XSNS_MAX; x++) {
if (xsns_func_ptr[x]) {
xsns_func_ptr[x](Function);
}
}
break;
case FUNC_XSNS_JSON:
for (byte x = 0; x < XSNS_MAX; x++) {
if (xsns_func_ptr[x]) {
if (xsns_func_ptr[x](Function)) {
result = true;
}
}
}
break;
}
return result;
}