v5.8.0o - Add VEML6070 and more light schemes

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)
This commit is contained in:
arendst 2017-10-25 14:27:30 +02:00
parent e7c0bb01b9
commit cf350dc584
17 changed files with 472 additions and 262 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.0n** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
Current version is **5.8.0o** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
### ATTENTION All versions

View File

@ -1,8 +1,14 @@
/* 5.8.0n
/* 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)

View File

@ -188,8 +188,9 @@
#define D_UPGRADE "upgrade"
#define D_UPLOAD "upload"
#define D_UPTIME "Laufzeit"
#define D_UTC_TIME "UTC"
#define D_USER "Benutzer"
#define D_UTC_TIME "UTC"
#define D_UV_LEVEL "UV Level"
#define D_VCC "VCC"
#define D_VERSION "Version"
#define D_VOLTAGE "Spannung"
@ -373,7 +374,6 @@
#define D_DOMOTICZ_KEY_IDX "Key idx"
#define D_DOMOTICZ_SWITCH_IDX "Switch idx"
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
#define DOMOTICZ_SENSORS_MAX_STRING_LENGTH 14
#define D_DOMOTICZ_TEMP "Temp"
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum"
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro"

View File

@ -188,8 +188,9 @@
#define D_UPGRADE "upgrade"
#define D_UPLOAD "Upload"
#define D_UPTIME "Uptime"
#define D_UTC_TIME "UTC"
#define D_USER "User"
#define D_UTC_TIME "UTC"
#define D_UV_LEVEL "UV Level"
#define D_VCC "Vcc"
#define D_VERSION "Version"
#define D_VOLTAGE "Voltage"
@ -373,7 +374,6 @@
#define D_DOMOTICZ_KEY_IDX "Key idx"
#define D_DOMOTICZ_SWITCH_IDX "Switch idx"
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
#define DOMOTICZ_SENSORS_MAX_STRING_LENGTH 14
#define D_DOMOTICZ_TEMP "Temp"
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum"
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro"

View File

@ -188,8 +188,9 @@
#define D_UPGRADE "opwaarderen"
#define D_UPLOAD "Verzenden"
#define D_UPTIME "Bedrijfstijd"
#define D_UTC_TIME "UTC"
#define D_USER "Gebruiker"
#define D_UTC_TIME "UTC"
#define D_UV_LEVEL "UV niveau"
#define D_VCC "Vcc"
#define D_VERSION "Versie"
#define D_VOLTAGE "Spanning"
@ -373,7 +374,6 @@
#define D_DOMOTICZ_KEY_IDX "Toets idx"
#define D_DOMOTICZ_SWITCH_IDX "Schakelaar idx"
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
#define DOMOTICZ_SENSORS_MAX_STRING_LENGTH 14
#define D_DOMOTICZ_TEMP "Temp"
#define D_DOMOTICZ_TEMP_HUM "Temp,Hum"
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Hum,Baro"

View File

@ -188,8 +188,9 @@
#define D_UPGRADE "Aktualizacji"
#define D_UPLOAD "Wgraj"
#define D_UPTIME "Uptime"
#define D_UTC_TIME "UTC"
#define D_USER "Uzytkownik"
#define D_UTC_TIME "UTC"
#define D_UV_LEVEL "UV Level"
#define D_VCC "VCC"
#define D_VERSION "Wersja"
#define D_VOLTAGE "Napiecie"
@ -373,7 +374,6 @@
#define D_DOMOTICZ_KEY_IDX "Key idx"
#define D_DOMOTICZ_SWITCH_IDX "Przelacznik idx"
#define D_DOMOTICZ_SENSOR_IDX "Sensor idx"
#define DOMOTICZ_SENSORS_MAX_STRING_LENGTH 14
#define D_DOMOTICZ_TEMP "Temp"
#define D_DOMOTICZ_TEMP_HUM "Temp,Wilg"
#define D_DOMOTICZ_TEMP_HUM_BARO "Temp,Wilg,Cis"

View File

@ -107,5 +107,8 @@ enum ButtonStates {PRESSED, NOT_PRESSED};
enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8};
enum Ws2812ClockIndex {WS_SECOND, WS_MINUTE, WS_HOUR};
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};
#endif // _SONOFF_H_

View File

@ -25,7 +25,7 @@
- Select IDE Tools - Flash Size: "1M (no SPIFFS)"
====================================================*/
#define VERSION 0x0508000E // 5.8.0n
#define VERSION 0x0508000F // 5.8.0o
// Location specific includes
#include "sonoff.h" // Enumaration used in user_config.h
@ -1792,7 +1792,10 @@ void MqttShowSensor(uint8_t* djson)
#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());
@ -1878,7 +1881,10 @@ void PerformEverySecond()
#ifdef USE_BH1750
Bh1750Detect();
#endif // USE_BH1750
}
#ifdef USE_VEML6070
Veml6070Detect();
#endif // USE_VEML6070
}
#endif // USE_I2C
}
if (tele_period >= Settings.tele_period) {
@ -2532,7 +2538,7 @@ void GpioInit()
devices_present = 1;
if (Settings.flag.pwm_control) {
light_type = 0;
light_type = LT_BASIC;
for (byte i = 0; i < MAX_PWMS; i++) {
if (pin[GPIO_PWM1 +i] < 99) {
light_type++; // Use Dimmer/Color control for all PWM as SetOption15 = 1
@ -2556,20 +2562,20 @@ void GpioInit()
}
else if ((H801 == Settings.module) || (MAGICHOME == Settings.module)) { // PWM RGBCW led
if (!Settings.flag.pwm_control) {
light_type = 0; // Use basic PWM control if SetOption15 = 0
light_type = LT_BASIC; // Use basic PWM control if SetOption15 = 0
}
}
else if (SONOFF_BN == Settings.module) { // PWM Single color led (White)
light_type = 1;
light_type = LT_PWM1;
}
else if (SONOFF_LED == Settings.module) { // PWM Dual color led (White warm and cold)
light_type = 2;
light_type = LT_PWM2;
}
else if (AILIGHT == Settings.module) { // RGBW led
light_type = 12;
light_type = LT_RGBW;
}
else if (SONOFF_B1 == Settings.module) { // RGBWC led
light_type = 13;
light_type = LT_RGBWC;
}
else {
if (!light_type) {
@ -2603,7 +2609,7 @@ void GpioInit()
#ifdef USE_WS2812
if (!light_type && (pin[GPIO_WS2812] < 99)) { // RGB led
devices_present++;
light_type = 11;
light_type = LT_WS2812;
}
#endif // USE_WS2812
if (light_type) { // Any Led light under Dimmer/Color control

View File

@ -795,6 +795,17 @@ void I2cScan(char *devs, unsigned int devs_len)
snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_NO_DEVICES_FOUND "\"}"));
}
}
boolean I2cDevice(byte addr)
{
for (byte address = 1; address <= 127; address++) {
Wire.beginTransmission(address);
if (!Wire.endTransmission() && (address == addr)) {
return true;
}
}
return false;
}
#endif // USE_I2C
/*********************************************************************************************\
@ -1159,6 +1170,16 @@ double FastPrecisePow(double a, double b)
return r * u.d;
}
char* GetIndexedString(char* destination, const char* source, uint8_t index)
{
strcpy_P(destination, source); // Copies Flash to Ram until end of string
char *indexed_string = strtok(destination, "|");
while (index--) {
indexed_string = strtok(NULL, "|");
}
return indexed_string;
}
/*********************************************************************************************\
* Syslog
\*********************************************************************************************/

View File

@ -44,7 +44,7 @@
// -- Wifi ----------------------------------------
#define WIFI_IP_ADDRESS "0.0.0.0" // [IpAddress1] Set to 0.0.0.0 for using DHCP or IP address
#define WIFI_GATEWAY "192.168.2.254" // {IpAddress2] If not using DHCP set Gateway IP address
#define WIFI_GATEWAY "192.168.2.254" // [IpAddress2] If not using DHCP set Gateway IP address
#define WIFI_SUBNETMASK "255.255.255.0" // [IpAddress3] If not using DHCP set Network mask
#define WIFI_DNS "192.168.2.27" // [IpAddress4] If not using DHCP set DNS IP address (might be equal to WIFI_GATEWAY)
@ -167,6 +167,7 @@
#define USE_I2C // I2C using library wire (+10k code, 0.2k mem) - Disable by //
#define USE_BH1750 // Add I2C code for BH1750 sensor
// #define USE_VEML6070 // Add I2C code for VEML6070 sensor (+0.5k code)
#define USE_BMP // Add I2C code for BMP/BME280 sensor
#define USE_HTU // Add I2C code for HTU21/SI7013/SI7020/SI7021 sensor
#define USE_SHT // Add I2C emulating code for SHT1X sensor

View File

@ -94,7 +94,7 @@ const char HTTP_HEAD[] PROGMEM =
#ifdef BE_MINIMAL
"<div style='text-align:center;color:red;'><h3>" D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "</h3></div>"
#endif
"<div style='text-align:center;'><h3>{ha} " D_MODULE "</h3><h2>{h}</h2></div>";
"<div style='text-align:center;'><h3>{ha " D_MODULE "</h3><h2>{h}</h2></div>";
const char HTTP_SCRIPT_CONSOL[] PROGMEM =
"var sn=0;" // Scroll position
"var id=99;" // Get most of weblog initially
@ -193,7 +193,7 @@ const char HTTP_BTN_CONF[] PROGMEM =
const char HTTP_FORM_MODULE[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_MODULE_PARAMETERS "&nbsp;</b></legend><form method='get' action='sv'>"
"<input id='w' name='w' value='6' hidden><input id='r' name='r' value='1' hidden>"
"<br/><b>" D_MODULE_TYPE "</b> ({mt})<br/><select id='g99' name='g99'></select><br/>";
"<br/><b>" D_MODULE_TYPE "</b> ({mt)<br/><select id='g99' name='g99'></select><br/>";
const char HTTP_LNK_ITEM[] PROGMEM =
"<div><a href='#p' onclick='c(this)'>{v}</a>&nbsp;<span class='q'>{i} {r}%</span></div>";
const char HTTP_LNK_SCAN[] PROGMEM =
@ -201,26 +201,26 @@ const char HTTP_LNK_SCAN[] PROGMEM =
const char HTTP_FORM_WIFI[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_WIFI_PARAMETERS "&nbsp;</b></legend><form method='get' action='sv'>"
"<input id='w' name='w' value='1' hidden><input id='r' name='r' value='1' hidden>"
"<br/><b>" D_AP1_SSID "</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' placeholder='" STA_SSID1 "' value='{s1}'><br/>"
"<br/><b>" D_AP1_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" STA_PASS1 "' value='{p1}'><br/>"
"<br/><b>" D_AP2_SSID "</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' placeholder='" STA_SSID2 "' value='{s2}'><br/>"
"<br/><b>" D_AP2_PASSWORD "</b><br/><input id='p2' name='p2' type='password' placeholder='" STA_PASS2 "' value='{p2}'><br/>"
"<br/><b>" D_HOSTNAME "</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' placeholder='" WIFI_HOSTNAME" ' value='{h1}'><br/>";
"<br/><b>" D_AP1_SSID "</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' placeholder='" STA_SSID1 "' value='{s1'><br/>"
"<br/><b>" D_AP1_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" STA_PASS1 "' value='{p1'><br/>"
"<br/><b>" D_AP2_SSID "</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' placeholder='" STA_SSID2 "' value='{s2'><br/>"
"<br/><b>" D_AP2_PASSWORD "</b><br/><input id='p2' name='p2' type='password' placeholder='" STA_PASS2 "' value='{p2'><br/>"
"<br/><b>" D_HOSTNAME "</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' placeholder='" WIFI_HOSTNAME" ' value='{h1'><br/>";
const char HTTP_FORM_MQTT[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_MQTT_PARAMETERS "&nbsp;</b></legend><form method='get' action='sv'>"
"<input id='w' name='w' value='2' hidden><input id='r' name='r' value='1' hidden>"
"<br/><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' placeholder='" MQTT_HOST" ' value='{m1}'><br/>"
"<br/><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' placeholder='" STR(MQTT_PORT) "' value='{m2}'><br/>"
"<br/><b>" D_CLIENT "</b> ({m0})<br/><input id='mc' name='mc' placeholder='" MQTT_CLIENT_ID "' value='{m3}'><br/>"
"<br/><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='{m4}'><br/>"
"<br/><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" MQTT_PASS "' value='{m5}'><br/>"
"<br/><b>" D_TOPIC "</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC" ' value='{m6}'><br/>"
"<br/><b>" D_FULL_TOPIC "</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' placeholder='" MQTT_FULLTOPIC" ' value='{m7}'><br/>";
"<br/><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' placeholder='" MQTT_HOST" ' value='{m1'><br/>"
"<br/><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' placeholder='" STR(MQTT_PORT) "' value='{m2'><br/>"
"<br/><b>" D_CLIENT "</b> ({m0)<br/><input id='mc' name='mc' placeholder='" MQTT_CLIENT_ID "' value='{m3'><br/>"
"<br/><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' placeholder='" MQTT_USER "' value='{m4'><br/>"
"<br/><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' type='password' placeholder='" MQTT_PASS "' value='{m5'><br/>"
"<br/><b>" D_TOPIC "</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' placeholder='" MQTT_TOPIC" ' value='{m6'><br/>"
"<br/><b>" D_FULL_TOPIC "</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' placeholder='" MQTT_FULLTOPIC" ' value='{m7'><br/>";
const char HTTP_FORM_LOG1[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_LOGGING_PARAMETERS "&nbsp;</b></legend><form method='get' action='sv'>"
"<input id='w' name='w' value='3' hidden><input id='r' name='r' value='0' hidden>";
const char HTTP_FORM_LOG2[] PROGMEM =
"<br/><b>{b0}" D_LOG_LEVEL "</b> ({b1})<br/><select id='{b2}' name='{b2}'>"
"<br/><b>{b0" D_LOG_LEVEL "</b> ({b1)<br/><select id='{b2' name='{b2'>"
"<option{a0value='0'>0 " D_NONE "</option>"
"<option{a1value='1'>1 " D_ERROR "</option>"
"<option{a2value='2'>2 " D_INFO "</option>"
@ -228,14 +228,14 @@ const char HTTP_FORM_LOG2[] PROGMEM =
"<option{a4value='4'>4 " D_MORE_DEBUG "</option>"
"</select><br/>";
const char HTTP_FORM_LOG3[] PROGMEM =
"<br/><b>" D_SYSLOG_HOST "</b> (" SYS_LOG_HOST ")<br/><input id='lh' name='lh' placeholder='" SYS_LOG_HOST "' value='{l2}'><br/>"
"<br/><b>" D_SYSLOG_PORT "</b> (" STR(SYS_LOG_PORT) ")<br/><input id='lp' name='lp' placeholder='" STR(SYS_LOG_PORT) "' value='{l3}'><br/>"
"<br/><b>" D_TELEMETRY_PERIOD "</b> (" STR(TELE_PERIOD) ")<br/><input id='lt' name='lt' placeholder='" STR(TELE_PERIOD) "' value='{l4}'><br/>";
"<br/><b>" D_SYSLOG_HOST "</b> (" SYS_LOG_HOST ")<br/><input id='lh' name='lh' placeholder='" SYS_LOG_HOST "' value='{l2'><br/>"
"<br/><b>" D_SYSLOG_PORT "</b> (" STR(SYS_LOG_PORT) ")<br/><input id='lp' name='lp' placeholder='" STR(SYS_LOG_PORT) "' value='{l3'><br/>"
"<br/><b>" D_TELEMETRY_PERIOD "</b> (" STR(TELE_PERIOD) ")<br/><input id='lt' name='lt' placeholder='" STR(TELE_PERIOD) "' value='{l4'><br/>";
const char HTTP_FORM_OTHER[] PROGMEM =
"<fieldset><legend><b>&nbsp;" D_OTHER_PARAMETERS "&nbsp;</b></legend><form method='get' action='sv'>"
"<input id='w' name='w' value='5' hidden><input id='r' name='r' value='1' hidden>"
"<br/><b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" WEB_PASSWORD "' value='{p1}'><br/>"
"<br/><input style='width:10%;' id='b1' name='b1' type='checkbox'{r1}><b>" D_MQTT_ENABLE "</b><br/>";
"<br/><b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' type='password' placeholder='" WEB_PASSWORD "' value='{p1'><br/>"
"<br/><input style='width:10%;' id='b1' name='b1' type='checkbox'{r1><b>" D_MQTT_ENABLE "</b><br/>";
const char HTTP_FORM_OTHER2[] PROGMEM =
"<br/><b>" D_FRIENDLY_NAME " {1</b> ({2)<br/><input id='a{1' name='a{1' placeholder='{2' value='{3'><br/>";
#ifdef USE_EMULATION
@ -253,14 +253,14 @@ const char HTTP_FORM_UPG[] PROGMEM =
"<div id='f1' name='f1' style='display:block;'>"
"<fieldset><legend><b>&nbsp;" D_UPGRADE_BY_WEBSERVER "&nbsp;</b></legend>"
"<form method='get' action='u1'>"
"<br/>" D_OTA_URL "<br/><input id='o' name='o' placeholder='OTA_URL' value='{o1}'><br/>"
"<br/>" D_OTA_URL "<br/><input id='o' name='o' placeholder='OTA_URL' value='{o1'><br/>"
"<br/><button type='submit'>" D_START_UPGRADE "</button></form>"
"</fieldset><br/><br/>"
"<fieldset><legend><b>&nbsp;" D_UPGRADE_BY_FILE_UPLOAD "&nbsp;</b></legend>";
const char HTTP_FORM_RST_UPG[] PROGMEM =
"<form method='post' action='u2' enctype='multipart/form-data'>"
"<br/><input type='file' name='u2'><br/>"
"<br/><button type='submit' onclick='document.getElementById(\"f1\").style.display=\"none\";document.getElementById(\"f2\").style.display=\"block\";this.form.submit();'>" D_START " {r1}</button></form>"
"<br/><button type='submit' onclick='document.getElementById(\"f1\").style.display=\"none\";document.getElementById(\"f2\").style.display=\"block\";this.form.submit();'>" D_START " {r1</button></form>"
"</fieldset>"
"</div>"
"<div id='f2' name='f2' style='display:none;text-align:center;'><b>" D_UPLOAD_STARTED " ...</b></div>";
@ -423,7 +423,7 @@ void ShowPage(String &page)
if((HTTP_ADMIN == webserver_state) && (Settings.web_password[0] != 0) && !WebServer->authenticate(WEB_USERNAME, Settings.web_password)) {
return WebServer->requestAuthentication();
}
page.replace(F("{ha}"), my_module.name);
page.replace(F("{ha"), my_module.name);
page.replace(F("{h}"), Settings.friendlyname[0]);
if (HTTP_MANAGER == webserver_state) {
if (WifiConfigCounter()) {
@ -457,7 +457,7 @@ void HandleRoot()
page += F("<div id='l1' name='l1'></div>");
if (devices_present) {
if (light_type) {
if ((2 == (light_type &7)) || (5 == (light_type &7))) {
if ((LST_COLDWARM == (light_type &7)) || (LST_RGBWC == (light_type &7))) {
snprintf_P(line, sizeof(line), HTTP_MSG_SLIDER1, LightGetColorTemp());
page += line;
}
@ -563,7 +563,10 @@ void HandleAjaxStatusRefresh()
#ifdef USE_BH1750
tpage += WebShowBh1750();
#endif
}
#ifdef USE_VEML6070
tpage += WebShowVeml6070();
#endif
}
#endif // USE_I2C
String page = "";
if (tpage.length() > 0) {
@ -693,7 +696,7 @@ void HandleModuleConfiguration()
page.replace(F("{v}"), FPSTR(S_CONFIGURE_MODULE));
page += FPSTR(HTTP_FORM_MODULE);
snprintf_P(stemp, sizeof(stemp), kModules[MODULE].name);
page.replace(F("{mt}"), stemp);
page.replace(F("{mt"), stemp);
mytmplt cmodule;
memcpy_P(&cmodule, &kModules[Settings.module], sizeof(cmodule));
@ -836,11 +839,11 @@ void HandleWifi(boolean scan)
}
page += FPSTR(HTTP_FORM_WIFI);
page.replace(F("{h1}"), Settings.hostname);
page.replace(F("{s1}"), Settings.sta_ssid[0]);
page.replace(F("{p1}"), Settings.sta_pwd[0]);
page.replace(F("{s2}"), Settings.sta_ssid[1]);
page.replace(F("{p2}"), Settings.sta_pwd[1]);
page.replace(F("{h1"), Settings.hostname);
page.replace(F("{s1"), Settings.sta_ssid[0]);
page.replace(F("{p1"), Settings.sta_pwd[0]);
page.replace(F("{s2"), Settings.sta_ssid[1]);
page.replace(F("{p2"), Settings.sta_pwd[1]);
page += FPSTR(HTTP_FORM_END);
if (HTTP_MANAGER == webserver_state) {
page += FPSTR(HTTP_BTN_RSTRT);
@ -862,14 +865,14 @@ void HandleMqttConfiguration()
page += FPSTR(HTTP_FORM_MQTT);
char str[sizeof(Settings.mqtt_client)];
GetMqttClient(str, MQTT_CLIENT_ID, sizeof(Settings.mqtt_client));
page.replace(F("{m0}"), str);
page.replace(F("{m1}"), Settings.mqtt_host);
page.replace(F("{m2}"), String(Settings.mqtt_port));
page.replace(F("{m3}"), Settings.mqtt_client);
page.replace(F("{m4}"), (Settings.mqtt_user[0] == '\0')?"0":Settings.mqtt_user);
page.replace(F("{m5}"), (Settings.mqtt_pwd[0] == '\0')?"0":Settings.mqtt_pwd);
page.replace(F("{m6}"), Settings.mqtt_topic);
page.replace(F("{m7}"), Settings.mqtt_fulltopic);
page.replace(F("{m0"), str);
page.replace(F("{m1"), Settings.mqtt_host);
page.replace(F("{m2"), String(Settings.mqtt_port));
page.replace(F("{m3"), Settings.mqtt_client);
page.replace(F("{m4"), (Settings.mqtt_user[0] == '\0')?"0":Settings.mqtt_user);
page.replace(F("{m5"), (Settings.mqtt_pwd[0] == '\0')?"0":Settings.mqtt_pwd);
page.replace(F("{m6"), Settings.mqtt_topic);
page.replace(F("{m7"), Settings.mqtt_fulltopic);
page += FPSTR(HTTP_FORM_END);
page += FPSTR(HTTP_BTN_CONF);
ShowPage(page);
@ -889,25 +892,25 @@ void HandleLoggingConfiguration()
page += FPSTR(HTTP_FORM_LOG2);
switch (idx) {
case 0:
page.replace(F("{b0}"), F(D_SERIAL " "));
page.replace(F("{b1}"), STR(SERIAL_LOG_LEVEL));
page.replace(F("{b2}"), F("ls"));
page.replace(F("{b0"), F(D_SERIAL " "));
page.replace(F("{b1"), STR(SERIAL_LOG_LEVEL));
page.replace(F("{b2"), F("ls"));
for (byte i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) {
page.replace("{a" + String(i), (i == Settings.seriallog_level) ? F(" selected ") : F(" "));
}
break;
case 1:
page.replace(F("{b0}"), F(D_WEB " "));
page.replace(F("{b1}"), STR(WEB_LOG_LEVEL));
page.replace(F("{b2}"), F("lw"));
page.replace(F("{b0"), F(D_WEB " "));
page.replace(F("{b1"), STR(WEB_LOG_LEVEL));
page.replace(F("{b2"), F("lw"));
for (byte i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) {
page.replace("{a" + String(i), (i == Settings.weblog_level) ? F(" selected ") : F(" "));
}
break;
case 2:
page.replace(F("{b0}"), F(D_SYS));
page.replace(F("{b1}"), STR(SYS_LOG_LEVEL));
page.replace(F("{b2}"), F("ll"));
page.replace(F("{b0"), F(D_SYS));
page.replace(F("{b1"), STR(SYS_LOG_LEVEL));
page.replace(F("{b2"), F("ll"));
for (byte i = LOG_LEVEL_NONE; i < LOG_LEVEL_ALL; i++) {
page.replace("{a" + String(i), (i == Settings.syslog_level) ? F(" selected ") : F(" "));
}
@ -915,9 +918,9 @@ void HandleLoggingConfiguration()
}
}
page += FPSTR(HTTP_FORM_LOG3);
page.replace(F("{l2}"), Settings.syslog_host);
page.replace(F("{l3}"), String(Settings.syslog_port));
page.replace(F("{l4}"), String(Settings.tele_period));
page.replace(F("{l2"), Settings.syslog_host);
page.replace(F("{l3"), String(Settings.syslog_port));
page.replace(F("{l4"), String(Settings.tele_period));
page += FPSTR(HTTP_FORM_END);
page += FPSTR(HTTP_BTN_CONF);
ShowPage(page);
@ -934,8 +937,8 @@ void HandleOtherConfiguration()
String page = FPSTR(HTTP_HEAD);
page.replace(F("{v}"), FPSTR(S_CONFIGURE_OTHER));
page += FPSTR(HTTP_FORM_OTHER);
page.replace(F("{p1}"), Settings.web_password);
page.replace(F("{r1}"), (Settings.flag.mqtt_enabled) ? F(" checked") : F(""));
page.replace(F("{p1"), Settings.web_password);
page.replace(F("{r1"), (Settings.flag.mqtt_enabled) ? F(" checked") : F(""));
page += FPSTR(HTTP_FORM_OTHER2);
page.replace(F("{1"), F("1"));
page.replace(F("{2"), FRIENDLY_NAME);
@ -1157,7 +1160,7 @@ void HandleRestoreConfiguration()
page.replace(F("{v}"), FPSTR(S_RESTORE_CONFIGURATION));
page += FPSTR(HTTP_FORM_RST);
page += FPSTR(HTTP_FORM_RST_UPG);
page.replace(F("{r1}"), F(D_RESTORE));
page.replace(F("{r1"), F(D_RESTORE));
page += FPSTR(HTTP_BTN_CONF);
ShowPage(page);
@ -1175,9 +1178,9 @@ void HandleUpgradeFirmware()
String page = FPSTR(HTTP_HEAD);
page.replace(F("{v}"), FPSTR(S_FIRMWARE_UPGRADE));
page += FPSTR(HTTP_FORM_UPG);
page.replace(F("{o1}"), Settings.ota_url);
page.replace(F("{o1"), Settings.ota_url);
page += FPSTR(HTTP_FORM_RST_UPG);
page.replace(F("{r1}"), F(D_UPGRADE));
page.replace(F("{r1"), F(D_UPGRADE));
page += FPSTR(HTTP_BTN_MAIN);
ShowPage(page);

View File

@ -35,26 +35,10 @@ const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM =
"<tr><td width='260'><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td width='70'><input id='ut' name='ut' placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
#endif // USE_WEBSERVER
enum DomoticzSensors {
DZ_TEMP,
DZ_TEMP_HUM,
DZ_TEMP_HUM_BARO,
DZ_POWER_ENERGY,
DZ_ILLUMINANCE,
DZ_COUNT,
DZ_VOLTAGE,
DZ_CURRENT,
DZ_MAX_SENSORS };
enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_MAX_SENSORS};
const char kDomoticzSensors[DZ_MAX_SENSORS][DOMOTICZ_SENSORS_MAX_STRING_LENGTH] PROGMEM = {
D_DOMOTICZ_TEMP,
D_DOMOTICZ_TEMP_HUM,
D_DOMOTICZ_TEMP_HUM_BARO,
D_DOMOTICZ_POWER_ENERGY,
D_DOMOTICZ_ILLUMINANCE,
D_DOMOTICZ_COUNT,
D_DOMOTICZ_VOLTAGE,
D_DOMOTICZ_CURRENT };
const char kDomoticzSensors[] PROGMEM =
D_DOMOTICZ_TEMP "|" D_DOMOTICZ_TEMP_HUM "|" D_DOMOTICZ_TEMP_HUM_BARO "|" D_DOMOTICZ_POWER_ENERGY "|" D_DOMOTICZ_ILLUMINANCE "|" D_DOMOTICZ_COUNT "|" D_DOMOTICZ_VOLTAGE "|" D_DOMOTICZ_CURRENT ;
char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC;
char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC;
@ -325,7 +309,8 @@ void HandleDomoticzConfiguration()
}
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ);
char stemp[20];
char stemp[sizeof(kDomoticzSensors)];
char *sensortype;
String page = FPSTR(HTTP_HEAD);
page.replace(F("{v}"), FPSTR(S_CONFIGURE_DOMOTICZ));
@ -345,8 +330,7 @@ void HandleDomoticzConfiguration()
for (int i = 0; i < DZ_MAX_SENSORS; i++) {
page += FPSTR(HTTP_FORM_DOMOTICZ_SENSOR);
page.replace("{1", String(i +1));
snprintf_P(stemp, sizeof(stemp), kDomoticzSensors[i]);
page.replace("{2", stemp);
page.replace("{2", GetIndexedString(stemp, kDomoticzSensors, i));
page.replace("{5", String((int)Settings.domoticz_sensor_idx[i]));
}
page += FPSTR(HTTP_FORM_DOMOTICZ_TIMER);

View File

@ -66,6 +66,10 @@ void IrSendInit(void)
#define IR_TIME_AVOID_DUPLICATE 500 // Milliseconds
// Based on IRremoteESP8266.h enum decode_type_t
const char kIrReceiveProtocols[] PROGMEM =
"UNKNOWN|RC5|RC6|NEC|SONY|PANASONIC|JVC|SAMSUNG|WHYNTER|AIWA_RC_T501|LG|SANYO|MITSUBISHI|DISH|SHARP";
IRrecv *irrecv = NULL;
unsigned long ir_lasttime = 0;
@ -79,10 +83,8 @@ void IrReceiveInit(void)
void IrReceiveCheck()
{
char sirtype[100];
char *protocol;
char sirtype[sizeof(kIrReceiveProtocols)];
int8_t iridx = 0;
uint8_t diridx = 0;
decode_results results;
@ -100,21 +102,12 @@ void IrReceiveCheck()
if ((iridx < 0) || (iridx > 14)) {
iridx = 0;
}
diridx = iridx;
// Based on IRremoteESP8266.h enum decode_type_t
snprintf_P(sirtype, sizeof(sirtype), PSTR("UNKNOWN RC5 RC6 NEC SONY PANASONIC JVC SAMSUNG WHYNTER AIWA_RC_T501 LG SANYO MITSUBISHI DISH SHARP"));
protocol = strtok(sirtype, " ");
while (iridx) {
iridx--;
protocol = strtok(NULL, " ");
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_IRRECEIVED "\":{\"" D_IR_PROTOCOL "\":\"%s\", \"" D_IR_BITS "\":%d, \"" D_IR_DATA "\":\"%X\"}}"),
protocol, results.bits, results.value);
GetIndexedString(sirtype, kIrReceiveProtocols, iridx), results.bits, results.value);
MqttPublishPrefixTopic_P(6, PSTR(D_IRRECEIVED));
#ifdef USE_DOMOTICZ
unsigned long value = results.value | (diridx << 28); // [Protocol:4, Data:28]
DomoticzSensor(DZ_COUNT, value); // Send data as Domoticz Counter value
unsigned long value = results.value | (iridx << 28); // [Protocol:4, Data:28]
DomoticzSensor(DZ_COUNT, value); // Send data as Domoticz Counter value
#endif // USE_DOMOTICZ
}

View File

@ -69,6 +69,7 @@ uint8_t light_current_color[5];
uint8_t light_new_color[5];
uint8_t light_last_color[5];
uint8_t light_wheel = 0;
uint8_t light_subtype = 0;
uint8_t light_power = 0;
uint8_t light_update = 1;
@ -159,11 +160,13 @@ void LightMy92x1Duty(uint8_t duty_r, uint8_t duty_g, uint8_t duty_b, uint8_t dut
void LightInit(void)
{
if (light_type < 6) { // PWM
uint8_t max_scheme = LS_MAX -1;
if (light_type < LT_PWM6) { // PWM
for (byte i = 0; i < light_type; i++) {
Settings.pwm_value[i] = 0; // Disable direct PWM control
}
if (1 == light_type) {
if (LT_PWM1 == light_type) {
Settings.led_color[0] = 255; // One PWM channel only supports Dimmer but needs max color
}
if (SONOFF_LED == Settings.module) { // Fix Sonoff Led instabilities
@ -180,14 +183,11 @@ void LightInit(void)
digitalWrite(14, LOW);
}
}
Settings.led_scheme = 0;
}
#ifdef USE_WS2812 // ************************************************************************
else if (11 == light_type) {
else if (LT_WS2812 == light_type) {
Ws2812Init();
if (1 == Settings.led_scheme) {
Settings.led_scheme = 0;
}
max_scheme += 8;
}
#endif // USE_WS2812 ************************************************************************
else {
@ -200,7 +200,10 @@ void LightInit(void)
digitalWrite(light_pdcki_pin, LOW);
LightMy92x1Init();
Settings.led_scheme = 0;
}
if ((LS_WAKEUP == Settings.led_scheme) || (Settings.led_scheme > max_scheme)) {
Settings.led_scheme = LS_POWER;
}
light_subtype = light_type &7;
@ -222,7 +225,7 @@ void LightSetColorTemp(uint16_t ct)
}
uint16_t icold = (100 * (347 - my_ct)) / 136;
uint16_t iwarm = (100 * my_ct) / 136;
if (5 == light_subtype) {
if (LST_RGBWC == light_subtype) {
Settings.led_color[0] = 0;
Settings.led_color[1] = 0;
Settings.led_color[2] = 0;
@ -237,7 +240,7 @@ void LightSetColorTemp(uint16_t ct)
uint16_t LightGetColorTemp()
{
uint8_t ct_idx = 0;
if (5 == light_subtype) {
if (LST_RGBWC == light_subtype) {
ct_idx = 3;
}
uint16_t my_ct = Settings.led_color[ct_idx +1];
@ -266,7 +269,6 @@ void LightSetDimmer(uint8_t myDimmer)
void LightSetColor()
{
uint8_t highest = 0;
float temp;
for (byte i = 0; i < light_subtype; i++) {
if (highest < light_current_color[i]) {
@ -277,7 +279,7 @@ void LightSetColor()
Settings.led_dimmer = (uint8_t)mDim;
float dimmer = 100 / mDim;
for (byte i = 0; i < light_subtype; i++) {
temp = (float)light_current_color[i] * dimmer;
float temp = (float)light_current_color[i] * dimmer;
Settings.led_color[i] = (uint8_t)temp;
}
}
@ -296,6 +298,13 @@ char* LightGetColor(uint8_t type, char* scolor)
return scolor;
}
void LightPowerOn()
{
if (Settings.led_dimmer && !(light_power)) {
ExecuteCommandPower(devices_present, 1);
}
}
void LightPreparePower()
{
char scolor[25];
@ -313,7 +322,7 @@ void LightPreparePower()
#endif // USE_DOMOTICZ
GetPowerDevice(scommand, devices_present, sizeof(scommand));
if (light_subtype > 1) {
if (light_subtype > LST_SINGLE) {
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"%s\":\"%s\", \"" D_CMND_DIMMER "\":%d, \"" D_CMND_COLOR "\":\"%s\"}"),
scommand, GetStateText(light_power), Settings.led_dimmer, LightGetColor(0, scolor));
} else {
@ -322,6 +331,85 @@ void LightPreparePower()
}
}
void LightFade()
{
if (0 == Settings.led_fade) {
for (byte i = 0; i < light_subtype; i++) {
light_new_color[i] = light_current_color[i];
}
} else {
uint8_t shift = Settings.led_speed;
if (Settings.led_speed > 6) {
shift = (strip_timer_counter % (Settings.led_speed -6)) ? 0 : 8;
}
if (shift) {
for (byte i = 0; i < light_subtype; i++) {
if (light_new_color[i] != light_current_color[i]) {
if (light_new_color[i] < light_current_color[i]) {
light_new_color[i] += ((light_current_color[i] - light_new_color[i]) >> shift) +1;
}
if (light_new_color[i] > light_current_color[i]) {
light_new_color[i] -= ((light_new_color[i] - light_current_color[i]) >> shift) +1;
}
}
}
}
}
}
void LightWheel(uint8_t wheel_pos)
{
wheel_pos = 255 - wheel_pos;
if (wheel_pos < 85) {
light_entry_color[0] = 255 - wheel_pos * 3;
light_entry_color[1] = 0;
light_entry_color[2] = wheel_pos * 3;
} else if (wheel_pos < 170) {
wheel_pos -= 85;
light_entry_color[0] = 0;
light_entry_color[1] = wheel_pos * 3;
light_entry_color[2] = 255 - wheel_pos * 3;
} else {
wheel_pos -= 170;
light_entry_color[0] = wheel_pos * 3;
light_entry_color[1] = 255 - wheel_pos * 3;
light_entry_color[2] = 0;
}
light_entry_color[3] = 0;
light_entry_color[4] = 0;
float dimmer = 100 / (float)Settings.led_dimmer;
for (byte i = 0; i < LST_RGB; i++) {
float temp = (float)light_entry_color[i] / dimmer;
light_entry_color[i] = (uint8_t)temp;
}
}
void LightCycleColor(int8_t direction)
{
if (strip_timer_counter % (Settings.led_speed * 2)) {
return;
}
light_wheel += direction;
LightWheel(light_wheel);
memcpy(light_new_color, light_entry_color, sizeof(light_new_color));
}
void LightRandomColor()
{
uint8_t light_update = 0;
for (byte i = 0; i < LST_RGB; i++) {
if (light_new_color[i] != light_current_color[i]) {
light_update = 1;
}
}
if (!light_update) {
light_wheel = random(255);
LightWheel(light_wheel);
memcpy(light_current_color, light_entry_color, sizeof(light_current_color));
}
LightFade();
}
void LightSetPower(uint8_t mpower)
{
light_power = mpower;
@ -336,7 +424,6 @@ void LightSetPower(uint8_t mpower)
void LightAnimate()
{
uint8_t fadeValue;
uint8_t cur_col[5];
strip_timer_counter++;
@ -350,26 +437,11 @@ void LightAnimate()
else {
sleep = 0;
switch (Settings.led_scheme) {
case 0: // Power On
case LS_POWER:
LightSetDimmer(Settings.led_dimmer);
if (0 == Settings.led_fade) {
for (byte i = 0; i < light_subtype; i++) {
light_new_color[i] = light_current_color[i];
}
} else {
for (byte i = 0; i < light_subtype; i++) {
if (light_new_color[i] != light_current_color[i]) {
if (light_new_color[i] < light_current_color[i]) {
light_new_color[i] += ((light_current_color[i] - light_new_color[i]) >> Settings.led_speed) +1;
}
if (light_new_color[i] > light_current_color[i]) {
light_new_color[i] -= ((light_new_color[i] - light_current_color[i]) >> Settings.led_speed) +1;
}
}
}
}
LightFade();
break;
case 1: // Power On using wake up duration
case LS_WAKEUP:
if (2 == light_wakeup_active) {
light_wakeup_active = 1;
for (byte i = 0; i < light_subtype; i++) {
@ -391,20 +463,29 @@ void LightAnimate()
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_DONE "\"}"));
MqttPublishPrefixTopic_P(2, PSTR(D_CMND_WAKEUP));
light_wakeup_active = 0;
Settings.led_scheme = 0;
Settings.led_scheme = LS_POWER;
}
}
break;
case LS_CYCLEUP:
LightCycleColor(1);
break;
case LS_CYCLEDN:
LightCycleColor(-1);
break;
case LS_RANDOM:
LightRandomColor();
break;
#ifdef USE_WS2812 // ************************************************************************
default:
if (11 == light_type) {
Ws2812ShowScheme(Settings.led_scheme -2);
if (LT_WS2812 == light_type) {
Ws2812ShowScheme(Settings.led_scheme -LS_MAX);
}
#endif // USE_WS2812 ************************************************************************
}
}
if ((Settings.led_scheme < 2) || !light_power) {
if ((Settings.led_scheme < LS_MAX) || !light_power) {
for (byte i = 0; i < light_subtype; i++) {
if (light_last_color[i] != light_new_color[i]) {
light_update = 1;
@ -415,7 +496,7 @@ void LightAnimate()
for (byte i = 0; i < light_subtype; i++) {
light_last_color[i] = light_new_color[i];
cur_col[i] = (Settings.led_table) ? ledTable[light_last_color[i]] : light_last_color[i];
if (light_type < 6) {
if (light_type < LT_PWM6) {
if (pin[GPIO_PWM1 +i] < 99) {
uint16_t curcol = cur_col[i] * (Settings.pwm_range / 255);
// snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_APPLICATION "Cur_Col%d %d, CurCol %d"), i, cur_col[i], curcol);
@ -425,11 +506,11 @@ void LightAnimate()
}
}
#ifdef USE_WS2812 // ************************************************************************
if (11 == light_type) {
if (LT_WS2812 == light_type) {
Ws2812SetColor(0, cur_col[0], cur_col[1], cur_col[2]);
}
#endif // USE_ES2812 ************************************************************************
if (light_type > 11) {
if (light_type > LT_WS2812) {
LightMy92x1Duty(cur_col[0], cur_col[1], cur_col[2], cur_col[3], cur_col[4]);
}
}
@ -543,7 +624,7 @@ void LightHsbToRgb()
void LightReplaceHsb(String *response)
{
if (light_subtype > 2) {
if (light_subtype > LST_COLDWARM) {
LightRgbToHsb();
response->replace("{h}", String((uint16_t)(65535.0f * light_hue)));
response->replace("{s}", String((uint8_t)(254.0f * light_saturation)));
@ -558,7 +639,7 @@ void LightReplaceHsb(String *response)
void LightGetHsb(float *hue, float *sat, float *bri)
{
if (light_subtype > 2) {
if (light_subtype > LST_COLDWARM) {
LightRgbToHsb();
*hue = light_hue;
*sat = light_saturation;
@ -573,8 +654,8 @@ void LightGetHsb(float *hue, float *sat, float *bri)
void LightSetHsb(float hue, float sat, float bri, uint16_t ct)
{
if (light_type > 2) {
if ((5 == light_subtype) && (ct > 0)) {
if (light_subtype > LST_COLDWARM) {
if ((LST_RGBWC == light_subtype) && (ct > 0)) {
LightSetColorTemp(ct);
} else {
light_hue = hue;
@ -588,7 +669,7 @@ void LightSetHsb(float hue, float sat, float bri, uint16_t ct)
} else {
uint8_t tmp = (uint8_t)(bri * 100);
Settings.led_dimmer = tmp;
if (2 == light_subtype) {
if (LST_COLDWARM == light_subtype) {
if (ct > 0) {
LightSetColorTemp(ct);
}
@ -645,7 +726,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
boolean valid_entry = false;
char scolor[25];
if ((light_subtype > 1) && !strcasecmp_P(type, PSTR(D_CMND_COLOR)) && (index > 0) && (index <= 4)) {
if ((light_subtype > LST_SINGLE) && !strcasecmp_P(type, PSTR(D_CMND_COLOR)) && (index > 0) && (index <= 4)) {
if (data_len > 0) {
valid_entry = LightColorEntry(dataBuf, data_len);
if (valid_entry) {
@ -657,7 +738,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
LightSetColor();
coldim = true;
} else { // Color2, 3 and 4
for (byte i = 0; i < 3; i++) {
for (byte i = 0; i < LST_RGB; i++) {
Settings.ws_color[index -2][i] = light_entry_color[i];
}
}
@ -668,7 +749,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
}
if (index > 1) {
scolor[0] = '\0';
for (byte i = 0; i < 3; i++) {
for (byte i = 0; i < LST_RGB; i++) {
if (Settings.flag.decimal_text) {
snprintf_P(scolor, 25, PSTR("%s%s%d"), scolor, (i > 0) ? "," : "", Settings.ws_color[index -2][i]);
} else {
@ -679,7 +760,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
}
}
#ifdef USE_WS2812 // ***********************************************************************
else if ((11 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_LED)) && (index > 0) && (index <= Settings.led_pixels)) {
else if ((LT_WS2812 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_LED)) && (index > 0) && (index <= Settings.led_pixels)) {
if (data_len > 0) {
if (LightColorEntry(dataBuf, data_len)) {
Ws2812SetColor(index, light_entry_color[0], light_entry_color[1], light_entry_color[2]);
@ -687,7 +768,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_LED "%d\":\"%s\"}"), index, Ws2812GetColor(index, scolor));
}
else if ((11 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_PIXELS))) {
else if ((LT_WS2812 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_PIXELS))) {
if ((payload > 0) && (payload <= WS2812_MAX_LEDS)) {
Settings.led_pixels = payload;
Ws2812Clear();
@ -695,7 +776,7 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_PIXELS "\":%d}"), Settings.led_pixels);
}
else if ((11 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_WIDTH)) && (index > 0) && (index <= 4)) {
else if ((LT_WS2812 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_WIDTH)) && (index > 0) && (index <= 4)) {
if (1 == index) {
if ((payload >= 0) && (payload <= 4)) {
Settings.led_width = payload;
@ -708,25 +789,32 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WIDTH "%d\":%d}"), index, Settings.ws_width[index -2]);
}
}
else if ((11 == light_type) && !strcasecmp_P(type, PSTR(D_CMND_SCHEME))) {
if ((payload >= 0) && (payload <= 9)) {
#endif // USE_WS2812 ************************************************************************
else if (!strcasecmp_P(type, PSTR(D_CMND_SCHEME))) {
uint8_t max_scheme = LS_WAKEUP;
if (light_subtype >= LST_RGB) {
max_scheme = LS_MAX -1;
}
if (LT_WS2812 == light_type) {
max_scheme += 8;
}
if ((payload >= 0) && (payload <= max_scheme)) {
Settings.led_scheme = payload;
if (1 == Settings.led_scheme) {
if (LS_WAKEUP == Settings.led_scheme) {
light_wakeup_active = 3;
}
ExecuteCommandPower(devices_present, 1);
LightPowerOn();
strip_timer_counter = 0;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SCHEME "\":%d}"), Settings.led_scheme);
}
#endif // USE_WS2812 ************************************************************************
else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUP))) {
if ((payload >= 0) && (payload <= 100)) {
Settings.led_dimmer = payload;
}
light_wakeup_active = 3;
Settings.led_scheme = 1;
ExecuteCommandPower(devices_present, 1);
Settings.led_scheme = LS_WAKEUP;
LightPowerOn();
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_STARTED "\"}"));
}
else if (!strcasecmp_P(type, PSTR(D_CMND_COLORTEMPERATURE)) && ((2 == light_subtype) || (5 == light_subtype))) { // ColorTemp
@ -772,8 +860,8 @@ boolean LightCommand(char *type, uint16_t index, char *dataBuf, uint16_t data_le
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_FADE "\":\"%s\"}"), GetStateText(Settings.led_fade));
}
else if (!strcasecmp_P(type, PSTR(D_CMND_SPEED))) { // 1 - fast, 8 - slow
if ((payload > 0) && (payload <= 8)) {
else if (!strcasecmp_P(type, PSTR(D_CMND_SPEED))) { // 1 - fast, 20 - very slow
if ((payload > 0) && (payload <= STATES)) {
Settings.led_speed = payload;
}
snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("{\"" D_CMND_SPEED "\":%d}"), Settings.led_speed);

View File

@ -40,12 +40,12 @@ const char WEMO_MSEARCH[] PROGMEM =
"CACHE-CONTROL: max-age=86400\r\n"
"DATE: Fri, 15 Apr 2016 04:56:29 GMT\r\n"
"EXT:\r\n"
"LOCATION: http://{r1}:80/setup.xml\r\n"
"LOCATION: http://{r1:80/setup.xml\r\n"
"OPT: \"http://schemas.upnp.org/upnp/1/0/\"; ns=01\r\n"
"01-NLS: b9200ebb-736d-4b93-bf03-835149d13983\r\n"
"SERVER: Unspecified, UPnP/1.0, Unspecified\r\n"
"ST: urn:Belkin:device:**\r\n"
"USN: uuid:{r2}::urn:Belkin:device:**\r\n"
"USN: uuid:{r2::urn:Belkin:device:**\r\n"
"X-User-Agent: redsonic\r\n"
"\r\n";
@ -71,8 +71,8 @@ void WemoRespondToMSearch()
if (PortUdp.beginPacket(PortUdp.remoteIP(), PortUdp.remotePort())) {
String response = FPSTR(WEMO_MSEARCH);
response.replace("{r1}", WiFi.localIP().toString());
response.replace("{r2}", WemoUuid());
response.replace("{r1", WiFi.localIP().toString());
response.replace("{r2", WemoUuid());
PortUdp.write(response.c_str());
PortUdp.endPacket();
snprintf_P(message, sizeof(message), PSTR(D_RESPONSE_SENT));
@ -97,20 +97,20 @@ const char HUE_RESPONSE[] PROGMEM =
"HOST: 239.255.255.250:1900\r\n"
"CACHE-CONTROL: max-age=100\r\n"
"EXT:\r\n"
"LOCATION: http://{r1}:80/description.xml\r\n"
"LOCATION: http://{r1:80/description.xml\r\n"
"SERVER: Linux/3.14.0 UPnP/1.0 IpBridge/1.17.0\r\n"
"hue-bridgeid: {r2}\r\n";
"hue-bridgeid: {r2\r\n";
const char HUE_ST1[] PROGMEM =
"ST: upnp:rootdevice\r\n"
"USN: uuid:{r3}::upnp:rootdevice\r\n"
"USN: uuid:{r3::upnp:rootdevice\r\n"
"\r\n";
const char HUE_ST2[] PROGMEM =
"ST: uuid:{r3}\r\n"
"USN: uuid:{r3}\r\n"
"ST: uuid:{r3\r\n"
"USN: uuid:{r3\r\n"
"\r\n";
const char HUE_ST3[] PROGMEM =
"ST: urn:schemas-upnp-org:device:basic:1\r\n"
"USN: uuid:{r3}\r\n"
"USN: uuid:{r3\r\n"
"\r\n";
String HueBridgeId()
@ -142,24 +142,24 @@ void HueRespondToMSearch()
if (PortUdp.beginPacket(PortUdp.remoteIP(), PortUdp.remotePort())) {
String response1 = FPSTR(HUE_RESPONSE);
response1.replace("{r1}", WiFi.localIP().toString());
response1.replace("{r2}", HueBridgeId());
response1.replace("{r1", WiFi.localIP().toString());
response1.replace("{r2", HueBridgeId());
String response = response1;
response += FPSTR(HUE_ST1);
response.replace("{r3}", HueUuid());
response.replace("{r3", HueUuid());
PortUdp.write(response.c_str());
PortUdp.endPacket();
response = response1;
response += FPSTR(HUE_ST2);
response.replace("{r3}", HueUuid());
response.replace("{r3", HueUuid());
PortUdp.write(response.c_str());
PortUdp.endPacket();
response = response1;
response += FPSTR(HUE_ST3);
response.replace("{r3}", HueUuid());
response.replace("{r3", HueUuid());
PortUdp.write(response.c_str());
PortUdp.endPacket();
@ -273,12 +273,12 @@ const char WEMO_SETUP_XML[] PROGMEM =
"<root>"
"<device>"
"<deviceType>urn:Belkin:device:controllee:1</deviceType>"
"<friendlyName>{x1}</friendlyName>"
"<friendlyName>{x1</friendlyName>"
"<manufacturer>Belkin International Inc.</manufacturer>"
"<modelName>Sonoff Socket</modelName>"
"<modelNumber>3.1415</modelNumber>"
"<UDN>uuid:{x2}</UDN>"
"<serialNumber>{x3}</serialNumber>"
"<UDN>uuid:{x2</UDN>"
"<serialNumber>{x3</serialNumber>"
"<binaryState>0</binaryState>"
"<serviceList>"
"<service>"
@ -321,9 +321,9 @@ void HandleUpnpSetupWemo()
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP));
String setup_xml = FPSTR(WEMO_SETUP_XML);
setup_xml.replace("{x1}", Settings.friendlyname[0]);
setup_xml.replace("{x2}", WemoUuid());
setup_xml.replace("{x3}", WemoSerialnumber());
setup_xml.replace("{x1", Settings.friendlyname[0]);
setup_xml.replace("{x2", WemoUuid());
setup_xml.replace("{x3", WemoSerialnumber());
WebServer->send(200, FPSTR(HDR_CTYPE_XML), setup_xml);
}
@ -338,18 +338,18 @@ const char HUE_DESCRIPTION_XML[] PROGMEM =
"<major>1</major>"
"<minor>0</minor>"
"</specVersion>"
// "<URLBase>http://{x1}/</URLBase>"
"<URLBase>http://{x1}:80/</URLBase>"
// "<URLBase>http://{x1/</URLBase>"
"<URLBase>http://{x1:80/</URLBase>"
"<device>"
"<deviceType>urn:schemas-upnp-org:device:Basic:1</deviceType>"
"<friendlyName>Amazon-Echo-HA-Bridge ({x1})</friendlyName>"
// "<friendlyName>Philips hue ({x1})</friendlyName>"
"<friendlyName>Amazon-Echo-HA-Bridge ({x1)</friendlyName>"
// "<friendlyName>Philips hue ({x1)</friendlyName>"
"<manufacturer>Royal Philips Electronics</manufacturer>"
"<modelDescription>Philips hue Personal Wireless Lighting</modelDescription>"
"<modelName>Philips hue bridge 2012</modelName>"
"<modelNumber>929000226503</modelNumber>"
"<serialNumber>{x3}</serialNumber>"
"<UDN>uuid:{x2}</UDN>"
"<serialNumber>{x3</serialNumber>"
"<UDN>uuid:{x2</UDN>"
"</device>"
"</root>\r\n"
"\r\n";
@ -366,31 +366,31 @@ const char HueLightStatus_JSON[] PROGMEM =
"\"reachable\":true";
const char HUE_LIGHTS_STATUS_JSON[] PROGMEM =
"\"type\":\"Extended color light\","
"\"name\":\"{j1}\","
"\"name\":\"{j1\","
"\"modelid\":\"LCT007\","
"\"uniqueid\":\"{j2}\","
"\"uniqueid\":\"{j2\","
"\"swversion\":\"5.50.1.19085\""
"}";
const char HUE_GROUP0_STATUS_JSON[] PROGMEM =
"{\"name\":\"Group 0\","
"\"lights\":[{l1}],"
"\"lights\":[{l1],"
"\"type\":\"LightGroup\","
"\"action\":{";
// "\"scene\":\"none\",";
const char HueConfigResponse_JSON[] PROGMEM =
"{\"name\":\"Philips hue\","
"\"mac\":\"{mac}\","
"\"mac\":\"{ma\","
"\"dhcp\":true,"
"\"ipaddress\":\"{ip}\","
"\"netmask\":\"{mask}\","
"\"gateway\":\"{gw}\","
"\"ipaddress\":\"{ip\","
"\"netmask\":\"{ms\","
"\"gateway\":\"{gw\","
"\"proxyaddress\":\"none\","
"\"proxyport\":0,"
"\"bridgeid\":\"{bid}\","
"\"UTC\":\"{dt}\","
"\"whitelist\":{\"{id}\":{"
"\"last use date\":\"{dt}\","
"\"create date\":\"{dt}\","
"\"bridgeid\":\"{br\","
"\"UTC\":\"{dt\","
"\"whitelist\":{\"{id\":{"
"\"last use date\":\"{dt\","
"\"create date\":\"{dt\","
"\"name\":\"Remote\"}},"
"\"swversion\":\"01039019\","
"\"apiversion\":\"1.17.0\","
@ -399,7 +399,7 @@ const char HueConfigResponse_JSON[] PROGMEM =
"\"portalservices\":false"
"}";
const char HUE_LIGHT_RESPONSE_JSON[] PROGMEM =
"{\"success\":{\"/lights/{id}/state/{cmd}\":{res}}}";
"{\"success\":{\"/lights/{id/state/{cm\":{re}}";
const char HUE_ERROR_JSON[] PROGMEM =
"[{\"error\":{\"type\":901,\"address\":\"/\",\"description\":\"Internal Error\"}}]";
@ -424,9 +424,9 @@ void HandleUpnpSetupHue()
{
AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_HUE_BRIDGE_SETUP));
String description_xml = FPSTR(HUE_DESCRIPTION_XML);
description_xml.replace("{x1}", WiFi.localIP().toString());
description_xml.replace("{x2}", HueUuid());
description_xml.replace("{x3}", HueSerialnumber());
description_xml.replace("{x1", WiFi.localIP().toString());
description_xml.replace("{x2", HueUuid());
description_xml.replace("{x3", HueSerialnumber());
WebServer->send(200, FPSTR(HDR_CTYPE_XML), description_xml);
}
@ -441,13 +441,13 @@ void HueNotImplemented(String *path)
void HueConfigResponse(String *response)
{
*response += FPSTR(HueConfigResponse_JSON);
response->replace("{mac}", WiFi.macAddress());
response->replace("{ip}", WiFi.localIP().toString());
response->replace("{mask}", WiFi.subnetMask().toString());
response->replace("{gw}", WiFi.gatewayIP().toString());
response->replace("{bid}", HueBridgeId());
response->replace("{dt}", GetUtcDateAndTime());
response->replace("{id}", GetHueUserId());
response->replace("{ma", WiFi.macAddress());
response->replace("{ip", WiFi.localIP().toString());
response->replace("{ms", WiFi.subnetMask().toString());
response->replace("{gw", WiFi.gatewayIP().toString());
response->replace("{br", HueBridgeId());
response->replace("{dt", GetUtcDateAndTime());
response->replace("{id", GetHueUserId());
}
void HueConfig(String *path)
@ -484,8 +484,8 @@ void HueGlobalConfig(String *path)
HueLightStatus(i, &response);
response += "},";
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
response.replace("{j1}", Settings.friendlyname[i-1]);
response.replace("{j2}", GetHueDeviceId(i));
response.replace("{j1", Settings.friendlyname[i-1]);
response.replace("{j2", GetHueDeviceId(i));
if (i < maxhue) {
response += ",\"";
}
@ -532,8 +532,8 @@ void HueLights(String *path)
HueLightStatus(i, &response);
response += "},";
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
response.replace("{j1}", Settings.friendlyname[i-1]);
response.replace("{j2}", GetHueDeviceId(i));
response.replace("{j1", Settings.friendlyname[i-1]);
response.replace("{j2", GetHueDeviceId(i));
if (i < maxhue) {
response += ",\"";
}
@ -556,19 +556,19 @@ void HueLights(String *path)
if (hue_json.containsKey("on")) {
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
response.replace("{id}", String(device));
response.replace("{cmd}", "on");
response.replace("{id", String(device));
response.replace("{cm", "on");
on = hue_json["on"];
switch(on)
{
case false : ExecuteCommandPower(device, 0);
response.replace("{res}", "false");
response.replace("{re", "false");
break;
case true : ExecuteCommandPower(device, 1);
response.replace("{res}", "true");
response.replace("{re", "true");
break;
default : response.replace("{res}", (power & (1 << (device-1))) ? "true" : "false");
default : response.replace("{re", (power & (1 << (device-1))) ? "true" : "false");
break;
}
resp = true;
@ -585,9 +585,9 @@ void HueLights(String *path)
response += ",";
}
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
response.replace("{id}", String(device));
response.replace("{cmd}", "bri");
response.replace("{res}", String(tmp));
response.replace("{id", String(device));
response.replace("{cm", "bri");
response.replace("{re", String(tmp));
resp = true;
change = true;
}
@ -598,9 +598,9 @@ void HueLights(String *path)
response += ",";
}
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
response.replace("{id}", String(device));
response.replace("{cmd}", "hue");
response.replace("{res}", String(tmp));
response.replace("{id", String(device));
response.replace("{cm", "hue");
response.replace("{re", String(tmp));
resp = true;
change = true;
}
@ -611,9 +611,9 @@ void HueLights(String *path)
response += ",";
}
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
response.replace("{id}", String(device));
response.replace("{cmd}", "sat");
response.replace("{res}", String(tmp));
response.replace("{id", String(device));
response.replace("{cm", "sat");
response.replace("{re", String(tmp));
change = true;
}
if (hue_json.containsKey("ct")) { // Color temperature 153 (Cold) to 500 (Warm)
@ -622,9 +622,9 @@ void HueLights(String *path)
response += ",";
}
response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
response.replace("{id}", String(device));
response.replace("{cmd}", "ct");
response.replace("{res}", String(ct));
response.replace("{id", String(device));
response.replace("{cm", "ct");
response.replace("{re", String(ct));
change = true;
}
if (change) {
@ -654,8 +654,8 @@ void HueLights(String *path)
HueLightStatus(device, &response);
response += "},";
response += FPSTR(HUE_LIGHTS_STATUS_JSON);
response.replace("{j1}", Settings.friendlyname[device-1]);
response.replace("{j2}", GetHueDeviceId(device));
response.replace("{j1", Settings.friendlyname[device-1]);
response.replace("{j2", GetHueDeviceId(device));
WebServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
}
else {
@ -677,7 +677,7 @@ void HueGroups(String *path)
for (uint8_t i = 2; i <= maxhue; i++) {
lights += ",\"" + String(i) + "\"";
}
response.replace("{l1}", lights);
response.replace("{l1", lights);
HueLightStatus(1, &response);
response += F("}}");
}

View File

@ -75,16 +75,6 @@ uint8_t kRepeat[5] = {
4, // Large
2, // Largest
1 }; // All
uint8_t kSpeed[9] = {
0, // None
1 * (STATES / 10), // Fastest
3 * (STATES / 10),
5 * (STATES / 10), // Fast
7 * (STATES / 10),
9 * (STATES / 10),
11 * (STATES / 10), // Slow
13 * (STATES / 10),
15 * (STATES / 10) }; // Slowest
uint8_t ws_show_next = 1;
@ -195,7 +185,8 @@ void Ws2812Gradient(uint8_t schemenr)
uint8_t repeat = kRepeat[Settings.led_width]; // number of scheme.count per ledcount
uint16_t range = (uint16_t)ceil((float)Settings.led_pixels / (float)repeat);
uint16_t gradRange = (uint16_t)ceil((float)range / (float)(scheme.count - 1));
uint16_t offset = kSpeed[Settings.led_speed] > 0 ? strip_timer_counter / kSpeed[Settings.led_speed] : 0;
uint16_t speed = ((Settings.led_speed * 2) -1) * (STATES / 10);
uint16_t offset = speed > 0 ? strip_timer_counter / speed : 0;
WsColor oldColor, currentColor;
Ws2812GradientColor(schemenr, &oldColor, range, gradRange, offset);
@ -206,9 +197,9 @@ void Ws2812Gradient(uint8_t schemenr)
}
if (Settings.led_speed > 0) {
// Blend old and current color based on time for smooth movement.
c.R = map(strip_timer_counter % kSpeed[Settings.led_speed], 0, kSpeed[Settings.led_speed], oldColor.red, currentColor.red);
c.G = map(strip_timer_counter % kSpeed[Settings.led_speed], 0, kSpeed[Settings.led_speed], oldColor.green, currentColor.green);
c.B = map(strip_timer_counter % kSpeed[Settings.led_speed], 0, kSpeed[Settings.led_speed], oldColor.blue, currentColor.blue);
c.R = map(strip_timer_counter % speed, 0, speed, oldColor.red, currentColor.red);
c.G = map(strip_timer_counter % speed, 0, speed, oldColor.green, currentColor.green);
c.B = map(strip_timer_counter % speed, 0, speed, oldColor.blue, currentColor.blue);
}
else {
// No animation, just use the current color.
@ -239,7 +230,8 @@ void Ws2812Bars(uint8_t schemenr)
maxSize = 0;
}
uint8_t offset = kSpeed[Settings.led_speed] > 0 ? strip_timer_counter / kSpeed[Settings.led_speed] : 0;
uint16_t speed = ((Settings.led_speed * 2) -1) * (STATES / 10);
uint8_t offset = speed > 0 ? strip_timer_counter / speed : 0;
WsColor mcolor[scheme.count];
memcpy(mcolor, scheme.colors, sizeof(mcolor));

113
sonoff/xsns_veml6070.ino Normal file
View File

@ -0,0 +1,113 @@
/*
xsns_veml6070.ino - VEML6070 ultra violet light sensor support for Sonoff-Tasmota
Copyright (C) 2017 Theo Arends
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/>.
*/
#ifdef USE_I2C
#ifdef USE_VEML6070
/*********************************************************************************************\
* VEML6070 - Ultra Violet Light Intensity
\*********************************************************************************************/
#define VEML6070_ADDR_H 0x39
#define VEML6070_ADDR_L 0x38
#define VEML6070_INTEGRATION_TIME 3 // 500msec integration time
uint8_t veml6070_address;
uint8_t veml6070_type = 0;
char veml6070_types[9];
uint16_t Veml6070ReadUv()
{
if (Wire.requestFrom(VEML6070_ADDR_H, 1) != 1) {
return -1;
}
uint16_t uvi = Wire.read();
uvi <<= 8;
if (Wire.requestFrom(VEML6070_ADDR_L, 1) != 1) {
return -1;
}
uvi |= Wire.read();
return uvi;
}
boolean Veml6070Detect()
{
if (veml6070_type) {
return true;
}
uint8_t status;
uint8_t itime = VEML6070_INTEGRATION_TIME;
boolean success = false;
veml6070_address = VEML6070_ADDR_L;
Wire.beginTransmission(veml6070_address);
Wire.write((itime << 2) | 0x02);
status = Wire.endTransmission();
if (!status) {
success = true;
veml6070_type = 1;
strcpy_P(veml6070_types, PSTR("VEML6070"));
}
if (success) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), veml6070_types, veml6070_address);
AddLog(LOG_LEVEL_DEBUG);
} else {
veml6070_type = 0;
}
return success;
}
/*********************************************************************************************\
* Presentation
\*********************************************************************************************/
void MqttShowVeml6070(uint8_t* djson)
{
if (!veml6070_type) {
return;
}
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
}
#ifdef USE_WEBSERVER
const char HTTP_SNS_ULTRAVIOLET[] PROGMEM =
"<tr><th>VEML6070 " D_UV_LEVEL "</th><td>%d</td></tr>";
String WebShowVeml6070()
{
String page = "";
if (veml6070_type) {
char sensor[80];
snprintf_P(sensor, sizeof(sensor), HTTP_SNS_ULTRAVIOLET, Veml6070ReadUv());
page += sensor;
}
return page;
}
#endif // USE_WEBSERVER
#endif // USE_VEML6070
#endif // USE_I2C