Add more user input validation

5.13.1c
 * Add more user input validation to commands TimeStd and
TimeDst
This commit is contained in:
Theo Arends 2018-05-15 12:32:53 +02:00
parent 5d55a11110
commit 12ffefe081
7 changed files with 104 additions and 91 deletions

View File

@ -1,5 +1,6 @@
/* 5.13.1c /* 5.13.1c
* Add user entry DST/STD using commands TimeStd and TimeDst with options like 0,0,3,1,2,120 (#2721) * Add user entry DST/STD using commands TimeStd and TimeDst with options like 0,0,3,1,2,120 (#2721)
* Add more user input validation to commands TimeStd and TimeDst
* *
* 5.13.1a * 5.13.1a
* Change user_config.h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602) * Change user_config.h otaurl to http://sonoff.maddox.co.uk/tasmota/sonoff.bin (#2588, #2602)

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.12.0m * Updated until v5.13.1c
\*********************************************************************/ \*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -61,7 +61,7 @@
#define D_BRIGHTLIGHT "Яркост" #define D_BRIGHTLIGHT "Яркост"
#define D_BUTTON "Бутон" #define D_BUTTON "Бутон"
#define D_BY "от" // Written by me #define D_BY "от" // Written by me
#define D_BYTES "Байт" #define D_BYTES "Байта"
#define D_CELSIUS "Целзий" #define D_CELSIUS "Целзий"
#define D_CO2 "Въглероден диоксид" #define D_CO2 "Въглероден диоксид"
#define D_CODE "код" // Button code #define D_CODE "код" // Button code
@ -75,7 +75,7 @@
#define D_DARKLIGHT "Тъмна" #define D_DARKLIGHT "Тъмна"
#define D_DEBUG "Дебъгване" #define D_DEBUG "Дебъгване"
#define D_DISABLED "Деактивиран" #define D_DISABLED "Деактивиран"
#define D_DISTANCE "Distance" #define D_DISTANCE "Разстояние"
#define D_DNS_SERVER "DNS Сървър" #define D_DNS_SERVER "DNS Сървър"
#define D_DONE "Изпълнено" #define D_DONE "Изпълнено"
#define D_DST_TIME "DST" #define D_DST_TIME "DST"
@ -86,12 +86,12 @@
#define D_ERROR "Грешка" #define D_ERROR "Грешка"
#define D_FAHRENHEIT "Фаренхайт" #define D_FAHRENHEIT "Фаренхайт"
#define D_FAILED "Неуспешно" #define D_FAILED "Неуспешно"
#define D_FALLBACK "Обратна връзка" #define D_FALLBACK "Помощен"
#define D_FALLBACK_TOPIC "Топик на обратната връзка" #define D_FALLBACK_TOPIC "Помощен топик"
#define D_FALSE "Невярно" #define D_FALSE "Невярно"
#define D_FILE "Файл" #define D_FILE "Файл"
#define D_FREE_MEMORY "Свободна памет" #define D_FREE_MEMORY "Свободна памет"
#define D_FREQUENCY "Frequency" #define D_FREQUENCY "Честота"
#define D_GAS "Газ" #define D_GAS "Газ"
#define D_GATEWAY "Шлюз" #define D_GATEWAY "Шлюз"
#define D_GROUP "Група" #define D_GROUP "Група"
@ -99,10 +99,10 @@
#define D_HOSTNAME "Име на хоста" #define D_HOSTNAME "Име на хоста"
#define D_HUMIDITY "Влажност" #define D_HUMIDITY "Влажност"
#define D_ILLUMINANCE "Осветеност" #define D_ILLUMINANCE "Осветеност"
#define D_IMMEDIATE "моментален" // Button immediate #define D_IMMEDIATE "Моментен" // Button immediate
#define D_INDEX "Индекс" #define D_INDEX "Индекс"
#define D_INFO "Информация" #define D_INFO "Информация"
#define D_INFRARED "Infrared" #define D_INFRARED "Инфрачервен"
#define D_INITIALIZED "Инициализирано" #define D_INITIALIZED "Инициализирано"
#define D_IP_ADDRESS "IP адрес" #define D_IP_ADDRESS "IP адрес"
#define D_LIGHT "Светлина" #define D_LIGHT "Светлина"
@ -121,9 +121,9 @@
#define D_PORT "Порт" #define D_PORT "Порт"
#define D_POWER_FACTOR "Фактор на мощността" #define D_POWER_FACTOR "Фактор на мощността"
#define D_POWERUSAGE "Мощност" #define D_POWERUSAGE "Мощност"
#define D_POWERUSAGE_ACTIVE "Active Power" #define D_POWERUSAGE_ACTIVE "Активна мощност"
#define D_POWERUSAGE_APPARENT "Apparent Power" #define D_POWERUSAGE_APPARENT "Пълна мощност"
#define D_POWERUSAGE_REACTIVE "Reactive Power" #define D_POWERUSAGE_REACTIVE "Реактивна мощност"
#define D_PRESSURE "Налягане" #define D_PRESSURE "Налягане"
#define D_PRESSUREATSEALEVEL "Налягане на морското ниво" #define D_PRESSUREATSEALEVEL "Налягане на морското ниво"
#define D_PROGRAM_FLASH_SIZE "Размер на флаш паметта за програми" #define D_PROGRAM_FLASH_SIZE "Размер на флаш паметта за програми"
@ -159,7 +159,7 @@
#define D_UPTIME "Време от стартирането" #define D_UPTIME "Време от стартирането"
#define D_USER "Потребител" #define D_USER "Потребител"
#define D_UTC_TIME "UTC" #define D_UTC_TIME "UTC"
#define D_UV_INDEX "UV Index" #define D_UV_INDEX "UV индекс"
#define D_UV_LEVEL "Ниво на ултравиолетово излъчване" #define D_UV_LEVEL "Ниво на ултравиолетово излъчване"
#define D_VERSION "Версия" #define D_VERSION "Версия"
#define D_VOLTAGE "Напрежение" #define D_VOLTAGE "Напрежение"
@ -205,7 +205,7 @@
#define D_ERASED_SECTOR "Изтрит сектор" #define D_ERASED_SECTOR "Изтрит сектор"
// webserver.ino // webserver.ino
#define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Фърмуеър MINIMAL - моля надградете го" #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "Минимаен фърмуеър - моля надградете го"
#define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на" #define D_WEBSERVER_ACTIVE_ON "Уеб сървърът е активен на"
#define D_WITH_IP_ADDRESS "с IP адрес" #define D_WITH_IP_ADDRESS "с IP адрес"
#define D_WEBSERVER_STOPPED "Уеб сървърът е спрян" #define D_WEBSERVER_STOPPED "Уеб сървърът е спрян"
@ -274,12 +274,12 @@
#define D_OTHER_PARAMETERS "Други параметри" #define D_OTHER_PARAMETERS "Други параметри"
#define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора" #define D_WEB_ADMIN_PASSWORD "Парола на уеб администратора"
#define D_MQTT_ENABLE "активиране на MQTT" #define D_MQTT_ENABLE "Активиране на MQTT"
#define D_FRIENDLY_NAME "приятелско име" #define D_FRIENDLY_NAME "Приятелско име"
#define D_BELKIN_WEMO "Belkin WeMo" #define D_BELKIN_WEMO "Belkin WeMo"
#define D_HUE_BRIDGE "Hue Bridge" #define D_HUE_BRIDGE "Hue Bridge"
#define D_SINGLE_DEVICE "единично" #define D_SINGLE_DEVICE "Единично"
#define D_MULTI_DEVICE "мулти" #define D_MULTI_DEVICE "Мулти"
#define D_SAVE_CONFIGURATION "Запазване на конфигурацията" #define D_SAVE_CONFIGURATION "Запазване на конфигурацията"
#define D_CONFIGURATION_SAVED "Конфигурацията е запазена" #define D_CONFIGURATION_SAVED "Конфигурацията е запазена"
@ -299,7 +299,7 @@
#define D_MQTT_FULL_TOPIC "MQTT пълен топик" #define D_MQTT_FULL_TOPIC "MQTT пълен топик"
#define D_MDNS_DISCOVERY "mDNS откриване" #define D_MDNS_DISCOVERY "mDNS откриване"
#define D_MDNS_ADVERTISE "mDNS транслация" #define D_MDNS_ADVERTISE "mDNS транслация"
#define D_ESP_CHIP_ID "ID на чипа ESP" #define D_ESP_CHIP_ID "ID на ESP чипа"
#define D_FLASH_CHIP_ID "ID на чипа на флаш паметта" #define D_FLASH_CHIP_ID "ID на чипа на флаш паметта"
#define D_FLASH_CHIP_SIZE "Размер на флаш паметта" #define D_FLASH_CHIP_SIZE "Размер на флаш паметта"
#define D_FREE_PROGRAM_SPACE "Свободно пространство за програми" #define D_FREE_PROGRAM_SPACE "Свободно пространство за програми"
@ -316,7 +316,7 @@
#define D_UPLOAD_ERR_3 "Magic байтът не е 0xE9" #define D_UPLOAD_ERR_3 "Magic байтът не е 0xE9"
#define D_UPLOAD_ERR_4 "Размерът на програмата е по-голям от реалния размер на флаш паметта" #define D_UPLOAD_ERR_4 "Размерът на програмата е по-голям от реалния размер на флаш паметта"
#define D_UPLOAD_ERR_5 "Грешка при зареждането в буфера" #define D_UPLOAD_ERR_5 "Грешка при зареждането в буфера"
#define D_UPLOAD_ERR_6 "Грешка пр зареждането. Включено е ниво 3 на лога" #define D_UPLOAD_ERR_6 "Грешка при зареждането. Включено е ниво 3 на лога"
#define D_UPLOAD_ERR_7 "Зареждането е прекъснато" #define D_UPLOAD_ERR_7 "Зареждането е прекъснато"
#define D_UPLOAD_ERR_8 "Файлът е невалиден" #define D_UPLOAD_ERR_8 "Файлът е невалиден"
#define D_UPLOAD_ERR_9 "Файлът е прекалено голям" #define D_UPLOAD_ERR_9 "Файлът е прекалено голям"
@ -348,7 +348,7 @@
#define D_RESPONSE_SENT "Отговорът е изпратен" #define D_RESPONSE_SENT "Отговорът е изпратен"
#define D_HUE "Hue" #define D_HUE "Hue"
#define D_HUE_BRIDGE_SETUP "Hue мост настройка" #define D_HUE_BRIDGE_SETUP "Настройка на Hue bridge"
#define D_HUE_API_NOT_IMPLEMENTED "Hue API не е внедрено" #define D_HUE_API_NOT_IMPLEMENTED "Hue API не е внедрено"
#define D_HUE_API "Hue API" #define D_HUE_API "Hue API"
#define D_HUE_POST_ARGS "Hue POST аргументи" #define D_HUE_POST_ARGS "Hue POST аргументи"
@ -413,9 +413,9 @@
// xsns_06_dht.ino // xsns_06_dht.ino
#define D_TIMEOUT_WAITING_FOR "Изтекло време за очакване на" #define D_TIMEOUT_WAITING_FOR "Изтекло време за очакване на"
#define D_START_SIGNAL_LOW "стартов сигнал нисък" #define D_START_SIGNAL_LOW "Нисък стартов сигнал"
#define D_START_SIGNAL_HIGH "стартов сигнал висок" #define D_START_SIGNAL_HIGH "Висок стартов сигнал"
#define D_PULSE "импулс" #define D_PULSE "Импулс"
#define D_CHECKSUM_FAILURE "Грешка в контролната сума" #define D_CHECKSUM_FAILURE "Грешка в контролната сума"
// xsns_07_sht1x.ino // xsns_07_sht1x.ino
@ -425,10 +425,10 @@
// xsns_18_pms5003.ino // xsns_18_pms5003.ino
#define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter #define D_STANDARD_CONCENTRATION "CF-1 PM" // Standard Particle CF-1 Particle Matter
#define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter #define D_ENVIRONMENTAL_CONCENTRATION "PM" // Environmetal Particle Matter
#define D_PARTICALS_BEYOND "Particals" #define D_PARTICALS_BEYOND "Частици"
// sonoff_template.h // sonoff_template.h
#define D_SENSOR_NONE "няма" #define D_SENSOR_NONE "Няма"
#define D_SENSOR_DHT11 "DHT11" #define D_SENSOR_DHT11 "DHT11"
#define D_SENSOR_AM2301 "AM2301" #define D_SENSOR_AM2301 "AM2301"
#define D_SENSOR_SI7021 "SI7021" #define D_SENSOR_SI7021 "SI7021"
@ -463,30 +463,30 @@
#define D_SENSOR_SDM120_RX "SDM120 Rx" #define D_SENSOR_SDM120_RX "SDM120 Rx"
// Units // Units
#define D_UNIT_AMPERE "А" #define D_UNIT_AMPERE "A"
#define D_UNIT_CENTIMETER "см" #define D_UNIT_CENTIMETER "cm"
#define D_UNIT_HERTZ "Hz" #define D_UNIT_HERTZ "Hz"
#define D_UNIT_HOUR "ч" #define D_UNIT_HOUR "h"
#define D_UNIT_KILOOHM "кОм" #define D_UNIT_KILOOHM ""
#define D_UNIT_KILOWATTHOUR "кВт/ч" #define D_UNIT_KILOWATTHOUR "kWh"
#define D_UNIT_LUX "лукс" #define D_UNIT_LUX "lx"
#define D_UNIT_MICROGRAM_PER_CUBIC_METER "микрограм/м3" #define D_UNIT_MICROGRAM_PER_CUBIC_METER "µg/m3"
#define D_UNIT_MICROMETER "микрометър" #define D_UNIT_MICROMETER "µm"
#define D_UNIT_MICROSECOND "микросек" #define D_UNIT_MICROSECOND "µs"
#define D_UNIT_MILLIAMPERE "мА" #define D_UNIT_MILLIAMPERE "mA"
#define D_UNIT_MILLISECOND "мсек" #define D_UNIT_MILLISECOND "ms"
#define D_UNIT_MINUTE "мин" #define D_UNIT_MINUTE "min"
#define D_UNIT_PARTS_PER_BILLION "ppb" #define D_UNIT_PARTS_PER_BILLION "ppb"
#define D_UNIT_PARTS_PER_DECILITER "ppd" #define D_UNIT_PARTS_PER_DECILITER "ppd"
#define D_UNIT_PARTS_PER_MILLION "ppm" #define D_UNIT_PARTS_PER_MILLION "ppm"
#define D_UNIT_PRESSURE "хПа" #define D_UNIT_PRESSURE "hPa"
#define D_UNIT_SECOND "сек" #define D_UNIT_SECOND "s"
#define D_UNIT_SECTORS "сектори" #define D_UNIT_SECTORS "сектори"
#define D_UNIT_VA "VA" #define D_UNIT_VA "VA"
#define D_UNIT_VAR "VAr" #define D_UNIT_VAR "VAr"
#define D_UNIT_VOLT "В" #define D_UNIT_VOLT "V"
#define D_UNIT_WATT "Вт" #define D_UNIT_WATT "W"
#define D_UNIT_WATTHOUR "Вт/ч" #define D_UNIT_WATTHOUR "Wh"
// Log message prefix // Log message prefix
#define D_LOG_APPLICATION "APP: " // Application #define D_LOG_APPLICATION "APP: " // Application

View File

@ -28,7 +28,7 @@
* Use online command StateText to translate ON, OFF, HOLD and TOGGLE. * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
* Use online command Prefix to translate cmnd, stat and tele. * Use online command Prefix to translate cmnd, stat and tele.
* *
* Updated until v5.13.1a * Updated until v5.13.1c
\*********************************************************************/ \*********************************************************************/
//#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English) //#define LANGUAGE_MODULE_NAME // Enable to display "Module Generic" (ie Spanish), Disable to display "Generic Module" (ie English)
@ -121,9 +121,9 @@
#define D_PORT "Poort" #define D_PORT "Poort"
#define D_POWER_FACTOR "Arbeidsfactor" #define D_POWER_FACTOR "Arbeidsfactor"
#define D_POWERUSAGE "Vermogen" #define D_POWERUSAGE "Vermogen"
#define D_POWERUSAGE_ACTIVE "Active Power" #define D_POWERUSAGE_ACTIVE "Werkelijk vermogen"
#define D_POWERUSAGE_APPARENT "Apparent Power" #define D_POWERUSAGE_APPARENT "Schijnbaar vermogen"
#define D_POWERUSAGE_REACTIVE "Reactive Power" #define D_POWERUSAGE_REACTIVE "Blindvermogen"
#define D_PRESSURE "Luchtdruk" #define D_PRESSURE "Luchtdruk"
#define D_PRESSUREATSEALEVEL "ZeeLuchtdruk" #define D_PRESSUREATSEALEVEL "ZeeLuchtdruk"
#define D_PROGRAM_FLASH_SIZE "Programma Flash Grootte" #define D_PROGRAM_FLASH_SIZE "Programma Flash Grootte"

View File

@ -455,7 +455,7 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
char *blcommand = strtok(dataBuf, ";"); char *blcommand = strtok(dataBuf, ";");
while ((blcommand != NULL) && (backlog_index != bl_pointer)) { while ((blcommand != NULL) && (backlog_index != bl_pointer)) {
while(true) { while(true) {
while ((*blcommand != '\0') && (isblank(*blcommand))) { blcommand++; } // Trim leading spaces blcommand = LTrim(blcommand);
if (!strncasecmp_P(blcommand, PSTR(D_CMND_BACKLOG), strlen(D_CMND_BACKLOG))) { if (!strncasecmp_P(blcommand, PSTR(D_CMND_BACKLOG), strlen(D_CMND_BACKLOG))) {
blcommand += strlen(D_CMND_BACKLOG); // Skip unnecessary command Backlog blcommand += strlen(D_CMND_BACKLOG); // Skip unnecessary command Backlog
} else { } else {
@ -1052,19 +1052,26 @@ void MqttDataHandler(char* topic, byte* data, unsigned int data_len)
uint8_t ts = 0; uint8_t ts = 0;
if (CMND_TIMEDST == command_code) { ts = 1; } if (CMND_TIMEDST == command_code) { ts = 1; }
if (data_len > 0) { if (data_len > 0) {
if (strstr(dataBuf, ",")) { // Parameter entry if (strstr(dataBuf, ",")) { // Process parameter entry
uint8_t tpos = 0; uint8_t tpos = 0; // Parameter index
int value = strtol(dataBuf, &p, 10); int value = 0;
p = dataBuf; // Parameters like "1, 2,3 , 4 ,5, -120" or ",,,,,+240"
char *q = p; // Value entered flag
while (p && (tpos < 7)) { while (p && (tpos < 7)) {
tpos++; if (p > q) { // Any value entered
if (1 == tpos) { Settings.tflag[ts].hemis = value &1; } if (1 == tpos) { Settings.tflag[ts].hemis = value &1; }
if (2 == tpos) { Settings.tflag[ts].week = (value < 0) ? 0 : (value > 4) ? 4 : value; } if (2 == tpos) { Settings.tflag[ts].week = (value < 0) ? 0 : (value > 4) ? 4 : value; }
if (3 == tpos) { Settings.tflag[ts].month = (value < 1) ? 1 : (value > 12) ? 12 : value; } if (3 == tpos) { Settings.tflag[ts].month = (value < 1) ? 1 : (value > 12) ? 12 : value; }
if (4 == tpos) { Settings.tflag[ts].dow = (value < 1) ? 1 : (value > 7) ? 7 : value; } if (4 == tpos) { Settings.tflag[ts].dow = (value < 1) ? 1 : (value > 7) ? 7 : value; }
if (5 == tpos) { Settings.tflag[ts].hour = (value < 0) ? 0 : (value > 23) ? 23 : value; } if (5 == tpos) { Settings.tflag[ts].hour = (value < 0) ? 0 : (value > 23) ? 23 : value; }
if (6 == tpos) { Settings.toffset[ts] = (value < -900) ? -900 : (value > 900) ? 900 : value; } if (6 == tpos) { Settings.toffset[ts] = (value < -900) ? -900 : (value > 900) ? 900 : value; }
p++; // Skip comma }
p = LTrim(p); // Skip spaces
if (tpos && (*p == ',')) { p++; } // Skip separator
p = LTrim(p); // Skip spaces
q = p; // Reset any value entered flag
value = strtol(p, &p, 10); value = strtol(p, &p, 10);
tpos++; // Next parameter
} }
ntp_force_sync = 1; ntp_force_sync = 1;
} else { } else {

View File

@ -236,6 +236,14 @@ char* UpperCase_P(char* dest, const char* source)
return dest; return dest;
} }
char* LTrim(char* p)
{
while ((*p != '\0') && (isblank(*p))) {
p++; // Trim leading spaces
}
return p;
}
char* NoAlNumToUnderscore(char* dest, const char* source) char* NoAlNumToUnderscore(char* dest, const char* source)
{ {
char* write = dest; char* write = dest;

View File

@ -130,20 +130,20 @@
#define NTP_SERVER3 "0.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (93.94.224.67) #define NTP_SERVER3 "0.nl.pool.ntp.org" // [NtpServer3] Select third NTP server by name or IP address (93.94.224.67)
// -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes // -- Time - Start Daylight Saving Time and timezone offset from UTC in minutes
#define TIME_DST_HEMISPHERE North // Northern Hemisphere #define TIME_DST_HEMISPHERE North // [TimeDst] Hemisphere (0 or North, 1 or South)
#define TIME_DST_WEEK Last #define TIME_DST_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth)
#define TIME_DST_DAY Sun #define TIME_DST_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat)
#define TIME_DST_MONTH Mar // Last sunday in march #define TIME_DST_MONTH Mar // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec)
#define TIME_DST_HOUR 2 // at 02:00 #define TIME_DST_HOUR 2 // Hour (0 to 23)
#define TIME_DST_OFFSET +120 // +120 minutes #define TIME_DST_OFFSET +120 // Offset from UTC in minutes (-780 to +780)
// -- Time - Start Standard Time and timezone offset from UTC in minutes // -- Time - Start Standard Time and timezone offset from UTC in minutes
#define TIME_STD_HEMISPHERE North // Northern Hemisphere #define TIME_STD_HEMISPHERE North // [TimeStd] Hemisphere (0 or North, 1 or South)
#define TIME_STD_WEEK Last #define TIME_STD_WEEK Last // Week of month (0 or Last, 1 or First, 2 or Second, 3 or Third, 4 or Fourth)
#define TIME_STD_DAY Sun #define TIME_STD_DAY Sun // Day of week (1 or Sun, 2 or Mon, 3 or Tue, 4 or Wed, 5 or Thu, 6 or Fri, 7 or Sat)
#define TIME_STD_MONTH Oct // Last sunday in october #define TIME_STD_MONTH Oct // Month (1 or Jan, 2 or Feb, 3 or Mar, 4 or Apr, 5 or May, 6 or Jun, 7 or Jul, 8 or Aug, 9 or Sep, 10 or Oct, 11 or Nov, 12 or Dec)
#define TIME_STD_HOUR 3 // at 03:00 #define TIME_STD_HOUR 3 // Hour (0 to 23)
#define TIME_STD_OFFSET +60 // +60 minutes #define TIME_STD_OFFSET +60 // Offset from UTC in minutes (-780 to +780)
// -- Location ------------------------------------ // -- Location ------------------------------------
#define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset #define LATITUDE 48.858360 // [Latitude] Your location to be used with sunrise and sunset
@ -291,7 +291,7 @@
#define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code) #define USE_NOVA_SDS // Add support for SDS011 and SDS021 particle concentration sensor (+0k7 code)
#define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code) #define USE_PZEM004T // Add support for PZEM004T Energy monitor (+2k code)
#define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code) #define USE_SERIAL_BRIDGE // Add support for software Serial Bridge (+0k8 code)
#define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k2 code) #define USE_SDM120 // Add support for Eastron SDM120-Modbus energy meter (+1k7 code)
#define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud) #define SDM120_SPEED 9600 // SDM120-Modbus RS485 serial speed (default: 2400 baud)
// -- Low level interface devices ----------------- // -- Low level interface devices -----------------

View File

@ -41,12 +41,12 @@ float sdm120_power_factor = 0;
float sdm120_frequency = 0; float sdm120_frequency = 0;
float sdm120_energy_total = 0; float sdm120_energy_total = 0;
bool SDM_ModbusReceiveReady() bool SDM120_ModbusReceiveReady()
{ {
return (SDM120Serial->available() > 1); return (SDM120Serial->available() > 1);
} }
void SDM_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count) void SDM120_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t register_count)
{ {
uint8_t frame[8]; uint8_t frame[8];
@ -57,7 +57,7 @@ void SDM_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t regi
frame[4] = (uint8_t)(register_count >> 8); frame[4] = (uint8_t)(register_count >> 8);
frame[5] = (uint8_t)(register_count); frame[5] = (uint8_t)(register_count);
uint16_t crc = SDM_calculateCRC(frame, 6); // calculate out crc only from first 6 bytes uint16_t crc = SDM120_calculateCRC(frame, 6); // calculate out crc only from first 6 bytes
frame[6] = lowByte(crc); frame[6] = lowByte(crc);
frame[7] = highByte(crc); frame[7] = highByte(crc);
@ -69,7 +69,7 @@ void SDM_ModbusSend(uint8_t function_code, uint16_t start_address, uint16_t regi
SDM120Serial->write(frame, sizeof(frame)); SDM120Serial->write(frame, sizeof(frame));
} }
uint8_t SDM_ModbusReceive(float *value) uint8_t SDM120_ModbusReceive(float *value)
{ {
uint8_t buffer[9]; uint8_t buffer[9];
@ -86,7 +86,7 @@ uint8_t SDM_ModbusReceive(float *value)
if (buffer[0] == 0x01 && buffer[1] == 0x04 && buffer[2] == 4) { // check node number, op code and reply bytes count if (buffer[0] == 0x01 && buffer[1] == 0x04 && buffer[2] == 4) { // check node number, op code and reply bytes count
if((SDM_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) { //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8) if((SDM120_calculateCRC(buffer, 7)) == ((buffer[8] << 8) | buffer[7])) { //calculate crc from first 7 bytes and compare with received crc (bytes 7 & 8)
((uint8_t*)value)[3] = buffer[3]; ((uint8_t*)value)[3] = buffer[3];
((uint8_t*)value)[2] = buffer[4]; ((uint8_t*)value)[2] = buffer[4];
@ -101,7 +101,7 @@ uint8_t SDM_ModbusReceive(float *value)
return 0; // SDM_ERR_NO_ERROR return 0; // SDM_ERR_NO_ERROR
} }
uint16_t SDM_calculateCRC(uint8_t *frame, uint8_t num) uint16_t SDM120_calculateCRC(uint8_t *frame, uint8_t num)
{ {
uint16_t crc, flag; uint16_t crc, flag;
crc = 0xFFFF; crc = 0xFFFF;
@ -121,7 +121,7 @@ uint16_t SDM_calculateCRC(uint8_t *frame, uint8_t num)
/*********************************************************************************************/ /*********************************************************************************************/
const uint16_t sdm_start_addresses[] { const uint16_t sdm120_start_addresses[] {
0x0000, // SDM120C_VOLTAGE [V] 0x0000, // SDM120C_VOLTAGE [V]
0x0006, // SDM120C_CURRENT [A] 0x0006, // SDM120C_CURRENT [A]
0x000C, // SDM120C_POWER [W] 0x000C, // SDM120C_POWER [W]
@ -129,8 +129,6 @@ const uint16_t sdm_start_addresses[] {
0x0018, // SDM120C_REACTIVE_POWER [VAR] 0x0018, // SDM120C_REACTIVE_POWER [VAR]
0x001E, // SDM120C_POWER_FACTOR 0x001E, // SDM120C_POWER_FACTOR
0x0046, // SDM120C_FREQUENCY [Hz] 0x0046, // SDM120C_FREQUENCY [Hz]
0x0048, // SDM120C_IMPORT_ACTIVE_ENERGY [Wh]
0x004A, // SDM120C_EXPORT_ACTIVE_ENERGY [Wh]
0x0156 // SDM120C_TOTAL_ACTIVE_ENERGY [Wh] 0x0156 // SDM120C_TOTAL_ACTIVE_ENERGY [Wh]
}; };
@ -144,10 +142,10 @@ void SDM12050ms() // Every 50 mSec
sdm120_state = 0; sdm120_state = 0;
float value = 0; float value = 0;
bool data_ready = SDM_ModbusReceiveReady(); bool data_ready = SDM120_ModbusReceiveReady();
if (data_ready) { if (data_ready) {
uint8_t error = SDM_ModbusReceive(&value); uint8_t error = SDM120_ModbusReceive(&value);
if (error) { if (error) {
snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SDM120 response error %d"), error); snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_DEBUG "SDM120 response error %d"), error);
AddLog(LOG_LEVEL_DEBUG); AddLog(LOG_LEVEL_DEBUG);
@ -181,14 +179,14 @@ void SDM12050ms() // Every 50 mSec
sdm120_frequency = value; sdm120_frequency = value;
break; break;
case 9: case 7:
sdm120_energy_total = value; sdm120_energy_total = value;
break; break;
} // end switch } // end switch
sdm120_read_state++; sdm120_read_state++;
if (sizeof(sdm_start_addresses)/2 == sdm120_read_state) { if (sizeof(sdm120_start_addresses)/2 == sdm120_read_state) {
sdm120_read_state = 0; sdm120_read_state = 0;
} }
} }
@ -196,7 +194,7 @@ void SDM12050ms() // Every 50 mSec
if (0 == sdm120_send_retry || data_ready) { if (0 == sdm120_send_retry || data_ready) {
sdm120_send_retry = 5; sdm120_send_retry = 5;
SDM_ModbusSend(0x04, sdm_start_addresses[sdm120_read_state], 2); SDM120_ModbusSend(0x04, sdm120_start_addresses[sdm120_read_state], 2);
} else { } else {
sdm120_send_retry--; sdm120_send_retry--;
} }
@ -300,4 +298,3 @@ boolean Xsns23(byte function)
} }
#endif // USE_SDM120 #endif // USE_SDM120