diff --git a/README.md b/README.md
index e8ab14f11..fca1f5af6 100644
--- a/README.md
+++ b/README.md
@@ -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.6.1h** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
+Current version is **5.6.1i** - See [sonoff/_releasenotes.ino](https://github.com/arendst/Sonoff-Tasmota/blob/development/sonoff/_releasenotes.ino) for change information.
 
 ### ATTENTION All versions
 
@@ -55,5 +55,5 @@ The following devices are supported:
 - [iTead Motor Clockwise/Anticlockwise](https://www.itead.cc/smart-home/motor-reversing-wifi-wireless-switch.html)
 - [Electrodragon IoT Relay Board](http://www.electrodragon.com/product/wifi-iot-relay-board-based-esp8266/)
 
-<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonofftoucheu.jpg" height="280" align="left" /> 
-<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff4ch.jpg" height="250" align="right" /> 
+<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonofftoucheu.jpg" height="280" align="left" />
+<img src="https://github.com/arendst/arendst.github.io/blob/master/media/sonoff4ch.jpg" height="250" align="right" />
diff --git a/sonoff/_releasenotes.ino b/sonoff/_releasenotes.ino
index b2a269e77..669d4e3c5 100644
--- a/sonoff/_releasenotes.ino
+++ b/sonoff/_releasenotes.ino
@@ -1,4 +1,8 @@
-/* 5.6.1h
+/* 5.6.1i
+ * Add basic internationalization and localization (#763)
+ * Fix invalid JSON (#822)
+ *
+ * 5.6.1h
  * Add PulseTime to power check at startup (#526)
  *
  * 5.6.1g
@@ -80,7 +84,7 @@
  * Fix button 1 double press behaviour on multi relay devices
  * Add support for Hua Fan Smart Socket (#479)
  * Add support for Sonoff 4ch Pro (#565)
- * Add command SetOption13 1 to allow immediate action on single button press 
+ * Add command SetOption13 1 to allow immediate action on single button press
  *   (disables multipress, hold and unrestricted commands) (#587)
  *
  * 5.3.0 20170715
@@ -111,7 +115,7 @@
  *
  * 5.2.1 20170622
  * Fix Restore Configuration in case of lower version
- * Revert auto configuration upgrade allowing easy upgrade which was removed in version 5.2.0 
+ * Revert auto configuration upgrade allowing easy upgrade which was removed in version 5.2.0
  * Fix config auto upgrade from versions below version 4.1.1 (#530)
  *
  * 5.2.0 20170619
@@ -180,7 +184,7 @@
  * Add command MqttRetry <seconds> to change default MQTT reconnect retry timer from minimal 10 seconds (#429)
  *
  * 5.0.5 20170508
- * Add command FullTopic with tokens %topic% (replaced by command Topic value) and 
+ * Add command FullTopic with tokens %topic% (replaced by command Topic value) and
  *  %prefix% (replaced by command Prefix<x> values) for more flexible topic definitions (#244)
  *  See wiki > MQTT Features https://github.com/arendst/Sonoff-Tasmota/wiki/MQTT-Features for more information
  *
@@ -255,7 +259,7 @@
  * Remove restart after IPAddress changes (#292)
  * Add support for MAX31850 in xsns_ds18x20.ino (#295)
  * Fix possible uptime update misses (#302)
- * 
+ *
  * 4.1.0 20170325
  * Change static IP addresses in user_config.h from list (using commas) to string (using dots)
  * Unify display result of commands Modules, Module and Gpios
@@ -354,7 +358,7 @@
  * 3.9.20 20170221
  * Add minimal basic authentication to Web Admin mode (#87)
  * Fix Hue and add HSB support (#89)
- * 
+ *
  * 3.9.19 20170219
  * Sonoff Led: Made GPIO04, 05 and 15 available for user
  * Sonoff Led: Add commands Fade, Speed, WakupDuration, Wakeup and LedTable
@@ -364,7 +368,7 @@
  * Fix Sonoff Led dimmer range (#16)
  * Change Sonoff Led command Dimmer to act on both cold and warm color
  * Add Sonoff Led command Color CCWW where CCWW are hexadecimal values fro 00 - FF
- * Reduce Sonoff Led flickering by disabling interrupts during flash save and disabling 
+ * Reduce Sonoff Led flickering by disabling interrupts during flash save and disabling
  *   Led during OTA upgrade and Web upload (#16)
  *
  * 3.9.17 20170217
@@ -435,7 +439,7 @@
  *
  * 3.9.3 20170127
  * Add confirmation before Restart via webpage
- * Expand Domoticz Configuration webpage with Key, Switch and Sensor Index and 
+ * Expand Domoticz Configuration webpage with Key, Switch and Sensor Index and
  *   add commands DomoticzSwitchIdx and DomoticzSensorIdx (#86) (#174) (#219)
  * Fix default DHT11 sensor driver selection
  * Fix LedPower status after button press (#279)
@@ -498,7 +502,7 @@
  * Add friendlyname to webpage replacing former hostname
  *
  * 3.1.15 20170108
- * Fix Domoticz send key regression with Toggle command  
+ * Fix Domoticz send key regression with Toggle command
  *
  * 3.1.14 20170107
  * Add support for command TOGGLE (define MQTT_CMND_TOGGLE) when ButtonTopic is in use and not equal to Topic (#207)
diff --git a/sonoff/i18n.h b/sonoff/i18n.h
new file mode 100644
index 000000000..6685662d0
--- /dev/null
+++ b/sonoff/i18n.h
@@ -0,0 +1,80 @@
+/*
+  i18n.h - internationalization 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/>.
+*/
+
+#ifndef LANGUAGE
+  #define LANGUAGE "language\en-GB.h"
+#endif
+#include LANGUAGE
+
+// Common
+
+const char S_LOG_HTTP[] PROGMEM = D_LOG_HTTP;
+const char S_LOG_WIFI[] PROGMEM = D_LOG_WIFI;
+const char S_LOG_MQTT[] PROGMEM = D_LOG_MQTT;
+
+const char S_RSLT_POWER[] PROGMEM = D_RSLT_POWER;
+const char S_RSLT_RESULT[] PROGMEM = D_RSLT_RESULT;
+const char S_RSLT_WARNING[] PROGMEM = D_RSLT_WARNING;
+
+const char S_LWT[] PROGMEM = D_LWT;
+const char S_OFFLINE[] PROGMEM = D_OFFLINE;
+
+// sonoff.ino
+
+#define MAX_BUTTON_COMMANDS  5  // Max number of button commands supported
+const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = {
+  D_CMND_WIFICONFIG " 1",   // Press button three times
+  D_CMND_WIFICONFIG " 2",   // Press button four times
+  D_CMND_WIFICONFIG " 3",   // Press button five times
+  D_CMND_RESTART " 1",      // Press button six times
+  D_CMND_UPGRADE " 1" };    // Press button seven times
+const char wificfg[5][WCFG_MAX_STRING_LENGTH] PROGMEM = {
+  D_WCFG_0_RESTART,
+  D_WCFG_1_SMARTCONFIG,
+  D_WCFG_2_WIFIMANAGER,
+  D_WCFG_3_WPSCONFIG,
+  D_WCFG_4_RETRY };
+const char PREFIXES[3][PRFX_MAX_STRING_LENGTH] PROGMEM = {
+  D_CMND,
+  D_STAT,
+  D_TELE };
+
+const char JSON_SNS_TEMPHUM[] PROGMEM =
+  "%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s}";
+
+// support.ino
+
+static const char monthNames[] = D_MONTH3LIST;
+
+// webserver.ino
+const char S_MAIN_MENU[] PROGMEM = D_MAIN_MENU;
+const char S_CONFIGURATION[] PROGMEM = D_CONFIGURATION;
+const char S_CONFIGURE_MODULE[] PROGMEM = D_CONFIGURE_MODULE;
+const char S_CONFIGURE_WIFI[] PROGMEM = D_CONFIGURE_WIFI;
+const char S_NO_NETWORKS_FOUND[] PROGMEM = D_NO_NETWORKS_FOUND;
+const char S_CONFIGURE_MQTT[] PROGMEM = D_CONFIGURE_MQTT;
+const char S_CONFIGURE_LOGGING[] PROGMEM = D_CONFIGURE_LOGGING;
+const char S_CONFIGURE_OTHER[] PROGMEM = D_CONFIGURE_OTHER;
+const char S_SAVE_CONFIGURATION[] PROGMEM = D_SAVE_CONFIGURATION;
+const char S_RESET_CONFIGURATION[] PROGMEM = D_RESET_CONFIGURATION;
+const char S_RESTORE_CONFIGURATION[] PROGMEM = D_RESTORE_CONFIGURATION;
+const char S_FIRMWARE_UPGRADE[] PROGMEM = D_FIRMWARE_UPGRADE;
+const char S_CONSOLE[] PROGMEM = D_CONSOLE;
+const char S_INFORMATION[] PROGMEM = D_INFORMATION;
+const char S_RESTART[] PROGMEM = D_RESTART;
diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h
new file mode 100644
index 000000000..dedb22a3b
--- /dev/null
+++ b/sonoff/language/en-GB.h
@@ -0,0 +1,665 @@
+/*
+  en-GB.h - localization for English - United Kingdom 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/>.
+*/
+
+/*************************** ATTENTION *******************************\
+ *
+ * Due to memory constraints only UTF-8 is supported.
+ * Time and Date provided by SDK can not be localized (yet).
+ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
+ * Use online command Prefix to translate cmnd, stat and tele.
+ *
+\*********************************************************************/
+
+// "2017-03-07T11:08:02" - ISO8601:2004
+#define D_YEAR_MONTH_SEPARATOR "-"
+#define D_MONTH_DAY_SEPARATOR "-"
+#define D_DATE_TIME_SEPARATOR "T"
+#define D_HOUR_MINUTE_SEPARATOR ":"
+#define D_MINUTE_SECOND_SEPARATOR ":"
+
+#define D_DAY3LIST "SunMonTueWedThuFriSat"
+#define D_MONTH3LIST "JanFebMarAprMayJunJulAugSepOctNovDec"
+
+// Non JSON decimal separator
+#define D_DECIMAL_SEPARATOR "."
+
+// Common
+#define D_ABORTED "Aborted"
+#define D_ACTIVE "Active"
+#define D_ADDRESS "Address"
+#define D_ADMIN "Admin"
+#define D_AIR_QUALITY "Air quality"
+#define D_AIRQUALITY "AirQuality"
+#define D_AP "AP"                    // Access Point
+#define D_APMAC_ADDRESS "APMac"
+#define D_APPENDED "Appended"
+#define D_AS "as"
+#define D_AUTO "AUTO"
+#define D_BAUDRATE "Baudrate"
+#define D_BLINK "Blink"
+#define D_BLINKOFF "BlinkOff"
+#define D_BOOTVERSION "Boot"
+#define D_BOOT_COUNT "Boot Count"
+#define D_BOOTCOUNT "BootCount"
+#define D_BRIGHTLIGHT "Bright"
+#define D_BUILDDATETIME "BuildDateTime"
+#define D_BUTTON "Button"
+#define D_CELSIUS "Celsius"
+#define D_CODE "code"                // Button code
+#define D_COLDLIGHT "Cold"
+#define D_COMMAND "Command"
+#define D_CONNECTED "Connected"
+#define D_COREVERSION "Core"
+#define D_COUNT "Count"
+#define D_COUNTER "Counter"
+#define D_CURRENT "Current"          // As in Voltage and Current
+#define D_DATA "Data"
+#define D_DARKLIGHT "Dark"
+#define D_DEBUG "Debug"
+#define D_DISABLED "Disabled"
+#define D_DNS_SERVER "DNS Server"
+#define D_DNSSERVER "DNSServer"
+#define D_DONE "Done"
+#define D_DST_TIME "DST"
+#define D_EMPTY "Empty"
+#define D_EMULATION "Emulation"
+#define D_ENABLED "Enabled"
+#define D_ENDDST "EndDST"           // End Daylight Savings Time
+#define D_ERASE "Erase"
+#define D_ERROR "Error"
+#define D_EVERY "Every"
+#define D_FAHRENHEIT "Fahrenheit"
+#define D_FAILED "Failed"
+#define D_FALLBACK "Fallback"
+#define D_FALLBACK_TOPIC "Fallback Topic"
+#define D_FALLBACKTOPIC "FallbackTopic"
+#define D_FALSE "False"
+#define D_FILE "File"
+#define D_FLASHMODE "FlashMode"
+#define D_FLASHSIZE "FlashSize"
+#define D_FREE_MEMORY "Free Memory"
+#define D_FREEMEMORY "Free"
+#define D_FROM "from"
+#define D_GATEWAY "Gateway"
+#define D_GROUP "Group"
+#define D_HEAPSIZE "Heap"
+#define D_HIGH "High"
+#define D_HOST "Host"
+#define D_HOSTNAME "Hostname"
+#define D_HUMIDITY "Humidity"
+#define D_ILLUMINANCE "Illuminance"
+#define D_IMMEDIATE "immediate"      // Button immediate
+#define D_INDEX "Index"
+#define D_INFO "Info"
+#define D_INITIALIZED "Initialized"
+#define D_IP_ADDRESS "IP Address"
+#define D_LIGHT "Light"
+#define D_LOCAL_TIME "Local"
+#define D_LOW "Low"
+#define D_LWT "LWT"
+#define D_MAC "Mac"
+#define D_MASK "Mask"
+#define D_MODULE "Module"
+#define D_MQTT "MQTT"
+#define D_MULTI_PRESS "multi-press"
+#define D_NO "No"
+#define D_NOISE "Noise"
+#define D_NONE "None"
+#define D_OFF "Off"
+#define D_OFFLINE "Offline"
+#define D_OK "Ok"
+#define D_ON "On"
+#define D_ONLINE "Online"
+#define D_OR "or"
+#define D_PASSWORD "Password"
+#define D_PERIOD "Period"
+#define D_PORT "Port"
+#define D_POWER_FACTOR "Power Factor"
+#define D_POWERFACTOR "Factor"
+#define D_POWERUSAGE "Power"
+#define D_PRESSURE "Pressure"
+#define D_PROGRAM_FLASH_SIZE "Program Flash Size"
+#define D_PROGRAMFLASHSIZE "ProgramFlashSize"
+#define D_PROGRAM_SIZE "Program Size"
+#define D_PROGRAMSIZE "ProgramSize"
+#define D_PROJECT "Project"
+#define D_RECEIVED "Received"
+#define D_RESTART "Restart"
+#define D_RESTARTING "Restarting"
+#define D_RESTART_REASON "Restart Reason"
+#define D_RESTARTREASON "RestartReason"
+#define D_RESTORE "restore"
+#define D_RETAINED "retained"
+#define D_SAVE "Save"
+#define D_SAVEADDRESS "SaveAddress"
+#define D_SAVECOUNT "SaveCount"
+#define D_SAVESTATE "SaveState"
+#define D_SDKVERSION "SDK"
+#define D_SELECTED "selected"
+#define D_SENSOR "Sensor"
+#define D_SERIAL "Serial"
+#define D_BYTES "Bytes"
+#define D_SSID "SSId"
+#define D_START "Start"
+#define D_STARTED "Started"
+#define D_STARTDST "StartDST"        // Start Daylight Savings Time
+#define D_STD_TIME "STD"
+#define D_STOP "Stop"
+#define D_SUBNET_MASK "Subnet Mask"
+#define D_SUBNETMASK "Subnetmask"
+#define D_SUCCESSFUL "Successful"
+#define D_SWITCH "Switch"
+#define D_SYNC "Sync"
+#define D_SYS "Sys"                  // Sys log
+#define D_TEMPERATURE "Temperature"
+#define D_TEMPERATURE_UNIT "TempUnit"
+#define D_TIME "Time"
+#define D_TO "to"
+#define D_TODAY "Today"
+#define D_TOGGLE "Toggle"
+#define D_TOPIC "Topic"
+#define D_TOTAL "Total"
+#define D_TRUE "True"
+#define D_TYPE "Type"
+#define D_UNKNOWN "Unknown"
+#define D_UPGRADE "upgrade"
+#define D_UPLOAD "Upload"
+#define D_UPTIME "Uptime"
+#define D_UTC_TIME "UTC"
+#define D_USER "User"
+#define D_VCC "Vcc"
+#define D_VERSION "Version"
+#define D_VOLTAGE "Voltage"
+#define D_WARMLIGHT "Warm"
+#define D_WEB "Web"                  // Web log
+#define D_WEB_SERVER "Web Server"
+#define D_WIFI "Wifi"
+#define D_WRONG "Wrong"
+#define D_YESTERDAY "Yesterday"
+
+// settings.ino
+#define D_SAVED_TO_FLASH_AT "Saved to flash at"
+#define D_LOADED_FROM_FLASH_AT "Loaded from flash at"
+#define D_USE_DEFAULTS "Use defaults"
+#define D_ERASED_SECTOR "Erased sector"
+
+// sonoff.ino
+#define D_LEVEL_10 "level 1-0"
+#define D_LEVEL_01 "level 0-1"
+#define D_SERIAL_LOGGING_DISABLED "Serial logging disabled"
+#define D_SYSLOG_LOGGING_REENABLED "Syslog logging re-enabled"
+
+#define D_SET_BAUDRATE_TO "Set Baudrate to"
+#define D_RECEIVED_TOPIC "Received Topic"
+#define D_DATA_SIZE "Data Size"
+#define D_ANALOG_INPUT0 "Analog0"
+
+#define D_FINGERPRINT "Verify TLS fingerprint..."
+#define D_TLS_CONNECT_FAILED_TO "TLS Connect failed to"
+#define D_RETRY_IN "Retry in"
+#define D_VERIFIED "Verified"
+#define D_INSECURE "Insecure connection due to invalid Fingerprint"
+#define D_CONNECT_FAILED_TO "Connect failed to"
+
+// support.ino
+#define D_OSWATCH "osWatch"
+#define D_BLOCKED_LOOP "Blocked Loop"
+#define D_WPS_FAILED_WITH_STATUS "WPSconfig FAILED with status"
+#define D_ACTIVE_FOR_1_MINUTE "active for 1 minute"
+#define D_FAILED_TO_START "failed to start"
+#define D_PATCH_ISSUE_2186 "Patch issue 2186"
+#define D_CONNECTING_TO_AP "Connecting to AP"
+#define D_IN_MODE "in mode"
+#define D_CONNECT_FAILED_NO_IP_ADDRESS "Connect failed as no IP address received"
+#define D_CONNECT_FAILED_AP_NOT_REACHED "Connect failed as AP cannot be reached"
+#define D_CONNECT_FAILED_WRONG_PASSWORD "Connect failed with AP incorrect password"
+#define D_CONNECT_FAILED_AP_TIMEOUT "Connect failed with AP timeout"
+#define D_ATTEMPTING_CONNECTION "Attempting connection..."
+#define D_CHECKING_CONNECTION "Checking connection..."
+#define D_QUERY_DONE "Query done. MQTT services found"
+#define D_MQTT_SERVICE_FOUND "MQTT service found on"
+#define D_I2CSCAN_DEVICES_FOUND_AT "Device(s) found at"
+#define D_FOUND_AT "found at"
+#define D_I2CSCAN_UNKNOWN_ERROR_AT "Unknown error at"
+#define D_I2CSCAN_NO_DEVICES_FOUND "No devices found"
+#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host not found"
+
+// webserver.ino
+#define D_WEBSERVER_ACTIVE_ON "Web server active on"
+#define D_WITH_IP_ADDRESS "with IP address"
+#define D_WEBSERVER_STOPPED "Web server stopped"
+#define D_FILE_NOT_FOUND "File Not Found"
+#define D_REDIRECTED "Redirected to captive portal"
+#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager set AccessPoint and keep Station"
+#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager set AccessPoint"
+#define D_TRYING_TO_CONNECT "Trying to connect device to network"
+
+#define D_RESTART_IN "Restart in"
+#define D_SECONDS "seconds"
+#define D_DEVICE_WILL_RESTART "Device will restart in a few seconds"
+#define D_BUTTON_TOGGLE "Toggle"
+#define D_CONFIGURATION "Configuration"
+#define D_INFORMATION "Information"
+#define D_FIRMWARE_UPGRADE "Firmware Upgrade"
+#define D_CONSOLE "Console"
+#define D_CONFIRM_RESTART "Confirm Restart"
+
+#define D_CONFIGURE_MODULE "Configure Module"
+#define D_CONFIGURE_WIFI "Configure WiFi"
+#define D_CONFIGURE_MQTT "Configure MQTT"
+#define D_CONFIGURE_DOMOTICZ "Configure Domoticz"
+#define D_CONFIGURE_LOGGING "Configure Logging"
+#define D_CONFIGURE_OTHER "Configure Other"
+#define D_CONFIRM_RESET_CONFIGURATION "Confirm Reset Configuration"
+#define D_RESET_CONFIGURATION "Reset Configuration"
+#define D_BACKUP_CONFIGURATION "Backup Configuration"
+#define D_RESTORE_CONFIGURATION "Restore Configuration"
+#define D_MAIN_MENU "Main Menu"
+
+#define D_MODULE_PARAMETERS "Module parameters"
+#define D_MODULE_TYPE "Module type"
+#define D_GPIO "GPIO"
+#define D_SERIAL_IN "Serial In"
+#define D_SERIAL_OUT "Serial Out"
+
+#define D_WIFI_PARAMETERS "Wifi parameters"
+#define D_SCAN_FOR_WIFI_NETWORKS "Scan for wifi networks"
+#define D_SCAN_DONE "Scan done"
+#define D_NO_NETWORKS_FOUND "No networks found"
+#define D_REFRESH_TO_SCAN_AGAIN "Refresh to scan again"
+#define D_DUPLICATE_ACCESSPOINT "Duplicate AccessPoint"
+#define D_SKIPPING_LOW_QUALITY "Skipping due to low quality"
+#define D_RSSI "RSSI"
+#define D_WEP "WEP"
+#define D_WPA_PSK "WPA PSK"
+#define D_WPA2_PSK "WPA2 PSK"
+#define D_AP1_SSID "AP1 SSId"
+#define D_AP1_PASSWORD "AP1 Password"
+#define D_AP2_SSID "AP2 SSId"
+#define D_AP2_PASSWORD "AP2 Password"
+
+#define D_MQTT_PARAMETERS "MQTT parameters"
+#define D_CLIENT "Client"
+#define D_FULL_TOPIC "Full Topic"
+
+#define D_LOGGING_PARAMETERS "Logging parameters"
+#define D_LOG_LEVEL "log level"
+#define D_MORE_DEBUG "More debug"
+#define D_SYSLOG_HOST "Syslog host"
+#define D_SYSLOG_PORT "Syslog port"
+#define D_TELEMETRY_PERIOD "Telemetry period"
+
+#define D_OTHER_PARAMETERS "Other parameters"
+#define D_WEB_ADMIN_PASSWORD "Web Admin Password"
+#define D_MQTT_ENABLE "MQTT enable"
+#define D_FRIENDLY_NAME "Friendly Name"
+#define D_BELKIN_WEMO "Belkin WeMo"
+#define D_HUE_BRIDGE "Hue Bridge"
+#define D_SINGLE_DEVICE "single device"
+#define D_MULTI_DEVICE "multi device"
+
+#define D_SAVE_CONFIGURATION "Save configuration"
+#define D_CONFIGURATION_SAVED "Configuration saved"
+#define D_CONFIGURATION_RESET "Configuration reset"
+
+#define D_PROGRAM_VERSION "Program Version"
+#define D_BUILD_DATE_AND_TIME "Build Date & Time"
+#define D_CORE_AND_SDK_VERSION "Core/SDK Version"
+#define D_FLASH_WRITE_COUNT "Flash write Count"
+#define D_MAC_ADDRESS "MAC Address"
+#define D_MQTT_HOST "MQTT Host"
+#define D_MQTT_PORT "MQTT Port"
+#define D_MQTT_CLIENT "MQTT Client"
+#define D_MQTT_USER "MQTT User"
+#define D_MQTT_TOPIC "MQTT Topic"
+#define D_MQTT_GROUP_TOPIC "MQTT Group Topic"
+#define D_MQTT_FULL_TOPIC "MQTT Full Topic"
+#define D_MDNS_DISCOVERY "mDNS Discovery"
+#define D_MDNS_ADVERTISE "mDNS Advertise"
+#define D_ESP_CHIP_ID "ESP Chip Id"
+#define D_FLASH_CHIP_ID "Flash Chip Id"
+#define D_FLASH_CHIP_SIZE "Flash Size"
+#define D_FREE_PROGRAM_SPACE "Free Program Space"
+
+#define D_UPGRADE_BY_WEBSERVER "Upgrade by web server"
+#define D_OTA_URL "OTA Url"
+#define D_START_UPGRADE "Start upgrade"
+#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade by file upload"
+#define D_UPLOAD_STARTED "Upload started"
+#define D_UPGRADE_STARTED "Upgrade started"
+#define D_UPLOAD_DONE "Upload done"
+#define D_UPLOAD_ERR_1 "No file selected"
+#define D_UPLOAD_ERR_2 "Not enough space"
+#define D_UPLOAD_ERR_3 "Magic byte is not 0xE9"
+#define D_UPLOAD_ERR_4 "Program flash size is larger than real flash size"
+#define D_UPLOAD_ERR_5 "Upload buffer miscompare"
+#define D_UPLOAD_ERR_6 "Upload failed. Enable logging 3"
+#define D_UPLOAD_ERR_7 "Upload aborted"
+#define D_UPLOAD_ERR_8 "File invalid"
+#define D_UPLOAD_ERR_9 "File too large"
+#define D_UPLOAD_ERROR_CODE "Upload error code"
+
+#define D_ENTER_COMMAND "Enter command"
+#define D_ENABLE_WEBLOG_FOR_RESPONSE "Enable weblog 2 if response expected"
+#define D_NEED_USER_AND_PASSWORD "Need user=<username>&password=<password>"
+
+// xdrv_domoticz.ino
+#define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
+#define D_DOMOTICZ_IDX "Idx"
+#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"
+  #define D_DOMOTICZ_POWER_ENERGY "Power,Energy"
+  #define D_DOMOTICZ_ILLUMINANCE "Illuminance"
+  #define D_DOMOTICZ_COUNT "Count"
+#define D_DOMOTICZ_UPDATE_TIMER "Update timer"
+#define D_CONFIGURE_DOMOTICZ "Configure Domoticz"
+
+// xdrv_ir-send.ino
+#define D_INVALID_JSON "Invalid JSON"
+#define D_PROTOCOL_NOT_SUPPORTED "Protocol not supported"
+#define D_IRSEND_PROTOCOL "PROTOCOL"
+#define D_IRSEND_BITS "BITS"
+#define D_IRSEND_DATA "DATA"
+#define D_IRHVAC_VENDOR "VENDOR"
+#define D_IRHVAC_POWER "POWER"
+#define D_IRHVAC_MODE "MODE"
+#define D_IRHVAC_FANSPEED "FANSPEED"
+#define D_IRHVAC_TEMP "TEMP"
+
+// xdrv_snfbridge.ino
+#define D_RFRECEIVED "RfReceived"
+#define D_START_LEARNING "Start learning"
+#define D_SET_TO_DEFAULT "Set to default"
+#define D_DEFAULT_SENT "Default sent"
+#define D_LEARNED_SENT "Learned sent"
+#define D_LEARNING_ACTIVE "Learning active"
+#define D_LEARN_FAILED "Learn failed"
+#define D_LEARNED "Learned"
+
+// xdrv_wemohue.ino
+#define D_MULTICAST_DISABLED "Multicast disabled"
+#define D_MULTICAST_REJOINED "Multicast (re)joined"
+#define D_MULTICAST_JOIN_FAILED "Multicast join failed"
+#define D_FAILED_TO_SEND_RESPONSE "Failed to send response"
+
+#define D_WEMO "WeMo"
+#define D_WEMO_BASIC_EVENT "WeMo basic event"
+#define D_WEMO_EVENT_SERVICE "WeMo event service"
+#define D_WEMO_SETUP "WeMo setup"
+#define D_RESPONSE_SENT "Response sent"
+
+#define D_HUE "Hue"
+#define D_HUE_BRIDGE_SETUP "Hue setup"
+#define D_HUE_API_NOT_IMPLEMENTED "Hue API not implemented"
+#define D_HUE_API "Hue API"
+#define D_HUE_POST_ARGS "Hue POST args"
+#define D_3_RESPONSE_PACKETS_SENT "3 response packets sent"
+
+// xsns_dht.ino
+#define D_TIMEOUT_WAITING_FOR "Timeout waiting for"
+#define D_START_SIGNAL_LOW "start signal low"
+#define D_START_SIGNAL_HIGH "start signal high"
+#define D_PULSE "pulse"
+#define D_CHECKSUM_FAILURE "Checksum failure"
+
+// xsns_ds18b20.ino
+#define D_SENSOR_BUSY "Sensor busy"
+#define D_SENSOR_CRC_ERROR "Sensor CRC error"
+
+// xsns_hlw8012.ino
+#define D_MAXPOWERREACHED "MaxPowerReached"
+#define D_MAXPOWERREACHEDRETRY "MaxPowerReachedRetry"
+#define D_POWERMONITOR "PowerMonitor"
+#define D_ENERGYMONITOR "EnergyMonitor"
+#define D_MAXENERGYREACHED "MaxEnergyReached"
+#define D_ENERGY_TODAY "Energy Today"
+#define D_ENERGY_YESTERDAY "Energy Yesterday"
+#define D_ENERGY_TOTAL "Energy Total"
+
+// xsns_sht1x.ino
+#define D_SENSOR_DID_NOT_ACK_COMMAND "Sensor did not ACK command"
+#define D_SHT1X_FOUND "SHT1X found"
+
+// sonoff_template.h
+// Max string length is 8 characters including suffixes
+#define D_SENSOR_NONE     "None"
+#define D_SENSOR_DHT11    "DHT11"
+#define D_SENSOR_AM2301   "AM2301"
+#define D_SENSOR_DHT22    "DHT22"
+#define D_SENSOR_DS18X20  "DS18x20"
+#define D_SENSOR_I2C_SCL  "I2C SCL"
+#define D_SENSOR_I2C_SDA  "I2C SDA"
+#define D_SENSOR_WS2812   "WS2812"
+#define D_SENSOR_IRREMOTE "IRremote"
+#define D_SENSOR_SWITCH   "Switch"   // Suffix "1"
+#define D_SENSOR_BUTTON   "Button"   // Suffix "1"
+#define D_SENSOR_RELAY    "Relay"    // Suffix "1I"
+#define D_SENSOR_LED      "Led"      // Suffix "1I"
+#define D_SENSOR_PWM      "PWM"      // Suffix "1"
+#define D_SENSOR_COUNTER  "Counter"  // Suffix "1"
+
+// Units
+#define D_UNIT_AMPERE "A"
+#define D_UNIT_HOUR "Hr"
+#define D_UNIT_KILOWATTHOUR "kWh"
+#define D_UNIT_MICROSECOND "us"
+#define D_UNIT_MILLIAMPERE "mA"
+#define D_UNIT_MILLISECOND "ms"
+#define D_UNIT_MINUTE "Min"
+#define D_UNIT_PRESSURE "hPa"
+#define D_UNIT_SECOND "sec"
+#define D_UNIT_SECTORS "sectors"
+#define D_UNIT_VOLT "V"
+#define D_UNIT_WATT "W"
+#define D_UNIT_WATTHOUR "Wh"
+
+// Log message prefix
+#define D_LOG_APPLICATION "APP: "
+#define D_LOG_BRIDGE "BRG: "
+#define D_LOG_CONFIG "CFG: "
+#define D_LOG_COMMAND "CND: "
+#define D_LOG_DHT "DHT: "
+#define D_LOG_DOMOTICZ "DOM: "
+#define D_LOG_DSB "DSB: "
+#define D_LOG_HTTP "HTP: "
+#define D_LOG_I2C "I2C: "
+#define D_LOG_LOG "LOG: "
+#define D_LOG_MODULE "MOD: "
+#define D_LOG_MDNS "DNS: "
+#define D_LOG_MQTT "MQT: "
+#define D_LOG_OTHER "OTH: "
+#define D_LOG_RESULT "RSL: "
+#define D_LOG_SHT1 "SHT: "
+#define D_LOG_UPLOAD "UPL: "
+#define D_LOG_UPNP "UPP: "
+#define D_LOG_WIFI "WIF: "
+
+// Result
+#define D_RSLT_RESULT "RESULT"
+#define D_RSLT_INFO "INFO"
+#define D_RSLT_STATE "STATE"
+#define D_RSLT_SENSOR "SENSOR"
+#define D_RSLT_UPTIME "UPTIME"
+#define D_RSLT_MARGINS "MARGINS"
+#define D_RSLT_WARNING "WARNING"
+#define D_RSLT_ENERGY "ENERGY"
+
+// Commands
+#define D_CMND_MQTTHOST "MqttHost"
+#define D_CMND_MQTTPORT "MqttPort"
+#define D_CMND_MQTTRETRY "MqttRetry"
+#define D_CMND_STATETEXT "StateText"
+#define D_CMND_MQTTFINGERPRINT "MqttFingerprint"
+#define D_CMND_MQTTCLIENT "MqttClient"
+#define D_CMND_MQTTUSER "MqttUser"
+#define D_CMND_MQTTPASSWORD "MqttPassword"
+#define D_CMND_FULLTOPIC "FullTopic"
+#define D_CMND_PREFIX "Prefix"
+  #define PRFX_MAX_STRING_LENGTH 5
+  #define D_CMND "cmnd"
+  #define D_STAT "stat"
+  #define D_TELE "tele"
+#define D_CMND_GROUPTOPIC "GroupTopic"
+#define D_CMND_TOPIC "Topic"
+#define D_CMND_BUTTONTOPIC "ButtonTopic"
+#define D_CMND_SWITCHTOPIC "SwitchTopic"
+#define D_CMND_BUTTONRETAIN "ButtonRetain"
+#define D_CMND_SWITCHRETAIN "SwitchRetain"
+#define D_CMND_POWERRETAIN "PowerRetain"
+#define D_CMND_SENSORRETAIN "SensorRetain"
+#define D_CMND_BACKLOG "Backlog"
+#define D_CMND_DELAY "Delay"
+#define D_CMND_STATUS "Status"
+  #define D_STATUS1_PARAMETER "PRM"
+  #define D_STATUS2_FIRMWARE "FWR"
+  #define D_STATUS3_LOGGING "LOG"
+  #define D_STATUS4_MEMORY "MEM"
+  #define D_STATUS5_NETWORK "NET"
+  #define D_STATUS6_MQTT "MQT"
+  #define D_STATUS7_TIME "TIM"
+  #define D_STATUS8_POWER "PWR"
+  #define D_STATUS9_MARGIN "PTH"
+  #define D_STATUS10_SENSOR "SNS"
+  #define D_STATUS11_STATUS "STS"
+#define D_CMND_POWER "Power"
+  #define D_RSLT_POWER "POWER"
+#define D_CMND_POWERONSTATE "PowerOnState"
+#define D_CMND_PULSETIME "PulseTime"
+#define D_CMND_BLINKTIME "BlinkTime"
+#define D_CMND_BLINKCOUNT "BlinkCount"
+#define D_CMND_SAVEDATA "SaveData"
+#define D_CMND_SETOPTION "SetOption"
+#define D_CMND_TEMPERATURE_RESOLUTION "TempRes"
+#define D_CMND_HUMIDITY_RESOLUTION "HumRes"
+#define D_CMND_PRESSURE_RESOLUTION "PressRes"
+#define D_CMND_POWER_RESOLUTION "WattRes"
+#define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
+#define D_CMND_ENERGY_RESOLUTION "EnergyRes"
+#define D_CMND_MODULE "Module"
+#define D_CMND_MODULES "Modules"
+#define D_CMND_GPIO "GPIO"
+  #define D_NOT_SUPPORTED "Not supported"
+#define D_CMND_GPIOS "GPIOs"
+#define D_CMND_PWM "PWM"
+#define D_CMND_COUNTER "Counter"
+#define D_CMND_COUNTERTYPE "CounterType"
+#define D_CMND_COUNTERDEBOUNCE "CounterDebounce"
+#define D_CMND_SLEEP "Sleep"
+#define D_CMND_UPLOAD "Upload"
+#define D_CMND_UPGRADE "Upgrade"
+  #define D_ONE_OR_GT "1 or >%s to upgrade"
+#define D_CMND_OTAURL "OtaUrl"
+#define D_CMND_SERIALLOG "SerialLog"
+#define D_CMND_SYSLOG "SysLog"
+#define D_CMND_LOGHOST "LogHost"
+#define D_CMND_LOGPORT "LogPort"
+#define D_CMND_IPADDRESS "IPAddress"
+#define D_CMND_NTPSERVER "NtpServer"
+#define D_CMND_AP "Ap"
+#define D_CMND_SSID "SSId"
+#define D_CMND_PASSWORD "Password"
+#define D_CMND_HOSTNAME "Hostname"
+#define D_CMND_WIFICONFIG "WifiConfig"
+  #define WCFG_MAX_STRING_LENGTH 12
+  #define D_WCFG_0_RESTART "Restart"
+  #define D_WCFG_1_SMARTCONFIG "SmartConfig"
+  #define D_WCFG_2_WIFIMANAGER "WifiManager"
+  #define D_WCFG_3_WPSCONFIG "WPSConfig"
+  #define D_WCFG_4_RETRY "Retry"
+#define D_CMND_FRIENDLYNAME "FriendlyName"
+#define D_CMND_SWITCHMODE "SwitchMode"
+#define D_CMND_WEBSERVER "Webserver"
+  #define D_WEBSERVER_MODE "WebServerMode"
+  #define D_ACTIVE_FOR "Active for"
+  #define D_ON_DEVICE "on"
+#define D_CMND_WEBPASSWORD "WebPassword"
+#define D_CMND_WEBLOG "WebLog"
+#define D_CMND_EMULATION "Emulation"
+#define D_CMND_TELEPERIOD "TelePeriod"
+#define D_CMND_RESTART "Restart"
+  #define D_ONE_TO_RESTART "1 to restart"
+#define D_CMND_RESET "Reset"
+  #define D_RESET_AND_RESTARTING "Reset and Restarting"
+  #define D_ONE_TO_RESET "1 to reset"
+#define D_CMND_TIMEZONE "Timezone"
+#define D_CMND_LEDPOWER "LedPower"
+#define D_CMND_LEDSTATE "LedState"
+#define D_CMND_CFGDUMP "CfgDump"
+#define D_CMND_I2CSCAN "I2CScan"
+#define D_CMND_EXCEPTION "Exception"
+
+// Commands xdrv_domoticz.ino
+#define D_CMND_DOMOTICZ "Domoticz"
+#define D_CMND_IDX "Idx"
+#define D_CMND_KEYIDX "KeyIdx"
+#define D_CMND_SWITCHIDX "SwitchIdx"
+#define D_CMND_SENSORIDX "SensorIdx"
+#define D_CMND_UPDATETIMER "UpdateTimer"
+
+// Commands xdrv_ir_send.ino
+#define D_CMND_IRSEND "IRSend"
+#define D_CMND_IRHVAC "IRHVAC"
+
+// Commands xdrv_snfbridge.ino
+#define D_CMND_RFKEY "RfKey"
+#define D_CMND_RFDEFAULT "RfDefault"
+
+// Commands xdrv_snfled.ino
+#define D_CMND_COLOR "Color"
+#define D_CMND_COLORTEMPERATURE "CT"
+#define D_CMND_DIMMER "Dimmer"
+#define D_CMND_LEDTABLE "LedTable"
+#define D_CMND_FADE "Fade"
+#define D_CMND_SPEED "Speed"
+#define D_CMND_WAKEUPDURATION "WakeUpDuration"
+#define D_CMND_WAKEUP "Wakeup"
+
+// Commands xdrv_ws2812.ino
+#define D_CMND_PIXELS "Pixels"
+#define D_CMND_LED "Led"
+#define D_CMND_WIDTH "Width"
+#define D_CMND_SCHEME "Scheme"
+
+// Commands xsns_hlw8012.ino
+#define D_CMND_POWERLOW "PowerLow"
+#define D_CMND_POWERHIGH "PowerHigh"
+#define D_CMND_VOLTAGELOW "VoltageLow"
+#define D_CMND_VOLTAGEHIGH "VoltageHigh"
+#define D_CMND_CURRENTLOW "CurrentLow"
+#define D_CMND_CURRENTHIGH "CurrentHigh"
+#define D_CMND_ENERGYRESET "EnergyReset"
+#define D_CMND_HLWPCAL "HlwPcal"
+#define D_CMND_HLWPSET "HlwPset"
+#define D_CMND_HLWUCAL "HlwUcal"
+#define D_CMND_HLWUSET "HlwUset"
+#define D_CMND_HLWICAL "HlwIcal"
+#define D_CMND_HLWISET "HlwIset"
+#define D_CMND_MAXPOWER "MaxPower"
+#define D_CMND_MAXPOWERHOLD "MaxPowerHold"
+#define D_CMND_MAXPOWERWINDOW "MaxPowerWindow"
+#define D_CMND_SAFEPOWER "SafePower"
+#define D_CMND_SAFEPOWERHOLD "SafePowerHold"
+#define D_CMND_SAFEPOWERWINDOW "SafePowerWindow"
+#define D_CMND_MAXENERGY "MaxEnergy"
+#define D_CMND_MAXENERGYSTART "MaxEnergyStart"
diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h
new file mode 100644
index 000000000..dc0e4b369
--- /dev/null
+++ b/sonoff/language/nl-NL.h
@@ -0,0 +1,666 @@
+/*
+  i18n_nl-NL.h - localization for Dutch - Nederland 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/>.
+*/
+
+/*************************** ATTENTION *******************************\
+ *
+ * Due to memory constraints only UTF-8 is supported.
+ * Time and Date provided by SDK can not be localized (yet).
+ * Use online command StateText to translate ON, OFF, HOLD and TOGGLE.
+ * Use online command Prefix to translate cmnd, stat and tele.
+ *
+\*********************************************************************/
+
+// Time and Date managed by SDK will not be localized (yet)
+// "2017-03-07T11:08:02" - ISO8601:2004
+#define D_YEAR_MONTH_SEPARATOR "-"
+#define D_MONTH_DAY_SEPARATOR "-"
+#define D_DATE_TIME_SEPARATOR "T"
+#define D_HOUR_MINUTE_SEPARATOR ":"
+#define D_MINUTE_SECOND_SEPARATOR ":"
+
+#define D_DAY3LIST "Zo Ma Di Wo Do Vr Za "
+#define D_MONTH3LIST "JanFebMarAprMeiJunJulAugSepOktNovDec"
+
+// Non JSON decimal separator
+#define D_DECIMAL_SEPARATOR ","
+
+// Common
+#define D_ABORTED "Afgebroken"
+#define D_ACTIVE "Actief"
+#define D_ADDRESS "Adres"
+#define D_ADMIN "Admin"
+#define D_AIR_QUALITY "Lucht kwalitiet"
+#define D_AIRQUALITY "LuchtKwaliteit"
+#define D_AP "AP"                    // Access Point
+#define D_APMAC_ADDRESS "APMac"
+#define D_APPENDED "Aangevuld"
+#define D_AS "als"
+#define D_AUTO "AUTO"
+#define D_BAUDRATE "Baudrate"
+#define D_BLINK "Knipper"
+#define D_BLINKOFF "KnipperUit"
+#define D_BOOTVERSION "Boot"
+#define D_BOOT_COUNT "Herstarts"
+#define D_BOOTCOUNT "Herstarts"
+#define D_BRIGHTLIGHT "Fel"
+#define D_BUILDDATETIME "BuildDateTime"
+#define D_BUTTON "DrukKnop"
+#define D_CELSIUS "Celsius"
+#define D_CODE "code"                // Button code
+#define D_COLDLIGHT "Koud"
+#define D_COMMAND "Opdracht"
+#define D_CONNECTED "Verbonden"
+#define D_COREVERSION "Core"
+#define D_COUNT "Aantal"
+#define D_COUNTER "Teller"
+#define D_CURRENT "Stroom"          // As in Voltage and Current
+#define D_DATA "Data"
+#define D_DARKLIGHT "Donker"
+#define D_DEBUG "Debug"
+#define D_DISABLED "Uitgeschakeld"
+#define D_DNS_SERVER "DNS Server"
+#define D_DNSSERVER "DNSServer"
+#define D_DONE "Klaar"
+#define D_DST_TIME "ZT"
+#define D_EMPTY "Leeg"
+#define D_EMULATION "Emulatie"
+#define D_ENABLED "Geactiveerd"
+#define D_ENDDST "WinterTijd"           // End Daylight Savings Time
+#define D_ERASE "Wissen"
+#define D_ERROR "Fout"
+#define D_EVERY "Iedere"
+#define D_FAHRENHEIT "Fahrenheit"
+#define D_FAILED "Mislukt"
+#define D_FALLBACK "Fallback"
+#define D_FALLBACK_TOPIC "Fallback Topic"
+#define D_FALLBACKTOPIC "FallbackTopic"
+#define D_FALSE "Onwaar"
+#define D_FILE "Bestand"
+#define D_FLASHMODE "FlashStand"
+#define D_FLASHSIZE "FlashGrootte"
+#define D_FREE_MEMORY "Vrij geheugen"
+#define D_FREEMEMORY "Vrij"
+#define D_FROM "van"
+#define D_GATEWAY "Gateway"
+#define D_GROUP "Groep"
+#define D_HEAPSIZE "Heap"
+#define D_HIGH "Hoog"
+#define D_HOST "Host"
+#define D_HOSTNAME "Hostnaam"
+#define D_HUMIDITY "Luchtvochtigheid"
+#define D_ILLUMINANCE "Verlichtingssterkte"
+#define D_IMMEDIATE "onmiddelijk"      // Button immediate
+#define D_INDEX "Index"
+#define D_INFO "Info"
+#define D_INITIALIZED "Geinitialiseerd"
+#define D_IP_ADDRESS "IP Adres"
+#define D_LIGHT "Ligt"
+#define D_LOCAL_TIME "Plaatselijk"
+#define D_LOW "Laag"
+#define D_LWT "LWT"
+#define D_MAC "Mac"
+#define D_MASK "Masker"
+#define D_MODULE "Module"
+#define D_MQTT "MQTT"
+#define D_MULTI_PRESS "meervoudig"
+#define D_NO "Nee"
+#define D_NOISE "Lawaai"
+#define D_NONE "Geen"
+#define D_OFF "Uit"
+#define D_OFFLINE "Offline"
+#define D_OK "Ok"
+#define D_ON "Ann"
+#define D_ONLINE "Online"
+#define D_OR "of"
+#define D_PASSWORD "Wachtwoord"
+#define D_PERIOD "Periode"
+#define D_PORT "Poort"
+#define D_POWER_FACTOR "Arbeidsfactor"
+#define D_POWERFACTOR "Factor"
+#define D_POWERUSAGE "Vermogen"
+#define D_PRESSURE "Luchtdruk"
+#define D_PROGRAM_FLASH_SIZE "Programma Flash Grootte"
+#define D_PROGRAMFLASHSIZE "ProgrammaFlashGrootte"
+#define D_PROGRAM_SIZE "Programma Grootte"
+#define D_PROGRAMSIZE "ProgrammaGrootte"
+#define D_PROJECT "Project"
+#define D_RECEIVED "Ontvangen"
+#define D_RESTART "Herstart"
+#define D_RESTARTING "Herstarten"
+#define D_RESTART_REASON "Reden herstart"
+#define D_RESTARTREASON "RedenHerstart"
+#define D_RESTORE "herstellen"
+#define D_RETAINED "retained"
+#define D_SAVE "Opslaan"
+#define D_SAVEADDRESS "OpslagAdres"
+#define D_SAVECOUNT "AantalOpslagen"
+#define D_SAVESTATE "OpslagToestand"
+#define D_SDKVERSION "SDK"
+#define D_SELECTED "gekozen"
+#define D_SENSOR "Sensor"
+#define D_SERIAL "Serieel"
+#define D_BYTES "Bytes"
+#define D_SSID "SSId"
+#define D_START "Start"
+#define D_STARTED "Gestart"
+#define D_STARTDST "Zomertijd"        // Start Daylight Savings Time
+#define D_STD_TIME "WT"
+#define D_STOP "Stop"
+#define D_SUBNET_MASK "Subnet Masker"
+#define D_SUBNETMASK "Subnetmasker"
+#define D_SUCCESSFUL "Gelukt"
+#define D_SWITCH "Schakelaar"
+#define D_SYNC "Sync"
+#define D_SYS "Sys"                  // Sys log
+#define D_TEMPERATURE "Temperatuur"
+#define D_TEMPERATURE_UNIT "TempEenheid"
+#define D_TIME "Tijd"
+#define D_TO "naar"
+#define D_TODAY "Vandaag"
+#define D_TOGGLE "Toggle"  // Wissel, Tuimel
+#define D_TOPIC "Topic"  // Onderwerp
+#define D_TOTAL "Totaal"
+#define D_TRUE "Waar"
+#define D_TYPE "Soort"
+#define D_UNKNOWN "Onbekend"
+#define D_UPGRADE "opwaarderen"
+#define D_UPLOAD "Verzenden"
+#define D_UPTIME "Bedrijfstijd"
+#define D_UTC_TIME "UTC"
+#define D_USER "Gebruiker"
+#define D_VCC "Vcc"
+#define D_VERSION "Versie"
+#define D_VOLTAGE "Spanning"
+#define D_WARMLIGHT "Warm"
+#define D_WEB "Web"                  // Web log
+#define D_WEB_SERVER "Webserver"
+#define D_WIFI "Wifi"
+#define D_WRONG "Fout"
+#define D_YESTERDAY "Gisteren"
+
+// settings.ino
+#define D_SAVED_TO_FLASH_AT "Opgeslagen in flash op"
+#define D_LOADED_FROM_FLASH_AT "Geladen vanuit flash op"
+#define D_USE_DEFAULTS "Gebruik standaardwaarden"
+#define D_ERASED_SECTOR "Wis sector"
+
+// sonoff.ino
+#define D_LEVEL_10 "niveau 1-0"
+#define D_LEVEL_01 "niveau 0-1"
+#define D_SERIAL_LOGGING_DISABLED "Serieel logging uitgeschakeld"
+#define D_SYSLOG_LOGGING_REENABLED "Syslog logging weer ingeschakeld"
+
+#define D_SET_BAUDRATE_TO "Zet baudrate op"
+#define D_RECEIVED_TOPIC "Ontvangen topic"
+#define D_DATA_SIZE "Data lengte"
+#define D_ANALOG_INPUT0 "Analoog0"
+
+#define D_FINGERPRINT "Controleer TLS vingerafdruk..."
+#define D_TLS_CONNECT_FAILED_TO "TLS Verbinding mislukt naar"
+#define D_RETRY_IN "Opnieuw proberen over"
+#define D_VERIFIED "Gecontroleerd"
+#define D_INSECURE "Door ongeldige vingerafdruk een onveilige verbinding"
+#define D_CONNECT_FAILED_TO "Verbinding mislukt naar"
+
+// support.ino
+#define D_OSWATCH "osWatch"
+#define D_BLOCKED_LOOP "Blocked Loop"
+#define D_WPS_FAILED_WITH_STATUS "WPSconfig mislukt met status"
+#define D_ACTIVE_FOR_1_MINUTE "1 minuut actief"
+#define D_FAILED_TO_START "mislukt"
+#define D_PATCH_ISSUE_2186 "Patch issue 2186"
+#define D_CONNECTING_TO_AP "Verbinden met AP"
+#define D_IN_MODE "in stand"
+#define D_CONNECT_FAILED_NO_IP_ADDRESS "Verbinding mislukt omdat geen IP adres werd ontvangen"
+#define D_CONNECT_FAILED_AP_NOT_REACHED "Verbinding mislukt omdat AP onbereikbaar is"
+#define D_CONNECT_FAILED_WRONG_PASSWORD "Verbinding mislukt door fout wachtwoord"
+#define D_CONNECT_FAILED_AP_TIMEOUT "Verbinding mislukt door AP time-out"
+#define D_ATTEMPTING_CONNECTION "Verbinden..."
+#define D_CHECKING_CONNECTION "Controleer verbinding..."
+#define D_QUERY_DONE "Aanvraag klaar. Aantal MQTT diensten gevonden"
+#define D_MQTT_SERVICE_FOUND "MQTT dienst gevonden op"
+#define D_I2CSCAN_DEVICES_FOUND_AT "Apparaten gevonden op"
+#define D_FOUND_AT "gevonden op"
+#define D_I2CSCAN_UNKNOWN_ERROR_AT "Onbekende fout op"
+#define D_I2CSCAN_NO_DEVICES_FOUND "Geen apparaten gevonden"
+#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host niet gevonden"
+
+// webserver.ino
+#define D_WEBSERVER_ACTIVE_ON "Webserver actief op"
+#define D_WITH_IP_ADDRESS "met IP adres"
+#define D_WEBSERVER_STOPPED "Webserver gestopt"
+#define D_FILE_NOT_FOUND "Bestand niet gevonden"
+#define D_REDIRECTED "Redirected to captive portal"
+#define D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION "Wifimanager start AccessPoint en hou Station"
+#define D_WIFIMANAGER_SET_ACCESSPOINT "Wifimanager start AccessPoint"
+#define D_TRYING_TO_CONNECT "Apparaat probeert te verbinden met netwerk"
+
+#define D_RESTART_IN "Herstart over"
+#define D_SECONDS "seconden"
+#define D_DEVICE_WILL_RESTART "Herstart over enkele seconden"
+#define D_BUTTON_TOGGLE "Toggle"  // Wissel, Tuimel
+#define D_CONFIGURATION "Configuratie"
+#define D_INFORMATION "Informatie"
+#define D_FIRMWARE_UPGRADE "Opwaarderen"
+#define D_CONSOLE "Console"
+#define D_CONFIRM_RESTART "Bevestig herstart"
+
+#define D_CONFIGURE_MODULE "Configureer Module"
+#define D_CONFIGURE_WIFI "Configureer WiFi"
+#define D_CONFIGURE_MQTT "Configureer MQTT"
+#define D_CONFIGURE_DOMOTICZ "Configureer Domoticz"
+#define D_CONFIGURE_LOGGING "Configureer Logging"
+#define D_CONFIGURE_OTHER "Configureer Overige"
+#define D_CONFIRM_RESET_CONFIGURATION "Bevestig reset configuratie"
+#define D_RESET_CONFIGURATION "Reset Configuratie"
+#define D_BACKUP_CONFIGURATION "Bewaar Configuratie"
+#define D_RESTORE_CONFIGURATION "Herstel Configuration"
+#define D_MAIN_MENU "Hoofdmenu"
+
+#define D_MODULE_PARAMETERS "Module parameters"
+#define D_MODULE_TYPE "Module soort"
+#define D_GPIO "GPIO"
+#define D_SERIAL_IN "Serieel In"
+#define D_SERIAL_OUT "Serieel Uit"
+
+#define D_WIFI_PARAMETERS "Wifi parameters"
+#define D_SCAN_FOR_WIFI_NETWORKS "Zoek wifi netwerken"
+#define D_SCAN_DONE "Scan klaar"
+#define D_NO_NETWORKS_FOUND "Geen netwerken gevonden"
+#define D_REFRESH_TO_SCAN_AGAIN "Vernieuw om opnieuw te zoeken"
+#define D_DUPLICATE_ACCESSPOINT "Dubbel AccessPoint"
+#define D_SKIPPING_LOW_QUALITY "Overslaan agv lage ontvangskwaliteit"
+#define D_RSSI "RSSI"
+#define D_WEP "WEP"
+#define D_WPA_PSK "WPA PSK"
+#define D_WPA2_PSK "WPA2 PSK"
+#define D_AP1_SSID "AP1 SSId"
+#define D_AP1_PASSWORD "AP1 Wachtwoord"
+#define D_AP2_SSID "AP2 SSId"
+#define D_AP2_PASSWORD "AP2 Wachtwoord"
+
+#define D_MQTT_PARAMETERS "MQTT parameters"
+#define D_CLIENT "Client"
+#define D_FULL_TOPIC "Volledig Topic"
+
+#define D_LOGGING_PARAMETERS "Logging parameters"
+#define D_LOG_LEVEL "log niveau"
+#define D_MORE_DEBUG "Meer debug"
+#define D_SYSLOG_HOST "Syslog host"
+#define D_SYSLOG_PORT "Syslog poort"
+#define D_TELEMETRY_PERIOD "Telemetry periode"
+
+#define D_OTHER_PARAMETERS "Overige parameters"
+#define D_WEB_ADMIN_PASSWORD "Web Admin Wachtwoord"
+#define D_MQTT_ENABLE "MQTT ingeschakeld"
+#define D_FRIENDLY_NAME "Beschrijvende naam"
+#define D_BELKIN_WEMO "Belkin WeMo"
+#define D_HUE_BRIDGE "Hue Bridge"
+#define D_SINGLE_DEVICE "een apparaat"
+#define D_MULTI_DEVICE "meer apparaten"
+
+#define D_SAVE_CONFIGURATION "Bewaar configuratie"
+#define D_CONFIGURATION_SAVED "Configuratie opgeslagen"
+#define D_CONFIGURATION_RESET "Configuratie ge-reset"
+
+#define D_PROGRAM_VERSION "Programma Versie"
+#define D_BUILD_DATE_AND_TIME "Compileer Datum & Tijd"
+#define D_CORE_AND_SDK_VERSION "Core/SDK Versie"
+#define D_FLASH_WRITE_COUNT "Aantal Flash opslagen"
+#define D_MAC_ADDRESS "MAC Adres"
+#define D_MQTT_HOST "MQTT Host"
+#define D_MQTT_PORT "MQTT Poort"
+#define D_MQTT_CLIENT "MQTT Client"
+#define D_MQTT_USER "MQTT Gebruiker"
+#define D_MQTT_TOPIC "MQTT Topic"
+#define D_MQTT_GROUP_TOPIC "MQTT Groep Topic"
+#define D_MQTT_FULL_TOPIC "MQTT Volledig Topic"
+#define D_MDNS_DISCOVERY "mDNS Discovery"
+#define D_MDNS_ADVERTISE "mDNS Advertise"
+#define D_ESP_CHIP_ID "ESP Chip Id"
+#define D_FLASH_CHIP_ID "Flash Chip Id"
+#define D_FLASH_CHIP_SIZE "Flash Grootte"
+#define D_FREE_PROGRAM_SPACE "Vrij programma ruimte"
+
+#define D_UPGRADE_BY_WEBSERVER "Opwaarderen dmv webserver"
+#define D_OTA_URL "OTA Url"
+#define D_START_UPGRADE "Start opwaarderen"
+#define D_UPGRADE_BY_FILE_UPLOAD "Opwaarderen dmv verzenden bestand"
+#define D_UPLOAD_STARTED "Verzending gestart"
+#define D_UPGRADE_STARTED "Opwaarderen gestart"
+#define D_UPLOAD_DONE "Opwaarderen klaar"
+#define D_UPLOAD_ERR_1 "Geen bestand gekozen"
+#define D_UPLOAD_ERR_2 "Onvoldoende geheugen ruimte"
+#define D_UPLOAD_ERR_3 "Magische byte is niet 0xE9"
+#define D_UPLOAD_ERR_4 "Programma flash grootte is groter dan werkelijke flash grootte"
+#define D_UPLOAD_ERR_5 "Opwaardeer buffer verschil"
+#define D_UPLOAD_ERR_6 "Opwaarderen mislukt. Schakel logging 3 in"
+#define D_UPLOAD_ERR_7 "Opwaarderen afgebroken"
+#define D_UPLOAD_ERR_8 "Ongeldig bestand"
+#define D_UPLOAD_ERR_9 "Bestand is te groot"
+#define D_UPLOAD_ERROR_CODE "Opwaardeer foutcode"
+
+#define D_ENTER_COMMAND "Geef opdracht"
+#define D_ENABLE_WEBLOG_FOR_RESPONSE "Schakel weblog 2 in indien antwoord verwacht"
+#define D_NEED_USER_AND_PASSWORD "Benodig user=<gebruiker>&password=<webwachtwoord>"
+
+// xdrv_domoticz.ino
+#define D_DOMOTICZ_PARAMETERS "Domoticz parameters"
+#define D_DOMOTICZ_IDX "Idx"
+#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"
+  #define D_DOMOTICZ_POWER_ENERGY "Power,Energy"
+  #define D_DOMOTICZ_ILLUMINANCE "Illuminance"
+  #define D_DOMOTICZ_COUNT "Count"
+#define D_DOMOTICZ_UPDATE_TIMER "Bijwerk timer"
+#define D_CONFIGURE_DOMOTICZ "Configureer Domoticz"
+
+// xdrv_ir-send.ino
+#define D_INVALID_JSON "Ongeldig JSON"
+#define D_PROTOCOL_NOT_SUPPORTED "Protocol wordt niet ondersteund"
+#define D_IRSEND_PROTOCOL "PROTOCOL"
+#define D_IRSEND_BITS "BITS"
+#define D_IRSEND_DATA "DATA"
+#define D_IRHVAC_VENDOR "VENDOR"
+#define D_IRHVAC_POWER "POWER"
+#define D_IRHVAC_MODE "MODE"
+#define D_IRHVAC_FANSPEED "FANSPEED"
+#define D_IRHVAC_TEMP "TEMP"
+
+// xdrv_snfbridge.ino
+#define D_RFRECEIVED "RfReceived"
+#define D_START_LEARNING "Start leren"
+#define D_SET_TO_DEFAULT "Zet standaard waarden"
+#define D_DEFAULT_SENT "Standaard verzonden"
+#define D_LEARNED_SENT "Geleerde verzonden"
+#define D_LEARNING_ACTIVE "Leren actief"
+#define D_LEARN_FAILED "Leren mislukt"
+#define D_LEARNED "Geleerd"
+
+// xdrv_wemohue.ino
+#define D_MULTICAST_DISABLED "Multicast uitgeschakeld"
+#define D_MULTICAST_REJOINED "Multicast verbonden"
+#define D_MULTICAST_JOIN_FAILED "Multicast verbinding mislukt"
+#define D_FAILED_TO_SEND_RESPONSE "Antwoord versturen mislukt"
+
+#define D_WEMO "WeMo"
+#define D_WEMO_BASIC_EVENT "WeMo basis gebeurtenis"
+#define D_WEMO_EVENT_SERVICE "WeMo gebeurtenis dienst"
+#define D_WEMO_SETUP "WeMo installatie"
+#define D_RESPONSE_SENT "Antwoord verstuurd"
+
+#define D_HUE "Hue"
+#define D_HUE_BRIDGE_SETUP "Hue installatie"
+#define D_HUE_API_NOT_IMPLEMENTED "Hue API niet beschikbaar"
+#define D_HUE_API "Hue API"
+#define D_HUE_POST_ARGS "Hue POST argumenten"
+#define D_3_RESPONSE_PACKETS_SENT "3 antwoord paketten verstuurd"
+
+// xsns_dht.ino
+#define D_TIMEOUT_WAITING_FOR "Te lang wachten op"
+#define D_START_SIGNAL_LOW "laag start signaal"
+#define D_START_SIGNAL_HIGH "hoog start signaal"
+#define D_PULSE "signaal"
+#define D_CHECKSUM_FAILURE "Controle mislukt"
+
+// xsns_ds18b20.ino
+#define D_SENSOR_BUSY "Sensor bezet"
+#define D_SENSOR_CRC_ERROR "Sensor CRC fout"
+
+// xsns_hlw8012.ino
+#define D_MAXPOWERREACHED "MaxPowerReached"
+#define D_MAXPOWERREACHEDRETRY "MaxPowerReachedRetry"
+#define D_POWERMONITOR "PowerMonitor"
+#define D_ENERGYMONITOR "EnergyMonitor"
+#define D_MAXENERGYREACHED "MaxEnergyReached"
+#define D_ENERGY_TODAY "Verbruik vandaag"
+#define D_ENERGY_YESTERDAY "Verbruik gisteren"
+#define D_ENERGY_TOTAL "Verbruik totaal"
+
+// xsns_sht1x.ino
+#define D_SENSOR_DID_NOT_ACK_COMMAND "Geen opdracht ACK van sensor"
+#define D_SHT1X_FOUND "SHT1X gevonden"
+
+// sonoff_template.h
+// Max string length is 8 characters including suffixes
+#define D_SENSOR_NONE     "Geen"
+#define D_SENSOR_DHT11    "DHT11"
+#define D_SENSOR_AM2301   "AM2301"
+#define D_SENSOR_DHT22    "DHT22"
+#define D_SENSOR_DS18X20  "DS18x20"
+#define D_SENSOR_I2C_SCL  "I2C SCL"
+#define D_SENSOR_I2C_SDA  "I2C SDA"
+#define D_SENSOR_WS2812   "WS2812"
+#define D_SENSOR_IRREMOTE "IRremote"
+#define D_SENSOR_SWITCH   "Switch"  // Suffix "1"
+#define D_SENSOR_BUTTON   "Button"  // Suffix "1"
+#define D_SENSOR_RELAY    "Relais"  // Suffix "1I"
+#define D_SENSOR_LED      "Led"     // Suffix "1I"
+#define D_SENSOR_PWM      "PWM"     // Suffix "1"
+#define D_SENSOR_COUNTER  "Teller"  // Suffix "1"
+
+// Units
+#define D_UNIT_AMPERE "A"
+#define D_UNIT_HOUR "Hr"
+#define D_UNIT_KILOWATTHOUR "kWh"
+#define D_UNIT_MICROSECOND "us"
+#define D_UNIT_MILLIAMPERE "mA"
+#define D_UNIT_MILLISECOND "ms"
+#define D_UNIT_MINUTE "Min"
+#define D_UNIT_PRESSURE "hPa"
+#define D_UNIT_SECOND "sec"
+#define D_UNIT_SECTORS "sectoren"
+#define D_UNIT_VOLT "V"
+#define D_UNIT_WATT "W"
+#define D_UNIT_WATTHOUR "Wh"
+
+// Log message prefix
+#define D_LOG_APPLICATION "APP: "
+#define D_LOG_BRIDGE "BRG: "
+#define D_LOG_CONFIG "CFG: "
+#define D_LOG_COMMAND "CND: "
+#define D_LOG_DHT "DHT: "
+#define D_LOG_DOMOTICZ "DOM: "
+#define D_LOG_DSB "DSB: "
+#define D_LOG_HTTP "HTP: "
+#define D_LOG_I2C "I2C: "
+#define D_LOG_LOG "LOG: "
+#define D_LOG_MODULE "MOD: "
+#define D_LOG_MDNS "DNS: "
+#define D_LOG_MQTT "MQT: "
+#define D_LOG_OTHER "OTH: "
+#define D_LOG_RESULT "RSL: "
+#define D_LOG_SHT1 "SHT: "
+#define D_LOG_UPLOAD "UPL: "
+#define D_LOG_UPNP "UPP: "
+#define D_LOG_WIFI "WIF: "
+
+// Result
+#define D_RSLT_RESULT "RESULTAAT"
+#define D_RSLT_INFO "INFO"
+#define D_RSLT_STATE "TOESTAND"
+#define D_RSLT_SENSOR "SENSOR"
+#define D_RSLT_UPTIME "BEDRIJFSTIJD"
+#define D_RSLT_MARGINS "GRENSWAARDEN"
+#define D_RSLT_WARNING "WAARSCHUWING"
+#define D_RSLT_ENERGY "ENERGIE"
+
+// Commands
+#define D_CMND_MQTTHOST "MqttHost"
+#define D_CMND_MQTTPORT "MqttPort"
+#define D_CMND_MQTTRETRY "MqttRetry"
+#define D_CMND_STATETEXT "StateText"
+#define D_CMND_MQTTFINGERPRINT "MqttFingerprint"
+#define D_CMND_MQTTCLIENT "MqttClient"
+#define D_CMND_MQTTUSER "MqttUser"
+#define D_CMND_MQTTPASSWORD "MqttPassword"
+#define D_CMND_FULLTOPIC "FullTopic"
+#define D_CMND_PREFIX "Prefix"
+  #define PRFX_MAX_STRING_LENGTH 5
+  #define D_CMND "cmnd"
+  #define D_STAT "stat"
+  #define D_TELE "tele"
+#define D_CMND_GROUPTOPIC "GroupTopic"
+#define D_CMND_TOPIC "Topic"
+#define D_CMND_BUTTONTOPIC "ButtonTopic"
+#define D_CMND_SWITCHTOPIC "SwitchTopic"
+#define D_CMND_BUTTONRETAIN "ButtonRetain"
+#define D_CMND_SWITCHRETAIN "SwitchRetain"
+#define D_CMND_POWERRETAIN "PowerRetain"
+#define D_CMND_SENSORRETAIN "SensorRetain"
+#define D_CMND_BACKLOG "Backlog"
+#define D_CMND_DELAY "Delay"
+#define D_CMND_STATUS "Status"
+  #define D_STATUS1_PARAMETER "PRM"
+  #define D_STATUS2_FIRMWARE "FWR"
+  #define D_STATUS3_LOGGING "LOG"
+  #define D_STATUS4_MEMORY "MEM"
+  #define D_STATUS5_NETWORK "NET"
+  #define D_STATUS6_MQTT "MQT"
+  #define D_STATUS7_TIME "TIM"
+  #define D_STATUS8_POWER "PWR"
+  #define D_STATUS9_MARGIN "PTH"
+  #define D_STATUS10_SENSOR "SNS"
+  #define D_STATUS11_STATUS "STS"
+#define D_CMND_POWER "Power"
+  #define D_RSLT_POWER "POWER"
+#define D_CMND_POWERONSTATE "PowerOnState"
+#define D_CMND_PULSETIME "PulseTime"
+#define D_CMND_BLINKTIME "BlinkTime"
+#define D_CMND_BLINKCOUNT "BlinkCount"
+#define D_CMND_SAVEDATA "SaveData"
+#define D_CMND_SETOPTION "SetOption"
+#define D_CMND_TEMPERATURE_RESOLUTION "TempRes"
+#define D_CMND_HUMIDITY_RESOLUTION "HumRes"
+#define D_CMND_PRESSURE_RESOLUTION "PressRes"
+#define D_CMND_POWER_RESOLUTION "WattRes"
+#define D_CMND_VOLTAGE_RESOLUTION "VoltRes"
+#define D_CMND_ENERGY_RESOLUTION "EnergyRes"
+#define D_CMND_MODULE "Module"
+#define D_CMND_MODULES "Modules"
+#define D_CMND_GPIO "GPIO"
+  #define D_NOT_SUPPORTED "Not supported"
+#define D_CMND_GPIOS "GPIOs"
+#define D_CMND_PWM "PWM"
+#define D_CMND_COUNTER "Counter"
+#define D_CMND_COUNTERTYPE "CounterType"
+#define D_CMND_COUNTERDEBOUNCE "CounterDebounce"
+#define D_CMND_SLEEP "Sleep"
+#define D_CMND_UPLOAD "Upload"
+#define D_CMND_UPGRADE "Upgrade"
+  #define D_ONE_OR_GT "1 or >%s to upgrade"
+#define D_CMND_OTAURL "OtaUrl"
+#define D_CMND_SERIALLOG "SerialLog"
+#define D_CMND_SYSLOG "SysLog"
+#define D_CMND_LOGHOST "LogHost"
+#define D_CMND_LOGPORT "LogPort"
+#define D_CMND_IPADDRESS "IPAddress"
+#define D_CMND_NTPSERVER "NtpServer"
+#define D_CMND_AP "Ap"
+#define D_CMND_SSID "SSId"
+#define D_CMND_PASSWORD "Password"
+#define D_CMND_HOSTNAME "Hostname"
+#define D_CMND_WIFICONFIG "WifiConfig"
+  #define WCFG_MAX_STRING_LENGTH 12
+  #define D_WCFG_0_RESTART "Restart"
+  #define D_WCFG_1_SMARTCONFIG "SmartConfig"
+  #define D_WCFG_2_WIFIMANAGER "WifiManager"
+  #define D_WCFG_3_WPSCONFIG "WPSConfig"
+  #define D_WCFG_4_RETRY "Opnieuw"
+#define D_CMND_FRIENDLYNAME "FriendlyName"
+#define D_CMND_SWITCHMODE "SwitchMode"
+#define D_CMND_WEBSERVER "Webserver"
+  #define D_WEBSERVER_MODE "WebServerSoort"
+  #define D_ACTIVE_FOR "Aktief als"
+  #define D_ON_DEVICE "op"
+#define D_CMND_WEBPASSWORD "WebPassword"
+#define D_CMND_WEBLOG "WebLog"
+#define D_CMND_EMULATION "Emulation"
+#define D_CMND_TELEPERIOD "TelePeriod"
+#define D_CMND_RESTART "Restart"
+  #define D_ONE_TO_RESTART "1 voor herstart"
+#define D_CMND_RESET "Reset"
+  #define D_RESET_AND_RESTARTING "Reset en herstarten"
+  #define D_ONE_TO_RESET "1 voor reset"
+#define D_CMND_TIMEZONE "Timezone"
+#define D_CMND_LEDPOWER "LedPower"
+#define D_CMND_LEDSTATE "LedState"
+#define D_CMND_CFGDUMP "CfgDump"
+#define D_CMND_I2CSCAN "I2CScan"
+#define D_CMND_EXCEPTION "Exception"
+
+// Commands xdrv_domoticz.ino
+#define D_CMND_DOMOTICZ "Domoticz"
+#define D_CMND_IDX "Idx"
+#define D_CMND_KEYIDX "KeyIdx"
+#define D_CMND_SWITCHIDX "SwitchIdx"
+#define D_CMND_SENSORIDX "SensorIdx"
+#define D_CMND_UPDATETIMER "UpdateTimer"
+
+// Commands xdrv_ir_send.ino
+#define D_CMND_IRSEND "IRSend"
+#define D_CMND_IRHVAC "IRHVAC"
+
+// Commands xdrv_snfbridge.ino
+#define D_CMND_RFKEY "RfKey"
+#define D_CMND_RFDEFAULT "RfDefault"
+
+// Commands xdrv_snfled.ino
+#define D_CMND_COLOR "Color"
+#define D_CMND_COLORTEMPERATURE "CT"
+#define D_CMND_DIMMER "Dimmer"
+#define D_CMND_LEDTABLE "LedTable"
+#define D_CMND_FADE "Fade"
+#define D_CMND_SPEED "Speed"
+#define D_CMND_WAKEUPDURATION "WakeUpDuration"
+#define D_CMND_WAKEUP "Wakeup"
+
+// Commands xdrv_ws2812.ino
+#define D_CMND_PIXELS "Pixels"
+#define D_CMND_LED "Led"
+#define D_CMND_WIDTH "Width"
+#define D_CMND_SCHEME "Scheme"
+
+// Commands xsns_hlw8012.ino
+#define D_CMND_POWERLOW "PowerLow"
+#define D_CMND_POWERHIGH "PowerHigh"
+#define D_CMND_VOLTAGELOW "VoltageLow"
+#define D_CMND_VOLTAGEHIGH "VoltageHigh"
+#define D_CMND_CURRENTLOW "CurrentLow"
+#define D_CMND_CURRENTHIGH "CurrentHigh"
+#define D_CMND_ENERGYRESET "EnergyReset"
+#define D_CMND_HLWPCAL "HlwPcal"
+#define D_CMND_HLWPSET "HlwPset"
+#define D_CMND_HLWUCAL "HlwUcal"
+#define D_CMND_HLWUSET "HlwUset"
+#define D_CMND_HLWICAL "HlwIcal"
+#define D_CMND_HLWISET "HlwIset"
+#define D_CMND_MAXPOWER "MaxPower"
+#define D_CMND_MAXPOWERHOLD "MaxPowerHold"
+#define D_CMND_MAXPOWERWINDOW "MaxPowerWindow"
+#define D_CMND_SAFEPOWER "SafePower"
+#define D_CMND_SAFEPOWERHOLD "SafePowerHold"
+#define D_CMND_SAFEPOWERWINDOW "SafePowerWindow"
+#define D_CMND_MAXENERGY "MaxEnergy"
+#define D_CMND_MAXENERGYSTART "MaxEnergyStart"
diff --git a/sonoff/settings.h b/sonoff/settings.h
index f51f8c1f8..cd0df85e7 100644
--- a/sonoff/settings.h
+++ b/sonoff/settings.h
@@ -19,7 +19,7 @@
 
 #define PARAM8_SIZE  23                    // Number of param bytes
 
-typedef union {                            // Restricted by MISRA-C Rule 18.4 but so usefull...    
+typedef union {                            // Restricted by MISRA-C Rule 18.4 but so usefull...
   uint32_t data;                           // Allow bit manipulation using SetOption
   struct {
     uint32_t savestate : 1;                // bit 0
@@ -58,7 +58,7 @@ struct SYSCFG {
   unsigned long bootcount;
   sysBitfield   flag;                      // Add flag since 5.0.2
   int16_t       savedata;
-  
+
   int8_t        timezone;
   char          otaUrl[101];
 
@@ -98,7 +98,7 @@ struct SYSCFG {
 
   uint8_t       param[PARAM8_SIZE];        // was domoticz_in_topic until 5.1.6
   char          state_text[4][11];         // was domoticz_out_topic until 5.1.6
-  
+
   uint16_t      domoticz_update_timer;
   unsigned long domoticz_relay_idx[4];
   unsigned long domoticz_key_idx[4];
@@ -115,14 +115,14 @@ struct SYSCFG {
   uint16_t      hlw_umax;
   uint16_t      hlw_imin;
   uint16_t      hlw_imax;
-  uint16_t      hlw_mpl;    // MaxPowerLimit
-  uint16_t      hlw_mplh;   // MaxPowerLimitHold
-  uint16_t      hlw_mplw;   // MaxPowerLimitWindow
-  uint16_t      hlw_mspl;   // MaxSafePowerLimit
-  uint16_t      hlw_msplh;  // MaxSafePowerLimitHold
-  uint16_t      hlw_msplw;  // MaxSafePowerLimitWindow
-  uint16_t      hlw_mkwh;   // MaxEnergy
-  uint16_t      hlw_mkwhs;  // MaxEnergyStart
+  uint16_t      hlw_mpl;                   // MaxPowerLimit
+  uint16_t      hlw_mplh;                  // MaxPowerLimitHold
+  uint16_t      hlw_mplw;                  // MaxPowerLimitWindow
+  uint16_t      hlw_mspl;                  // MaxSafePowerLimit
+  uint16_t      hlw_msplh;                 // MaxSafePowerLimitHold
+  uint16_t      hlw_msplw;                 // MaxSafePowerLimitWindow
+  uint16_t      hlw_mkwh;                  // MaxEnergy
+  uint16_t      hlw_mkwhs;                 // MaxEnergyStart
 
   // 3.0.6
   uint16_t      mqtt_retry;                // was ex_pulsetime until 4.0.4
@@ -217,8 +217,7 @@ struct RTCMEM {
   unsigned long pCounter[MAX_COUNTERS];
 } rtcMem;
 
-// See issue https://github.com/esp8266/Arduino/issues/2913  
+// See issue https://github.com/esp8266/Arduino/issues/2913
 #ifdef USE_ADC_VCC
-  ADC_MODE(ADC_VCC);                        // Set ADC input for Power Supply Voltage usage
+  ADC_MODE(ADC_VCC);                       // Set ADC input for Power Supply Voltage usage
 #endif
-
diff --git a/sonoff/settings.ino b/sonoff/settings.ino
index 47a537a1b..844a3a595 100644
--- a/sonoff/settings.ino
+++ b/sonoff/settings.ino
@@ -81,7 +81,7 @@ boolean RTC_Valid()
 void RTC_Dump()
 {
   #define CFG_COLS 16
-  
+
   char log[LOGSZ];
   uint16_t idx;
   uint16_t maxrow;
@@ -186,7 +186,7 @@ uint32_t CFG_Address()
 void CFG_Save(byte rotate)
 {
 /* Save configuration in eeprom or one of 7 slots below
- *  
+ *
  * rotate 0 = Save in next flash slot
  * rotate 1 = Save only in eeprom flash slot until SetOption12 0 or restart
  * rotate 2 = Save in eeprom flash slot, erase next flash slots and continue depending on stop_flash_rotate
@@ -224,7 +224,8 @@ void CFG_Save(byte rotate)
         delay(1);
       }
     }
-    snprintf_P(log, sizeof(log), PSTR("Cnfg: Save (%d bytes) to flash at %X and count %d"), sizeof(SYSCFG), _cfgLocation, sysCfg.saveFlag);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_CONFIG D_SAVED_TO_FLASH_AT " %X, " D_COUNT " %d, " D_BYTES " %d"),
+       _cfgLocation, sysCfg.saveFlag, sizeof(SYSCFG));
     addLog(LOG_LEVEL_DEBUG, log);
     _cfgHash = getHash();
   }
@@ -259,7 +260,8 @@ void CFG_Load()
     }
     delay(1);
   }
-  snprintf_P(log, sizeof(log), PSTR("Cnfg: Load from flash at %X and count %d"), _cfgLocation, sysCfg.saveFlag);
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_CONFIG D_LOADED_FROM_FLASH_AT " %X, " D_COUNT " %d"),
+    _cfgLocation, sysCfg.saveFlag);
   addLog(LOG_LEVEL_DEBUG, log);
   if (sysCfg.cfg_holder != CFG_HOLDER) {
     // Auto upgrade
@@ -273,7 +275,7 @@ void CFG_Load()
       CFG_Default();
     }
   }
-  
+
   _cfgHash = getHash();
 
   RTC_Load();
@@ -288,7 +290,7 @@ void CFG_Erase()
   uint32_t _sectorEnd = ESP.getFlashChipRealSize() / SPI_FLASH_SEC_SIZE;
   boolean _serialoutput = (LOG_LEVEL_DEBUG_MORE <= seriallog_level);
 
-  snprintf_P(log, sizeof(log), PSTR("Cnfg: Erase %d flash sectors"), _sectorEnd - _sectorStart);
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_ERASE " %d " D_UNIT_SECTORS), _sectorEnd - _sectorStart);
   addLog(LOG_LEVEL_DEBUG, log);
 
   for (uint32_t _sector = _sectorStart; _sector < _sectorEnd; _sector++) {
@@ -296,12 +298,12 @@ void CFG_Erase()
     result = spi_flash_erase_sector(_sector);
     interrupts();
     if (_serialoutput) {
-      Serial.print(F("Flash: Erased sector "));
+      Serial.print(F(D_LOG_APPLICATION D_ERASED_SECTOR " "));
       Serial.print(_sector);
       if (SPI_FLASH_RESULT_OK == result) {
-        Serial.println(F(" OK"));
+        Serial.println(F(" " D_OK));
       } else {
-        Serial.println(F(" Error"));
+        Serial.println(F(" " D_ERROR));
       }
       delay(10);
     }
@@ -311,7 +313,7 @@ void CFG_Erase()
 void CFG_Dump(char* parms)
 {
   #define CFG_COLS 16
-  
+
   char log[LOGSZ];
   uint16_t idx;
   uint16_t maxrow;
@@ -364,7 +366,7 @@ void CFG_Dump(char* parms)
 
 void CFG_Default()
 {
-  addLog_P(LOG_LEVEL_NONE, PSTR("Cnfg: Use defaults"));
+  addLog_P(LOG_LEVEL_NONE, PSTR(D_LOG_CONFIG D_USE_DEFAULTS));
   CFG_DefaultSet1();
   CFG_DefaultSet2();
   CFG_Save(2);
@@ -379,11 +381,11 @@ void CFG_DefaultSet1()
   sysCfg.version = VERSION;
 //  sysCfg.bootcount = 0;
 }
-  
+
 void CFG_DefaultSet2()
 {
   memset((char*)&sysCfg +16, 0x00, sizeof(SYSCFG) -16);
-  
+
   sysCfg.flag.savestate = SAVE_STATE;
   sysCfg.savedata = SAVE_DATA;
   sysCfg.timezone = APP_TIMEZONE;
@@ -504,7 +506,7 @@ void CFG_DefaultSet2()
 
   // 5.4.1
   memcpy_P(sysCfg.sfb_code[0], sfb_codeDefault, 9);
- 
+
 }
 
 /********************************************************************************************/
@@ -619,7 +621,7 @@ void CFG_Delta()
       strlcpy(sysCfg.friendlyname[1], FRIENDLY_NAME"2", sizeof(sysCfg.friendlyname[1]));
       strlcpy(sysCfg.friendlyname[2], FRIENDLY_NAME"3", sizeof(sysCfg.friendlyname[2]));
       strlcpy(sysCfg.friendlyname[3], FRIENDLY_NAME"4", sizeof(sysCfg.friendlyname[3]));
-    }      
+    }
     if (sysCfg.version < 0x03020800) {  // 3.2.8 - Add parameter
       strlcpy(sysCfg.switch_topic, sysCfg.button_topic, sizeof(sysCfg.switch_topic));
       sysCfg.ex_mqtt_switch_retain = MQTT_SWITCH_RETAIN;
@@ -713,7 +715,7 @@ void CFG_Delta()
       }
       memcpy_P(sysCfg.sfb_code[0], sfb_codeDefault, 9);
     }
-    
+
     sysCfg.version = VERSION;
     CFG_Save(1);
   }
diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino
index 9e04fdee4..c77c2ae55 100644
--- a/sonoff/sonoff.ino
+++ b/sonoff/sonoff.ino
@@ -25,7 +25,7 @@
     - Select IDE Tools - Flash Size: "1M (no SPIFFS)"
   ====================================================*/
 
-#define VERSION                0x05060108  // 5.6.1h
+#define VERSION                0x05060109  // 5.6.1i
 
 enum log_t   {LOG_LEVEL_NONE, LOG_LEVEL_ERROR, LOG_LEVEL_INFO, LOG_LEVEL_DEBUG, LOG_LEVEL_DEBUG_MORE, LOG_LEVEL_ALL};
 enum week_t  {Last, First, Second, Third, Fourth};
@@ -36,10 +36,10 @@ enum swtch_t {TOGGLE, FOLLOW, FOLLOW_INV, PUSHBUTTON, PUSHBUTTON_INV, PUSHBUTTON
 enum led_t   {LED_OFF, LED_POWER, LED_MQTTSUB, LED_POWER_MQTTSUB, LED_MQTTPUB, LED_POWER_MQTTPUB, LED_MQTT, LED_POWER_MQTT, MAX_LED_OPTION};
 enum emul_t  {EMUL_NONE, EMUL_WEMO, EMUL_HUE, EMUL_MAX};
 
-#include "sonoff_template.h"
-
 #include "user_config.h"
 #include "user_config_override.h"
+#include "i18n.h"
+#include "sonoff_template.h"
 
 /*********************************************************************************************\
  * No user configurable items below
@@ -188,17 +188,6 @@ enum opt_t   {P_HOLD_TIME, P_MAX_POWER_RETRY, P_MAX_PARAM8};   // Index in sysCf
 #endif  // USE_SPI
 #include "settings.h"
 
-#define MAX_BUTTON_COMMANDS    5            // Max number of button commands supported
-const char commands[MAX_BUTTON_COMMANDS][14] PROGMEM = {
-  {"wificonfig 1"},   // Press button three times
-  {"wificonfig 2"},   // Press button four times
-  {"wificonfig 3"},   // Press button five times
-  {"restart 1"},      // Press button six times
-  {"upgrade 1"}};     // Press button seven times
-
-const char wificfg[5][12] PROGMEM = { "Restart", "Smartconfig", "Wifimanager", "WPSconfig", "Retry" };
-const char PREFIXES[3][5] PROGMEM = { "cmnd", "stat", "tele" };
-
 struct TIME_T {
   uint8_t       Second;
   uint8_t       Minute;
@@ -342,7 +331,7 @@ void getTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic)
 {
   char romram[CMDSZ];
   String fulltopic;
-  
+
   snprintf_P(romram, sizeof(romram), subtopic);
   if (fallbacktopic) {
     fulltopic = FPSTR(PREFIXES[prefix]);
@@ -460,13 +449,13 @@ void mqtt_publish_sec(const char* topic, const char* data, boolean retained)
 
   if (sysCfg.flag.mqtt_enabled) {
     if (mqttClient.publish(topic, data, retained)) {
-      snprintf_P(log, sizeof(log), PSTR("MQTT: %s = %s%s"), topic, data, (retained) ? " (retained)" : "");
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT "%s = %s%s"), topic, data, (retained) ? " (" D_RETAINED ")" : "");
 //      mqttClient.loop();  // Do not use here! Will block previous publishes
     } else  {
-      snprintf_P(log, sizeof(log), PSTR("RSLT: %s = %s"), topic, data);
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_RESULT "%s = %s"), topic, data);
     }
   } else {
-    snprintf_P(log, sizeof(log), PSTR("RSLT: %s = %s"), strrchr(topic,'/')+1, data);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_RESULT "%s = %s"), strrchr(topic,'/')+1, data);
   }
 
   addLog(LOG_LEVEL_INFO, log);
@@ -503,9 +492,12 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data
  * prefix 6 = tele using subtopic or RESULT
  */
   char romram[16];
-  char stopic[TOPSZ];  
+  char stopic[TOPSZ];
 
-  snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? PSTR("RESULT") : subtopic);
+  snprintf_P(romram, sizeof(romram), ((prefix > 3) && !sysCfg.flag.mqtt_response) ? S_RSLT_RESULT : subtopic);
+  for (byte i = 0; i < strlen(romram); i++) {
+    romram[i] = toupper(romram[i]);
+  }
   prefix &= 3;
   getTopic_P(stopic, prefix, sysCfg.mqtt_topic, romram);
   mqtt_publish(stopic, data, retained);
@@ -519,20 +511,17 @@ void mqtt_publish_topic_P(uint8_t prefix, const char* subtopic, const char* data
 void mqtt_publishPowerState(byte device)
 {
   char stopic[TOPSZ];
-  char sdevice[10];
-  char scommand[10];
+  char scommand[16];
   char svalue[64];  // was MESSZ
 
   if ((device < 1) || (device > Maxdevice)) {
     device = 1;
   }
-  snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device);
-  snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (Maxdevice > 1) ? sdevice : "");
-
-  getTopic_P(stopic, 1, sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response)?"POWER":"RESULT");
+  getPowerDevice(scommand, device, sizeof(scommand));
+  getTopic_P(stopic, 1, sysCfg.mqtt_topic, (sysCfg.flag.mqtt_response) ? scommand : S_RSLT_RESULT);
   snprintf_P(svalue, sizeof(svalue), PSTR("{\"%s\":\"%s\"}"), scommand, getStateText(bitRead(power, device -1)));
   mqtt_publish(stopic, svalue);
-  
+
   getTopic_P(stopic, 1, sysCfg.mqtt_topic, scommand);
   snprintf_P(svalue, sizeof(svalue), PSTR("%s"), getStateText(bitRead(power, device -1)));
   mqtt_publish(stopic, svalue, sysCfg.flag.mqtt_power_retain);
@@ -540,16 +529,16 @@ void mqtt_publishPowerState(byte device)
 
 void mqtt_publishPowerBlinkState(byte device)
 {
-  char sdevice[10];
+  char scommand[16];
   char svalue[64];  // was MESSZ
 
   if ((device < 1) || (device > Maxdevice)) {
     device = 1;
   }
-  snprintf_P(sdevice, sizeof(sdevice), PSTR("%d"), device);
-  snprintf_P(svalue, sizeof(svalue), PSTR("{\"POWER%s\":\"BLINK %s\"}"),
-    (Maxdevice > 1) ? sdevice : "", getStateText(bitRead(blink_mask, device -1)));
-  mqtt_publish_topic_P(5, PSTR("POWER"), svalue);
+  snprintf_P(svalue, sizeof(svalue), PSTR("{\"%s\":\"" D_BLINK " %s\"}"),
+    getPowerDevice(scommand, device, sizeof(scommand)), getStateText(bitRead(blink_mask, device -1)));
+
+  mqtt_publish_topic_P(5, S_RSLT_POWER, svalue);
 }
 
 void mqtt_connected()
@@ -561,8 +550,8 @@ void mqtt_connected()
 
     // Satisfy iobroker (#299)
     svalue[0] = '\0';
-    mqtt_publish_topic_P(0, PSTR("POWER"), svalue);
-    
+    mqtt_publish_topic_P(0, S_RSLT_POWER, svalue);
+
     getTopic_P(stopic, 0, sysCfg.mqtt_topic, PSTR("#"));
     mqttClient.subscribe(stopic);
     mqttClient.loop();  // Solve LmacRxBlk:1 messages
@@ -582,19 +571,19 @@ void mqtt_connected()
   }
 
   if (mqttflag) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"Module\":\"%s\", \"Version\":\"%s\", \"FallbackTopic\":\"%s\", \"GroupTopic\":\"%s\"}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULE "\":\"%s\", \"" D_VERSION "\":\"%s\", \"" D_FALLBACKTOPIC "\":\"%s\", \"" D_CMND_GROUPTOPIC "\":\"%s\"}"),
       my_module.name, Version, MQTTClient, sysCfg.mqtt_grptopic);
-    mqtt_publish_topic_P(2, PSTR("INFO1"), svalue);
+    mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "1"), svalue);
 #ifdef USE_WEBSERVER
     if (sysCfg.webserver) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebserverMode\":\"%s\", \"Hostname\":\"%s\", \"IPaddress\":\"%s\"}"),
-        (2 == sysCfg.webserver) ? "Admin" : "User", Hostname, WiFi.localIP().toString().c_str());
-      mqtt_publish_topic_P(2, PSTR("INFO2"), svalue);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_WEBSERVER_MODE "\":\"%s\", \"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\"}"),
+        (2 == sysCfg.webserver) ? D_ADMIN : D_USER, Hostname, WiFi.localIP().toString().c_str());
+      mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "2"), svalue);
     }
 #endif  // USE_WEBSERVER
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"Started\":\"%s\"}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_RESTARTREASON "\":\"%s\"}"),
       (getResetReason() == "Exception") ? ESP.getResetInfo().c_str() : getResetReason().c_str());
-    mqtt_publish_topic_P(2, PSTR("INFO3"), svalue);
+    mqtt_publish_topic_P(2, PSTR(D_RSLT_INFO "3"), svalue);
     if (sysCfg.tele_period) {
       tele_period = sysCfg.tele_period -9;
     }
@@ -623,17 +612,17 @@ void mqtt_reconnect()
 #endif  // USE_EMULATION
   if (mqttflag > 1) {
 #ifdef USE_MQTT_TLS
-    addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verify TLS fingerprint..."));
+    addLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_FINGERPRINT));
     if (!espClient.connect(sysCfg.mqtt_host, sysCfg.mqtt_port)) {
-      snprintf_P(log, sizeof(log), PSTR("MQTT: TLS Connect FAILED to %s:%d. Retry in %d seconds"),
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT D_TLS_CONNECT_FAILED_TO " %s:%d. " D_RETRY_IN " %d " D_UNIT_SECOND),
         sysCfg.mqtt_host, sysCfg.mqtt_port, mqttcounter);
       addLog(LOG_LEVEL_DEBUG, log);
       return;
     }
     if (espClient.verify(sysCfg.mqtt_fingerprint, sysCfg.mqtt_host)) {
-      addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Verified"));
+      addLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_VERIFIED));
     } else {
-      addLog_P(LOG_LEVEL_DEBUG, PSTR("MQTT: Insecure connection due to invalid Fingerprint"));
+      addLog_P(LOG_LEVEL_DEBUG, S_LOG_MQTT, PSTR(D_INSECURE));
     }
 #endif  // USE_MQTT_TLS
     mqttClient.setCallback(mqttDataCb);
@@ -642,7 +631,7 @@ void mqtt_reconnect()
     return;
   }
 
-  addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Attempting connection..."));
+  addLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_ATTEMPTING_CONNECTION));
 #ifndef USE_MQTT_TLS
 #ifdef USE_DISCOVERY
 #ifdef MQTT_HOST_DISCOVERY
@@ -652,16 +641,16 @@ void mqtt_reconnect()
 #endif  // USE_MQTT_TLS
   mqttClient.setServer(sysCfg.mqtt_host, sysCfg.mqtt_port);
 
-  getTopic_P(stopic, 2, sysCfg.mqtt_topic, PSTR("LWT"));
-  snprintf_P(svalue, sizeof(svalue), PSTR("Offline"));
+  getTopic_P(stopic, 2, sysCfg.mqtt_topic, S_LWT);
+  snprintf_P(svalue, sizeof(svalue), S_OFFLINE);
   if (mqttClient.connect(MQTTClient, sysCfg.mqtt_user, sysCfg.mqtt_pwd, stopic, 1, true, svalue)) {
-    addLog_P(LOG_LEVEL_INFO, PSTR("MQTT: Connected"));
+    addLog_P(LOG_LEVEL_INFO, S_LOG_MQTT, PSTR(D_CONNECTED));
     mqttcounter = 0;
-    snprintf_P(svalue, sizeof(svalue), PSTR("Online"));
+    snprintf_P(svalue, sizeof(svalue), PSTR(D_ONLINE));
     mqtt_publish(stopic, svalue, true);
     mqtt_connected();
   } else {
-    snprintf_P(log, sizeof(log), PSTR("MQTT: Connect FAILED to %s:%d, rc %d. Retry in %d seconds"),
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT D_CONNECT_FAILED_TO " %s:%d, rc %d. " D_RETRY_IN " %d " D_UNIT_SECOND),
       sysCfg.mqtt_host, sysCfg.mqtt_port, mqttClient.state(), mqttcounter);  //status codes are documented here http://pubsubclient.knolleary.net/api.html#state
     addLog(LOG_LEVEL_INFO, log);
   }
@@ -676,29 +665,29 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
   char stemp2[10];
   char scommand[CMDSZ];
   uint16_t i;
-  
-  if (!strcmp_P(type,PSTR("MQTTHOST"))) {
+
+  if (!strcasecmp_P(type, PSTR(D_CMND_MQTTHOST))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_host))) {
       strlcpy(sysCfg.mqtt_host, (1 == payload) ? MQTT_HOST : dataBuf, sizeof(sysCfg.mqtt_host));
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttHost\",\"%s\"}"), sysCfg.mqtt_host);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTHOST "\":\"%s\"}"), sysCfg.mqtt_host);
   }
-  else if (!strcmp_P(type,PSTR("MQTTPORT"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTPORT))) {
     if ((payload > 0) && (payload < 32766)) {
       sysCfg.mqtt_port = (1 == payload) ? MQTT_PORT : payload;
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttPort\":%d}"), sysCfg.mqtt_port);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTPORT "\":%d}"), sysCfg.mqtt_port);
   }
-  else if (!strcmp_P(type,PSTR("MQTTRETRY"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTRETRY))) {
     if ((payload >= MQTT_RETRY_SECS) && (payload < 32001)) {
       sysCfg.mqtt_retry = payload;
       mqttcounter = sysCfg.mqtt_retry;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttRetry\":%d}"), sysCfg.mqtt_retry);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTRETRY "\":%d}"), sysCfg.mqtt_retry);
   }
-  else if (!strcmp_P(type,PSTR("STATETEXT")) && (index > 0) && (index <= 4)) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_STATETEXT)) && (index > 0) && (index <= 4)) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.state_text[0]))) {
       for(i = 0; i <= data_len; i++) {
         if (dataBuf[i] == ' ') {
@@ -707,39 +696,39 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       strlcpy(sysCfg.state_text[index -1], dataBuf, sizeof(sysCfg.state_text[0]));
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"StateText%d\":\"%s\"}"), index, getStateText(index -1));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_STATETEXT "%d\":\"%s\"}"), index, getStateText(index -1));
   }
 #ifdef USE_MQTT_TLS
-  else if (!strcmp_P(type,PSTR("MQTTFINGERPRINT"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTFINGERPRINT))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_fingerprint))) {
       strlcpy(sysCfg.mqtt_fingerprint, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_FINGERPRINT : dataBuf, sizeof(sysCfg.mqtt_fingerprint));
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttFingerprint\":\"%s\"}"), sysCfg.mqtt_fingerprint);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTFINGERPRINT "\":\"%s\"}"), sysCfg.mqtt_fingerprint);
   }
 #endif
-  else if (!grpflg && !strcmp_P(type,PSTR("MQTTCLIENT"))) {
+  else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_MQTTCLIENT))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_client))) {
       strlcpy(sysCfg.mqtt_client, (1 == payload) ? MQTT_CLIENT_ID : dataBuf, sizeof(sysCfg.mqtt_client));
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttClient\":\"%s\"}"), sysCfg.mqtt_client);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTCLIENT "\":\"%s\"}"), sysCfg.mqtt_client);
   }
-  else if (!strcmp_P(type,PSTR("MQTTUSER"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTUSER))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_user))) {
       strlcpy(sysCfg.mqtt_user, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_USER : dataBuf, sizeof(sysCfg.mqtt_user));
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttUser\":\"%s\"}"), sysCfg.mqtt_user);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTUSER "\":\"%s\"}"), sysCfg.mqtt_user);
   }
-  else if (!strcmp_P(type,PSTR("MQTTPASSWORD"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MQTTPASSWORD))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_pwd))) {
       strlcpy(sysCfg.mqtt_pwd, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? MQTT_PASS : dataBuf, sizeof(sysCfg.mqtt_pwd));
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MqttPassword\":\"%s\"}"), sysCfg.mqtt_pwd);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MQTTPASSWORD "\":\"%s\"}"), sysCfg.mqtt_pwd);
   }
-  else if (!strcmp_P(type,PSTR("FULLTOPIC"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_FULLTOPIC))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_fulltopic))) {
       mqttfy(1, dataBuf);
       if (!strcmp(dataBuf, MQTTClient)) {
@@ -747,23 +736,23 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       strlcpy(stemp1, (1 == payload) ? MQTT_FULLTOPIC : dataBuf, sizeof(stemp1));
       if (strcmp(stemp1, sysCfg.mqtt_fulltopic)) {
-        mqtt_publish_topic_P(2, PSTR("LWT"), (sysCfg.flag.mqtt_offline) ? "Offline" : "", true);  // Offline or remove previous retained topic
+        mqtt_publish_topic_P(2, PSTR(D_LWT), (sysCfg.flag.mqtt_offline) ? D_OFFLINE : "", true);  // Offline or remove previous retained topic
         strlcpy(sysCfg.mqtt_fulltopic, stemp1, sizeof(sysCfg.mqtt_fulltopic));
         restartflag = 2;
       }
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"FullTopic\":\"%s\"}"), sysCfg.mqtt_fulltopic);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_FULLTOPIC "\":\"%s\"}"), sysCfg.mqtt_fulltopic);
   }
-  else if (!strcmp_P(type,PSTR("PREFIX")) && (index > 0) && (index <= 3)) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_PREFIX)) && (index > 0) && (index <= 3)) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_prefix[0]))) {
       mqttfy(0, dataBuf);
       strlcpy(sysCfg.mqtt_prefix[index -1], (1 == payload) ? (1==index)?SUB_PREFIX:(2==index)?PUB_PREFIX:PUB_PREFIX2 : dataBuf, sizeof(sysCfg.mqtt_prefix[0]));
 //      if (sysCfg.mqtt_prefix[index -1][strlen(sysCfg.mqtt_prefix[index -1])] == '/') sysCfg.mqtt_prefix[index -1][strlen(sysCfg.mqtt_prefix[index -1])] = 0;
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Prefix%d\":\"%s\"}"), index, sysCfg.mqtt_prefix[index -1]);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_PREFIX "%d\":\"%s\"}"), index, sysCfg.mqtt_prefix[index -1]);
   }
-  else if (!strcmp_P(type,PSTR("GROUPTOPIC"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_GROUPTOPIC))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_grptopic))) {
       mqttfy(0, dataBuf);
       if (!strcmp(dataBuf, MQTTClient)) {
@@ -772,9 +761,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       strlcpy(sysCfg.mqtt_grptopic, (1 == payload) ? MQTT_GRPTOPIC : dataBuf, sizeof(sysCfg.mqtt_grptopic));
       restartflag = 2;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"GroupTopic\":\"%s\"}"), sysCfg.mqtt_grptopic);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_GROUPTOPIC "\":\"%s\"}"), sysCfg.mqtt_grptopic);
   }
-  else if (!grpflg && !strcmp_P(type,PSTR("TOPIC"))) {
+  else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_TOPIC))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.mqtt_topic))) {
       mqttfy(0, dataBuf);
       if (!strcmp(dataBuf, MQTTClient)) {
@@ -782,14 +771,14 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       strlcpy(stemp1, (1 == payload) ? MQTT_TOPIC : dataBuf, sizeof(stemp1));
       if (strcmp(stemp1, sysCfg.mqtt_topic)) {
-        mqtt_publish_topic_P(2, PSTR("LWT"), (sysCfg.flag.mqtt_offline) ? "Offline" : "", true);  // Offline or remove previous retained topic
+        mqtt_publish_topic_P(2, PSTR(D_LWT), (sysCfg.flag.mqtt_offline) ? D_OFFLINE : "", true);  // Offline or remove previous retained topic
         strlcpy(sysCfg.mqtt_topic, stemp1, sizeof(sysCfg.mqtt_topic));
         restartflag = 2;
       }
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Topic\":\"%s\"}"), sysCfg.mqtt_topic);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_TOPIC "\":\"%s\"}"), sysCfg.mqtt_topic);
   }
-  else if (!grpflg && !strcmp_P(type,PSTR("BUTTONTOPIC"))) {
+  else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_BUTTONTOPIC))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.button_topic))) {
       mqttfy(0, dataBuf);
       if (!strcmp(dataBuf, MQTTClient)) {
@@ -797,9 +786,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       strlcpy(sysCfg.button_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.button_topic));
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"ButtonTopic\":\"%s\"}"), sysCfg.button_topic);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_BUTTONTOPIC "\":\"%s\"}"), sysCfg.button_topic);
   }
-  else if (!grpflg && !strcmp_P(type,PSTR("SWITCHTOPIC"))) {
+  else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_SWITCHTOPIC))) {
     if ((data_len > 0) && (data_len < sizeof(sysCfg.switch_topic))) {
       mqttfy(0, dataBuf);
       if (!strcmp(dataBuf, MQTTClient)) {
@@ -807,9 +796,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       strlcpy(sysCfg.switch_topic, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? sysCfg.mqtt_topic : dataBuf, sizeof(sysCfg.switch_topic));
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"SwitchTopic\":\"%s\"}"), sysCfg.switch_topic);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SWITCHTOPIC "\":\"%s\"}"), sysCfg.switch_topic);
   }
-  else if (!strcmp_P(type,PSTR("BUTTONRETAIN"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_BUTTONRETAIN))) {
     if ((payload >= 0) && (payload <= 1)) {
       strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
       if (!payload) {
@@ -819,9 +808,9 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       sysCfg.flag.mqtt_button_retain = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"ButtonRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_BUTTONRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_button_retain));
   }
-  else if (!strcmp_P(type,PSTR("SWITCHRETAIN"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SWITCHRETAIN))) {
     if ((payload >= 0) && (payload <= 1)) {
       strlcpy(sysCfg.button_topic, sysCfg.mqtt_topic, sizeof(sysCfg.button_topic));
       if (!payload) {
@@ -831,31 +820,29 @@ boolean mqtt_command(boolean grpflg, char *type, uint16_t index, char *dataBuf,
       }
       sysCfg.flag.mqtt_switch_retain = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"SwitchRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SWITCHRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_switch_retain));
   }
-  else if (!strcmp_P(type,PSTR("POWERRETAIN"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_POWERRETAIN))) {
     if ((payload >= 0) && (payload <= 1)) {
       if (!payload) {
         for(i = 1; i <= Maxdevice; i++) {  // Clear MQTT retain in broker
-          snprintf_P(stemp2, sizeof(stemp2), PSTR("%d"), i);
-          snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (Maxdevice > 1) ? stemp2 : "");
-          getTopic_P(stemp1, 1, sysCfg.mqtt_topic, scommand);
+          getTopic_P(stemp1, 1, sysCfg.mqtt_topic, getPowerDevice(scommand, i, sizeof(scommand)));
           mqtt_publish(stemp1, "", sysCfg.flag.mqtt_power_retain);
         }
       }
       sysCfg.flag.mqtt_power_retain = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"PowerRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_POWERRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_power_retain));
   }
-  else if (!strcmp_P(type,PSTR("SENSORRETAIN"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SENSORRETAIN))) {
     if ((payload >= 0) && (payload <= 1)) {
       if (!payload) {
         svalue[0] = '\0';
-        mqtt_publish_topic_P(2, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain);
+        mqtt_publish_topic_P(2, PSTR(D_RSLT_SENSOR), svalue, sysCfg.flag.mqtt_sensor_retain);
       }
       sysCfg.flag.mqtt_sensor_retain = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"SensorRetain\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_sensor_retain));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SENSORRETAIN "\":\"%s\"}"), getStateText(sysCfg.flag.mqtt_sensor_retain));
   }
 
 #ifdef USE_DOMOTICZ
@@ -879,7 +866,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
     str = strstr(topic,sysCfg.mqtt_prefix[0]);
     if ((str == topic) && mqtt_cmnd_publish) {
       if (mqtt_cmnd_publish > 8) {
-        mqtt_cmnd_publish -= 8; 
+        mqtt_cmnd_publish -= 8;
       } else {
         mqtt_cmnd_publish = 0;
       }
@@ -906,7 +893,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
   memcpy(dataBuf, data, sizeof(dataBuf));
   dataBuf[sizeof(dataBuf)-1] = 0;
 
-  snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: Receive topic %s, data size %d, data %s"), topicBuf, data_len, dataBuf);
+  snprintf_P(svalue, sizeof(svalue), PSTR(D_LOG_RESULT D_RECEIVED_TOPIC " %s, " D_DATA_SIZE " %d, " D_DATA " %s"),
+    topicBuf, data_len, dataBuf);
   addLog(LOG_LEVEL_DEBUG_MORE, svalue);
 //  if (LOG_LEVEL_DEBUG_MORE <= seriallog_level) Serial.println(dataBuf);
 
@@ -940,12 +928,12 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
     dataBufUc[i] = toupper(dataBuf[i]);
   }
 
-  snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: DataCb Group %d, Index %d, Type %s, Data %s (%s)"),
+  snprintf_P(svalue, sizeof(svalue), PSTR(D_LOG_RESULT D_GROUP " %d, " D_INDEX " %d, " D_COMMAND " %s, " D_DATA " %s (%s)"),
     grpflg, index, type, dataBuf, dataBufUc);
   addLog(LOG_LEVEL_DEBUG, svalue);
 
   if (type != NULL) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"Command\":\"Error\"}"));
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_COMMAND "\":\"" D_ERROR "\"}"));
     if (sysCfg.ledstate &0x02) {
       blinks++;
     }
@@ -962,26 +950,26 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
     }
     blogdelay = MIN_BACKLOG_DELAY;       // Reset backlog delay
 
-    if (!strcmp_P(dataBufUc,PSTR("OFF")) || !strcmp_P(dataBufUc,PSTR("FALSE")) || !strcmp_P(dataBufUc,PSTR("STOP")) || !strcmp_P(dataBufUc,PSTR("CELSIUS"))) {
+    if (!strcasecmp_P(dataBuf, PSTR(D_OFF)) || !strcasecmp_P(dataBuf, PSTR(D_FALSE)) || !strcasecmp_P(dataBuf, PSTR(D_STOP)) || !strcasecmp_P(dataBuf, PSTR(D_CELSIUS))) {
       payload = 0;
     }
-    if (!strcmp_P(dataBufUc,PSTR("ON")) || !strcmp_P(dataBufUc,PSTR("TRUE")) || !strcmp_P(dataBufUc,PSTR("START")) || !strcmp_P(dataBufUc,PSTR("FAHRENHEIT")) || !strcmp_P(dataBufUc,PSTR("USER"))) {
+    if (!strcasecmp_P(dataBuf, PSTR(D_ON)) || !strcasecmp_P(dataBuf, PSTR(D_TRUE)) || !strcasecmp_P(dataBuf, PSTR(D_START)) || !strcasecmp_P(dataBuf, PSTR(D_FAHRENHEIT)) || !strcasecmp_P(dataBuf, PSTR(D_USER))) {
       payload = 1;
     }
-    if (!strcmp_P(dataBufUc,PSTR("TOGGLE")) || !strcmp_P(dataBufUc,PSTR("ADMIN"))) {
+    if (!strcasecmp_P(dataBuf, PSTR(D_TOGGLE)) || !strcasecmp_P(dataBuf, PSTR(D_ADMIN))) {
       payload = 2;
     }
-    if (!strcmp_P(dataBufUc,PSTR("BLINK"))) {
+    if (!strcasecmp_P(dataBuf, PSTR(D_BLINK))) {
       payload = 3;
     }
-    if (!strcmp_P(dataBufUc,PSTR("BLINKOFF"))) {
+    if (!strcasecmp_P(dataBuf, PSTR(D_BLINKOFF))) {
       payload = 4;
     }
 
 //    snprintf_P(svalue, sizeof(svalue), PSTR("RSLT: Payload %d, Payload16 %d"), payload, payload16);
 //    addLog(LOG_LEVEL_DEBUG, svalue);
 
-    if (!strcmp_P(type,PSTR("BACKLOG"))) {
+    if (!strcasecmp_P(type, PSTR(D_CMND_BACKLOG))) {
       if (data_len) {
         char *blcommand = strtok(dataBuf, ";");
         while (blcommand != NULL) {
@@ -995,20 +983,20 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
           blogidx &= 0xF;
           blcommand = strtok(NULL, ";");
         }
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Backlog\":\"Appended\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BACKLOG "\":\"" D_APPENDED "\"}"));
       } else {
         uint8_t blflag = (blogptr == blogidx);
         blogptr = blogidx;
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Backlog\":\"%s\"}"), blflag ? "Empty" : "Aborted");
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BACKLOG "\":\"%s\"}"), blflag ? D_EMPTY : D_ABORTED);
       }
     }
-    else if (!strcmp_P(type,PSTR("DELAY"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_DELAY))) {
       if ((payload >= MIN_BACKLOG_DELAY) && (payload <= 3600)) {
         blogdelay = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Delay\":%d}"), blogdelay);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_DELAY "\":%d}"), blogdelay);
     }
-    else if (!strcmp_P(type,PSTR("POWER")) && (index > 0) && (index <= Maxdevice)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_POWER)) && (index > 0) && (index <= Maxdevice)) {
       if ((payload < 0) || (payload > 4)) {
         payload = 9;
       }
@@ -1016,7 +1004,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       fallbacktopic = 0;
       return;
     }
-    else if (!strcmp_P(type,PSTR("STATUS"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_STATUS))) {
       if ((payload < 0) || (payload > MAX_STATUS)) {
         payload = 99;
       }
@@ -1024,7 +1012,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       fallbacktopic = 0;
       return;
     }
-    else if ((sysCfg.module != MOTOR) && !strcmp_P(type,PSTR("POWERONSTATE"))) {
+    else if ((sysCfg.module != MOTOR) && !strcasecmp_P(type, PSTR(D_CMND_POWERONSTATE))) {
       /* 0 = Keep relays off after power on
        * 1 = Turn relays on after power on
        * 2 = Toggle relays after power on
@@ -1039,37 +1027,37 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
           }
         }
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"PowerOnState\":%d}"), sysCfg.poweronstate);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_POWERONSTATE "\":%d}"), sysCfg.poweronstate);
     }
-    else if (!strcmp_P(type,PSTR("PULSETIME")) && (index > 0) && (index <= MAX_PULSETIMERS)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_PULSETIME)) && (index > 0) && (index <= MAX_PULSETIMERS)) {
       if (data_len > 0) {
         sysCfg.pulsetime[index -1] = payload16;  // 0 - 65535
         pulse_timer[index -1] = 0;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"PulseTime%d\":%d}"), index, sysCfg.pulsetime[index -1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PULSETIME "%d\":%d}"), index, sysCfg.pulsetime[index -1]);
     }
-    else if (!strcmp_P(type,PSTR("BLINKTIME"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_BLINKTIME))) {
       if ((payload > 2) && (payload <= 3600)) {
         sysCfg.blinktime = payload;
         if (blink_timer) {
           blink_timer = sysCfg.blinktime;
         }
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"BlinkTime\":%d}"), sysCfg.blinktime);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BLINKTIME "\":%d}"), sysCfg.blinktime);
     }
-    else if (!strcmp_P(type,PSTR("BLINKCOUNT"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_BLINKCOUNT))) {
       if (data_len > 0) {
         sysCfg.blinkcount = payload16;  // 0 - 65535
         if (blink_counter) {
           blink_counter = sysCfg.blinkcount *2;
         }
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"BlinkCount\":%d}"), sysCfg.blinkcount);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_BLINKCOUNT "\":%d}"), sysCfg.blinkcount);
     }
     else if (sfl_flg && sl_command(type, index, dataBufUc, data_len, payload, svalue, sizeof(svalue))) {
       // Serviced
     }
-    else if (!strcmp_P(type,PSTR("SAVEDATA"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_SAVEDATA))) {
       if ((payload >= 0) && (payload <= 3600)) {
         sysCfg.savedata = payload;
         savedatacounter = sysCfg.savedata;
@@ -1079,11 +1067,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       }
       CFG_Save(0);
       if (sysCfg.savedata > 1) {
-        snprintf_P(stemp1, sizeof(stemp1), PSTR("Every %d seconds"), sysCfg.savedata);
+        snprintf_P(stemp1, sizeof(stemp1), PSTR(D_EVERY " %d " D_UNIT_SECOND), sysCfg.savedata);
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"SaveData\":\"%s\"}"), (sysCfg.savedata > 1) ? stemp1 : getStateText(sysCfg.savedata));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SAVEDATA "\":\"%s\"}"), (sysCfg.savedata > 1) ? stemp1 : getStateText(sysCfg.savedata));
     }
-    else if (!strcmp_P(type,PSTR("SETOPTION")) && ((index >= 0) && (index <= 14)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_SETOPTION)) && ((index >= 0) && (index <= 14)) || ((index > 31) && (index <= P_MAX_PARAM8 +31))) {
       if (index <= 31) {
         ptype = 0;   // SetOption0 .. 31
       } else {
@@ -1132,45 +1120,45 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       if (ptype) {
         snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), sysCfg.param[index]);
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"SetOption%d\":\"%s\"}"), (ptype) ? index +32 : index, (ptype) ? stemp1 : getStateText(bitRead(sysCfg.flag.data, index)));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SETOPTION "%d\":\"%s\"}"), (ptype) ? index +32 : index, (ptype) ? stemp1 : getStateText(bitRead(sysCfg.flag.data, index)));
     }
-    else if (!strcmp_P(type,PSTR("TEMPRES"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_TEMPERATURE_RESOLUTION))) {
       if ((payload >= 0) && (payload <= 3)) {
         sysCfg.flag.temperature_resolution = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"TempRes\":%d}"), sysCfg.flag.temperature_resolution);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_TEMPERATURE_RESOLUTION "\":%d}"), sysCfg.flag.temperature_resolution);
     }
-    else if (!strcmp_P(type,PSTR("HUMRES"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_HUMIDITY_RESOLUTION))) {
       if ((payload >= 0) && (payload <= 3)) {
         sysCfg.flag.humidity_resolution = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"HumRes\":%d}"), sysCfg.flag.humidity_resolution);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_HUMIDITY_RESOLUTION "\":%d}"), sysCfg.flag.humidity_resolution);
     }
-    else if (!strcmp_P(type,PSTR("PRESSRES"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_PRESSURE_RESOLUTION))) {
       if ((payload >= 0) && (payload <= 3)) {
         sysCfg.flag.pressure_resolution = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"PressRes\":%d}"), sysCfg.flag.pressure_resolution);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PRESSURE_RESOLUTION "\":%d}"), sysCfg.flag.pressure_resolution);
     }
-    else if (!strcmp_P(type,PSTR("WATTRES"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_POWER_RESOLUTION))) {
       if ((payload >= 0) && (payload <= 1)) {
         sysCfg.flag.wattage_resolution = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"WattRes\":%d}"), sysCfg.flag.wattage_resolution);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_POWER_RESOLUTION "\":%d}"), sysCfg.flag.wattage_resolution);
     }
-    else if (!strcmp_P(type,PSTR("VOLTRES"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_VOLTAGE_RESOLUTION))) {
       if ((payload >= 0) && (payload <= 1)) {
         sysCfg.flag.voltage_resolution = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"VoltRes\":%d}"), sysCfg.flag.voltage_resolution);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_VOLTAGE_RESOLUTION "\":%d}"), sysCfg.flag.voltage_resolution);
     }
-    else if (!strcmp_P(type,PSTR("ENERGYRES"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_ENERGY_RESOLUTION))) {
       if ((payload >= 0) && (payload <= 5)) {
         sysCfg.flag.energy_resolution = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"EnergyRes\":%d}"), sysCfg.flag.energy_resolution);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_ENERGY_RESOLUTION "\":%d}"), sysCfg.flag.energy_resolution);
     }
-    else if (!strcmp_P(type,PSTR("MODULE"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_MODULE))) {
       if ((payload > 0) && (payload <= MAXMODULE)) {
         payload--;
         byte new_modflg = (sysCfg.module != payload);
@@ -1183,10 +1171,10 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         restartflag = 2;
       }
       snprintf_P(stemp1, sizeof(stemp1), modules[sysCfg.module].name);
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Module\":\"%d (%s)\"}"), sysCfg.module +1, stemp1);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULE "\":\"%d (%s)\"}"), sysCfg.module +1, stemp1);
     }
-    else if (!strcmp_P(type,PSTR("MODULES"))) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Modules1\":\""), svalue);
+    else if (!strcasecmp_P(type, PSTR(D_CMND_MODULES))) {
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULES "1\":\""), svalue);
       byte jsflg = 0;
       for (byte i = 0; i < MAXMODULE /2; i++) {
         if (jsflg) {
@@ -1198,7 +1186,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       }
       snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
       mqtt_publish_topic_P(5, type, svalue);
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Modules2\":\""), svalue);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_MODULES "2\":\""), svalue);
       jsflg = 0;
       for (byte i = MAXMODULE /2; i < MAXMODULE; i++) {
         if (jsflg) {
@@ -1210,7 +1198,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       }
       snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
     }
-    else if (!strcmp_P(type,PSTR("GPIO")) && (index < MAX_GPIO_PIN)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_GPIO)) && (index < MAX_GPIO_PIN)) {
       mytmplt cmodule;
       memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
       if ((GPIO_USER == cmodule.gp.io[index]) && (payload >= 0) && (payload < GPIO_SENSOR_END)) {
@@ -1231,17 +1219,17 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
           }
           jsflg = 1;
           snprintf_P(stemp1, sizeof(stemp1), sensors[sysCfg.my_module.gp.io[i]]);
-          snprintf_P(svalue, sizeof(svalue), PSTR("%s\"GPIO%d\":%d (%s)"), svalue, i, sysCfg.my_module.gp.io[i], stemp1);
+          snprintf_P(svalue, sizeof(svalue), PSTR("%s\"" D_CMND_GPIO "%d\":%d (%s)"), svalue, i, sysCfg.my_module.gp.io[i], stemp1);
         }
       }
       if (jsflg) {
         snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
       } else {
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"GPIO\":\"Not supported\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_GPIO "\":\"" D_NOT_SUPPORTED "\"}"));
       }
     }
-    else if (!strcmp_P(type,PSTR("GPIOS"))) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"GPIOs1\":\""), svalue);
+    else if (!strcasecmp_P(type, PSTR(D_CMND_GPIOS))) {
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_GPIOS "1\":\""), svalue);
       byte jsflg = 0;
       for (byte i = 0; i < GPIO_SENSOR_END /2; i++) {
         if (jsflg) {
@@ -1253,7 +1241,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       }
       snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
       mqtt_publish_topic_P(5, type, svalue);
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"GPIOs2\":\""), svalue);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_GPIOS "2\":\""), svalue);
       jsflg = 0;
       for (byte i = GPIO_SENSOR_END /2; i < GPIO_SENSOR_END; i++) {
         if (jsflg) {
@@ -1265,43 +1253,43 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       }
       snprintf_P(svalue, sizeof(svalue), PSTR("%s\"}"), svalue);
     }
-    else if (!strcmp_P(type,PSTR("PWM")) && (index > pwm_idxoffset) && (index <= 5)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_PWM)) && (index > pwm_idxoffset) && (index <= 5)) {
       if ((payload >= 0) && (payload <= PWM_RANGE) && (pin[GPIO_PWM1 + index -1] < 99)) {
         sysCfg.pwmvalue[index -1] = payload;
         analogWrite(pin[GPIO_PWM1 + index -1], payload);
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"PWM\":{"));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PWM "\":{"));
       bool first = true;
       for (byte i = 0; i < 5; i++) {
         if(pin[GPIO_PWM1 + i] < 99) {
-          snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PWM%d\":%d"), svalue, first ? "" : ", ", i+1, sysCfg.pwmvalue[i]);
+          snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_PWM "%d\":%d"), svalue, first ? "" : ", ", i+1, sysCfg.pwmvalue[i]);
           first = false;
         }
       }
       snprintf_P(svalue, sizeof(svalue), PSTR("%s}}"),svalue);
     }
-    else if (!strcmp_P(type,PSTR("COUNTER")) && (index > 0) && (index <= MAX_COUNTERS)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_COUNTER)) && (index > 0) && (index <= MAX_COUNTERS)) {
       if ((data_len > 0) && (pin[GPIO_CNTR1 + index -1] < 99)) {
         rtcMem.pCounter[index -1] = payload16;
         sysCfg.pCounter[index -1] = payload16;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Counter%d\":%d}"), index, rtcMem.pCounter[index -1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_COUNTER "%d\":%d}"), index, rtcMem.pCounter[index -1]);
     }
-    else if (!strcmp_P(type,PSTR("COUNTERTYPE")) && (index > 0) && (index <= MAX_COUNTERS)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_COUNTERTYPE)) && (index > 0) && (index <= MAX_COUNTERS)) {
       if ((payload >= 0) && (payload <= 1) && (pin[GPIO_CNTR1 + index -1] < 99)) {
         bitWrite(sysCfg.pCounterType, index -1, payload &1);
         rtcMem.pCounter[index -1] = 0;
         sysCfg.pCounter[index -1] = 0;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"CounterType%d\":%d}"), index, bitRead(sysCfg.pCounterType, index -1));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_COUNTERTYPE "%d\":%d}"), index, bitRead(sysCfg.pCounterType, index -1));
     }
-    else if (!strcmp_P(type,PSTR("COUNTERDEBOUNCE"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_COUNTERDEBOUNCE))) {
       if ((data_len > 0) && (payload16 < 32001)) {
         sysCfg.pCounterDebounce = payload16;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"CounterDebounce\":%d}"), sysCfg.pCounterDebounce);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_COUNTERDEBOUNCE "\":%d}"), sysCfg.pCounterDebounce);
     }
-    else if (!strcmp_P(type,PSTR("SLEEP"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_SLEEP))) {
       if ((payload >= 0) && (payload < 251)) {
         if ((!sysCfg.sleep && payload) || (sysCfg.sleep && !payload)) {
           restartflag = 2;
@@ -1309,62 +1297,62 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         sysCfg.sleep = payload;
         sleep = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Sleep\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " mS" : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " mS" : "");
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SLEEP "\":\"%d%s (%d%s)\"}"), sleep, (sysCfg.flag.value_units) ? " " D_UNIT_MILLISECOND : "", sysCfg.sleep, (sysCfg.flag.value_units) ? " " D_UNIT_MILLISECOND : "");
     }
-    else if (!strcmp_P(type,PSTR("UPGRADE")) || !strcmp_P(type,PSTR("UPLOAD"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_UPGRADE)) || !strcasecmp_P(type, PSTR(D_CMND_UPLOAD))) {
       // Check if the payload is numerically 1, and had no trailing chars.
       //   e.g. "1foo" or "1.2.3" could fool us.
       // Check if the version we have been asked to upgrade to is higher than our current version.
       //   We also need at least 3 chars to make a valid version number string.
       if (((1 == data_len) && (1 == payload)) || ((data_len >= 3) && newerVersion(dataBuf))) {
         otaflag = 3;
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Version %s from %s\"}"), Version, sysCfg.otaUrl);
+        snprintf_P(svalue, sizeof(svalue), "{\"" D_CMND_UPGRADE "\":\"" D_VERSION " %s " D_FROM " %s\"}", Version, sysCfg.otaUrl);
       } else {
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Upgrade\":\"Option 1 or >%s to upgrade\"}"), Version);
+        snprintf_P(svalue, sizeof(svalue), "{\"" D_CMND_UPGRADE "\":\"" D_ONE_OR_GT "\"}", Version);
       }
     }
-    else if (!strcmp_P(type,PSTR("OTAURL"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_OTAURL))) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.otaUrl)))
         strlcpy(sysCfg.otaUrl, (1 == payload) ? OTA_URL : dataBuf, sizeof(sysCfg.otaUrl));
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"OtaUrl\":\"%s\"}"), sysCfg.otaUrl);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_OTAURL "\":\"%s\"}"), sysCfg.otaUrl);
     }
-    else if (!strcmp_P(type,PSTR("SERIALLOG"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_SERIALLOG))) {
       if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
         sysCfg.seriallog_level = payload;
         seriallog_level = payload;
         seriallog_timer = 0;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"SerialLog\":\"%d (Active %d)\"}"), sysCfg.seriallog_level, seriallog_level);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SERIALLOG "\":\"%d (" D_ACTIVE " %d)\"}"), sysCfg.seriallog_level, seriallog_level);
     }
-    else if (!strcmp_P(type,PSTR("SYSLOG"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_SYSLOG))) {
       if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
         sysCfg.syslog_level = payload;
         syslog_level = (sysCfg.flag.emulation) ? 0 : payload;
         syslog_timer = 0;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"SysLog\":\"%d (Active %d)\"}"), sysCfg.syslog_level, syslog_level);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SYSLOG "\":\"%d (" D_ACTIVE " %d)\"}"), sysCfg.syslog_level, syslog_level);
     }
-    else if (!strcmp_P(type,PSTR("LOGHOST"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_LOGHOST))) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.syslog_host))) {
         strlcpy(sysCfg.syslog_host, (1 == payload) ? SYS_LOG_HOST : dataBuf, sizeof(sysCfg.syslog_host));
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"LogHost\":\"%s\"}"), sysCfg.syslog_host);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LOGHOST "\":\"%s\"}"), sysCfg.syslog_host);
     }
-    else if (!strcmp_P(type,PSTR("LOGPORT"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_LOGPORT))) {
       if ((payload > 0) && (payload < 32766)) {
         sysCfg.syslog_port = (1 == payload) ? SYS_LOG_PORT : payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"LogPort\":%d}"), sysCfg.syslog_port);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LOGPORT "\":%d}"), sysCfg.syslog_port);
     }
-    else if (!strcmp_P(type,PSTR("IPADDRESS")) && (index > 0) && (index <= 4)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_IPADDRESS)) && (index > 0) && (index <= 4)) {
       if (parseIP(&address, dataBuf)) {
         sysCfg.ip_address[index -1] = address;
 //        restartflag = 2;
       }
       snprintf_P(stemp1, sizeof(stemp1), PSTR(" (%s)"), WiFi.localIP().toString().c_str());
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"IPAddress%d\":\"%s%s\"}"), index, IPAddress(sysCfg.ip_address[index -1]).toString().c_str(), (1 == index) ? stemp1:"");
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_IPADDRESS "%d\":\"%s%s\"}"), index, IPAddress(sysCfg.ip_address[index -1]).toString().c_str(), (1 == index) ? stemp1:"");
     }
-    else if (!strcmp_P(type,PSTR("NTPSERVER")) && (index > 0) && (index <= 3)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_NTPSERVER)) && (index > 0) && (index <= 3)) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.ntp_server[0]))) {
         strlcpy(sysCfg.ntp_server[index -1], (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? (1==index)?NTP_SERVER1:(2==index)?NTP_SERVER2:NTP_SERVER3 : dataBuf, sizeof(sysCfg.ntp_server[0]));
         for (i = 0; i < strlen(sysCfg.ntp_server[index -1]); i++) {
@@ -1374,9 +1362,9 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         }
         restartflag = 2;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"NtpServer%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_NTPSERVER "%d\":\"%s\"}"), index, sysCfg.ntp_server[index -1]);
     }
-    else if (!strcmp_P(type,PSTR("AP"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_AP))) {
       if ((payload >= 0) && (payload <= 2)) {
         switch (payload) {
         case 0:  // Toggle
@@ -1388,25 +1376,25 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         }
         restartflag = 2;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Ap\":\"%d (%s)\"}"), sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_AP "\":\"%d (%s)\"}"), sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active]);
     }
-    else if (!strcmp_P(type,PSTR("SSID")) && (index > 0) && (index <= 2)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_SSID)) && (index > 0) && (index <= 2)) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.sta_ssid[0]))) {
         strlcpy(sysCfg.sta_ssid[index -1], (1 == payload) ? (1 == index) ? STA_SSID1 : STA_SSID2 : dataBuf, sizeof(sysCfg.sta_ssid[0]));
         sysCfg.sta_active = 0;
         restartflag = 2;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"SSid%d\":\"%s\"}"), index, sysCfg.sta_ssid[index -1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SSID "%d\":\"%s\"}"), index, sysCfg.sta_ssid[index -1]);
     }
-    else if (!strcmp_P(type,PSTR("PASSWORD")) && (index > 0) && (index <= 2)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_PASSWORD)) && (index > 0) && (index <= 2)) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.sta_pwd[0]))) {
         strlcpy(sysCfg.sta_pwd[index -1], (1 == payload) ? (1 == index) ? STA_PASS1 : STA_PASS2 : dataBuf, sizeof(sysCfg.sta_pwd[0]));
         sysCfg.sta_active = 0;
         restartflag = 2;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Password%d\":\"%s\"}"), index, sysCfg.sta_pwd[index -1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_PASSWORD "%d\":\"%s\"}"), index, sysCfg.sta_pwd[index -1]);
     }
-    else if (!grpflg && !strcmp_P(type,PSTR("HOSTNAME"))) {
+    else if (!grpflg && !strcasecmp_P(type, PSTR(D_CMND_HOSTNAME))) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.hostname))) {
         strlcpy(sysCfg.hostname, (1 == payload) ? WIFI_HOSTNAME : dataBuf, sizeof(sysCfg.hostname));
         if (strstr(sysCfg.hostname,"%")) {
@@ -1414,24 +1402,24 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         }
         restartflag = 2;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Hostname\":\"%s\"}"), sysCfg.hostname);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_HOSTNAME "\":\"%s\"}"), sysCfg.hostname);
     }
-    else if (!strcmp_P(type,PSTR("WIFICONFIG"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_WIFICONFIG))) {
       if ((payload >= WIFI_RESTART) && (payload < MAX_WIFI_OPTION)) {
         sysCfg.sta_config = payload;
         wificheckflag = sysCfg.sta_config;
         snprintf_P(stemp1, sizeof(stemp1), wificfg[sysCfg.sta_config]);
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"WifiConfig\":\"%s selected\"}"), stemp1);
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WIFICONFIG "\":\"%s " D_SELECTED "\"}"), stemp1);
         if (WIFI_State() != WIFI_RESTART) {
 //          snprintf_P(svalue, sizeof(svalue), PSTR("%s after restart"), svalue);
           restartflag = 2;
         }
       } else {
         snprintf_P(stemp1, sizeof(stemp1), wificfg[sysCfg.sta_config]);
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"WifiConfig\":\"%d (%s)\"}"), sysCfg.sta_config, stemp1);
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WIFICONFIG "\":\"%d (%s)\"}"), sysCfg.sta_config, stemp1);
       }
     }
-    else if (!strcmp_P(type,PSTR("FRIENDLYNAME")) && (index > 0) && (index <= 4)) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_FRIENDLYNAME)) && (index > 0) && (index <= 4)) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.friendlyname[0]))) {
         if (1 == index) {
           snprintf_P(stemp1, sizeof(stemp1), PSTR(FRIENDLY_NAME));
@@ -1440,49 +1428,49 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         }
         strlcpy(sysCfg.friendlyname[index -1], (1 == payload) ? stemp1 : dataBuf, sizeof(sysCfg.friendlyname[index -1]));
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"FriendlyName%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_FRIENDLYNAME "%d\":\"%s\"}"), index, sysCfg.friendlyname[index -1]);
     }
-    else if (swt_flg && !strcmp_P(type,PSTR("SWITCHMODE")) && (index > 0) && (index <= 4)) {
+    else if (swt_flg && !strcasecmp_P(type, PSTR(D_CMND_SWITCHMODE)) && (index > 0) && (index <= 4)) {
       if ((payload >= 0) && (payload < MAX_SWITCH_OPTION)) {
         sysCfg.switchmode[index -1] = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"SwitchMode%d\":%d}"), index, sysCfg.switchmode[index-1]);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_SWITCHMODE "%d\":%d}"), index, sysCfg.switchmode[index-1]);
     }
 #ifdef USE_WEBSERVER
-    else if (!strcmp_P(type,PSTR("WEBSERVER"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_WEBSERVER))) {
       if ((payload >= 0) && (payload <= 2)) {
         sysCfg.webserver = payload;
       }
       if (sysCfg.webserver) {
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Webserver\":\"Active for %s on %s with IP address %s\"}"),
-          (2 == sysCfg.webserver) ? "ADMIN" : "USER", Hostname, WiFi.localIP().toString().c_str());
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBSERVER "\":\"" D_ACTIVE_FOR " %s " D_ON_DEVICE " %s " D_WITH_IP_ADDRESS " %s\"}"),
+          (2 == sysCfg.webserver) ? D_ADMIN : D_USER, Hostname, WiFi.localIP().toString().c_str());
       } else {
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Webserver\":\"%s\"}"), getStateText(0));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBSERVER "\":\"%s\"}"), getStateText(0));
       }
     }
-    else if (!strcmp_P(type,PSTR("WEBPASSWORD"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_WEBPASSWORD))) {
       if ((data_len > 0) && (data_len < sizeof(sysCfg.web_password))) {
         strlcpy(sysCfg.web_password, (!strcmp(dataBuf,"0")) ? "" : (1 == payload) ? WEB_PASSWORD : dataBuf, sizeof(sysCfg.web_password));
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebPassword\":\"%s\"}"), sysCfg.web_password);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBPASSWORD "\":\"%s\"}"), sysCfg.web_password);
     }
-    else if (!strcmp_P(type,PSTR("WEBLOG"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_WEBLOG))) {
       if ((payload >= LOG_LEVEL_NONE) && (payload <= LOG_LEVEL_ALL)) {
         sysCfg.weblog_level = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"WebLog\":%d}"), sysCfg.weblog_level);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WEBLOG "\":%d}"), sysCfg.weblog_level);
     }
 #ifdef USE_EMULATION
-    else if (!strcmp_P(type,PSTR("EMULATION"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_EMULATION))) {
       if ((payload >= 0) && (payload <= 2)) {
         sysCfg.flag.emulation = payload;
         restartflag = 2;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Emulation\":%d}"), sysCfg.flag.emulation);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_EMULATION "\":%d}"), sysCfg.flag.emulation);
     }
 #endif  // USE_EMULATION
 #endif  // USE_WEBSERVER
-    else if (!strcmp_P(type,PSTR("TELEPERIOD"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_TELEPERIOD))) {
       if ((payload >= 0) && (payload < 3601)) {
         sysCfg.tele_period = (1 == payload) ? TELE_PERIOD : payload;
         if ((sysCfg.tele_period > 0) && (sysCfg.tele_period < 10)) {
@@ -1490,43 +1478,43 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         }
         tele_period = sysCfg.tele_period;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"TelePeriod\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.flag.value_units) ? " Sec" : "");
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_TELEPERIOD "\":\"%d%s\"}"), sysCfg.tele_period, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : "");
     }
-    else if (!strcmp_P(type,PSTR("RESTART"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_RESTART))) {
       switch (payload) {
       case 1:
         restartflag = 2;
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Restart\":\"Restarting\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESTART "\":\"" D_RESTARTING "\"}"));
         break;
       case 99:
-        addLog_P(LOG_LEVEL_INFO, PSTR("APP: Restarting"));
+        addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
         ESP.restart();
         break;
       default:
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Restart\":\"1 to restart\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESTART "\":\"" D_ONE_TO_RESTART "\"}"));
       }
     }
-    else if (!strcmp_P(type,PSTR("RESET"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_RESET))) {
       switch (payload) {
       case 1:
         restartflag = 211;
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Reset\":\"Reset and Restarting\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESET "\":\"" D_RESET_AND_RESTARTING "\"}"));
         break;
       case 2:
         restartflag = 212;
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Reset\":\"Erase, Reset and Restarting\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESET "\":\"" D_ERASE ", " D_RESET_AND_RESTARTING "\"}"));
         break;
       default:
-        snprintf_P(svalue, sizeof(svalue), PSTR("{\"Reset\":\"1 to reset\"}"));
+        snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RESET "\":\"" D_ONE_TO_RESET "\"}"));
       }
     }
-    else if (!strcmp_P(type,PSTR("TIMEZONE"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_TIMEZONE))) {
       if ((data_len > 0) && (((payload >= -12) && (payload <= 12)) || (99 == payload))) {
         sysCfg.timezone = payload;
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Timezone\":%d}"), sysCfg.timezone);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_TIMEZONE "\":%d}"), sysCfg.timezone);
     }
-    else if (!strcmp_P(type,PSTR("LEDPOWER"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_LEDPOWER))) {
       if ((payload >= 0) && (payload <= 2)) {
         sysCfg.ledstate &= 8;
         switch (payload) {
@@ -1541,20 +1529,20 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
         blinks = 0;
         setLed(sysCfg.ledstate &8);
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedPower\":\"%s\"}"), getStateText(bitRead(sysCfg.ledstate, 3)));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LEDPOWER "\":\"%s\"}"), getStateText(bitRead(sysCfg.ledstate, 3)));
     }
-    else if (!strcmp_P(type,PSTR("LEDSTATE"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_LEDSTATE))) {
       if ((payload >= 0) && (payload < MAX_LED_OPTION)) {
         sysCfg.ledstate = payload;
         if (!sysCfg.ledstate) {
           setLed(0);
         }
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"LedState\":%d}"), sysCfg.ledstate);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_LEDSTATE "\":%d}"), sysCfg.ledstate);
     }
-    else if (!strcmp_P(type,PSTR("CFGDUMP"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_CFGDUMP))) {
       CFG_Dump(dataBuf);
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"CfgDump\":\"Done\"}"));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_CFGDUMP "\":\"" D_DONE "\"}"));
     }
     else if (sysCfg.flag.mqtt_enabled && mqtt_command(grpflg, type, index, dataBuf, data_len, payload, svalue, sizeof(svalue))) {
       // Serviced
@@ -1566,7 +1554,7 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
       // Serviced
     }
 #ifdef USE_I2C
-    else if (i2c_flg && !strcmp_P(type,PSTR("I2CSCAN"))) {
+    else if (i2c_flg && !strcasecmp_P(type, PSTR(D_CMND_I2CSCAN))) {
       i2c_scan(svalue, sizeof(svalue));
     }
 #endif  // USE_I2C
@@ -1581,11 +1569,11 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
     }
 #endif  // USE_IR_REMOTE
 #ifdef DEBUG_THEO
-    else if (!strcmp_P(type,PSTR("EXCEPTION"))) {
+    else if (!strcasecmp_P(type, PSTR(D_CMND_EXCEPTION))) {
       if (data_len > 0) {
         exception_tst(payload);
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"Exception\":\"Triggered\"}"));
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_EXCEPTION "\":\"" D_DONE "\"}"));
     }
 #endif  // DEBUG_THEO
     else {
@@ -1594,8 +1582,8 @@ void mqttDataCb(char* topic, byte* data, unsigned int data_len)
   }
   if (type == NULL) {
     blinks = 201;
-    snprintf_P(topicBuf, sizeof(topicBuf), PSTR("COMMAND"));
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"Command\":\"Unknown\"}"));
+    snprintf_P(topicBuf, sizeof(topicBuf), PSTR(D_COMMAND));
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_COMMAND "\":\"" D_UNKNOWN "\"}"));
     type = (char*)topicBuf;
   }
   if (svalue[0] != '\0') {
@@ -1627,10 +1615,13 @@ boolean send_button_power(byte key, byte device, byte state)
     if (!key && (device > Maxdevice)) {
       device = 1;
     }
-    snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
-    snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (key || (Maxdevice > 1)) ? stemp1 : "");
-    getTopic_P(stopic, 0, key_topic, scommand);
-  
+
+//    snprintf_P(stemp1, sizeof(stemp1), PSTR("%d"), device);
+//    snprintf_P(scommand, sizeof(scommand), PSTR("POWER%s"), (key || (Maxdevice > 1)) ? stemp1 : "");
+//    getTopic_P(stopic, 0, key_topic, scommand);
+
+    getTopic_P(stopic, 0, key_topic, getPowerDevice(scommand, device, sizeof(scommand), key));
+
     if (9 == state) {
       svalue[0] = '\0';
     } else {
@@ -1781,119 +1772,114 @@ void publish_status(uint8_t payload)
   }
 
   if ((0 == payload) || (99 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"Status\":{\"Module\":%d, \"FriendlyName\":\"%s\", \"Topic\":\"%s\", \"ButtonTopic\":\"%s\", \"Power\":%d, \"PowerOnState\":%d, \"LedState\":%d, \"SaveData\":%d, \"SaveState\":%d, \"ButtonRetain\":%d, \"PowerRetain\":%d}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS "\":{\"" D_CMND_MODULE "\":%d, \"" D_CMND_FRIENDLYNAME "\":\"%s\", \"" D_CMND_TOPIC "\":\"%s\", \"" D_CMND_BUTTONTOPIC "\":\"%s\", \"" D_CMND_POWER "\":%d, \"" D_CMND_POWERONSTATE "\":%d, \"" D_CMND_LEDSTATE "\":%d, \"" D_CMND_SAVEDATA "\":%d, \"" D_SAVESTATE "\":%d, \"" D_CMND_BUTTONRETAIN "\":%d, \"" D_CMND_POWERRETAIN "\":%d}}"),
       sysCfg.module +1, sysCfg.friendlyname[0], sysCfg.mqtt_topic, sysCfg.button_topic, power, sysCfg.poweronstate, sysCfg.ledstate, sysCfg.savedata, sysCfg.flag.savestate, sysCfg.flag.mqtt_button_retain, sysCfg.flag.mqtt_power_retain);
-    mqtt_publish_topic_P(option, PSTR("STATUS"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS), svalue);
   }
 
   if ((0 == payload) || (1 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusPRM\":{\"Baudrate\":%d, \"GroupTopic\":\"%s\", \"OtaUrl\":\"%s\", \"Uptime\":%d, \"Sleep\":%d, \"BootCount\":%d, \"SaveCount\":%d, \"SaveAddress\":\"%X\"}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS1_PARAMETER "\":{\"" D_BAUDRATE "\":%d, \"" D_CMND_GROUPTOPIC "\":\"%s\", \"" D_CMND_OTAURL "\":\"%s\", \"" D_UPTIME "\":%d, \"" D_CMND_SLEEP "\":%d, \"" D_BOOTCOUNT "\":%d, \"" D_SAVECOUNT "\":%d, \"" D_SAVEADDRESS "\":\"%X\"}}"),
       Baudrate, sysCfg.mqtt_grptopic, sysCfg.otaUrl, uptime, sysCfg.sleep, sysCfg.bootcount, sysCfg.saveFlag, CFG_Address());
-    mqtt_publish_topic_P(option, PSTR("STATUS1"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "1"), svalue);
   }
 
   if ((0 == payload) || (2 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusFWR\":{\"Program\":\"%s\", \"BuildDateTime\":\"%s\", \"Boot\":%d, \"Core\":\"%s\", \"SDK\":\"%s\"}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS2_FIRMWARE "\":{\"" D_VERSION "\":\"%s\", \"" D_BUILDDATETIME "\":\"%s\", \"" D_BOOTVERSION "\":%d, \"" D_COREVERSION "\":\"%s\", \"" D_SDKVERSION "\":\"%s\"}}"),
       Version, getBuildDateTime().c_str(), ESP.getBootVersion(), ESP.getCoreVersion().c_str(), ESP.getSdkVersion());
-    mqtt_publish_topic_P(option, PSTR("STATUS2"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "2"), svalue);
   }
 
   if ((0 == payload) || (3 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusLOG\":{\"Seriallog\":%d, \"Weblog\":%d, \"Syslog\":%d, \"LogHost\":\"%s\", \"SSId1\":\"%s\", \"SSId2\":\"%s\", \"TelePeriod\":%d, \"Option\":\"%08X\"}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS3_LOGGING "\":{\"" D_CMND_SERIALLOG "\":%d, \"" D_CMND_WEBLOG "\":%d, \"" D_CMND_SYSLOG "\":%d, \"" D_CMND_LOGHOST "\":\"%s\", \"" D_CMND_SSID "1\":\"%s\", \"" D_CMND_SSID "2\":\"%s\", \"" D_CMND_TELEPERIOD "\":%d, \"" D_CMND_SETOPTION "\":\"%08X\"}}"),
       sysCfg.seriallog_level, sysCfg.weblog_level, sysCfg.syslog_level, sysCfg.syslog_host, sysCfg.sta_ssid[0], sysCfg.sta_ssid[1], sysCfg.tele_period, sysCfg.flag.data);
-    mqtt_publish_topic_P(option, PSTR("STATUS3"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "3"), svalue);
   }
 
   if ((0 == payload) || (4 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMEM\":{\"ProgramSize\":%d, \"Free\":%d, \"Heap\":%d, \"ProgramFlashSize\":%d, \"FlashSize\":%d, \"FlashMode\":%d}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS4_MEMORY "\":{\"" D_PROGRAMSIZE "\":%d, \"" D_FREEMEMORY "\":%d, \"" D_HEAPSIZE "\":%d, \"" D_PROGRAMFLASHSIZE "\":%d, \"" D_FLASHSIZE "\":%d, \"" D_FLASHMODE "\":%d}}"),
       ESP.getSketchSize()/1024, ESP.getFreeSketchSpace()/1024, ESP.getFreeHeap()/1024, ESP.getFlashChipSize()/1024, ESP.getFlashChipRealSize()/1024, ESP.getFlashChipMode());
-    mqtt_publish_topic_P(option, PSTR("STATUS4"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "4"), svalue);
   }
 
   if ((0 == payload) || (5 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusNET\":{\"Hostname\":\"%s\", \"IPaddress\":\"%s\", \"Gateway\":\"%s\", \"Subnetmask\":\"%s\", \"DNSServer\":\"%s\", \"Mac\":\"%s\", \"Webserver\":%d, \"WifiConfig\":%d}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS5_NETWORK "\":{\"" D_CMND_HOSTNAME "\":\"%s\", \"" D_CMND_IPADDRESS "\":\"%s\", \"" D_GATEWAY "\":\"%s\", \"" D_SUBNETMASK "\":\"%s\", \"" D_DNSSERVER "\":\"%s\", \"" D_MAC "\":\"%s\", \"" D_CMND_WEBSERVER "\":%d, \"" D_CMND_WIFICONFIG "\":%d}}"),
       Hostname, WiFi.localIP().toString().c_str(), IPAddress(sysCfg.ip_address[1]).toString().c_str(), IPAddress(sysCfg.ip_address[2]).toString().c_str(), IPAddress(sysCfg.ip_address[3]).toString().c_str(),
       WiFi.macAddress().c_str(), sysCfg.webserver, sysCfg.sta_config);
-    mqtt_publish_topic_P(option, PSTR("STATUS5"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "5"), svalue);
   }
 
   if (((0 == payload) || (6 == payload)) && sysCfg.flag.mqtt_enabled) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusMQT\":{\"Host\":\"%s\", \"Port\":%d, \"ClientMask\":\"%s\", \"Client\":\"%s\", \"User\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS6_MQTT "\":{\"" D_CMND_MQTTHOST "\":\"%s\", \"" D_CMND_MQTTPORT "\":%d, \"" D_CMND_MQTTCLIENT D_MASK "\":\"%s\", \"" D_CMND_MQTTCLIENT "\":\"%s\", \"" D_CMND_MQTTUSER "\":\"%s\", \"MAX_PACKET_SIZE\":%d, \"KEEPALIVE\":%d}}"),
       sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, MQTTClient, sysCfg.mqtt_user, MQTT_MAX_PACKET_SIZE, MQTT_KEEPALIVE);
-    mqtt_publish_topic_P(option, PSTR("STATUS6"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "6"), svalue);
   }
 
   if ((0 == payload) || (7 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusTIM\":{\"UTC\":\"%s\", \"Local\":\"%s\", \"StartDST\":\"%s\", \"EndDST\":\"%s\", \"Timezone\":%d}}"),
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS7_TIME "\":{\"" D_UTC_TIME "\":\"%s\", \"" D_LOCAL_TIME "\":\"%s\", \"" D_STARTDST "\":\"%s\", \"" D_ENDDST "\":\"%s\", \"" D_CMND_TIMEZONE "\":%d}}"),
       rtc_time(0).c_str(), rtc_time(1).c_str(), rtc_time(2).c_str(), rtc_time(3).c_str(), sysCfg.timezone);
-    mqtt_publish_topic_P(option, PSTR("STATUS7"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "7"), svalue);
   }
 
   if (hlw_flg) {
     if ((0 == payload) || (8 == payload)) {
-      hlw_mqttStatus(svalue, sizeof(svalue));      
-      mqtt_publish_topic_P(option, PSTR("STATUS8"), svalue);
+      hlw_mqttStatus(svalue, sizeof(svalue));
+      mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "8"), svalue);
     }
 
     if ((0 == payload) || (9 == payload)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusPTH\":{\"PowerLow\":%d, \"PowerHigh\":%d, \"VoltageLow\":%d, \"VoltageHigh\":%d, \"CurrentLow\":%d, \"CurrentHigh\":%d}}"),
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS9_MARGIN "\":{\"" D_CMND_POWERLOW "\":%d, \"" D_CMND_POWERHIGH "\":%d, \"" D_CMND_VOLTAGELOW "\":%d, \"" D_CMND_VOLTAGEHIGH "\":%d, \"" D_CMND_CURRENTLOW "\":%d, \"" D_CMND_CURRENTHIGH "\":%d}}"),
         sysCfg.hlw_pmin, sysCfg.hlw_pmax, sysCfg.hlw_umin, sysCfg.hlw_umax, sysCfg.hlw_imin, sysCfg.hlw_imax);
-      mqtt_publish_topic_P(option, PSTR("STATUS9"), svalue);
+      mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "9"), svalue);
     }
   }
 
   if ((0 == payload) || (10 == payload)) {
     uint8_t djson = 0;
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusSNS\":"));
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS10_SENSOR "\":"));
     sensors_mqttPresent(svalue, sizeof(svalue), &djson);
     snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
-    mqtt_publish_topic_P(option, PSTR("STATUS10"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "10"), svalue);
   }
 
   if ((0 == payload) || (11 == payload)) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"StatusSTS\":"));
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_STATUS D_STATUS11_STATUS "\":"));
     state_mqttPresent(svalue, sizeof(svalue));
     snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
-    mqtt_publish_topic_P(option, PSTR("STATUS11"), svalue);
+    mqtt_publish_topic_P(option, PSTR(D_CMND_STATUS "11"), svalue);
   }
- 
+
 }
 
 void state_mqttPresent(char* svalue, uint16_t ssvalue)
 {
-  char stemp1[8];
-  
-  snprintf_P(svalue, ssvalue, PSTR("%s{\"Time\":\"%s\", \"Uptime\":%d"), svalue, getDateTime().c_str(), uptime);
+  char stemp1[16];
+
+  snprintf_P(svalue, ssvalue, PSTR("%s{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d"), svalue, getDateTime().c_str(), uptime);
 #ifdef USE_ADC_VCC
-  dtostrf((double)ESP.getVcc()/1000, 1, 3, stemp1);
-  snprintf_P(svalue, ssvalue, PSTR("%s, \"Vcc\":%s"), svalue, stemp1);
-#endif        
+  dtostrfd((double)ESP.getVcc()/1000, 3, stemp1);
+  snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_VCC "\":%s"), svalue, stemp1);
+#endif
   for (byte i = 0; i < Maxdevice; i++) {
-    if (1 == Maxdevice) {  // Legacy
-      snprintf_P(svalue, ssvalue, PSTR("%s, \"POWER\":"), svalue);
-    } else {
-      snprintf_P(svalue, ssvalue, PSTR("%s, \"POWER%d\":"), svalue, i +1);
-    }
-    snprintf_P(svalue, ssvalue, PSTR("%s\"%s\""), svalue, getStateText(bitRead(power, i)));
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":\"%s\""), svalue, getPowerDevice(stemp1, i +1, sizeof(stemp1)), getStateText(bitRead(power, i)));
   }
-  snprintf_P(svalue, ssvalue, PSTR("%s, \"Wifi\":{\"AP\":%d, \"SSID\":\"%s\", \"RSSI\":%d, \"APMac\":\"%s\"}}"),
+  snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_WIFI "\":{\"" D_AP "\":%d, \"" D_SSID "\":\"%s\", \"" D_RSSI "\":%d, \"" D_APMAC_ADDRESS "\":\"%s\"}}"),
     svalue, sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], WIFI_getRSSIasQuality(WiFi.RSSI()), WiFi.BSSIDstr().c_str());
 }
 
 void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
 {
-  snprintf_P(svalue, ssvalue, PSTR("%s{\"Time\":\"%s\""), svalue, getDateTime().c_str());
+  snprintf_P(svalue, ssvalue, PSTR("%s{\"" D_TIME "\":\"%s\""), svalue, getDateTime().c_str());
   for (byte i = 0; i < 4; i++) {
     if (pin[GPIO_SWT1 +i] < 99) {
       boolean swm = ((FOLLOW_INV == sysCfg.switchmode[i]) || (PUSHBUTTON_INV == sysCfg.switchmode[i]) || (PUSHBUTTONHOLD_INV == sysCfg.switchmode[i]));
-      snprintf_P(svalue, ssvalue, PSTR("%s, \"Switch%d\":\"%s\""), svalue, i +1, getStateText(swm ^ lastwallswitch[i]));
+      snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_SWITCH "%d\":\"%s\""), svalue, i +1, getStateText(swm ^ lastwallswitch[i]));
       *djson = 1;
     }
   }
   counter_mqttPresent(svalue, ssvalue, djson);
 #ifndef USE_ADC_VCC
   if (pin[GPIO_ADC0] < 99) {
-    snprintf_P(svalue, ssvalue, PSTR("%s, \"AnalogInput0\":%d"), svalue, getAdc0());
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_ANALOG_INPUT0 "\":%d"), svalue, getAdc0());
     *djson = 1;
   }
 #endif
@@ -1929,8 +1915,8 @@ void sensors_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
 #endif  // USE_BH1750
   }
 #endif  // USE_I2C
-  if (strstr_P(svalue, PSTR("Temperature"))) {
-    snprintf_P(svalue, ssvalue, PSTR("%s, \"TempUnit\":\"%c\""), svalue, tempUnit());
+  if (strstr_P(svalue, PSTR(D_TEMPERATURE))) {
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_TEMPERATURE_UNIT "\":\"%c\""), svalue, tempUnit());
   }
   snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue);
 }
@@ -1955,7 +1941,7 @@ void every_second()
     seriallog_timer--;
     if (!seriallog_timer) {
       if (seriallog_level) {
-        addLog_P(LOG_LEVEL_INFO, PSTR("APP: Serial logging disabled"));
+        addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SERIAL_LOGGING_DISABLED));
       }
       seriallog_level = 0;
     }
@@ -1966,7 +1952,7 @@ void every_second()
     if (!syslog_timer) {
       syslog_level = (sysCfg.flag.emulation) ? 0 : sysCfg.syslog_level;
       if (sysCfg.syslog_level) {
-        addLog_P(LOG_LEVEL_INFO, PSTR("SYSL: Syslog logging re-enabled"));  // Might trigger disable again (on purpose)
+        addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_SYSLOG_LOGGING_REENABLED));  // Might trigger disable again (on purpose)
       }
     }
   }
@@ -2023,13 +2009,13 @@ void every_second()
 
       svalue[0] = '\0';
       state_mqttPresent(svalue, sizeof(svalue));
-      mqtt_publish_topic_P(2, PSTR("STATE"), svalue);
+      mqtt_publish_topic_P(2, PSTR(D_RSLT_STATE), svalue);
 
       uint8_t djson = 0;
       svalue[0] = '\0';
       sensors_mqttPresent(svalue, sizeof(svalue), &djson);
       if (djson) {
-        mqtt_publish_topic_P(2, PSTR("SENSOR"), svalue, sysCfg.flag.mqtt_sensor_retain);
+        mqtt_publish_topic_P(2, PSTR(D_RSLT_SENSOR), svalue, sysCfg.flag.mqtt_sensor_retain);
       }
 
       if (hlw_flg) {
@@ -2045,8 +2031,8 @@ void every_second()
   if ((2 == rtcTime.Minute) && uptime_flg) {
     uptime_flg = false;
     uptime++;
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", \"Uptime\":%d}"), getDateTime().c_str(), uptime);
-    mqtt_publish_topic_P(2, PSTR("UPTIME"), svalue);
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_TIME "\":\"%s\", \"" D_UPTIME "\":%d}"), getDateTime().c_str(), uptime);
+    mqtt_publish_topic_P(2, PSTR(D_RSLT_UPTIME), svalue);
   }
   if ((3 == rtcTime.Minute) && !uptime_flg) {
     uptime_flg = true;
@@ -2072,7 +2058,7 @@ void button_handler()
     if (!i && ((SONOFF_DUAL == sysCfg.module) || (CH4 == sysCfg.module))) {
       butt_present = 1;
       if (ButtonCode) {
-        snprintf_P(log, sizeof(log), PSTR("APP: Button code %04X"), ButtonCode);
+        snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " " D_CODE " %04X"), ButtonCode);
         addLog(LOG_LEVEL_DEBUG, log);
         button = PRESSED;
         if (0xF500 == ButtonCode) {                     // Button hold
@@ -2094,13 +2080,13 @@ void button_handler()
         }
         flag = 0;
         if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) {
-          snprintf_P(log, sizeof(log), PSTR("APP: Button %d level 1-0"), i +1);
+          snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_10), i +1);
           addLog(LOG_LEVEL_DEBUG, log);
           holdbutton[i] = STATES;
           flag = 1;
         }
         if ((NOT_PRESSED == button) && (PRESSED == lastbutton[i])) {
-          snprintf_P(log, sizeof(log), PSTR("APP: Button %d level 0-1"), i +1);
+          snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_LEVEL_01), i +1);
           addLog(LOG_LEVEL_DEBUG, log);
           if (!holdbutton[i]) {                           // Do not allow within 1 second
             flag = 1;
@@ -2114,19 +2100,19 @@ void button_handler()
       } else {
         if ((PRESSED == button) && (NOT_PRESSED == lastbutton[i])) {
           if (sysCfg.flag.button_single) {                // Allow only single button press for immediate action
-            snprintf_P(log, sizeof(log), PSTR("APP: Button %d immediate"), i +1);
+            snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_IMMEDIATE), i +1);
             if (!send_button_power(0, i +1, 2)) {         // Execute Toggle command via MQTT if ButtonTopic is set
               do_cmnd_power(i +1, 2);                     // Execute Toggle command internally
             }
           } else {
             multipress[i] = (multiwindow[i]) ? multipress[i] +1 : 1;
-            snprintf_P(log, sizeof(log), PSTR("APP: Button %d multi-press %d"), i +1, multipress[i]);
+            snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BUTTON " %d " D_MULTI_PRESS " %d"), i +1, multipress[i]);
             multiwindow[i] = STATES /2;                   // 0.5 second multi press window
           }
           addLog(LOG_LEVEL_DEBUG, log);
           blinks = 201;
         }
-    
+
         if (NOT_PRESSED == button) {
           holdbutton[i] = 0;
         } else {
@@ -2134,14 +2120,14 @@ void button_handler()
           if (sysCfg.flag.button_single) {                // Allow only single button press for immediate action
             if (holdbutton[i] == sysCfg.param[P_HOLD_TIME] * (STATES / 10) * 4) {  // Button hold for four times longer
 //              sysCfg.flag.button_single = 0;
-              snprintf_P(scmnd, sizeof(scmnd), PSTR("setoption13 0"));  // Disable single press only
+              snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_SETOPTION "13 0"));  // Disable single press only
               do_cmnd(scmnd);
             }
           } else {
             if (holdbutton[i] == sysCfg.param[P_HOLD_TIME] * (STATES / 10)) {      // Button hold
               multipress[i] = 0;
               if (!sysCfg.flag.button_restrict) {         // No button restriction
-                snprintf_P(scmnd, sizeof(scmnd), PSTR("reset 1"));
+                snprintf_P(scmnd, sizeof(scmnd), PSTR(D_CMND_RESET " 1"));
                 do_cmnd(scmnd);
               } else {
                 send_button_power(0, i +1, 3);            // Execute Hold command via MQTT if ButtonTopic is set
@@ -2208,7 +2194,7 @@ void switch_handler()
           send_button_power(1, i +1, 3);         // Execute command via MQTT
         }
       }
-      
+
       button = digitalRead(pin[GPIO_SWT1 +i]);
       if (button != lastwallswitch[i]) {
         switchflag = 3;
@@ -2251,13 +2237,13 @@ void switch_handler()
           }
           break;
         }
-        
+
         if (switchflag < 3) {
           if (!send_button_power(1, i +1, switchflag)) {  // Execute command via MQTT
             do_cmnd_power(i +1, switchflag);              // Execute command internally (if i < Maxdevice)
           }
         }
-        
+
         lastwallswitch[i] = button;
       }
     }
@@ -2295,7 +2281,7 @@ void stateloop()
     if (mqtt_cmnd_publish) {
       mqtt_cmnd_publish--;  // Clean up
     }
-  
+
     if (latching_relay_pulse) {
       latching_relay_pulse--;
       if (!latching_relay_pulse) {
@@ -2428,12 +2414,12 @@ void stateloop()
         otaflag = 0;
         if (otaok) {
           setFlashModeDout();  // Force DOUT for both ESP8266 and ESP8285
-          snprintf_P(svalue, sizeof(svalue), PSTR("Successful. Restarting"));
+          snprintf_P(svalue, sizeof(svalue), PSTR(D_SUCCESSFUL ". " D_RESTARTING));
         } else {
-          snprintf_P(svalue, sizeof(svalue), PSTR("Failed %s"), ESPhttpUpdate.getLastErrorString().c_str());
+          snprintf_P(svalue, sizeof(svalue), PSTR(D_FAILED " %s"), ESPhttpUpdate.getLastErrorString().c_str());
         }
         restartflag = 2;       // Restart anyway to keep memory clean webserver
-        mqtt_publish_topic_P(1, PSTR("UPGRADE"), svalue);
+        mqtt_publish_topic_P(1, PSTR(D_CMND_UPGRADE), svalue);
       }
     }
     break;
@@ -2479,7 +2465,7 @@ void stateloop()
       CFG_Save(0);
       restartflag--;
       if (restartflag <= 0) {
-        addLog_P(LOG_LEVEL_INFO, PSTR("APP: Restarting"));
+        addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_RESTARTING));
         ESP.restart();
       }
     }
@@ -2574,7 +2560,7 @@ void serial()
     else if (SerialInByte == '\n') {
       serialInBuf[SerialInByteCounter] = 0;  // serial data completed
       seriallog_level = (sysCfg.seriallog_level < LOG_LEVEL_INFO) ? LOG_LEVEL_INFO : sysCfg.seriallog_level;
-      snprintf_P(log, sizeof(log), PSTR("CMND: %s"), serialInBuf);
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_COMMAND "%s"), serialInBuf);
       addLog(LOG_LEVEL_INFO, log);
       do_cmnd(serialInBuf);
       SerialInByteCounter = 0;
@@ -2616,7 +2602,7 @@ void GPIO_init()
 
 //  snprintf_P(log, sizeof(log), PSTR("DBG: gpio pin %d, mpin %d"), i, mpin);
 //  addLog(LOG_LEVEL_DEBUG, log);
-    
+
     if (mpin) {
       if ((mpin >= GPIO_REL1_INV) && (mpin <= GPIO_REL4_INV)) {
         rel_inverted[mpin - GPIO_REL1_INV] = 1;
@@ -2626,7 +2612,7 @@ void GPIO_init()
         led_inverted[mpin - GPIO_LED1_INV] = 1;
         mpin -= 4;
       }
-#ifdef USE_DHT      
+#ifdef USE_DHT
       else if ((mpin >= GPIO_DHT11) && (mpin <= GPIO_DHT22)) {
         if (dht_setup(i, mpin)) {
           dht_flg = 1;
@@ -2635,7 +2621,7 @@ void GPIO_init()
           mpin = 0;
         }
       }
-#endif  // USE_DHT      
+#endif  // USE_DHT
     }
     if (mpin) {
       pin[mpin] = i;
@@ -2703,7 +2689,7 @@ void GPIO_init()
       lastwallswitch[i] = digitalRead(pin[GPIO_SWT1 +i]);  // set global now so doesn't change the saved power state on first switch check
     }
   }
-  
+
   if (sfl_flg) {                // Sonoff B1, AiLight, Sonoff Led or BN-SZ01
     if (sfl_flg < 4) {
       pwm_idxoffset = sfl_flg;  // 1 for BN-SZ01, 2 for Sonoff Led
@@ -2800,14 +2786,14 @@ void setup()
   sleep = sysCfg.sleep;
 
   sysCfg.bootcount++;
-  snprintf_P(log, sizeof(log), PSTR("APP: Bootcount %d"), sysCfg.bootcount);
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_BOOT_COUNT " %d"), sysCfg.bootcount);
   addLog(LOG_LEVEL_DEBUG, log);
 
   GPIO_init();
 
   if (Serial.baudRate() != Baudrate) {
     if (seriallog_level) {
-      snprintf_P(log, sizeof(log), PSTR("APP: Set baudrate to %d"), Baudrate);
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_SET_BAUDRATE_TO " %d"), Baudrate);
       addLog(LOG_LEVEL_INFO, log);
     }
     delay(100);
@@ -2871,7 +2857,7 @@ void setup()
       pulse_timer[i] = sysCfg.pulsetime[i];
     }
   }
-  
+
   blink_powersave = power;
 
   if (SONOFF_SC == sysCfg.module) {
@@ -2880,7 +2866,7 @@ void setup()
 
   rtc_init();
 
-  snprintf_P(log, sizeof(log), PSTR("APP: Project %s %s (Topic %s, Fallback %s, GroupTopic %s) Version %s"),
+  snprintf_P(log, sizeof(log), PSTR(D_PROJECT " %s %s (" D_CMND_TOPIC " %s, " D_FALLBACK " %s, " D_CMND_GROUPTOPIC " %s) " D_VERSION " %s"),
     PROJECT, sysCfg.friendlyname[0], sysCfg.mqtt_topic, MQTTClient, sysCfg.mqtt_grptopic, Version);
   addLog(LOG_LEVEL_INFO, log);
 }
@@ -2888,7 +2874,7 @@ void setup()
 void loop()
 {
   osw_loop();
-  
+
 #ifdef USE_WEBSERVER
   pollDnsWeb();
 #endif  // USE_WEBSERVER
diff --git a/sonoff/sonoff_template.h b/sonoff/sonoff_template.h
index adf932dbd..abb3a33f7 100644
--- a/sonoff/sonoff_template.h
+++ b/sonoff/sonoff_template.h
@@ -65,50 +65,50 @@ enum upins_t {
 
 // Text in webpage Module Parameters and commands GPIOS and GPIO
 const char sensors[GPIO_SENSOR_END][9] PROGMEM = {
-  "None",
-  "DHT11",
-  "AM2301",
-  "DHT22",
-  "DS18x20",
-  "I2C SCL",
-  "I2C SDA",
-  "WS2812",
-  "IRremote",
-  "Switch1",
-  "Switch2",
-  "Switch3",
-  "Switch4",
-  "Button1",
-  "Button2",
-  "Button3",
-  "Button4",
-  "Relay1",
-  "Relay2",
-  "Relay3",
-  "Relay4",
-  "Relay1I",
-  "Relay2I",
-  "Relay3I",
-  "Relay4I",
-  "Led1",
-  "Led2",
-  "Led3",
-  "Led4",
-  "Led1I",
-  "Led2I",
-  "Led3I",
-  "Led4I",
-  "PWM1",
-  "PWM2",
-  "PWM3",
-  "PWM4",
-  "PWM5",
-  "Counter1",
-  "Counter2",
-  "Counter3",
-  "Counter4"
+  D_SENSOR_NONE,
+  D_SENSOR_DHT11,
+  D_SENSOR_AM2301,
+  D_SENSOR_DHT22,
+  D_SENSOR_DS18X20,
+  D_SENSOR_I2C_SCL,
+  D_SENSOR_I2C_SDA,
+  D_SENSOR_WS2812,
+  D_SENSOR_IRREMOTE,
+  D_SENSOR_SWITCH "1",
+  D_SENSOR_SWITCH "2",
+  D_SENSOR_SWITCH "3",
+  D_SENSOR_SWITCH "4",
+  D_SENSOR_BUTTON "1",
+  D_SENSOR_BUTTON "2",
+  D_SENSOR_BUTTON "3",
+  D_SENSOR_BUTTON "4",
+  D_SENSOR_RELAY "1",
+  D_SENSOR_RELAY "2",
+  D_SENSOR_RELAY "3",
+  D_SENSOR_RELAY "4",
+  D_SENSOR_RELAY "1I",
+  D_SENSOR_RELAY "2I",
+  D_SENSOR_RELAY "3I",
+  D_SENSOR_RELAY "4I",
+  D_SENSOR_LED "1",
+  D_SENSOR_LED "2",
+  D_SENSOR_LED "3",
+  D_SENSOR_LED "4",
+  D_SENSOR_LED "1I",
+  D_SENSOR_LED "2I",
+  D_SENSOR_LED "3I",
+  D_SENSOR_LED "4I",
+  D_SENSOR_PWM "1",
+  D_SENSOR_PWM "2",
+  D_SENSOR_PWM "3",
+  D_SENSOR_PWM "4",
+  D_SENSOR_PWM "5",
+  D_SENSOR_COUNTER "1",
+  D_SENSOR_COUNTER "2",
+  D_SENSOR_COUNTER "3",
+  D_SENSOR_COUNTER "4"
   };
-  
+
 // Programmer selectable GPIO functionality offset by user selectable GPIOs
 enum fpins_t {
   GPIO_RXD = GPIO_SENSOR_END,  // Serial interface
@@ -169,7 +169,7 @@ typedef struct MYIO {
 
 typedef struct MYTMPLT {
   char         name[15];
-  myio         gp;  
+  myio         gp;
 } mytmplt;
 
 const uint8_t nicelist[MAXMODULE] PROGMEM = {
@@ -211,7 +211,7 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
   { "Sonoff Basic",    // Sonoff Basic (ESP8266)
      GPIO_KEY1,        // GPIO00 Button
      GPIO_USER,        // GPIO01 Serial RXD and Optional sensor
-     0,                // GPIO02 
+     0,                // GPIO02
      GPIO_USER,        // GPIO03 Serial TXD and Optional sensor
      GPIO_USER,        // GPIO04 Optional sensor
      0,                // GPIO05
@@ -460,13 +460,13 @@ const mytmplt modules[MAXMODULE] PROGMEM = {
      GPIO_LED1,        // GPIO01 Green LED
      GPIO_TXD,         // GPIO02 RX - Pin next to TX on the PCB
      GPIO_RXD,         // GPIO03 TX - Pin next to GND on the PCB
-     GPIO_PWM2,        // GPIO04 W2 
+     GPIO_PWM2,        // GPIO04 W2
      GPIO_LED2_INV,    // GPIO05 Red LED
      0, 0, 0, 0, 0, 0, // Flash connection
-     GPIO_PWM3,        // GPIO12 Blue 
-     GPIO_PWM4,        // GPIO13 Green 
-     GPIO_PWM1,        // GPIO14 W1 
-     GPIO_PWM5,        // GPIO15 Red 
+     GPIO_PWM3,        // GPIO12 Blue
+     GPIO_PWM4,        // GPIO13 Green
+     GPIO_PWM1,        // GPIO14 W1
+     GPIO_PWM5,        // GPIO15 Red
      0, 0
   },
   { "Sonoff SC",       // Sonoff SC (ESP8266)
diff --git a/sonoff/support.ino b/sonoff/support.ino
index cdf7047a8..44cbaf0ce 100644
--- a/sonoff/support.ino
+++ b/sonoff/support.ino
@@ -17,9 +17,6 @@
   along with this program.  If not, see <http://www.gnu.org/licenses/>.
 */
 
-const char JSON_SNS_TEMPHUM[] PROGMEM =
-  "%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}";
-
 /*********************************************************************************************\
  * Watchdog extension (https://github.com/esp8266/Arduino/issues/1532)
 \*********************************************************************************************/
@@ -42,14 +39,14 @@ void osw_osWatch()
 
 #ifdef DEBUG_THEO
   char log[LOGSZ];
-  snprintf_P(log, sizeof(log), PSTR("osWatch: FreeRam %d, rssi %d, last_run %d"), ESP.getFreeHeap(), WIFI_getRSSIasQuality(WiFi.RSSI()), last_run);
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION D_OSWATCH " FreeRam %d, rssi %d, last_run %d"), ESP.getFreeHeap(), WIFI_getRSSIasQuality(WiFi.RSSI()), last_run);
   addLog(LOG_LEVEL_DEBUG, log);
 #endif  // DEBUG_THEO
   if (last_run >= (OSWATCH_RESET_TIME * 1000)) {
-    addLog_P(LOG_LEVEL_INFO, PSTR("osWatch: Warning, loop blocked. Restart now"));
+    addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_APPLICATION D_OSWATCH " " D_BLOCKED_LOOP ". " D_RESTARTING));
     rtcMem.osw_flag = 1;
     RTC_Save();
-//    ESP.restart();  // normal reboot 
+//    ESP.restart();  // normal reboot
     ESP.reset();  // hard reset
   }
 }
@@ -72,7 +69,7 @@ String getResetReason()
 {
   char buff[32];
   if (osw_flag) {
-    strcpy_P(buff, PSTR("Blocked Loop"));
+    strcpy_P(buff, PSTR(D_BLOCKED_LOOP));
     return String(buff);
   } else {
     return ESP.getResetReason();
@@ -82,11 +79,11 @@ String getResetReason()
 #ifdef DEBUG_THEO
 void exception_tst(byte type)
 {
-/*    
+/*
 Exception (28):
 epc1=0x4000bf64 epc2=0x00000000 epc3=0x00000000 excvaddr=0x00000007 depc=0x00000000
 
-ctx: cont 
+ctx: cont
 sp: 3fff1f30 end: 3fff2840 offset: 01a0
 
 >>>stack>>>
@@ -149,6 +146,85 @@ Decoding 14 results
  * General
 \*********************************************************************************************/
 
+char* _dtostrf(double number, unsigned char prec, char *s, bool i18n)
+{
+  bool negative = false;
+
+  if (isnan(number)) {
+    strcpy(s, "nan");
+    return s;
+  }
+  if (isinf(number)) {
+    strcpy(s, "inf");
+    return s;
+  }
+  char decimal = '.';
+  if (i18n) {
+    decimal = D_DECIMAL_SEPARATOR[0];
+  }
+
+  char* out = s;
+
+  // Handle negative numbers
+  if (number < 0.0) {
+    negative = true;
+    number = -number;
+  }
+
+  // Round correctly so that print(1.999, 2) prints as "2.00"
+  // I optimized out most of the divisions
+  double rounding = 2.0;
+  for (uint8_t i = 0; i < prec; ++i) {
+    rounding *= 10.0;
+  }
+  rounding = 1.0 / rounding;
+  number += rounding;
+
+  // Figure out how big our number really is
+  double tenpow = 1.0;
+  int digitcount = 1;
+  while (number >= 10.0 * tenpow) {
+    tenpow *= 10.0;
+    digitcount++;
+  }
+  number /= tenpow;
+
+  // Handle negative sign
+  if (negative) {
+    *out++ = '-';
+  }
+
+  // Print the digits, and if necessary, the decimal point
+  digitcount += prec;
+  int8_t digit = 0;
+  while (digitcount-- > 0) {
+    digit = (int8_t)number;
+    if (digit > 9) {
+      digit = 9; // insurance
+    }
+    *out++ = (char)('0' | digit);
+    if ((digitcount == prec) && (prec > 0)) {
+      *out++ = decimal;
+    }
+    number -= digit;
+    number *= 10.0;
+  }
+
+  // make sure the string is terminated
+  *out = 0;
+  return s;
+}
+
+char* dtostrfd(double number, unsigned char prec, char *s)  // Always decimal dot
+{
+  return _dtostrf(number, prec, s, 0);
+}
+
+char* dtostrfi(double number, unsigned char prec, char *s) // Use localized decimal dot
+{
+  return _dtostrf(number, prec, s, 1);
+}
+
 boolean parseIP(uint32_t* addr, const char* str)
 {
   uint8_t *part = (uint8_t*)addr;
@@ -169,7 +245,7 @@ boolean parseIP(uint32_t* addr, const char* str)
 void mqttfy(byte option, char* str)
 {
 // option 0 = replace by underscore
-// option 1 = delete character  
+// option 1 = delete character
   uint16_t i = 0;
   while (str[i] > 0) {
 //        if ((str[i] == '/') || (str[i] == '+') || (str[i] == '#') || (str[i] == ' ')) {
@@ -233,6 +309,23 @@ bool newerVersion(char* version_str)
   return (version > VERSION);
 }
 
+char* getPowerDevice(char* dest, uint8_t idx, size_t size, uint8_t option)
+{
+  char sidx[8];
+
+  strncpy_P(dest, S_RSLT_POWER, size);
+  if ((Maxdevice + option) > 1) {
+    snprintf_P(sidx, sizeof(sidx), PSTR("%d"), idx);
+    strncat(dest, sidx, size);
+  }
+  return dest;
+}
+
+char* getPowerDevice(char* dest, uint8_t idx, size_t size)
+{
+  return getPowerDevice(dest, idx, size, 0);
+}
+
 /*********************************************************************************************\
  * Wifi
 \*********************************************************************************************/
@@ -295,7 +388,7 @@ void WIFI_wps_status_cb(wps_cb_status status)
   if (WPS_CB_ST_SUCCESS == _wpsresult) {
     wifi_wps_disable();
   } else {
-    snprintf_P(log, sizeof(log), PSTR("WPSconfig: FAILED with status %d"), _wpsresult);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_WPS_FAILED_WITH_STATUS " %d"), _wpsresult);
     addLog(LOG_LEVEL_DEBUG, log);
     _wifiConfigCounter = 2;
   }
@@ -342,20 +435,20 @@ void WIFI_config(uint8_t type)
       restartflag = 2;
     }
     else if (WIFI_SMARTCONFIG == _wificonfigflag) {
-      addLog_P(LOG_LEVEL_INFO, PSTR("Smartconfig: Active for 1 minute"));
+      addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_1_SMARTCONFIG D_ACTIVE_FOR_1_MINUTE));
       WiFi.beginSmartConfig();
     }
     else if (WIFI_WPSCONFIG == _wificonfigflag) {
       if (WIFI_beginWPSConfig()) {
-        addLog_P(LOG_LEVEL_INFO, PSTR("WPSconfig: Active for 1 minute"));
+        addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_3_WPSCONFIG D_ACTIVE_FOR_1_MINUTE));
       } else {
-        addLog_P(LOG_LEVEL_INFO, PSTR("WPSconfig: Failed to start"));
+        addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_3_WPSCONFIG D_FAILED_TO_START));
         _wifiConfigCounter = 3;
       }
     }
 #ifdef USE_WEBSERVER
     else if (WIFI_MANAGER == _wificonfigflag) {
-      addLog_P(LOG_LEVEL_INFO, PSTR("Wifimanager: Active for 1 minute"));
+      addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_WCFG_2_WIFIMANAGER D_ACTIVE_FOR_1_MINUTE));
       beginWifiManager();
     }
 #endif  // USE_WEBSERVER
@@ -371,7 +464,7 @@ void WIFI_begin(uint8_t flag)
   UDP_Disconnect();
 #endif  // USE_EMULATION
   if (!strncmp_P(ESP.getSdkVersion(),PSTR("1.5.3"),5)) {
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: Patch issue 2186"));
+    addLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, PSTR(D_PATCH_ISSUE_2186));
     WiFi.mode(WIFI_OFF);    // See https://github.com/esp8266/Arduino/issues/2186
   }
   WiFi.disconnect();
@@ -402,7 +495,7 @@ void WIFI_begin(uint8_t flag)
   }
   WiFi.hostname(Hostname);
   WiFi.begin(sysCfg.sta_ssid[sysCfg.sta_active], sysCfg.sta_pwd[sysCfg.sta_active]);
-  snprintf_P(log, sizeof(log), PSTR("Wifi: Connecting to AP%d %s in mode 11%c as %s..."),
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_CONNECTING_TO_AP "%d %s " D_IN_MODE " 11%c " D_AS " %s..."),
     sysCfg.sta_active +1, sysCfg.sta_ssid[sysCfg.sta_active], PhyMode[WiFi.getPhyMode() & 0x3], Hostname);
   addLog(LOG_LEVEL_INFO, log);
 }
@@ -412,7 +505,7 @@ void WIFI_check_ip()
   if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0)) {
     _wificounter = WIFI_CHECK_SEC;
     _wifiretry = WIFI_RETRY_SEC;
-    addLog_P((_wifistatus != WL_CONNECTED) ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG_MORE, PSTR("Wifi: Connected"));
+    addLog_P((_wifistatus != WL_CONNECTED) ? LOG_LEVEL_INFO : LOG_LEVEL_DEBUG_MORE, S_LOG_WIFI, PSTR(D_CONNECTED));
     if (_wifistatus != WL_CONNECTED) {
 //      addLog_P(LOG_LEVEL_INFO, PSTR("Wifi: Set IP addresses"));
       sysCfg.ip_address[1] = (uint32_t)WiFi.gatewayIP();
@@ -424,12 +517,12 @@ void WIFI_check_ip()
     _wifistatus = WiFi.status();
     switch (_wifistatus) {
       case WL_CONNECTED:
-        addLog_P(LOG_LEVEL_INFO, PSTR("Wifi: Connect failed as no IP address received"));
+        addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_NO_IP_ADDRESS));
         _wifistatus = 0;
         _wifiretry = WIFI_RETRY_SEC;
         break;
       case WL_NO_SSID_AVAIL:
-        addLog_P(LOG_LEVEL_INFO, PSTR("Wifi: Connect failed as AP cannot be reached"));
+        addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_NOT_REACHED));
         if (_wifiretry > (WIFI_RETRY_SEC / 2)) {
           _wifiretry = WIFI_RETRY_SEC / 2;
         }
@@ -438,7 +531,7 @@ void WIFI_check_ip()
         }
         break;
       case WL_CONNECT_FAILED:
-        addLog_P(LOG_LEVEL_INFO, PSTR("Wifi: Connect failed with AP incorrect password"));
+        addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_WRONG_PASSWORD));
         if (_wifiretry > (WIFI_RETRY_SEC / 2)) {
           _wifiretry = WIFI_RETRY_SEC / 2;
         }
@@ -448,9 +541,9 @@ void WIFI_check_ip()
         break;
       default:  // WL_IDLE_STATUS and WL_DISCONNECTED
         if (!_wifiretry || ((WIFI_RETRY_SEC / 2) == _wifiretry)) {
-          addLog_P(LOG_LEVEL_INFO, PSTR("Wifi: Connect failed with AP timeout"));
+          addLog_P(LOG_LEVEL_INFO, S_LOG_WIFI, PSTR(D_CONNECT_FAILED_AP_TIMEOUT));
         } else {
-          addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: Attempting connection..."));
+          addLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, PSTR(D_ATTEMPTING_CONNECTION));
         }
     }
     if (_wifiretry) {
@@ -500,7 +593,7 @@ void WIFI_Check(uint8_t param)
             strlcpy(sysCfg.sta_pwd[0], WiFi.psk().c_str(), sizeof(sysCfg.sta_pwd[0]));
           }
           sysCfg.sta_active = 0;
-          snprintf_P(log, sizeof(log), PSTR("Wificonfig: SSID1 %s and Password1 %s"), sysCfg.sta_ssid[0], sysCfg.sta_pwd[0]);
+          snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_WCFG_1_SMARTCONFIG D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s"), sysCfg.sta_ssid[0], sysCfg.sta_pwd[0]);
           addLog(LOG_LEVEL_INFO, log);
         }
       }
@@ -512,7 +605,7 @@ void WIFI_Check(uint8_t param)
       }
     } else {
       if (_wificounter <= 0) {
-        addLog_P(LOG_LEVEL_DEBUG_MORE, PSTR("Wifi: Checking connection..."));
+        addLog_P(LOG_LEVEL_DEBUG_MORE, S_LOG_WIFI, PSTR(D_CHECKING_CONNECTION));
         _wificounter = WIFI_CHECK_SEC;
         WIFI_check_ip();
       }
@@ -520,7 +613,7 @@ void WIFI_Check(uint8_t param)
 #ifdef USE_DISCOVERY
         if (!mDNSbegun) {
           mDNSbegun = MDNS.begin(Hostname);
-          snprintf_P(log, sizeof(log), PSTR("mDNS: %s"), (mDNSbegun)?"Initialized":"Failed");
+          snprintf_P(log, sizeof(log), PSTR(D_LOG_MDNS "%s"), (mDNSbegun) ? D_INITIALIZED : D_FAILED);
           addLog(LOG_LEVEL_INFO, log);
         }
 #endif  // USE_DISCOVERY
@@ -530,7 +623,7 @@ void WIFI_Check(uint8_t param)
 #ifdef USE_DISCOVERY
 #ifdef WEBSERVER_ADVERTISE
           MDNS.addService("http", "tcp", 80);
-#endif  // WEBSERVER_ADVERTISE          
+#endif  // WEBSERVER_ADVERTISE
 #endif  // USE_DISCOVERY
         } else {
           stopWebserver();
@@ -590,14 +683,14 @@ boolean mdns_discoverMQTTServer()
 
   n = MDNS.queryService("mqtt", "tcp");  // Search for mqtt service
 
-  snprintf_P(log, sizeof(log), PSTR("mDNS: Query done with %d mqtt services found"), n);
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n);
   addLog(LOG_LEVEL_INFO, log);
 
   if (n > 0) {
     // Note: current strategy is to get the first MQTT service (even when many are found)
     IPtoCharArray(MDNS.IP(0), ip_str, 20);
-    
-    snprintf_P(log, sizeof(log), PSTR("mDNS: Service found on %s ip %s port %d"),
+
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"),
       MDNS.hostname(0).c_str(), ip_str, MDNS.port(0));
     addLog(LOG_LEVEL_INFO, log);
 
@@ -701,7 +794,7 @@ void i2c_scan(char *devs, unsigned int devs_len)
   byte any = 0;
   char tstr[10];
 
-  snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"Device(s) found at"));
+  snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_DEVICES_FOUND_AT));
   for (address = 1; address <= 127; address++) {
     Wire.beginTransmission(address);
     error = Wire.endTransmission();
@@ -711,13 +804,13 @@ void i2c_scan(char *devs, unsigned int devs_len)
       any = 1;
     }
     else if (4 == error) {
-      snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"Unknown error at 0x%2x\"}"), address);
+      snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_UNKNOWN_ERROR_AT " 0x%2x\"}"), address);
     }
   }
   if (any) {
     strncat(devs, "\"}", devs_len);
   } else {
-    snprintf_P(devs, devs_len, PSTR("{\"I2Cscan\":\"No devices found\"}"));
+    snprintf_P(devs, devs_len, PSTR("{\"" D_CMND_I2CSCAN "\":\"" D_I2CSCAN_NO_DEVICES_FOUND "\"}"));
   }
 }
 #endif  // USE_I2C
@@ -741,7 +834,6 @@ extern "C" {
 Ticker tickerRTC;
 
 static const uint8_t monthDays[] = { 31, 28, 31, 30, 31, 30, 31, 31, 30, 31, 30, 31 }; // API starts months from 1, this array starts from 0
-static const char monthNames[] = "JanFebMarAprMayJunJulAugSepOctNovDec";
 
 uint32_t utctime = 0;
 uint32_t loctime = 0;
@@ -762,7 +854,7 @@ String getBuildDateTime()
   int month;
   int day;
   int year;
-  
+
 //  sscanf(mdate, "%s %d %d", bdt, &day, &year);  // Not implemented in 2.3.0 and probably too many code
   byte i = 0;
   for (str = strtok_r(mdate, " ", &p); str && i < 3; str = strtok_r(NULL, " ", &p)) {
@@ -778,7 +870,7 @@ String getBuildDateTime()
     }
   }
   month = (strstr(monthNames, smonth) -monthNames) /3 +1;
-  snprintf_P(bdt, sizeof(bdt), PSTR("%d-%02d-%02dT%s"), year, month, day, __TIME__);
+  snprintf_P(bdt, sizeof(bdt), PSTR("%d" D_YEAR_MONTH_SEPARATOR "%02d" D_MONTH_DAY_SEPARATOR "%02d" D_DATE_TIME_SEPARATOR "%s"), year, month, day, __TIME__);
   return String(bdt);
 }
 
@@ -786,8 +878,8 @@ String getDateTime()
 {
   // "2017-03-07T11:08:02" - ISO8601:2004
   char dt[21];
-  
-  snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
+
+  snprintf_P(dt, sizeof(dt), PSTR("%04d" D_YEAR_MONTH_SEPARATOR "%02d" D_MONTH_DAY_SEPARATOR "%02d" D_DATE_TIME_SEPARATOR "%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"),
     rtcTime.Year, rtcTime.Month, rtcTime.Day, rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
   return String(dt);
 }
@@ -801,7 +893,7 @@ String getUTCDateTime()
   breakTime(utctime, tmpTime);
   tmpTime.Year += 1970;
 
-  snprintf_P(dt, sizeof(dt), PSTR("%04d-%02d-%02dT%02d:%02d:%02d"),
+  snprintf_P(dt, sizeof(dt), PSTR("%04d" D_YEAR_MONTH_SEPARATOR "%02d" D_MONTH_DAY_SEPARATOR "%02d" D_DATE_TIME_SEPARATOR "%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"),
     tmpTime.Year, tmpTime.Month, tmpTime.Day, tmpTime.Hour, tmpTime.Minute, tmpTime.Second);
   return String(dt);
 }
@@ -984,11 +1076,11 @@ void rtc_second()
       rtcTime.Year = tmpTime.Year + 1970;
       dsttime = toTime_t(myDST, rtcTime.Year);
       stdtime = toTime_t(mySTD, rtcTime.Year);
-      snprintf_P(log, sizeof(log), PSTR("RTC: (UTC) %s"), rtc_time(0).c_str());
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION "(" D_UTC_TIME ") %s"), rtc_time(0).c_str());
       addLog(LOG_LEVEL_DEBUG, log);
-      snprintf_P(log, sizeof(log), PSTR("RTC: (DST) %s"), rtc_time(2).c_str());
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION "(" D_DST_TIME ") %s"), rtc_time(2).c_str());
       addLog(LOG_LEVEL_DEBUG, log);
-      snprintf_P(log, sizeof(log), PSTR("RTC: (STD) %s"), rtc_time(3).c_str());
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_APPLICATION "(" D_STD_TIME ") %s"), rtc_time(3).c_str());
       addLog(LOG_LEVEL_DEBUG, log);
     }
   }
@@ -1035,7 +1127,7 @@ void rtc_init()
 float convertTemp(float c)
 {
   float result = c;
-  
+
   if (!isnan(c) && sysCfg.flag.temperature_conversion) {
     result = c * 1.8 + 32;  // Fahrenheit
   }
@@ -1072,7 +1164,7 @@ void syslog(const char *message)
   } else {
     syslog_level = 0;
     syslog_timer = SYSLOG_TIMER;
-    snprintf_P(str, sizeof(str), PSTR("SYSL: Syslog Host not found so logging disabled for %d seconds. Consider syslog 0"), SYSLOG_TIMER);
+    snprintf_P(str, sizeof(str), PSTR(D_LOG_APPLICATION D_SYSLOG_HOST_NOT_FOUND ". " D_RETRY_IN " %d " D_UNIT_SECOND), SYSLOG_TIMER);
     addLog(LOG_LEVEL_INFO, str);
   }
 }
@@ -1081,7 +1173,7 @@ void addLog(byte loglevel, const char *line)
 {
   char mxtime[9];
 
-  snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d:%02d:%02d"), rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
+  snprintf_P(mxtime, sizeof(mxtime), PSTR("%02d" D_HOUR_MINUTE_SEPARATOR "%02d" D_MINUTE_SECOND_SEPARATOR "%02d"), rtcTime.Hour, rtcTime.Minute, rtcTime.Second);
 
   if (loglevel <= seriallog_level) Serial.printf("%s %s\n", mxtime, line);
 #ifdef USE_WEBSERVER
@@ -1106,6 +1198,17 @@ void addLog_P(byte loglevel, const char *formatP)
   addLog(loglevel, mess);
 }
 
+void addLog_P(byte loglevel, const char *formatP, const char *formatP2)
+{
+  char mess[LOGSZ];  // was MESSZ
+  char mes2[LOGSZ];
+
+  snprintf_P(mess, sizeof(mess), formatP);
+  snprintf_P(mes2, sizeof(mes2), formatP2);
+  strncat(mess, mes2, sizeof(mess));
+  addLog(loglevel, mess);
+}
+
 /*********************************************************************************************\
  *
 \*********************************************************************************************/
diff --git a/sonoff/user_config.h b/sonoff/user_config.h
index ec8cc5984..a81b0bab0 100644
--- a/sonoff/user_config.h
+++ b/sonoff/user_config.h
@@ -25,6 +25,10 @@
  * Corresponding MQTT/Serial/Console commands in [brackets]
 \*********************************************************************************************/
 
+// -- Localization --------------------------------
+#define LANGUAGE               "language\en-GB.h"
+//#define LANGUAGE               "language\nl-NL.h"
+
 // -- Project -------------------------------------
 #define PROJECT                "sonoff"          // PROJECT is used as the default topic delimiter and OTA file name
                                                  //   As an IDE restriction it needs to be the same as the main .ino file
@@ -45,7 +49,7 @@
 #define STA_PASS2              "VnsqrtnrsddbrN"  // [Password2] Optional alternate AP Wifi password
 #define WIFI_CONFIG_TOOL       WIFI_WPSCONFIG    // [WifiConfig] Default tool if wifi fails to connect
                                                  //   (WIFI_RESTART, WIFI_SMARTCONFIG, WIFI_MANAGER, WIFI_WPSCONFIG, WIFI_RETRY)
-                                                 
+
 // -- Syslog --------------------------------------
 #define SYS_LOG_HOST           "domus1"          // [LogHost] (Linux) syslog host
 #define SYS_LOG_PORT           514               // [LogPort] default syslog UDP port
@@ -172,7 +176,7 @@
 
 /*********************************************************************************************\
  * Compile a minimal version if upgrade memory gets tight ONLY TO BE USED FOR UPGRADE STEP 1!
- *   To be used as step 1 during upgrade. 
+ *   To be used as step 1 during upgrade.
  *   Step 2 is re-compile with option BE_MINIMAL commented out.
  *   !!! Needed for next release of Arduino/ESP8266 (+22k code, +2k mem) !!!
 \*********************************************************************************************/
diff --git a/sonoff/user_config_override.h b/sonoff/user_config_override.h
index 39ce166cb..02631af99 100644
--- a/sonoff/user_config_override.h
+++ b/sonoff/user_config_override.h
@@ -19,7 +19,7 @@
 
 /*****************************************************************************************************\
  * ATTENTION: - Changes to most PARAMETER defines will only override flash settings if you change
- *              define CFG_HOLDER. 
+ *              define CFG_HOLDER.
  *            - Expect compiler warnings when no ifdef/undef/endif sequence is used.
  *            - You still need to update user_config.h for major defines MODULE and USE_MQTT_TLS.
  *            - Changing MODULE defines are not being tested for validity as they are in user_config.h.
diff --git a/sonoff/webserver.ino b/sonoff/webserver.ino
index f17883609..c12da3973 100644
--- a/sonoff/webserver.ino
+++ b/sonoff/webserver.ino
@@ -41,7 +41,7 @@ const char HTTP_HEAD[] PROGMEM =
   "x=null;"                  // Allow for abortion
   "function u(){"
     "if(cn>=0){"
-      "document.getElementById('t').innerHTML='Restart in '+cn+' seconds';"
+      "document.getElementById('t').innerHTML='" D_RESTART_IN " '+cn+' " D_SECONDS "';"
       "cn--;"
       "setTimeout(u,1000);"
     "}"
@@ -91,7 +91,7 @@ const char HTTP_HEAD[] PROGMEM =
   "</head>"
   "<body>"
   "<div style='text-align:left;display:inline-block;min-width:340px;'>"
-  "<div style='text-align:center;'><h3>{ha} 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
@@ -141,112 +141,118 @@ const char HTTP_SCRIPT_MODULE2[] PROGMEM =
 const char HTTP_SCRIPT_MODULE3[] PROGMEM =
     "\";"
     "os=o0.replace(/}1/g,\"<option value=\").replace(/}2/g,\"</option>\");";
+const char HTTP_MSG_SLIDER1[] PROGMEM =
+  "<div><span class='p'>" D_COLDLIGHT "</span><span class='q'>" D_WARMLIGHT "</span></div>"
+  "<div><input type='range' min='153' max='500' value='%d' onchange='lc(value)'></div>";
+const char HTTP_MSG_SLIDER2[] PROGMEM =
+  "<div><span class='p'>" D_DARKLIGHT "</span><span class='q'>" D_BRIGHTLIGHT "</span></div>"
+  "<div><input type='range' min='1' max='100' value='%d' onchange='lb(value)'></div>";
 const char HTTP_MSG_RSTRT[] PROGMEM =
-  "<br/><div style='text-align:center;'>Device will restart in a few seconds</div><br/>";
+  "<br/><div style='text-align:center;'>" D_DEVICE_WILL_RESTART "</div><br/>";
 const char HTTP_BTN_MENU1[] PROGMEM =
-  "<br/><form action='cn' method='get'><button>Configuration</button></form>"
-  "<br/><form action='in' method='get'><button>Information</button></form>"
-  "<br/><form action='up' method='get'><button>Firmware upgrade</button></form>"
-  "<br/><form action='cs' method='get'><button>Console</button></form>";
+  "<br/><form action='cn' method='get'><button>" D_CONFIGURATION "</button></form>"
+  "<br/><form action='in' method='get'><button>" D_INFORMATION "</button></form>"
+  "<br/><form action='up' method='get'><button>" D_FIRMWARE_UPGRADE "</button></form>"
+  "<br/><form action='cs' method='get'><button>" D_CONSOLE "</button></form>";
 const char HTTP_BTN_RSTRT[] PROGMEM =
-  "<br/><form action='rb' method='get' onsubmit='return confirm(\"Confirm Restart\");'><button>Restart</button></form>";
+  "<br/><form action='rb' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESTART "\");'><button>" D_RESTART "</button></form>";
 const char HTTP_BTN_MENU2[] PROGMEM =
-  "<br/><form action='md' method='get'><button>Configure Module</button></form>"
-  "<br/><form action='w0' method='get'><button>Configure WiFi</button></form>";
+  "<br/><form action='md' method='get'><button>" D_CONFIGURE_MODULE "</button></form>"
+  "<br/><form action='w0' method='get'><button>" D_CONFIGURE_WIFI "</button></form>";
 const char HTTP_BTN_MENU3[] PROGMEM =
-  "<br/><form action='mq' method='get'><button>Configure MQTT</button></form>"
+  "<br/><form action='mq' method='get'><button>" D_CONFIGURE_MQTT "</button></form>"
 #ifdef USE_DOMOTICZ
-  "<br/><form action='dm' method='get'><button>Configure Domoticz</button></form>"
+  "<br/><form action='dm' method='get'><button>" D_CONFIGURE_DOMOTICZ "</button></form>"
 #endif  // USE_DOMOTICZ
   "";
 const char HTTP_BTN_MENU4[] PROGMEM =
-  "<br/><form action='lg' method='get'><button>Configure Logging</button></form>"
-  "<br/><form action='co' method='get'><button>Configure Other</button></form>"
-  "<br/><form action='rt' method='get' onsubmit='return confirm(\"Confirm Reset Configuration\");'><button>Reset Configuration</button></form>"
-  "<br/><form action='dl' method='get'><button>Backup Configuration</button></form>"
-  "<br/><form action='rs' method='get'><button>Restore Configuration</button></form>";
+  "<br/><form action='lg' method='get'><button>" D_CONFIGURE_LOGGING "</button></form>"
+  "<br/><form action='co' method='get'><button>" D_CONFIGURE_OTHER "</button></form>"
+  "<br/><form action='rt' method='get' onsubmit='return confirm(\"" D_CONFIRM_RESET_CONFIGURATION "\");'><button>" D_RESET_CONFIGURATION "</button></form>"
+  "<br/><form action='dl' method='get'><button>" D_BACKUP_CONFIGURATION "</button></form>"
+  "<br/><form action='rs' method='get'><button>" D_RESTORE_CONFIGURATION "</button></form>";
 const char HTTP_BTN_MAIN[] PROGMEM =
-  "<br/><br/><form action='.' method='get'><button>Main menu</button></form>";
+  "<br/><br/><form action='.' method='get'><button>" D_MAIN_MENU "</button></form>";
 const char HTTP_BTN_CONF[] PROGMEM =
-  "<br/><br/><form action='cn' method='get'><button>Configuration menu</button></form>";
+  "<br/><br/><form action='cn' method='get'><button>" D_CONFIGURATION "</button></form>";
 const char HTTP_FORM_MODULE[] PROGMEM =
-  "<fieldset><legend><b>&nbsp;Module parameters&nbsp;</b></legend><form method='get' action='sv'>"
+  "<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>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 =
-  "<div><a href='/w1'>Scan for wifi networks</a></div><br/>";
+  "<div><a href='/w1'>" D_SCAN_FOR_WIFI_NETWORKS "</a></div><br/>";
 const char HTTP_FORM_WIFI[] PROGMEM =
-  "<fieldset><legend><b>&nbsp;Wifi parameters&nbsp;</b></legend><form method='get' action='sv'>"
+  "<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>AP1 SSId</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' length=32 placeholder='" STA_SSID1 "' value='{s1}'><br/>"
-  "<br/><b>AP1 Password</b></br><input id='p1' name='p1' length=64 type='password' placeholder='" STA_PASS1 "' value='{p1}'><br/>"
-  "<br/><b>AP2 SSId</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' length=32 placeholder='" STA_SSID2 "' value='{s2}'><br/>"
-  "<br/><b>AP2 Password</b></br><input id='p2' name='p2' length=64 type='password' placeholder='" STA_PASS2 "' value='{p2}'><br/>"
-  "<br/><b>Hostname</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' length=32 placeholder='" WIFI_HOSTNAME" ' value='{h1}'><br/>";
+  "<br/><b>" D_AP1_SSID "</b> (" STA_SSID1 ")<br/><input id='s1' name='s1' length=32 placeholder='" STA_SSID1 "' value='{s1}'><br/>"
+  "<br/><b>" D_AP1_PASSWORD "</b></br><input id='p1' name='p1' length=64 type='password' placeholder='" STA_PASS1 "' value='{p1}'><br/>"
+  "<br/><b>" D_AP2_SSID "</b> (" STA_SSID2 ")<br/><input id='s2' name='s2' length=32 placeholder='" STA_SSID2 "' value='{s2}'><br/>"
+  "<br/><b>" D_AP2_PASSWORD "</b></br><input id='p2' name='p2' length=64 type='password' placeholder='" STA_PASS2 "' value='{p2}'><br/>"
+  "<br/><b>" D_HOSTNAME "</b> (" WIFI_HOSTNAME ")<br/><input id='h' name='h' length=32 placeholder='" WIFI_HOSTNAME" ' value='{h1}'><br/>";
 const char HTTP_FORM_MQTT[] PROGMEM =
-  "<fieldset><legend><b>&nbsp;MQTT parameters&nbsp;</b></legend><form method='get' action='sv'>"
+  "<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>Host</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' length=32 placeholder='" MQTT_HOST" ' value='{m1}'><br/>"
-  "<br/><b>Port</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' length=5 placeholder='" STR(MQTT_PORT) "' value='{m2}'><br/>"
-  "<br/><b>Client Id</b> ({m0})<br/><input id='mc' name='mc' length=32 placeholder='" MQTT_CLIENT_ID "' value='{m3}'><br/>"
-  "<br/><b>User</b> (" MQTT_USER ")<br/><input id='mu' name='mu' length=32 placeholder='" MQTT_USER "' value='{m4}'><br/>"
-  "<br/><b>Password</b><br/><input id='mp' name='mp' length=32 type='password' placeholder='" MQTT_PASS "' value='{m5}'><br/>"
-  "<br/><b>Topic</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' length=32 placeholder='" MQTT_TOPIC" ' value='{m6}'><br/>"
-  "<br/><b>Full Topic</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' length=80 placeholder='" MQTT_FULLTOPIC" ' value='{m7}'><br/>";
+  "<br/><b>" D_HOST "</b> (" MQTT_HOST ")<br/><input id='mh' name='mh' length=32 placeholder='" MQTT_HOST" ' value='{m1}'><br/>"
+  "<br/><b>" D_PORT "</b> (" STR(MQTT_PORT) ")<br/><input id='ml' name='ml' length=5 placeholder='" STR(MQTT_PORT) "' value='{m2}'><br/>"
+  "<br/><b>" D_CLIENT "</b> ({m0})<br/><input id='mc' name='mc' length=32 placeholder='" MQTT_CLIENT_ID "' value='{m3}'><br/>"
+  "<br/><b>" D_USER "</b> (" MQTT_USER ")<br/><input id='mu' name='mu' length=32 placeholder='" MQTT_USER "' value='{m4}'><br/>"
+  "<br/><b>" D_PASSWORD "</b><br/><input id='mp' name='mp' length=32 type='password' placeholder='" MQTT_PASS "' value='{m5}'><br/>"
+  "<br/><b>" D_TOPIC "</b> = %topic% (" MQTT_TOPIC ")<br/><input id='mt' name='mt' length=32 placeholder='" MQTT_TOPIC" ' value='{m6}'><br/>"
+  "<br/><b>" D_FULL_TOPIC "</b> (" MQTT_FULLTOPIC ")<br/><input id='mf' name='mf' length=80 placeholder='" MQTT_FULLTOPIC" ' value='{m7}'><br/>";
 const char HTTP_FORM_LOG1[] PROGMEM =
-  "<fieldset><legend><b>&nbsp;Logging parameters&nbsp;</b></legend><form method='get' action='sv'>"
+  "<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}log level</b> ({b1})<br/><select id='{b2}' name='{b2}'>"
-  "<option{a0value='0'>0 None</option>"
-  "<option{a1value='1'>1 Error</option>"
-  "<option{a2value='2'>2 Info</option>"
-  "<option{a3value='3'>3 Debug</option>"
-  "<option{a4value='4'>4 More debug</option>"
-  "</select></br>";  
+  "<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>"
+  "<option{a3value='3'>3 " D_DEBUG "</option>"
+  "<option{a4value='4'>4 " D_MORE_DEBUG "</option>"
+  "</select></br>";
 const char HTTP_FORM_LOG3[] PROGMEM =
-  "<br/><b>Syslog host</b> (" SYS_LOG_HOST ")<br/><input id='lh' name='lh' length=32 placeholder='" SYS_LOG_HOST "' value='{l2}'><br/>"
-  "<br/><b>Syslog port</b> (" STR(SYS_LOG_PORT) ")<br/><input id='lp' name='lp' length=5 placeholder='" STR(SYS_LOG_PORT) "' value='{l3}'><br/>"
-  "<br/><b>Telemetric period</b> (" STR(TELE_PERIOD) ")<br/><input id='lt' name='lt' length=4 placeholder='" STR(TELE_PERIOD) "' value='{l4}'><br/>";
+  "<br/><b>" D_SYSLOG_HOST "</b> (" SYS_LOG_HOST ")<br/><input id='lh' name='lh' length=32 placeholder='" SYS_LOG_HOST "' value='{l2}'><br/>"
+  "<br/><b>" D_SYSLOG_PORT "</b> (" STR(SYS_LOG_PORT) ")<br/><input id='lp' name='lp' length=5 placeholder='" STR(SYS_LOG_PORT) "' value='{l3}'><br/>"
+  "<br/><b>" D_TELEMETRY_PERIOD "</b> (" STR(TELE_PERIOD) ")<br/><input id='lt' name='lt' length=4 placeholder='" STR(TELE_PERIOD) "' value='{l4}'><br/>";
 const char HTTP_FORM_OTHER[] PROGMEM =
-  "<fieldset><legend><b>&nbsp;Other parameters&nbsp;</b></legend><form method='get' action='sv'>"
+  "<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>Web Admin Password</b><br/><input id='p1' name='p1' length=32 type='password' placeholder='" WEB_PASSWORD "' value='{p1}'><br/>"
-  "<br/><input style='width:10%;float:left' id='b1' name='b1' type='checkbox'{r1}><b>MQTT enable</b><br/>";
+  "<br/><b>" D_WEB_ADMIN_PASSWORD "</b><br/><input id='p1' name='p1' length=32 type='password' placeholder='" WEB_PASSWORD "' value='{p1}'><br/>"
+  "<br/><input style='width:10%;float:left' id='b1' name='b1' type='checkbox'{r1}><b>" D_MQTT_ENABLE "</b><br/>";
 const char HTTP_FORM_OTHER2[] PROGMEM =
-  "<br/><b>Friendly Name {1</b> ({2)<br/><input id='a{1' name='a{1' length=32 placeholder='{2' value='{3'><br/>";
+  "<br/><b>" D_FRIENDLY_NAME " {1</b> ({2)<br/><input id='a{1' name='a{1' length=32 placeholder='{2' value='{3'><br/>";
 #ifdef USE_EMULATION
 const char HTTP_FORM_OTHER3a[] PROGMEM =
-  "<br/><fieldset><legend><b>&nbsp;Emulation&nbsp;</b></legend>";
+  "<br/><fieldset><legend><b>&nbsp;" D_EMULATION "&nbsp;</b></legend>";
 const char HTTP_FORM_OTHER3b[] PROGMEM =
   "<br/><input style='width:10%;float:left' id='b2' name='b2' type='radio' value='{1'{2><b>{3</b>{4";
 #endif  // USE_EMULATION
 const char HTTP_FORM_END[] PROGMEM =
-  "<br/><button type='submit'>Save</button></form></fieldset>";
+  "<br/><button type='submit'>" D_SAVE "</button></form></fieldset>";
 const char HTTP_FORM_RST[] PROGMEM =
   "<div id='f1' name='f1' style='display:block;'>"
-  "<fieldset><legend><b>&nbsp;Restore configuration&nbsp;</b></legend>";
+  "<fieldset><legend><b>&nbsp;" D_RESTORE_CONFIGURATION "&nbsp;</b></legend>";
 const char HTTP_FORM_UPG[] PROGMEM =
   "<div id='f1' name='f1' style='display:block;'>"
-  "<fieldset><legend><b>&nbsp;Upgrade by web server&nbsp;</b></legend>"
+  "<fieldset><legend><b>&nbsp;" D_UPGRADE_BY_WEBSERVER "&nbsp;</b></legend>"
   "<form method='get' action='u1'>"
-  "<br/>OTA Url<br/><input id='o' name='o' length=80 placeholder='OTA_URL' value='{o1}'><br/>"
-  "<br/><button type='submit'>Start upgrade</button></form>"
+  "<br/>" D_OTA_URL "<br/><input id='o' name='o' length=80 placeholder='OTA_URL' value='{o1}'><br/>"
+  "<br/><button type='submit'>" D_START_UPGRADE "</button></form>"
   "</fieldset><br/><br/>"
-  "<fieldset><legend><b>&nbsp;Upgrade by file upload&nbsp;</b></legend>";
+  "<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();'>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>Upload started ...</b></div>";
+  "<div id='f2' name='f2' style='display:none;text-align:center;'><b>" D_UPLOAD_STARTED " ...</b></div>";
 const char HTTP_FORM_CMND[] PROGMEM =
   "<br/><textarea readonly id='t1' name='t1' cols='" STR(MESSZ) "' wrap='off'></textarea><br/><br/>"
   "<form method='get' onsubmit='return l(1);'>"
-  "<input style='width:98%' id='c1' name='c1' length='99' placeholder='Enter command' autofocus><br/>"
+  "<input style='width:98%' id='c1' name='c1' length='99' placeholder='" D_ENTER_COMMAND "' autofocus><br/>"
 //  "<br/><button type='submit'>Send command</button>"
   "</form>";
 const char HTTP_TABLE100[] PROGMEM =
@@ -254,17 +260,17 @@ const char HTTP_TABLE100[] PROGMEM =
 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 Temperature</th><td>%s&deg;%c</td></tr>";
+  "<tr><th>%s " D_TEMPERATURE "</th><td>%s&deg;%c</td></tr>";
 const char HTTP_SNS_HUM[] PROGMEM =
-  "<tr><th>%s Humidity</th><td>%s%</td></tr>";
+  "<tr><th>%s " D_HUMIDITY "</th><td>%s%</td></tr>";
 const char HTTP_SNS_PRESSURE[] PROGMEM =
-  "<tr><th>%s Pressure</th><td>%s hPa</td></tr>";
+  "<tr><th>%s " D_PRESSURE "</th><td>%s " D_UNIT_PRESSURE "</td></tr>";
 const char HTTP_SNS_LIGHT[] PROGMEM =
-  "<tr><th>%s Light</th><td>%d%</td></tr>";
+  "<tr><th>%s " D_LIGHT "</th><td>%d%</td></tr>";
 const char HTTP_SNS_NOISE[] PROGMEM =
-  "<tr><th>%s Noise</th><td>%d%</td></tr>";
+  "<tr><th>%s " D_NOISE "</th><td>%d%</td></tr>";
 const char HTTP_SNS_DUST[] PROGMEM =
-  "<tr><th>%s Air quality</th><td>%d%</td></tr>";
+  "<tr><th>%s " D_AIR_QUALITY "</th><td>%d%</td></tr>";
 const char HTTP_END[] PROGMEM =
   "</div>"
   "</body>"
@@ -339,8 +345,8 @@ void startWebserver(int type, IPAddress ipweb)
     webServer->begin(); // Web server start
   }
   if (_httpflag != type) {
-    snprintf_P(log, sizeof(log), PSTR("HTTP: Webserver active on %s%s with IP address %s"),
-      Hostname, (mDNSbegun)?".local":"", ipweb.toString().c_str());
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_WEBSERVER_ACTIVE_ON " %s%s " D_WITH_IP_ADDRESS " %s"),
+      Hostname, (mDNSbegun) ? ".local" : "", ipweb.toString().c_str());
     addLog(LOG_LEVEL_INFO, log);
   }
   if (type) _httpflag = type;
@@ -351,7 +357,7 @@ void stopWebserver()
   if (_httpflag) {
     webServer->close();
     _httpflag = HTTP_OFF;
-    addLog_P(LOG_LEVEL_INFO, PSTR("HTTP: Webserver stopped"));
+    addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_HTTP D_WEBSERVER_STOPPED));
   }
 }
 
@@ -360,10 +366,10 @@ void beginWifiManager()
   // setup AP
   if ((WL_CONNECTED == WiFi.status()) && (static_cast<uint32_t>(WiFi.localIP()) != 0)) {
     WiFi.mode(WIFI_AP_STA);
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifimanager: Set AccessPoint and keep Station"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_WIFIMANAGER_SET_ACCESSPOINT_AND_STATION));
   } else {
     WiFi.mode(WIFI_AP);
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifimanager: Set AccessPoint"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_WIFIMANAGER_SET_ACCESSPOINT));
   }
 
   stopWebserver();
@@ -415,7 +421,8 @@ void showPage(String &page)
 
 void handleRoot()
 {
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Root"));
+//  addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_MAIN_MENU));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_MAIN_MENU);
 
   if (captivePortal()) { // If captive portal redirect instead of displaying the page.
     return;
@@ -426,26 +433,24 @@ void handleRoot()
   } else {
     char stemp[10], line[160];
     String page = FPSTR(HTTP_HEAD);
-    page.replace(F("{v}"), F("Main menu"));
+    page.replace(F("{v}"), S_MAIN_MENU);
     page.replace(F("<body>"), F("<body onload='la()'>"));
 
     page += F("<div id='l1' name='l1'></div>");
     if (Maxdevice) {
       if (sfl_flg) {
         if ((2 == sfl_flg) || (5 == sfl_flg)) {
-          snprintf_P(line, sizeof(line), PSTR("<div><span class='p'>Cold</span><span class='q'>Warm</span></div><div><input type='range' min='153' max='500' value='%d' onchange='lc(value)'></div>"),
-            sl_getColorTemp());
+          snprintf_P(line, sizeof(line), HTTP_MSG_SLIDER1, sl_getColorTemp());
           page += line;
         }
-        snprintf_P(line, sizeof(line), PSTR("<div><span class='p'>Dark</span><span class='q'>Bright</span></div><div><input type='range' min='1' max='100' value='%d' onchange='lb(value)'></div>"),
-          sysCfg.led_dimmer[0]);
+        snprintf_P(line, sizeof(line), HTTP_MSG_SLIDER2, sysCfg.led_dimmer[0]);
         page += line;
       }
       page += FPSTR(HTTP_TABLE100);
       page += F("<tr>");
       for (byte idx = 1; idx <= Maxdevice; idx++) {
         snprintf_P(stemp, sizeof(stemp), PSTR(" %d"), idx);
-        snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>Toggle%s</button></td>"),
+        snprintf_P(line, sizeof(line), PSTR("<td style='width:%d%'><button onclick='la(\"?o=%d\");'>" D_BUTTON_TOGGLE "%s</button></td>"),
           100 / Maxdevice, idx, (Maxdevice > 1) ? stemp : "");
         page += line;
       }
@@ -468,7 +473,7 @@ void handleRoot()
       }
       page += F("</tr></table>");
     }
-    
+
     if (HTTP_ADMIN == _httpflag) {
       page += FPSTR(HTTP_BTN_MENU1);
       page += FPSTR(HTTP_BTN_RSTRT);
@@ -480,28 +485,28 @@ void handleRoot()
 void handleAjax2()
 {
   char svalue[50];
-  
+
   if (strlen(webServer->arg("o").c_str())) {
     do_cmnd_power(atoi(webServer->arg("o").c_str()), 2);
   }
   if (strlen(webServer->arg("d").c_str())) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("dimmer %s"), webServer->arg("d").c_str());
+    snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_DIMMER " %s"), webServer->arg("d").c_str());
     do_cmnd(svalue);
   }
   if (strlen(webServer->arg("t").c_str())) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("ct %s"), webServer->arg("t").c_str());
+    snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_COLORTEMPERATURE " %s"), webServer->arg("t").c_str());
     do_cmnd(svalue);
   }
   if (strlen(webServer->arg("k").c_str())) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("rfkey%s"), webServer->arg("k").c_str());
+    snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RFKEY "%s"), webServer->arg("k").c_str());
     do_cmnd(svalue);
   }
-  
+
   String tpage = "";
   tpage += counter_webPresent();
 #ifndef USE_ADC_VCC
   if (pin[GPIO_ADC0] < 99) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("<tr><th>AnalogInput0</th><td>%d</td></tr>"), getAdc0());
+    snprintf_P(svalue, sizeof(svalue), PSTR("<tr><th>" D_ANALOG_INPUT0 "</th><td>%d</td></tr>"), getAdc0());
     tpage += svalue;
   }
 #endif
@@ -530,7 +535,7 @@ void handleAjax2()
   if (i2c_flg) {
 #ifdef USE_SHT
     tpage += sht_webPresent();
-#endif    
+#endif
 #ifdef USE_HTU
     tpage += htu_webPresent();
 #endif
@@ -541,7 +546,7 @@ void handleAjax2()
     tpage += bh1750_webPresent();
 #endif
   }
-#endif  // USE_I2C    
+#endif  // USE_I2C
   String page = "";
   if (tpage.length() > 0) {
     page += FPSTR(HTTP_TABLE100);
@@ -584,10 +589,10 @@ void handleConfig()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Config"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURATION);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Configuration"));
+  page.replace(F("{v}"), S_CONFIGURATION);
   page += FPSTR(HTTP_BTN_MENU2);
   if (sysCfg.flag.mqtt_enabled) {
     page += FPSTR(HTTP_BTN_MENU3);
@@ -600,7 +605,7 @@ void handleConfig()
 boolean inModule(byte val, uint8_t *arr)
 {
   int offset = 0;
-  
+
   if (!val) {
     return false;  // None
   }
@@ -647,18 +652,18 @@ void handleModule()
   char stemp[20];
   char line[128];
   uint8_t midx;
-  
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Module config"));
+
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MODULE);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Config module"));
+  page.replace(F("{v}"), S_CONFIGURE_MODULE);
   page += FPSTR(HTTP_FORM_MODULE);
   snprintf_P(stemp, sizeof(stemp), modules[MODULE].name);
   page.replace(F("{mt}"), stemp);
 
   mytmplt cmodule;
   memcpy_P(&cmodule, &modules[sysCfg.module], sizeof(cmodule));
-  
+
   String func = FPSTR(HTTP_SCRIPT_MODULE1);
   for (byte i = 0; i < MAXMODULE; i++) {
     midx = pgm_read_byte(nicelist + i);
@@ -679,8 +684,8 @@ void handleModule()
   func += FPSTR(HTTP_SCRIPT_MODULE3);
   for (byte i = 0; i < MAX_GPIO_PIN; i++) {
     if (GPIO_USER == cmodule.gp.io[i]) {
-      snprintf_P(line, sizeof(line), PSTR("<br/><b>GPIO%d</b> %s<select id='g%d' name='g%d'></select></br>"),
-        i, (0==i)?"Button1":(1==i)?"Serial Out":(3==i)?"Serial In":(12==i)?"Relay1":(13==i)?"Led1I":(14==i)?"Sensor":"", i, i);
+      snprintf_P(line, sizeof(line), PSTR("<br/><b>" D_GPIO "%d</b> %s<select id='g%d' name='g%d'></select></br>"),
+        i, (0==i)? D_SENSOR_BUTTON "1":(1==i)? D_SERIAL_OUT :(3==i)? D_SERIAL_IN :(12==i)? D_SENSOR_RELAY "1":(13==i)? D_SENSOR_LED "1I":(14==i)? D_SENSOR :"", i, i);
       page += line;
       snprintf_P(line, sizeof(line), PSTR("sk(%d,%d);"), my_module.gp.io[i], i);  // g0 - g16
       func += line;
@@ -689,7 +694,7 @@ void handleModule()
   func += F("}</script>");
   page.replace(F("</script>"), func);
   page.replace(F("<body>"), F("<body onload='sl()'>"));
-  
+
   page += FPSTR(HTTP_FORM_END);
   page += FPSTR(HTTP_BTN_CONF);
   showPage(page);
@@ -712,21 +717,22 @@ void handleWifi(boolean scan)
   }
   char log[LOGSZ];
 
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Wifi config"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_WIFI);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Configure Wifi"));
+  page.replace(F("{v}"), S_CONFIGURE_WIFI);
 
   if (scan) {
 #ifdef USE_EMULATION
     UDP_Disconnect();
 #endif  // USE_EMULATION
     int n = WiFi.scanNetworks();
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: Scan done"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_SCAN_DONE));
 
     if (0 == n) {
-      addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: No networks found"));
-      page += F("No networks found. Refresh to scan again.");
+      addLog_P(LOG_LEVEL_DEBUG, S_LOG_WIFI, S_NO_NETWORKS_FOUND);
+      page += S_NO_NETWORKS_FOUND;
+      page += F(". " D_REFRESH_TO_SCAN_AGAIN ".");
     } else {
       //sort networks
       int indices[n];
@@ -753,7 +759,7 @@ void handleWifi(boolean scan)
           cssid = WiFi.SSID(indices[i]);
           for (int j = i + 1; j < n; j++) {
             if (cssid == WiFi.SSID(indices[j])) {
-              snprintf_P(log, sizeof(log), PSTR("Wifi: Duplicate AccessPoint %s"), WiFi.SSID(indices[j]).c_str());
+              snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_DUPLICATE_ACCESSPOINT " %s"), WiFi.SSID(indices[j]).c_str());
               addLog(LOG_LEVEL_DEBUG, log);
               indices[j] = -1; // set dup aps to index -1
             }
@@ -766,7 +772,7 @@ void handleWifi(boolean scan)
         if (-1 == indices[i]) {
           continue; // skip dups
         }
-        snprintf_P(log, sizeof(log), PSTR("Wifi: SSID %s, RSSI %d"), WiFi.SSID(indices[i]).c_str(), WiFi.RSSI(indices[i]));
+        snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_SSID " %s, " D_RSSI " %d"), WiFi.SSID(indices[i]).c_str(), WiFi.RSSI(indices[i]));
         addLog(LOG_LEVEL_DEBUG, log);
         int quality = WIFI_getRSSIasQuality(WiFi.RSSI(indices[i]));
 
@@ -777,11 +783,11 @@ void handleWifi(boolean scan)
           item.replace(F("{v}"), WiFi.SSID(indices[i]));
           item.replace(F("{r}"), rssiQ);
           uint8_t auth = WiFi.encryptionType(indices[i]);
-          item.replace(F("{i}"), (ENC_TYPE_WEP == auth) ? F("WEP") : (ENC_TYPE_TKIP == auth) ? F("WPA PSK") : (ENC_TYPE_CCMP == auth) ? F("WPA2 PSK") : (ENC_TYPE_AUTO == auth) ? F("AUTO") : F(""));
+          item.replace(F("{i}"), (ENC_TYPE_WEP == auth) ? F(D_WEP) : (ENC_TYPE_TKIP == auth) ? F(D_WPA_PSK) : (ENC_TYPE_CCMP == auth) ? F(D_WPA2_PSK) : (ENC_TYPE_AUTO == auth) ? F(D_AUTO) : F(""));
           page += item;
           delay(0);
         } else {
-          addLog_P(LOG_LEVEL_DEBUG, PSTR("Wifi: Skipping due to low quality"));
+          addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_WIFI D_SKIPPING_LOW_QUALITY));
         }
 
       }
@@ -811,10 +817,10 @@ void handleMqtt()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: MQTT config"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_MQTT);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Configure MQTT"));
+  page.replace(F("{v}"), S_CONFIGURE_MQTT);
   page += FPSTR(HTTP_FORM_MQTT);
   char str[sizeof(sysCfg.mqtt_client)];
   getClient(str, MQTT_CLIENT_ID, sizeof(sysCfg.mqtt_client));
@@ -836,16 +842,16 @@ void handleLog()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Log config"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_LOGGING);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Config logging"));
+  page.replace(F("{v}"), S_CONFIGURE_LOGGING);
   page += FPSTR(HTTP_FORM_LOG1);
   for (byte idx = 0; idx < 3; idx++) {
     page += FPSTR(HTTP_FORM_LOG2);
     switch (idx) {
     case 0:
-      page.replace(F("{b0}"), F("Serial "));
+      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++) {
@@ -853,7 +859,7 @@ void handleLog()
       }
       break;
     case 1:
-      page.replace(F("{b0}"), F("Web "));
+      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++) {
@@ -861,7 +867,7 @@ void handleLog()
       }
       break;
     case 2:
-      page.replace(F("{b0}"), F("Sys"));
+      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++) {
@@ -884,11 +890,11 @@ void handleOther()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Other config"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_OTHER);
   char stemp[40];
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Configure Other"));
+  page.replace(F("{v}"), S_CONFIGURE_OTHER);
   page += FPSTR(HTTP_FORM_OTHER);
   page.replace(F("{p1}"), sysCfg.web_password);
   page.replace(F("{r1}"), (sysCfg.flag.mqtt_enabled) ? F(" checked") : F(""));
@@ -902,8 +908,8 @@ void handleOther()
     page += FPSTR(HTTP_FORM_OTHER3b);
     page.replace(F("{1"), String(i));
     page.replace(F("{2"), (i == sysCfg.flag.emulation) ? F(" checked") : F(""));
-    page.replace(F("{3"), (i == EMUL_NONE) ? F("None") : (i == EMUL_WEMO) ? F("Belkin WeMo") : F("Hue Bridge"));
-    page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" single device") : F(" multi devices"));
+    page.replace(F("{3"), (i == EMUL_NONE) ? F(D_NONE) : (i == EMUL_WEMO) ? F(D_BELKIN_WEMO) : F(D_HUE_BRIDGE));
+    page.replace(F("{4"), (i == EMUL_NONE) ? F("") : (i == EMUL_WEMO) ? F(" " D_SINGLE_DEVICE) : F(" " D_MULTI_DEVICE));
   }
   page += F("<br/>");
   for (int i = 1; i < Maxdevice; i++) {
@@ -925,7 +931,7 @@ void handleDownload()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Download config"));
+  addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_BACKUP_CONFIGURATION));
 
   uint8_t buffer[sizeof(sysCfg)];
 
@@ -961,7 +967,7 @@ void handleSave()
   byte restart;
   String result = "";
 
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Parameter save"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_SAVE_CONFIGURATION);
 
   if (strlen(webServer->arg("w").c_str())) {
     what = atoi(webServer->arg("w").c_str());
@@ -976,10 +982,10 @@ void handleSave()
     strlcpy(sysCfg.sta_pwd[0], (!strlen(webServer->arg("p1").c_str())) ? STA_PASS1 : webServer->arg("p1").c_str(), sizeof(sysCfg.sta_pwd[0]));
     strlcpy(sysCfg.sta_ssid[1], (!strlen(webServer->arg("s2").c_str())) ? STA_SSID2 : webServer->arg("s2").c_str(), sizeof(sysCfg.sta_ssid[1]));
     strlcpy(sysCfg.sta_pwd[1], (!strlen(webServer->arg("p2").c_str())) ? STA_PASS2 : webServer->arg("p2").c_str(), sizeof(sysCfg.sta_pwd[1]));
-    snprintf_P(log, sizeof(log), PSTR("HTTP: Wifi Hostname %s, SSID1 %s, Password1 %s, SSID2 %s, Password2 %s"),
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_WIFI D_CMND_HOSTNAME " %s, " D_CMND_SSID "1 %s, " D_CMND_PASSWORD "1 %s, " D_CMND_SSID "2 %s, " D_CMND_PASSWORD "2 %s"),
       sysCfg.hostname, sysCfg.sta_ssid[0], sysCfg.sta_pwd[0], sysCfg.sta_ssid[1], sysCfg.sta_pwd[1]);
     addLog(LOG_LEVEL_INFO, log);
-    result += F("<br/>Trying to connect device to network<br/>If it fails reconnect to try again");
+    result += F("<br/>" D_TRYING_TO_CONNECT "<br/>");
     break;
   case 2:
     strlcpy(stemp, (!strlen(webServer->arg("mt").c_str())) ? MQTT_TOPIC : webServer->arg("mt").c_str(), sizeof(stemp));
@@ -987,7 +993,7 @@ void handleSave()
     strlcpy(stemp2, (!strlen(webServer->arg("mf").c_str())) ? MQTT_FULLTOPIC : webServer->arg("mf").c_str(), sizeof(stemp2));
     mqttfy(1,stemp2);
     if ((strcmp(stemp, sysCfg.mqtt_topic)) || (strcmp(stemp2, sysCfg.mqtt_fulltopic))) {
-      mqtt_publish_topic_P(2, PSTR("LWT"), (sysCfg.flag.mqtt_offline) ? "Offline" : "", true);  // Offline or remove previous retained topic
+      mqtt_publish_topic_P(2, S_LWT, (sysCfg.flag.mqtt_offline) ? S_OFFLINE : "", true);  // Offline or remove previous retained topic
     }
     strlcpy(sysCfg.mqtt_topic, stemp, sizeof(sysCfg.mqtt_topic));
     strlcpy(sysCfg.mqtt_fulltopic, stemp2, sizeof(sysCfg.mqtt_fulltopic));
@@ -996,7 +1002,7 @@ void handleSave()
     strlcpy(sysCfg.mqtt_client, (!strlen(webServer->arg("mc").c_str())) ? MQTT_CLIENT_ID : webServer->arg("mc").c_str(), sizeof(sysCfg.mqtt_client));
     strlcpy(sysCfg.mqtt_user, (!strlen(webServer->arg("mu").c_str())) ? MQTT_USER : (!strcmp(webServer->arg("mu").c_str(),"0")) ? "" : webServer->arg("mu").c_str(), sizeof(sysCfg.mqtt_user));
     strlcpy(sysCfg.mqtt_pwd, (!strlen(webServer->arg("mp").c_str())) ? MQTT_PASS : (!strcmp(webServer->arg("mp").c_str(),"0")) ? "" : webServer->arg("mp").c_str(), sizeof(sysCfg.mqtt_pwd));
-    snprintf_P(log, sizeof(log), PSTR("HTTP: MQTT Host %s, Port %d, Client %s, User %s, Password %s, Topic %s, FullTopic %s"),
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_MQTT D_CMND_MQTTHOST " %s, " D_CMND_MQTTPORT " %d, " D_CMND_MQTTCLIENT " %s, " D_CMND_MQTTUSER " %s, " D_CMND_MQTTPASSWORD " %s, " D_CMND_TOPIC " %s, " D_CMND_FULLTOPIC " %s"),
       sysCfg.mqtt_host, sysCfg.mqtt_port, sysCfg.mqtt_client, sysCfg.mqtt_user, sysCfg.mqtt_pwd, sysCfg.mqtt_topic, sysCfg.mqtt_fulltopic);
     addLog(LOG_LEVEL_INFO, log);
     break;
@@ -1009,7 +1015,7 @@ void handleSave()
     strlcpy(sysCfg.syslog_host, (!strlen(webServer->arg("lh").c_str())) ? SYS_LOG_HOST : webServer->arg("lh").c_str(), sizeof(sysCfg.syslog_host));
     sysCfg.syslog_port = (!strlen(webServer->arg("lp").c_str())) ? SYS_LOG_PORT : atoi(webServer->arg("lp").c_str());
     sysCfg.tele_period = (!strlen(webServer->arg("lt").c_str())) ? TELE_PERIOD : atoi(webServer->arg("lt").c_str());
-    snprintf_P(log, sizeof(log), PSTR("HTTP: Logging Seriallog %d, Weblog %d, Syslog %d, Host %s, Port %d, TelePeriod %d"),
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_LOG D_CMND_SERIALLOG " %d, " D_CMND_WEBLOG " %d, " D_CMND_SYSLOG " %d, " D_CMND_LOGHOST " %s, " D_CMND_LOGPORT " %d, " D_CMND_TELEPERIOD " %d"),
       sysCfg.seriallog_level, sysCfg.weblog_level, sysCfg.syslog_level, sysCfg.syslog_host, sysCfg.syslog_port, sysCfg.tele_period);
     addLog(LOG_LEVEL_INFO, log);
     break;
@@ -1028,7 +1034,7 @@ void handleSave()
     strlcpy(sysCfg.friendlyname[1], (!strlen(webServer->arg("a2").c_str())) ? FRIENDLY_NAME"2" : webServer->arg("a2").c_str(), sizeof(sysCfg.friendlyname[1]));
     strlcpy(sysCfg.friendlyname[2], (!strlen(webServer->arg("a3").c_str())) ? FRIENDLY_NAME"3" : webServer->arg("a3").c_str(), sizeof(sysCfg.friendlyname[2]));
     strlcpy(sysCfg.friendlyname[3], (!strlen(webServer->arg("a4").c_str())) ? FRIENDLY_NAME"4" : webServer->arg("a4").c_str(), sizeof(sysCfg.friendlyname[3]));
-    snprintf_P(log, sizeof(log), PSTR("HTTP: Other MQTT Enable %s, Emulation %d, Friendly Names %s, %s, %s and %s"),
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_OTHER D_MQTT_ENABLE " %s, " D_CMND_EMULATION " %d, " D_CMND_FRIENDLYNAME " %s, %s, %s, %s"),
       getStateText(sysCfg.flag.mqtt_enabled), sysCfg.flag.emulation, sysCfg.friendlyname[0], sysCfg.friendlyname[1], sysCfg.friendlyname[2], sysCfg.friendlyname[3]);
     addLog(LOG_LEVEL_INFO, log);
     break;
@@ -1046,11 +1052,11 @@ void handleSave()
       if (GPIO_USER == cmodule.gp.io[i]) {
         snprintf_P(stemp, sizeof(stemp), PSTR("g%d"), i);
         sysCfg.my_module.gp.io[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
-        gpios += F(", GPIO"); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_module.gp.io[i]);
+        gpios += F(", " D_GPIO ); gpios += String(i); gpios += F(" "); gpios += String(sysCfg.my_module.gp.io[i]);
       }
     }
     snprintf_P(stemp, sizeof(stemp), modules[sysCfg.module].name);
-    snprintf_P(log, sizeof(log), PSTR("HTTP: %s Module%s"), stemp, gpios.c_str());
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_MODULE "%s " D_CMND_MODULE "%s"), stemp, gpios.c_str());
     addLog(LOG_LEVEL_INFO, log);
     break;
   }
@@ -1058,8 +1064,8 @@ void handleSave()
   restart = (!strlen(webServer->arg("r").c_str())) ? 1 : atoi(webServer->arg("r").c_str());
   if (restart) {
     String page = FPSTR(HTTP_HEAD);
-    page.replace(F("{v}"), F("Save parameters"));
-    page += F("<div style='text-align:center;'><b>Parameters saved</b><br/>");
+    page.replace(F("{v}"), S_SAVE_CONFIGURATION);
+    page += F("<div style='text-align:center;'><b>" D_CONFIGURATION_SAVED "</b><br/>");
     page += result;
     page += F("</div>");
     page += FPSTR(HTTP_MSG_RSTRT);
@@ -1084,16 +1090,16 @@ void handleReset()
 
   char svalue[16];  // was MESSZ
 
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Reset parameters"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_RESET_CONFIGURATION);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Default parameters"));
-  page += F("<div style='text-align:center;'>Parameters reset to default</div>");
+  page.replace(F("{v}"), S_RESET_CONFIGURATION);
+  page += F("<div style='text-align:center;'>" D_CONFIGURATION_RESET "</div>");
   page += FPSTR(HTTP_MSG_RSTRT);
   page += FPSTR(HTTP_BTN_MAIN);
   showPage(page);
 
-  snprintf_P(svalue, sizeof(svalue), PSTR("reset 1"));
+  snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_RESET " 1"));
   do_cmnd(svalue);
 }
 
@@ -1102,13 +1108,13 @@ void handleRestore()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Restore"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_RESTORE_CONFIGURATION);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Restore Configuration"));
+  page.replace(F("{v}"), S_RESTORE_CONFIGURATION);
   page += FPSTR(HTTP_FORM_RST);
   page += FPSTR(HTTP_FORM_RST_UPG);
-  page.replace(F("{r1}"), F("restore"));
+  page.replace(F("{r1}"), F(D_RESTORE));
   page += FPSTR(HTTP_BTN_CONF);
   showPage(page);
 
@@ -1121,14 +1127,14 @@ void handleUpgrade()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Upgrade"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_FIRMWARE_UPGRADE);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Firmware upgrade"));
+  page.replace(F("{v}"), S_FIRMWARE_UPGRADE);
   page += FPSTR(HTTP_FORM_UPG);
   page.replace(F("{o1}"), sysCfg.otaUrl);
   page += FPSTR(HTTP_FORM_RST_UPG);
-  page.replace(F("{r1}"), F("upgrade"));
+  page.replace(F("{r1}"), F(D_UPGRADE));
   page += FPSTR(HTTP_BTN_MAIN);
   showPage(page);
 
@@ -1143,22 +1149,22 @@ void handleUpgradeStart()
   }
   char svalue[100];  // was MESSZ
 
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Firmware upgrade start"));
+  addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_UPGRADE_STARTED));
   WIFI_configCounter();
 
   if (strlen(webServer->arg("o").c_str())) {
-    snprintf_P(svalue, sizeof(svalue), PSTR("otaurl %s"), webServer->arg("o").c_str());
+    snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_OTAURL " %s"), webServer->arg("o").c_str());
     do_cmnd(svalue);
   }
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Info"));
-  page += F("<div style='text-align:center;'><b>Upgrade started ...</b></div>");
+  page.replace(F("{v}"), S_INFORMATION);
+  page += F("<div style='text-align:center;'><b>" D_UPGRADE_STARTED " ...</b></div>");
   page += FPSTR(HTTP_MSG_RSTRT);
   page += FPSTR(HTTP_BTN_MAIN);
   showPage(page);
 
-  snprintf_P(svalue, sizeof(svalue), PSTR("upgrade 1"));
+  snprintf_P(svalue, sizeof(svalue), PSTR(D_CMND_UPGRADE " 1"));
   do_cmnd(svalue);
 }
 
@@ -1167,39 +1173,40 @@ void handleUploadDone()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: File upload done"));
+  addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_UPLOAD_DONE));
 
-  char error[80];
+  char error[100];
   char log[LOGSZ];
-  
+
   WIFI_configCounter();
   restartflag = 0;
   mqttcounter = 0;
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Info"));
-  page += F("<div style='text-align:center;'><b>Upload ");
+  page.replace(F("{v}"), S_INFORMATION);
+  page += F("<div style='text-align:center;'><b>" D_UPLOAD " <font color='");
   if (_uploaderror) {
-    page += F("<font color='red'>failed</font></b><br/><br/>");
+    page += F("red'>" D_FAILED "</font></b><br/><br/>");
     switch (_uploaderror) {
-      case 1: strcpy_P(error, PSTR("No file selected")); break;
-      case 2: strcpy_P(error, PSTR("Not enough space")); break;
-      case 3: strcpy_P(error, PSTR("Magic byte is not 0xE9")); break;
-      case 4: strcpy_P(error, PSTR("IDE flash size larger than device flash size")); break;
-      case 5: strcpy_P(error, PSTR("Upload buffer miscompare")); break;
-      case 6: strcpy_P(error, PSTR("Upload failed. Enable logging 3")); break;
-      case 7: strcpy_P(error, PSTR("Upload aborted")); break;
-      case 8: strcpy_P(error, PSTR("File invalid")); break;
-      case 9: strcpy_P(error, PSTR("File too large")); break;
+      case 1: strcpy_P(error, PSTR(D_UPLOAD_ERR_1)); break;
+      case 2: strcpy_P(error, PSTR(D_UPLOAD_ERR_2)); break;
+      case 3: strcpy_P(error, PSTR(D_UPLOAD_ERR_3)); break;
+      case 4: strcpy_P(error, PSTR(D_UPLOAD_ERR_4)); break;
+      case 5: strcpy_P(error, PSTR(D_UPLOAD_ERR_5)); break;
+      case 6: strcpy_P(error, PSTR(D_UPLOAD_ERR_6)); break;
+      case 7: strcpy_P(error, PSTR(D_UPLOAD_ERR_7)); break;
+      case 8: strcpy_P(error, PSTR(D_UPLOAD_ERR_8)); break;
+      case 9: strcpy_P(error, PSTR(D_UPLOAD_ERR_9)); break;
       default:
-        snprintf_P(error, sizeof(error), PSTR("Upload error code %d"), _uploaderror);
+        snprintf_P(error, sizeof(error), PSTR(D_UPLOAD_ERROR_CODE " %d"), _uploaderror);
     }
     page += error;
-    snprintf_P(log, sizeof(log), PSTR("Upload: %s"), error);
+    snprintf_P(log, sizeof(log), PSTR(D_UPLOAD ": %s"), error);
     addLog(LOG_LEVEL_DEBUG, log);
     stop_flash_rotate = sysCfg.flag.stop_flash_rotate;
   } else {
-    page += F("<font color='green'>successful</font></b><br/><br/>Device will restart in a few seconds");
+    page += F("green'>" D_SUCCESSFUL "</font></b><br/>");
+    page += FPSTR(HTTP_MSG_RSTRT);
     restartflag = 2;
   }
   page += F("</div><br/>");
@@ -1232,7 +1239,7 @@ void handleUploadLoop()
       return;
     }
     CFG_Save(1);  // Free flash for upload
-    snprintf_P(log, sizeof(log), PSTR("Upload: File %s ..."), upload.filename.c_str());
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_UPLOAD D_FILE " %s ..."), upload.filename.c_str());
     addLog(LOG_LEVEL_INFO, log);
     if (!_uploadfiletype) {
       mqttcounter = 60;
@@ -1312,7 +1319,7 @@ void handleUploadLoop()
       }
     }
     if (!_uploaderror) {
-      snprintf_P(log, sizeof(log), PSTR("Upload: Successful %u bytes. Restarting"), upload.totalSize);
+      snprintf_P(log, sizeof(log), PSTR(D_LOG_UPLOAD D_SUCCESSFUL " %u bytes. " D_RESTARTING), upload.totalSize);
       addLog(LOG_LEVEL_INFO, log);
     }
   } else if (UPLOAD_FILE_ABORTED == upload.status) {
@@ -1333,7 +1340,7 @@ void handleCmnd()
   }
   char svalue[INPUT_BUFFER_SIZE];  // big to serve Backlog
 
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Command"));
+  addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_COMMAND));
 
   uint8_t valid = 1;
   if (sysCfg.web_password[0] != 0) {
@@ -1376,10 +1383,10 @@ void handleCmnd()
         }
       } while (counter != logidx);
     } else {
-      message = F("Enable weblog 2 if response expected\n");
+      message = F(D_ENABLE_WEBLOG_FOR_RESPONSE "\n");
     }
   } else {
-    message = F("Need user=<username>&password=<password>\n");
+    message = F(D_NEED_USER_AND_PASSWORD "\n");
   }
   webServer->send(200, FPSTR(HDR_CTYPE_PLAIN), message);
 }
@@ -1390,10 +1397,10 @@ void handleConsole()
     return;
   }
 
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Console"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONSOLE);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Console"));
+  page.replace(F("{v}"), S_CONSOLE);
   page.replace(F("</script>"), FPSTR(HTTP_SCRIPT_CONSOL));
   page.replace(F("<body>"), F("<body onload='l()'>"));
   page += FPSTR(HTTP_FORM_CMND);
@@ -1413,14 +1420,14 @@ void handleAjax()
 
   if (strlen(webServer->arg("c1").c_str())) {
     snprintf_P(svalue, sizeof(svalue), PSTR("%s"), webServer->arg("c1").c_str());
-    snprintf_P(log, sizeof(log), PSTR("CMND: %s"), svalue);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_COMMAND "%s"), svalue);
     addLog(LOG_LEVEL_INFO, log);
     byte syslog_now = syslog_level;
     syslog_level = 0;  // Disable UDP syslog to not trigger hardware WDT
     do_cmnd(svalue);
     syslog_level = syslog_now;
   }
-  
+
   if (strlen(webServer->arg("c2").c_str())) {
     counter = atoi(webServer->arg("c2").c_str());
   }
@@ -1463,103 +1470,100 @@ void handleInfo()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Info"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_INFORMATION);
 
   char stopic[TOPSZ];
 
   int freeMem = ESP.getFreeHeap();
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Information"));
+  page.replace(F("{v}"), S_INFORMATION);
 //  page += F("<fieldset><legend><b>&nbsp;Information&nbsp;</b></legend>");
   page += F("<style>td{padding:0px 5px;}</style>");
   page += F("<table style'width:100%;'>");
-  page += F("<tr><th>Program version</th><td>"); page += Version; page += F("</td></tr>");
-  page += F("<tr><th>Build Date & Time</th><td>"); page += getBuildDateTime(); page += F("</td></tr>");
-  page += F("<tr><th>Core/SDK version</th><td>"); page += ESP.getCoreVersion(); page += F("/"); page += String(ESP.getSdkVersion()); page += F("</td></tr>");
-//  page += F("<tr><th>Boot version</th><td>"); page += String(ESP.getBootVersion()); page += F("</td></tr>");
-  page += F("<tr><th>Uptime</th><td>"); page += String(uptime); page += F(" Hours</td></tr>");
+  page += F("<tr><th>" D_PROGRAM_VERSION "</th><td>"); page += Version; page += F("</td></tr>");
+  page += F("<tr><th>" D_BUILD_DATE_AND_TIME "</th><td>"); page += getBuildDateTime(); page += F("</td></tr>");
+  page += F("<tr><th>" D_CORE_AND_SDK_VERSION "</th><td>"); page += ESP.getCoreVersion(); page += F("/"); page += String(ESP.getSdkVersion()); page += F("</td></tr>");
+  page += F("<tr><th>" D_UPTIME "</th><td>"); page += String(uptime); page += F(" Hours</td></tr>");
   snprintf_P(stopic, sizeof(stopic), PSTR(" at %X"), CFG_Address());
-  page += F("<tr><th>Flash write count</th><td>"); page += String(sysCfg.saveFlag); page += stopic; page += F("</td></tr>");
-  page += F("<tr><th>Boot count</th><td>"); page += String(sysCfg.bootcount); page += F("</td></tr>");
-  page += F("<tr><th>Reset reason</th><td>"); page += getResetReason(); page += F("</td></tr>");
+  page += F("<tr><th>" D_FLASH_WRITE_COUNT "</th><td>"); page += String(sysCfg.saveFlag); page += stopic; page += F("</td></tr>");
+  page += F("<tr><th>" D_BOOT_COUNT "</th><td>"); page += String(sysCfg.bootcount); page += F("</td></tr>");
+  page += F("<tr><th>" D_RESTART_REASON "</th><td>"); page += getResetReason(); page += F("</td></tr>");
   for (byte i = 0; i < Maxdevice; i++) {
-    page += F("<tr><th>Friendly name ");
+    page += F("<tr><th>" D_FRIENDLY_NAME " ");
     page += i +1;
     page += F("</th><td>"); page += sysCfg.friendlyname[i]; page += F("</td></tr>");
   }
   page += F("<tr><td>&nbsp;</td></tr>");
-  page += F("<tr><th>AP"); page += String(sysCfg.sta_active +1);
-    page += F(" SSId (RSSI)</th><td>"); page += sysCfg.sta_ssid[sysCfg.sta_active]; page += F(" ("); page += WIFI_getRSSIasQuality(WiFi.RSSI()); page += F("%)</td></tr>");
-  page += F("<tr><th>Hostname</th><td>"); page += Hostname; page += F("</td></tr>");
+  page += F("<tr><th>" D_AP); page += String(sysCfg.sta_active +1);
+    page += F(" " D_SSID " (" D_RSSI ")</th><td>"); page += sysCfg.sta_ssid[sysCfg.sta_active]; page += F(" ("); page += WIFI_getRSSIasQuality(WiFi.RSSI()); page += F("%)</td></tr>");
+  page += F("<tr><th>" D_HOSTNAME "</th><td>"); page += Hostname; page += F("</td></tr>");
   if (static_cast<uint32_t>(WiFi.localIP()) != 0) {
-    page += F("<tr><th>IP address</th><td>"); page += WiFi.localIP().toString(); page += F("</td></tr>");
-    page += F("<tr><th>Gateway</th><td>"); page += IPAddress(sysCfg.ip_address[1]).toString(); page += F("</td></tr>");
-    page += F("<tr><th>Subnet mask</th><td>"); page += IPAddress(sysCfg.ip_address[2]).toString(); page += F("</td></tr>");
-    page += F("<tr><th>DNS server</th><td>"); page += IPAddress(sysCfg.ip_address[3]).toString(); page += F("</td></tr>");
-    page += F("<tr><th>MAC address</th><td>"); page += WiFi.macAddress(); page += F("</td></tr>");
+    page += F("<tr><th>" D_IP_ADDRESS "</th><td>"); page += WiFi.localIP().toString(); page += F("</td></tr>");
+    page += F("<tr><th>" D_GATEWAY "</th><td>"); page += IPAddress(sysCfg.ip_address[1]).toString(); page += F("</td></tr>");
+    page += F("<tr><th>" D_SUBNET_MASK "</th><td>"); page += IPAddress(sysCfg.ip_address[2]).toString(); page += F("</td></tr>");
+    page += F("<tr><th>" D_DNS_SERVER "</th><td>"); page += IPAddress(sysCfg.ip_address[3]).toString(); page += F("</td></tr>");
+    page += F("<tr><th>" D_MAC_ADDRESS "</th><td>"); page += WiFi.macAddress(); page += F("</td></tr>");
   }
   if (static_cast<uint32_t>(WiFi.softAPIP()) != 0) {
-    page += F("<tr><th>AP IP address</th><td>"); page += WiFi.softAPIP().toString(); page += F("</td></tr>");
-    page += F("<tr><th>AP Gateway</th><td>"); page += WiFi.softAPIP().toString(); page += F("</td></tr>");
-    page += F("<tr><th>AP MAC address</th><td>"); page += WiFi.softAPmacAddress(); page += F("</td></tr>");
+    page += F("<tr><th>" D_AP " " D_IP_ADDRESS "</th><td>"); page += WiFi.softAPIP().toString(); page += F("</td></tr>");
+    page += F("<tr><th>" D_AP " " D_GATEWAY "</th><td>"); page += WiFi.softAPIP().toString(); page += F("</td></tr>");
+    page += F("<tr><th>" D_AP " " D_MAC_ADDRESS "</th><td>"); page += WiFi.softAPmacAddress(); page += F("</td></tr>");
   }
   page += F("<tr><td>&nbsp;</td></tr>");
   if (sysCfg.flag.mqtt_enabled) {
-    page += F("<tr><th>MQTT Host</th><td>"); page += sysCfg.mqtt_host; page += F("</td></tr>");
-    page += F("<tr><th>MQTT Port</th><td>"); page += String(sysCfg.mqtt_port); page += F("</td></tr>");
-    page += F("<tr><th>MQTT Client &<br/>&nbsp;Fallback Topic</th><td>"); page += MQTTClient; page += F("</td></tr>");
-    page += F("<tr><th>MQTT User</th><td>"); page += sysCfg.mqtt_user; page += F("</td></tr>");
-//    page += F("<tr><th>MQTT Password</th><td>"); page += sysCfg.mqtt_pwd; page += F("</td></tr>");
-    page += F("<tr><th>MQTT Topic</th><td>"); page += sysCfg.mqtt_topic; page += F("</td></tr>");
-    page += F("<tr><th>MQTT Group Topic</th><td>"); page += sysCfg.mqtt_grptopic; page += F("</td></tr>");
-
+    page += F("<tr><th>" D_MQTT_HOST "</th><td>"); page += sysCfg.mqtt_host; page += F("</td></tr>");
+    page += F("<tr><th>" D_MQTT_PORT "</th><td>"); page += String(sysCfg.mqtt_port); page += F("</td></tr>");
+    page += F("<tr><th>" D_MQTT_CLIENT " &<br/>&nbsp;" D_FALLBACK_TOPIC "</th><td>"); page += MQTTClient; page += F("</td></tr>");
+    page += F("<tr><th>" D_MQTT_USER "</th><td>"); page += sysCfg.mqtt_user; page += F("</td></tr>");
+    page += F("<tr><th>" D_MQTT_TOPIC "</th><td>"); page += sysCfg.mqtt_topic; page += F("</td></tr>");
+    page += F("<tr><th>" D_MQTT_GROUP_TOPIC "</th><td>"); page += sysCfg.mqtt_grptopic; page += F("</td></tr>");
     getTopic_P(stopic, 0, sysCfg.mqtt_topic, "");
-    page += F("<tr><th>MQTT Full Topic</th><td>"); page += stopic; page += F("</td></tr>");
-    
+    page += F("<tr><th>" D_MQTT_FULL_TOPIC "</th><td>"); page += stopic; page += F("</td></tr>");
+
   } else {
-    page += F("<tr><th>MQTT</th><td>Disabled</td></tr>");
+    page += F("<tr><th>" D_MQTT "</th><td>" D_DISABLED "</td></tr>");
   }
   page += F("<tr><td>&nbsp;</td></tr>");
-  page += F("<tr><th>Emulation</th><td>");
+  page += F("<tr><th>" D_EMULATION "</th><td>");
 #ifdef USE_EMULATION
   if (EMUL_WEMO == sysCfg.flag.emulation) {
-    page += F("Belkin WeMo");
+    page += F(D_BELKIN_WEMO);
   }
   else if (EMUL_HUE == sysCfg.flag.emulation) {
-    page += F("Hue Bridge");
+    page += F(D_HUE_BRIDGE);
   }
   else {
-    page += F("None");
+    page += F(D_NONE);
   }
 #else
-  page += F("Disabled");
+  page += F(D_DISABLED);
 #endif // USE_EMULATION
   page += F("</td></tr>");
-  
-  page += F("<tr><th>mDNS Discovery</th><td>");
+
+  page += F("<tr><th>" D_MDNS_DISCOVERY "</th><td>");
 #ifdef USE_DISCOVERY
-  page += F("Enabled");
+  page += F(D_ENABLED);
   page += F("</td></tr>");
-  page += F("<tr><th>mDNS Advertise</th><td>");
+  page += F("<tr><th>" D_MDNS_ADVERTISE "</th><td>");
 #ifdef WEBSERVER_ADVERTISE
-  page += F("Webserver");
+  page += F(D_WEB_SERVER);
 #else
-  page += F("Disabled");
+  page += F(D_DISABLED);
 #endif // WEBSERVER_ADVERTISE
 #else
-  page += F("Disabled");
+  page += F(D_DISABLED);
 #endif // USE_DISCOVERY
   page += F("</td></tr>");
 
   page += F("<tr><td>&nbsp;</td></tr>");
-  page += F("<tr><th>ESP Chip id</th><td>"); page += String(ESP.getChipId()); page += F("</td></tr>");
-  page += F("<tr><th>Flash Chip id</th><td>"); page += String(ESP.getFlashChipId()); page += F("</td></tr>");
-  page += F("<tr><th>Flash size</th><td>"); page += String(ESP.getFlashChipRealSize() / 1024); page += F("kB</td></tr>");
-  page += F("<tr><th>Program flash size</th><td>"); page += String(ESP.getFlashChipSize() / 1024); page += F("kB</td></tr>");
-  page += F("<tr><th>Program size</th><td>"); page += String(ESP.getSketchSize() / 1024); page += F("kB</td></tr>");
-  page += F("<tr><th>Free program space</th><td>"); page += String(ESP.getFreeSketchSpace() / 1024); page += F("kB</td></tr>");
-  page += F("<tr><th>Free memory</th><td>"); page += String(freeMem / 1024); page += F("kB</td></tr>");
+  page += F("<tr><th>" D_ESP_CHIP_ID "</th><td>"); page += String(ESP.getChipId()); page += F("</td></tr>");
+  page += F("<tr><th>" D_FLASH_CHIP_ID "</th><td>"); page += String(ESP.getFlashChipId()); page += F("</td></tr>");
+  page += F("<tr><th>" D_FLASH_CHIP_SIZE "</th><td>"); page += String(ESP.getFlashChipRealSize() / 1024); page += F("kB</td></tr>");
+  page += F("<tr><th>" D_PROGRAM_FLASH_SIZE "</th><td>"); page += String(ESP.getFlashChipSize() / 1024); page += F("kB</td></tr>");
+  page += F("<tr><th>" D_PROGRAM_SIZE "</th><td>"); page += String(ESP.getSketchSize() / 1024); page += F("kB</td></tr>");
+  page += F("<tr><th>" D_FREE_PROGRAM_SPACE "</th><td>"); page += String(ESP.getFreeSketchSpace() / 1024); page += F("kB</td></tr>");
+  page += F("<tr><th>" D_FREE_MEMORY "</th><td>"); page += String(freeMem / 1024); page += F("kB</td></tr>");
   page += F("</table>");
 //  page += F("</fieldset>");
   page += FPSTR(HTTP_BTN_MAIN);
@@ -1571,10 +1575,10 @@ void handleRestart()
   if (httpUser()) {
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Restarting"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_RESTART);
 
   String page = FPSTR(HTTP_HEAD);
-  page.replace(F("{v}"), F("Info"));
+  page.replace(F("{v}"), S_RESTART);
   page += FPSTR(HTTP_MSG_RSTRT);
   if (HTTP_MANAGER == _httpflag) {
     _httpflag = HTTP_ADMIN;
@@ -1594,14 +1598,14 @@ void handleNotFound()
     return;
   }
 
-#ifdef USE_EMULATION  
+#ifdef USE_EMULATION
   String path = webServer->uri();
   if ((EMUL_HUE == sysCfg.flag.emulation) && (path.startsWith("/api"))) {
     handle_hue_api(&path);
   } else
 #endif // USE_EMULATION
   {
-    String message = F("File Not Found\n\nURI: ");
+    String message = F(D_FILE_NOT_FOUND "\n\nURI: ");
     message += webServer->uri();
     message += F("\nMethod: ");
     message += (webServer->method() == HTTP_GET) ? F("GET") : F("POST");
@@ -1620,7 +1624,7 @@ void handleNotFound()
 boolean captivePortal()
 {
   if ((HTTP_MANAGER == _httpflag) && !isIp(webServer->hostHeader())) {
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Request redirected to captive portal"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_HTTP D_REDIRECTED));
 
     webServer->sendHeader(F("Location"), String("http://") + webServer->client().localIP().toString(), true);
     webServer->send(302, FPSTR(HDR_CTYPE_PLAIN), ""); // Empty content inhibits Content-length header so we have to close the socket ourselves.
diff --git a/sonoff/xdrv_domoticz.ino b/sonoff/xdrv_domoticz.ino
index d496b2f92..6ea9e6a46 100644
--- a/sonoff/xdrv_domoticz.ino
+++ b/sonoff/xdrv_domoticz.ino
@@ -23,22 +23,22 @@
 
 #ifdef USE_WEBSERVER
 const char HTTP_FORM_DOMOTICZ[] PROGMEM =
-  "<fieldset><legend><b>&nbsp;Domoticz parameters&nbsp;</b></legend><form method='post' action='sv'>"
+  "<fieldset><legend><b>&nbsp;" D_DOMOTICZ_PARAMETERS "&nbsp;</b></legend><form method='post' action='sv'>"
   "<input id='w' name='w' value='4' hidden><input id='r' name='r' value='1' hidden>"
   "<br/><table style='width:97%'>";
 const char HTTP_FORM_DOMOTICZ_RELAY[] PROGMEM =
-  "<tr><td><b>Idx {1</b></td></td><td width='20%'><input id='r{1' name='r{1' length=8 placeholder='0' value='{2'></td></tr>"
-  "<tr><td><b>Key idx {1</b></td><td><input id='k{1' name='k{1' length=8 placeholder='0' value='{3'></td></tr>";
+  "<tr><td><b>" D_DOMOTICZ_IDX " {1</b></td></td><td width='20%'><input id='r{1' name='r{1' length=8 placeholder='0' value='{2'></td></tr>"
+  "<tr><td><b>" D_DOMOTICZ_KEY_IDX " {1</b></td><td><input id='k{1' name='k{1' length=8 placeholder='0' value='{3'></td></tr>";
 const char HTTP_FORM_DOMOTICZ_SWITCH[] PROGMEM =
-  "<tr><td><b>Switch idx {1</b></td><td width='20%'><input id='s{1' name='s{1' length=8 placeholder='0' value='{4'></td></tr>";
+  "<tr><td><b>" D_DOMOTICZ_SWITCH_IDX " {1</b></td><td width='20%'><input id='s{1' name='s{1' length=8 placeholder='0' value='{4'></td></tr>";
 const char HTTP_FORM_DOMOTICZ_SENSOR[] PROGMEM =
-  "<tr><td><b>Sensor idx {1</b> - {2</td><td width='20%'><input id='l{1' name='l{1' length=8 placeholder='0' value='{5'></td></tr>";
+  "<tr><td><b>" D_DOMOTICZ_SENSOR_IDX " {1</b> - {2</td><td width='20%'><input id='l{1' name='l{1' length=8 placeholder='0' value='{5'></td></tr>";
 const char HTTP_FORM_DOMOTICZ_TIMER[] PROGMEM =
-  "<tr><td><b>Update timer</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td><input id='ut' name='ut' length=32 placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
+  "<tr><td><b>" D_DOMOTICZ_UPDATE_TIMER "</b> (" STR(DOMOTICZ_UPDATE_TIMER) ")</td><td><input id='ut' name='ut' length=32 placeholder='" STR(DOMOTICZ_UPDATE_TIMER) "' value='{6'</td></tr>";
 #endif  // USE_WEBSERVER
 
-const char domoticz_sensors[DOMOTICZ_MAX_SENSORS][14] PROGMEM =
-  { "Temp", "Temp,Hum", "Temp,Hum,Baro", "Power,Energy", "Illuminance", "Count" };
+const char domoticz_sensors[DOMOTICZ_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 };
 
 char domoticz_in_topic[] = DOMOTICZ_IN_TOPIC;
 char domoticz_out_topic[] = DOMOTICZ_OUT_TOPIC;
@@ -142,7 +142,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
   unsigned long idx = 0;
   int16_t nvalue;
   int16_t found = 0;
-  
+
   domoticz_update_flag = 1;
   if (!strncmp(topicBuf, domoticz_out_topic, strlen(domoticz_out_topic)) != 0) {
     if (sdataBuf < 20) {
@@ -159,7 +159,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
     idx = domoticz["idx"];
     nvalue = domoticz["nvalue"];
 
-    snprintf_P(log, sizeof(log), PSTR("DMTZ: idx %d, nvalue %d"), idx, nvalue);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ "idx %d, nvalue %d"), idx, nvalue);
     addLog(LOG_LEVEL_DEBUG_MORE, log);
 
     if (nvalue >= 0 && nvalue <= 2) {
@@ -174,14 +174,14 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
             if (sfl_flg && (sysCfg.led_dimmer[i] == nvalue)) {
               return 1;
             }
-            snprintf_P(topicBuf, stopicBuf, PSTR("/DIMMER%s"), (Maxdevice > 1) ? stemp1 : "");
+            snprintf_P(topicBuf, stopicBuf, PSTR("/" D_CMND_DIMMER "%s"), (Maxdevice > 1) ? stemp1 : "");
             snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
             found = 1;
           } else {
             if (((power >> i) &1) == nvalue) {
               return 1;
             }
-            snprintf_P(topicBuf, stopicBuf, PSTR("/POWER%s"), (Maxdevice > 1) ? stemp1 : "");
+            snprintf_P(topicBuf, stopicBuf, PSTR("/" D_CMND_POWER "%s"), (Maxdevice > 1) ? stemp1 : "");
             snprintf_P(dataBuf, sdataBuf, PSTR("%d"), nvalue);
             found = 1;
           }
@@ -193,7 +193,7 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
       return 1;
     }
 
-    snprintf_P(log, sizeof(log), PSTR("DMTZ: Receive topic %s, data %s"), topicBuf, dataBuf);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ D_RECEIVED_TOPIC " %s, " D_DATA " %s"), topicBuf, dataBuf);
     addLog(LOG_LEVEL_DEBUG_MORE, log);
 
     domoticz_update_flag = 0;
@@ -208,38 +208,39 @@ boolean domoticz_mqttData(char *topicBuf, uint16_t stopicBuf, char *dataBuf, uin
 boolean domoticz_command(const char *type, uint16_t index, char *dataBuf, uint16_t data_len, int16_t payload, char *svalue, uint16_t ssvalue)
 {
   boolean serviced = true;
-  
-  if (!strncmp_P(type,PSTR("DOMOTICZ"),8)) {
-    if (!strcmp_P(type +8,PSTR("IDX")) && (index > 0) && (index <= Maxdevice)) {
+  uint8_t dmtcz_len = strlen(D_CMND_DOMOTICZ);  // Prep for string length change
+
+  if (!strncasecmp_P(type, PSTR(D_CMND_DOMOTICZ), dmtcz_len)) {  // Prefix
+    if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_IDX)) && (index > 0) && (index <= Maxdevice)) {
       if (payload >= 0) {
         sysCfg.domoticz_relay_idx[index -1] = payload;
         restartflag = 2;
       }
-      snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzIdx%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_IDX "%d\":%d}"), index, sysCfg.domoticz_relay_idx[index -1]);
     }
-    else if (!strcmp_P(type +8,PSTR("KEYIDX")) && (index > 0) && (index <= Maxdevice)) {
+    else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_KEYIDX)) && (index > 0) && (index <= Maxdevice)) {
       if (payload >= 0) {
         sysCfg.domoticz_key_idx[index -1] = payload;
       }
-      snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzKeyIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_KEYIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
     }
-    else if (!strcmp_P(type +8,PSTR("SWITCHIDX")) && (index > 0) && (index <= Maxdevice)) {
+    else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_SWITCHIDX)) && (index > 0) && (index <= Maxdevice)) {
       if (payload >= 0) {
         sysCfg.domoticz_switch_idx[index -1] = payload;
       }
-      snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSwitchIdx%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_SWITCHIDX "%d\":%d}"), index, sysCfg.domoticz_key_idx[index -1]);
     }
-    else if (!strcmp_P(type +8,PSTR("SENSORIDX")) && (index > 0) && (index <= DOMOTICZ_MAX_SENSORS)) {
+    else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_SENSORIDX)) && (index > 0) && (index <= DOMOTICZ_MAX_SENSORS)) {
       if (payload >= 0) {
         sysCfg.domoticz_sensor_idx[index -1] = payload;
       }
-      snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzSensorIdx%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_SENSORIDX "%d\":%d}"), index, sysCfg.domoticz_sensor_idx[index -1]);
     }
-    else if (!strcmp_P(type +8,PSTR("UPDATETIMER"))) {
+    else if (!strcasecmp_P(type +dmtcz_len, PSTR(D_CMND_UPDATETIMER))) {
       if ((payload >= 0) && (payload < 3601)) {
         sysCfg.domoticz_update_timer = payload;
       }
-      snprintf_P(svalue, ssvalue, PSTR("{\"DomoticzUpdateTimer\":%d}"), sysCfg.domoticz_update_timer);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DOMOTICZ D_CMND_UPDATETIMER "\":%d}"), sysCfg.domoticz_update_timer);
     }
     else serviced = false;
   }
@@ -327,18 +328,20 @@ void domoticz_sensor6(uint32_t count)
 \*********************************************************************************************/
 
 #ifdef USE_WEBSERVER
+const char S_CONFIGURE_DOMOTICZ[] PROGMEM = D_CONFIGURE_DOMOTICZ;
+
 void handleDomoticz()
 {
   if (HTTP_USER == _httpflag) {
     handleRoot();
     return;
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Handle Domoticz config"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, S_CONFIGURE_DOMOTICZ);
 
   char stemp[20];
-  
+
   String page = FPSTR(HTTP_HEAD);
-  page.replace("{v}", "Configure Domoticz");
+  page.replace("{v}", S_CONFIGURE_DOMOTICZ);
   page += FPSTR(HTTP_FORM_DOMOTICZ);
   for (int i = 0; i < 4; i++) {
     if (i < Maxdevice) {
@@ -384,11 +387,11 @@ void domoticz_saveSettings()
     sysCfg.domoticz_sensor_idx[i] = (!strlen(webServer->arg(stemp).c_str())) ? 0 : atoi(webServer->arg(stemp).c_str());
   }
   sysCfg.domoticz_update_timer = (!strlen(webServer->arg("ut").c_str())) ? DOMOTICZ_UPDATE_TIMER : atoi(webServer->arg("ut").c_str());
-  snprintf_P(log, sizeof(log), PSTR("HTTP: Domoticz idx %d, %d, %d, %d, update timer %d"),
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ D_CMND_IDX " %d, %d, %d, %d, " D_CMND_UPDATETIMER " %d"),
     sysCfg.domoticz_relay_idx[0], sysCfg.domoticz_relay_idx[1], sysCfg.domoticz_relay_idx[2], sysCfg.domoticz_relay_idx[3],
     sysCfg.domoticz_update_timer);
   addLog(LOG_LEVEL_INFO, log);
-  snprintf_P(log, sizeof(log), PSTR("HTTP: key %d, %d, %d, %d, switch %d, %d, %d, %d, sensor %d, %d, %d, %d, %d, %d"),
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_DOMOTICZ D_CMND_KEYIDX " %d, %d, %d, %d, " D_CMND_SWITCHIDX " %d, %d, %d, %d, " D_CMND_SENSORIDX " %d, %d, %d, %d, %d, %d"),
     sysCfg.domoticz_key_idx[0], sysCfg.domoticz_key_idx[1], sysCfg.domoticz_key_idx[2], sysCfg.domoticz_key_idx[3],
     sysCfg.domoticz_switch_idx[0], sysCfg.domoticz_switch_idx[1], sysCfg.domoticz_switch_idx[2], sysCfg.domoticz_switch_idx[3],
     sysCfg.domoticz_sensor_idx[0], sysCfg.domoticz_sensor_idx[1], sysCfg.domoticz_sensor_idx[2], sysCfg.domoticz_sensor_idx[3],
@@ -397,4 +400,3 @@ void domoticz_saveSettings()
 }
 #endif  // USE_WEBSERVER
 #endif  // USE_DOMOTICZ
-
diff --git a/sonoff/xdrv_ir_send.ino b/sonoff/xdrv_ir_send.ino
index e25b44176..0a4abade6 100644
--- a/sonoff/xdrv_ir_send.ino
+++ b/sonoff/xdrv_ir_send.ino
@@ -84,17 +84,17 @@ boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t da
 
 //  char log[LOGSZ];
 
-  if (!strcmp_P(type,PSTR("IRSEND"))) {
+  if (!strcasecmp_P(type, PSTR(D_CMND_IRSEND))) {
 	  if (data_len) {
       StaticJsonBuffer<128> jsonBuf;
       JsonObject &ir_json = jsonBuf.parseObject(dataBufUc);
       if (!ir_json.success()) {
-        snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Invalid JSON\"}"));  // JSON decode failed 
+        snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_INVALID_JSON "\"}"));  // JSON decode failed
       } else {
-        snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Done\"}"));
-        protocol = ir_json["PROTOCOL"];
-        bits = ir_json["BITS"];
-        data = ir_json["DATA"];
+        snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_DONE "\"}"));
+        protocol = ir_json[D_IRSEND_PROTOCOL];
+        bits = ir_json[D_IRSEND_BITS];
+        data = ir_json[D_IRSEND_DATA];
         if (protocol && bits && data) {
           if      (!strcmp_P(protocol,PSTR("NEC")))     irsend->sendNEC(data, bits);
           else if (!strcmp_P(protocol,PSTR("SONY")))    irsend->sendSony(data, bits);
@@ -104,34 +104,34 @@ boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t da
           else if (!strcmp_P(protocol,PSTR("JVC")))     irsend->sendJVC(data, bits, 1);
           else if (!strcmp_P(protocol,PSTR("SAMSUNG"))) irsend->sendSAMSUNG(data, bits);
           else {
-            snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"Protocol not supported\"}"));
+            snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_PROTOCOL_NOT_SUPPORTED "\"}"));
           }
         } else error = true;
       }
     } else error = true;
     if (error) {
-      snprintf_P(svalue, ssvalue, PSTR("{\"IRSend\":\"No protocol, bits or data\"}"));
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRSEND "\":\"" D_NO D_IRSEND_PROTOCOL ", " D_IRSEND_BITS " " D_OR " " D_IRSEND_DATA "\"}"));
     }
   }
 #ifdef USE_IR_HVAC
-  else if (!strcmp_P(type,PSTR("IRHVAC"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_IRHVAC))) {
     if (data_len) {
       StaticJsonBuffer<164> jsonBufer;
       JsonObject &root = jsonBufer.parseObject(dataBufUc);
       if (!root.success()) {
-        snprintf_P(svalue, ssvalue, PSTR("{\"IRHVAC\":\"Invalid JSON\"}"));  // JSON decode failed
+        snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRHVAC "\":\"" D_INVALID_JSON "\"}"));  // JSON decode failed
       } else {
-        snprintf_P(svalue, ssvalue, PSTR("{\"IRHVAC\":\"Done\"}"));
-        HVAC_Vendor = root["VENDOR"];
-        HVAC_Power = root["POWER"];
-        HVAC_Mode = root["MODE"];
-        HVAC_FanMode = root["FANSPEED"];
-        HVAC_Temp = root["TEMP"];
+        snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRHVAC "\":\"" D_DONE "\"}"));
+        HVAC_Vendor = root[D_IRHVAC_VENDOR];
+        HVAC_Power = root[D_IRHVAC_POWER];
+        HVAC_Mode = root[D_IRHVAC_MODE];
+        HVAC_FanMode = root[D_IRHVAC_FANSPEED];
+        HVAC_Temp = root[D_IRHVAC_TEMP];
 
 //        snprintf_P(log, sizeof(log), PSTR("IRHVAC: Received Vendor %s, Power %d, Mode %s, FanSpeed %s, Temp %d"),
 //          HVAC_Vendor, HVAC_Power, HVAC_Mode, HVAC_FanMode, HVAC_Temp);
 //        addLog(LOG_LEVEL_DEBUG, log);
-        
+
         if (HVAC_Vendor == NULL || !strcmp_P(HVAC_Vendor,PSTR("TOSHIBA"))) {
           error = ir_hvac_toshiba(HVAC_Mode, HVAC_FanMode, HVAC_Power, HVAC_Temp);
         }
@@ -142,7 +142,7 @@ boolean ir_send_command(char *type, uint16_t index, char *dataBufUc, uint16_t da
       }
     } else error = true;
     if (error) {
-      snprintf_P(svalue, ssvalue, PSTR("{\"IRHVAC\":\"Wrong Vendor, Mode and/or FanSpeed\"}"));
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_IRHVAC "\":\"" D_WRONG D_IRHVAC_VENDOR ", " D_IRHVAC_MODE " " D_OR " " D_IRHVAC_FANSPEED "\"}"));
     }
   }
 #endif  // USE_IR_HVAC
@@ -184,7 +184,7 @@ boolean ir_hvac_toshiba(const char *HVAC_Mode, const char *HVAC_FanMode, boolean
   if (!p) {
     return true;
   }
-  mode = p - FANSPEED +1;    
+  mode = p - FANSPEED +1;
   if ((1 == mode) || (7 == mode)) {
     mode = 0;
   }
@@ -247,7 +247,7 @@ boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boole
   char *token;
   uint8_t mode;
   char log[LOGSZ];
-    
+
   mitsubir->stateReset();
 
   if (HVAC_Mode == NULL) {
@@ -277,11 +277,11 @@ boolean ir_hvac_mitsubishi(const char *HVAC_Mode,const char *HVAC_FanMode, boole
   mitsubir->setTemp(HVAC_Temp);
   mitsubir->setVane(MITSUBISHI_AC_VANE_AUTO);
   mitsubir->send();
-  
+
 //  snprintf_P(log, sizeof(log), PSTR("IRHVAC: Mitsubishi Power %d, Mode %d, FanSpeed %d, Temp %d, VaneMode %d"),
 //    mitsubir->getPower(), mitsubir->getMode(), mitsubir->getFan(), mitsubir->getTemp(), mitsubir->getVane());
 //  addLog(LOG_LEVEL_DEBUG, log);
-  
+
   return false;
 }
 #endif  // USE_IR_HVAC
diff --git a/sonoff/xdrv_snfbridge.ino b/sonoff/xdrv_snfbridge.ino
index 3a60498b9..c69765423 100644
--- a/sonoff/xdrv_snfbridge.ino
+++ b/sonoff/xdrv_snfbridge.ino
@@ -45,13 +45,13 @@ void sb_received()
   for (i = 0; i < SerialInByteCounter; i++) {
     snprintf_P(svalue, sizeof(svalue), PSTR("%s%02X "), svalue, serialInBuf[i]);
   }
-  snprintf_P(log, sizeof(log), PSTR("BRDG: Received %s"), svalue);
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_BRIDGE D_RECEIVED " %s"), svalue);
   addLog(LOG_LEVEL_DEBUG, log);
 
   if (0xA2 == serialInBuf[0]) {       // Learn timeout
     sfb_learnFlg = 0;
-    snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfKey%d\":\"Learn failed\"}"), sfb_learnKey);
-    mqtt_publish_topic_P(5, PSTR("RFKEY"), svalue);
+    snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARN_FAILED "\"}"), sfb_learnKey);
+    mqtt_publish_topic_P(5, PSTR(D_CMND_RFKEY), svalue);
   }
   else if (0xA3 == serialInBuf[0]) {  // Learned A3 20 F8 01 18 03 3E 2E 1A 22 55
     sfb_learnFlg = 0;
@@ -61,11 +61,11 @@ void sb_received()
       for (i = 0; i < 9; i++) {
         sysCfg.sfb_code[sfb_learnKey][i] = serialInBuf[i +1];
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfKey%d\":\"Learned\"}"), sfb_learnKey);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNED "\"}"), sfb_learnKey);
     } else {
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfKey%d\":\"Learn failed\"}"), sfb_learnKey);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARN_FAILED "\"}"), sfb_learnKey);
     }
-    mqtt_publish_topic_P(5, PSTR("RFKEY"), svalue);
+    mqtt_publish_topic_P(5, PSTR(D_CMND_RFKEY), svalue);
   }
   else if (0xA4 == serialInBuf[0]) {  // Received RF data A4 20 EE 01 18 03 3E 2E 1A 22 55
     rsy = serialInBuf[1] << 8 | serialInBuf[2];  // Sync time in uSec
@@ -77,7 +77,7 @@ void sb_received()
     if (!((rid == sfb_lastrid) && (now - sfb_lasttime < SFB_TIME_AVOID_DUPLICATE))) {
       sfb_lastrid = rid;
       sfb_lasttime = now;
-      strcpy_P(rfkey, PSTR("\"None\""));
+      strcpy_P(rfkey, PSTR("\"" D_NONE "\""));
       for (i = 1; i <= 16; i++) {
         if (sysCfg.sfb_code[i][0]) {
           sid = sysCfg.sfb_code[i][6] << 16 | sysCfg.sfb_code[i][7] << 8 | sysCfg.sfb_code[i][8];
@@ -87,11 +87,11 @@ void sb_received()
           }
         }
       }
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"RfReceived\":{\"Sync\":%d, \"Low\":%d, \"High\":%d, \"Data\":\"%06X\", \"RfKey\":%s}}"),
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_RFRECEIVED "\":{\"" D_SYNC "\":%d, \"" D_LOW "\":%d, \"" D_HIGH "\":%d, \"" D_DATA "\":\"%06X\", \"" D_CMND_RFKEY "\":%s}}"),
         rsy, rlo, rhi, rid, rfkey);
-      mqtt_publish_topic_P(6, PSTR("RFRECEIVED"), svalue);
+      mqtt_publish_topic_P(6, PSTR(D_RFRECEIVED), svalue);
     }
-  }  
+  }
 }
 
 boolean sb_serial()
@@ -125,7 +125,7 @@ void sb_sendAck()
 void sb_send(uint8_t idx, uint8_t key)
 {
   uint8_t code;
-  
+
   key--;               // Support 1 to 16
   Serial.write(0xAA);  // Start of Text
   Serial.write(0xA5);  // Send following code
@@ -160,7 +160,7 @@ boolean sb_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len,
   boolean serviced = true;
   char *p;
 
-  if (!strcmp_P(type, PSTR("RFDEFAULT"))) {
+  if (!strcasecmp_P(type, PSTR(D_CMND_RFDEFAULT))) {
     if (4 == data_len) {
       uint16_t hexcode = strtol(dataBuf, &p, 16);
       uint8_t msb = hexcode >> 8;
@@ -170,28 +170,28 @@ boolean sb_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len,
         sysCfg.sfb_code[0][7] = lsb;
       }
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"RfDefault\":\"%0X%0X\"}"), sysCfg.sfb_code[0][6], sysCfg.sfb_code[0][7]);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFDEFAULT "\":\"%0X%0X\"}"), sysCfg.sfb_code[0][6], sysCfg.sfb_code[0][7]);
   }
-  else if (!strcmp_P(type, PSTR("RFKEY")) && (index > 0) && (index <= 16)) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_RFKEY)) && (index > 0) && (index <= 16)) {
     if (!sfb_learnFlg) {
       if (2 == payload) {
         sb_learn(index);
-        snprintf_P(svalue, ssvalue, PSTR("{\"RfKey%d\":\"Start learning\"}"), index);
+        snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_START_LEARNING "\"}"), index);
       }
       else if (3 == payload) {
         sysCfg.sfb_code[index][0] = 0;
-        snprintf_P(svalue, ssvalue, PSTR("{\"RfKey%d\":\"Set to default\"}"), index);
+        snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_SET_TO_DEFAULT "\"}"), index);
       } else {
         if ((1 == payload) || (0 == sysCfg.sfb_code[index][0])) {
           sb_send(0, index);
-          snprintf_P(svalue, ssvalue, PSTR("{\"RfKey%d\":\"Default sent\"}"), index);
+          snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_DEFAULT_SENT "\"}"), index);
         } else {
           sb_send(index, 0);
-          snprintf_P(svalue, ssvalue, PSTR("{\"RfKey%d\":\"Learned sent\"}"), index);
+          snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNED_SENT "\"}"), index);
         }
       }
     } else {
-      snprintf_P(svalue, ssvalue, PSTR("{\"RfKey%d\":\"Learning active\"}"), sfb_learnKey);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_RFKEY "%d\":\"" D_LEARNING_ACTIVE "\"}"), sfb_learnKey);
     }
   }
   else {
diff --git a/sonoff/xdrv_snfled.ino b/sonoff/xdrv_snfled.ino
index dba0e6167..0e80d18d9 100644
--- a/sonoff/xdrv_snfled.ino
+++ b/sonoff/xdrv_snfled.ino
@@ -19,7 +19,7 @@
 
 /*********************************************************************************************\
  * Sonoff B1, AiLight, Sonoff Led and BN-SZ01
- * 
+ *
  * sfl_flg  Module        Color  ColorTemp
  * 1        Sonoff BN-SZ  W      no
  * 2        Sonoff Led    CW     yes
@@ -101,7 +101,7 @@ void sl_my92x1_init()
 {
   uint8_t chips = sfl_flg -3;  // 1 (AiLight) or 2 (Sonoff B1)
 
-  sl_dcki_pulse(chips * 32);   // Clear all duty register 
+  sl_dcki_pulse(chips * 32);   // Clear all duty register
   os_delay_us(12);             // TStop > 12us.
   // Send 12 DI pulse, after 6 pulse's falling edge store duty data, and 12
   // pulse's rising edge convert to command mode.
@@ -160,7 +160,7 @@ void sl_init(void)
   } else {
     sl_pdi = pin[GPIO_DI];
     sl_pdcki = pin[GPIO_DCKI];
-    
+
     pinMode(sl_pdi, OUTPUT);
     pinMode(sl_pdcki, OUTPUT);
     digitalWrite(sl_pdi, LOW);
@@ -168,7 +168,7 @@ void sl_init(void)
 
     sl_my92x1_init();
   }
-  
+
   sl_power = 0;
   sl_any = 0;
   sl_wakeupActive = 0;
@@ -177,7 +177,7 @@ void sl_init(void)
 void sl_setColorTemp(uint16_t ct)
 {
 /* Color Temperature (https://developers.meethue.com/documentation/core-concepts)
- * 
+ *
  * ct = 153 = 2000K = Warm = CCWW = 00FF
  * ct = 500 = 6500K = Cold = CCWW = FF00
  */
@@ -260,7 +260,7 @@ char* sl_getColor(char* scolor)
 void sl_prepPower(char *svalue, uint16_t ssvalue)
 {
   char scolor[11];
-  
+
 //  do_cmnd_power(index, (sysCfg.led_dimmer[0]>0));
   if (sysCfg.led_dimmer[0] && !(power&1)) {
     do_cmnd_power(1, 7);  // No publishPowerState
@@ -272,10 +272,10 @@ void sl_prepPower(char *svalue, uint16_t ssvalue)
   mqtt_publishDomoticzPowerState(1);
 #endif  // USE_DOMOTICZ
   if (sfl_flg > 1) {
-    snprintf_P(svalue, ssvalue, PSTR("{\"POWER\":\"%s\", \"Dimmer\":%d, \"Color\":\"%s\"}"),
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_RSLT_POWER "\":\"%s\", \"" D_CMND_DIMMER "\":%d, \"" D_CMND_COLOR "\":\"%s\"}"),
       getStateText(power &1), sysCfg.led_dimmer[0], sl_getColor(scolor));
   } else {
-    snprintf_P(svalue, ssvalue, PSTR("{\"POWER\":\"%s\", \"Dimmer\":%d}"),
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_RSLT_POWER "\":\"%s\", \"" D_CMND_DIMMER "\":%d}"),
       getStateText(power &1), sysCfg.led_dimmer[0]);
   }
 }
@@ -295,7 +295,7 @@ void sl_animate()
   char svalue[32];  // was MESSZ
   uint8_t fadeValue;
   uint8_t cur_col[5];
-  
+
   if (0 == sl_power) {  // Power Off
     for (byte i = 0; i < sfl_flg; i++) {
       sl_tcolor[i] = 0;
@@ -339,8 +339,8 @@ void sl_animate()
             sl_tcolor[i] = sl_dcolor[i];
           }
         } else {
-          snprintf_P(svalue, sizeof(svalue), PSTR("{\"Wakeup\":\"Done\"}"));
-          mqtt_publish_topic_P(2, PSTR("WAKEUP"), svalue);
+          snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_CMND_WAKEUP "\":\"" D_DONE "\"}"));
+          mqtt_publish_topic_P(2, PSTR(D_CMND_WAKEUP), svalue);
           sl_wakeupActive = 0;
         }
       }
@@ -375,7 +375,7 @@ void sl_animate()
 void sl_rgb2hsb(float *hue, float *sat, float *bri)
 {
   RgbColor dcolor;
-  
+
   sl_setDim(sysCfg.led_dimmer[0]);
   dcolor.R = sl_dcolor[0];
   dcolor.G = sl_dcolor[1];
@@ -384,7 +384,7 @@ void sl_rgb2hsb(float *hue, float *sat, float *bri)
   *hue = hsb.H;
   *sat = hsb.S;
   *bri = hsb.B;
-}  
+}
 
 /********************************************************************************************/
 
@@ -393,7 +393,7 @@ void sl_replaceHSB(String *response)
   float hue;
   float sat;
   float bri;
-  
+
   if (sfl_flg > 2) {
     sl_rgb2hsb(&hue, &sat, &bri);
     response->replace("{h}", String((uint16_t)(65535.0f * hue)));
@@ -423,15 +423,15 @@ void sl_setHSB(float hue, float sat, float bri, uint16_t ct)
 {
   char svalue[MESSZ];
   HsbColor hsb;
-  
+
 /*
   char log[LOGSZ];
   char stemp1[10];
   char stemp2[10];
   char stemp3[10];
-  dtostrf(hue, 1, 3, stemp1);
-  dtostrf(sat, 1, 3, stemp2);
-  dtostrf(bri, 1, 3, stemp3);
+  dtostrfi(hue, 3, stemp1);
+  dtostrfi(sat, 3, stemp2);
+  dtostrfi(bri, 3, stemp3);
   snprintf_P(log, sizeof(log), PSTR("HUE: Set Hue %s, Sat %s, Bri %s, Ct %d"), stemp1, stemp2, stemp3, ct);
   addLog(LOG_LEVEL_DEBUG, log);
 */
@@ -450,7 +450,7 @@ void sl_setHSB(float hue, float sat, float bri, uint16_t ct)
       sl_setColor();
     }
     sl_prepPower(svalue, sizeof(svalue));
-    mqtt_publish_topic_P(5, "COLOR", svalue);
+    mqtt_publish_topic_P(5, PSTR(D_CMND_COLOR), svalue);
   } else {
     uint8_t tmp = (uint8_t)(bri * 100);
     sysCfg.led_dimmer[0] = tmp;
@@ -459,10 +459,10 @@ void sl_setHSB(float hue, float sat, float bri, uint16_t ct)
         sl_setColorTemp(ct);
       }
       sl_prepPower(svalue, sizeof(svalue));
-      mqtt_publish_topic_P(5, "COLOR", svalue);
+      mqtt_publish_topic_P(5, PSTR(D_CMND_COLOR), svalue);
     } else {
       sl_prepPower(svalue, sizeof(svalue));
-      mqtt_publish_topic_P(5, "DIMMER", svalue);
+      mqtt_publish_topic_P(5, PSTR(D_CMND_DIMMER), svalue);
     }
   }
 }
@@ -478,7 +478,7 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le
   char scolor[11];
   char *p;
 
-  if ((sfl_flg > 1) && !strcmp_P(type,PSTR("COLOR"))) {
+  if ((sfl_flg > 1) && !strcasecmp_P(type, PSTR(D_CMND_COLOR))) {
     if ((2 * sfl_flg) == data_len) {
       for (byte i = 0; i < sfl_flg; i++) {
         strlcpy(scolor, dataBufUc + (i *2), 3);
@@ -487,26 +487,26 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le
       sl_setColor();
       coldim = true;
     } else {
-      snprintf_P(svalue, ssvalue, PSTR("{\"Color\":\"%s\"}"), sl_getColor(scolor));
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_COLOR "\":\"%s\"}"), sl_getColor(scolor));
     }
   }
-  else if (!strcmp_P(type,PSTR("CT")) && ((2 == sfl_flg) || (5 == sfl_flg))) { // ColorTemp
+  else if (!strcasecmp_P(type, PSTR(D_CMND_COLORTEMPERATURE)) && ((2 == sfl_flg) || (5 == sfl_flg))) { // ColorTemp
     if ((payload >= 153) && (payload <= 500)) {  // https://developers.meethue.com/documentation/core-concepts
       sl_setColorTemp(payload);
       coldim = true;
     } else {
-      snprintf_P(svalue, ssvalue, PSTR("{\"CT\":%d}"), sl_getColorTemp());
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_COLORTEMPERATURE "\":%d}"), sl_getColorTemp());
     }
   }
-  else if (!strcmp_P(type,PSTR("DIMMER"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_DIMMER))) {
     if ((payload >= 0) && (payload <= 100)) {
       sysCfg.led_dimmer[0] = payload;
       coldim = true;
     } else {
-      snprintf_P(svalue, ssvalue, PSTR("{\"Dimmer\":%d}"), sysCfg.led_dimmer[0]);
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DIMMER "\":%d}"), sysCfg.led_dimmer[0]);
     }
   }
-  else if (!strcmp_P(type,PSTR("LEDTABLE"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_LEDTABLE))) {
     if ((payload >= 0) && (payload <= 2)) {
       switch (payload) {
       case 0: // Off
@@ -519,9 +519,9 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le
       }
       sl_any = 1;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"LedTable\":\"%s\"}"), getStateText(sysCfg.led_table));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_LEDTABLE "\":\"%s\"}"), getStateText(sysCfg.led_table));
   }
-  else if (!strcmp_P(type,PSTR("FADE"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_FADE))) {
     switch (payload) {
     case 0: // Off
     case 1: // On
@@ -531,25 +531,25 @@ boolean sl_command(char *type, uint16_t index, char *dataBufUc, uint16_t data_le
       sysCfg.led_fade ^= 1;
       break;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Fade\":\"%s\"}"), getStateText(sysCfg.led_fade));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_FADE "\":\"%s\"}"), getStateText(sysCfg.led_fade));
   }
-  else if (!strcmp_P(type,PSTR("SPEED"))) {  // 1 - fast, 8 - slow
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SPEED))) {  // 1 - fast, 8 - slow
     if ((payload > 0) && (payload <= 8)) {
       sysCfg.led_speed = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Speed\":%d}"), sysCfg.led_speed);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SPEED "\":%d}"), sysCfg.led_speed);
   }
-  else if (!strcmp_P(type,PSTR("WAKEUPDURATION"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUPDURATION))) {
     if ((payload > 0) && (payload < 3001)) {
       sysCfg.led_wakeup = payload;
       sl_wakeupActive = 0;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"WakeUpDuration\":%d}"), sysCfg.led_wakeup);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WAKEUPDURATION "\":%d}"), sysCfg.led_wakeup);
   }
-  else if (!strcmp_P(type,PSTR("WAKEUP"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUP))) {
     sl_wakeupActive = 3;
     do_cmnd_power(1, 1);
-    snprintf_P(svalue, ssvalue, PSTR("{\"Wakeup\":\"Started\"}"));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WAKEUP "\":\"" D_STARTED "\"}"));
   }
   else {
     serviced = false;  // Unknown command
diff --git a/sonoff/xdrv_snfsc.ino b/sonoff/xdrv_snfsc.ino
index 18c542d93..37d8fa9f5 100644
--- a/sonoff/xdrv_snfsc.ino
+++ b/sonoff/xdrv_snfsc.ino
@@ -106,11 +106,10 @@ void sc_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
     char stemp2[10];
 
     float t = convertTemp(sc_value[1]);
-    dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
+    dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1);
     float h = sc_value[0];
-    dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2);
-//    snprintf_P(svalue, ssvalue, PSTR("%s, \"SC\":{\"Temperature\":%s, \"Humidity\":%s, \"Light\":%d, \"Noise\":%d, \"AirQuality\":%d}"),
-    snprintf_P(svalue, ssvalue, PSTR("%s, \"Temperature\":%s, \"Humidity\":%s, \"Light\":%d, \"Noise\":%d, \"AirQuality\":%d"),
+    dtostrfd(h, sysCfg.flag.humidity_resolution, stemp2);
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_LIGHT "\":%d, \"" D_NOISE "\":%d, \"" D_AIRQUALITY "\":%d"),
       svalue, stemp1, stemp2, sc_value[2], sc_value[3], sc_value[4]);
     *djson = 1;
 #ifdef USE_DOMOTICZ
@@ -131,11 +130,11 @@ String sc_webPresent()
     char scstype[] = "";
 
     float t = convertTemp(sc_value[1]);
-    dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp);
+    dtostrfi(t, sysCfg.flag.temperature_resolution, stemp);
     snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, scstype, stemp, tempUnit());
     page += sensor;
     float h = sc_value[0];
-    dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp);
+    dtostrfi(h, sysCfg.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]);
diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino
index ac522167d..a331ed577 100644
--- a/sonoff/xdrv_wemohue.ino
+++ b/sonoff/xdrv_wemohue.ino
@@ -52,7 +52,7 @@ const char WEMO_MSEARCH[] PROGMEM =
 String wemo_serial()
 {
   char serial[16];
-  
+
   snprintf_P(serial, sizeof(serial), PSTR("201612K%08X"), ESP.getChipId());
   return String(serial);
 }
@@ -60,7 +60,7 @@ String wemo_serial()
 String wemo_UUID()
 {
   char uuid[27];
-  
+
   snprintf_P(uuid, sizeof(uuid), PSTR("Socket-1_0-%s"), wemo_serial().c_str());
   return String(uuid);
 }
@@ -76,11 +76,11 @@ void wemo_respondToMSearch()
     response.replace("{r2}", wemo_UUID());
     portUDP.write(response.c_str());
     portUDP.endPacket();
-    snprintf_P(message, sizeof(message), PSTR("Response sent"));
+    snprintf_P(message, sizeof(message), PSTR(D_RESPONSE_SENT));
   } else {
-    snprintf_P(message, sizeof(message), PSTR("Failed to send response"));
+    snprintf_P(message, sizeof(message), PSTR(D_FAILED_TO_SEND_RESPONSE));
   }
-  snprintf_P(log, sizeof(log), PSTR("UPnP: Wemo %s to %s:%d"),
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_UPNP D_WEMO " %s " D_TO " %s:%d"),
     message, portUDP.remoteIP().toString().c_str(), portUDP.remotePort());
   addLog(LOG_LEVEL_DEBUG, log);
 }
@@ -88,7 +88,7 @@ void wemo_respondToMSearch()
 /*********************************************************************************************\
  * Hue Bridge UPNP support routines
  * Need to send 3 response packets with varying ST and USN
- * 
+ *
  * Using Espressif Inc Mac Address of 5C:CF:7F:00:00:00
  * Philips Lighting is 00:17:88:00:00:00
 \*********************************************************************************************/
@@ -101,7 +101,7 @@ const char HUE_RESPONSE[] PROGMEM =
   "LOCATION: http://{r1}:80/description.xml\r\n"
   "SERVER: FreeRTOS/7.4.2 UPnP/1.0 IpBridge/1.16.0\r\n"
   "hue-bridgeid: {r2}\r\n";
-const char HUE_ST1[] PROGMEM = 
+const char HUE_ST1[] PROGMEM =
   "ST: upnp:rootdevice\r\n"
   "USN: uuid:{r3}::upnp:rootdevice\r\n"
   "\r\n";
@@ -113,7 +113,7 @@ const char HUE_ST3[] PROGMEM =
   "ST: urn:schemas-upnp-org:device:Basic:1\r\n"
   "USN: uuid:{r3}\r\n"
   "\r\n";
-  
+
 String hue_bridgeid()
 {
   String temp = WiFi.macAddress();
@@ -154,7 +154,7 @@ void hue_respondToMSearch()
     portUDP.endPacket();
 
 //addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
-    
+
     response = response1;
     response += FPSTR(HUE_ST2);
     response.replace("{r3}", hue_UUID());
@@ -162,7 +162,7 @@ void hue_respondToMSearch()
     portUDP.endPacket();
 
 //addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
-    
+
     response = response1;
     response += FPSTR(HUE_ST3);
     response.replace("{r3}", hue_UUID());
@@ -171,11 +171,11 @@ void hue_respondToMSearch()
 
 //addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
 
-    snprintf_P(message, sizeof(message), PSTR("3 response packets sent"));
+    snprintf_P(message, sizeof(message), PSTR(D_3_RESPONSE_PACKETS_SENT));
   } else {
-    snprintf_P(message, sizeof(message), PSTR("Failed to send response"));
+    snprintf_P(message, sizeof(message), PSTR(D_FAILED_TO_SEND_RESPONSE));
   }
-  snprintf_P(log, sizeof(log), PSTR("UPnP: HUE %s to %s:%d"),
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_UPNP D_HUE " %s " D_TO " %s:%d"),
     message, portUDP.remoteIP().toString().c_str(), portUDP.remotePort());
   addLog(LOG_LEVEL_DEBUG, log);
 }
@@ -188,7 +188,7 @@ boolean UDP_Disconnect()
 {
   if (udpConnected) {
     WiFiUDP::stopAll();
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("UPnP: Multicast disabled"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_UPNP D_MULTICAST_DISABLED));
     udpConnected = false;
   }
   return udpConnected;
@@ -198,10 +198,10 @@ boolean UDP_Connect()
 {
   if (!udpConnected) {
     if (portUDP.beginMulticast(WiFi.localIP(), ipMulticast, portMulticast)) {
-      addLog_P(LOG_LEVEL_INFO, PSTR("UPnP: Multicast (re)joined"));
+      addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_REJOINED));
       udpConnected = true;
     } else {
-      addLog_P(LOG_LEVEL_INFO, PSTR("UPnP: Multicast join failed"));
+      addLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_UPNP D_MULTICAST_JOIN_FAILED));
       udpConnected = false;
     }
   }
@@ -300,13 +300,12 @@ const char WEMO_SETUP_XML[] PROGMEM =
     "</device>"
   "</root>\r\n"
   "\r\n";
-  
+
 /********************************************************************************************/
 
 void handleUPnPevent()
 {
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: WeMo basic event"));
-
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT));
   String request = webServer->arg(0);
   if (request.indexOf(F("State>1</Binary")) > 0) {
 //    do_cmnd_power(1, 1);
@@ -321,14 +320,13 @@ void handleUPnPevent()
 
 void handleUPnPservice()
 {
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: WeMo event service"));
-  
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_EVENT_SERVICE));
   webServer->send(200, FPSTR(HDR_CTYPE_PLAIN), FPSTR(WEMO_EVENTSERVICE_XML));
 }
 
 void handleUPnPsetupWemo()
 {
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: WeMo setup"));
+  addLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_SETUP));
 
   String setup_xml = FPSTR(WEMO_SETUP_XML);
   setup_xml.replace("{x1}", sysCfg.friendlyname[0]);
@@ -432,8 +430,7 @@ String hue_userId()
 
 void handleUPnPsetupHue()
 {
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("HTTP: Hue Bridge setup"));
-
+  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}", hue_UUID());
@@ -444,8 +441,8 @@ void handleUPnPsetupHue()
 void hue_todo(String *path)
 {
   char log[LOGSZ];
-  
-  snprintf_P(log, sizeof(log), PSTR("HTTP: HUE API not implemented (%s)"),path->c_str());
+
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_HUE_API_NOT_IMPLEMENTED " (%s)"), path->c_str());
   addLog(LOG_LEVEL_DEBUG_MORE, log);
 
   webServer->send(200, FPSTR(HDR_CTYPE_JSON), "{}");
@@ -474,7 +471,7 @@ void hue_light_status(byte device, String *response)
 {
   *response += FPSTR(HUE_LIGHT_STATUS_JSON);
   response->replace("{state}", (power & (0x01 << (device-1))) ? "true" : "false");
-  
+
   if (sfl_flg) {
     sl_replaceHSB(response);
 #ifdef USE_WS2812
@@ -500,9 +497,9 @@ void hue_global_cfg(String *path)
     response += F("\":{\"state\":{");
     hue_light_status(i, &response);
     response += "},";
-    response += FPSTR(HUE_LIGHTS_STATUS_JSON);    
+    response += FPSTR(HUE_LIGHTS_STATUS_JSON);
     response.replace("{j1}", sysCfg.friendlyname[i-1]);
-    response.replace("{j2}", hue_deviceId(i));  
+    response.replace("{j2}", hue_deviceId(i));
     if (i < Maxdevice) {
       response += ",\"";
     }
@@ -516,7 +513,7 @@ void hue_global_cfg(String *path)
 void hue_auth(String *path)
 {
   char response[38];
-  
+
   snprintf_P(response, sizeof(response), PSTR("[{\"success\":{\"username\":\"%s\"}}]"), hue_userId().c_str());
   webServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
 }
@@ -547,9 +544,9 @@ void hue_lights(String *path)
       response += F("\":{\"state\":{");
       hue_light_status(i, &response);
       response += "},";
-      response += FPSTR(HUE_LIGHTS_STATUS_JSON);    
+      response += FPSTR(HUE_LIGHTS_STATUS_JSON);
       response.replace("{j1}", sysCfg.friendlyname[i-1]);
-      response.replace("{j2}", hue_deviceId(i));  
+      response.replace("{j2}", hue_deviceId(i));
       if (i < Maxdevice) {
         response += ",\"";
       }
@@ -570,11 +567,11 @@ void hue_lights(String *path)
       StaticJsonBuffer<400> jsonBuffer;
       JsonObject &hue_json = jsonBuffer.parseObject(webServer->arg(0));
       if (hue_json.containsKey("on")) {
-      
+
         response += FPSTR(HUE_LIGHT_RESPONSE_JSON);
         response.replace("{id}", String(device));
         response.replace("{cmd}", "on");
-      
+
         on = hue_json["on"];
         switch(on)
         {
@@ -589,7 +586,7 @@ void hue_lights(String *path)
         }
         resp = true;
       }
-      
+
       if (sfl_flg) {
         sl_getHSB(&hue,&sat,&bri);
 #ifdef USE_WS2812
@@ -663,13 +660,13 @@ void hue_lights(String *path)
       if (2 == response.length()) {
         response = FPSTR(HUE_ERROR_JSON);
       }
-    }   
+    }
     else {
       response = FPSTR(HUE_ERROR_JSON);
     }
 
 //addLog(LOG_LEVEL_DEBUG_MORE, response.c_str());
-    
+
     webServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
   }
   else if(path->indexOf("/lights/") >= 0) {            // Got /lights/ID
@@ -681,7 +678,7 @@ void hue_lights(String *path)
     response += F("{\"state\":{");
     hue_light_status(device, &response);
     response += "},";
-    response += FPSTR(HUE_LIGHTS_STATUS_JSON);    
+    response += FPSTR(HUE_LIGHTS_STATUS_JSON);
     response.replace("{j1}", sysCfg.friendlyname[device-1]);
     response.replace("{j2}", hue_deviceId(device));
     webServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
@@ -693,11 +690,11 @@ void hue_lights(String *path)
 
 void hue_groups(String *path)
 {
-/*  
+/*
  * http://sonoff/api/username/groups?1={"name":"Woonkamer","lights":[],"type":"Room","class":"Living room"})
  */
   String response = "{}";
-  
+
   if (path->endsWith("/0")) {
     response = FPSTR(HUE_GROUP0_STATUS_JSON);
     String lights = F("\"1\"");
@@ -708,7 +705,7 @@ void hue_groups(String *path)
     hue_light_status(1, &response);
     response += F("}}");
   }
- 
+
   webServer->send(200, FPSTR(HDR_CTYPE_JSON), response);
 }
 
@@ -716,31 +713,31 @@ void handle_hue_api(String *path)
 {
   /* HUE API uses /api/<userid>/<command> syntax. The userid is created by the echo device and
    * on original HUE the pressed button allows for creation of this user. We simply ignore the
-   * user part and allow every caller as with Web or WeMo. 
+   * user part and allow every caller as with Web or WeMo.
    *
    * (c) Heiko Krupp, 2017
    */
-   
+
   char log[LOGSZ];
   uint8_t args = 0;
 
   path->remove(0, 4);                                // remove /api
   uint16_t apilen = path->length();
-  snprintf_P(log, sizeof(log), PSTR("HTTP: Hue API (%s)"), path->c_str());
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_HUE_API " (%s)"), path->c_str());
   addLog(LOG_LEVEL_DEBUG_MORE, log);
   for (args = 0; args < webServer->args(); args++) {
     String json = webServer->arg(args);
-    snprintf_P(log, sizeof(log), PSTR("HTTP: Hue POST args (%s)"), json.c_str());
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_HTTP D_HUE_POST_ARGS " (%s)"), json.c_str());
     addLog(LOG_LEVEL_DEBUG_MORE, log);
   }
-  
+
   if (path->endsWith("/invalid/")) {}                 // Just ignore
   else if (!apilen) hue_auth(path);                   // New HUE App setup
   else if (path->endsWith("/")) hue_auth(path);       // New HUE App setup
   else if (path->endsWith("/config")) hue_config(path);
   else if (path->indexOf("/lights") >= 0) hue_lights(path);
-  else if (path->indexOf("/groups") >= 0) hue_groups(path); 
-  else if (path->endsWith("/schedules")) hue_todo(path); 
+  else if (path->indexOf("/groups") >= 0) hue_groups(path);
+  else if (path->endsWith("/schedules")) hue_todo(path);
   else if (path->endsWith("/sensors")) hue_todo(path);
   else if (path->endsWith("/scenes")) hue_todo(path);
   else if (path->endsWith("/rules")) hue_todo(path);
diff --git a/sonoff/xdrv_ws2812.ino b/sonoff/xdrv_ws2812.ino
index 92fe3e349..83ad693ec 100644
--- a/sonoff/xdrv_ws2812.ino
+++ b/sonoff/xdrv_ws2812.ino
@@ -63,19 +63,19 @@ ColorScheme schemes[7] = {
   rainbow, 7,
   fire, 3 };
 
-uint8_t widthValues[5] = { 
+uint8_t widthValues[5] = {
     1,     // Small
     2,     // Medium
     4,     // Large
     8,     // Largest
   255 };   // All
-uint8_t repeatValues[5] = { 
+uint8_t repeatValues[5] = {
     8,     // Small
     6,     // Medium
     4,     // Large
     2,     // Largest
     1 };   // All
-uint8_t speedValues[6] = { 
+uint8_t speedValues[6] = {
     0,                     // None
     9 * (STATES / 10),     // Slowest
     7 * (STATES / 10),     // Slower
@@ -108,8 +108,8 @@ void ws2812_setColor(uint16_t led, char* colstr)
 {
   HtmlColor hcolor;
   char log[LOGSZ];
-  char lcolstr[8]; 
-  
+  char lcolstr[8];
+
   snprintf_P(lcolstr, sizeof(lcolstr), PSTR("#%s"), colstr);
   uint8_t result = hcolor.Parse<HtmlColorNames>((char *)lcolstr, 7);
   if (result) {
@@ -121,7 +121,7 @@ void ws2812_setColor(uint16_t led, char* colstr)
 
 //      snprintf_P(log, sizeof(log), PSTR("DBG: Red %02X, Green %02X, Blue %02X"), dcolor.R, dcolor.G, dcolor.B);
 //      addLog(LOG_LEVEL_DEBUG, log);
-  
+
       uint16_t temp = dcolor.R;
       if (temp < dcolor.G) {
         temp = dcolor.G;
@@ -131,7 +131,7 @@ void ws2812_setColor(uint16_t led, char* colstr)
       }
       float mDim = (float)temp / 2.55;
       sysCfg.ws_dimmer = (uint8_t)mDim;
-  
+
       float newDim = 100 / mDim;
       float fmyRed = (float)dcolor.R * newDim;
       float fmyGrn = (float)dcolor.G * newDim;
@@ -149,14 +149,14 @@ void ws2812_getColor(uint16_t led, char* svalue, uint16_t ssvalue)
 {
   RgbColor mcolor;
   char stemp[20];
-  
+
   if (led) {
     mcolor = strip->GetPixelColor(led -1);
-    snprintf_P(stemp, sizeof(stemp), PSTR("Led%d"), led);
+    snprintf_P(stemp, sizeof(stemp), PSTR(D_CMND_LED "%d"), led);
   } else {
     ws2812_setDim(sysCfg.ws_dimmer);
     mcolor = dcolor;
-    snprintf_P(stemp, sizeof(stemp), PSTR("Color"));
+    snprintf_P(stemp, sizeof(stemp), PSTR(D_CMND_COLOR));
   }
   uint32_t color = (uint32_t)mcolor.R << 16;
   color += (uint32_t)mcolor.G << 8;
@@ -166,7 +166,7 @@ void ws2812_getColor(uint16_t led, char* svalue, uint16_t ssvalue)
 
 void ws2812_stripShow()
 {
-  RgbColor c;  
+  RgbColor c;
 
   if (sysCfg.ws_ledtable) {
     for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) {
@@ -200,7 +200,7 @@ int mod(int a, int b)
 void ws2812_clock()
 {
   RgbColor c;
-  
+
   strip->ClearTo(0);   // Reset strip
   float newDim = 100 / (float)sysCfg.ws_dimmer;
   float f1 = 255 / newDim;
@@ -255,7 +255,7 @@ void ws2812_gradientColor(struct wsColor* mColor, uint16_t range, uint16_t gradR
 
 void ws2812_gradient()
 {
-/* 
+/*
  * This routine courtesy Tony DiCola (Adafruit)
  * Display a gradient of colors for the current color scheme.
  *  Repeat is the number of repetitions of the gradient (pick a multiple of 2 for smooth looping of the gradient).
@@ -299,7 +299,7 @@ void ws2812_gradient()
 
 void ws2812_bars()
 {
-/* 
+/*
  * This routine courtesy Tony DiCola (Adafruit)
  * Display solid bars of color for the current color scheme.
  * Width is the width of each bar in pixels/lights.
@@ -344,7 +344,7 @@ void ws2812_animate()
 {
   char log[LOGSZ];
   uint8_t fadeValue;
-  
+
   stripTimerCntr++;
   if (0 == bitRead(power, ws_bit)) {  // Power Off
     sleep = sysCfg.sleep;
@@ -428,7 +428,7 @@ void ws2812_animate()
 
       if (sysCfg.ws_ledtable) {
         for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) {
-          strip->SetPixelColor(i, RgbColor(ledTable[lcolor.R],ledTable[lcolor.G],ledTable[lcolor.B]));      
+          strip->SetPixelColor(i, RgbColor(ledTable[lcolor.R],ledTable[lcolor.G],ledTable[lcolor.B]));
         }
       } else {
         for (uint16_t i = 0; i < sysCfg.ws_pixels; i++) {
@@ -498,7 +498,7 @@ void ws2812_getHSB(float *hue, float *sat, float *bri)
 void ws2812_setHSB(float hue, float sat, float bri)
 {
   char rgb[7];
-  
+
   HsbColor hsb;
   hsb.H = hue;
   hsb.S = sat;
@@ -516,27 +516,27 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_
 {
   boolean serviced = true;
 
-  if (!strcmp_P(type,PSTR("PIXELS"))) {
+  if (!strcasecmp_P(type, PSTR(D_CMND_PIXELS))) {
     if ((payload > 0) && (payload <= WS2812_MAX_LEDS)) {
       sysCfg.ws_pixels = payload;
       ws2812_pixels();
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Pixels\":%d}"), sysCfg.ws_pixels);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_PIXELS "\":%d}"), sysCfg.ws_pixels);
   }
-  else if (!strcmp_P(type,PSTR("LED")) && (index > 0) && (index <= sysCfg.ws_pixels)) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_LED)) && (index > 0) && (index <= sysCfg.ws_pixels)) {
     if (6 == data_len) {
       ws2812_setColor(index, dataBuf);
     }
     ws2812_getColor(index, svalue, ssvalue);
   }
-  else if (!strcmp_P(type,PSTR("COLOR"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_COLOR))) {
     if (6 == data_len) {
       ws2812_setColor(0, dataBuf);
       bitSet(power, ws_bit);
     }
     ws2812_getColor(0, svalue, ssvalue);
   }
-  else if (!strcmp_P(type,PSTR("DIMMER"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_DIMMER))) {
     if ((payload >= 0) && (payload <= 100)) {
       sysCfg.ws_dimmer = payload;
       bitSet(power, ws_bit);
@@ -545,9 +545,9 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_
       mqtt_publishDomoticzPowerState(ws_bit +1);
 #endif  // USE_DOMOTICZ
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Dimmer\":%d}"), sysCfg.ws_dimmer);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_DIMMER "\":%d}"), sysCfg.ws_dimmer);
   }
-  else if (!strcmp_P(type,PSTR("LEDTABLE"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_LEDTABLE))) {
     if ((payload >= 0) && (payload <= 2)) {
       switch (payload) {
       case 0: // Off
@@ -560,9 +560,9 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_
       }
       ws2812_update();
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"LedTable\":\"%s\"}"), getStateText(sysCfg.ws_ledtable));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_LEDTABLE "\":\"%s\"}"), getStateText(sysCfg.ws_ledtable));
   }
-  else if (!strcmp_P(type,PSTR("FADE"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_FADE))) {
     switch (payload) {
     case 0: // Off
     case 1: // On
@@ -572,30 +572,30 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_
       sysCfg.ws_fade ^= 1;
       break;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Fade\":\"%s\"}"), getStateText(sysCfg.ws_fade));
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_FADE "\":\"%s\"}"), getStateText(sysCfg.ws_fade));
   }
-  else if (!strcmp_P(type,PSTR("SPEED"))) {  // 1 - fast, 5 - slow
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SPEED))) {  // 1 - fast, 5 - slow
     if ((payload > 0) && (payload <= 5)) {
       sysCfg.ws_speed = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Speed\":%d}"), sysCfg.ws_speed);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SPEED "\":%d}"), sysCfg.ws_speed);
   }
-  else if (!strcmp_P(type,PSTR("WIDTH"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_WIDTH))) {
     if ((payload >= 0) && (payload <= 4)) {
       sysCfg.ws_width = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Width\":%d}"), sysCfg.ws_width);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WIDTH "\":%d}"), sysCfg.ws_width);
   }
-  else if (!strcmp_P(type,PSTR("WAKEUP"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_WAKEUP))) {
     if ((payload > 0) && (payload < 3001)) {
       sysCfg.ws_wakeup = payload;
       if (1 == sysCfg.ws_scheme) {
         sysCfg.ws_scheme = 0;
       }
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"WakeUp\":%d}"), sysCfg.ws_wakeup);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_WAKEUP "\":%d}"), sysCfg.ws_wakeup);
   }
-  else if (!strcmp_P(type,PSTR("SCHEME"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SCHEME))) {
     if ((payload >= 0) && (payload <= 9)) {
       sysCfg.ws_scheme = payload;
       if (1 == sysCfg.ws_scheme) {
@@ -604,7 +604,7 @@ boolean ws2812_command(char *type, uint16_t index, char *dataBuf, uint16_t data_
       bitSet(power, ws_bit);
       ws2812_resetStripTimer();
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"Scheme\":%d}"), sysCfg.ws_scheme);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SCHEME "\":%d}"), sysCfg.ws_scheme);
   }
   else if (!strcmp_P(type,PSTR("UNDOCA"))) {  // Theos WS2812 legacy status
     RgbColor mcolor;
diff --git a/sonoff/xsns_bh1750.ino b/sonoff/xsns_bh1750.ino
index b263fbaf4..cfce0fc3f 100644
--- a/sonoff/xsns_bh1750.ino
+++ b/sonoff/xsns_bh1750.ino
@@ -67,7 +67,7 @@ boolean bh1750_detect()
     strcpy(bh1750stype, "BH1750");
   }
   if (success) {
-    snprintf_P(log, sizeof(log), PSTR("I2C: %s found at address 0x%x"), bh1750stype, bh1750addr);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bh1750stype, bh1750addr);
     addLog(LOG_LEVEL_DEBUG, log);
   } else {
     bh1750type = 0;
@@ -86,7 +86,7 @@ void bh1750_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   }
 
   uint16_t l = bh1750_readLux();
-  snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Illuminance\":%d}"), svalue, bh1750stype, l);
+  snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"" D_ILLUMINANCE "\":%d}"), svalue, bh1750stype, l);
   *djson = 1;
 #ifdef USE_DOMOTICZ
   domoticz_sensor5(l);
@@ -95,7 +95,7 @@ void bh1750_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
 
 #ifdef USE_WEBSERVER
 const char HTTP_SNS_ILLUMINANCE[] PROGMEM =
-  "<tr><th>BH1750 Illuminance</th><td>%d lx</td></tr>";
+  "<tr><th>BH1750 " D_ILLUMINANCE "</th><td>%d lx</td></tr>";
 
 String bh1750_webPresent()
 {
diff --git a/sonoff/xsns_bmp.ino b/sonoff/xsns_bmp.ino
index fdf472705..34ebd6e71 100644
--- a/sonoff/xsns_bmp.ino
+++ b/sonoff/xsns_bmp.ino
@@ -348,7 +348,7 @@ double bme280_readHumidity(void)
 double bmp_readTemperature(void)
 {
   double t = NAN;
-  
+
   switch (bmptype) {
   case BMP180_CHIPID:
     t = bmp180_readTemperature();
@@ -418,7 +418,7 @@ boolean bmp_detect()
     strcpy_P(bmpstype, PSTR("BME280"));
   }
   if (success) {
-    snprintf_P(log, sizeof(log), PSTR("I2C: %s found at address 0x%x"), bmpstype, bmpaddr);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), bmpstype, bmpaddr);
     addLog(LOG_LEVEL_DEBUG, log);
   } else {
     bmptype = 0;
@@ -443,19 +443,19 @@ void bmp_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   double t = bmp_readTemperature();
   double p = bmp_readPressure();
   double h = bmp_readHumidity();
-  dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
-  dtostrf(p, 1, sysCfg.flag.pressure_resolution, stemp2);
-  dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp3);
+  dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1);
+  dtostrfd(p, sysCfg.flag.pressure_resolution, stemp2);
+  dtostrfd(h, sysCfg.flag.humidity_resolution, stemp3);
   if (!strcmp(bmpstype,"BME280")) {
-    snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s, \"Pressure\":%s}"),
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_HUMIDITY "\":%s, \"" D_PRESSURE "\":%s}"),
       svalue, bmpstype, stemp1, stemp3, stemp2);
   } else {
-    snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Pressure\":%s}"),
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"" D_TEMPERATURE "\":%s, \"" D_PRESSURE "\":%s}"),
       svalue, bmpstype, stemp1, stemp2);
   }
   *djson = 1;
 #ifdef USE_DOMOTICZ
-  domoticz_sensor3(stemp1, stemp3, stemp2); 
+  domoticz_sensor3(stemp1, stemp3, stemp2);
 #endif  // USE_DOMOTICZ
 }
 
@@ -470,15 +470,15 @@ String bmp_webPresent()
     double t_bmp = bmp_readTemperature();
     double p_bmp = bmp_readPressure();
     double h_bmp = bmp_readHumidity();
-    dtostrf(t_bmp, 1, sysCfg.flag.temperature_resolution, stemp);
+    dtostrfi(t_bmp, sysCfg.flag.temperature_resolution, stemp);
     snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, bmpstype, stemp, tempUnit());
     page += sensor;
     if (!strcmp(bmpstype,"BME280")) {
-      dtostrf(h_bmp, 1, sysCfg.flag.humidity_resolution, stemp);
+      dtostrfi(h_bmp, sysCfg.flag.humidity_resolution, stemp);
       snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, bmpstype, stemp);
       page += sensor;
     }
-    dtostrf(p_bmp, 1, sysCfg.flag.pressure_resolution, stemp);
+    dtostrfi(p_bmp, sysCfg.flag.pressure_resolution, stemp);
     snprintf_P(sensor, sizeof(sensor), HTTP_SNS_PRESSURE, bmpstype, stemp);
     page += sensor;
   }
diff --git a/sonoff/xsns_counter.ino b/sonoff/xsns_counter.ino
index f940887c9..b9377a31a 100644
--- a/sonoff/xsns_counter.ino
+++ b/sonoff/xsns_counter.ino
@@ -1,5 +1,5 @@
 /*
-  xsns_counter.ino - Counter sensors (water meters, electricity meters etc.) sensor support for Sonoff-Tasmota 
+  xsns_counter.ino - Counter sensors (water meters, electricity meters etc.) sensor support for Sonoff-Tasmota
 
   Copyright (C) 2017  Maarten Damen and Theo Arends
 
@@ -74,7 +74,7 @@ void counter_init()
 {
   typedef void (*function) () ;
   function counter_callbacks[] = { counter_update1, counter_update2, counter_update3, counter_update4 };
-  
+
   for (byte i = 0; i < MAX_COUNTERS; i++) {
     if (pin[GPIO_CNTR1 +i] < 99) {
       pinMode(pin[GPIO_CNTR1 +i], INPUT_PULLUP);
@@ -95,12 +95,12 @@ void counter_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   for (byte i = 0; i < MAX_COUNTERS; i++) {
     if (pin[GPIO_CNTR1 +i] < 99) {
       if (bitRead(sysCfg.pCounterType, i)) {
-        dtostrf((double)rtcMem.pCounter[i] / 1000, 1, 3, stemp);
+        dtostrfd((double)rtcMem.pCounter[i] / 1000, 3, stemp);
       } else {
         dsxflg++;
-        dtostrf(rtcMem.pCounter[i], 1, 0, stemp);
+        dtostrfd(rtcMem.pCounter[i], 0, stemp);
       }
-      snprintf_P(svalue, ssvalue, PSTR("%s, \"Counter%d\":%s"), svalue, i +1, stemp);
+      snprintf_P(svalue, ssvalue, PSTR("%s, \"" D_COUNTER "%d\":%s"), svalue, i +1, stemp);
       *djson = 1;
 #ifdef USE_DOMOTICZ
       if (1 == dsxflg) {
@@ -114,7 +114,7 @@ void counter_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
 
 #ifdef USE_WEBSERVER
 const char HTTP_SNS_COUNTER[] PROGMEM =
-  "<tr><th>Counter%d</th><td>%s%s</td></tr>";  
+  "<tr><th>" D_COUNTER "%d</th><td>%s%s</td></tr>";
 
 String counter_webPresent()
 {
@@ -125,11 +125,11 @@ String counter_webPresent()
   for (byte i = 0; i < MAX_COUNTERS; i++) {
     if (pin[GPIO_CNTR1 +i] < 99) {
       if (bitRead(sysCfg.pCounterType, i)) {
-        dtostrf((double)rtcMem.pCounter[i] / 1000, 1, 3, stemp);
+        dtostrfi((double)rtcMem.pCounter[i] / 1000, 3, stemp);
       } else {
-        dtostrf(rtcMem.pCounter[i], 1, 0, stemp);
+        dtostrfi(rtcMem.pCounter[i], 0, stemp);
       }
-      snprintf_P(sensor, sizeof(sensor), HTTP_SNS_COUNTER, i+1, stemp, (bitRead(sysCfg.pCounterType, i)) ? " Sec" : "");
+      snprintf_P(sensor, sizeof(sensor), HTTP_SNS_COUNTER, i+1, stemp, (bitRead(sysCfg.pCounterType, i)) ? " " D_UNIT_SECOND : "");
       page += sensor;
     }
   }
diff --git a/sonoff/xsns_dht.ino b/sonoff/xsns_dht.ino
index 722e1e033..85d5a19ca 100644
--- a/sonoff/xsns_dht.ino
+++ b/sonoff/xsns_dht.ino
@@ -88,12 +88,12 @@ boolean dht_read(byte sensor)
   pinMode(dht[sensor].pin, INPUT_PULLUP);
   delayMicroseconds(10);
   if (0 == dht_expectPulse(sensor, LOW)) {
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for start signal low pulse"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_LOW " " D_PULSE));
     dht[sensor].lastresult = false;
     return dht[sensor].lastresult;
   }
   if (0 == dht_expectPulse(sensor, HIGH)) {
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for start signal high pulse"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_START_SIGNAL_HIGH " " D_PULSE));
     dht[sensor].lastresult = false;
     return dht[sensor].lastresult;
   }
@@ -107,7 +107,7 @@ boolean dht_read(byte sensor)
     uint32_t lowCycles  = cycles[2*i];
     uint32_t highCycles = cycles[2*i+1];
     if ((0 == lowCycles) || (0 == highCycles)) {
-      addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Timeout waiting for pulse"));
+      addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_TIMEOUT_WAITING_FOR " " D_PULSE));
       dht[sensor].lastresult = false;
       return dht[sensor].lastresult;
     }
@@ -117,14 +117,14 @@ boolean dht_read(byte sensor)
     }
   }
 
-  snprintf_P(log, sizeof(log), PSTR("DHT: Received %02X, %02X, %02X, %02X, %02X =? %02X"),
+  snprintf_P(log, sizeof(log), PSTR(D_LOG_DHT D_RECEIVED " %02X, %02X, %02X, %02X, %02X =? %02X"),
     dht_data[0], dht_data[1], dht_data[2], dht_data[3], dht_data[4], (dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF);
   addLog(LOG_LEVEL_DEBUG, log);
 
   if (dht_data[4] == ((dht_data[0] + dht_data[1] + dht_data[2] + dht_data[3]) & 0xFF)) {
     dht[sensor].lastresult = true;
   } else {
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("DHT: Checksum failure"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DHT D_CHECKSUM_FAILURE));
     dht[sensor].lastresult = false;
   }
   return dht[sensor].lastresult;
@@ -175,7 +175,7 @@ boolean dht_readTempHum(byte sensor, float &t, float &h)
 boolean dht_setup(byte pin, byte type)
 {
   boolean success = false;
-  
+
   if (dht_sensors < DHT_MAX_SENSORS) {
     dht[dht_sensors].pin = pin;
     dht[dht_sensors].type = type;
@@ -208,9 +208,6 @@ void dht_init()
       snprintf_P(dht[i].stype, sizeof(dht[i].stype), PSTR("%s-%02d"), dht[i].stype, dht[i].pin);
     }
   }
-  
-  snprintf_P(log, sizeof(log), PSTR("DHT: Max clock cycles %d"), dht_maxcycles);
-  addLog(LOG_LEVEL_DEBUG, log);
 }
 
 /*********************************************************************************************\
@@ -227,10 +224,8 @@ void dht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   byte dsxflg = 0;
   for (byte i = 0; i < dht_sensors; i++) {
     if (dht_readTempHum(i, t, h)) {     // Read temperature
-      dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
-      dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2);
-//      snprintf_P(svalue, ssvalue, PSTR("%s, \"%s\":{\"Temperature\":%s, \"Humidity\":%s}"),
-//        svalue, dhtstype, stemp1, stemp2);
+      dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1);
+      dtostrfd(h, sysCfg.flag.humidity_resolution, stemp2);
       snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, dht[i].stype, stemp1, stemp2);
       *djson = 1;
 #ifdef USE_DOMOTICZ
@@ -251,13 +246,13 @@ String dht_webPresent()
   char sensor[80];
   float t;
   float h;
-  
+
   for (byte i = 0; i < dht_sensors; i++) {
     if (dht_readTempHum(i, t, h)) {
-      dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp);
+      dtostrfi(t, sysCfg.flag.temperature_resolution, stemp);
       snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, dht[i].stype, stemp, tempUnit());
       page += sensor;
-      dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp);
+      dtostrfi(h, sysCfg.flag.humidity_resolution, stemp);
       snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, dht[i].stype, stemp);
       page += sensor;
     }
diff --git a/sonoff/xsns_ds18b20.ino b/sonoff/xsns_ds18b20.ino
index bbc9bcf8f..a27860eb1 100644
--- a/sonoff/xsns_ds18b20.ino
+++ b/sonoff/xsns_ds18b20.ino
@@ -135,7 +135,7 @@ boolean dsb_readTemp(float &t)
   }
 
   if (!dsb_read_bit()) {     //check measurement end
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("DSB: Sensor busy"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSOR_BUSY));
     return !isnan(t);
   }
 /*
@@ -160,7 +160,7 @@ boolean dsb_readTemp(float &t)
   crc = dsb_crc(dsb_read(), crc);
   dsb_reset();
   if (crc) { //check crc
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("DSB: Sensor CRC error"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_DSB D_SENSOR_CRC_ERROR));
   } else {
     DSTemp = (msb << 8) + lsb;
     if (DSTemp > 2047) {
@@ -183,8 +183,8 @@ void dsb_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   float t;
 
   if (dsb_readTemp(t)) {  // Check if read failed
-    dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
-    snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"Temperature\":%s}"), svalue, stemp1);
+    dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1);
+    snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18B20\":{\"" D_TEMPERATURE "\":%s}"), svalue, stemp1);
     *djson = 1;
 #ifdef USE_DOMOTICZ
     domoticz_sensor1(stemp1);
@@ -198,12 +198,12 @@ String dsb_webPresent()
   // Needs TelePeriod to refresh data (Do not do it here as it takes too much time)
   String page = "";
   float st;
-  
+
   if (dsb_readTemp(st)) {  // Check if read failed
     char stemp[10];
     char sensor[80];
-    
-    dtostrf(st, 1, sysCfg.flag.temperature_resolution, stemp);
+
+    dtostrfi(st, sysCfg.flag.temperature_resolution, stemp);
     snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, "DS18B20", stemp, tempUnit());
     page += sensor;
   }
diff --git a/sonoff/xsns_ds18x20.ino b/sonoff/xsns_ds18x20.ino
index a20bb6b91..e30c2d4d8 100644
--- a/sonoff/xsns_ds18x20.ino
+++ b/sonoff/xsns_ds18x20.ino
@@ -190,14 +190,14 @@ void ds18x20_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   for (byte i = 0; i < ds18x20_sensors(); i++) {
     if (ds18x20_read(i, t)) {           // Check if read failed
       ds18x20_type(i);
-      dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp2);
+      dtostrfd(t, sysCfg.flag.temperature_resolution, stemp2);
       if (!dsxflg) {
         snprintf_P(svalue, ssvalue, PSTR("%s, \"DS18x20\":{"), svalue);
         *djson = 1;
         stemp1[0] = '\0';
       }
       dsxflg++;
-      snprintf_P(svalue, ssvalue, PSTR("%s%s\"DS%d\":{\"Type\":\"%s\", \"Address\":\"%s\", \"Temperature\":%s}"),
+      snprintf_P(svalue, ssvalue, PSTR("%s%s\"DS%d\":{\"" D_TYPE "\":\"%s\", \"" D_ADDRESS "\":\"%s\", \"" D_TEMPERATURE "\":%s}"),
         svalue, stemp1, i +1, dsbstype, ds18x20_address(i).c_str(), stemp2);
       strcpy(stemp1, ", ");
 #ifdef USE_DOMOTICZ
@@ -222,7 +222,7 @@ String ds18x20_webPresent()
   for (byte i = 0; i < ds18x20_sensors(); i++) {
     if (ds18x20_read(i, t)) {   // Check if read failed
       ds18x20_type(i);
-      dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp);
+      dtostrfi(t, sysCfg.flag.temperature_resolution, stemp);
       snprintf_P(stemp2, sizeof(stemp2), PSTR("%s-%d"), dsbstype, i +1);
       snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, stemp2, stemp, tempUnit());
       page += sensor;
diff --git a/sonoff/xsns_hlw8012.ino b/sonoff/xsns_hlw8012.ino
index 76eaba43b..9e25c8a5a 100644
--- a/sonoff/xsns_hlw8012.ino
+++ b/sonoff/xsns_hlw8012.ino
@@ -345,32 +345,32 @@ void hlw_margin_chk()
     snprintf_P(svalue, sizeof(svalue), PSTR("{"));
     jsonflg = 0;
     if (hlw_margin(0, sysCfg.hlw_pmin, pwv, flag, hlw_pminflg)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerLow\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
+      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_POWERLOW "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
       jsonflg = 1;
     }
     if (hlw_margin(1, sysCfg.hlw_pmax, pwv, flag, hlw_pmaxflg)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"PowerHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
+      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_POWERHIGH "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
       jsonflg = 1;
     }
     if (hlw_margin(0, sysCfg.hlw_umin, puv, flag, hlw_uminflg)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"VoltageLow\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
+      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_VOLTAGELOW "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
       jsonflg = 1;
     }
     if (hlw_margin(1, sysCfg.hlw_umax, puv, flag, hlw_umaxflg)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"VoltageHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
+      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_VOLTAGEHIGH "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
       jsonflg = 1;
     }
     if (hlw_margin(0, sysCfg.hlw_imin, piv, flag, hlw_iminflg)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"CurrentLow\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
+      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_CURRENTLOW "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
       jsonflg = 1;
     }
     if (hlw_margin(1, sysCfg.hlw_imax, piv, flag, hlw_imaxflg)) {
-      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"CurrentHigh\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
+      snprintf_P(svalue, sizeof(svalue), PSTR("%s%s\"" D_CMND_CURRENTHIGH "\":\"%s\""), svalue, (jsonflg)?", ":"", getStateText(flag));
       jsonflg = 1;
     }
     if (jsonflg) {
       snprintf_P(svalue, sizeof(svalue), PSTR("%s}"), svalue);
-      mqtt_publish_topic_P(2, PSTR("MARGINS"), svalue);
+      mqtt_publish_topic_P(2, PSTR(D_RSLT_MARGINS), svalue);
       hlw_mqttPresent(0);
     }
   }
@@ -384,8 +384,8 @@ void hlw_margin_chk()
       } else {
         hlw_mplh_counter--;
         if (!hlw_mplh_counter) {
-          snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReached\":\"%d%s\"}"), pwv, (sysCfg.flag.value_units) ? " W" : "");
-          mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
+          snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_MAXPOWERREACHED "\":\"%d%s\"}"), pwv, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : "");
+          mqtt_publish_topic_P(1, S_RSLT_WARNING, svalue);
           hlw_mqttPresent(0);
           do_cmnd_power(1, 0);
           if (!hlw_mplr_counter) {
@@ -407,12 +407,12 @@ void hlw_margin_chk()
         if (hlw_mplr_counter) {
           hlw_mplr_counter--;
           if (hlw_mplr_counter) {
-            snprintf_P(svalue, sizeof(svalue), PSTR("{\"PowerMonitor\":\"%s\"}"), getStateText(1));
-            mqtt_publish_topic_P(5, PSTR("POWERMONITOR"), svalue);
+            snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_POWERMONITOR "\":\"%s\"}"), getStateText(1));
+            mqtt_publish_topic_P(5, PSTR(D_POWERMONITOR), svalue);
             do_cmnd_power(1, 1);
           } else {
-            snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxPowerReachedRetry\":\"%s\"}"), getStateText(0));
-            mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
+            snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_MAXPOWERREACHEDRETRY "\":\"%s\"}"), getStateText(0));
+            mqtt_publish_topic_P(1, S_RSLT_WARNING, svalue);
             hlw_mqttPresent(0);
           }
         }
@@ -425,15 +425,15 @@ void hlw_margin_chk()
     uped = (uint16_t)(ped * 1000);
     if (!hlw_mkwh_state && (rtcTime.Hour == sysCfg.hlw_mkwhs)) {
       hlw_mkwh_state = 1;
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"EnergyMonitor\":\"%s\"}"), getStateText(1));
-      mqtt_publish_topic_P(5, PSTR("ENERGYMONITOR"), svalue);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_ENERGYMONITOR "\":\"%s\"}"), getStateText(1));
+      mqtt_publish_topic_P(5, PSTR(D_ENERGYMONITOR), svalue);
       do_cmnd_power(1, 1);
     }
     else if ((1 == hlw_mkwh_state) && (uped >= sysCfg.hlw_mkwh)) {
       hlw_mkwh_state = 2;
-      dtostrf(ped, 1, 3, svalue);
-      snprintf_P(svalue, sizeof(svalue), PSTR("{\"MaxEnergyReached\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " kWh" : "");
-      mqtt_publish_topic_P(1, PSTR("WARNING"), svalue);
+      dtostrfd(ped, 3, svalue);
+      snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_MAXENERGYREACHED "\":\"%s%s\"}"), svalue, (sysCfg.flag.value_units) ? " " D_UNIT_KILOWATTHOUR : "");
+      mqtt_publish_topic_P(1, S_RSLT_WARNING, svalue);
       hlw_mqttPresent(0);
       do_cmnd_power(1, 0);
     }
@@ -450,43 +450,43 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len
   boolean serviced = true;
   uint8_t caltext = 0;
 
-  if (!strcmp_P(type,PSTR("POWERLOW"))) {
+  if (!strcasecmp_P(type, PSTR(D_CMND_POWERLOW))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_pmin = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"PowerLow\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " W" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_POWERLOW "\":\"%d%s\"}"), sysCfg.hlw_pmin, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : "");
   }
-  else if (!strcmp_P(type,PSTR("POWERHIGH"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_POWERHIGH))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_pmax = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"PowerHigh\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " W" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_POWERHIGH "\":\"%d%s\"}"), sysCfg.hlw_pmax, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : "");
   }
-  else if (!strcmp_P(type,PSTR("VOLTAGELOW"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_VOLTAGELOW))) {
     if ((payload >= 0) && (payload < 501)) {
       sysCfg.hlw_umin = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"VoltageLow\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " V" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_VOLTAGELOW "\":\"%d%s\"}"), sysCfg.hlw_umin, (sysCfg.flag.value_units) ? " " D_UNIT_VOLT : "");
   }
-  else if (!strcmp_P(type,PSTR("VOLTAGEHIGH"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_VOLTAGEHIGH))) {
     if ((payload >= 0) && (payload < 501)) {
       sysCfg.hlw_umax = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("[\"VoltageHigh\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " V" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_VOLTAGEHIGH "\":\"%d%s\"}"), sysCfg.hlw_umax, (sysCfg.flag.value_units) ? " " D_UNIT_VOLT : "");
   }
-  else if (!strcmp_P(type,PSTR("CURRENTLOW"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_CURRENTLOW))) {
     if ((payload >= 0) && (payload < 16001)) {
       sysCfg.hlw_imin = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"CurrentLow\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " mA" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_CURRENTLOW "\":\"%d%s\"}"), sysCfg.hlw_imin, (sysCfg.flag.value_units) ? " " D_UNIT_MILLIAMPERE : "");
   }
-  else if (!strcmp_P(type,PSTR("CURRENTHIGH"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_CURRENTHIGH))) {
     if ((payload >= 0) && (payload < 16001)) {
       sysCfg.hlw_imax = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"CurrentHigh\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " mA" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_CURRENTHIGH "\":\"%d%s\"}"), sysCfg.hlw_imax, (sysCfg.flag.value_units) ? " " D_UNIT_MILLIAMPERE : "");
   }
-  else if (!strcmp_P(type,PSTR("ENERGYRESET"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_ENERGYRESET))) {
     if ((payload >= 1) && (payload <= 3)) {
       switch (payload) {
       case 1:
@@ -506,96 +506,96 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len
     char sey[10];
     char sen[10];
     char set[10];
-    dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey);
-    dtostrf((float)rtcMem.hlw_kWhtoday / 100000000, 1, sysCfg.flag.energy_resolution, sen);
-    dtostrf((float)(rtcMem.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, 1, sysCfg.flag.energy_resolution, set);
-    snprintf_P(svalue, ssvalue, PSTR("{\"EnergyReset\":{\"Total\":%s, \"Yesterday\":%s, \"Today\":%s}}"), set, sey, sen);
+    dtostrfd((float)sysCfg.hlw_kWhyesterday / 100000000, sysCfg.flag.energy_resolution, sey);
+    dtostrfd((float)rtcMem.hlw_kWhtoday / 100000000, sysCfg.flag.energy_resolution, sen);
+    dtostrfd((float)(rtcMem.hlw_kWhtotal + (hlw_kWhtoday / 1000)) / 100000, sysCfg.flag.energy_resolution, set);
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_ENERGYRESET "\":{\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s}}"), set, sey, sen);
   }
-  else if (!strcmp_P(type,PSTR("HLWPCAL"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_HLWPCAL))) {
     if ((payload > 0) && (payload < 32001)) {
       sysCfg.hlw_pcal = (payload > 4000) ? payload : HLW_PREF_PULSE;  // 12530
     }
     caltext = 1;
   }
-  else if (!strcmp_P(type,PSTR("HLWPSET"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_HLWPSET))) {
     if ((payload > 0) && (payload < 3601) && hlw_cf_plen) {
       sysCfg.hlw_pcal = (payload * 10 * hlw_cf_plen) / HLW_PREF;
     }
     caltext = 1;
   }
-  else if (!strcmp_P(type,PSTR("HLWUCAL"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_HLWUCAL))) {
     if ((payload > 0) && (payload < 32001)) {
       sysCfg.hlw_ucal = (payload > 999) ? payload : HLW_UREF_PULSE;  // 1950
     }
     caltext = 2;
   }
-  else if (!strcmp_P(type,PSTR("HLWUSET"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_HLWUSET))) {
     if ((payload > 0) && (payload < 501) && hlw_cf1u_plen) {
       sysCfg.hlw_ucal = (payload * 10 * hlw_cf1u_plen) / HLW_UREF;
     }
     caltext = 2;
   }
-  else if (!strcmp_P(type,PSTR("HLWICAL"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_HLWICAL))) {
     if ((payload > 0) && (payload < 32001)) {
       sysCfg.hlw_ical = (payload > 1100) ? payload : HLW_IREF_PULSE;  // 3500
     }
     caltext = 3;
   }
-  else if (!strcmp_P(type,PSTR("HLWISET"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_HLWISET))) {
     if ((payload > 0) && (payload < 16001) && hlw_cf1i_plen) {
       sysCfg.hlw_ical = (payload * hlw_cf1i_plen) / HLW_IREF;
     }
     caltext = 3;
   }
 #if FEATURE_POWER_LIMIT
-  else if (!strcmp_P(type,PSTR("MAXPOWER"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MAXPOWER))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_mpl = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MaxPower\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " W" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXPOWER "\":\"%d%s\"}"), sysCfg.hlw_mpl, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : "");
   }
-  else if (!strcmp_P(type,PSTR("MAXPOWERHOLD"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MAXPOWERHOLD))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_mplh = (1 == payload) ? MAX_POWER_HOLD : payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerHold\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " Sec" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXPOWERHOLD "\":\"%d%s\"}"), sysCfg.hlw_mplh, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : "");
   }
-  else if (!strcmp_P(type,PSTR("MAXPOWERWINDOW"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MAXPOWERWINDOW))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_mplw = (1 == payload) ? MAX_POWER_WINDOW : payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MaxPowerWindow\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " Sec" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXPOWERWINDOW "\":\"%d%s\"}"), sysCfg.hlw_mplw, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : "");
   }
-  else if (!strcmp_P(type,PSTR("SAFEPOWER"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SAFEPOWER))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_mspl = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"SafePower\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " W" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SAFEPOWER "\":\"%d%s\"}"), sysCfg.hlw_mspl, (sysCfg.flag.value_units) ? " " D_UNIT_WATT : "");
   }
-  else if (!strcmp_P(type,PSTR("SAFEPOWERHOLD"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SAFEPOWERHOLD))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_msplh = (1 == payload) ? SAFE_POWER_HOLD : payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerHold\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " Sec" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SAFEPOWERHOLD "\":\"%d%s\"}"), sysCfg.hlw_msplh, (sysCfg.flag.value_units) ? " " D_UNIT_SECOND : "");
   }
-  else if (!strcmp_P(type,PSTR("SAFEPOWERWINDOW"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_SAFEPOWERWINDOW))) {
     if ((payload >= 0) && (payload < 1440)) {
       sysCfg.hlw_msplw = (1 == payload) ? SAFE_POWER_WINDOW : payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"SafePowerWindow\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " Min" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_SAFEPOWERWINDOW "\":\"%d%s\"}"), sysCfg.hlw_msplw, (sysCfg.flag.value_units) ? " " D_UNIT_MINUTE : "");
   }
-  else if (!strcmp_P(type,PSTR("MAXENERGY"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MAXENERGY))) {
     if ((payload >= 0) && (payload < 3601)) {
       sysCfg.hlw_mkwh = payload;
       hlw_mkwh_state = 3;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergy\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " Wh" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXENERGY "\":\"%d%s\"}"), sysCfg.hlw_mkwh, (sysCfg.flag.value_units) ? " " D_UNIT_WATTHOUR : "");
   }
-  else if (!strcmp_P(type,PSTR("MAXENERGYSTART"))) {
+  else if (!strcasecmp_P(type, PSTR(D_CMND_MAXENERGYSTART))) {
     if ((payload >= 0) && (payload < 24)) {
       sysCfg.hlw_mkwhs = payload;
     }
-    snprintf_P(svalue, ssvalue, PSTR("{\"MaxEnergyStart\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " Hr" : "");
+    snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_MAXENERGYSTART "\":\"%d%s\"}"), sysCfg.hlw_mkwhs, (sysCfg.flag.value_units) ? " " D_UNIT_HOUR : "");
   }
 #endif  // FEATURE_POWER_LIMIT
   else {
@@ -603,13 +603,13 @@ boolean hlw_command(char *type, uint16_t index, char *dataBuf, uint16_t data_len
   }
   switch (caltext) {
     case 1:
-      snprintf_P(svalue, ssvalue, PSTR("(\"HlwPcal\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " uS" : "");
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_HLWPCAL "\":\"%d%s\"}"), sysCfg.hlw_pcal, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : "");
       break;
     case 2:
-      snprintf_P(svalue, ssvalue, PSTR("{\"HlwUcal\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " uS" : "");
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_HLWUCAL "\":\"%d%s\"}"), sysCfg.hlw_ucal, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : "");
       break;
     case 3:
-      snprintf_P(svalue, ssvalue, PSTR("(\"HlwIcal\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " uS" : "");
+      snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_HLWICAL "\":\"%d%s\"}"), sysCfg.hlw_ical, (sysCfg.flag.value_units) ? " " D_UNIT_MICROSECOND : "");
       break;
   }
   return serviced;
@@ -642,20 +642,20 @@ void hlw_mqttStat(byte option, char* svalue, uint16_t ssvalue)
   char speriod[20];
 
   hlw_readEnergy(option, pet, ped, pe, pw, pu, pi, pc);
-  dtostrf(pet, 1, sysCfg.flag.energy_resolution, spet);
-  dtostrf(ped, 1, sysCfg.flag.energy_resolution, sped);
-  dtostrf(pe, 1, sysCfg.flag.wattage_resolution, spe);
-  dtostrf(pw, 1, sysCfg.flag.wattage_resolution, spw);
-  dtostrf(pu, 1, sysCfg.flag.voltage_resolution, spu);
-  dtostrf(pi, 1, 3, spi);
-  dtostrf(pc, 1, 2, spc);
-  dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey);
-  snprintf_P(speriod, sizeof(speriod), PSTR(", \"Period\":%s"), spe);
-  snprintf_P(svalue, ssvalue, PSTR("%s\"Total\":%s, \"Yesterday\":%s, \"Today\":%s%s, \"Power\":%s, \"Factor\":%s, \"Voltage\":%s, \"Current\":%s}"),
+  dtostrfd(pet, sysCfg.flag.energy_resolution, spet);
+  dtostrfd(ped, sysCfg.flag.energy_resolution, sped);
+  dtostrfd(pe, sysCfg.flag.wattage_resolution, spe);
+  dtostrfd(pw, sysCfg.flag.wattage_resolution, spw);
+  dtostrfd(pu, sysCfg.flag.voltage_resolution, spu);
+  dtostrfd(pi, 3, spi);
+  dtostrfd(pc, 2, spc);
+  dtostrfd((float)sysCfg.hlw_kWhyesterday / 100000000, sysCfg.flag.energy_resolution, sey);
+  snprintf_P(speriod, sizeof(speriod), PSTR(", \"" D_PERIOD "\":%s"), spe);
+  snprintf_P(svalue, ssvalue, PSTR("%s\"" D_TOTAL "\":%s, \"" D_YESTERDAY "\":%s, \"" D_TODAY "\":%s%s, \"" D_POWERUSAGE "\":%s, \"" D_POWERFACTOR "\":%s, \"" D_VOLTAGE "\":%s, \"" D_CURRENT "\":%s}"),
     svalue, spet, sey, sped, (option) ? speriod : "", spw, spc, spu, spi);
 #ifdef USE_DOMOTICZ
   if (option) {  // Only send if telemetry
-    dtostrf(pet * 1000, 1, 1, spet);
+    dtostrfd(pet * 1000, 1, spet);
     domoticz_sensor4((uint16_t)pw, spet);
   }
 #endif  // USE_DOMOTICZ
@@ -669,27 +669,27 @@ void hlw_mqttPresent(byte option)
 // {"Time":"2017-03-04T13:37:24", "Total":0.013, "Yesterday":0.013, "Today":0.000, "Period":0, "Power":0, "Factor":0.00, "Voltage":0, "Current":0.000}
   char svalue[200];  // was MESSZ
 
-  snprintf_P(svalue, sizeof(svalue), PSTR("{\"Time\":\"%s\", "), getDateTime().c_str());
+  snprintf_P(svalue, sizeof(svalue), PSTR("{\"" D_TIME "\":\"%s\", "), getDateTime().c_str());
   hlw_mqttStat(option, svalue, sizeof(svalue));
-  mqtt_publish_topic_P(2, PSTR("ENERGY"), svalue);
+  mqtt_publish_topic_P(2, PSTR(D_RSLT_ENERGY), svalue);
 }
 
 void hlw_mqttStatus(char* svalue, uint16_t ssvalue)
 {
-  snprintf_P(svalue, ssvalue, PSTR("{\"StatusPWR\":{"));
+  snprintf_P(svalue, ssvalue, PSTR("{\"" D_CMND_STATUS D_STATUS8_POWER "\":{"));
   hlw_mqttStat(0, svalue, ssvalue);
   snprintf_P(svalue, ssvalue, PSTR("%s}"), svalue);
 }
 
 #ifdef USE_WEBSERVER
 const char HTTP_ENERGY_SNS[] PROGMEM =
-  "<tr><th>Voltage</th><td>%s V</td></tr>"
-  "<tr><th>Current</th><td>%s A</td></tr>"
-  "<tr><th>Power</th><td>%s W</td></tr>"
-  "<tr><th>Power Factor</th><td>%s</td></tr>"
-  "<tr><th>Energy Today</th><td>%s kWh</td></tr>"
-  "<tr><th>Energy Yesterday</th><td>%s kWh</td></tr>"
-  "<tr><th>Energy Total</th><td>%s kWh</td></tr>";
+  "<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>";
 
 String hlw_webPresent()
 {
@@ -707,16 +707,16 @@ String hlw_webPresent()
   char spi[10];
   char spc[10];
   char sey[10];
-  char sensor[320];
+  char sensor[400];
 
   hlw_readEnergy(0, pet, ped, pe, pw, pu, pi, pc);
-  dtostrf(pet, 1, sysCfg.flag.energy_resolution, spet);
-  dtostrf(ped, 1, sysCfg.flag.energy_resolution, sped);
-  dtostrf(pw, 1, sysCfg.flag.wattage_resolution, spw);
-  dtostrf(pu, 1, sysCfg.flag.voltage_resolution, spu);
-  dtostrf(pi, 1, 3, spi);
-  dtostrf(pc, 1, 2, spc);
-  dtostrf((float)sysCfg.hlw_kWhyesterday / 100000000, 1, sysCfg.flag.energy_resolution, sey);
+  dtostrfi(pet, sysCfg.flag.energy_resolution, spet);
+  dtostrfi(ped, sysCfg.flag.energy_resolution, sped);
+  dtostrfi(pw, sysCfg.flag.wattage_resolution, spw);
+  dtostrfi(pu, sysCfg.flag.voltage_resolution, spu);
+  dtostrfi(pi, 3, spi);
+  dtostrfi(pc, 2, spc);
+  dtostrfi((float)sysCfg.hlw_kWhyesterday / 100000000, sysCfg.flag.energy_resolution, sey);
   snprintf_P(sensor, sizeof(sensor), HTTP_ENERGY_SNS, spu, spi, spw, spc, sped, sey, spet);
   return String(sensor);
 }
diff --git a/sonoff/xsns_htu21.ino b/sonoff/xsns_htu21.ino
index a84709316..f0b25c822 100644
--- a/sonoff/xsns_htu21.ino
+++ b/sonoff/xsns_htu21.ino
@@ -244,7 +244,7 @@ uint8_t htu_detect()
     delayH=23;
   }
   if (success) {
-    snprintf_P(log, sizeof(log), PSTR("I2C: %s found at address 0x%x"), htustype, htuaddr);
+    snprintf_P(log, sizeof(log), PSTR(D_LOG_I2C "%s " D_FOUND_AT " 0x%x"), htustype, htuaddr);
     addLog(LOG_LEVEL_DEBUG, log);
   } else {
     htutype = 0;
@@ -268,8 +268,8 @@ void htu_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
   float t = htu21_readTemperature();
   float h = htu21_readHumidity();
   h = htu21_compensatedHumidity(h, t);
-  dtostrf(t, 1, sysCfg.flag.temperature_resolution, stemp1);
-  dtostrf(h, 1, sysCfg.flag.humidity_resolution, stemp2);
+  dtostrfd(t, sysCfg.flag.temperature_resolution, stemp1);
+  dtostrfd(h, sysCfg.flag.humidity_resolution, stemp2);
   snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, htustype, stemp1, stemp2);
   *djson = 1;
 #ifdef USE_DOMOTICZ
@@ -288,10 +288,10 @@ String htu_webPresent()
     float t_htu21 = htu21_readTemperature();
     float h_htu21 = htu21_readHumidity();
     h_htu21 = htu21_compensatedHumidity(h_htu21, t_htu21);
-    dtostrf(t_htu21, 1, sysCfg.flag.temperature_resolution, stemp);
+    dtostrfi(t_htu21, sysCfg.flag.temperature_resolution, stemp);
     snprintf_P(sensor, sizeof(sensor), HTTP_SNS_TEMP, htustype, stemp, tempUnit());
     page += sensor;
-    dtostrf(h_htu21, 1, sysCfg.flag.humidity_resolution, stemp);
+    dtostrfi(h_htu21, sysCfg.flag.humidity_resolution, stemp);
     snprintf_P(sensor, sizeof(sensor), HTTP_SNS_HUM, htustype, stemp);
     page += sensor;
   }
diff --git a/sonoff/xsns_sht1x.ino b/sonoff/xsns_sht1x.ino
index 918713873..899c1fbdd 100644
--- a/sonoff/xsns_sht1x.ino
+++ b/sonoff/xsns_sht1x.ino
@@ -77,7 +77,7 @@ boolean sht_sendCommand(const byte cmd)
   }
   if (ackerror) {
     shttype = 0;
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("SHT1X: Sensor did not ACK command"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_SHT1 D_SENSOR_DID_NOT_ACK_COMMAND));
   }
   return (!ackerror);
 }
@@ -91,7 +91,7 @@ boolean sht_awaitResult()
     }
     delay(20);
   }
-  addLog_P(LOG_LEVEL_DEBUG, PSTR("SHT1X: Data not ready"));
+  addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_SHT1 D_SENSOR_BUSY));
   shttype = 0;
   return false;
 }
@@ -159,17 +159,6 @@ boolean sht_readTempHum(float &t, float &h)
   return (!isnan(t) && !isnan(h));
 }
 
-boolean sht_readCharTempHum(char* temp, char* hum)
-{
-  float t;
-  float h;
-
-  boolean success = sht_readTempHum(t, h);
-  dtostrf(t, 1, sysCfg.flag.temperature_resolution, temp);
-  dtostrf(h, 1, sysCfg.flag.humidity_resolution, hum);
-  return success;
-}
-
 boolean sht_detect()
 {
   if (shttype) {
@@ -178,12 +167,12 @@ boolean sht_detect()
 
   float t;
   float h;
-  
+
   sht_sda_pin = pin[GPIO_I2C_SDA];
   sht_scl_pin = pin[GPIO_I2C_SCL];
   if (sht_readTempHum(t, h)) {
     shttype = 1;
-    addLog_P(LOG_LEVEL_DEBUG, PSTR("I2C: SHT1X found"));
+    addLog_P(LOG_LEVEL_DEBUG, PSTR(D_LOG_I2C D_SHT1X_FOUND));
   } else {
     Wire.begin(sht_sda_pin, sht_scl_pin);
     shttype = 0;
@@ -201,10 +190,15 @@ void sht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
     return;
   }
 
-  char stemp[10];
-  char shum[10];
-  
-  if (sht_readCharTempHum(stemp, shum)) {
+  float t;
+  float h;
+
+  if (sht_readTempHum(t, h)) {
+    char stemp[10];
+    char shum[10];
+
+    dtostrfd(t, sysCfg.flag.temperature_resolution, stemp);
+    dtostrfd(h, sysCfg.flag.humidity_resolution, shum);
     snprintf_P(svalue, ssvalue, JSON_SNS_TEMPHUM, svalue, "SHT1X", stemp, shum);
     *djson = 1;
 #ifdef USE_DOMOTICZ
@@ -216,13 +210,18 @@ void sht_mqttPresent(char* svalue, uint16_t ssvalue, uint8_t* djson)
 #ifdef USE_WEBSERVER
 String sht_webPresent()
 {
+  float t;
+  float h;
+
   String page = "";
   if (shttype) {
-    char stemp[10];
-    char shum[10];
-    
-    if (sht_readCharTempHum(stemp, shum)) {
+    if (sht_readTempHum(t, h)) {
+      char stemp[10];
+      char shum[10];
       char sensor[80];
+
+      dtostrfi(t, sysCfg.flag.temperature_resolution, stemp);
+      dtostrfi(h, sysCfg.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);
@@ -234,4 +233,3 @@ String sht_webPresent()
 #endif  // USE_WEBSERVER
 #endif  // USE_SHT
 #endif  // USE_I2C
-