diff --git a/.gitignore b/.gitignore index 15e64bd518..e0c8e6c426 100644 --- a/.gitignore +++ b/.gitignore @@ -4,3 +4,4 @@ **/.DS_Store node_modules *.ps1 +main/certs/private* \ No newline at end of file diff --git a/docs/.vuepress/public/apple-touch-icon.png b/docs/.vuepress/public/apple-touch-icon.png index 273d887356..83e0523eb8 100644 Binary files a/docs/.vuepress/public/apple-touch-icon.png and b/docs/.vuepress/public/apple-touch-icon.png differ diff --git a/docs/.vuepress/public/favicon-144x144.png b/docs/.vuepress/public/favicon-144x144.png index 22eaf4d102..fb55347411 100644 Binary files a/docs/.vuepress/public/favicon-144x144.png and b/docs/.vuepress/public/favicon-144x144.png differ diff --git a/docs/.vuepress/public/favicon-16x16.png b/docs/.vuepress/public/favicon-16x16.png index 48c257b453..a19113d69e 100644 Binary files a/docs/.vuepress/public/favicon-16x16.png and b/docs/.vuepress/public/favicon-16x16.png differ diff --git a/docs/.vuepress/public/favicon-32x32.png b/docs/.vuepress/public/favicon-32x32.png index 5c7d04e8c2..6c3a5d8b7c 100644 Binary files a/docs/.vuepress/public/favicon-32x32.png and b/docs/.vuepress/public/favicon-32x32.png differ diff --git a/docs/integrate/aws_iot.md b/docs/integrate/aws_iot.md index 178b8b746e..8948b14efc 100644 --- a/docs/integrate/aws_iot.md +++ b/docs/integrate/aws_iot.md @@ -93,7 +93,7 @@ With PlatformIO you can directly leverage the environment `esp32dev-ble-aws` ## Build and upload -## Connect to a wifi Access point [see portal](../upload/portal) +## Connect to a WiFi Access point [see portal](../upload/portal) Enter your credentials and verify that Secure connection is marked. ## Verify that you receive data in AWS diff --git a/docs/integrate/home_assistant.md b/docs/integrate/home_assistant.md index 95be8b3023..56aef8312d 100644 --- a/docs/integrate/home_assistant.md +++ b/docs/integrate/home_assistant.md @@ -37,7 +37,7 @@ OMG will use the auto discovery functionality of home assistant to create gatewa The Bluetooth and the RTL_433 gateway will create automatically devices and entities, the RF gateway will create DeviceTrigger. The OpenMQTTGateway will also be available as a device to monitor its parameters and control it. The sensors (DHT for example) and actuators (relays) are attached to the gateway. -30 minutes after its activation the auto discovery will be automaticaly deactivated, you can reactivate it from the gateway controls. +30 minutes after its activation the auto discovery will be automatically deactivated, you can reactivate it from the gateway controls. Some devices may require a button push or motion/contact event to trigger a message and generate the auto discovery. ::: diff --git a/docs/prerequisites/devices.md b/docs/prerequisites/devices.md index 2b69025606..cab4b36890 100644 --- a/docs/prerequisites/devices.md +++ b/docs/prerequisites/devices.md @@ -55,11 +55,13 @@ Added to that it retrieves the measures from the devices below. By default the d | INKBIRD|IBT-4X(S/C)|temperature1/temperature2/temperature3/temperature4| | INKBIRD|IBT-6XS|temperature1/temperature2/temperature3/temperature4/temperature5/temperature6| | iNode|Energy Meter|Current average and aggregate kW(h)/m³/battery| +| KKM |K6P|temperature/humidity/voltage| +| KKM |K9|temperature/humidity/voltage/acceleration x/y/z-axis (optional - without recognised as K6P)| | Oria/Brifit/SigmaWit/SensorPro|TH Sensor T201|temperature/humidity/battery| | Oria/Brifit/SigmaWit/SensorPro|TH Sensor T301|temperature/humidity/battery| | Mokosmart|M1|acceleration x/y/z-axis/battery| | Mokosmart|H4|temperature/humidity/voltage| -| Mopeka|Pro|temperature/level/sync status/voltage/battery/reading quality| +| Mopeka|Pro|temperature/level/sync status/voltage/battery/reading quality/acceleration x/y-axis| | Otio/BeeWi|Door & Window Sensor|contact/battery| | Polar|H10 Chest strap|activity heart rate| | Qingping|CGDK2|temperature/humidity| @@ -73,11 +75,13 @@ Added to that it retrieves the measures from the devices below. By default the d | SmartDry|Laundry Sensor|temperature/humidity/shake/voltage/wake| | Sensirion|MyCO₂/CO₂ Gadget|temperature/humidity/carbon dioxide| | Sensirion|SHT4X TH sensor|temperature/humidity| +| Shelly|Button1|button press type, battery, packet ID| | Switchbot|Bot (c)|mode/state/battery| | Switchbot|Motion Sensor|movement/light level/sensing distance/led/scope tested/battery| | Switchbot|Contact Sensor|contact/movement/scope tested/light level/in count/out count/push count/battery| | Switchbot|Curtain|motion state/position/light level/battery/calibration state| | Switchbot|Meter (Plus)|temperature/humidity/battery| +| Switchbot|Outdoor Meter|temperature/humidity/battery| | Thermobeacon|WS02|temperature/humidity/voltage/timestamp/maximum temperature/maximum temperature timestamp/minimum temperature/minimum temperature timestamp| | Thermobeacon|WS08|temperature/humidity/voltage/timestamp/maximum temperature/maximum temperature timestamp/minimum temperature/minimum temperature timestamp| | ThermoPro|TP357|temperature/humidity| diff --git a/docs/upload/troubleshoot.md b/docs/upload/troubleshoot.md index 396f9ac95d..97a31b7ffb 100644 --- a/docs/upload/troubleshoot.md +++ b/docs/upload/troubleshoot.md @@ -6,7 +6,7 @@ If you see a green badge this means that the code compilation is OK with the con Check your IDE environment version, boards version, libraries version before submitting an issue or a question. Verify especially that the libraries provided into the [release page](https://github.com/1technophile/OpenMQTTGateway/releases) are located into your "sketchbook folder"/libraries if your are using the Arduino IDE. -## ESP32 compilation errors related to wifi +## ESP32 compilation errors related to WiFi If you get one or several of the following errors: `error: 'WIFI_STA' was not declared in this scope` @@ -15,7 +15,7 @@ If you get one or several of the following errors: `error: no matching function for call to 'WiFiClass::macAddress()` -You have a conflict between Arduino default wifi library and ESP32 one. So as to resolve this issue you should move or remove the Arduino wifi library (Arduino Sketchbook folder\libraries\WiFi) in order to enable the IDE to take the one from ESP32 (Arduino Sketchbook folder\hardware\espressif\arduino-esp32\libraries\WiFi) +You have a conflict between Arduino default WiFi library and ESP32 one. So as to resolve this issue you should move or remove the Arduino WiFi library (Arduino Sketchbook folder\libraries\WiFi) in order to enable the IDE to take the one from ESP32 (Arduino Sketchbook folder\hardware\espressif\arduino-esp32\libraries\WiFi) More info on [this topic](https://community.openmqttgateway.com/t/esp32-compilation-error/144/5?u=1technophile) ## Not able to send or receive RF or IR diff --git a/docs/upload/web-install.md b/docs/upload/web-install.md index c35faa45dd..2f39215333 100644 --- a/docs/upload/web-install.md +++ b/docs/upload/web-install.md @@ -18,7 +18,7 @@ You can upload the firmware to your ESP device directly from here. 2. Select the firmware in the box below. 3. Click the install button and choose the port that the ESP is connected to. 4. Wait until the process is complete. -5. Once completed you can configure your [Wifi and MQTT credentials](portal.md) +5. Once completed you can configure your [WiFi and MQTT credentials](portal.md) diff --git a/docs/use/ble.md b/docs/use/ble.md index 753ba83c6f..2e3e3bfdf6 100644 --- a/docs/use/ble.md +++ b/docs/use/ble.md @@ -30,8 +30,8 @@ Once the data has been transmitted to the MQTT broker, it can be easily integrat Examples of compatible sensors among [our list](https://decoder.theengs.io/devices/devices_by_brand.html: Mi Flora, Mi jia, LYWDS02, LYWSD03MMC, ClearGrass, Mi scale, iBBQ, TPMS ## Receiving signals from BLE tracker devices for Presence detection -The gateway can detect the BLE trackers from Tile, NUT, TAGIT, ITAG, MiBand, Amazfit and RuuviTag and create automaticaly a device tracker entity following the Home Assistant discovery convention (if the auto discovery is activated). -To do this activate the "BT: Publish HASS presence" switch in your controller or send the followng MQTT command to your broker: +The gateway can detect the BLE trackers from Tile, NUT, TAGIT, ITAG, MiBand, Amazfit and RuuviTag and create automatically a device tracker entity following the Home Assistant discovery convention (if the auto discovery is activated). +To do this activate the "BT: Publish HASS presence" switch in your controller or send the following MQTT command to your broker: `mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{"hasspresence":true}'` The entity created can be attached to a person to leverage presence detection. The `away` or `not home` state is triggered if the BLE tracker is not detected during the timer defined by `presenceawaytimer`. @@ -287,7 +287,7 @@ To specify the MAC address type add the parameter `"mac_type"` to the command. F ### Example write command ``` -mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{ +mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT -m '{ "ble_write_address":"AA:BB:CC:DD:EE:FF", "ble_write_service":"cba20d00-224d-11e6-9fb8-0002a5d5c51b", "ble_write_char":"cba20002-224d-11e6-9fb8-0002a5d5c51b", @@ -308,7 +308,7 @@ Response: ``` ### Example read command ``` -mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{ +mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT -m '{ "ble_read_address":"AA:BB:CC:DD:EE:FF", "ble_read_service":"cba20d00-224d-11e6-9fb8-0002a5d5c51b", "ble_read_char":"cba20002-224d-11e6-9fb8-0002a5d5c51b", @@ -343,7 +343,7 @@ The device can also be controlled over MQTT with a simplified BLE write command. ### Example command to set the SwitchBot state to ON: ``` -mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT/config -m '{ +mosquitto_pub -t home/OpenMQTTGateway/commands/MQTTtoBT -m '{ "SBS1":"on", "mac":"AA:BB:CC:DD:EE:FF" }' diff --git a/docs/use/boards.md b/docs/use/boards.md index 5c15493320..9015027a98 100644 --- a/docs/use/boards.md +++ b/docs/use/boards.md @@ -13,12 +13,12 @@ On M5Stack boards you may do a long press to these buttons in low power mode 0 ( You can also do a long press when powering the board to reset it, this press must be done during the first 5 seconds after the start. -### Wifi interference on ESP32 ### -Certain sensors like HC-SR501 is prone to generate false signals / triggers when used on a ESP32 with Wifi enabled. To reduce or elimate the effect the board must be put into Wifi B/G with lower TX power. +### Wifi interference on sensors when using an ESP ### +Certain sensors like HC-SR501 is prone to generate false signals / triggers when used on a ESP with Wifi enabled. To reduce or elimate the effect the board must be put into Wifi B/G with lower TX power. -This can be achieved with the following macro, `WifiGMode` defined true and `WifiPower` to e.g. WIFI_POWER_11dBm. +This can be achieved with the following macro, `WifiGMode` defined true and `WifiPower` to e.g. WIFI_POWER_11dBm (ESP32) or 11 (ESP8266). -Since the WiFi protocol is persisted in the flash of the ESP32 you have to run at least once with `WiFiGMode` defined **false** to get Band N back. +Since the WiFi protocol is persisted in the flash of the ESP you have to run at least once with `WiFiGMode` defined **false** to get Band N back. ### Low power mode for ESP32 OpenMQTTGateway support a low power mode for ESP32, this mode is available per default on boards with batteries. The other boards needs to have the macro `DEFAULT_LOW_POWER_MODE` defined at 0, 1 or 2 to use it. More information about the modes is available into User_config.h. @@ -37,7 +37,7 @@ The interval between the ESP32 wake up is defined at build time by the macro `Ti ::: tip When coming back from mode 2 to mode 0 you may publish the command with a retain flag so as to enable the gateway to retrieve it when reconnecting. -A low power mode switch is automatically created by discovery with Home Assistant, you may experience a delay between the command and the state update due to the fact that the update will be revceived and acknowledged when the device woke up. +A low power mode switch is automatically created by discovery with Home Assistant, you may experience a delay between the command and the state update due to the fact that the update will be received and acknowledged when the device woke up. In low power mode you should use ESPWifiManualSetup so as to rely on the credentials entered into User_config.h. So as to do that uncomment the line below in User_config.h ``` c @@ -54,7 +54,7 @@ If you change the default low power mode in config_BT.h to 2 and your credential ### Behaviour -If the connection of the board to WIFI and MQTT is successful you will see the logo with text like below: +If the connection of the board to WiFi and MQTT is successful you will see the logo with text like below: ![boards](../img/OpenMQTTgateway_M5_Stack_Board_Display_Text.png) @@ -93,7 +93,7 @@ The low power mode can be changed also with a push to button B when the board is If you are already in low power mode 1 or 2 with M5Stack you can wake up the board by pressing the red button. ### Low power mode (deepSleep) for ESP8266 & ESP32 boards -In certain use cases where power is severly limited you can use the ESP8266 or ESP32 deep sleep capability. +In certain use cases where power is severely limited you can use the ESP8266 or ESP32 deep sleep capability. * e.g. measuring a pool temperature every 5 minutes using an ESP8266 and DS18B20 probe where the ESP8266 is powered by very limited battery backed solar power. * e.g. as a water/leak detector which wake-up based on sensor state an ESP32 and C-37 YL-83 HM-RD sensor where the ESP32 is powered by very limited battery power. @@ -110,4 +110,4 @@ For an ESP8266 a hardware jumper is required connecting RST to a GPIO (not to CH On an ESP32 we can also use an external sensor state to wake-up the ESP and this is defined by macro `ESP32_EXT0_WAKE_PIN` and which state it must toggle to by macro `ESP32_EXT0_WAKE_PIN_STATE` defaulted to 1 (high). -And the sensor code must set variable `ready_to_sleep` to true after publishing the measurement to MQTT and the main loop will then enter deep sleep. \ No newline at end of file +And the sensor code must set variable `ready_to_sleep` to true after publishing the measurement to MQTT and the main loop will then enter deep sleep. diff --git a/docs/use/webui.md b/docs/use/webui.md index 78888d47e5..260b1ddcac 100644 --- a/docs/use/webui.md +++ b/docs/use/webui.md @@ -6,25 +6,25 @@ For ESP32 based environments a WebUI is available to provide basic configuration * Information * Firmware Upgrade * Console -* Resart +* Restart # Login Authentication -By default access to the WebUI uses basic authentication to control access to your OpenMQTTGateway Device. The login is `admin` and the password is your ota_password. +By default access to the WebUI uses basic authentication to control access to your OpenMQTTGateway Device. The login is `admin` and the password is your ota_password (if unchanged, the default ota_password is `OTAPASSWORD`). ::: warning -The communication with the WEBUI is not encrypted, which means that your data may be visible on your local network. +The communication with the WebUI is not encrypted, which means that your data may be visible on your local network. ::: # Configuration Options -## Wifi +## WiFi -Abiltity to change the SSID and password for your Wifi, if the change is unsuccessful it will revert back to the previous wifi settings. +Ability to change the SSID and password for your WiFi, if the change is unsuccessful it will revert back to the previous WiFi settings. ## MQTT -Abiltity to change the mqtt settings, if the change is unsuccessful it will revert back to the previous mqtt settings. +Ability to change the mqtt settings, if the change is unsuccessful it will revert back to the previous mqtt settings. ## WebUI @@ -44,7 +44,7 @@ Ability to upgrade firmware by URL or to latest version. # Console -Ability to view messages from the OpenMQTTGateway console. The scope of messages visible in the UI is limited to just the OpenMQTTGatewy codebase, messages from the ESP hardware or other libraries are not visible, +Ability to view messages from the OpenMQTTGateway console. The scope of messages visible in the UI is limited to just the OpenMQTTGateway codebase, messages from the ESP hardware or other libraries are not visible, Ability to inject commands to OpenMQTTGateway for processing. The commands accepted are of the form mqtt topic then json message. And as you are already on the target device, you do not need to include the device name ie diff --git a/environments.ini b/environments.ini index 146121ead6..2b636f06de 100644 --- a/environments.ini +++ b/environments.ini @@ -214,6 +214,7 @@ custom_description = RS232 reading of GridFree Sun Inverter [env:esp32dev-ir] platform = ${com.esp32_platform} board = esp32dev +board_build.partitions = min_spiffs.csv lib_deps = ${com-esp32.lib_deps} ${libraries.irremoteesp} @@ -1059,6 +1060,8 @@ build_flags = '-DsimplePublishing=true' '-DGateway_Name="OMG_ESP8266_ALL"' '-DDEEP_SLEEP_IN_US=120000000' + '-DWifiGMode=true' + '-DWifiPower=11' board_build.flash_mode = dout [env:nodemcuv2-fastled-test] diff --git a/main/User_config.h b/main/User_config.h index b74cb4915e..78be725cf1 100644 --- a/main/User_config.h +++ b/main/User_config.h @@ -148,6 +148,7 @@ const byte mac[] = {0xDE, 0xED, 0xBA, 0xFE, 0x54, 0x95}; //W5100 ethernet shield # define mqtt_topic_max_size 150 # ifndef mqtt_max_packet_size # ifdef MQTT_HTTPS_FW_UPDATE +# define CHECK_OTA_UPDATE true // enable to check for the presence of a new version for your environment on Github # define mqtt_max_packet_size 2560 # else # define mqtt_max_packet_size 1024 @@ -208,32 +209,11 @@ const char* certificate PROGMEM = R"EOF(" # ifdef MQTT_HTTPS_FW_UPDATE // If used, this should be set to the root CA certificate of the server hosting the firmware. -// The certificate must be in PEM ascii format. -// The default certificate is for github. -const char* OTAserver_cert PROGMEM = R"EOF(" ------BEGIN CERTIFICATE----- -MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh -MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 -d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD -QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT -MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j -b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG -9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB -CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 -nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt -43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P -T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 -gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO -BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR -TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw -DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr -hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg -06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF -PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls -YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk -CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= ------END CERTIFICATE----- -")EOF"; +# ifdef PRIVATE_CERTS +# include "certs/private_ota_cert.h" +# else +# include "certs/default_ota_cert.h" +# endif # ifndef MQTT_HTTPS_FW_UPDATE_USE_PASSWORD # define MQTT_HTTPS_FW_UPDATE_USE_PASSWORD 1 // Set this to 0 if not using TLS connection to MQTT broker to prevent clear text passwords being sent. @@ -261,23 +241,15 @@ CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= # endif # if MQTT_SECURE_SELF_SIGNED -const char* ss_server_cert PROGMEM = R"EOF(" ------BEGIN CERTIFICATE----- -... ------END CERTIFICATE----- -")EOF"; - -const char* ss_client_cert PROGMEM = R"EOF(" ------BEGIN CERTIFICATE----- -... ------END CERTIFICATE----- -")EOF"; - -const char* ss_client_key PROGMEM = R"EOF(" ------BEGIN RSA PRIVATE KEY----- -... ------END RSA PRIVATE KEY----- -")EOF"; +# ifdef PRIVATE_CERTS +# include "certs/private_client_cert.h" +# include "certs/private_client_key.h" +# include "certs/private_server_cert.h" +# else +# include "certs/default_client_cert.h" +# include "certs/default_client_key.h" +# include "certs/default_server_cert.h" +# endif struct ss_certs { const char* server_cert; @@ -716,18 +688,17 @@ Adafruit_NeoPixel leds2(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO2, ANEOPIX_IN # define LOG_LEVEL LOG_LEVEL_NOTICE #endif -/*-------------------ESP32 Wifi band and tx power ---------------------*/ -//Certain sensors are sensitive to ESP32 Wifi which can cause interference with their normal operation +/*-------------------ESP Wifi band and tx power ---------------------*/ +//Certain sensors are sensitive to Wifi which can cause interference with their normal operation //For example it can cause false triggers on a PIR HC-SR501 //It is reccomended to change Wifi BAND to G and reduce tx power level to 11dBm -//Since the WiFi protocol is persisted in the flash of the ESP32 you have to run at least once with `WiFiGMode` defined false to get Band N back. -#ifdef ESP32 -# ifndef WifiGMode +//Since the WiFi protocol is persisted in the flash of the ESP you have to run at least once with `WiFiGMode` defined false to get Band N back. +#ifndef WifiGMode //# define WifiGMode true -# endif -# ifndef WifiPower -//# define WifiPower WIFI_POWER_11dBm -# endif +#endif +#ifndef WifiPower +//# define WifiPower WIFI_POWER_11dBm //When using an ESP32 +//# define WifiPower 11 //When using an ESP8266 #endif /*-----------PLACEHOLDERS FOR WebUI DISPLAY--------------*/ diff --git a/main/ZgatewayBT.ino b/main/ZgatewayBT.ino index faf37d0324..d6f06f7287 100644 --- a/main/ZgatewayBT.ino +++ b/main/ZgatewayBT.ino @@ -692,14 +692,6 @@ void procBLETask(void* pvParameters) { String mac_adress = advertisedDevice->getAddress().toString().c_str(); mac_adress.toUpperCase(); BLEdata["id"] = (char*)mac_adress.c_str(); -# if defined(ESP8266) || defined(ESP32) -# if message_UTCtimestamp == true - BLEdata["UTCtime"] = UTCtimestamp(); -# endif -# if message_unixtimestamp == true - BLEdata["unixtime"] = unixtimestamp(); -# endif -# endif BLEdata["mac_type"] = advertisedDevice->getAddress().getType(); BLEdata["adv_type"] = advertisedDevice->getAdvType(); Log.notice(F("Device detected: %s" CR), (char*)mac_adress.c_str()); @@ -1130,7 +1122,7 @@ void launchBTDiscovery(bool overrideDiscovery) { Gateway_AnnouncementMsg, will_Message, false, subjectMQTTtoBTset, model.c_str(), brand.c_str(), model_id.c_str(), macWOdots.c_str(), false, stateClassNone, "off", "on"); - } else if (strcmp(prop.key().c_str(), "device") != 0) { + } else if (strcmp(prop.key().c_str(), "device") != 0 || strcmp(prop.key().c_str(), "mac") != 0) { // Exception on device and mac as these ones are not sensors createDiscovery("sensor", discovery_topic.c_str(), entity_name.c_str(), unique_id.c_str(), will_Topic, prop.value()["name"], value_template.c_str(), @@ -1369,7 +1361,8 @@ void MQTTtoBTAction(JsonObject& BTdata) { if (BTdata.containsKey("SBS1")) { strcpy(action.addr, (const char*)BTdata["mac"]); action.write = true; - action.value = BTdata["SBS1"].as(); + std::string val = BTdata["SBS1"].as(); // Fix #1694 + action.value = val; action.ttl = 1; createOrUpdateDevice(action.addr, device_flags_connect, TheengsDecoder::BLE_ID_NUM::SBS1, 1); @@ -1405,7 +1398,8 @@ void MQTTtoBTAction(JsonObject& BTdata) { strcpy(action.addr, (const char*)BTdata["ble_write_address"]); action.service = NimBLEUUID((const char*)BTdata["ble_write_service"]); action.characteristic = NimBLEUUID((const char*)BTdata["ble_write_char"]); - action.value = std::string((const char*)BTdata["ble_write_value"]); + std::string val = BTdata["ble_write_value"].as(); // Fix #1694 + action.value = val; action.write = true; Log.trace(F("BLE ACTION Write" CR)); } else if (BTdata.containsKey("ble_read_address") && @@ -1472,7 +1466,7 @@ void MQTTtoBT(char* topicOri, JsonObject& BTdata) { // json object decoding if (BTdata.containsKey("lowpowermode")) { changelowpowermode((int)BTdata["lowpowermode"]); } - + } else if (cmpToMainTopic(topicOri, subjectMQTTtoBT)) { MQTTtoBTAction(BTdata); } } diff --git a/main/ZsensorGPIOInput.ino b/main/ZsensorGPIOInput.ino index a1ab7a6bcc..6cc5af7d06 100644 --- a/main/ZsensorGPIOInput.ino +++ b/main/ZsensorGPIOInput.ino @@ -66,6 +66,15 @@ void MeasureGPIOInput() { resetTime = millis(); } else if ((millis() - resetTime) > 3000) { Log.trace(F("Button Held" CR)); + InfoIndicatorOFF(); + SendReceiveIndicatorOFF(); +// Switching off the relay during reset or failsafe operations +# ifdef ZactuatorONOFF + uint8_t level = digitalRead(ACTUATOR_ONOFF_GPIO); + if (level == ACTUATOR_ON) { + ActuatorTrigger(); + } +# endif Log.notice(F("Erasing ESP Config, restarting" CR)); setup_wifimanager(true); } diff --git a/main/certs/default_client_cert.h b/main/certs/default_client_cert.h new file mode 100644 index 0000000000..f7e6613a62 --- /dev/null +++ b/main/certs/default_client_cert.h @@ -0,0 +1,5 @@ +const char* ss_client_cert PROGMEM = R"EOF(" +-----BEGIN CERTIFICATE----- +... +-----END CERTIFICATE----- +")EOF"; diff --git a/main/certs/default_client_key.h b/main/certs/default_client_key.h new file mode 100644 index 0000000000..6a18da7a2b --- /dev/null +++ b/main/certs/default_client_key.h @@ -0,0 +1,5 @@ +const char* ss_client_key PROGMEM = R"EOF(" +-----BEGIN RSA PRIVATE KEY----- +... +-----END RSA PRIVATE KEY----- +")EOF"; diff --git a/main/certs/default_ota_cert.h b/main/certs/default_ota_cert.h new file mode 100644 index 0000000000..b0601654db --- /dev/null +++ b/main/certs/default_ota_cert.h @@ -0,0 +1,26 @@ +// The certificate must be in PEM ascii format. +// The default certificate is for github. +const char* OTAserver_cert PROGMEM = R"EOF(" +-----BEGIN CERTIFICATE----- +MIIDrzCCApegAwIBAgIQCDvgVpBCRrGhdWrJWZHHSjANBgkqhkiG9w0BAQUFADBh +MQswCQYDVQQGEwJVUzEVMBMGA1UEChMMRGlnaUNlcnQgSW5jMRkwFwYDVQQLExB3 +d3cuZGlnaWNlcnQuY29tMSAwHgYDVQQDExdEaWdpQ2VydCBHbG9iYWwgUm9vdCBD +QTAeFw0wNjExMTAwMDAwMDBaFw0zMTExMTAwMDAwMDBaMGExCzAJBgNVBAYTAlVT +MRUwEwYDVQQKEwxEaWdpQ2VydCBJbmMxGTAXBgNVBAsTEHd3dy5kaWdpY2VydC5j +b20xIDAeBgNVBAMTF0RpZ2lDZXJ0IEdsb2JhbCBSb290IENBMIIBIjANBgkqhkiG +9w0BAQEFAAOCAQ8AMIIBCgKCAQEA4jvhEXLeqKTTo1eqUKKPC3eQyaKl7hLOllsB +CSDMAZOnTjC3U/dDxGkAV53ijSLdhwZAAIEJzs4bg7/fzTtxRuLWZscFs3YnFo97 +nh6Vfe63SKMI2tavegw5BmV/Sl0fvBf4q77uKNd0f3p4mVmFaG5cIzJLv07A6Fpt +43C/dxC//AH2hdmoRBBYMql1GNXRor5H4idq9Joz+EkIYIvUX7Q6hL+hqkpMfT7P +T19sdl6gSzeRntwi5m3OFBqOasv+zbMUZBfHWymeMr/y7vrTC0LUq7dBMtoM1O/4 +gdW7jVg/tRvoSSiicNoxBN33shbyTApOB6jtSj1etX+jkMOvJwIDAQABo2MwYTAO +BgNVHQ8BAf8EBAMCAYYwDwYDVR0TAQH/BAUwAwEB/zAdBgNVHQ4EFgQUA95QNVbR +TLtm8KPiGxvDl7I90VUwHwYDVR0jBBgwFoAUA95QNVbRTLtm8KPiGxvDl7I90VUw +DQYJKoZIhvcNAQEFBQADggEBAMucN6pIExIK+t1EnE9SsPTfrgT1eXkIoyQY/Esr +hMAtudXH/vTBH1jLuG2cenTnmCmrEbXjcKChzUyImZOMkXDiqw8cvpOp/2PV5Adg +06O/nVsJ8dWO41P0jmP6P6fbtGbfYmbW0W5BjfIttep3Sp+dWOIrWcBAI+0tKIJF +PnlUkiaY4IBIqDfv8NZ5YBberOgOzW6sRBc4L0na4UU+Krk2U886UAb3LujEV0ls +YSEY1QSteDwsOoBrp+uvFRTp2InBuThs4pFsiv9kuXclVzDAGySj4dzp30d8tbQk +CAUw7C29C79Fv1C5qfPrmAESrciIxpg0X40KPMbp1ZWVbd4= +-----END CERTIFICATE----- +")EOF"; diff --git a/main/certs/default_server_cert.h b/main/certs/default_server_cert.h new file mode 100644 index 0000000000..f51eea77d7 --- /dev/null +++ b/main/certs/default_server_cert.h @@ -0,0 +1,5 @@ +const char* ss_server_cert PROGMEM = R"EOF(" +-----BEGIN CERTIFICATE----- +... +-----END CERTIFICATE----- +")EOF"; diff --git a/main/config_BT.h b/main/config_BT.h index 45dc5c42af..ebde35a52d 100644 --- a/main/config_BT.h +++ b/main/config_BT.h @@ -46,6 +46,7 @@ extern int btQueueLengthCount; /*-----------BT TOPICS & COMPILATION PARAMETERS-----------*/ #define subjectBTtoMQTT "/BTtoMQTT" #define subjectMQTTtoBTset "/commands/MQTTtoBT/config" +#define subjectMQTTtoBT "/commands/MQTTtoBT" // Uncomment to send undecoded device data to another gateway device for decoding // #define MQTTDecodeTopic "undecoded" #ifndef UseExtDecoder diff --git a/main/config_RN8209.h b/main/config_RN8209.h index c8cd17ff96..e24483085c 100644 --- a/main/config_RN8209.h +++ b/main/config_RN8209.h @@ -48,7 +48,7 @@ extern void RN8209toMQTT(); #endif #ifndef TimeOutWDTRN8209 -# define TimeOutWDTRN8209 60 // time out if RN8209 task is stuck in seconds (should be more than TimeBetweenReadingRN8209/1000), the WDT will reset the ESP +# define TimeOutWDTRN8209 5 // time out if RN8209 task is stuck in seconds (should be more than TimeBetweenReadingRN8209/1000), the WDT will reset the ESP #endif #ifndef TimeBetweenPublishingRN8209 # define TimeBetweenPublishingRN8209 60000 // time between 2 RN8209 publishing in ms diff --git a/main/main.ino b/main/main.ino index b9083bd1d0..1f6616e5e8 100644 --- a/main/main.ino +++ b/main/main.ino @@ -224,7 +224,7 @@ unsigned long timer_led_measures = 0; static void* eClient = nullptr; static unsigned long last_ota_activity_millis = 0; #if defined(ESP8266) || defined(ESP32) - +bool failSafeMode = false; static bool mqtt_secure = MQTT_SECURE_DEFAULT; static bool mqtt_cert_validate = MQTT_CERT_VALIDATE_DEFAULT; static uint8_t mqtt_ss_index = MQTT_SECURE_SELF_SIGNED_INDEX_DEFAULT; @@ -400,6 +400,16 @@ void pub(const char* topicori, const char* payload, bool retainFlag) { */ void pub(const char* topicori, JsonObject& data) { String dataAsString = ""; + +#if defined(ESP8266) || defined(ESP32) +# if message_UTCtimestamp == true + data["UTCtime"] = UTCtimestamp(); +# endif +# if message_unixtimestamp == true + data["unixtime"] = unixtimestamp(); +# endif +#endif + serializeJson(data, dataAsString); Log.notice(F("Send on %s msg %s" CR), topicori, dataAsString.c_str()); String topic = String(mqtt_topic) + String(gateway_name) + String(topicori); @@ -493,11 +503,7 @@ void pubMQTT(const char* topic, const char* payload, bool retainFlag) { if (client.connected()) { SendReceiveIndicatorON(); Log.trace(F("[ OMG->MQTT ] topic: %s msg: %s " CR), topic, payload); -#if AWS_IOT - client.publish(topic, payload); // AWS IOT doesn't support retain flag for the moment -#else client.publish(topic, payload, retainFlag); -#endif } else { Log.warning(F("Client not connected, aborting the publication" CR)); } @@ -716,7 +722,7 @@ void callback(char* topic, byte* payload, unsigned int length) { } #if defined(ESP32) && (defined(WifiGMode) || defined(WifiPower)) -void setESP32WifiPorotocolTxPower() { +void setESPWifiProtocolTxPower() { //Reduce WiFi interference when using ESP32 using custom WiFi mode and tx power //https://github.com/espressif/arduino-esp32/search?q=WIFI_PROTOCOL_11G //https://www.letscontrolit.com/forum/viewtopic.php?t=671&start=20 @@ -757,6 +763,48 @@ void setESP32WifiPorotocolTxPower() { } #endif +#if defined(ESP8266) && (defined(WifiGMode) || defined(WifiPower)) +void setESPWifiProtocolTxPower() { +# if WifiGMode == true + if (!wifi_set_phy_mode(PHY_MODE_11G)) { + Log.error(F("Failed to change WifiMode." CR)); + } +# endif + +# if WifiGMode == false + if (!wifi_set_phy_mode(PHY_MODE_11N)) { + Log.error(F("Failed to change WifiMode." CR)); + } +# endif + + phy_mode_t getprotocol = wifi_get_phy_mode(); + if (getprotocol == PHY_MODE_11N) { + Log.notice(F("WiFi_Protocol_11n" CR)); + } + if (getprotocol == PHY_MODE_11G) { + Log.notice(F("WiFi_Protocol_11g" CR)); + } + if (getprotocol == PHY_MODE_11B) { + Log.notice(F("WiFi_Protocol_11b" CR)); + } + +# ifdef WifiPower + Log.notice(F("Requested WiFi power level: %i dBm" CR), WifiPower); + + int i_dBm = int(WifiPower * 4.0f); + + // i_dBm 82 == 20.5 dBm + if (i_dBm > 82) { + i_dBm = 82; + } else if (i_dBm < 0) { + i_dBm = 0; + } + + system_phy_set_max_tpw((uint8_t)i_dBm); +# endif +} +#endif + void setup() { //Launch serial for debugging purposes Serial.begin(SERIAL_BAUD); @@ -841,26 +889,14 @@ void setup() { modules.add(ZactuatorONOFF); # endif - String s = WiFi.macAddress(); -# ifdef USE_MAC_AS_GATEWAY_NAME - sprintf(gateway_name, "%.2s%.2s%.2s%.2s%.2s%.2s", - s.c_str(), s.c_str() + 3, s.c_str() + 6, s.c_str() + 9, s.c_str() + 12, s.c_str() + 15); - snprintf(WifiManager_ssid, MAC_NAME_MAX_LEN, "%s_%.2s%.2s", Gateway_Short_Name, s.c_str(), s.c_str() + 3); - strcpy(ota_hostname, WifiManager_ssid); - Log.notice(F("OTA Hostname: %s.local" CR), ota_hostname); -# endif -# ifdef WM_PWD_FROM_MAC // From ESP Mac Address, last 8 digits as the password - sprintf(WifiManager_password, "%.2s%.2s%.2s%.2s", - s.c_str() + 6, s.c_str() + 9, s.c_str() + 12, s.c_str() + 15); -# endif - # ifdef ESP32_ETHERNET setup_ethernet_esp32(); # else // WIFI ESP # if defined(ESPWifiManualSetup) setup_wifi(); # else - setup_wifimanager(false); + // In failSafeMode we don't want to setup wifi manager as it has already been done before + if (!failSafeMode) setup_wifimanager(false); # endif Log.trace(F("OpenMQTTGateway mac: %s" CR), WiFi.macAddress().c_str()); Log.trace(F("OpenMQTTGateway ip: %s" CR), WiFi.localIP().toString().c_str()); @@ -1094,8 +1130,8 @@ bool wifi_reconnect_bypass() { Log.notice(F("Attempting Wifi connection with saved AP: %d" CR), wifi_autoreconnect_cnt); WiFi.begin(); -# if defined(ESP32) && (defined(WifiGMode) || defined(WifiPower)) - setESP32WifiPorotocolTxPower(); +# if (defined(ESP8266) || defined(ESP32)) && (defined(WifiGMode) || defined(WifiPower)) + setESPWifiProtocolTxPower(); # endif delay(1000); wifi_autoreconnect_cnt++; @@ -1291,7 +1327,7 @@ void saveConfigCallback() { # ifdef TRIGGER_GPIO /** - * Identify a long button press to trigger a reset + * Identify a long button press to trigger a reset or a failsafe mode * */ void blockingWaitForReset() { if (digitalRead(TRIGGER_GPIO) == LOW) { @@ -1301,8 +1337,31 @@ void blockingWaitForReset() { delay(3000); // reset delay hold if (digitalRead(TRIGGER_GPIO) == LOW) { Log.trace(F("Button Held" CR)); - Log.notice(F("Erasing ESP Config, restarting" CR)); - setup_wifimanager(true); +// Switching off the relay during reset or failsafe operations +# ifdef ZactuatorONOFF + uint8_t level = digitalRead(ACTUATOR_ONOFF_GPIO); + if (level == ACTUATOR_ON) { + ActuatorTrigger(); + } +# endif + InfoIndicatorOFF(); + SendReceiveIndicatorOFF(); + // Checking if the flash has already been erased to identify if we erase it or go into failsafe mode + // going to failsafe mode is done by doing a long button press from a state where the flash has already been erased + if (SPIFFS.begin()) { + Log.trace(F("mounted file system" CR)); + if (SPIFFS.exists("/config.json")) { + Log.notice(F("Erasing ESP Config, restarting" CR)); + setup_wifimanager(true); + } + } + delay(30000); + if (digitalRead(TRIGGER_GPIO) == LOW) { + Log.notice(F("Going into failsafe mode without peripherals" CR)); + // Failsafe mode enable to connect to Wifi or change the firmware without the peripherals setup + failSafeMode = true; + setup_wifimanager(false); + } } } } @@ -1360,6 +1419,19 @@ void setup_wifimanager(bool reset_settings) { if (reset_settings) eraseAndRestart(); + String s = WiFi.macAddress(); +# ifdef USE_MAC_AS_GATEWAY_NAME + sprintf(gateway_name, "%.2s%.2s%.2s%.2s%.2s%.2s", + s.c_str(), s.c_str() + 3, s.c_str() + 6, s.c_str() + 9, s.c_str() + 12, s.c_str() + 15); + snprintf(WifiManager_ssid, MAC_NAME_MAX_LEN, "%s_%.2s%.2s", Gateway_Short_Name, s.c_str(), s.c_str() + 3); + strcpy(ota_hostname, WifiManager_ssid); + Log.notice(F("OTA Hostname: %s.local" CR), ota_hostname); +# endif +# ifdef WM_PWD_FROM_MAC // From ESP Mac Address, last 8 digits as the password + sprintf(WifiManager_password, "%.2s%.2s%.2s%.2s", + s.c_str() + 6, s.c_str() + 9, s.c_str() + 12, s.c_str() + 15); +# endif + //read configuration from FS json Log.trace(F("mounting FS..." CR)); @@ -1960,14 +2032,6 @@ String stateMeasures() { StaticJsonDocument jsonBuffer; JsonObject SYSdata = jsonBuffer.to(); SYSdata["uptime"] = uptime(); -# if defined(ESP8266) || defined(ESP32) -# if message_UTCtimestamp == true - SYSdata["UTCtime"] = UTCtimestamp(); -# endif -# if message_unixtimestamp == true - SYSdata["unixtime"] = unixtimestamp(); -# endif -# endif SYSdata["version"] = OMG_VERSION; # ifdef ZmqttDiscovery @@ -2250,6 +2314,7 @@ String latestVersion; # include "zzHTTPUpdate.h" +# ifdef CHECK_OTA_UPDATE /** * Check on a server the latest version information to build a releaseLink * The release link will be used when the user trigger an OTA update command @@ -2291,13 +2356,17 @@ bool checkForUpdates() { } Log.notice(F("Update check done, free heap: %d"), ESP.getFreeHeap()); } + +# else +bool checkForUpdates() {} +# endif # elif ESP8266 # include # endif void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) { if (strstr(topicOri, subjectMQTTtoSYSupdate) != NULL) { - const char* version = HttpsFwUpdateData["version"]; + const char* version = HttpsFwUpdateData["version"] | "latest"; if (version && ((strlen(version) != strlen(OMG_VERSION)) || strcmp(version, OMG_VERSION) != 0)) { const char* url = HttpsFwUpdateData["url"]; String systemUrl; @@ -2348,18 +2417,19 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) { pub(subjectRLStoMQTT, jsondata); const char* ota_cert = HttpsFwUpdateData["server_cert"]; - if (!ota_cert) { + if (!ota_cert && !strstr(url, "http:")) { if (ota_server_cert.length() > 0) { - Log.notice(F("using stored cert" CR)); + Log.notice(F("Using stored cert" CR)); ota_cert = ota_server_cert.c_str(); } else { - Log.notice(F("using config cert" CR)); + Log.notice(F("Using config cert" CR)); ota_cert = OTAserver_cert; } } t_httpUpdate_return result = HTTP_UPDATE_FAILED; if (strstr(url, "http:")) { + Log.notice(F("Http update" CR)); WiFiClient update_client; # ifdef ESP32 httpUpdate.setFollowRedirects(HTTPC_STRICT_FOLLOW_REDIRECTS); @@ -2464,8 +2534,8 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding Log.warning(F("Attempting connection to new AP %s" CR), (const char*)SYSdata["wifi_ssid"]); WiFi.begin((const char*)SYSdata["wifi_ssid"], (const char*)SYSdata["wifi_pass"]); -# if defined(ESP32) && (defined(WifiGMode) || defined(WifiPower)) - setESP32WifiPorotocolTxPower(); +# if (defined(ESP8266) || defined(ESP32)) && (defined(WifiGMode) || defined(WifiPower)) + setESPWifiProtocolTxPower(); # endif WiFi.waitForConnectResult(); @@ -2473,8 +2543,8 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding Log.error(F("Failed to connect to new AP; falling back" CR)); WiFi.disconnect(true); WiFi.begin(prev_ssid.c_str(), prev_pass.c_str()); -# if defined(ESP32) && (defined(WifiGMode) || defined(WifiPower)) - setESP32WifiPorotocolTxPower(); +# if (defined(ESP8266) || defined(ESP32)) && (defined(WifiGMode) || defined(WifiPower)) + setESPWifiProtocolTxPower(); # endif } ESPRestart(7); diff --git a/platformio.ini b/platformio.ini index 46dfa97fd4..6db51ece5f 100644 --- a/platformio.ini +++ b/platformio.ini @@ -151,7 +151,7 @@ somfy_remote=Somfy_Remote_Lib@0.3.0 rtl_433_ESP = https://github.com/NorthernMan54/rtl_433_ESP.git#v0.3.0 emodbus = miq19/eModbus@1.0.0 gfSunInverter = https://github.com/BlackSmith/GFSunInverter.git#v1.0.1 -decoder = https://github.com/theengs/decoder.git +decoder = https://github.com/theengs/decoder.git#v1.5.5 ssd1306 = https://github.com/ThingPulse/esp8266-oled-ssd1306.git#f96fd6a lm75 = jeremycole/I2C Temperature Sensors derived from the LM75@^1.0.3 rn8209 = https://github.com/theengs/RN8209C-SDK.git#arduino diff --git a/scripts/gen_wu.py b/scripts/gen_wu.py index d5e3365f7f..ab5f85c03f 100644 --- a/scripts/gen_wu.py +++ b/scripts/gen_wu.py @@ -124,7 +124,7 @@ for item in range(len(assets)): name = assets[item]['name'] - if 'firmware.bin' in name and ('esp32' in name or 'ttgo' in name or 'heltec' in name or 'thingpulse' in name or 'lilygo' in name or 'shelly' in name): + if 'firmware.bin' in name and ('esp32' in name or 'ttgo' in name or 'heltec' in name or 'thingpulse' in name or 'lilygo' in name or 'shelly' in name or 'lolin_c3' in name or 'tinypico' in name): fw = name.split('-firmware')[0] man_file = fw + '.manifest.json' fw_url = assets[item]['browser_download_url'] diff --git a/scripts/gen_wu_dev.py b/scripts/gen_wu_dev.py index 054d3020a4..9457d0941a 100644 --- a/scripts/gen_wu_dev.py +++ b/scripts/gen_wu_dev.py @@ -111,7 +111,7 @@ output_file.write(boot_bin.content) for name in os.listdir(bin_path): - if 'firmware.bin' in name and ('esp32' in name or 'ttgo' in name or 'heltec' in name or 'thingpulse' in name or 'lilygo' in name or 'shelly' in name): + if 'firmware.bin' in name and ('esp32' in name or 'ttgo' in name or 'heltec' in name or 'thingpulse' in name or 'lilygo' in name or 'shelly' in name or 'lolin_c3' in name or 'tinypico' in name): fw = name.split('-firmware')[0] man_file = fw + '.manifest.json' print('Bin name:' + name)