From e76b2abd9fa60f5b16e230680432c464f1c8b6d6 Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Tue, 28 Nov 2017 22:49:28 +0100 Subject: [PATCH 01/23] some corrections for the german translation --- sonoff/language/de-DE.h | 156 ++++++++++++++++++++-------------------- 1 file changed, 78 insertions(+), 78 deletions(-) diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 1410ee50e..c188df3ae 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -31,9 +31,9 @@ \*********************************************************************/ // "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_YEAR_MONTH_SEPARATOR "." +#define D_MONTH_DAY_SEPARATOR "." +#define D_DATE_TIME_SEPARATOR " " #define D_HOUR_MINUTE_SEPARATOR ":" #define D_MINUTE_SECOND_SEPARATOR ":" @@ -59,17 +59,17 @@ #define D_BLINK "Blinken" #define D_BLINKOFF "BlinkenAus" #define D_BOOTVERSION "Boot" -#define D_BOOT_COUNT "Boot-Zähler" +#define D_BOOT_COUNT "Anzahl Startvorgänge" #define D_BOOTCOUNT "BootZähler" #define D_BRIGHTLIGHT "hell" #define D_BUILDDATETIME "BuildDatumUhrzeit" -#define D_BUTTON "Taste" +#define D_BUTTON "Knopf" #define D_CELSIUS "Celsius" #define D_CODE "code" // Button code #define D_COLDLIGHT "kalt" #define D_COMMAND "Befehl" #define D_CONNECTED "verbunden" -#define D_COREVERSION "Kern" +#define D_COREVERSION "Core" #define D_COUNT "zählen" #define D_COUNTER "Zähler" #define D_CURRENT "Strom" // As in Voltage and Current @@ -82,7 +82,7 @@ #define D_DONE "erledigt" #define D_DST_TIME "DST" #define D_EMPTY "leer" -#define D_EMULATION "Emulierung" +#define D_EMULATION "Emulation" #define D_ENABLED "aktiviert" #define D_ENDDST "EndDST" // End Daylight Savings Time #define D_ERASE "löschen" @@ -97,14 +97,14 @@ #define D_FILE "Datei" #define D_FLASHMODE "FlashMode" #define D_FLASHSIZE "FlashSize" -#define D_FREE_MEMORY "freier Speicher" +#define D_FREE_MEMORY "Freier Speicher" #define D_FREEMEMORY "frei" #define D_FROM "von" #define D_GATEWAY "Gateway" #define D_GROUP "Gruppe" #define D_HEAPSIZE "Heap-Größe" #define D_HIGH "hoch" -#define D_HOST "host" +#define D_HOST "Host" #define D_HOSTNAME "Hostname" #define D_HUMIDITY "Feuchtigkeit" #define D_ID "ID" @@ -115,10 +115,10 @@ #define D_INITIALIZED "initialisiert" #define D_IP_ADDRESS "IP-Addresse" #define D_LIGHT "Licht" -#define D_LOCAL_TIME "örtlich" +#define D_LOCAL_TIME "lokale Zeit" #define D_LOW "niedrig" #define D_LWT "LWT" -#define D_MAC "Mac" +#define D_MAC "MAC" #define D_MASK "Maske" #define D_MODULE "Modul" #define D_MQTT "MQTT" @@ -134,13 +134,13 @@ #define D_OR "oder" #define D_PASSWORD "Passwort" #define D_PERIOD "Punkt" -#define D_PORT "port" +#define D_PORT "Port" #define D_POWER_FACTOR "Leistungsfaktor" #define D_POWERFACTOR "Faktor" #define D_POWERUSAGE "Leistung" #define D_PRESSURE "Druck" #define D_PRESSUREATSEALEVEL "MeeresDruck" -#define D_PROGRAM_FLASH_SIZE "Programm-Flash-Größe" +#define D_PROGRAM_FLASH_SIZE "Programm Flash Größe" #define D_PROGRAMFLASHSIZE "ProgramFlashSize" #define D_PROGRAM_SIZE "Programmgröße" #define D_PROGRAMSIZE "ProgramSize" @@ -150,16 +150,16 @@ #define D_RESTARTING "starte neu" #define D_RESTART_REASON "Grund für Neustart" #define D_RESTARTREASON "RestartReason" -#define D_RESTORE "wiederherstellen" +#define D_RESTORE "Wiederherstellung" #define D_RETAINED "beibehalten" -#define D_SAVE "speichern" +#define D_SAVE "Speichern" #define D_SAVEADDRESS "SaveAddress" #define D_SAVECOUNT "SaveCount" #define D_SAVESTATE "SaveState" #define D_SDKVERSION "SDK" #define D_SELECTED "ausgewählt" #define D_SENSOR "Sensor" -#define D_SERIAL "Serial" +#define D_SERIAL "Seriell" #define D_BYTES "Bytes" #define D_SSID "SSID" #define D_START "Start" @@ -171,7 +171,7 @@ #define D_SUBNETMASK "Subnetmaske" #define D_SUBSCRIBE_TO "subscribe to" #define D_SUCCESSFUL "erfolgreich" -#define D_SWITCH "switch" +#define D_SWITCH "Schalter" #define D_SYNC "sync" #define D_SYS "sys" // Sys log #define D_TEMPERATURE "Temperatur" @@ -179,15 +179,15 @@ #define D_TIME "Zeit" #define D_TO "bis" #define D_TODAY "heute" -#define D_TOGGLE "schalten" +#define D_TOGGLE "An/Aus" #define D_TOPIC "topic" #define D_TOTAL "Total" #define D_TRANSMIT "Übertragen" #define D_TRUE "wahr" -#define D_TYPE "Typ" +#define D_TYPE "Art" #define D_UNKNOWN "unbekannt" -#define D_UPGRADE "upgrade" -#define D_UPLOAD "upload" +#define D_UPGRADE "update" +#define D_UPLOAD "Upload" #define D_UPTIME "Laufzeit" #define D_USER "Benutzer" #define D_UTC_TIME "UTC" @@ -196,26 +196,26 @@ #define D_VERSION "Version" #define D_VOLTAGE "Spannung" #define D_WARMLIGHT "warm" -#define D_WEB "web" // Web log +#define D_WEB "Web" // Web log #define D_WEB_SERVER "Web-Server" #define D_WIFI "WLAN" #define D_WRONG "falsch" #define D_YESTERDAY "gestern" // settings.ino -#define D_SAVED_TO_FLASH_AT "in flash gespeichert am" -#define D_LOADED_FROM_FLASH_AT "geladen aus flash am" +#define D_SAVED_TO_FLASH_AT "in Flash gespeichert am" +#define D_LOADED_FROM_FLASH_AT "aus Flash geladen am" #define D_USE_DEFAULTS "Standard verwenden" #define D_ERASED_SECTOR "gelöschter Sektor" // sonoff.ino #define D_LEVEL_10 "level 1-0" #define D_LEVEL_01 "level 0-1" -#define D_SERIAL_LOGGING_DISABLED "serielles logging deaktiviert" -#define D_SYSLOG_LOGGING_REENABLED "syslog logging reaktiviert" +#define D_SERIAL_LOGGING_DISABLED "Serielles logging deaktiviert" +#define D_SYSLOG_LOGGING_REENABLED "Syslog logging reaktiviert" -#define D_SET_BAUDRATE_TO "Baudrate eingestell auf" -#define D_RECEIVED_TOPIC "erhaltenes topic" +#define D_SET_BAUDRATE_TO "Baudrate eingestellt auf" +#define D_RECEIVED_TOPIC "empfangenes topic" #define D_DATA_SIZE "Datengröße" #define D_ANALOG_INPUT "Analog" @@ -229,16 +229,16 @@ // support.ino #define D_OSWATCH "osWatch" #define D_BLOCKED_LOOP "Blocked Loop" -#define D_WPS_FAILED_WITH_STATUS "WPSconfig fehlgeschlagen mit Status" +#define D_WPS_FAILED_WITH_STATUS "WPS fehlgeschlagen mit Status" #define D_ACTIVE_FOR_1_MINUTE "aktiv für 1 Minute" #define D_FAILED_TO_START "Starten fehlgeschlagen" #define D_PATCH_ISSUE_2186 "Patch-Problem 2186" #define D_CONNECTING_TO_AP "verbinden mit AP" #define D_IN_MODE "in Modus" -#define D_CONNECT_FAILED_NO_IP_ADDRESS "Verbindung fehlgeschlagen da keine IP-Adresse erhalten wurde" +#define D_CONNECT_FAILED_NO_IP_ADDRESS "Verbindung fehlgeschlagen da keine IP-Adresse zugeteilt wurde" #define D_CONNECT_FAILED_AP_NOT_REACHED "Verbindung fehlgeschlagen da AP nicht erreicht werden konnte" -#define D_CONNECT_FAILED_WRONG_PASSWORD "Verbindung fehlgeschlagen mit AP falschem Passwort" -#define D_CONNECT_FAILED_AP_TIMEOUT "Verbindung fehlgeschlagen mit AP timeout" +#define D_CONNECT_FAILED_WRONG_PASSWORD "Verbindung fehlgeschlagen mit AP weil das Passwort falsch ist" +#define D_CONNECT_FAILED_AP_TIMEOUT "Verbindung fehlgeschlagen da der AP nicht antwortet (timeout)" #define D_ATTEMPTING_CONNECTION "Verbindungsversuch..." #define D_CHECKING_CONNECTION "prüfe Verbindung..." #define D_QUERY_DONE "Suchanfrage abgeschlossen. MQTT-Services gefunden" @@ -247,7 +247,7 @@ #define D_FOUND_AT "gefunden bei" #define D_I2CSCAN_UNKNOWN_ERROR_AT "unbekannter Fehler bei" #define D_I2CSCAN_NO_DEVICES_FOUND "keine Geräte gefunden" -#define D_SYSLOG_HOST_NOT_FOUND "syslog host nicht gefunden" +#define D_SYSLOG_HOST_NOT_FOUND "Syslog Host nicht gefunden" // webserver.ino #define D_MINIMAL_FIRMWARE_PLEASE_UPGRADE "MINIMUM-Firmware - bitte upgraden" @@ -262,11 +262,11 @@ #define D_RESTART_IN "Neustart in" #define D_SECONDS "Sekunden" -#define D_DEVICE_WILL_RESTART "Gerät wird in wenigen Sekunden neu starten" -#define D_BUTTON_TOGGLE "schalten" +#define D_DEVICE_WILL_RESTART "Gerät wird jetzt neu gestartet" +#define D_BUTTON_TOGGLE "An/Aus" #define D_CONFIGURATION "Einstellungen" #define D_INFORMATION "Informationen" -#define D_FIRMWARE_UPGRADE "Firmware-Upgrade" +#define D_FIRMWARE_UPGRADE "Firmware Update" #define D_CONSOLE "Konsole" #define D_CONFIRM_RESTART "Neustart bestätigen" @@ -282,16 +282,16 @@ #define D_RESTORE_CONFIGURATION "Konfiguration wiederherstellen" #define D_MAIN_MENU "Hauptmenü" -#define D_MODULE_PARAMETERS "Modul-Parameter" -#define D_MODULE_TYPE "Module-Typ" +#define D_MODULE_PARAMETERS "Modul Einstellungen" +#define D_MODULE_TYPE "Modul Typ" #define D_GPIO "GPIO" #define D_SERIAL_IN "serieller Eingang [serial in]" #define D_SERIAL_OUT "serieller Ausgang [serial out]" -#define D_WIFI_PARAMETERS "WLAN-Parameter" -#define D_SCAN_FOR_WIFI_NETWORKS "Suche nach WLAN-Netzwerke" -#define D_SCAN_DONE "scan abgeschlossen" -#define D_NO_NETWORKS_FOUND "keine Netzwerke gefunden" +#define D_WIFI_PARAMETERS "WLAN Einstellungen" +#define D_SCAN_FOR_WIFI_NETWORKS "WLAN-Netzwerk suchen und auswählen" +#define D_SCAN_DONE "Suche abgeschlossen" +#define D_NO_NETWORKS_FOUND "Keine Netzwerke gefunden" #define D_REFRESH_TO_SCAN_AGAIN "Aktualisieren um erneut zu suchen" #define D_DUPLICATE_ACCESSPOINT "AccessPoint duplizieren" #define D_SKIPPING_LOW_QUALITY "überspringe wegen niedriger Qualität" @@ -299,42 +299,42 @@ #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_AP1_SSID "WLAN 1 - SSID" +#define D_AP1_PASSWORD "WLAN 1 - Passwort" +#define D_AP2_SSID "WLAN 2 - SSID" +#define D_AP2_PASSWORD "WLAN 2 - Passwort" -#define D_MQTT_PARAMETERS "MQTT-Parameter" +#define D_MQTT_PARAMETERS "MQTT Einstellungen" #define D_CLIENT "client" #define D_FULL_TOPIC "full topic" -#define D_LOGGING_PARAMETERS "Logging-Parameter" -#define D_LOG_LEVEL "log level" +#define D_LOGGING_PARAMETERS "Logging Einstellungen" +#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_SYSLOG_HOST "Syslog Host" +#define D_SYSLOG_PORT "Syslog Port" #define D_TELEMETRY_PERIOD "Telemetry period" -#define D_OTHER_PARAMETERS "andere Parameter" -#define D_WEB_ADMIN_PASSWORD "Web-Admin-Passwort" +#define D_OTHER_PARAMETERS "Sonstige Einstellungen" +#define D_WEB_ADMIN_PASSWORD "Passwort für Web Oberfläche" #define D_MQTT_ENABLE "MQTT aktivieren" #define D_FRIENDLY_NAME "Name [friendly name]" #define D_BELKIN_WEMO "Belkin WeMo" #define D_HUE_BRIDGE "Hue Bridge" -#define D_SINGLE_DEVICE "einzelnes Gerät" +#define D_SINGLE_DEVICE "Einzelnes Gerät" #define D_MULTI_DEVICE "Mehrfachgerät" #define D_SAVE_CONFIGURATION "Konfiguration speichern" #define D_CONFIGURATION_SAVED "Konfiguration gespeichert" #define D_CONFIGURATION_RESET "Konfiguration zurücksetzen" -#define D_PROGRAM_VERSION "Programmversion" +#define D_PROGRAM_VERSION "Tasmota Version" #define D_BUILD_DATE_AND_TIME "Build-Datum & -Uhrzeit" #define D_CORE_AND_SDK_VERSION "Core-/SDK-Version" -#define D_FLASH_WRITE_COUNT "Flash-Schreibzähler" +#define D_FLASH_WRITE_COUNT "Anz. Flash Schreibzugriffe" #define D_MAC_ADDRESS "MAC-Adresse" -#define D_MQTT_HOST "MQTT host" -#define D_MQTT_PORT "MQTT port" +#define D_MQTT_HOST "MQTT Host" +#define D_MQTT_PORT "MQTT Port" #define D_MQTT_CLIENT "MQTT client" #define D_MQTT_USER "MQTT-Benutzer" #define D_MQTT_TOPIC "MQTT topic" @@ -344,26 +344,26 @@ #define D_MDNS_ADVERTISE "mDNS-Bekanntmachung" #define D_ESP_CHIP_ID "ESP Chip ID" #define D_FLASH_CHIP_ID "Flash Chip ID" -#define D_FLASH_CHIP_SIZE "Flash-Größe" -#define D_FREE_PROGRAM_SPACE "freier Programmspeicherplatz" +#define D_FLASH_CHIP_SIZE "Flash Größe" +#define D_FREE_PROGRAM_SPACE "Freier Programm Speicher" -#define D_UPGRADE_BY_WEBSERVER "Upgrade über Web-Server" +#define D_UPGRADE_BY_WEBSERVER "Update über Web-Server" #define D_OTA_URL "OTA-URL" -#define D_START_UPGRADE "Upgrade starten" -#define D_UPGRADE_BY_FILE_UPLOAD "Upgrade per Datei-Upload" +#define D_START_UPGRADE "Update starten" +#define D_UPGRADE_BY_FILE_UPLOAD "Update Datei hochladen" #define D_UPLOAD_STARTED "Upload gestartet" -#define D_UPGRADE_STARTED "Upgrade gestartet" +#define D_UPGRADE_STARTED "Update gestartet" #define D_UPLOAD_DONE "Upload abgeschlossen" #define D_UPLOAD_ERR_1 "keine Datei ausgewählt" #define D_UPLOAD_ERR_2 "ungenügend Speicherplatz" #define D_UPLOAD_ERR_3 "magic byte ist nicht 0xE9" -#define D_UPLOAD_ERR_4 "Flash-Größe des Programmes ist größer als die reale Flash-Größe" +#define D_UPLOAD_ERR_4 "Flash-Größe des Programmes ist größer als der reale Flashspeicher" #define D_UPLOAD_ERR_5 "Upload-buffer-Vergleich weicht ab" #define D_UPLOAD_ERR_6 "Upload fehlgeschlagen. Aktiviere logging 3" #define D_UPLOAD_ERR_7 "Upload abgebrochen" #define D_UPLOAD_ERR_8 "Datei ungültig" #define D_UPLOAD_ERR_9 "Datei zu groß" -#define D_UPLOAD_ERROR_CODE "Upload-Fehler-Code" +#define D_UPLOAD_ERROR_CODE "Upload Fehler Nummer" #define D_ENTER_COMMAND "Befehl eingeben" #define D_ENABLE_WEBLOG_FOR_RESPONSE "aktivere weblog 2 falls Reaktion erwartet" @@ -396,10 +396,10 @@ #define D_IRHVAC_MODE "MODUS" #define D_IRHVAC_FANSPEED "LÜFTERGESCHWINDIGKEIT" #define D_IRHVAC_TEMP "TEMPERATUR" -#define D_IRRECEIVED "IrReceived" +#define D_IRRECEIVED "IR empfangen" // xdrv_snfbridge.ino -#define D_RFRECEIVED "RfReceived" +#define D_RFRECEIVED "RF empfangen" #define D_START_LEARNING "starte Anlernen" #define D_SET_TO_DEFAULT "auf Standard zurücksetzen" #define D_DEFAULT_SENT "Standard gesendet" @@ -412,7 +412,7 @@ // xdrv_wemohue.ino #define D_MULTICAST_DISABLED "Multicast deaktiviert" #define D_MULTICAST_REJOINED "Multicast (wieder-)verbunden" -#define D_MULTICAST_JOIN_FAILED "Multicast-Verbinden fehlgeschlagen" +#define D_MULTICAST_JOIN_FAILED "Multicast Verbindung fehlgeschlagen" #define D_FAILED_TO_SEND_RESPONSE "Antwort senden fehlgeschlagen" #define D_WEMO "WeMo" @@ -464,14 +464,14 @@ #define D_SENSOR_I2C_SCL "I2C SCL" #define D_SENSOR_I2C_SDA "I2C SDA" #define D_SENSOR_WS2812 "WS2812" -#define D_SENSOR_IRSEND "IRsend" -#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_IRSEND "IRSend" +#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" -#define D_SENSOR_IRRECV "IRrecv" +#define D_SENSOR_IRRECV "IRRecv" #define D_SENSOR_SPI_CS "SPI CS" #define D_SENSOR_SPI_DC "SPI DC" #define D_SENSOR_BACKLIGHT "BLight" @@ -481,12 +481,12 @@ #define D_UNIT_HOUR "h" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" -#define D_UNIT_MICROSECOND "us" +#define D_UNIT_MICROSECOND "µs" #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_SECOND "sek" #define D_UNIT_SECTORS "Sektoren" #define D_UNIT_VOLT "V" #define D_UNIT_WATT "W" From d34c51cda32b3408e26da467454071efc8b81e9b Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Tue, 28 Nov 2017 23:04:00 +0100 Subject: [PATCH 02/23] fix missing space --- sonoff/language/de-DE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index c188df3ae..29bd8586d 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -173,7 +173,7 @@ #define D_SUCCESSFUL "erfolgreich" #define D_SWITCH "Schalter" #define D_SYNC "sync" -#define D_SYS "sys" // Sys log +#define D_SYS "Sys " // Sys log #define D_TEMPERATURE "Temperatur" #define D_TEMPERATURE_UNIT "TempUnit" #define D_TIME "Zeit" From 95e6002b51722f8bf1a34ca9ed914cf77ddeebcf Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Wed, 29 Nov 2017 00:08:26 +0100 Subject: [PATCH 03/23] fix translate fix --- sonoff/language/de-DE.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 29bd8586d..a236a6472 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -177,7 +177,7 @@ #define D_TEMPERATURE "Temperatur" #define D_TEMPERATURE_UNIT "TempUnit" #define D_TIME "Zeit" -#define D_TO "bis" +#define D_TO "zu" #define D_TODAY "heute" #define D_TOGGLE "An/Aus" #define D_TOPIC "topic" @@ -694,4 +694,4 @@ #define D_CMND_MAXENERGY "MaxEnergy" #define D_CMND_MAXENERGYSTART "MaxEnergyStart" -#endif // _LANGUAGE_DE_DE_H_ \ No newline at end of file +#endif // _LANGUAGE_DE_DE_H_ From 12bbfd962b0529d5d33bec995a15a1a16c0aef9e Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Wed, 13 Dec 2017 23:39:54 +0100 Subject: [PATCH 04/23] Add WeMo GetBinaryState --- sonoff/xdrv_wemohue.ino | 93 ++++++++++++++++++++++++++++++----------- 1 file changed, 69 insertions(+), 24 deletions(-) diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index 9fbb3cd35..ad339a382 100755 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -242,18 +242,18 @@ void PollUdp() const char WEMO_EVENTSERVICE_XML[] PROGMEM = "" - "" - "" - "SetBinaryState" - "" - "" - "" - "BinaryState" - "BinaryState" - "in" - "" - "" - "" + "" + "" + "SetBinaryState" + "" + "" + "" + "BinaryState" + "BinaryState" + "in" + "" + "" + "" "" "BinaryState" "Boolean" @@ -263,14 +263,43 @@ const char WEMO_EVENTSERVICE_XML[] PROGMEM = "level" "string" "0" - "" - "" + "" + "" + "" + "" + "GetBinaryState" + "" + "" + "" + "BinaryState" + "BinaryState" + "out" + "" + "" "" "\r\n" "\r\n"; +const char WEMO_SETSTATE_XML[] PROGMEM = +"" + "" + "" + "{x1" + "" + "" +"\r\n" +"\r\n"; +const char WEMO_GETSTATE_XML[] PROGMEM = +"" + "" + "" + "{x1" + "" + "" +"\r\n" +"\r\n"; const char WEMO_SETUP_XML[] PROGMEM = "" - "" + "" "" "urn:Belkin:device:controllee:1" "{x1" @@ -297,17 +326,34 @@ const char WEMO_SETUP_XML[] PROGMEM = void HandleUpnpEvent() { - AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT)); String request = WebServer->arg(0); - if (request.indexOf(F("State>1 0) { -// ExecuteCommandPower(1, 1); - ExecuteCommandPower(devices_present, 1); + AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT)); + //differentiate get and set state + if (request.indexOf(F("SetBinaryState")) > 0) { + String setstate_xml = FPSTR(WEMO_SETSTATE_XML); + if (request.indexOf(F("State>1 0) { + AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT " SET STATE 1")); + ExecuteCommandPower(devices_present, 1); + setstate_xml.replace("{x1", "1"); + } + else if (request.indexOf(F("State>0 0) { + AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT " SET STATE 0")); + ExecuteCommandPower(devices_present, 0); + setstate_xml.replace("{x1", "0"); + } + WebServer->send(200, FPSTR(HDR_CTYPE_XML), setstate_xml.c_str()); } - if (request.indexOf(F("State>0 0) { -// ExecuteCommandPower(1, 0); - ExecuteCommandPower(devices_present, 0); + else if(request.indexOf(F("GetBinaryState")) > 0){ + String getstate_xml = FPSTR(WEMO_GETSTATE_XML); + char svalue[80]; + /** TODO: can only return one device status for now in response, + * check how to response multi device status to echo + */ + snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, 1 -1)); + AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT " GET STATE")); + getstate_xml.replace("{x1", svalue); + WebServer->send(200, FPSTR(HDR_CTYPE_XML), getstate_xml.c_str()); } - WebServer->send(200, FPSTR(HDR_CTYPE_PLAIN), ""); } void HandleUpnpService() @@ -720,4 +766,3 @@ void HandleHueApi(String *path) } #endif // USE_WEBSERVER #endif // USE_EMULATION - From f2362af36f51ccfadbbe971f12dc1983215a51e6 Mon Sep 17 00:00:00 2001 From: Nils Sdun Date: Fri, 15 Dec 2017 13:13:53 +0100 Subject: [PATCH 05/23] save some bytes, merge set and get to one pattern --- sonoff/xdrv_wemohue.ino | 39 +++++++++++++++------------------------ 1 file changed, 15 insertions(+), 24 deletions(-) diff --git a/sonoff/xdrv_wemohue.ino b/sonoff/xdrv_wemohue.ino index ad339a382..f8dfb7cc8 100755 --- a/sonoff/xdrv_wemohue.ino +++ b/sonoff/xdrv_wemohue.ino @@ -279,21 +279,12 @@ const char WEMO_EVENTSERVICE_XML[] PROGMEM = "" "\r\n" "\r\n"; -const char WEMO_SETSTATE_XML[] PROGMEM = +const char WEMO_RESPONSE_STATE_XML[] PROGMEM = "" "" - "" - "{x1" - "" - "" -"\r\n" -"\r\n"; -const char WEMO_GETSTATE_XML[] PROGMEM = -"" - "" - "" - "{x1" - "" + "" + "{x2" + "" "" "\r\n" "\r\n"; @@ -326,33 +317,33 @@ const char WEMO_SETUP_XML[] PROGMEM = void HandleUpnpEvent() { - String request = WebServer->arg(0); AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT)); + String request = WebServer->arg(0); + String state_xml = FPSTR(WEMO_RESPONSE_STATE_XML); //differentiate get and set state if (request.indexOf(F("SetBinaryState")) > 0) { - String setstate_xml = FPSTR(WEMO_SETSTATE_XML); if (request.indexOf(F("State>1 0) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT " SET STATE 1")); ExecuteCommandPower(devices_present, 1); - setstate_xml.replace("{x1", "1"); + state_xml.replace("{x1", "Set"); + state_xml.replace("{x2", "1"); } else if (request.indexOf(F("State>0 0) { AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT " SET STATE 0")); ExecuteCommandPower(devices_present, 0); - setstate_xml.replace("{x1", "0"); + + state_xml.replace("{x1", "Set"); + state_xml.replace("{x2", "0"); } - WebServer->send(200, FPSTR(HDR_CTYPE_XML), setstate_xml.c_str()); + WebServer->send(200, FPSTR(HDR_CTYPE_XML), state_xml.c_str()); } else if(request.indexOf(F("GetBinaryState")) > 0){ - String getstate_xml = FPSTR(WEMO_GETSTATE_XML); char svalue[80]; - /** TODO: can only return one device status for now in response, - * check how to response multi device status to echo - */ snprintf_P(svalue, sizeof(svalue), PSTR("%d"), bitRead(power, 1 -1)); AddLog_P(LOG_LEVEL_DEBUG, S_LOG_HTTP, PSTR(D_WEMO_BASIC_EVENT " GET STATE")); - getstate_xml.replace("{x1", svalue); - WebServer->send(200, FPSTR(HDR_CTYPE_XML), getstate_xml.c_str()); + state_xml.replace("{x1", "Get"); + state_xml.replace("{x2", svalue); + WebServer->send(200, FPSTR(HDR_CTYPE_XML), state_xml.c_str()); } } From 25e3918ce3c0cc74f21d1dcd0ab4a7ac48e80674 Mon Sep 17 00:00:00 2001 From: Nils Sdun Date: Fri, 15 Dec 2017 13:31:38 +0100 Subject: [PATCH 06/23] ignore lib/readme --- .gitignore | 1 + 1 file changed, 1 insertion(+) diff --git a/.gitignore b/.gitignore index 5dac9f52f..f5681567e 100644 --- a/.gitignore +++ b/.gitignore @@ -2,3 +2,4 @@ .piolibdeps .clang_complete .gcc-flags.json +lib/readme.txt From a51bb39a5d18c0e5e35cea75d69322cc7e2e0701 Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Thu, 12 Apr 2018 22:56:08 +0200 Subject: [PATCH 07/23] igno --- .gitignore | 2 ++ 1 file changed, 2 insertions(+) diff --git a/.gitignore b/.gitignore index 01bb48119..3ac33def4 100644 --- a/.gitignore +++ b/.gitignore @@ -9,3 +9,5 @@ .clang_complete .gcc-flags.json lib/readme.txt +sonoff/user_config_override.h +sonoff/user_config_my.h From 5482ac9bfc5e756a09dea94864a8709f50638396 Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Mon, 27 Aug 2018 22:56:26 +0200 Subject: [PATCH 08/23] ignore --- .gitignore | 3 +++ 1 file changed, 3 insertions(+) diff --git a/.gitignore b/.gitignore index b6460347b..028a76667 100644 --- a/.gitignore +++ b/.gitignore @@ -12,3 +12,6 @@ build ## Visual Studio Code specific ###### .vscode +.vscode/.browse.c_cpp.db* +.vscode/c_cpp_properties.json +.vscode/launch.json From 259c638cb8d961fc16122789f1d796c0fde44ac7 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Sun, 28 Oct 2018 14:14:10 +0100 Subject: [PATCH 09/23] Update en-GB.h --- sonoff/language/en-GB.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/language/en-GB.h b/sonoff/language/en-GB.h index 925080d3d..48641d0ff 100644 --- a/sonoff/language/en-GB.h +++ b/sonoff/language/en-GB.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" From 12f17cc86a877e2edfdaa909ca04e217d832d77c Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Sun, 28 Oct 2018 14:17:01 +0100 Subject: [PATCH 10/23] Update de-DE.h --- sonoff/language/de-DE.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/language/de-DE.h b/sonoff/language/de-DE.h index 6a783a45b..0c2ab9f6a 100644 --- a/sonoff/language/de-DE.h +++ b/sonoff/language/de-DE.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "h" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" From 432c4df27aee16c1477711a819c8342dc02e5b62 Mon Sep 17 00:00:00 2001 From: Jason2866 Date: Sun, 28 Oct 2018 14:24:20 +0100 Subject: [PATCH 11/23] kmph to km/h MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit "SI, and hence the use of "km/h" (or "km h−1" or "km·h−1") has now been adopted around the world --- sonoff/language/bg-BG.h | 2 +- sonoff/language/el-GR.h | 3 ++- sonoff/language/es-AR.h | 2 +- sonoff/language/fr-FR.h | 2 +- sonoff/language/he-HE.h | 2 +- sonoff/language/hu-HU.h | 2 +- sonoff/language/it-IT.h | 2 +- sonoff/language/nl-NL.h | 2 +- sonoff/language/pl-PL.h | 2 +- sonoff/language/pt-BR.h | 2 +- sonoff/language/pt-PT.h | 2 +- sonoff/language/ru-RU.h | 2 +- sonoff/language/tr-TR.h | 2 +- sonoff/language/uk-UK.h | 2 +- sonoff/language/zh-CN.h | 2 +- sonoff/language/zh-TW.h | 2 +- 16 files changed, 17 insertions(+), 16 deletions(-) diff --git a/sonoff/language/bg-BG.h b/sonoff/language/bg-BG.h index 7e096f673..d91c66bda 100644 --- a/sonoff/language/bg-BG.h +++ b/sonoff/language/bg-BG.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "h" #define D_UNIT_KILOGRAM "kg" #define D_UNIT_INCREMENTS "inc" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/el-GR.h b/sonoff/language/el-GR.h index 937464699..c5a3db324 100644 --- a/sonoff/language/el-GR.h +++ b/sonoff/language/el-GR.h @@ -1,3 +1,4 @@ + /* el-GR.h - localization for Greek - Greece for Sonoff-Tasmota @@ -537,7 +538,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/es-AR.h b/sonoff/language/es-AR.h index d78c807da..a5d044985 100644 --- a/sonoff/language/es-AR.h +++ b/sonoff/language/es-AR.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/fr-FR.h b/sonoff/language/fr-FR.h index bb32c2d2e..0e37d9990 100644 --- a/sonoff/language/fr-FR.h +++ b/sonoff/language/fr-FR.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "h" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kΩ" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/he-HE.h b/sonoff/language/he-HE.h index d1aee3423..355fe8231 100644 --- a/sonoff/language/he-HE.h +++ b/sonoff/language/he-HE.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/hu-HU.h b/sonoff/language/hu-HU.h index 91b005e39..cbe52378d 100644 --- a/sonoff/language/hu-HU.h +++ b/sonoff/language/hu-HU.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "ó" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/it-IT.h b/sonoff/language/it-IT.h index 2ed03ca35..8449d250d 100644 --- a/sonoff/language/it-IT.h +++ b/sonoff/language/it-IT.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/nl-NL.h b/sonoff/language/nl-NL.h index ca7be61af..afaf9d08a 100644 --- a/sonoff/language/nl-NL.h +++ b/sonoff/language/nl-NL.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "h" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/pl-PL.h b/sonoff/language/pl-PL.h index 3fd26f29b..686f5cc76 100644 --- a/sonoff/language/pl-PL.h +++ b/sonoff/language/pl-PL.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Godz" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/pt-BR.h b/sonoff/language/pt-BR.h index dceadf085..ef5104fdb 100644 --- a/sonoff/language/pt-BR.h +++ b/sonoff/language/pt-BR.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "H" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/pt-PT.h b/sonoff/language/pt-PT.h index a7b9236ae..97750f38c 100644 --- a/sonoff/language/pt-PT.h +++ b/sonoff/language/pt-PT.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/ru-RU.h b/sonoff/language/ru-RU.h index fc2dc2892..28aa1d7f2 100644 --- a/sonoff/language/ru-RU.h +++ b/sonoff/language/ru-RU.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Ч" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "кОм" #define D_UNIT_KILOWATTHOUR "кВт" #define D_UNIT_LUX "лк" diff --git a/sonoff/language/tr-TR.h b/sonoff/language/tr-TR.h index ea3f10ce6..0588b5175 100755 --- a/sonoff/language/tr-TR.h +++ b/sonoff/language/tr-TR.h @@ -536,7 +536,7 @@ #define D_UNIT_HOUR "Hr" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "kOhm" #define D_UNIT_KILOWATTHOUR "kWh" #define D_UNIT_LUX "lx" diff --git a/sonoff/language/uk-UK.h b/sonoff/language/uk-UK.h index cf9d8bcf3..fc32479fc 100644 --- a/sonoff/language/uk-UK.h +++ b/sonoff/language/uk-UK.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "Г" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "кОм" #define D_UNIT_KILOWATTHOUR "кВт" #define D_UNIT_LUX "лк" diff --git a/sonoff/language/zh-CN.h b/sonoff/language/zh-CN.h index 15708dded..f4a19e324 100644 --- a/sonoff/language/zh-CN.h +++ b/sonoff/language/zh-CN.h @@ -536,7 +536,7 @@ #define D_UNIT_HOUR "时" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "千欧" #define D_UNIT_KILOWATTHOUR "千瓦时" #define D_UNIT_LUX "勒克斯" diff --git a/sonoff/language/zh-TW.h b/sonoff/language/zh-TW.h index 75c682396..61fa90d4d 100644 --- a/sonoff/language/zh-TW.h +++ b/sonoff/language/zh-TW.h @@ -537,7 +537,7 @@ #define D_UNIT_HOUR "時" #define D_UNIT_INCREMENTS "inc" #define D_UNIT_KILOGRAM "kg" -#define D_UNIT_KILOMETER_PER_HOUR "kmph" // or "km/h" +#define D_UNIT_KILOMETER_PER_HOUR "km/h" // or "km/h" #define D_UNIT_KILOOHM "千歐" #define D_UNIT_KILOWATTHOUR "千瓦時" #define D_UNIT_LUX "勒克斯" From 6119c43610a69b0959357877f1a9c991d9c59a7c Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 28 Oct 2018 16:16:18 +0100 Subject: [PATCH 12/23] Fix version --- sonoff/sonoff_version.h | 2 +- sonoff/xplg_wemohue.ino | 5 +++++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 2c70d6928..9befe342e 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020112 +#define VERSION 0x06020113 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/xplg_wemohue.ino b/sonoff/xplg_wemohue.ino index f8eff5ddc..8bd5e529c 100644 --- a/sonoff/xplg_wemohue.ino +++ b/sonoff/xplg_wemohue.ino @@ -809,6 +809,11 @@ void HandleHueApi(String *path) * user part and allow every caller as with Web or WeMo. * * (c) Heiko Krupp, 2017 + * + * Hue URL + * http://sonoff/api/username/lights/1/state with post data {"on":true,"hue":56100,"sat":254,"bri":254,"alert":"none","transitiontime":40} + * is converted by webserver to + * http://sonoff/api/username/lights/1/state with arg plain={"on":true,"hue":56100,"sat":254,"bri":254,"alert":"none","transitiontime":40} */ uint8_t args = 0; From 5c78561b07eccf766e144069e24d22c2d69a5ea0 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Sun, 28 Oct 2018 17:57:25 +0100 Subject: [PATCH 13/23] 6.2.1.20 Add mDNS delay option 6.2.1.20 20181028 * Add command SetOption35 0..255 (seconds) to delay mDNS initialization to control possible Wifi connect problems --- sonoff/_changelog.ino | 7 ++++-- sonoff/sonoff.h | 2 +- sonoff/sonoff.ino | 2 ++ sonoff/sonoff_version.h | 2 +- sonoff/support.ino | 53 +++++++++++++---------------------------- sonoff/xdrv_02_mqtt.ino | 37 +++++++++++++++++++++++++--- 6 files changed, 59 insertions(+), 44 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index b1417029e..aace62b7d 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,11 +1,14 @@ -/* 6.2.1.19 20181023 +/* 6.2.1.20 20181028 + * Add command SetOption35 0..255 (seconds) to delay mDNS initialization to control possible Wifi connect problems + * + * 6.2.1.19 20181023 * Fix header file execution order by renaming user_config.h to my_user_config.h * Fix invalid JSON floating point result from nan (Not a Number) and inf (Infinity) into null (#4147) * Fix rule mqtt#connected trigger when mqtt is disabled (#4149) * Initial release of RF transceiving using library RcSwitch (#2702) * Change default OTA Url to http://thehackbox.org/tasmota/release/sonoff.bin (#4170) * Add Tuya Software Serial to support additional Tuya configurations (#4178) - * Add sonoff-basic.bin without most sensors + * Add define USE_BASIC for selecting image sonoff-basic without most sensors * * 6.2.1.18 20181019 * Add more API callbacks and document API.md diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 70e0e9a3d..15d003cd1 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -202,7 +202,7 @@ enum ButtonStates { PRESSED, NOT_PRESSED }; enum Shortcuts { SC_CLEAR, SC_DEFAULT, SC_USER }; -enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MAX_PARAM8}; +enum SettingsParmaIndex {P_HOLD_TIME, P_MAX_POWER_RETRY, P_TUYA_DIMMER_ID, P_MDNS_DELAYED_START, P_MAX_PARAM8}; // Max is PARAM8_SIZE (18) enum DomoticzSensors {DZ_TEMP, DZ_TEMP_HUM, DZ_TEMP_HUM_BARO, DZ_POWER_ENERGY, DZ_ILLUMINANCE, DZ_COUNT, DZ_VOLTAGE, DZ_CURRENT, DZ_AIRQUALITY, DZ_MAX_SENSORS}; diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 153e55fb7..5eadb50a8 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -186,6 +186,7 @@ byte reset_web_log_flag = 0; // Reset web console log byte devices_present = 0; // Max number of devices supported byte seriallog_level; // Current copy of Settings.seriallog_level byte syslog_level; // Current copy of Settings.syslog_level +byte mdns_delayed_start = 0; // mDNS delayed start boolean latest_uptime_flag = true; // Signal latest uptime boolean pwm_present = false; // Any PWM channel configured with SetOption15 0 boolean mdns_begun = false; // mDNS active @@ -2580,6 +2581,7 @@ void setup() } baudrate = Settings.baudrate * 1200; + mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; seriallog_level = Settings.seriallog_level; seriallog_timer = SERIALLOG_TIMER; #ifndef USE_EMULATION diff --git a/sonoff/sonoff_version.h b/sonoff/sonoff_version.h index 9befe342e..4a1b9ac5d 100644 --- a/sonoff/sonoff_version.h +++ b/sonoff/sonoff_version.h @@ -20,7 +20,7 @@ #ifndef _SONOFF_VERSION_H_ #define _SONOFF_VERSION_H_ -#define VERSION 0x06020113 +#define VERSION 0x06020114 #define D_PROGRAMNAME "Sonoff-Tasmota" #define D_AUTHOR "Theo Arends" diff --git a/sonoff/support.ino b/sonoff/support.ino index 88545e211..67d55a8ab 100644 --- a/sonoff/support.ino +++ b/sonoff/support.ino @@ -715,7 +715,6 @@ boolean GetUsedInModule(byte val, uint8_t *arr) if (GPIO_RFRECV == val) { return true; } #endif - if ((val >= GPIO_REL1) && (val < GPIO_REL1 + MAX_RELAYS)) { offset = (GPIO_REL1_INV - GPIO_REL1); } @@ -1558,19 +1557,29 @@ void WifiCheck(uint8_t param) ota_state_flag = 3; } #endif // BE_MINIMAL + #ifdef USE_DISCOVERY if (!mdns_begun) { - mdns_begun = MDNS.begin(my_hostname); - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS "%s"), (mdns_begun) ? D_INITIALIZED : D_FAILED); - AddLog(LOG_LEVEL_INFO); + if (mdns_delayed_start) { + AddLog_P(LOG_LEVEL_INFO, PSTR(D_LOG_MDNS D_ATTEMPTING_CONNECTION)); + mdns_delayed_start--; + } else { + mdns_delayed_start = Settings.param[P_MDNS_DELAYED_START]; + mdns_begun = MDNS.begin(my_hostname); + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS "%s"), (mdns_begun) ? D_INITIALIZED : D_FAILED); + AddLog(LOG_LEVEL_INFO); + } } #endif // USE_DISCOVERY + #ifdef USE_WEBSERVER if (Settings.webserver) { StartWebserver(Settings.webserver, WiFi.localIP()); #ifdef USE_DISCOVERY #ifdef WEBSERVER_ADVERTISE - MDNS.addService("http", "tcp", WEB_PORT); + if (mdns_begun) { + MDNS.addService("http", "tcp", WEB_PORT); + } #endif // WEBSERVER_ADVERTISE #endif // USE_DISCOVERY } else { @@ -1580,12 +1589,14 @@ void WifiCheck(uint8_t param) if (Settings.flag2.emulation) { UdpConnect(); } #endif // USE_EMULATION #endif // USE_WEBSERVER + #ifdef USE_KNX if (!knx_started && Settings.flag.knx_enabled) { KNXStart(); knx_started = true; } #endif // USE_KNX + } else { WifiState(0); #if defined(USE_WEBSERVER) && defined(USE_EMULATION) @@ -1646,38 +1657,6 @@ void EspRestart() ESP.restart(); } -#ifdef USE_DISCOVERY -/*********************************************************************************************\ - * mDNS -\*********************************************************************************************/ - -#ifdef MQTT_HOST_DISCOVERY -boolean MdnsDiscoverMqttServer() -{ - if (!mdns_begun) { - return false; - } - - int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); - AddLog(LOG_LEVEL_INFO); - - if (n > 0) { - // Note: current strategy is to get the first MQTT service (even when many are found) - snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(0).toString().c_str()); - Settings.mqtt_port = MDNS.port(0); - - snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), - MDNS.hostname(0).c_str(), Settings.mqtt_host, Settings.mqtt_port); - AddLog(LOG_LEVEL_INFO); - } - - return n > 0; -} -#endif // MQTT_HOST_DISCOVERY -#endif // USE_DISCOVERY - /*********************************************************************************************\ * Basic I2C routines \*********************************************************************************************/ diff --git a/sonoff/xdrv_02_mqtt.ino b/sonoff/xdrv_02_mqtt.ino index bb1a86e13..ed24d31ed 100644 --- a/sonoff/xdrv_02_mqtt.ino +++ b/sonoff/xdrv_02_mqtt.ino @@ -197,6 +197,32 @@ void MqttLoop() /*********************************************************************************************/ +#ifdef USE_DISCOVERY +#ifdef MQTT_HOST_DISCOVERY +boolean MqttDiscoverServer() +{ + if (!mdns_begun) { return false; } + + int n = MDNS.queryService("mqtt", "tcp"); // Search for mqtt service + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_QUERY_DONE " %d"), n); + AddLog(LOG_LEVEL_INFO); + + if (n > 0) { + // Note: current strategy is to get the first MQTT service (even when many are found) + snprintf_P(Settings.mqtt_host, sizeof(Settings.mqtt_host), MDNS.IP(0).toString().c_str()); + Settings.mqtt_port = MDNS.port(0); + + snprintf_P(log_data, sizeof(log_data), PSTR(D_LOG_MDNS D_MQTT_SERVICE_FOUND " %s, " D_IP_ADDRESS " %s, " D_PORT " %d"), + MDNS.hostname(0).c_str(), Settings.mqtt_host, Settings.mqtt_port); + AddLog(LOG_LEVEL_INFO); + } + + return n > 0; +} +#endif // MQTT_HOST_DISCOVERY +#endif // USE_DISCOVERY + int MqttLibraryType() { return (int)MQTT_LIBRARY_TYPE; @@ -468,9 +494,7 @@ void MqttReconnect() #ifndef USE_MQTT_TLS #ifdef USE_DISCOVERY #ifdef MQTT_HOST_DISCOVERY - if (!strlen(Settings.mqtt_host)) { - MdnsDiscoverMqttServer(); - } + if (!strlen(Settings.mqtt_host) && !MqttDiscoverServer()) { return; } #endif // MQTT_HOST_DISCOVERY #endif // USE_DISCOVERY #endif // USE_MQTT_TLS @@ -539,6 +563,13 @@ void MqttCheck() if (!MqttIsConnected()) { global_state.mqtt_down = 1; if (!mqtt_retry_counter) { +#ifndef USE_MQTT_TLS +#ifdef USE_DISCOVERY +#ifdef MQTT_HOST_DISCOVERY + if (!strlen(Settings.mqtt_host) && !mdns_begun) { return; } +#endif // MQTT_HOST_DISCOVERY +#endif // USE_DISCOVERY +#endif // USE_MQTT_TLS MqttReconnect(); } else { mqtt_retry_counter--; From 925cd37bbe74671725556456b17d0a84e7ecd7e9 Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Sun, 28 Oct 2018 20:49:22 +0100 Subject: [PATCH 14/23] support multiple bmp/bme sensors --- sonoff/my_user_config.h | 1 + sonoff/xsns_09_bmp2x.ino | 623 +++++++++++++++++++++++++++++++++++++++ 2 files changed, 624 insertions(+) create mode 100644 sonoff/xsns_09_bmp2x.ino diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 81eb4e987..0360cb01b 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -282,6 +282,7 @@ #define USE_SHT // Enable SHT1X sensor (+1k4 code) #define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) + #define USE_BMP2X // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) // #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code) #define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code) // #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+1k5 code) diff --git a/sonoff/xsns_09_bmp2x.ino b/sonoff/xsns_09_bmp2x.ino new file mode 100644 index 000000000..962d6e31e --- /dev/null +++ b/sonoff/xsns_09_bmp2x.ino @@ -0,0 +1,623 @@ +/* + xsns_09_bmp.ino - BMP pressure, temperature, humidity and gas sensor support for Sonoff-Tasmota + + Copyright (C) 2018 Heiko Krupp and 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 . +*/ + +#ifdef USE_I2C +#ifdef USE_BMP2X +/*********************************************************************************************\ + * BMP085, BMP180, BMP280, BME280, BME680 - Pressure, Temperature, Humidity (BME280/BME680) and gas (BME680) + * + * Source: Heiko Krupp and Adafruit Industries + * + * I2C Address: 0x76 or 0x77 +\*********************************************************************************************/ + +#define BMP_ADDR1 0x77 +#define BMP_ADDR2 0x76 + +#define BMP180_CHIPID 0x55 +#define BMP280_CHIPID 0x58 +#define BME280_CHIPID 0x60 +#define BME680_CHIPID 0x61 + +#define BMP_REGISTER_CHIPID 0xD0 + +#define BMP2X_MAX_SENSORS 2 + +const char kBmpTypes[] PROGMEM = "BMP1802X|BMP2802X|BME2802X|BME6802X"; +uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 }; + +uint8_t bmp2x_count = 0; +struct BMP2xSTRUCT { + uint8_t bmp_address; // I2C bus address + char bmp_name[9]; // Sensor name - "BMPXXX2x" + uint8_t bmp_type = 0; + uint8_t bmp_model = 0; + + uint8_t bmp_valid = 0; + float bmp_temperature = 0.0; + float bmp_pressure = 0.0; + float bmp_humidity = 0.0; + #ifdef USE_BME680 + float bmp_gas_resistance = 0.0; + uint8_t bme680_state = 0; + #endif // USE_BME680 + + +} bmp2x_sensors[BMP2X_MAX_SENSORS]; + + +uint8_t bmp_type = 0; + +/*********************************************************************************************\ + * BMP085 and BME180 +\*********************************************************************************************/ + +#define BMP180_REG_CONTROL 0xF4 +#define BMP180_REG_RESULT 0xF6 +#define BMP180_TEMPERATURE 0x2E +#define BMP180_PRESSURE3 0xF4 // Max. oversampling -> OSS = 3 + +#define BMP180_AC1 0xAA +#define BMP180_AC2 0xAC +#define BMP180_AC3 0xAE +#define BMP180_AC4 0xB0 +#define BMP180_AC5 0xB2 +#define BMP180_AC6 0xB4 +#define BMP180_VB1 0xB6 +#define BMP180_VB2 0xB8 +#define BMP180_MB 0xBA +#define BMP180_MC 0xBC +#define BMP180_MD 0xBE + +#define BMP180_OSS 3 + +int16_t cal_ac1; +int16_t cal_ac2; +int16_t cal_ac3; +int16_t cal_b1; +int16_t cal_b2; +int16_t cal_mc; +int16_t cal_md; +uint16_t cal_ac4; +uint16_t cal_ac5; +uint16_t cal_ac6; + +boolean Bmp1802xCalibration(uint8_t bmp2x_idx) +{ + cal_ac1 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC1); + cal_ac2 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC2); + cal_ac3 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC3); + cal_ac4 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC4); + cal_ac5 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC5); + cal_ac6 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC6); + cal_b1 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_VB1); + cal_b2 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_VB2); + cal_mc = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_MC); + cal_md = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_MD); + + // Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF + if (!cal_ac1 | !cal_ac2 | !cal_ac3 | !cal_ac4 | !cal_ac5 | !cal_ac6 | !cal_b1 | !cal_b2 | !cal_mc | !cal_md) { + return false; + } + + if ((cal_ac1 == (int16_t)0xFFFF) | + (cal_ac2 == (int16_t)0xFFFF) | + (cal_ac3 == (int16_t)0xFFFF) | + (cal_ac4 == 0xFFFF) | + (cal_ac5 == 0xFFFF) | + (cal_ac6 == 0xFFFF) | + (cal_b1 == (int16_t)0xFFFF) | + (cal_b2 == (int16_t)0xFFFF) | + (cal_mc == (int16_t)0xFFFF) | + (cal_md == (int16_t)0xFFFF)) { + return false; + } + return true; +} + +void Bmp1802xRead(uint8_t bmp2x_idx) +{ + + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); + delay(5); // 5ms conversion time + int ut = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_RESULT); + int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; + int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md); + int32_t bmp180_b5 = xt1 + xt2; + bmp2x_sensors[bmp2x_idx].bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0; + + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution + delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution + uint32_t up = I2cRead24(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_RESULT); + up >>= (8 - BMP180_OSS); + + int32_t b6 = bmp180_b5 - 4000; + int32_t x1 = ((int32_t)cal_b2 * ((b6 * b6) >> 12)) >> 11; + int32_t x2 = ((int32_t)cal_ac2 * b6) >> 11; + int32_t x3 = x1 + x2; + int32_t b3 = ((((int32_t)cal_ac1 * 4 + x3) << BMP180_OSS) + 2) >> 2; + + x1 = ((int32_t)cal_ac3 * b6) >> 13; + x2 = ((int32_t)cal_b1 * ((b6 * b6) >> 12)) >> 16; + x3 = ((x1 + x2) + 2) >> 2; + uint32_t b4 = ((uint32_t)cal_ac4 * (uint32_t)(x3 + 32768)) >> 15; + uint32_t b7 = ((uint32_t)up - b3) * (uint32_t)(50000UL >> BMP180_OSS); + + int32_t p; + if (b7 < 0x80000000) { + p = (b7 * 2) / b4; + } + else { + p = (b7 / b4) * 2; + } + x1 = (p >> 8) * (p >> 8); + x1 = (x1 * 3038) >> 16; + x2 = (-7357 * p) >> 16; + p += ((x1 + x2 + (int32_t)3791) >> 4); + bmp2x_sensors[bmp2x_idx].bmp_pressure = (float)p / 100.0; // convert to mbar +} + +/*********************************************************************************************\ + * BMP280 and BME280 + * + * Programmer : BMP280/BME280 Datasheet and Adafruit with changes by Theo Arends +\*********************************************************************************************/ + +#define BME280_REGISTER_CONTROLHUMID 0xF2 +#define BME280_REGISTER_CONTROL 0xF4 +#define BME280_REGISTER_CONFIG 0xF5 +#define BME280_REGISTER_PRESSUREDATA 0xF7 +#define BME280_REGISTER_TEMPDATA 0xFA +#define BME280_REGISTER_HUMIDDATA 0xFD + +#define BME280_REGISTER_DIG_T1 0x88 +#define BME280_REGISTER_DIG_T2 0x8A +#define BME280_REGISTER_DIG_T3 0x8C +#define BME280_REGISTER_DIG_P1 0x8E +#define BME280_REGISTER_DIG_P2 0x90 +#define BME280_REGISTER_DIG_P3 0x92 +#define BME280_REGISTER_DIG_P4 0x94 +#define BME280_REGISTER_DIG_P5 0x96 +#define BME280_REGISTER_DIG_P6 0x98 +#define BME280_REGISTER_DIG_P7 0x9A +#define BME280_REGISTER_DIG_P8 0x9C +#define BME280_REGISTER_DIG_P9 0x9E +#define BME280_REGISTER_DIG_H1 0xA1 +#define BME280_REGISTER_DIG_H2 0xE1 +#define BME280_REGISTER_DIG_H3 0xE3 +#define BME280_REGISTER_DIG_H4 0xE4 +#define BME280_REGISTER_DIG_H5 0xE5 +#define BME280_REGISTER_DIG_H6 0xE7 + +struct BME280CALIBDATA +{ + uint16_t dig_T1; + int16_t dig_T2; + int16_t dig_T3; + uint16_t dig_P1; + int16_t dig_P2; + int16_t dig_P3; + int16_t dig_P4; + int16_t dig_P5; + int16_t dig_P6; + int16_t dig_P7; + int16_t dig_P8; + int16_t dig_P9; + uint8_t dig_H1; + int16_t dig_H2; + uint8_t dig_H3; + int16_t dig_H4; + int16_t dig_H5; + int8_t dig_H6; +} Bme280CalibrationData; + +boolean Bmx2802xCalibrate(uint8_t bmp2x_idx) +{ + // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; + + Bme280CalibrationData.dig_T1 = I2cRead16LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_T1); + Bme280CalibrationData.dig_T2 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_T2); + Bme280CalibrationData.dig_T3 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_T3); + Bme280CalibrationData.dig_P1 = I2cRead16LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P1); + Bme280CalibrationData.dig_P2 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P2); + Bme280CalibrationData.dig_P3 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P3); + Bme280CalibrationData.dig_P4 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P4); + Bme280CalibrationData.dig_P5 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P5); + Bme280CalibrationData.dig_P6 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P6); + Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P7); + Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P8); + Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P9); + if (BME280_CHIPID == bmp_type) { // #1051 + Bme280CalibrationData.dig_H1 = I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H1); + Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H2); + Bme280CalibrationData.dig_H3 = I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H3); + Bme280CalibrationData.dig_H4 = (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF); + Bme280CalibrationData.dig_H5 = (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H5) >> 4); + Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H6); + + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) + // Set before CONTROL_meas (DS 5.4.3) + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode + } else { + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit) + } + + return true; +} + +void Bme2802xRead(uint8_t bmp2x_idx) +{ + int32_t adc_T = I2cRead24(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_TEMPDATA); + adc_T >>= 4; + + int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; + int32_t vart2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) * + ((int32_t)Bme280CalibrationData.dig_T3)) >> 14; + int32_t t_fine = vart1 + vart2; + float T = (t_fine * 5 + 128) >> 8; + bmp2x_sensors[bmp2x_idx].bmp_temperature = T / 100.0; + + int32_t adc_P = I2cRead24(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_PRESSUREDATA); + adc_P >>= 4; + + int64_t var1 = ((int64_t)t_fine) - 128000; + int64_t var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6; + var2 = var2 + ((var1 * (int64_t)Bme280CalibrationData.dig_P5) << 17); + var2 = var2 + (((int64_t)Bme280CalibrationData.dig_P4) << 35); + var1 = ((var1 * var1 * (int64_t)Bme280CalibrationData.dig_P3) >> 8) + ((var1 * (int64_t)Bme280CalibrationData.dig_P2) << 12); + var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)Bme280CalibrationData.dig_P1) >> 33; + if (0 == var1) { + return; // avoid exception caused by division by zero + } + int64_t p = 1048576 - adc_P; + p = (((p << 31) - var2) * 3125) / var1; + var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; + var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19; + p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4); + bmp2x_sensors[bmp2x_idx].bmp_pressure = (float)p / 25600.0; + + if (BMP280_CHIPID == bmp2x_sensors[bmp2x_idx].bmp_type) { return; } + + int32_t adc_H = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_HUMIDDATA); + + int32_t v_x1_u32r = (t_fine - ((int32_t)76800)); + v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) - + (((int32_t)Bme280CalibrationData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * + (((((((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H6)) >> 10) * + (((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + + ((int32_t)2097152)) * ((int32_t)Bme280CalibrationData.dig_H2) + 8192) >> 14)); + v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * + ((int32_t)Bme280CalibrationData.dig_H1)) >> 4)); + v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; + v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; + float h = (v_x1_u32r >> 12); + bmp2x_sensors[bmp2x_idx].bmp_humidity = h / 1024.0; +} + +#ifdef USE_BME680 +/*********************************************************************************************\ + * BME680 support by Bosch https://github.com/BoschSensortec/BME680_driver +\*********************************************************************************************/ + +#include + +struct bme680_dev gas_sensor; + + + +static void BmeDelayMs(uint32_t ms) +{ + delay(ms); +} + +boolean Bme6802xInit(uint8_t bmp2x_idx) +{ + gas_sensor.dev_id = bmp2x_sensors[bmp2x_idx].bmp_address; + gas_sensor.intf = BME680_I2C_INTF; + gas_sensor.read = &I2cReadBuffer; + gas_sensor.write = &I2cWriteBuffer; + gas_sensor.delay_ms = BmeDelayMs; + /* amb_temp can be set to 25 prior to configuring the gas sensor + * or by performing a few temperature readings without operating the gas sensor. + */ + gas_sensor.amb_temp = 25; + + int8_t rslt = BME680_OK; + rslt = bme680_init(&gas_sensor); + if (rslt != BME680_OK) { return false; } + + /* Set the temperature, pressure and humidity settings */ + gas_sensor.tph_sett.os_hum = BME680_OS_2X; + gas_sensor.tph_sett.os_pres = BME680_OS_4X; + gas_sensor.tph_sett.os_temp = BME680_OS_8X; + gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3; + + /* Set the remaining gas sensor settings and link the heating profile */ + gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; + /* Create a ramp heat waveform in 3 steps */ + gas_sensor.gas_sett.heatr_temp = 320; /* degree Celsius */ + gas_sensor.gas_sett.heatr_dur = 150; /* milliseconds */ + + /* Select the power mode */ + /* Must be set before writing the sensor configuration */ + gas_sensor.power_mode = BME680_FORCED_MODE; + + /* Set the required sensor settings needed */ + uint8_t set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL; + + /* Set the desired sensor configuration */ + rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor); + if (rslt != BME680_OK) { return false; } + + bmp2x_sensors[bmp2x_idx].bme680_state = 0; + + return true; +} + +void Bme6802xRead(uint8_t bmp2x_idx) +{ + int8_t rslt = BME680_OK; + + if (BME680_CHIPID == bmp2x_sensors[bmp2x_idx].bmp_type) { + if (0 == bmp2x_sensors[bmp2x_idx].bme680_state) { + /* Trigger the next measurement if you would like to read data out continuously */ + rslt = bme680_set_sensor_mode(&gas_sensor); + if (rslt != BME680_OK) { return; } + + /* Get the total measurement duration so as to sleep or wait till the + * measurement is complete */ +// uint16_t meas_period; +// bme680_get_profile_dur(&meas_period, &gas_sensor); +// delay(meas_period); /* Delay till the measurement is ready */ // 183 mSec - we'll wait a second + + bmp2x_sensors[bmp2x_idx].bme680_state = 1; + } else { + bmp2x_sensors[bmp2x_idx].bme680_state = 0; + + struct bme680_field_data data; + rslt = bme680_get_sensor_data(&data, &gas_sensor); + if (rslt != BME680_OK) { return; } + + bmp2x_sensors[bmp2x_idx].bmp_temperature = data.temperature / 100.0; + bmp2x_sensors[bmp2x_idx].bmp_humidity = data.humidity / 1000.0; + bmp2x_sensors[bmp2x_idx].bmp_pressure = data.pressure / 100.0; + /* Avoid using measurements from an unstable heating setup */ + if (data.status & BME680_GASM_VALID_MSK) { + bmp2x_sensors[bmp2x_idx].bmp_gas_resistance = data.gas_resistance / 1000.0; + } else { + bmp2x_sensors[bmp2x_idx].bmp_gas_resistance = 0; + } + } + } + return; +} + +#endif // USE_BME680 + +/********************************************************************************************/ + +void Bmp2xDetect() +{ + //if (bmp_type) { return; } + if (bmp2x_count) return; + + //for (byte i = 0; i < sizeof(bmp_addresses); i++) { + for (byte i = 0; i < BMP2X_MAX_SENSORS; i++) { + + bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID); + if (bmp_type) { + bmp2x_sensors[bmp2x_count].bmp_address = bmp_addresses[i]; + bmp2x_sensors[bmp2x_count].bmp_type = bmp_type; + bmp2x_sensors[bmp2x_count].bmp_model = 0; + + boolean success = false; + + switch (bmp_type) { + case BMP180_CHIPID: + success = Bmp1802xCalibration(bmp2x_count); + break; + case BME280_CHIPID: + bmp2x_sensors[bmp2x_count].bmp_model++; // 2 + case BMP280_CHIPID: + bmp2x_sensors[bmp2x_count].bmp_model++; // 1 + success = Bmx2802xCalibrate(bmp2x_count); + break; + #ifdef USE_BME680 + case BME680_CHIPID: + bmp2x_sensors[bmp2x_count].bmp_model = 3; // 3 + success = Bme6802xInit(bmp2x_count); + break; + #endif // USE_BME680 + } + + if (success) { + GetTextIndexed(bmp2x_sensors[bmp2x_count].bmp_name, sizeof(bmp2x_sensors[bmp2x_count].bmp_name), i, kBmpTypes); + + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp2x_sensors[bmp2x_count].bmp_name, bmp2x_sensors[bmp2x_count].bmp_address); + AddLog(LOG_LEVEL_DEBUG); + bmp2x_count++; + } + else { + bmp_type = 0; + } + } + } + +} + +void Bmp2xRead(uint8_t bmp2x_idx) +{ + switch (bmp2x_sensors[bmp2x_idx].bmp_type) { + case BMP180_CHIPID: + Bmp1802xRead(bmp2x_idx); + break; + case BMP280_CHIPID: + case BME280_CHIPID: + Bme2802xRead(bmp2x_idx); + break; + #ifdef USE_BME680 + case BME680_CHIPID: + Bme6802xRead(bmp2x_idx); + break; + #endif // USE_BME680 + } + if (bmp2x_sensors[bmp2x_idx].bmp_temperature != 0.0) { + bmp2x_sensors[bmp2x_idx].bmp_temperature = ConvertTemp(bmp2x_sensors[bmp2x_idx].bmp_temperature); } + + //SetGlobalValues(bmp_temperature, bmp_humidity); +} + +void Bmp2xEverySecond() +{ + if (91 == (uptime %100)) { + // 1mS + Bmp2xDetect(); + } + else { + // 2mS + for (byte bmp2x_idx = 0; bmp2x_idx < bmp2x_count; bmp2x_idx++) { + Bmp2xRead(bmp2x_idx); + } + } +} + +void Bmp2xShow(boolean json) +{ + for (byte bmp2x_idx = 0; bmp2x_idx < bmp2x_count; bmp2x_idx++) { + + if (bmp2x_sensors[bmp2x_idx].bmp_type) { + float bmp_sealevel = 0.0; + char temperature[10]; + char pressure[10]; + char sea_pressure[10]; + char humidity[10]; + char name[14];// "BMXXXX2X-XX" + + if (bmp2x_sensors[bmp2x_idx].bmp_pressure != 0.0) { + bmp_sealevel = (bmp2x_sensors[bmp2x_idx].bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; + } + + snprintf_P(name, sizeof(name), PSTR("%s-%02X"), bmp2x_sensors[bmp2x_idx].bmp_name, bmp2x_sensors[bmp2x_idx].bmp_address); // "BMXXXX2X-0xXX" + + dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_temperature, Settings.flag2.temperature_resolution, temperature); + dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_pressure, Settings.flag2.pressure_resolution, pressure); + dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); + dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_humidity, Settings.flag2.humidity_resolution, humidity); + #ifdef USE_BME680 + char gas_resistance[10]; + dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_gas_resistance, 2, gas_resistance); + #endif // USE_BME680 + + if (json) { + char json_humidity[40]; + snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity); + char json_sealevel[40]; + snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); + #ifdef USE_BME680 + char json_gas[40]; + snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance); + + snprintf_P(mqtt_data, + sizeof(mqtt_data), + PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"), + mqtt_data, + name, + temperature, + (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", + pressure, (Settings.altitude != 0) ? json_sealevel : "", + (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) ? json_gas : "" + ); + + + #else + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"), + mqtt_data, name, temperature, (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : ""); + #endif // USE_BME680 + #ifdef USE_DOMOTICZ + if (0 == tele_period) { + DomoticzTempHumPressureSensor(temperature, humidity, pressure); + #ifdef USE_BME680 + if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp2x_sensors[bmp2x_idx].bmp_gas_resistance); } + #endif // USE_BME680 + } + #endif // USE_DOMOTICZ + + #ifdef USE_KNX + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, bmp2x_sensors[bmp2x_idx].bmp_temperature); + KnxSensor(KNX_HUMIDITY, bmp2x_sensors[bmp2x_idx].bmp_humidity); + } + #endif // USE_KNX + + #ifdef USE_WEBSERVER + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, name, temperature, TempUnit()); + if (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, name, humidity); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, name, pressure); + if (Settings.altitude != 0) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, name, sea_pressure); + } + #ifdef USE_BME680 + if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, name, gas_resistance); + } + #endif // USE_BME680 + #endif // USE_WEBSERVER + } + } + } +} + +/*********************************************************************************************\ + * Interface +\*********************************************************************************************/ + +#define XSNS_09 + +boolean Xsns09(byte function) +{ + boolean result = false; + + if (i2c_flg) { + switch (function) { + case FUNC_INIT: + Bmp2xDetect(); + break; + case FUNC_EVERY_SECOND: + Bmp2xEverySecond(); + break; + case FUNC_JSON_APPEND: + Bmp2xShow(1); + break; +#ifdef USE_WEBSERVER + case FUNC_WEB_APPEND: + Bmp2xShow(0); + break; +#endif // USE_WEBSERVER + } + } + return result; +} + +#endif // USE_BMP +#endif // USE_I2C From 2e08463ae85ef917a5550647144ec40694c05ecc Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Sun, 28 Oct 2018 20:52:48 +0100 Subject: [PATCH 15/23] dont be on by default --- sonoff/my_user_config.h | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 0360cb01b..187f8cb5e 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -281,8 +281,8 @@ #ifdef USE_I2C #define USE_SHT // Enable SHT1X sensor (+1k4 code) #define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) - #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) - #define USE_BMP2X // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address 0x76 or 0x77) (+4k code) + #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address either 0x76 or 0x77) (+4k code) +//#define USE_BMP2X // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address both 0x76 or 0x77) (+???k code) // #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code) #define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code) // #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+1k5 code) From bf6ac243e5c1cd181b3c7a878e6dff7cc5e3744d Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Sun, 28 Oct 2018 21:32:58 +0100 Subject: [PATCH 16/23] Update xsns_09_bmp2x.ino fix model detection --- sonoff/xsns_09_bmp2x.ino | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/sonoff/xsns_09_bmp2x.ino b/sonoff/xsns_09_bmp2x.ino index 962d6e31e..9b6684bbd 100644 --- a/sonoff/xsns_09_bmp2x.ino +++ b/sonoff/xsns_09_bmp2x.ino @@ -449,8 +449,7 @@ void Bmp2xDetect() } if (success) { - GetTextIndexed(bmp2x_sensors[bmp2x_count].bmp_name, sizeof(bmp2x_sensors[bmp2x_count].bmp_name), i, kBmpTypes); - + GetTextIndexed(bmp2x_sensors[bmp2x_count].bmp_name, sizeof(bmp2x_sensors[bmp2x_count].bmp_name), bmp2x_sensors[bmp2x_count].bmp_model, kBmpTypes); snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp2x_sensors[bmp2x_count].bmp_name, bmp2x_sensors[bmp2x_count].bmp_address); AddLog(LOG_LEVEL_DEBUG); bmp2x_count++; From 756bbc33cdd09d9c378e0c026715bd0fba1cb3bc Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Sun, 28 Oct 2018 21:59:34 +0100 Subject: [PATCH 17/23] typos --- sonoff/xsns_09_bmp2x.ino | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/sonoff/xsns_09_bmp2x.ino b/sonoff/xsns_09_bmp2x.ino index 9b6684bbd..8fcaa8874 100644 --- a/sonoff/xsns_09_bmp2x.ino +++ b/sonoff/xsns_09_bmp2x.ino @@ -1,5 +1,5 @@ /* - xsns_09_bmp.ino - BMP pressure, temperature, humidity and gas sensor support for Sonoff-Tasmota + xsns_09_bmp2x.ino - BMP pressure, temperature, humidity and gas sensor support for Sonoff-Tasmota Copyright (C) 2018 Heiko Krupp and Theo Arends @@ -43,7 +43,7 @@ const char kBmpTypes[] PROGMEM = "BMP1802X|BMP2802X|BME2802X|BME6802X"; uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 }; uint8_t bmp2x_count = 0; -struct BMP2xSTRUCT { +struct BMP2XSTRUCT { uint8_t bmp_address; // I2C bus address char bmp_name[9]; // Sensor name - "BMPXXX2x" uint8_t bmp_type = 0; From 82efaccc910bcf2f050199559cf016bf2c895200 Mon Sep 17 00:00:00 2001 From: reloxx13 Date: Sun, 28 Oct 2018 22:00:12 +0100 Subject: [PATCH 18/23] typo2 --- sonoff/xsns_09_bmp2x.ino | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/sonoff/xsns_09_bmp2x.ino b/sonoff/xsns_09_bmp2x.ino index 8fcaa8874..f0e95168c 100644 --- a/sonoff/xsns_09_bmp2x.ino +++ b/sonoff/xsns_09_bmp2x.ino @@ -618,5 +618,5 @@ boolean Xsns09(byte function) return result; } -#endif // USE_BMP +#endif // USE_BMP2X #endif // USE_I2C From ac00e6541a1a37192b50464517319ef41e090390 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Oct 2018 11:30:36 +0100 Subject: [PATCH 19/23] Quick fixes Quick fixes --- sonoff/xsns_09_bmp2x.ino | 76 ++++++++++++++++++++-------------------- 1 file changed, 38 insertions(+), 38 deletions(-) diff --git a/sonoff/xsns_09_bmp2x.ino b/sonoff/xsns_09_bmp2x.ino index f0e95168c..52561de3d 100644 --- a/sonoff/xsns_09_bmp2x.ino +++ b/sonoff/xsns_09_bmp2x.ino @@ -62,7 +62,7 @@ struct BMP2XSTRUCT { } bmp2x_sensors[BMP2X_MAX_SENSORS]; -uint8_t bmp_type = 0; +uint8_t bmp_type = 0; /*********************************************************************************************\ * BMP085 and BME180 @@ -133,7 +133,7 @@ boolean Bmp1802xCalibration(uint8_t bmp2x_idx) void Bmp1802xRead(uint8_t bmp2x_idx) { - + I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); delay(5); // 5ms conversion time int ut = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_RESULT); @@ -429,7 +429,7 @@ void Bmp2xDetect() bmp2x_sensors[bmp2x_count].bmp_model = 0; boolean success = false; - + switch (bmp_type) { case BMP180_CHIPID: success = Bmp1802xCalibration(bmp2x_count); @@ -447,7 +447,7 @@ void Bmp2xDetect() break; #endif // USE_BME680 } - + if (success) { GetTextIndexed(bmp2x_sensors[bmp2x_count].bmp_name, sizeof(bmp2x_sensors[bmp2x_count].bmp_name), bmp2x_sensors[bmp2x_count].bmp_model, kBmpTypes); snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp2x_sensors[bmp2x_count].bmp_name, bmp2x_sensors[bmp2x_count].bmp_address); @@ -459,7 +459,7 @@ void Bmp2xDetect() } } } - + } void Bmp2xRead(uint8_t bmp2x_idx) @@ -478,7 +478,7 @@ void Bmp2xRead(uint8_t bmp2x_idx) break; #endif // USE_BME680 } - if (bmp2x_sensors[bmp2x_idx].bmp_temperature != 0.0) { + if (bmp2x_sensors[bmp2x_idx].bmp_temperature != 0.0) { bmp2x_sensors[bmp2x_idx].bmp_temperature = ConvertTemp(bmp2x_sensors[bmp2x_idx].bmp_temperature); } //SetGlobalValues(bmp_temperature, bmp_humidity); @@ -501,14 +501,14 @@ void Bmp2xEverySecond() void Bmp2xShow(boolean json) { for (byte bmp2x_idx = 0; bmp2x_idx < bmp2x_count; bmp2x_idx++) { - + if (bmp2x_sensors[bmp2x_idx].bmp_type) { float bmp_sealevel = 0.0; char temperature[10]; char pressure[10]; char sea_pressure[10]; char humidity[10]; - char name[14];// "BMXXXX2X-XX" + char name[14]; // "BMXXXX2X-XX" if (bmp2x_sensors[bmp2x_idx].bmp_pressure != 0.0) { bmp_sealevel = (bmp2x_sensors[bmp2x_idx].bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; @@ -520,53 +520,53 @@ void Bmp2xShow(boolean json) dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_pressure, Settings.flag2.pressure_resolution, pressure); dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_humidity, Settings.flag2.humidity_resolution, humidity); - #ifdef USE_BME680 +#ifdef USE_BME680 char gas_resistance[10]; dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_gas_resistance, 2, gas_resistance); - #endif // USE_BME680 +#endif // USE_BME680 if (json) { char json_humidity[40]; snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity); char json_sealevel[40]; snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); - #ifdef USE_BME680 +#ifdef USE_BME680 char json_gas[40]; snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance); - - snprintf_P(mqtt_data, - sizeof(mqtt_data), + + snprintf_P(mqtt_data, + sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"), - mqtt_data, - name, - temperature, - (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", - pressure, (Settings.altitude != 0) ? json_sealevel : "", + mqtt_data, + name, + temperature, + (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", + pressure, + (Settings.altitude != 0) ? json_sealevel : "", (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) ? json_gas : "" ); - - - #else +#else snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"), mqtt_data, name, temperature, (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : ""); - #endif // USE_BME680 - #ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzTempHumPressureSensor(temperature, humidity, pressure); - #ifdef USE_BME680 - if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp2x_sensors[bmp2x_idx].bmp_gas_resistance); } - #endif // USE_BME680 - } - #endif // USE_DOMOTICZ +#endif // USE_BME680 - #ifdef USE_KNX +#ifdef USE_DOMOTICZ + if ((0 == tele_period) && (0 == bmp2x_idx)) { // We want the same first sensor to report to Domoticz in case a read is missed + DomoticzTempHumPressureSensor(temperature, humidity, pressure); +#ifdef USE_BME680 + if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp2x_sensors[bmp2x_idx].bmp_gas_resistance); } +#endif // USE_BME680 + } +#endif // USE_DOMOTICZ + +#ifdef USE_KNX if (0 == tele_period) { KnxSensor(KNX_TEMPERATURE, bmp2x_sensors[bmp2x_idx].bmp_temperature); KnxSensor(KNX_HUMIDITY, bmp2x_sensors[bmp2x_idx].bmp_humidity); } - #endif // USE_KNX +#endif // USE_KNX - #ifdef USE_WEBSERVER +#ifdef USE_WEBSERVER } else { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, name, temperature, TempUnit()); if (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) { @@ -576,14 +576,14 @@ void Bmp2xShow(boolean json) if (Settings.altitude != 0) { snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, name, sea_pressure); } - #ifdef USE_BME680 +#ifdef USE_BME680 if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, name, gas_resistance); } - #endif // USE_BME680 - #endif // USE_WEBSERVER +#endif // USE_BME680 +#endif // USE_WEBSERVER } - } + } } } From cc56677ba30adf89c05ea98af631a6484b5afba1 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Oct 2018 12:21:27 +0100 Subject: [PATCH 20/23] Add Gui Hostname display Add command SetOption53 0/1 to toggle gui display of Hostname and IP address --- sonoff/_changelog.ino | 1 + sonoff/settings.h | 2 +- sonoff/xdrv_01_webserver.ino | 22 +++++++++++++++++++++- 3 files changed, 23 insertions(+), 2 deletions(-) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index aace62b7d..8fa067b63 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,5 +1,6 @@ /* 6.2.1.20 20181028 * Add command SetOption35 0..255 (seconds) to delay mDNS initialization to control possible Wifi connect problems + * Add command SetOption53 0/1 to toggle gui display of Hostname and IP address * * 6.2.1.19 20181023 * Fix header file execution order by renaming user_config.h to my_user_config.h diff --git a/sonoff/settings.h b/sonoff/settings.h index 29aaf2121..8e0a22a2f 100644 --- a/sonoff/settings.h +++ b/sonoff/settings.h @@ -66,7 +66,7 @@ typedef union { // Restricted by MISRA-C Rule 18.4 bu uint32_t timers_enable : 1; // bit 0 (v6.1.1b) uint32_t user_esp8285_enable : 1; // bit 1 (v6.1.1.14) uint32_t time_append_timezone : 1; // bit 2 (v6.2.1.2) - uint32_t spare03 : 1; + uint32_t gui_hostname_ip : 1; // bit 3 (v6.2.1.20) uint32_t spare04 : 1; uint32_t spare05 : 1; uint32_t spare06 : 1; diff --git a/sonoff/xdrv_01_webserver.ino b/sonoff/xdrv_01_webserver.ino index 3cb2b31cb..261510924 100644 --- a/sonoff/xdrv_01_webserver.ino +++ b/sonoff/xdrv_01_webserver.ino @@ -119,7 +119,7 @@ const char HTTP_HEAD_STYLE[] PROGMEM = #else "

{ha " D_MODULE "

" #endif - "

{h}

"; + "

{h}

{j}"; const char HTTP_SCRIPT_CONSOL[] PROGMEM = "var sn=0;" // Scroll position "var id=0;" // Get most of weblog initially @@ -453,6 +453,25 @@ void ShowPage(String &page, bool auth) page.replace(F("{a}"), String(Settings.web_refresh)); page.replace(F("{ha"), my_module.name); page.replace(F("{h}"), Settings.friendlyname[0]); + + String info = ""; + if (Settings.flag3.gui_hostname_ip) { + uint8_t more_ips = 0; + info += F("

"); info += my_hostname; + if (mdns_begun) { info += F(".local"); } + info += F(" ("); + if (static_cast(WiFi.localIP()) != 0) { + info += WiFi.localIP().toString(); + more_ips++; + } + if (static_cast(WiFi.softAPIP()) != 0) { + if (more_ips) { info += F(", "); } + info += WiFi.softAPIP().toString(); + } + info += F(")

"); + } + page.replace(F("{j}"), info); + if (HTTP_MANAGER == webserver_state) { if (WifiConfigCounter()) { page.replace(F(""), F("")); @@ -1241,6 +1260,7 @@ void HandleInformation() func += F("}1" D_AP); func += String(Settings.sta_active +1); func += F(" " D_SSID " (" D_RSSI ")}2"); func += Settings.sta_ssid[Settings.sta_active]; func += F(" ("); func += WifiGetRssiAsQuality(WiFi.RSSI()); func += F("%)"); func += F("}1" D_HOSTNAME "}2"); func += my_hostname; + if (mdns_begun) { func += F(".local"); } if (static_cast(WiFi.localIP()) != 0) { func += F("}1" D_IP_ADDRESS "}2"); func += WiFi.localIP().toString(); func += F("}1" D_GATEWAY "}2"); func += IPAddress(Settings.ip_address[1]).toString(); From 6b86c473d96b313be380169736aaad2bcd8b9519 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Oct 2018 12:38:44 +0100 Subject: [PATCH 21/23] Add token %hostname% Add token %hostname% to command FullTopic (#3018) --- sonoff/_changelog.ino | 1 + sonoff/sonoff.h | 1 + sonoff/sonoff.ino | 1 + 3 files changed, 3 insertions(+) diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 8fa067b63..2c2753edd 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,6 +1,7 @@ /* 6.2.1.20 20181028 * Add command SetOption35 0..255 (seconds) to delay mDNS initialization to control possible Wifi connect problems * Add command SetOption53 0/1 to toggle gui display of Hostname and IP address + * Add token %hostname% to command FullTopic (#3018) * * 6.2.1.19 20181023 * Fix header file execution order by renaming user_config.h to my_user_config.h diff --git a/sonoff/sonoff.h b/sonoff/sonoff.h index 15d003cd1..ebc2ddb8a 100644 --- a/sonoff/sonoff.h +++ b/sonoff/sonoff.h @@ -60,6 +60,7 @@ typedef unsigned long power_t; // Power (Relay) type #define MQTT_TOKEN_PREFIX "%prefix%" // To be substituted by mqtt_prefix[x] #define MQTT_TOKEN_TOPIC "%topic%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic +#define MQTT_TOKEN_HOSTNAME "%hostname%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic #define MQTT_TOKEN_ID "%id%" // To be substituted by mqtt_topic, mqtt_grptopic, mqtt_buttontopic, mqtt_switchtopic #define WIFI_HOSTNAME "%s-%04d" // Expands to - diff --git a/sonoff/sonoff.ino b/sonoff/sonoff.ino index 5eadb50a8..2258ab240 100755 --- a/sonoff/sonoff.ino +++ b/sonoff/sonoff.ino @@ -279,6 +279,7 @@ void GetTopic_P(char *stopic, byte prefix, char *topic, const char* subtopic) } fulltopic.replace(F(MQTT_TOKEN_PREFIX), Settings.mqtt_prefix[prefix]); fulltopic.replace(F(MQTT_TOKEN_TOPIC), topic); + fulltopic.replace(F(MQTT_TOKEN_HOSTNAME), my_hostname); String token_id = WiFi.macAddress(); token_id.replace(":", ""); fulltopic.replace(F(MQTT_TOKEN_ID), token_id); From 9d981d83e4dd01376f0b20ac5408bc7470c11600 Mon Sep 17 00:00:00 2001 From: Theo Arends <11044339+arendst@users.noreply.github.com> Date: Mon, 29 Oct 2018 15:46:03 +0100 Subject: [PATCH 22/23] Add support for two BMP/BME Add support for two BMP/BME sensors (#4195) --- sonoff/_changelog.ino | 3 +- sonoff/my_user_config.h | 3 +- sonoff/xsns_09_bmp.ino | 391 ++++++++++++------------ sonoff/xsns_09_bmp2x.ino | 622 --------------------------------------- 4 files changed, 212 insertions(+), 807 deletions(-) delete mode 100644 sonoff/xsns_09_bmp2x.ino diff --git a/sonoff/_changelog.ino b/sonoff/_changelog.ino index 2c2753edd..7bf6d8aba 100644 --- a/sonoff/_changelog.ino +++ b/sonoff/_changelog.ino @@ -1,7 +1,8 @@ /* 6.2.1.20 20181028 * Add command SetOption35 0..255 (seconds) to delay mDNS initialization to control possible Wifi connect problems - * Add command SetOption53 0/1 to toggle gui display of Hostname and IP address + * Add command SetOption53 0/1 to toggle gui display of Hostname and IP address (#1006, #2091) * Add token %hostname% to command FullTopic (#3018) + * Add support for two BMP/BME sensors (#4195) * * 6.2.1.19 20181023 * Fix header file execution order by renaming user_config.h to my_user_config.h diff --git a/sonoff/my_user_config.h b/sonoff/my_user_config.h index 187f8cb5e..5b721af2a 100644 --- a/sonoff/my_user_config.h +++ b/sonoff/my_user_config.h @@ -281,8 +281,7 @@ #ifdef USE_I2C #define USE_SHT // Enable SHT1X sensor (+1k4 code) #define USE_HTU // Enable HTU21/SI7013/SI7020/SI7021 sensor (I2C address 0x40) (+1k5 code) - #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address either 0x76 or 0x77) (+4k code) -//#define USE_BMP2X // Enable BMP085/BMP180/BMP280/BME280 sensor (I2C address both 0x76 or 0x77) (+???k code) + #define USE_BMP // Enable BMP085/BMP180/BMP280/BME280 sensors (I2C addresses 0x76 and 0x77) (+4k4 code) // #define USE_BME680 // Enable support for BME680 sensor using Bosch BME680 library (+4k code) #define USE_BH1750 // Enable BH1750 sensor (I2C address 0x23 or 0x5C) (+0k5 code) // #define USE_VEML6070 // Enable VEML6070 sensor (I2C addresses 0x38 and 0x39) (+1k5 code) diff --git a/sonoff/xsns_09_bmp.ino b/sonoff/xsns_09_bmp.ino index 8a50b8ae6..781b85f20 100755 --- a/sonoff/xsns_09_bmp.ino +++ b/sonoff/xsns_09_bmp.ino @@ -27,8 +27,8 @@ * I2C Address: 0x76 or 0x77 \*********************************************************************************************/ -#define BMP_ADDR1 0x77 -#define BMP_ADDR2 0x76 +#define BMP_ADDR1 0x76 +#define BMP_ADDR2 0x77 #define BMP180_CHIPID 0x55 #define BMP280_CHIPID 0x58 @@ -37,18 +37,27 @@ #define BMP_REGISTER_CHIPID 0xD0 +#define BMP_MAX_SENSORS 2 + const char kBmpTypes[] PROGMEM = "BMP180|BMP280|BME280|BME680"; - -uint8_t bmp_address; uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 }; -uint8_t bmp_type = 0; -uint8_t bmp_model = 0; -char bmp_name[7]; +uint8_t bmp_count = 0; -uint8_t bmp_valid = 0; -float bmp_temperature = 0.0; -float bmp_pressure = 0.0; -float bmp_humidity = 0.0; +struct BMPSTRUCT { + uint8_t bmp_address; // I2C bus address + char bmp_name[7]; // Sensor name - "BMPXXX" + uint8_t bmp_type = 0; + uint8_t bmp_model = 0; + + uint8_t bmp_valid = 0; +#ifdef USE_BME680 + uint8_t bme680_state = 0; + float bmp_gas_resistance = 0.0; +#endif // USE_BME680 + float bmp_temperature = 0.0; + float bmp_pressure = 0.0; + float bmp_humidity = 0.0; +} bmp_sensors[BMP_MAX_SENSORS]; /*********************************************************************************************\ * BMP085 and BME180 @@ -84,18 +93,18 @@ uint16_t cal_ac4; uint16_t cal_ac5; uint16_t cal_ac6; -boolean Bmp180Calibration() +boolean Bmp1802xCalibration(uint8_t bmp_idx) { - cal_ac1 = I2cRead16(bmp_address, BMP180_AC1); - cal_ac2 = I2cRead16(bmp_address, BMP180_AC2); - cal_ac3 = I2cRead16(bmp_address, BMP180_AC3); - cal_ac4 = I2cRead16(bmp_address, BMP180_AC4); - cal_ac5 = I2cRead16(bmp_address, BMP180_AC5); - cal_ac6 = I2cRead16(bmp_address, BMP180_AC6); - cal_b1 = I2cRead16(bmp_address, BMP180_VB1); - cal_b2 = I2cRead16(bmp_address, BMP180_VB2); - cal_mc = I2cRead16(bmp_address, BMP180_MC); - cal_md = I2cRead16(bmp_address, BMP180_MD); + cal_ac1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC1); + cal_ac2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC2); + cal_ac3 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC3); + cal_ac4 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC4); + cal_ac5 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC5); + cal_ac6 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_AC6); + cal_b1 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB1); + cal_b2 = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_VB2); + cal_mc = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MC); + cal_md = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_MD); // Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF if (!cal_ac1 | !cal_ac2 | !cal_ac3 | !cal_ac4 | !cal_ac5 | !cal_ac6 | !cal_b1 | !cal_b2 | !cal_mc | !cal_md) { @@ -117,19 +126,20 @@ boolean Bmp180Calibration() return true; } -void Bmp180Read() +void Bmp1802xRead(uint8_t bmp_idx) { - I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); + + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); delay(5); // 5ms conversion time - int ut = I2cRead16(bmp_address, BMP180_REG_RESULT); + int ut = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT); int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md); int32_t bmp180_b5 = xt1 + xt2; - bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0; + bmp_sensors[bmp_idx].bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0; - I2cWrite8(bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution - uint32_t up = I2cRead24(bmp_address, BMP180_REG_RESULT); + uint32_t up = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BMP180_REG_RESULT); up >>= (8 - BMP180_OSS); int32_t b6 = bmp180_b5 - 4000; @@ -155,7 +165,7 @@ void Bmp180Read() x1 = (x1 * 3038) >> 16; x2 = (-7357 * p) >> 16; p += ((x1 + x2 + (int32_t)3791) >> 4); - bmp_pressure = (float)p / 100.0; // convert to mbar + bmp_sensors[bmp_idx].bmp_pressure = (float)p / 100.0; // convert to mbar } /*********************************************************************************************\ @@ -212,45 +222,45 @@ struct BME280CALIBDATA int8_t dig_H6; } Bme280CalibrationData; -boolean Bmx280Calibrate() +boolean Bmx2802xCalibrate(uint8_t bmp_idx) { // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; - Bme280CalibrationData.dig_T1 = I2cRead16LE(bmp_address, BME280_REGISTER_DIG_T1); - Bme280CalibrationData.dig_T2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_T2); - Bme280CalibrationData.dig_T3 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_T3); - Bme280CalibrationData.dig_P1 = I2cRead16LE(bmp_address, BME280_REGISTER_DIG_P1); - Bme280CalibrationData.dig_P2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P2); - Bme280CalibrationData.dig_P3 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P3); - Bme280CalibrationData.dig_P4 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P4); - Bme280CalibrationData.dig_P5 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P5); - Bme280CalibrationData.dig_P6 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P6); - Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P7); - Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P8); - Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_P9); - if (BME280_CHIPID == bmp_type) { // #1051 - Bme280CalibrationData.dig_H1 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H1); - Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp_address, BME280_REGISTER_DIG_H2); - Bme280CalibrationData.dig_H3 = I2cRead8(bmp_address, BME280_REGISTER_DIG_H3); - Bme280CalibrationData.dig_H4 = (I2cRead8(bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF); - Bme280CalibrationData.dig_H5 = (I2cRead8(bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp_address, BME280_REGISTER_DIG_H5) >> 4); - Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp_address, BME280_REGISTER_DIG_H6); + Bme280CalibrationData.dig_T1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T1); + Bme280CalibrationData.dig_T2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T2); + Bme280CalibrationData.dig_T3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_T3); + Bme280CalibrationData.dig_P1 = I2cRead16LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P1); + Bme280CalibrationData.dig_P2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P2); + Bme280CalibrationData.dig_P3 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P3); + Bme280CalibrationData.dig_P4 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P4); + Bme280CalibrationData.dig_P5 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P5); + Bme280CalibrationData.dig_P6 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P6); + Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P7); + Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P8); + Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_P9); + if (BME280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { // #1051 + Bme280CalibrationData.dig_H1 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H1); + Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H2); + Bme280CalibrationData.dig_H3 = I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H3); + Bme280CalibrationData.dig_H4 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF); + Bme280CalibrationData.dig_H5 = (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H5) >> 4); + Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_DIG_H6); - I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) // Set before CONTROL_meas (DS 5.4.3) - I2cWrite8(bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling - I2cWrite8(bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off - I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode } else { - I2cWrite8(bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit) + I2cWrite8(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit) } return true; } -void Bme280Read(void) +void Bme2802xRead(uint8_t bmp_idx) { - int32_t adc_T = I2cRead24(bmp_address, BME280_REGISTER_TEMPDATA); + int32_t adc_T = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_TEMPDATA); adc_T >>= 4; int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; @@ -258,9 +268,9 @@ void Bme280Read(void) ((int32_t)Bme280CalibrationData.dig_T3)) >> 14; int32_t t_fine = vart1 + vart2; float T = (t_fine * 5 + 128) >> 8; - bmp_temperature = T / 100.0; + bmp_sensors[bmp_idx].bmp_temperature = T / 100.0; - int32_t adc_P = I2cRead24(bmp_address, BME280_REGISTER_PRESSUREDATA); + int32_t adc_P = I2cRead24(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_PRESSUREDATA); adc_P >>= 4; int64_t var1 = ((int64_t)t_fine) - 128000; @@ -277,11 +287,11 @@ void Bme280Read(void) var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19; p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4); - bmp_pressure = (float)p / 25600.0; + bmp_sensors[bmp_idx].bmp_pressure = (float)p / 25600.0; - if (BMP280_CHIPID == bmp_type) { return; } + if (BMP280_CHIPID == bmp_sensors[bmp_idx].bmp_type) { return; } - int32_t adc_H = I2cRead16(bmp_address, BME280_REGISTER_HUMIDDATA); + int32_t adc_H = I2cRead16(bmp_sensors[bmp_idx].bmp_address, BME280_REGISTER_HUMIDDATA); int32_t v_x1_u32r = (t_fine - ((int32_t)76800)); v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) - @@ -294,7 +304,7 @@ void Bme280Read(void) v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; float h = (v_x1_u32r >> 12); - bmp_humidity = h / 1024.0; + bmp_sensors[bmp_idx].bmp_humidity = h / 1024.0; } #ifdef USE_BME680 @@ -306,17 +316,14 @@ void Bme280Read(void) struct bme680_dev gas_sensor; -float bmp_gas_resistance = 0.0; -uint8_t bme680_state = 0; - static void BmeDelayMs(uint32_t ms) { delay(ms); } -boolean Bme680Init() +boolean Bme6802xInit(uint8_t bmp_idx) { - gas_sensor.dev_id = bmp_address; + gas_sensor.dev_id = bmp_sensors[bmp_idx].bmp_address; gas_sensor.intf = BME680_I2C_INTF; gas_sensor.read = &I2cReadBuffer; gas_sensor.write = &I2cWriteBuffer; @@ -353,17 +360,17 @@ boolean Bme680Init() rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor); if (rslt != BME680_OK) { return false; } - bme680_state = 0; + bmp_sensors[bmp_idx].bme680_state = 0; return true; } -void Bme680Read() +void Bme6802xRead(uint8_t bmp_idx) { int8_t rslt = BME680_OK; - if (BME680_CHIPID == bmp_type) { - if (0 == bme680_state) { + if (BME680_CHIPID == bmp_sensors[bmp_idx].bmp_type) { + if (0 == bmp_sensors[bmp_idx].bme680_state) { /* Trigger the next measurement if you would like to read data out continuously */ rslt = bme680_set_sensor_mode(&gas_sensor); if (rslt != BME680_OK) { return; } @@ -374,22 +381,22 @@ void Bme680Read() // bme680_get_profile_dur(&meas_period, &gas_sensor); // delay(meas_period); /* Delay till the measurement is ready */ // 183 mSec - we'll wait a second - bme680_state = 1; + bmp_sensors[bmp_idx].bme680_state = 1; } else { - bme680_state = 0; + bmp_sensors[bmp_idx].bme680_state = 0; struct bme680_field_data data; rslt = bme680_get_sensor_data(&data, &gas_sensor); if (rslt != BME680_OK) { return; } - bmp_temperature = data.temperature / 100.0; - bmp_humidity = data.humidity / 1000.0; - bmp_pressure = data.pressure / 100.0; + bmp_sensors[bmp_idx].bmp_temperature = data.temperature / 100.0; + bmp_sensors[bmp_idx].bmp_humidity = data.humidity / 1000.0; + bmp_sensors[bmp_idx].bmp_pressure = data.pressure / 100.0; /* Avoid using measurements from an unstable heating setup */ if (data.status & BME680_GASM_VALID_MSK) { - bmp_gas_resistance = data.gas_resistance / 1000.0; + bmp_sensors[bmp_idx].bmp_gas_resistance = data.gas_resistance / 1000.0; } else { - bmp_gas_resistance = 0; + bmp_sensors[bmp_idx].bmp_gas_resistance = 0; } } } @@ -402,65 +409,66 @@ void Bme680Read() void BmpDetect() { - if (bmp_type) { return; } + if (bmp_count) return; - for (byte i = 0; i < sizeof(bmp_addresses); i++) { - bmp_address = bmp_addresses[i]; - bmp_type = I2cRead8(bmp_address, BMP_REGISTER_CHIPID); + for (byte i = 0; i < BMP_MAX_SENSORS; i++) { + uint8_t bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID); if (bmp_type) { - break; - } - } - if (bmp_type) { - bmp_model = 0; - boolean success = false; - switch (bmp_type) { - case BMP180_CHIPID: - success = Bmp180Calibration(); - break; - case BME280_CHIPID: - bmp_model++; // 2 - case BMP280_CHIPID: - bmp_model++; // 1 - success = Bmx280Calibrate(); - break; -#ifdef USE_BME680 - case BME680_CHIPID: - bmp_model = 3; // 3 - success = Bme680Init(); - break; -#endif // USE_BME680 - } - if (success) { - GetTextIndexed(bmp_name, sizeof(bmp_name), bmp_model, kBmpTypes); - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_name, bmp_address); - AddLog(LOG_LEVEL_DEBUG); - } - else { - bmp_type = 0; + bmp_sensors[bmp_count].bmp_address = bmp_addresses[i]; + bmp_sensors[bmp_count].bmp_type = bmp_type; + bmp_sensors[bmp_count].bmp_model = 0; + + boolean success = false; + switch (bmp_type) { + case BMP180_CHIPID: + success = Bmp1802xCalibration(bmp_count); + break; + case BME280_CHIPID: + bmp_sensors[bmp_count].bmp_model++; // 2 + case BMP280_CHIPID: + bmp_sensors[bmp_count].bmp_model++; // 1 + success = Bmx2802xCalibrate(bmp_count); + break; + #ifdef USE_BME680 + case BME680_CHIPID: + bmp_sensors[bmp_count].bmp_model = 3; // 3 + success = Bme6802xInit(bmp_count); + break; + #endif // USE_BME680 + } + if (success) { + GetTextIndexed(bmp_sensors[bmp_count].bmp_name, sizeof(bmp_sensors[bmp_count].bmp_name), bmp_sensors[bmp_count].bmp_model, kBmpTypes); + snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp_sensors[bmp_count].bmp_name, bmp_sensors[bmp_count].bmp_address); + AddLog(LOG_LEVEL_DEBUG); + bmp_count++; + } } } } void BmpRead() { - switch (bmp_type) { - case BMP180_CHIPID: - Bmp180Read(); - break; - case BMP280_CHIPID: - case BME280_CHIPID: - Bme280Read(); - break; -#ifdef USE_BME680 - case BME680_CHIPID: - Bme680Read(); - break; -#endif // USE_BME680 + for (byte bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) { + switch (bmp_sensors[bmp_idx].bmp_type) { + case BMP180_CHIPID: + Bmp1802xRead(bmp_idx); + break; + case BMP280_CHIPID: + case BME280_CHIPID: + Bme2802xRead(bmp_idx); + break; + #ifdef USE_BME680 + case BME680_CHIPID: + Bme6802xRead(bmp_idx); + break; + #endif // USE_BME680 + } + if (bmp_sensors[bmp_idx].bmp_temperature != 0.0) { + bmp_sensors[bmp_idx].bmp_temperature = ConvertTemp(bmp_sensors[bmp_idx].bmp_temperature); + } } - if (bmp_temperature != 0.0) { bmp_temperature = ConvertTemp(bmp_temperature); } - SetGlobalValues(bmp_temperature, bmp_humidity); + SetGlobalValues(bmp_sensors[0].bmp_temperature, bmp_sensors[0].bmp_humidity); } void BmpEverySecond() @@ -477,72 +485,91 @@ void BmpEverySecond() void BmpShow(boolean json) { - if (bmp_type) { - float bmp_sealevel = 0.0; - char temperature[10]; - char pressure[10]; - char sea_pressure[10]; - char humidity[10]; + for (byte bmp_idx = 0; bmp_idx < bmp_count; bmp_idx++) { + if (bmp_sensors[bmp_idx].bmp_type) { + float bmp_sealevel = 0.0; + char temperature[10]; + char pressure[10]; + char sea_pressure[10]; + char humidity[10]; + char name[10]; - if (bmp_pressure != 0.0) { - bmp_sealevel = (bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; - } - - dtostrfd(bmp_temperature, Settings.flag2.temperature_resolution, temperature); - dtostrfd(bmp_pressure, Settings.flag2.pressure_resolution, pressure); - dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); - dtostrfd(bmp_humidity, Settings.flag2.humidity_resolution, humidity); -#ifdef USE_BME680 - char gas_resistance[10]; - dtostrfd(bmp_gas_resistance, 2, gas_resistance); -#endif // USE_BME680 - - if (json) { - char json_humidity[40]; - snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity); - char json_sealevel[40]; - snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); -#ifdef USE_BME680 - char json_gas[40]; - snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance); - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"), - mqtt_data, bmp_name, temperature, (bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : "", (bmp_model >= 3) ? json_gas : ""); -#else - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"), - mqtt_data, bmp_name, temperature, (bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : ""); -#endif // USE_BME680 -#ifdef USE_DOMOTICZ - if (0 == tele_period) { - DomoticzTempHumPressureSensor(temperature, humidity, pressure); -#ifdef USE_BME680 - if (bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp_gas_resistance); } -#endif // USE_BME680 + if (bmp_sensors[bmp_idx].bmp_pressure != 0.0) { + bmp_sealevel = (bmp_sensors[bmp_idx].bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; } + + snprintf(name, sizeof(name), bmp_sensors[bmp_idx].bmp_name); + if (bmp_count > 1) { + snprintf_P(name, sizeof(name), PSTR("%s-%02X"), name, bmp_sensors[bmp_idx].bmp_address); // BMXXXX-XX + } + + dtostrfd(bmp_sensors[bmp_idx].bmp_temperature, Settings.flag2.temperature_resolution, temperature); + dtostrfd(bmp_sensors[bmp_idx].bmp_pressure, Settings.flag2.pressure_resolution, pressure); + dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); + dtostrfd(bmp_sensors[bmp_idx].bmp_humidity, Settings.flag2.humidity_resolution, humidity); +#ifdef USE_BME680 + char gas_resistance[10]; + dtostrfd(bmp_sensors[bmp_idx].bmp_gas_resistance, 2, gas_resistance); +#endif // USE_BME680 + + if (json) { + char json_humidity[40]; + snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity); + char json_sealevel[40]; + snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); +#ifdef USE_BME680 + char json_gas[40]; + snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance); + + snprintf_P(mqtt_data, + sizeof(mqtt_data), + PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"), + mqtt_data, + name, + temperature, + (bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "", + pressure, + (Settings.altitude != 0) ? json_sealevel : "", + (bmp_sensors[bmp_idx].bmp_model >= 3) ? json_gas : "" + ); +#else + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"), + mqtt_data, name, temperature, (bmp_sensors[bmp_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : ""); +#endif // USE_BME680 + +#ifdef USE_DOMOTICZ + if ((0 == tele_period) && (0 == bmp_idx)) { // We want the same first sensor to report to Domoticz in case a read is missed + DomoticzTempHumPressureSensor(temperature, humidity, pressure); +#ifdef USE_BME680 + if (bmp_sensors[bmp_idx].bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp_sensors[bmp_idx].bmp_gas_resistance); } +#endif // USE_BME680 + } #endif // USE_DOMOTICZ #ifdef USE_KNX - if (0 == tele_period) { - KnxSensor(KNX_TEMPERATURE, bmp_temperature); - KnxSensor(KNX_HUMIDITY, bmp_humidity); - } + if (0 == tele_period) { + KnxSensor(KNX_TEMPERATURE, bmp_sensors[bmp_idx].bmp_temperature); + KnxSensor(KNX_HUMIDITY, bmp_sensors[bmp_idx].bmp_humidity); + } #endif // USE_KNX #ifdef USE_WEBSERVER - } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, bmp_name, temperature, TempUnit()); - if (bmp_model >= 2) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, bmp_name, humidity); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, bmp_name, pressure); - if (Settings.altitude != 0) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, bmp_name, sea_pressure); - } + } else { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, name, temperature, TempUnit()); + if (bmp_sensors[bmp_idx].bmp_model >= 2) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, name, humidity); + } + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, name, pressure); + if (Settings.altitude != 0) { + snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, name, sea_pressure); + } #ifdef USE_BME680 - if (bmp_model >= 3) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, bmp_name, gas_resistance); - } + if (bmp_sensors[bmp_idx].bmp_model >= 3) { + snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, name, gas_resistance); + } #endif // USE_BME680 #endif // USE_WEBSERVER + } } } } diff --git a/sonoff/xsns_09_bmp2x.ino b/sonoff/xsns_09_bmp2x.ino deleted file mode 100644 index 52561de3d..000000000 --- a/sonoff/xsns_09_bmp2x.ino +++ /dev/null @@ -1,622 +0,0 @@ -/* - xsns_09_bmp2x.ino - BMP pressure, temperature, humidity and gas sensor support for Sonoff-Tasmota - - Copyright (C) 2018 Heiko Krupp and 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 . -*/ - -#ifdef USE_I2C -#ifdef USE_BMP2X -/*********************************************************************************************\ - * BMP085, BMP180, BMP280, BME280, BME680 - Pressure, Temperature, Humidity (BME280/BME680) and gas (BME680) - * - * Source: Heiko Krupp and Adafruit Industries - * - * I2C Address: 0x76 or 0x77 -\*********************************************************************************************/ - -#define BMP_ADDR1 0x77 -#define BMP_ADDR2 0x76 - -#define BMP180_CHIPID 0x55 -#define BMP280_CHIPID 0x58 -#define BME280_CHIPID 0x60 -#define BME680_CHIPID 0x61 - -#define BMP_REGISTER_CHIPID 0xD0 - -#define BMP2X_MAX_SENSORS 2 - -const char kBmpTypes[] PROGMEM = "BMP1802X|BMP2802X|BME2802X|BME6802X"; -uint8_t bmp_addresses[] = { BMP_ADDR1, BMP_ADDR2 }; - -uint8_t bmp2x_count = 0; -struct BMP2XSTRUCT { - uint8_t bmp_address; // I2C bus address - char bmp_name[9]; // Sensor name - "BMPXXX2x" - uint8_t bmp_type = 0; - uint8_t bmp_model = 0; - - uint8_t bmp_valid = 0; - float bmp_temperature = 0.0; - float bmp_pressure = 0.0; - float bmp_humidity = 0.0; - #ifdef USE_BME680 - float bmp_gas_resistance = 0.0; - uint8_t bme680_state = 0; - #endif // USE_BME680 - - -} bmp2x_sensors[BMP2X_MAX_SENSORS]; - - -uint8_t bmp_type = 0; - -/*********************************************************************************************\ - * BMP085 and BME180 -\*********************************************************************************************/ - -#define BMP180_REG_CONTROL 0xF4 -#define BMP180_REG_RESULT 0xF6 -#define BMP180_TEMPERATURE 0x2E -#define BMP180_PRESSURE3 0xF4 // Max. oversampling -> OSS = 3 - -#define BMP180_AC1 0xAA -#define BMP180_AC2 0xAC -#define BMP180_AC3 0xAE -#define BMP180_AC4 0xB0 -#define BMP180_AC5 0xB2 -#define BMP180_AC6 0xB4 -#define BMP180_VB1 0xB6 -#define BMP180_VB2 0xB8 -#define BMP180_MB 0xBA -#define BMP180_MC 0xBC -#define BMP180_MD 0xBE - -#define BMP180_OSS 3 - -int16_t cal_ac1; -int16_t cal_ac2; -int16_t cal_ac3; -int16_t cal_b1; -int16_t cal_b2; -int16_t cal_mc; -int16_t cal_md; -uint16_t cal_ac4; -uint16_t cal_ac5; -uint16_t cal_ac6; - -boolean Bmp1802xCalibration(uint8_t bmp2x_idx) -{ - cal_ac1 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC1); - cal_ac2 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC2); - cal_ac3 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC3); - cal_ac4 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC4); - cal_ac5 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC5); - cal_ac6 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_AC6); - cal_b1 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_VB1); - cal_b2 = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_VB2); - cal_mc = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_MC); - cal_md = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_MD); - - // Check for Errors in calibration data. Value never is 0x0000 or 0xFFFF - if (!cal_ac1 | !cal_ac2 | !cal_ac3 | !cal_ac4 | !cal_ac5 | !cal_ac6 | !cal_b1 | !cal_b2 | !cal_mc | !cal_md) { - return false; - } - - if ((cal_ac1 == (int16_t)0xFFFF) | - (cal_ac2 == (int16_t)0xFFFF) | - (cal_ac3 == (int16_t)0xFFFF) | - (cal_ac4 == 0xFFFF) | - (cal_ac5 == 0xFFFF) | - (cal_ac6 == 0xFFFF) | - (cal_b1 == (int16_t)0xFFFF) | - (cal_b2 == (int16_t)0xFFFF) | - (cal_mc == (int16_t)0xFFFF) | - (cal_md == (int16_t)0xFFFF)) { - return false; - } - return true; -} - -void Bmp1802xRead(uint8_t bmp2x_idx) -{ - - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_CONTROL, BMP180_TEMPERATURE); - delay(5); // 5ms conversion time - int ut = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_RESULT); - int32_t xt1 = (ut - (int32_t)cal_ac6) * ((int32_t)cal_ac5) >> 15; - int32_t xt2 = ((int32_t)cal_mc << 11) / (xt1 + (int32_t)cal_md); - int32_t bmp180_b5 = xt1 + xt2; - bmp2x_sensors[bmp2x_idx].bmp_temperature = ((bmp180_b5 + 8) >> 4) / 10.0; - - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_CONTROL, BMP180_PRESSURE3); // Highest resolution - delay(2 + (4 << BMP180_OSS)); // 26ms conversion time at ultra high resolution - uint32_t up = I2cRead24(bmp2x_sensors[bmp2x_idx].bmp_address, BMP180_REG_RESULT); - up >>= (8 - BMP180_OSS); - - int32_t b6 = bmp180_b5 - 4000; - int32_t x1 = ((int32_t)cal_b2 * ((b6 * b6) >> 12)) >> 11; - int32_t x2 = ((int32_t)cal_ac2 * b6) >> 11; - int32_t x3 = x1 + x2; - int32_t b3 = ((((int32_t)cal_ac1 * 4 + x3) << BMP180_OSS) + 2) >> 2; - - x1 = ((int32_t)cal_ac3 * b6) >> 13; - x2 = ((int32_t)cal_b1 * ((b6 * b6) >> 12)) >> 16; - x3 = ((x1 + x2) + 2) >> 2; - uint32_t b4 = ((uint32_t)cal_ac4 * (uint32_t)(x3 + 32768)) >> 15; - uint32_t b7 = ((uint32_t)up - b3) * (uint32_t)(50000UL >> BMP180_OSS); - - int32_t p; - if (b7 < 0x80000000) { - p = (b7 * 2) / b4; - } - else { - p = (b7 / b4) * 2; - } - x1 = (p >> 8) * (p >> 8); - x1 = (x1 * 3038) >> 16; - x2 = (-7357 * p) >> 16; - p += ((x1 + x2 + (int32_t)3791) >> 4); - bmp2x_sensors[bmp2x_idx].bmp_pressure = (float)p / 100.0; // convert to mbar -} - -/*********************************************************************************************\ - * BMP280 and BME280 - * - * Programmer : BMP280/BME280 Datasheet and Adafruit with changes by Theo Arends -\*********************************************************************************************/ - -#define BME280_REGISTER_CONTROLHUMID 0xF2 -#define BME280_REGISTER_CONTROL 0xF4 -#define BME280_REGISTER_CONFIG 0xF5 -#define BME280_REGISTER_PRESSUREDATA 0xF7 -#define BME280_REGISTER_TEMPDATA 0xFA -#define BME280_REGISTER_HUMIDDATA 0xFD - -#define BME280_REGISTER_DIG_T1 0x88 -#define BME280_REGISTER_DIG_T2 0x8A -#define BME280_REGISTER_DIG_T3 0x8C -#define BME280_REGISTER_DIG_P1 0x8E -#define BME280_REGISTER_DIG_P2 0x90 -#define BME280_REGISTER_DIG_P3 0x92 -#define BME280_REGISTER_DIG_P4 0x94 -#define BME280_REGISTER_DIG_P5 0x96 -#define BME280_REGISTER_DIG_P6 0x98 -#define BME280_REGISTER_DIG_P7 0x9A -#define BME280_REGISTER_DIG_P8 0x9C -#define BME280_REGISTER_DIG_P9 0x9E -#define BME280_REGISTER_DIG_H1 0xA1 -#define BME280_REGISTER_DIG_H2 0xE1 -#define BME280_REGISTER_DIG_H3 0xE3 -#define BME280_REGISTER_DIG_H4 0xE4 -#define BME280_REGISTER_DIG_H5 0xE5 -#define BME280_REGISTER_DIG_H6 0xE7 - -struct BME280CALIBDATA -{ - uint16_t dig_T1; - int16_t dig_T2; - int16_t dig_T3; - uint16_t dig_P1; - int16_t dig_P2; - int16_t dig_P3; - int16_t dig_P4; - int16_t dig_P5; - int16_t dig_P6; - int16_t dig_P7; - int16_t dig_P8; - int16_t dig_P9; - uint8_t dig_H1; - int16_t dig_H2; - uint8_t dig_H3; - int16_t dig_H4; - int16_t dig_H5; - int8_t dig_H6; -} Bme280CalibrationData; - -boolean Bmx2802xCalibrate(uint8_t bmp2x_idx) -{ - // if (I2cRead8(bmp_address, BMP_REGISTER_CHIPID) != BME280_CHIPID) return false; - - Bme280CalibrationData.dig_T1 = I2cRead16LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_T1); - Bme280CalibrationData.dig_T2 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_T2); - Bme280CalibrationData.dig_T3 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_T3); - Bme280CalibrationData.dig_P1 = I2cRead16LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P1); - Bme280CalibrationData.dig_P2 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P2); - Bme280CalibrationData.dig_P3 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P3); - Bme280CalibrationData.dig_P4 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P4); - Bme280CalibrationData.dig_P5 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P5); - Bme280CalibrationData.dig_P6 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P6); - Bme280CalibrationData.dig_P7 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P7); - Bme280CalibrationData.dig_P8 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P8); - Bme280CalibrationData.dig_P9 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_P9); - if (BME280_CHIPID == bmp_type) { // #1051 - Bme280CalibrationData.dig_H1 = I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H1); - Bme280CalibrationData.dig_H2 = I2cReadS16_LE(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H2); - Bme280CalibrationData.dig_H3 = I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H3); - Bme280CalibrationData.dig_H4 = (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H4) << 4) | (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H4 + 1) & 0xF); - Bme280CalibrationData.dig_H5 = (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H5 + 1) << 4) | (I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H5) >> 4); - Bme280CalibrationData.dig_H6 = (int8_t)I2cRead8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_DIG_H6); - - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROL, 0x00); // sleep mode since writes to config can be ignored in normal mode (Datasheet 5.4.5/6 page 27) - // Set before CONTROL_meas (DS 5.4.3) - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROLHUMID, 0x01); // 1x oversampling - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONFIG, 0xA0); // 1sec standby between measurements (to limit self heating), IIR filter off - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROL, 0x27); // 1x oversampling, normal mode - } else { - I2cWrite8(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_CONTROL, 0xB7); // 16x oversampling, normal mode (Adafruit) - } - - return true; -} - -void Bme2802xRead(uint8_t bmp2x_idx) -{ - int32_t adc_T = I2cRead24(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_TEMPDATA); - adc_T >>= 4; - - int32_t vart1 = ((((adc_T >> 3) - ((int32_t)Bme280CalibrationData.dig_T1 << 1))) * ((int32_t)Bme280CalibrationData.dig_T2)) >> 11; - int32_t vart2 = (((((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1)) * ((adc_T >> 4) - ((int32_t)Bme280CalibrationData.dig_T1))) >> 12) * - ((int32_t)Bme280CalibrationData.dig_T3)) >> 14; - int32_t t_fine = vart1 + vart2; - float T = (t_fine * 5 + 128) >> 8; - bmp2x_sensors[bmp2x_idx].bmp_temperature = T / 100.0; - - int32_t adc_P = I2cRead24(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_PRESSUREDATA); - adc_P >>= 4; - - int64_t var1 = ((int64_t)t_fine) - 128000; - int64_t var2 = var1 * var1 * (int64_t)Bme280CalibrationData.dig_P6; - var2 = var2 + ((var1 * (int64_t)Bme280CalibrationData.dig_P5) << 17); - var2 = var2 + (((int64_t)Bme280CalibrationData.dig_P4) << 35); - var1 = ((var1 * var1 * (int64_t)Bme280CalibrationData.dig_P3) >> 8) + ((var1 * (int64_t)Bme280CalibrationData.dig_P2) << 12); - var1 = (((((int64_t)1) << 47) + var1)) * ((int64_t)Bme280CalibrationData.dig_P1) >> 33; - if (0 == var1) { - return; // avoid exception caused by division by zero - } - int64_t p = 1048576 - adc_P; - p = (((p << 31) - var2) * 3125) / var1; - var1 = (((int64_t)Bme280CalibrationData.dig_P9) * (p >> 13) * (p >> 13)) >> 25; - var2 = (((int64_t)Bme280CalibrationData.dig_P8) * p) >> 19; - p = ((p + var1 + var2) >> 8) + (((int64_t)Bme280CalibrationData.dig_P7) << 4); - bmp2x_sensors[bmp2x_idx].bmp_pressure = (float)p / 25600.0; - - if (BMP280_CHIPID == bmp2x_sensors[bmp2x_idx].bmp_type) { return; } - - int32_t adc_H = I2cRead16(bmp2x_sensors[bmp2x_idx].bmp_address, BME280_REGISTER_HUMIDDATA); - - int32_t v_x1_u32r = (t_fine - ((int32_t)76800)); - v_x1_u32r = (((((adc_H << 14) - (((int32_t)Bme280CalibrationData.dig_H4) << 20) - - (((int32_t)Bme280CalibrationData.dig_H5) * v_x1_u32r)) + ((int32_t)16384)) >> 15) * - (((((((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H6)) >> 10) * - (((v_x1_u32r * ((int32_t)Bme280CalibrationData.dig_H3)) >> 11) + ((int32_t)32768))) >> 10) + - ((int32_t)2097152)) * ((int32_t)Bme280CalibrationData.dig_H2) + 8192) >> 14)); - v_x1_u32r = (v_x1_u32r - (((((v_x1_u32r >> 15) * (v_x1_u32r >> 15)) >> 7) * - ((int32_t)Bme280CalibrationData.dig_H1)) >> 4)); - v_x1_u32r = (v_x1_u32r < 0) ? 0 : v_x1_u32r; - v_x1_u32r = (v_x1_u32r > 419430400) ? 419430400 : v_x1_u32r; - float h = (v_x1_u32r >> 12); - bmp2x_sensors[bmp2x_idx].bmp_humidity = h / 1024.0; -} - -#ifdef USE_BME680 -/*********************************************************************************************\ - * BME680 support by Bosch https://github.com/BoschSensortec/BME680_driver -\*********************************************************************************************/ - -#include - -struct bme680_dev gas_sensor; - - - -static void BmeDelayMs(uint32_t ms) -{ - delay(ms); -} - -boolean Bme6802xInit(uint8_t bmp2x_idx) -{ - gas_sensor.dev_id = bmp2x_sensors[bmp2x_idx].bmp_address; - gas_sensor.intf = BME680_I2C_INTF; - gas_sensor.read = &I2cReadBuffer; - gas_sensor.write = &I2cWriteBuffer; - gas_sensor.delay_ms = BmeDelayMs; - /* amb_temp can be set to 25 prior to configuring the gas sensor - * or by performing a few temperature readings without operating the gas sensor. - */ - gas_sensor.amb_temp = 25; - - int8_t rslt = BME680_OK; - rslt = bme680_init(&gas_sensor); - if (rslt != BME680_OK) { return false; } - - /* Set the temperature, pressure and humidity settings */ - gas_sensor.tph_sett.os_hum = BME680_OS_2X; - gas_sensor.tph_sett.os_pres = BME680_OS_4X; - gas_sensor.tph_sett.os_temp = BME680_OS_8X; - gas_sensor.tph_sett.filter = BME680_FILTER_SIZE_3; - - /* Set the remaining gas sensor settings and link the heating profile */ - gas_sensor.gas_sett.run_gas = BME680_ENABLE_GAS_MEAS; - /* Create a ramp heat waveform in 3 steps */ - gas_sensor.gas_sett.heatr_temp = 320; /* degree Celsius */ - gas_sensor.gas_sett.heatr_dur = 150; /* milliseconds */ - - /* Select the power mode */ - /* Must be set before writing the sensor configuration */ - gas_sensor.power_mode = BME680_FORCED_MODE; - - /* Set the required sensor settings needed */ - uint8_t set_required_settings = BME680_OST_SEL | BME680_OSP_SEL | BME680_OSH_SEL | BME680_FILTER_SEL | BME680_GAS_SENSOR_SEL; - - /* Set the desired sensor configuration */ - rslt = bme680_set_sensor_settings(set_required_settings,&gas_sensor); - if (rslt != BME680_OK) { return false; } - - bmp2x_sensors[bmp2x_idx].bme680_state = 0; - - return true; -} - -void Bme6802xRead(uint8_t bmp2x_idx) -{ - int8_t rslt = BME680_OK; - - if (BME680_CHIPID == bmp2x_sensors[bmp2x_idx].bmp_type) { - if (0 == bmp2x_sensors[bmp2x_idx].bme680_state) { - /* Trigger the next measurement if you would like to read data out continuously */ - rslt = bme680_set_sensor_mode(&gas_sensor); - if (rslt != BME680_OK) { return; } - - /* Get the total measurement duration so as to sleep or wait till the - * measurement is complete */ -// uint16_t meas_period; -// bme680_get_profile_dur(&meas_period, &gas_sensor); -// delay(meas_period); /* Delay till the measurement is ready */ // 183 mSec - we'll wait a second - - bmp2x_sensors[bmp2x_idx].bme680_state = 1; - } else { - bmp2x_sensors[bmp2x_idx].bme680_state = 0; - - struct bme680_field_data data; - rslt = bme680_get_sensor_data(&data, &gas_sensor); - if (rslt != BME680_OK) { return; } - - bmp2x_sensors[bmp2x_idx].bmp_temperature = data.temperature / 100.0; - bmp2x_sensors[bmp2x_idx].bmp_humidity = data.humidity / 1000.0; - bmp2x_sensors[bmp2x_idx].bmp_pressure = data.pressure / 100.0; - /* Avoid using measurements from an unstable heating setup */ - if (data.status & BME680_GASM_VALID_MSK) { - bmp2x_sensors[bmp2x_idx].bmp_gas_resistance = data.gas_resistance / 1000.0; - } else { - bmp2x_sensors[bmp2x_idx].bmp_gas_resistance = 0; - } - } - } - return; -} - -#endif // USE_BME680 - -/********************************************************************************************/ - -void Bmp2xDetect() -{ - //if (bmp_type) { return; } - if (bmp2x_count) return; - - //for (byte i = 0; i < sizeof(bmp_addresses); i++) { - for (byte i = 0; i < BMP2X_MAX_SENSORS; i++) { - - bmp_type = I2cRead8(bmp_addresses[i], BMP_REGISTER_CHIPID); - if (bmp_type) { - bmp2x_sensors[bmp2x_count].bmp_address = bmp_addresses[i]; - bmp2x_sensors[bmp2x_count].bmp_type = bmp_type; - bmp2x_sensors[bmp2x_count].bmp_model = 0; - - boolean success = false; - - switch (bmp_type) { - case BMP180_CHIPID: - success = Bmp1802xCalibration(bmp2x_count); - break; - case BME280_CHIPID: - bmp2x_sensors[bmp2x_count].bmp_model++; // 2 - case BMP280_CHIPID: - bmp2x_sensors[bmp2x_count].bmp_model++; // 1 - success = Bmx2802xCalibrate(bmp2x_count); - break; - #ifdef USE_BME680 - case BME680_CHIPID: - bmp2x_sensors[bmp2x_count].bmp_model = 3; // 3 - success = Bme6802xInit(bmp2x_count); - break; - #endif // USE_BME680 - } - - if (success) { - GetTextIndexed(bmp2x_sensors[bmp2x_count].bmp_name, sizeof(bmp2x_sensors[bmp2x_count].bmp_name), bmp2x_sensors[bmp2x_count].bmp_model, kBmpTypes); - snprintf_P(log_data, sizeof(log_data), S_LOG_I2C_FOUND_AT, bmp2x_sensors[bmp2x_count].bmp_name, bmp2x_sensors[bmp2x_count].bmp_address); - AddLog(LOG_LEVEL_DEBUG); - bmp2x_count++; - } - else { - bmp_type = 0; - } - } - } - -} - -void Bmp2xRead(uint8_t bmp2x_idx) -{ - switch (bmp2x_sensors[bmp2x_idx].bmp_type) { - case BMP180_CHIPID: - Bmp1802xRead(bmp2x_idx); - break; - case BMP280_CHIPID: - case BME280_CHIPID: - Bme2802xRead(bmp2x_idx); - break; - #ifdef USE_BME680 - case BME680_CHIPID: - Bme6802xRead(bmp2x_idx); - break; - #endif // USE_BME680 - } - if (bmp2x_sensors[bmp2x_idx].bmp_temperature != 0.0) { - bmp2x_sensors[bmp2x_idx].bmp_temperature = ConvertTemp(bmp2x_sensors[bmp2x_idx].bmp_temperature); } - - //SetGlobalValues(bmp_temperature, bmp_humidity); -} - -void Bmp2xEverySecond() -{ - if (91 == (uptime %100)) { - // 1mS - Bmp2xDetect(); - } - else { - // 2mS - for (byte bmp2x_idx = 0; bmp2x_idx < bmp2x_count; bmp2x_idx++) { - Bmp2xRead(bmp2x_idx); - } - } -} - -void Bmp2xShow(boolean json) -{ - for (byte bmp2x_idx = 0; bmp2x_idx < bmp2x_count; bmp2x_idx++) { - - if (bmp2x_sensors[bmp2x_idx].bmp_type) { - float bmp_sealevel = 0.0; - char temperature[10]; - char pressure[10]; - char sea_pressure[10]; - char humidity[10]; - char name[14]; // "BMXXXX2X-XX" - - if (bmp2x_sensors[bmp2x_idx].bmp_pressure != 0.0) { - bmp_sealevel = (bmp2x_sensors[bmp2x_idx].bmp_pressure / FastPrecisePow(1.0 - ((float)Settings.altitude / 44330.0), 5.255)) - 21.6; - } - - snprintf_P(name, sizeof(name), PSTR("%s-%02X"), bmp2x_sensors[bmp2x_idx].bmp_name, bmp2x_sensors[bmp2x_idx].bmp_address); // "BMXXXX2X-0xXX" - - dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_temperature, Settings.flag2.temperature_resolution, temperature); - dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_pressure, Settings.flag2.pressure_resolution, pressure); - dtostrfd(bmp_sealevel, Settings.flag2.pressure_resolution, sea_pressure); - dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_humidity, Settings.flag2.humidity_resolution, humidity); -#ifdef USE_BME680 - char gas_resistance[10]; - dtostrfd(bmp2x_sensors[bmp2x_idx].bmp_gas_resistance, 2, gas_resistance); -#endif // USE_BME680 - - if (json) { - char json_humidity[40]; - snprintf_P(json_humidity, sizeof(json_humidity), PSTR(",\"" D_JSON_HUMIDITY "\":%s"), humidity); - char json_sealevel[40]; - snprintf_P(json_sealevel, sizeof(json_sealevel), PSTR(",\"" D_JSON_PRESSUREATSEALEVEL "\":%s"), sea_pressure); -#ifdef USE_BME680 - char json_gas[40]; - snprintf_P(json_gas, sizeof(json_gas), PSTR(",\"" D_JSON_GAS "\":%s"), gas_resistance); - - snprintf_P(mqtt_data, - sizeof(mqtt_data), - PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s%s}"), - mqtt_data, - name, - temperature, - (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", - pressure, - (Settings.altitude != 0) ? json_sealevel : "", - (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) ? json_gas : "" - ); -#else - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s,\"%s\":{\"" D_JSON_TEMPERATURE "\":%s%s,\"" D_JSON_PRESSURE "\":%s%s}"), - mqtt_data, name, temperature, (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) ? json_humidity : "", pressure, (Settings.altitude != 0) ? json_sealevel : ""); -#endif // USE_BME680 - -#ifdef USE_DOMOTICZ - if ((0 == tele_period) && (0 == bmp2x_idx)) { // We want the same first sensor to report to Domoticz in case a read is missed - DomoticzTempHumPressureSensor(temperature, humidity, pressure); -#ifdef USE_BME680 - if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { DomoticzSensor(DZ_AIRQUALITY, (uint32_t)bmp2x_sensors[bmp2x_idx].bmp_gas_resistance); } -#endif // USE_BME680 - } -#endif // USE_DOMOTICZ - -#ifdef USE_KNX - if (0 == tele_period) { - KnxSensor(KNX_TEMPERATURE, bmp2x_sensors[bmp2x_idx].bmp_temperature); - KnxSensor(KNX_HUMIDITY, bmp2x_sensors[bmp2x_idx].bmp_humidity); - } -#endif // USE_KNX - -#ifdef USE_WEBSERVER - } else { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_TEMP, mqtt_data, name, temperature, TempUnit()); - if (bmp2x_sensors[bmp2x_idx].bmp_model >= 2) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_HUM, mqtt_data, name, humidity); - } - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_PRESSURE, mqtt_data, name, pressure); - if (Settings.altitude != 0) { - snprintf_P(mqtt_data, sizeof(mqtt_data), HTTP_SNS_SEAPRESSURE, mqtt_data, name, sea_pressure); - } -#ifdef USE_BME680 - if (bmp2x_sensors[bmp2x_idx].bmp_model >= 3) { - snprintf_P(mqtt_data, sizeof(mqtt_data), PSTR("%s{s}%s " D_GAS "{m}%s " D_UNIT_KILOOHM "{e}"), mqtt_data, name, gas_resistance); - } -#endif // USE_BME680 -#endif // USE_WEBSERVER - } - } - } -} - -/*********************************************************************************************\ - * Interface -\*********************************************************************************************/ - -#define XSNS_09 - -boolean Xsns09(byte function) -{ - boolean result = false; - - if (i2c_flg) { - switch (function) { - case FUNC_INIT: - Bmp2xDetect(); - break; - case FUNC_EVERY_SECOND: - Bmp2xEverySecond(); - break; - case FUNC_JSON_APPEND: - Bmp2xShow(1); - break; -#ifdef USE_WEBSERVER - case FUNC_WEB_APPEND: - Bmp2xShow(0); - break; -#endif // USE_WEBSERVER - } - } - return result; -} - -#endif // USE_BMP2X -#endif // USE_I2C From 51a86d3ff522a64d997101e5c30e66d1032a5231 Mon Sep 17 00:00:00 2001 From: Norbert Richter Date: Mon, 29 Oct 2018 16:26:45 +0100 Subject: [PATCH 23/23] decode-config.py v2.0.0001: add v6.2.1.20 config changes - change pw defaults to unhide [Norbert Richter] - fix handling 'raw' keys and GetTemplateSetting() error --- tools/decode-config.py | 81 +++++++++++++++++++++++++++--------------- 1 file changed, 53 insertions(+), 28 deletions(-) diff --git a/tools/decode-config.py b/tools/decode-config.py index 1eb991d11..8e160f751 100755 --- a/tools/decode-config.py +++ b/tools/decode-config.py @@ -1,6 +1,6 @@ #!/usr/bin/env python # -*- coding: utf-8 -*- -VER = '2.0.0000' +VER = '2.0.0001' """ decode-config.py - Backup/Restore Sonoff-Tasmota configuration data @@ -201,7 +201,7 @@ DEFAULTS = { 'jsonsort': True, 'jsonrawvalues':False, 'jsonrawkeys': False, - 'jsonhidepw': True, + 'jsonhidepw': False, }, } args = {} @@ -250,21 +250,27 @@ Settings dictionary describes the config file fields definition: negative shift the result left bits datadef - Define the field interpretation different from simple - standard types (like char, byte, int) e. g. lists or bit fields - Can be None, a single integer, a list or a dictionary - None: - None must be given if the field contains a simple value - desrcibed by the prefix - n: - Same as [n] below - [n]: - Defines a one-dimensional array of size - [n, n <,n...>] - Defines a multi-dimensional array + Data definition, is either a array definition or a + tuple containing an array definition and min/max values + Format: arraydef|(arraydef, min, max) + arraydef: + None: + None must be given if the field contains a + simple value desrcibed by the prefix + n: + [n]: + Defines a one-dimensional array of size + [n, m <,o...>] + Defines a multi-dimensional array + min: + defines a minimum valid value or None if all values + for this format is allowed. + max: + defines a maximum valid value or None if all values + for this format is allowed. converter (optional) - Conversion methode(s): ()|'xxx'|func + Conversion methode(s): 'xxx'|func or ('xxx'|func, 'xxx'|func) Read conversion is used if args.jsonrawvalues is False Write conversion is used if jsonrawvalues from restore json file is False or args.jsonrawvalues is False. @@ -845,7 +851,19 @@ Setting_6_2_1_19.update({ 'weight_max': ('= cfg[0]: + template = cfg + size = template[1] + setting = template[2] + break except: - return None,None,None,None - - # search setting definition - template = None - setting = None - size = None - for cfg in Settings: - if version >= cfg[0]: - template = cfg - size = template[1] - setting = template[2] - break + pass return version, template, size, setting @@ -1652,6 +1671,9 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0): result = None + if fieldname == 'raw' and not args.jsonrawkeys: + return result + # get field definition _format, baseaddr, bits, bitshift, datadef, convert = GetFieldDef(fielddef) @@ -1662,7 +1684,7 @@ def GetField(dobj, fieldname, fielddef, raw=False, addroffset=0): for i in range(0, datadef[0]): subfielddef = GetSubfieldDef(fielddef) length = GetFieldLength(subfielddef) - if length != 0 and (fieldname != 'raw' or args.jsonrawkeys): + if length != 0: result.append(GetField(dobj, fieldname, subfielddef, raw=raw, addroffset=addroffset+offset)) offset += length @@ -1722,6 +1744,9 @@ def SetField(dobj, fieldname, fielddef, restore, raw=False, addroffset=0, filena _format, baseaddr, bits, bitshift, datadef, convert = GetFieldDef(fielddef) fieldname = str(fieldname) + if fieldname == 'raw' and not args.jsonrawkeys: + return dobj + # do not write readonly values if isinstance(convert, (list,tuple)) and len(convert)>1 and convert[1]==None: if args.debug: