mirror of
https://github.com/1technophile/OpenMQTTGateway.git
synced 2026-02-20 00:32:04 +01:00
[LED] Refactor LED handling (#2051)
Refactor LED handling into a library Use a task instead of relying on the loop for precise timing Co-authored-by: Florian <1technophile@users.noreply.github.com>
This commit is contained in:
1
.gitignore
vendored
1
.gitignore
vendored
@@ -9,6 +9,7 @@ main/certs/private*
|
||||
lib/*
|
||||
!lib/esp32-bt-lib
|
||||
!lib/TheengsUtils
|
||||
!lib/LEDManager
|
||||
CMakeLists.txt
|
||||
dependencies.lock
|
||||
sdkconfig.*
|
||||
|
||||
@@ -300,17 +300,97 @@ Minimum: 0, Maximum: 255, Default defined by DEFAULT_ADJ_BRIGHTNESS
|
||||
|
||||
`mosquitto_pub -t "home/OpenMQTTGateway/commands/MQTTtoSYS/config" -m '{"brightness":200}'`
|
||||
|
||||
## State LED usage
|
||||
## Understanding LED Indicators in OpenMQTTGateway
|
||||
With boards having one or several RGB Led, OpenMQTTGateway uses them to provide visual feedback about its current state. This guide will help you interpret these LED signals to understand what's happening with your gateway.
|
||||
|
||||
The gateway can support up to 3 LED to display its operating state:
|
||||
* LED_INFO
|
||||
switched ON when network and MQTT connection are OK
|
||||
5s ON, 5s OFF when MQTT is disconnected
|
||||
2s ON, 2s OFF when NETWORK is disconnected
|
||||
## LED Color Guide
|
||||
OpenMQTTGateway uses a variety of colors to indicate different states:
|
||||
|
||||
* LED_RECEIVE
|
||||
Blink for `TimeLedON` 1s when the gateway receive a signal from one of its module so as to send to MQTT
|
||||
Green (0x00FF00): Indicates normal operation or successful connections
|
||||
Blue (0x0000FF): Shows processing or offline status
|
||||
Orange (0xFFA500): Indicates waiting states or minor issues
|
||||
Yellow (0xFFFF00): Used during the onboarding process
|
||||
Red (0xFF0000): Signals an error state
|
||||
Magenta (0xFF00FF): Indicates local Over-The-Air (OTA) updates
|
||||
Purple (0x8000FF): Shows remote OTA updates are in progress
|
||||
|
||||
* LED_SEND
|
||||
Blink for `TimeLedON` 1s when the gateway send a signal with one of its module from an MQTT command
|
||||
## Understanding Gateway States
|
||||
Here's what different LED behaviors mean:
|
||||
|
||||
### Power On
|
||||
|
||||
Color: Green
|
||||
Behavior: Solid light
|
||||
Meaning: The gateway is powered and operational
|
||||
|
||||
### Processing
|
||||
|
||||
Color: Blue
|
||||
Behavior: Blinking (3 times)
|
||||
Meaning: The gateway is processing data
|
||||
|
||||
### Waiting for Onboarding
|
||||
|
||||
Color: Orange
|
||||
Behavior: Solid light
|
||||
Meaning: The gateway is ready to be set up
|
||||
|
||||
### Onboarding in Progress
|
||||
|
||||
Color: Yellow
|
||||
Behavior: Solid light
|
||||
Meaning: The gateway is being configured
|
||||
|
||||
### Network Connected
|
||||
|
||||
Color: Green
|
||||
Behavior: Solid light
|
||||
Meaning: Successfully connected to the network
|
||||
|
||||
### Network Disconnected
|
||||
|
||||
Color: Orange
|
||||
Behavior: Blinking
|
||||
Meaning: Lost connection to the network
|
||||
|
||||
### MQTT Broker Connected
|
||||
|
||||
Color: Green
|
||||
Behavior: Solid light
|
||||
Meaning: Successfully connected to the MQTT broker
|
||||
|
||||
### MQTT Broker Disconnected
|
||||
|
||||
Color: Orange
|
||||
Behavior: Blinking
|
||||
Meaning: Lost connection to the MQTT broker
|
||||
|
||||
### Offline
|
||||
|
||||
Color: Blue
|
||||
Behavior: Blinking
|
||||
Meaning: The gateway is offline
|
||||
|
||||
### Local OTA Update
|
||||
|
||||
Color: Magenta
|
||||
Behavior: Blinking
|
||||
Meaning: A local Over-The-Air update is in progress
|
||||
|
||||
### Remote OTA Update
|
||||
|
||||
Color: Purple
|
||||
Behavior: Blinking
|
||||
Meaning: A remote Over-The-Air update is in progress
|
||||
|
||||
### Error
|
||||
|
||||
Color: Red
|
||||
Behavior: Blinking (3 times)
|
||||
Meaning: An error has occurred
|
||||
|
||||
### Actuator On/Off
|
||||
|
||||
Color: Green
|
||||
Behavior: Depends on actuator state
|
||||
Meaning: Indicates the state of a connected actuator
|
||||
176
environments.ini
176
environments.ini
@@ -62,8 +62,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DESP32_ETHERNET=true'
|
||||
'-DETH_PHY_TYPE=ETH_PHY_LAN8720'
|
||||
'-DETH_PHY_ADDR=0'
|
||||
@@ -71,13 +71,13 @@ build_flags =
|
||||
'-DETH_PHY_MDC=23'
|
||||
'-DETH_PHY_MDIO=18'
|
||||
'-DETH_CLK_MODE=ETH_CLOCK_GPIO16_OUT'
|
||||
'-DANEOPIX_IND_DATA_GPIO=32'
|
||||
'-DANEOPIX_IND_NUM_LEDS=4'
|
||||
'-DANEOPIX_INFO_LED=0'
|
||||
'-DANEOPIX_SEND_RECEIVE_LED=1'
|
||||
'-DANEOPIX_ERROR_LED=1'
|
||||
'-DANEOPIX_BRIGHTNESS=10'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=32'
|
||||
'-DLED_ADDRESSABLE_NUM=4'
|
||||
'-DLED_BROKER=0'
|
||||
'-DLED_PROCESSING=1'
|
||||
'-DLED_ERROR=1'
|
||||
'-DDEFAULT_ADJ_BRIGHTNESS=10'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DAttemptBLEConnect=false'
|
||||
'-DUSE_MAC_AS_GATEWAY_NAME'
|
||||
'-DGATEWAY_MANUFACTURER="Theengs"'
|
||||
@@ -100,8 +100,6 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DESP32_ETHERNET=true'
|
||||
'-DETH_PHY_TYPE=ETH_PHY_LAN8720'
|
||||
'-DETH_PHY_ADDR=0'
|
||||
@@ -109,13 +107,14 @@ build_flags =
|
||||
'-DETH_PHY_MDC=23'
|
||||
'-DETH_PHY_MDIO=18'
|
||||
'-DETH_CLK_MODE=ETH_CLOCK_GPIO16_OUT'
|
||||
'-DANEOPIX_IND_DATA_GPIO=32'
|
||||
'-DANEOPIX_IND_NUM_LEDS=4'
|
||||
'-DANEOPIX_INFO_LED=0'
|
||||
'-DANEOPIX_SEND_RECEIVE_LED=1'
|
||||
'-DANEOPIX_ERROR_LED=1'
|
||||
'-DANEOPIX_BRIGHTNESS=100'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=32'
|
||||
'-DLED_ADDRESSABLE_NUM=4'
|
||||
'-DLED_ERROR=3'
|
||||
'-DLED_PROCESSING=3'
|
||||
'-DLED_BROKER=2'
|
||||
'-DLED_NETWORK=1'
|
||||
'-DLED_POWER=0'
|
||||
'-DAttemptBLEConnect=false'
|
||||
'-DTRIGGER_GPIO=4'
|
||||
'-DUSE_MAC_AS_GATEWAY_NAME'
|
||||
@@ -331,8 +330,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_ESP32_BLE"'
|
||||
custom_description = Regular BLE gateway with adaptive scanning activated, automatically adapts the scan parameters depending on your devices
|
||||
|
||||
@@ -348,8 +347,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_ESP32_BLE"'
|
||||
'-DMQTT_BROKER_MODE=true'
|
||||
custom_description = MQTT Broker with BLE gateway with adaptive scanning activated, automatically adapts the scan parameters depending on your devices
|
||||
@@ -366,8 +365,8 @@ build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DBLEDecoder=false'
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_ESP32_BLE"'
|
||||
'-DMQTTDecodeTopic="undecoded"'
|
||||
custom_description = BLE gateway with the decoding offloaded to Theengs Gateway
|
||||
@@ -385,8 +384,8 @@ build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-UZmqttDiscovery="HADiscovery"'
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DARDUINO_LOOP_STACK_SIZE=17500'
|
||||
'-DMQTT_SECURE_DEFAULT=true'
|
||||
'-DMQTT_CERT_VALIDATE_DEFAULT=true'
|
||||
@@ -410,8 +409,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=13'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=13'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_ESP32_FTH_BLE"'
|
||||
custom_description = BLE Gateway
|
||||
custom_hardware = ESP32 Feather Adafruit
|
||||
@@ -428,8 +427,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=22'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=22'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_LOLIN32LITE_BLE"'
|
||||
;; Low power parameters, uncomment and fill credentials
|
||||
'-DDEFAULT_LOW_POWER_MODE=INTERVAL'
|
||||
@@ -458,8 +457,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=33'
|
||||
'-DLED_SEND_RECEIVE_ON=1'
|
||||
'-DLED_PIN=33'
|
||||
'-DLED_PIN_ON=1'
|
||||
'-DTRIGGER_GPIO=34'
|
||||
'-DESP32_ETHERNET=true'
|
||||
'-DGateway_Name="OMG_ESP32_OLM_GTWE"'
|
||||
@@ -553,8 +552,8 @@ build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DZgatewayIR="IR"'
|
||||
'-DLED_SEND_RECEIVE=19'
|
||||
'-DLED_SEND_RECEIVE_ON=1'
|
||||
'-DLED_PIN=19'
|
||||
'-DLED_PIN_ON=1'
|
||||
'-DTRIGGER_GPIO=35'
|
||||
'-DIR_EMITTER_GPIO=17'
|
||||
'-DDEFAULT_LOW_POWER_MODE=ALWAYS_ON'
|
||||
@@ -578,7 +577,7 @@ build_flags =
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DZsensorGPIOInput="GPIOInput"'
|
||||
'-DZboardM5STACK="M5Stack"'
|
||||
'-DLED_SEND_RECEIVE=15'
|
||||
'-DLED_PIN=15'
|
||||
'-DTRIGGER_GPIO=37'
|
||||
'-DSLEEP_BUTTON=38'
|
||||
'-DINPUT_GPIO=39'
|
||||
@@ -626,8 +625,8 @@ build_flags =
|
||||
'-DZboardM5STICKC="M5StickC"'
|
||||
'-DACTUATOR_ONOFF_GPIO=10'
|
||||
'-DINPUT_GPIO=37'
|
||||
'-DLED_SEND_RECEIVE=10'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=10'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DSLEEP_BUTTON=39'
|
||||
'-DTRIGGER_GPIO=39'
|
||||
'-DIR_EMITTER_INVERTED=true'
|
||||
@@ -657,8 +656,8 @@ build_flags =
|
||||
'-DZboardM5STICKCP="M5StickCP"'
|
||||
'-DACTUATOR_ONOFF_GPIO=10'
|
||||
'-DINPUT_GPIO=37'
|
||||
'-DLED_SEND_RECEIVE=10'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=10'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DSLEEP_BUTTON=39'
|
||||
'-DTRIGGER_GPIO=39'
|
||||
'-DIR_EMITTER_INVERTED=true'
|
||||
@@ -687,9 +686,14 @@ build_flags =
|
||||
'-DTRIGGER_GPIO=39'
|
||||
'-DSLEEP_BUTTON=39'
|
||||
'-DIR_EMITTER_GPIO=12'
|
||||
'-DANEOPIX_IND_DATA_GPIO=27'
|
||||
'-DANEOPIX_IND_NUM_LEDS=25'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=27'
|
||||
'-DLED_ADDRESSABLE_NUM=25'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DLED_ERROR=4'
|
||||
'-DLED_PROCESSING=3'
|
||||
'-DLED_BROKER=2'
|
||||
'-DLED_NETWORK=1'
|
||||
'-DLED_POWER=0'
|
||||
'-DGateway_Name="OMG_ATOM_M"'
|
||||
board_upload.speed = 1500000
|
||||
custom_description = Compact enclosure ESP32 with BLE gateway
|
||||
@@ -713,9 +717,9 @@ build_flags =
|
||||
'-DTRIGGER_GPIO=39'
|
||||
'-DSLEEP_BUTTON=39'
|
||||
'-DIR_EMITTER_GPIO=12'
|
||||
'-DANEOPIX_IND_DATA_GPIO=27'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=27'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DGateway_Name="OMG_ATOM_L"'
|
||||
board_upload.speed = 1500000
|
||||
custom_description = Compact enclosure ESP32 with BLE gateway
|
||||
@@ -1145,11 +1149,11 @@ build_flags =
|
||||
'-DZgatewayLORA="LORA"'
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DGateway_Name="OMG_ESP32_BLE_LORA"'
|
||||
'-DLED_SEND_RECEIVE=21' # T-BEAM board V0.5
|
||||
# '-DLED_SEND_RECEIVE=14' # T-BEAM board V0.7
|
||||
# '-DLED_SEND_RECEIVE=4' # T-BEAM board V1.0+
|
||||
'-DLED_PIN=21' # T-BEAM board V0.5
|
||||
# '-DLED_PIN=14' # T-BEAM board V0.7
|
||||
# '-DLED_PIN=4' # T-BEAM board V1.0+
|
||||
'-DTimeLedON=0.05'
|
||||
'-DLED_SEND_RECEIVE_ON=1' # Set 0 for board V1.0+
|
||||
'-DLED_PIN_ON=1' # Set 0 for board V1.0+
|
||||
# for V0.5 and V0.7 ONLY (V1.0+ as onboard AXP202 dedicated chip, need driver)
|
||||
# it's a 100K/100K divider (so 2 divider) and connected to GPIO35
|
||||
'-DZsensorADC="ADC"'
|
||||
@@ -1173,9 +1177,9 @@ build_flags =
|
||||
'-DZgatewayLORA="LORA"'
|
||||
'-DLORA_BAND=868E6'
|
||||
'-DGateway_Name="OMG_ESP32_LORA"'
|
||||
'-DLED_SEND_RECEIVE=25'
|
||||
'-DLED_PIN=25'
|
||||
'-DTimeLedON=0.1'
|
||||
'-DLED_SEND_RECEIVE_ON=1'
|
||||
'-DLED_PIN_ON=1'
|
||||
; *** ssd1306 Display Options ***
|
||||
'-DZdisplaySSD1306="HELTEC_SSD1306"'
|
||||
; '-DLOG_TO_OLED=true' ; Enable log to OLED
|
||||
@@ -1352,7 +1356,7 @@ build_flags =
|
||||
${com-esp.build_flags}
|
||||
'-DZgatewayIR="IR"'
|
||||
'-DTRIGGER_GPIO=13'
|
||||
'-DLED_SEND_RECEIVE=4'
|
||||
'-DLED_PIN=4'
|
||||
'-DIR_EMITTER_GPIO=14'
|
||||
'-DIR_RECEIVER_GPIO=5'
|
||||
'-UMQTTsetMQTT' ;We remove this function to have sufficient FLASH available for OTA, you should also use ESPWifiManualSetup and 'board_build.ldscript = eagle.flash.1m64.ld' to save flash memory and have OTA working
|
||||
@@ -1565,8 +1569,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DTimeBtwRead=0'
|
||||
'-DScan_duration=3000'
|
||||
'-DAttemptBLEConnect=false'
|
||||
@@ -1585,9 +1589,9 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DANEOPIX_IND_DATA_GPIO=48'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=48'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DNO_INT_TEMP_READING=true' ; Internal temperature reading not building on ESP32 C3 or S3
|
||||
'-DGateway_Name="OMG_ESP32_BLE"'
|
||||
custom_description = BLE gateway on the S3
|
||||
@@ -1605,9 +1609,9 @@ build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DZgatewayIR="IR"'
|
||||
'-DANEOPIX_IND_DATA_GPIO=35'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=35'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DTRIGGER_GPIO=41'
|
||||
'-DIR_EMITTER_GPIO=12'
|
||||
'-DNO_INT_TEMP_READING=true' ; Internal temperature reading not building on ESP32 C3 or S3
|
||||
@@ -1628,9 +1632,9 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DANEOPIX_IND_DATA_GPIO=8'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=8'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DNO_INT_TEMP_READING=true' ; Internal temperature reading not building on ESP32 C3 or S3
|
||||
'-DGateway_Name="OMG_ESP32_BLE"'
|
||||
custom_description = BLE gateway on the C3
|
||||
@@ -1647,7 +1651,7 @@ build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_INFO=19'
|
||||
'-DLED_SEND_RECEIVE=20'
|
||||
'-DLED_PIN=20'
|
||||
'-DNO_INT_TEMP_READING=true' ; Internal temperature reading not building on ESP32 C3 or S3
|
||||
'-DGateway_Name="OMG_AirM2M_Core_ESP32C3"'
|
||||
custom_description = BLE gateway on the C3
|
||||
@@ -1666,11 +1670,11 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DANEOPIX_IND_DATA_GPIO=8'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
; '-DANEOPIX_BRIGHTNESS=10' ; 0 - 255, default 20
|
||||
'-DLED_ADDRESSABLE_PIN1=8'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
; '-DDEFAULT_ADJ_BRIGHTNESS=10' ; 0 - 255, default 20
|
||||
'-DANEOPIX_COLOR_SCHEME=2' ; blue based signalling colors
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DNO_INT_TEMP_READING=true' ; No internal temperature reading on ESP32 C3 or S3
|
||||
'-DTRIGGER_GPIO=7'
|
||||
'-DGateway_Name="OpenMQTTGateway_ESP32C3_DKC02"'
|
||||
@@ -1698,11 +1702,11 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DANEOPIX_IND_DATA_GPIO=7'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
; '-DANEOPIX_BRIGHTNESS=10' ; 0 - 255, default 20
|
||||
'-DLED_ADDRESSABLE_PIN1=7'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
; '-DDEFAULT_ADJ_BRIGHTNESS=10' ; 0 - 255, default 20
|
||||
'-DANEOPIX_COLOR_SCHEME=1' ; Alternative LED colour scheme: 2 = blue/gold. 1 = green/gold
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
; The momentary switch on the board is connected to GPIO9
|
||||
'-DTRIGGER_GPIO=9'
|
||||
'-DNO_INT_TEMP_READING=true' ; No internal temperature on ESP32 C3 or S3
|
||||
@@ -1738,9 +1742,9 @@ build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DTRIGGER_GPIO=3'
|
||||
'-DANEOPIX_IND_DATA_GPIO=2'
|
||||
'-DANEOPIX_IND_NUM_LEDS=1'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=2'
|
||||
'-DLED_ADDRESSABLE_NUM=1'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
'-DNO_INT_TEMP_READING=true' ; Internal temperature reading not building on ESP32 C3 or S3
|
||||
'-DUSE_MAC_AS_GATEWAY_NAME'
|
||||
custom_description = BLE gateway on ESP32C3
|
||||
@@ -1759,8 +1763,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_THINGPULSE_ETH_BLE"'
|
||||
'-DESP32_ETHERNET=true'
|
||||
'-DETH_PHY_TYPE=ETH_PHY_LAN8720'
|
||||
@@ -1769,13 +1773,13 @@ build_flags =
|
||||
'-DETH_PHY_MDC=23'
|
||||
'-DETH_PHY_MDIO=18'
|
||||
'-DETH_CLK_MODE=ETH_CLOCK_GPIO16_OUT'
|
||||
'-DANEOPIX_IND_DATA_GPIO=32'
|
||||
'-DANEOPIX_IND_NUM_LEDS=4'
|
||||
'-DANEOPIX_INFO_LED=0'
|
||||
'-DANEOPIX_SEND_RECEIVE_LED=1'
|
||||
'-DANEOPIX_ERROR_LED=2'
|
||||
'-DANEOPIX_BRIGHTNESS=255'
|
||||
'-DRGB_INDICATORS=true'
|
||||
'-DLED_ADDRESSABLE_PIN1=32'
|
||||
'-DLED_ADDRESSABLE_NUM=4'
|
||||
'-DLED_BROKER=0'
|
||||
'-DLED_PROCESSING=1'
|
||||
'-DLED_ERROR=2'
|
||||
'-DDEFAULT_ADJ_BRIGHTNESS=255'
|
||||
'-DLED_ADDRESSABLE=true'
|
||||
; '-DsimplePublishing=true'
|
||||
custom_description = BLE Gateway using ethernet or wifi with external antenna
|
||||
custom_hardware = ThingPulse gateway single ESP32
|
||||
@@ -1793,8 +1797,8 @@ lib_deps =
|
||||
build_flags =
|
||||
${com-esp32.build_flags}
|
||||
'-DZgatewayBT="BT"'
|
||||
'-DLED_SEND_RECEIVE=2'
|
||||
'-DLED_SEND_RECEIVE_ON=0'
|
||||
'-DLED_PIN=2'
|
||||
'-DLED_PIN_ON=0'
|
||||
'-DGateway_Name="OMG_ESP32_BLE"'
|
||||
'-DUSE_BLUFI=1'
|
||||
'-DARDUINO_LOOP_STACK_SIZE=17500'
|
||||
|
||||
243
lib/LEDManager/LEDManager.cpp
Normal file
243
lib/LEDManager/LEDManager.cpp
Normal file
@@ -0,0 +1,243 @@
|
||||
/*
|
||||
Theengs LEDManager - We Unite Sensors in One Open-Source Interface
|
||||
|
||||
Copyright: (c)Florian ROBERT
|
||||
|
||||
This file is part of LEDManager library.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
|
||||
#include "LEDManager.h"
|
||||
|
||||
LEDManager::LEDManager() : globalBrightness(255) {}
|
||||
|
||||
void LEDManager::addLEDStrip(int pin, int numLeds) {
|
||||
LEDStrip ledStrip;
|
||||
ledStrip.pin = pin;
|
||||
#ifdef LED_ADDRESSABLE
|
||||
ledStrip.strip = new Adafruit_NeoPixel(numLeds, pin, NEO_GRB + NEO_KHZ800);
|
||||
ledStrip.strip->begin();
|
||||
ledStrip.strip->show();
|
||||
ledStrip.strip->setBrightness(globalBrightness);
|
||||
#else
|
||||
pinMode(pin, OUTPUT);
|
||||
#endif
|
||||
|
||||
ledStrip.ledStates.resize(numLeds, {OFF, OFF, 0, 0, 0, 0, 0, false, 255, FADE_AMOUNT, {OFF, 0, -1, false}});
|
||||
|
||||
ledStrips.push_back(ledStrip);
|
||||
}
|
||||
|
||||
void LEDManager::setMode(int stripIndex, int ledIndex, Mode mode, uint32_t color, int durationOrBlinkCount) {
|
||||
if (stripIndex >= 0 && stripIndex < ledStrips.size()) {
|
||||
if (ledIndex == -1) {
|
||||
for (int i = 0; i < ledStrips[stripIndex].ledStates.size(); i++) {
|
||||
setModeForSingleLED(stripIndex, i, mode, color, durationOrBlinkCount);
|
||||
}
|
||||
} else if (ledIndex >= 0 && ledIndex < ledStrips[stripIndex].ledStates.size()) {
|
||||
setModeForSingleLED(stripIndex, ledIndex, mode, color, durationOrBlinkCount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LEDManager::setModeForSingleLED(int stripIndex, int ledIndex, Mode mode, uint32_t color, int durationOrBlinkCount) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
|
||||
if ((state.mode == BLINK || state.mode == PULSE) && state.durationOrBlinkCount > 0) {
|
||||
state.queuedState = {mode, color, durationOrBlinkCount, true};
|
||||
return;
|
||||
}
|
||||
|
||||
if (mode != BLINK && mode != PULSE) {
|
||||
state.previousMode = state.mode;
|
||||
state.previousColor = state.color;
|
||||
}
|
||||
state.mode = mode;
|
||||
state.color = color;
|
||||
state.durationOrBlinkCount = durationOrBlinkCount;
|
||||
state.lastUpdateTime = millis();
|
||||
state.blinkCounter = 0;
|
||||
state.isBlinkOn = false;
|
||||
state.brightness = globalBrightness;
|
||||
state.fadeAmount = FADE_AMOUNT;
|
||||
state.queuedState.isQueued = false;
|
||||
}
|
||||
|
||||
void LEDManager::setBrightness(uint8_t brightness) {
|
||||
#ifdef LED_ADDRESSABLE
|
||||
globalBrightness = brightness;
|
||||
for (auto& ledStrip : ledStrips) {
|
||||
ledStrip.strip->setBrightness(brightness);
|
||||
for (auto& state : ledStrip.ledStates) {
|
||||
state.brightness = brightness;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LEDManager::setLEDColor(int stripIndex, int ledIndex, uint32_t color) {
|
||||
if (stripIndex < 0 || stripIndex >= ledStrips.size()) return;
|
||||
if (ledIndex < 0 || ledIndex >= ledStrips[stripIndex].ledStates.size()) return;
|
||||
|
||||
uint8_t r, g, b;
|
||||
extractRGB(color, r, g, b);
|
||||
|
||||
r = (r * globalBrightness) / 255;
|
||||
g = (g * globalBrightness) / 255;
|
||||
b = (b * globalBrightness) / 255;
|
||||
|
||||
#ifdef LED_ADDRESSABLE
|
||||
ledStrips[stripIndex].strip->setPixelColor(ledIndex, r, g, b);
|
||||
ledStrips[stripIndex].strip->show();
|
||||
#else
|
||||
// For non-addressable LEDs, we'll use the first LED of each strip
|
||||
if (ledIndex == 0) {
|
||||
int pin = ledStrips[stripIndex].pin;
|
||||
analogWrite(pin, (r + g + b) / 3); // Average of RGB for single-color LED
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
void LEDManager::update() {
|
||||
for (int stripIndex = 0; stripIndex < ledStrips.size(); stripIndex++) {
|
||||
for (int ledIndex = 0; ledIndex < ledStrips[stripIndex].ledStates.size(); ledIndex++) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
switch (state.mode) {
|
||||
case BLINK:
|
||||
handleBlink(stripIndex, ledIndex);
|
||||
break;
|
||||
case PULSE:
|
||||
handlePulse(stripIndex, ledIndex);
|
||||
break;
|
||||
case STATIC:
|
||||
handleStatic(stripIndex, ledIndex);
|
||||
break;
|
||||
case OFF:
|
||||
setLEDColor(stripIndex, ledIndex, 0);
|
||||
break;
|
||||
}
|
||||
}
|
||||
#ifdef LED_ADDRESSABLE
|
||||
ledStrips[stripIndex].strip->show();
|
||||
#endif
|
||||
}
|
||||
}
|
||||
|
||||
void LEDManager::handleBlink(int stripIndex, int ledIndex) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
unsigned long currentTime = millis();
|
||||
if (currentTime - state.lastUpdateTime >= BLINK_INTERVAL) {
|
||||
state.lastUpdateTime = currentTime;
|
||||
if (state.durationOrBlinkCount > 0) {
|
||||
if (state.blinkCounter == 0) {
|
||||
state.blinkCounter = state.durationOrBlinkCount * 2;
|
||||
} else {
|
||||
state.blinkCounter--;
|
||||
if (state.blinkCounter == 0) {
|
||||
if (state.queuedState.isQueued) {
|
||||
applyQueuedState(stripIndex, ledIndex);
|
||||
} else {
|
||||
returnToPreviousState(stripIndex, ledIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
state.isBlinkOn = !state.isBlinkOn;
|
||||
if (state.isBlinkOn) {
|
||||
setLEDColor(stripIndex, ledIndex, state.color);
|
||||
} else {
|
||||
setLEDColor(stripIndex, ledIndex, 0);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void LEDManager::handlePulse(int stripIndex, int ledIndex) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
unsigned long currentTime = millis();
|
||||
if (currentTime - state.lastUpdateTime >= PULSE_INTERVAL) {
|
||||
state.lastUpdateTime = currentTime;
|
||||
state.brightness += state.fadeAmount;
|
||||
if (state.brightness <= 0 || state.brightness >= 255) {
|
||||
state.fadeAmount = -state.fadeAmount;
|
||||
state.brightness = constrain(state.brightness, 0, 255);
|
||||
if (state.durationOrBlinkCount > 0) {
|
||||
state.durationOrBlinkCount--;
|
||||
if (state.durationOrBlinkCount == 0) {
|
||||
if (state.queuedState.isQueued) {
|
||||
applyQueuedState(stripIndex, ledIndex);
|
||||
} else {
|
||||
returnToPreviousState(stripIndex, ledIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
uint32_t adjustedColor = (state.color & 0xFF000000) |
|
||||
(((state.color & 0x00FF0000) * state.brightness / 255) & 0x00FF0000) |
|
||||
(((state.color & 0x0000FF00) * state.brightness / 255) & 0x0000FF00) |
|
||||
(((state.color & 0x000000FF) * state.brightness / 255) & 0x000000FF);
|
||||
setLEDColor(stripIndex, ledIndex, adjustedColor);
|
||||
}
|
||||
}
|
||||
|
||||
void LEDManager::handleStatic(int stripIndex, int ledIndex) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
unsigned long currentTime = millis();
|
||||
if (state.durationOrBlinkCount > 0) {
|
||||
if (currentTime - state.lastUpdateTime >= static_cast<unsigned long>(state.durationOrBlinkCount) * 1000) {
|
||||
if (state.queuedState.isQueued) {
|
||||
applyQueuedState(stripIndex, ledIndex);
|
||||
} else {
|
||||
returnToPreviousState(stripIndex, ledIndex);
|
||||
}
|
||||
return;
|
||||
}
|
||||
}
|
||||
setLEDColor(stripIndex, ledIndex, state.color);
|
||||
}
|
||||
|
||||
void LEDManager::returnToPreviousState(int stripIndex, int ledIndex) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
state.mode = state.previousMode;
|
||||
state.color = state.previousColor;
|
||||
state.durationOrBlinkCount = -1; // Set to infinite for the previous state
|
||||
state.lastUpdateTime = millis();
|
||||
state.blinkCounter = 0;
|
||||
state.isBlinkOn = false;
|
||||
state.brightness = globalBrightness;
|
||||
state.fadeAmount = FADE_AMOUNT;
|
||||
}
|
||||
|
||||
void LEDManager::applyQueuedState(int stripIndex, int ledIndex) {
|
||||
auto& state = ledStrips[stripIndex].ledStates[ledIndex];
|
||||
state.mode = state.queuedState.mode;
|
||||
state.color = state.queuedState.color;
|
||||
state.durationOrBlinkCount = state.queuedState.durationOrBlinkCount;
|
||||
state.lastUpdateTime = millis();
|
||||
state.blinkCounter = 0;
|
||||
state.isBlinkOn = false;
|
||||
state.brightness = globalBrightness;
|
||||
state.fadeAmount = FADE_AMOUNT;
|
||||
state.queuedState.isQueued = false;
|
||||
}
|
||||
|
||||
void LEDManager::extractRGB(uint32_t color, uint8_t& r, uint8_t& g, uint8_t& b) {
|
||||
r = (color >> 16) & 0xFF;
|
||||
g = (color >> 8) & 0xFF;
|
||||
b = color & 0xFF;
|
||||
}
|
||||
107
lib/LEDManager/LEDManager.h
Normal file
107
lib/LEDManager/LEDManager.h
Normal file
@@ -0,0 +1,107 @@
|
||||
/*
|
||||
Theengs LEDManager - We Unite Sensors in One Open-Source Interface
|
||||
|
||||
Copyright: (c)Florian ROBERT
|
||||
|
||||
This file is part of LEDManager library.
|
||||
|
||||
This program is free software; you can redistribute it and/or
|
||||
modify it under the terms of the GNU Lesser 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
|
||||
Lesser General Public License for more details.
|
||||
|
||||
You should have received a copy of the GNU Lesser General Public License
|
||||
along with this program; if not, write to the Free Software Foundation,
|
||||
Inc., 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA.
|
||||
*/
|
||||
#ifndef LED_MANAGER_H
|
||||
#define LED_MANAGER_H
|
||||
|
||||
#include <Arduino.h>
|
||||
|
||||
#include <vector>
|
||||
|
||||
#ifdef LED_ADDRESSABLE
|
||||
# include <Adafruit_NeoPixel.h>
|
||||
#endif
|
||||
|
||||
#ifndef BLINK_INTERVAL
|
||||
# define BLINK_INTERVAL 500
|
||||
#endif
|
||||
|
||||
#ifndef PULSE_INTERVAL
|
||||
# define PULSE_INTERVAL 30
|
||||
#endif
|
||||
|
||||
#ifndef FADE_AMOUNT
|
||||
# define FADE_AMOUNT 5
|
||||
#endif
|
||||
|
||||
// Define the pins for the RGB LED power if needed
|
||||
#ifndef LED_ADDRESSABLE_POWER
|
||||
# define LED_ADDRESSABLE_POWER -1
|
||||
#endif
|
||||
|
||||
class LEDManager {
|
||||
public:
|
||||
enum Mode { OFF,
|
||||
STATIC,
|
||||
BLINK,
|
||||
PULSE };
|
||||
|
||||
LEDManager();
|
||||
void init();
|
||||
void addLEDStrip(int pin, int numLeds);
|
||||
void setMode(int stripIndex, int ledIndex, Mode mode, uint32_t color, int durationOrBlinkCount = -1);
|
||||
void update();
|
||||
void setBrightness(uint8_t brightness);
|
||||
|
||||
private:
|
||||
struct QueuedState {
|
||||
Mode mode;
|
||||
uint32_t color;
|
||||
int durationOrBlinkCount;
|
||||
bool isQueued;
|
||||
};
|
||||
|
||||
struct LEDState {
|
||||
Mode mode;
|
||||
Mode previousMode;
|
||||
uint32_t color;
|
||||
uint32_t previousColor;
|
||||
int durationOrBlinkCount;
|
||||
unsigned long lastUpdateTime;
|
||||
int blinkCounter;
|
||||
bool isBlinkOn;
|
||||
int brightness;
|
||||
int fadeAmount;
|
||||
QueuedState queuedState;
|
||||
};
|
||||
|
||||
struct LEDStrip {
|
||||
#ifdef LED_ADDRESSABLE
|
||||
Adafruit_NeoPixel* strip;
|
||||
#endif
|
||||
int pin;
|
||||
std::vector<LEDState> ledStates;
|
||||
};
|
||||
|
||||
std::vector<LEDStrip> ledStrips;
|
||||
int globalBrightness;
|
||||
|
||||
void setModeForSingleLED(int stripIndex, int ledIndex, Mode mode, uint32_t color, int durationOrBlinkCount);
|
||||
void setLEDColor(int stripIndex, int ledIndex, uint32_t color);
|
||||
void handleBlink(int stripIndex, int ledIndex);
|
||||
void handlePulse(int stripIndex, int ledIndex);
|
||||
void handleStatic(int stripIndex, int ledIndex);
|
||||
void returnToPreviousState(int stripIndex, int ledIndex);
|
||||
void applyQueuedState(int stripIndex, int ledIndex);
|
||||
void extractRGB(uint32_t color, uint8_t& r, uint8_t& g, uint8_t& b);
|
||||
};
|
||||
|
||||
#endif // LED_MANAGER_H
|
||||
132
lib/LEDManager/README.md
Normal file
132
lib/LEDManager/README.md
Normal file
@@ -0,0 +1,132 @@
|
||||
# LEDManager Library
|
||||
|
||||
## Overview
|
||||
|
||||
The LEDManager library provides a flexible and easy-to-use interface for controlling LEDs in projects. It supports both addressable LED strips and individual non-addressable LEDs, offering various modes of operation such as static, blinking, and pulsing. The library is designed to work seamlessly with PlatformIO and can be easily configured using build flags.
|
||||
|
||||
## Features
|
||||
|
||||
- Support for both addressable LED strips and individual non-addressable LEDs
|
||||
- Multiple operation modes: OFF, STATIC, BLINK, and PULSE
|
||||
- Individual control of LEDs within each strip (for addressable LEDs)
|
||||
- Global brightness control
|
||||
- Queueing of LED states for complex sequences
|
||||
- Automatic return to previous state after temporary modes
|
||||
- Compatible with PlatformIO build flags for easy configuration
|
||||
- Customizable color schemes
|
||||
|
||||
## Installation
|
||||
|
||||
1. Clone this repository or download the ZIP file.
|
||||
2. Extract the contents to your PlatformIO project's `lib` directory.
|
||||
|
||||
## Configuration
|
||||
|
||||
Configure the LEDManager library using build flags in your `platformio.ini` file:
|
||||
|
||||
```ini
|
||||
build_flags =
|
||||
; For addressable LEDs:
|
||||
-DLED_ADDRESSABLE=true
|
||||
; For non-addressable LEDs, comment out the line above
|
||||
|
||||
; Optional timing configurations:
|
||||
-DBLINK_INTERVAL=500
|
||||
-DPULSE_INTERVAL=30
|
||||
-DFADE_AMOUNT=5
|
||||
```
|
||||
|
||||
## Usage
|
||||
|
||||
Here's a basic example of how to use the LEDManager library:
|
||||
|
||||
```cpp
|
||||
#include "LEDManager.h"
|
||||
|
||||
LEDManager ledManager;
|
||||
|
||||
void setup() {
|
||||
|
||||
#ifdef LED_ADDRESSABLE
|
||||
ledManager.addLEDStrip(5, 30); // Add addressable LED strip on pin 5 with 30 LEDs
|
||||
#else
|
||||
ledManager.addLEDStrip(5, 1); // Add non-addressable LED on pin 5
|
||||
ledManager.addLEDStrip(6, 1); // Add non-addressable LED on pin 6
|
||||
#endif
|
||||
|
||||
ledManager.setBrightness(128); // Set global brightness to 50%
|
||||
}
|
||||
|
||||
void loop() {
|
||||
#ifdef LED_ADDRESSABLE
|
||||
// Set all LEDs on the strip to static green
|
||||
ledManager.setMode(0, -1, LEDManager::STATIC, LED_COLOR_GREEN);
|
||||
|
||||
// Blink first 5 LEDs red for 3 times
|
||||
for (int i = 0; i < 5; i++) {
|
||||
ledManager.setMode(0, i, LEDManager::BLINK, LED_COLOR_RED, 3);
|
||||
}
|
||||
#else
|
||||
// Set first LED to static green
|
||||
ledManager.setMode(0, 0, LEDManager::STATIC, LED_COLOR_GREEN);
|
||||
|
||||
// Blink second LED red
|
||||
ledManager.setMode(1, 0, LEDManager::BLINK, LED_COLOR_RED, 3);
|
||||
#endif
|
||||
|
||||
ledManager.update();
|
||||
delay(100);
|
||||
}
|
||||
```
|
||||
|
||||
## API Reference
|
||||
|
||||
### Initialization and Setup
|
||||
|
||||
```cpp
|
||||
LEDManager ledManager;
|
||||
ledManager.addLEDStrip(int pin, int numLeds);
|
||||
```
|
||||
|
||||
### Setting LED Mode
|
||||
|
||||
```cpp
|
||||
ledManager.setMode(int stripIndex, int ledIndex, Mode mode, uint32_t color, int durationOrBlinkCount = -1);
|
||||
```
|
||||
|
||||
- `stripIndex`: Index of the LED strip (0-based)
|
||||
- `ledIndex`: LED index within the strip (0-based) or -1 for all LEDs in the strip (addressable LEDs only)
|
||||
- `mode`: `LEDManager::OFF`, `LEDManager::STATIC`, `LEDManager::BLINK`, or `LEDManager::PULSE`
|
||||
- `color`: Color value (use predefined colors from LEDColorDefinitions.h or custom 24-bit RGB values)
|
||||
- `durationOrBlinkCount`: Duration for STATIC mode (in milliseconds), blink/pulse count for BLINK/PULSE modes (-1 for infinite)
|
||||
|
||||
### Setting Brightness
|
||||
|
||||
```cpp
|
||||
ledManager.setBrightness(brightness);
|
||||
```
|
||||
|
||||
- `brightness`: Global brightness value (0-255)
|
||||
|
||||
### Updating LEDs
|
||||
|
||||
Call this method in your main loop to update LED states:
|
||||
|
||||
```cpp
|
||||
ledManager.update();
|
||||
```
|
||||
## Advanced Configuration
|
||||
|
||||
You can customize the behavior of the LEDManager by defining the following build flags:
|
||||
|
||||
- `BLINK_INTERVAL`: Sets the interval (in milliseconds) between blink states (default: 500)
|
||||
- `PULSE_INTERVAL`: Sets the interval (in milliseconds) between pulse updates (default: 30)
|
||||
- `FADE_AMOUNT`: Sets the increment/decrement value for pulsing (default: 5)
|
||||
|
||||
## Contributing
|
||||
|
||||
Contributions to the LEDManager library are welcome! Please feel free to submit a Pull Request.
|
||||
|
||||
## License
|
||||
|
||||
This library is released under the LGPL V3 License.
|
||||
@@ -434,260 +434,84 @@ ss_cnt_parameters cnt_parameters_array[cnt_parameters_array_size] = {
|
||||
# define ota_timeout_millis 30000
|
||||
#endif
|
||||
|
||||
/*-------------ERRORS, INFOS, SEND RECEIVE Display through LED----------------*/
|
||||
#ifndef RGB_INDICATORS // Management of Errors, reception/emission and informations indicators with basic LED
|
||||
/*-------------DEFINE PINs FOR STATUS LEDs----------------*/
|
||||
# ifndef LED_SEND_RECEIVE
|
||||
# ifdef ESP8266
|
||||
//# define LED_SEND_RECEIVE 40
|
||||
# elif ESP32
|
||||
//# define LED_SEND_RECEIVE 40
|
||||
# endif
|
||||
# endif
|
||||
# ifndef LED_SEND_RECEIVE_ON
|
||||
# define LED_SEND_RECEIVE_ON HIGH
|
||||
# endif
|
||||
# ifndef LED_ERROR
|
||||
# ifdef ESP8266
|
||||
//# define LED_ERROR 42
|
||||
# elif ESP32
|
||||
//# define LED_ERROR 42
|
||||
# endif
|
||||
# endif
|
||||
# ifndef LED_ERROR_ON
|
||||
# define LED_ERROR_ON HIGH
|
||||
# endif
|
||||
# ifndef RGB_LED_ON_ON
|
||||
# define RGB_LED_ON_ON HIGH
|
||||
# endif
|
||||
# ifndef LED_INFO
|
||||
# ifdef ESP8266
|
||||
//# define LED_INFO 44
|
||||
# elif ESP32
|
||||
//# define LED_INFO 44
|
||||
# endif
|
||||
# endif
|
||||
# ifndef LED_INFO_ON
|
||||
# define LED_INFO_ON HIGH
|
||||
# endif
|
||||
# ifdef RGB_LED_ON
|
||||
# define SetupIndicatorError() \
|
||||
pinMode(RGB_LED_ON, OUTPUT);
|
||||
# define ONIndicatorON() digitalWrite(RGB_LED_ON, RGB_LED_ON_ON)
|
||||
# else
|
||||
# define ONIndicatorON()
|
||||
# endif
|
||||
# ifdef LED_ERROR
|
||||
# define SetupIndicatorError() \
|
||||
pinMode(LED_ERROR, OUTPUT); \
|
||||
ErrorIndicatorOFF();
|
||||
# define ErrorIndicatorON() digitalWrite(LED_ERROR, LED_ERROR_ON)
|
||||
# define ErrorIndicatorOFF() digitalWrite(LED_ERROR, !LED_ERROR_ON)
|
||||
# else
|
||||
# define SetupIndicatorError()
|
||||
# define ErrorIndicatorON()
|
||||
# define ErrorIndicatorOFF()
|
||||
# endif
|
||||
# ifdef LED_SEND_RECEIVE
|
||||
# define SetupIndicatorSendReceive() \
|
||||
pinMode(LED_SEND_RECEIVE, OUTPUT); \
|
||||
SendReceiveIndicatorOFF();
|
||||
# define SendReceiveIndicatorON() digitalWrite(LED_SEND_RECEIVE, LED_SEND_RECEIVE_ON)
|
||||
# define SendReceiveIndicatorOFF() digitalWrite(LED_SEND_RECEIVE, !LED_SEND_RECEIVE_ON)
|
||||
# else
|
||||
# define SetupIndicatorSendReceive()
|
||||
# define SendReceiveIndicatorON()
|
||||
# define SendReceiveIndicatorOFF()
|
||||
# endif
|
||||
# ifdef LED_INFO
|
||||
# define SetupIndicatorInfo() \
|
||||
pinMode(LED_INFO, OUTPUT); \
|
||||
InfoIndicatorOFF();
|
||||
# define InfoIndicatorON() digitalWrite(LED_INFO, LED_INFO_ON)
|
||||
# define InfoIndicatorOFF() digitalWrite(LED_INFO, !LED_INFO_ON)
|
||||
# else
|
||||
# define SetupIndicatorInfo()
|
||||
# define InfoIndicatorON()
|
||||
# define InfoIndicatorOFF()
|
||||
# endif
|
||||
# define CriticalIndicatorON() // Not used
|
||||
# define PowerIndicatorON() // Not used
|
||||
# define PowerIndicatorOFF() // Not used
|
||||
# define SetupIndicators() // Not used
|
||||
#else // Management of Errors, reception/emission and informations indicators with RGB LED
|
||||
# include <Adafruit_NeoPixel.h>
|
||||
# ifndef ANEOPIX_IND_TYPE // needs library constants
|
||||
# define ANEOPIX_IND_TYPE NEO_GRB + NEO_KHZ800 // ws2812 and alike
|
||||
# endif
|
||||
Adafruit_NeoPixel leds(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO, ANEOPIX_IND_TYPE);
|
||||
# ifdef ANEOPIX_IND_DATA_GPIO2 // Only used for Critical Indicator
|
||||
// assume the same LED type
|
||||
Adafruit_NeoPixel leds2(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO2, ANEOPIX_IND_TYPE);
|
||||
# endif
|
||||
# ifdef ANEOPIX_IND_DATA_GPIO3
|
||||
// assume the same LED type
|
||||
Adafruit_NeoPixel leds3(ANEOPIX_IND_NUM_LEDS, ANEOPIX_IND_DATA_GPIO3, ANEOPIX_IND_TYPE);
|
||||
# endif
|
||||
// LED index depending on state, each state can have a different LED index or be grouped if there is a limited number of LEDs
|
||||
#ifndef LED_ERROR
|
||||
# define LED_ERROR 0
|
||||
#endif
|
||||
#ifndef LED_PROCESSING
|
||||
# define LED_PROCESSING 0
|
||||
#endif
|
||||
#ifndef LED_BROKER
|
||||
# define LED_BROKER 0
|
||||
#endif
|
||||
#ifndef LED_NETWORK
|
||||
# define LED_NETWORK 0
|
||||
#endif
|
||||
#ifndef LED_POWER
|
||||
# define LED_POWER -1
|
||||
#endif
|
||||
|
||||
# ifndef RGB_LED_POWER
|
||||
# define RGB_LED_POWER -1 // If the RGB Led is linked to GPIO pin for power define it here
|
||||
// Single standard LED pin
|
||||
#ifndef LED_PIN
|
||||
# ifdef LED_BUILTIN
|
||||
# define LED_PIN LED_BUILTIN
|
||||
# endif
|
||||
# ifndef ANEOPIX_BRIGHTNESS
|
||||
# define ANEOPIX_BRIGHTNESS 20 // Set Default maximum RGB brightness to approx 10% (0-255 scale)
|
||||
#endif
|
||||
#ifndef LED_PIN_ON
|
||||
# define LED_PIN_ON HIGH
|
||||
#endif
|
||||
#ifndef LED_ACTUATOR_ONOFF
|
||||
# ifdef LED_BUILTIN
|
||||
# define LED_ACTUATOR_ONOFF LED_BUILTIN
|
||||
# endif
|
||||
# ifndef DEFAULT_ADJ_BRIGHTNESS
|
||||
# define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness
|
||||
# endif
|
||||
# ifndef ANEOPIX_COLOR_SCHEME // allow for different color combinations
|
||||
# define ANEOPIX_COLOR_SCHEME 0
|
||||
# endif
|
||||
// Allow to set LED used (for example thingpulse gateway has 4 we use them independently)
|
||||
# ifndef ANEOPIX_ON_LED
|
||||
# define ANEOPIX_ON_LED 0 // First Led
|
||||
# endif
|
||||
# ifndef ANEOPIX_INFO_LED
|
||||
# define ANEOPIX_INFO_LED 0 // First Led
|
||||
# endif
|
||||
# ifndef ANEOPIX_SEND_RECEIVE_LED
|
||||
# define ANEOPIX_SEND_RECEIVE_LED 0 // First Led
|
||||
# endif
|
||||
# ifndef ANEOPIX_ERROR_LED
|
||||
# define ANEOPIX_ERROR_LED 0 // First Led
|
||||
# endif
|
||||
# ifndef ANEOPIX_CRITICAL_LED
|
||||
# define ANEOPIX_CRITICAL_LED 0 // First Led
|
||||
# endif
|
||||
// compile time calculation of color values
|
||||
# define ANEOPIX_RED ((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 16
|
||||
# define ANEOPIX_RED_DIM ((0x3F * ANEOPIX_BRIGHTNESS) >> 8) << 16 // dimmed /4
|
||||
# define ANEOPIX_ORANGE (((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 16) | \
|
||||
(((0xA5 * ANEOPIX_BRIGHTNESS) >> 8) << 8)
|
||||
# define ANEOPIX_GOLD (((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 16) | \
|
||||
(((0xD7 * ANEOPIX_BRIGHTNESS) >> 8) << 8)
|
||||
# define ANEOPIX_GREEN ((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 8
|
||||
# define ANEOPIX_GREEN_DIM ((0x3F * ANEOPIX_BRIGHTNESS) >> 8) << 8 // dimmed /4
|
||||
# define ANEOPIX_AQUA (((0xFF * ANEOPIX_BRIGHTNESS) >> 8) << 8) | \
|
||||
(0xFF * ANEOPIX_BRIGHTNESS) >> 8
|
||||
# define ANEOPIX_BLUE (0xFF * ANEOPIX_BRIGHTNESS) >> 8
|
||||
# define ANEOPIX_BLUE_DIM (0x3F * ANEOPIX_BRIGHTNESS) >> 8 // dimmed /4
|
||||
# define ANEOPIX_BLACK 0
|
||||
#endif
|
||||
|
||||
# if ANEOPIX_COLOR_SCHEME == 0
|
||||
// original color combination remains default
|
||||
# define ANEOPIX_INFO ANEOPIX_GREEN
|
||||
# define ANEOPIX_ERROR ANEOPIX_ORANGE
|
||||
# define ANEOPIX_SENDRECEIVE ANEOPIX_BLUE
|
||||
# define ANEOPIX_CRITICAL ANEOPIX_RED // second led
|
||||
# define ANEOPIX_POWER ANEOPIX_GREEN // second led
|
||||
# define ANEOPIX_BOOT ANEOPIX_BLACK // unused
|
||||
# define ANEOPIX_OFF ANEOPIX_BLACK
|
||||
// color combinations tested for good visibility of onboard leds
|
||||
# elif ANEOPIX_COLOR_SCHEME == 1
|
||||
# define ANEOPIX_INFO ANEOPIX_GREEN_DIM // dimmed green info background
|
||||
# define ANEOPIX_ERROR ANEOPIX_RED_DIM
|
||||
# define ANEOPIX_SENDRECEIVE ANEOPIX_GOLD // bright gold = sending
|
||||
# define ANEOPIX_CRITICAL ANEOPIX_BLACK // unused
|
||||
# define ANEOPIX_POWER ANEOPIX_BLACK // unused
|
||||
# define ANEOPIX_BOOT ANEOPIX_AQUA
|
||||
# define ANEOPIX_OFF ANEOPIX_BLACK
|
||||
# else
|
||||
# define ANEOPIX_INFO ANEOPIX_BLUE_DIM // dimmed blue info background
|
||||
# define ANEOPIX_ERROR ANEOPIX_RED_DIM
|
||||
# define ANEOPIX_SENDRECEIVE ANEOPIX_GOLD // bright gold = sending
|
||||
# define ANEOPIX_CRITICAL ANEOPIX_BLACK // unused
|
||||
# define ANEOPIX_POWER ANEOPIX_BLACK // unused
|
||||
# define ANEOPIX_BOOT ANEOPIX_AQUA
|
||||
# define ANEOPIX_OFF ANEOPIX_BLACK
|
||||
# endif
|
||||
# if !defined(ANEOPIX_IND_DATA_GPIO2) && !defined(ANEOPIX_IND_DATA_GPIO3)
|
||||
// during boot the RGB LED is on to signal also reboots
|
||||
# define SetupIndicators() \
|
||||
if (RGB_LED_POWER > -1) { \
|
||||
pinMode(RGB_LED_POWER, OUTPUT); \
|
||||
digitalWrite(RGB_LED_POWER, HIGH); \
|
||||
} \
|
||||
leds.begin(); \
|
||||
leds.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_BOOT); \
|
||||
leds.show();
|
||||
# elif defined(ANEOPIX_IND_DATA_GPIO2) && !defined(ANEOPIX_IND_DATA_GPIO3)
|
||||
# define SetupIndicators() \
|
||||
if (RGB_LED_POWER > -1) { \
|
||||
pinMode(RGB_LED_POWER, OUTPUT); \
|
||||
digitalWrite(RGB_LED_POWER, HIGH); \
|
||||
} \
|
||||
leds.begin(); \
|
||||
leds2.begin();
|
||||
# else
|
||||
# define SetupIndicators() \
|
||||
if (RGB_LED_POWER > -1) { \
|
||||
pinMode(RGB_LED_POWER, OUTPUT); \
|
||||
digitalWrite(RGB_LED_POWER, HIGH); \
|
||||
} \
|
||||
leds.begin(); \
|
||||
leds2.begin(); \
|
||||
leds3.begin();
|
||||
# endif
|
||||
# ifndef RGB_LED_ERROR
|
||||
# define RGB_LED_ERROR leds
|
||||
# endif
|
||||
# ifndef RGB_LED_SR
|
||||
# define RGB_LED_SR leds
|
||||
# endif
|
||||
# ifndef RGB_LED_INFO
|
||||
# define RGB_LED_INFO leds
|
||||
# endif
|
||||
# ifndef RGB_LED_ON
|
||||
# define RGB_LED_ON leds
|
||||
# endif
|
||||
# define ONIndicatorON() \
|
||||
RGB_LED_ON.setPixelColor(ANEOPIX_ON_LED, ANEOPIX_POWER); \
|
||||
RGB_LED_ON.setBrightness(SYSConfig.rgbbrightness); \
|
||||
RGB_LED_ON.show();
|
||||
# define ErrorIndicatorON() \
|
||||
RGB_LED_ERROR.setPixelColor(ANEOPIX_ERROR_LED, ANEOPIX_ERROR); \
|
||||
RGB_LED_ERROR.setBrightness(SYSConfig.rgbbrightness); \
|
||||
RGB_LED_ERROR.show();
|
||||
# define ErrorIndicatorOFF() \
|
||||
RGB_LED_ERROR.setPixelColor(ANEOPIX_ERROR_LED, ANEOPIX_OFF); \
|
||||
RGB_LED_ERROR.show();
|
||||
# define SendReceiveIndicatorON() \
|
||||
RGB_LED_SR.setPixelColor(ANEOPIX_SEND_RECEIVE_LED, ANEOPIX_SENDRECEIVE); \
|
||||
RGB_LED_SR.setBrightness(SYSConfig.rgbbrightness); \
|
||||
RGB_LED_SR.show();
|
||||
# define SendReceiveIndicatorOFF() \
|
||||
RGB_LED_SR.setPixelColor(ANEOPIX_SEND_RECEIVE_LED, ANEOPIX_OFF); \
|
||||
RGB_LED_SR.show();
|
||||
# define InfoIndicatorON() \
|
||||
RGB_LED_INFO.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_INFO); \
|
||||
RGB_LED_INFO.setBrightness(SYSConfig.rgbbrightness); \
|
||||
RGB_LED_INFO.show();
|
||||
# define InfoIndicatorOFF() \
|
||||
RGB_LED_INFO.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_OFF); \
|
||||
RGB_LED_INFO.show();
|
||||
# ifdef ANEOPIX_IND_DATA_GPIO2 // Used for relay power indicator
|
||||
// For the critical ON indicator there is no method to turn it off, the only way is to unplug the device
|
||||
// This enable to have persistence of the indicator to inform the user
|
||||
# ifndef LED_CRITICAL
|
||||
# define LED_CRITICAL leds2
|
||||
# endif
|
||||
# ifndef LED_POWER
|
||||
# define LED_POWER leds2
|
||||
# endif
|
||||
# define CriticalIndicatorON() \
|
||||
LED_CRITICAL.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_CRITICAL); \
|
||||
LED_CRITICAL.setBrightness(255); \
|
||||
LED_CRITICAL.show();
|
||||
# define PowerIndicatorON() \
|
||||
LED_POWER.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_INFO); \
|
||||
LED_POWER.setBrightness(SYSConfig.rgbbrightness); \
|
||||
LED_POWER.show();
|
||||
# define PowerIndicatorOFF() \
|
||||
LED_POWER.setPixelColor(ANEOPIX_INFO_LED, ANEOPIX_OFF); \
|
||||
LED_POWER.show();
|
||||
# endif
|
||||
# define SetupIndicatorInfo()
|
||||
# define SetupIndicatorSendReceive()
|
||||
# define SetupIndicatorError()
|
||||
// TODO adapt to other boards
|
||||
#ifndef DEFAULT_ADJ_BRIGHTNESS
|
||||
# define DEFAULT_ADJ_BRIGHTNESS 255 // Set Default RGB adjustable brightness
|
||||
#endif
|
||||
|
||||
#ifndef LED_POWER_COLOR
|
||||
# define LED_POWER_COLOR 0x00FF00 // Green
|
||||
#endif
|
||||
#ifndef LED_PROCESSING_COLOR
|
||||
# define LED_PROCESSING_COLOR 0x0000FF // Blue
|
||||
#endif
|
||||
#ifndef LED_WAITING_ONBOARD_COLOR
|
||||
# define LED_WAITING_ONBOARD_COLOR 0xFFA500 // Orange
|
||||
#endif
|
||||
#ifndef LED_ONBOARD_COLOR
|
||||
# define LED_ONBOARD_COLOR 0xFFFF00 // Yellow
|
||||
#endif
|
||||
#ifndef LED_NETWORK_OK_COLOR
|
||||
# define LED_NETWORK_OK_COLOR 0x00FF00 // Green
|
||||
#endif
|
||||
#ifndef LED_NETWORK_ERROR_COLOR
|
||||
# define LED_NETWORK_ERROR_COLOR 0xFFA500 // Orange
|
||||
#endif
|
||||
#ifndef LED_BROKER_OK_COLOR
|
||||
# define LED_BROKER_OK_COLOR 0x00FF00 // Green
|
||||
#endif
|
||||
#ifndef LED_BROKER_ERROR_COLOR
|
||||
# define LED_BROKER_ERROR_COLOR 0xFFA500 // Orange
|
||||
#endif
|
||||
#ifndef LED_OFFLINE_COLOR
|
||||
# define LED_OFFLINE_COLOR 0x0000FF // Blue
|
||||
#endif
|
||||
#ifndef LED_OTA_LOCAL_COLOR
|
||||
# define LED_OTA_LOCAL_COLOR 0xFF00FF // Magenta
|
||||
#endif
|
||||
#ifndef LED_OTA_REMOTE_COLOR
|
||||
# define LED_OTA_REMOTE_COLOR 0x8000FF // Purple
|
||||
#endif
|
||||
#ifndef LED_ERROR_COLOR
|
||||
# define LED_ERROR_COLOR 0xFF0000 // Red
|
||||
#endif
|
||||
#ifndef LED_ACTUATOR_ONOFF_COLOR
|
||||
# define LED_ACTUATOR_ONOFF_COLOR 0x00FF00 // Green
|
||||
#endif
|
||||
#ifndef LED_COLOR_BLACK
|
||||
# define LED_COLOR_BLACK 0x000000
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
@@ -827,7 +651,7 @@ struct SYSConfig_s {
|
||||
bool offline;
|
||||
bool discovery; // HA discovery convention
|
||||
bool ohdiscovery; // OH discovery specificities
|
||||
#ifdef RGB_INDICATORS
|
||||
#ifdef LED_ADDRESSABLE
|
||||
int rgbbrightness; // brightness of the RGB LED
|
||||
#endif
|
||||
enum PowerMode powerMode;
|
||||
|
||||
@@ -100,11 +100,13 @@ void ONOFFConfig_load(){};
|
||||
# endif
|
||||
|
||||
void updatePowerIndicator() {
|
||||
# ifdef LED_ACTUATOR_ONOFF
|
||||
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) {
|
||||
PowerIndicatorON();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
|
||||
} else {
|
||||
PowerIndicatorOFF();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
|
||||
}
|
||||
# endif
|
||||
}
|
||||
|
||||
void setupONOFF() {
|
||||
@@ -142,11 +144,13 @@ void MQTTtoONOFF(char* topicOri, JsonObject& ONOFFdata) {
|
||||
Log.notice(F("GPIO number: %d" CR), gpio);
|
||||
pinMode(gpio, OUTPUT);
|
||||
digitalWrite(gpio, boolSWITCHTYPE);
|
||||
# ifdef LED_ACTUATOR_ONOFF
|
||||
if (boolSWITCHTYPE == ACTUATOR_ON) {
|
||||
PowerIndicatorON();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
|
||||
} else {
|
||||
PowerIndicatorOFF();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
|
||||
}
|
||||
# endif
|
||||
# ifdef ESP32
|
||||
if (ONOFFConfig.useLastStateOnStart) {
|
||||
ONOFFdata["save"] = true;
|
||||
@@ -221,11 +225,13 @@ void MQTTtoONOFF(char* topicOri, char* datacallback) {
|
||||
ON = false;
|
||||
|
||||
digitalWrite(gpio, ON);
|
||||
# ifdef LED_ACTUATOR_ONOFF
|
||||
if (ON == ACTUATOR_ON) {
|
||||
PowerIndicatorON();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
|
||||
} else {
|
||||
PowerIndicatorOFF();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
|
||||
}
|
||||
# endif
|
||||
// we acknowledge the sending by publishing the value to an acknowledgement topic
|
||||
char b = ON;
|
||||
pub(subjectGTWONOFFtoMQTT, &b);
|
||||
@@ -246,7 +252,9 @@ void overLimitTemp(void* pvParameters) {
|
||||
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead
|
||||
Log.error(F("[ActuatorONOFF] OverTemperature detected ( %F > %F ) switching OFF Actuator" CR), internalTempc, MAX_TEMP_ACTUATOR);
|
||||
ActuatorTrigger();
|
||||
CriticalIndicatorON();
|
||||
# ifdef LED_ACTUATOR_ONOFF
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ERROR_COLOR, -1);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
previousInternalTempc = internalTempc;
|
||||
@@ -266,7 +274,9 @@ void overLimitCurrent(float RN8209current) {
|
||||
if (digitalRead(ACTUATOR_ONOFF_GPIO) == ACTUATOR_ON) { // This could be with the previous condition, but it is better to trigger the digitalRead only if the previous condition is met to avoid the digitalRead
|
||||
Log.error(F("[ActuatorONOFF] OverCurrent detected ( %F > %F ) switching OFF Actuator" CR), RN8209current, MAX_CURRENT_ACTUATOR);
|
||||
ActuatorTrigger();
|
||||
CriticalIndicatorON();
|
||||
# ifdef LED_ACTUATOR_ONOFF
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ERROR_COLOR, -1);
|
||||
# endif
|
||||
}
|
||||
}
|
||||
RN8209previousCurrent = RN8209current;
|
||||
@@ -284,11 +294,13 @@ void ActuatorTrigger() {
|
||||
uint8_t level = !digitalRead(ACTUATOR_ONOFF_GPIO);
|
||||
Log.trace(F("Actuator triggered %d" CR), level);
|
||||
digitalWrite(ACTUATOR_ONOFF_GPIO, level);
|
||||
# ifdef LED_ACTUATOR_ONOFF
|
||||
if (level == ACTUATOR_ON) {
|
||||
PowerIndicatorON();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_ACTUATOR_ONOFF_COLOR);
|
||||
} else {
|
||||
PowerIndicatorOFF();
|
||||
ledManager.setMode(LED_ACTUATOR_ONOFF, 0, LEDManager::Mode::STATIC, LED_COLOR_BLACK);
|
||||
}
|
||||
# endif
|
||||
|
||||
# ifdef ESP32
|
||||
if (ONOFFConfig.useLastStateOnStart) {
|
||||
|
||||
@@ -203,6 +203,5 @@ void M5Print(char* line1, char* line2, char* line3) {
|
||||
M5.Lcd.drawString(line2, 5, M5.Lcd.height() * 0.8, 1);
|
||||
M5.Lcd.drawString(line3, 5, M5.Lcd.height() * 0.9, 1);
|
||||
delay(2000);
|
||||
InfoIndicatorOFF(); // to switch off no need of condition
|
||||
}
|
||||
#endif
|
||||
|
||||
@@ -53,8 +53,13 @@ void testDevice() {
|
||||
|
||||
void testLeds() {
|
||||
Log.notice(F("LED Test" CR));
|
||||
InfoIndicatorON();
|
||||
SendReceiveIndicatorON();
|
||||
ledManager.setMode(0, 0, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
|
||||
delay(1000);
|
||||
ledManager.setMode(0, 1, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
|
||||
delay(1000);
|
||||
ledManager.setMode(0, 2, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
|
||||
delay(1000);
|
||||
ledManager.setMode(0, 3, LEDManager::Mode::STATIC, LED_NETWORK_OK_COLOR, -1);
|
||||
Log.notice(F("LED Test Finished" CR));
|
||||
}
|
||||
|
||||
|
||||
@@ -557,7 +557,7 @@ void pubMqttDiscovery() {
|
||||
stateClassNone, //State Class
|
||||
"false", "true" //state_off, state_on
|
||||
);
|
||||
# ifdef RGB_INDICATORS
|
||||
# ifdef LED_ADDRESSABLE
|
||||
createDiscovery("number", //set Type
|
||||
subjectSYStoMQTT, "SYS: LED Brightness", (char*)getUniqueId("rgbb", "").c_str(), //set state_topic,name,uniqueId
|
||||
will_Topic, "", "{{ (value_json.rgbb/2.55) | round(0) }}", //set availability_topic,device_class,value_template,
|
||||
|
||||
@@ -64,8 +64,6 @@ 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);
|
||||
|
||||
@@ -1937,7 +1937,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
|
||||
// Queue completed message
|
||||
|
||||
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
|
||||
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
free(message);
|
||||
} else {
|
||||
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
|
||||
@@ -2003,7 +2003,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
|
||||
// Queue completed message
|
||||
|
||||
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
|
||||
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
free(message);
|
||||
} else {
|
||||
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
|
||||
@@ -2331,7 +2331,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
|
||||
line4.toCharArray(message->line4, WEBUI_TEXT_WIDTH);
|
||||
|
||||
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
|
||||
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
free(message);
|
||||
} else {
|
||||
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
|
||||
@@ -2389,7 +2389,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
|
||||
// Queue completed message
|
||||
|
||||
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
|
||||
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
free(message);
|
||||
} else {
|
||||
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
|
||||
@@ -2441,7 +2441,7 @@ void webUIPubPrint(const char* topicori, JsonObject& data) {
|
||||
// Queue completed message
|
||||
|
||||
if (xQueueSend(webUIQueue, (void*)&message, 0) != pdTRUE) {
|
||||
Log.error(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
Log.warning(F("[ WebUI ] webUIQueue full, discarding signal %s" CR), message->title);
|
||||
free(message);
|
||||
} else {
|
||||
// Log.notice(F("[ WebUI ] Queued %s" CR), message->title);
|
||||
|
||||
228
main/main.ino
228
main/main.ino
@@ -38,7 +38,8 @@ enum GatewayState {
|
||||
BROKER_DISCONNECTED,
|
||||
LOCAL_OTA_IN_PROGRESS,
|
||||
REMOTE_OTA_IN_PROGRESS,
|
||||
SLEEPING
|
||||
SLEEPING,
|
||||
ERROR
|
||||
};
|
||||
GatewayState gatewayState = GatewayState::WAITING_ONBOARDING;
|
||||
|
||||
@@ -86,8 +87,11 @@ bool ready_to_sleep = false;
|
||||
|
||||
#include <memory>
|
||||
|
||||
#include "LEDManager.h"
|
||||
#include "TheengsUtils.h"
|
||||
|
||||
LEDManager ledManager;
|
||||
|
||||
struct JsonBundle {
|
||||
StaticJsonDocument<JSON_MSG_BUFFER> doc;
|
||||
};
|
||||
@@ -382,6 +386,8 @@ void Config_update(JsonObject& data, const char* key, T& var) {
|
||||
bool jsonDispatch(JsonObject& data) {
|
||||
bool res = false;
|
||||
if (data.containsKey("origin")) {
|
||||
GatewayState previousGatewayState = gatewayState;
|
||||
gatewayState = GatewayState::PROCESSING;
|
||||
#if message_UTCtimestamp == true
|
||||
data["UTCtime"] = TheengsUtils::UTCtimestamp();
|
||||
#endif
|
||||
@@ -405,8 +411,10 @@ bool jsonDispatch(JsonObject& data) {
|
||||
res = true;
|
||||
}
|
||||
#endif
|
||||
gatewayState = previousGatewayState; // restore the previous state
|
||||
} else {
|
||||
Log.error(F("No origin in JSON filtered" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
return res;
|
||||
}
|
||||
@@ -416,6 +424,7 @@ boolean enqueueJsonObject(const StaticJsonDocument<JSON_MSG_BUFFER>& jsonDoc, in
|
||||
receivedMessages++;
|
||||
if (jsonDoc.size() == 0) {
|
||||
Log.error(F("Empty JSON, skipping" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return true;
|
||||
}
|
||||
if (queueLength >= QueueSize) {
|
||||
@@ -430,6 +439,7 @@ boolean enqueueJsonObject(const StaticJsonDocument<JSON_MSG_BUFFER>& jsonDoc, in
|
||||
// Semaphore check before enqueueing a document
|
||||
if (xSemaphoreTake(xQueueMutex, pdMS_TO_TICKS(timeout)) == pdFALSE) {
|
||||
Log.error(F("xQueueMutex not taken" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
blockedMessages++;
|
||||
return false;
|
||||
}
|
||||
@@ -474,6 +484,7 @@ std::string generateHash(const std::string& input) {
|
||||
void buildTopicFromId(JsonObject& Jsondata, const char* origin) {
|
||||
if (!Jsondata.containsKey("id")) {
|
||||
Log.error(F("No id in Jsondata" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -491,6 +502,7 @@ void buildTopicFromId(JsonObject& Jsondata, const char* origin) {
|
||||
topic = Jsondata["uuid"].as<std::string>();
|
||||
} else {
|
||||
Log.error(F("No uuid in Jsondata" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -520,6 +532,7 @@ void emptyQueue() {
|
||||
#ifdef ESP32
|
||||
if (xSemaphoreTake(xQueueMutex, pdMS_TO_TICKS(QueueSemaphoreTimeOutTask)) == pdFALSE) {
|
||||
Log.error(F("xQueueMutex not taken" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
#endif
|
||||
@@ -530,6 +543,7 @@ void emptyQueue() {
|
||||
#endif
|
||||
if (error) {
|
||||
Log.error(F("deserialize jsonQueue.front() failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
|
||||
gatewayState = GatewayState::ERROR;
|
||||
} else {
|
||||
if (jsonDispatch(obj))
|
||||
queueLengthSum++;
|
||||
@@ -566,6 +580,7 @@ bool pub(const char* topicori, JsonObject& data) {
|
||||
}
|
||||
if (data.size() == 0) {
|
||||
Log.error(F("Empty JSON, not published" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return res;
|
||||
}
|
||||
String topic = String(mqtt_topic) + String(gateway_name) + String(topicori);
|
||||
@@ -662,11 +677,11 @@ bool pubMQTT(const char* topic, const char* payload, bool retainFlag) {
|
||||
#ifdef ESP32
|
||||
if (xSemaphoreTake(xMqttMutex, pdMS_TO_TICKS(QueueSemaphoreTimeOutTask)) == pdFALSE) {
|
||||
Log.error(F("xMqttMutex not taken" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return res;
|
||||
}
|
||||
#endif
|
||||
if (mqtt && mqtt->connected()) {
|
||||
SendReceiveIndicatorON();
|
||||
Log.notice(F("[ OMG->MQTT ] topic: %s msg: %s " CR), topic, payload);
|
||||
res = mqtt->publish(topic, payload, 0, retainFlag);
|
||||
} else {
|
||||
@@ -784,7 +799,7 @@ void SYSConfig_init() {
|
||||
SYSConfig.discovery = DEFAULT_DISCOVERY;
|
||||
SYSConfig.ohdiscovery = OpenHABDiscovery;
|
||||
#endif
|
||||
#ifdef RGB_INDICATORS
|
||||
#ifdef LED_ADDRESSABLE
|
||||
SYSConfig.rgbbrightness = DEFAULT_ADJ_BRIGHTNESS;
|
||||
#endif
|
||||
SYSConfig.powerMode = DEFAULT_LOW_POWER_MODE;
|
||||
@@ -798,7 +813,7 @@ void SYSConfig_fromJson(JsonObject& SYSdata) {
|
||||
Config_update(SYSdata, "disc", SYSConfig.discovery);
|
||||
Config_update(SYSdata, "ohdisc", SYSConfig.ohdiscovery);
|
||||
#endif
|
||||
#ifdef RGB_INDICATORS
|
||||
#ifdef LED_ADDRESSABLE
|
||||
Config_update(SYSdata, "rgbb", SYSConfig.rgbbrightness);
|
||||
#endif
|
||||
Config_update(SYSdata, "powermode", SYSConfig.powerMode);
|
||||
@@ -816,7 +831,7 @@ void SYSConfig_save() {
|
||||
SYSdata["disc"] = SYSConfig.discovery;
|
||||
SYSdata["ohdisc"] = SYSConfig.ohdiscovery;
|
||||
# endif
|
||||
# ifdef RGB_INDICATORS
|
||||
# ifdef LED_ADDRESSABLE
|
||||
SYSdata["rgbb"] = SYSConfig.rgbbrightness;
|
||||
# endif
|
||||
String conf = "";
|
||||
@@ -855,6 +870,7 @@ void SYSConfig_load() {
|
||||
preferences.end();
|
||||
if (error) {
|
||||
Log.error(F("SYS config deserialization failed: %s, buffer capacity: %u" CR), error.c_str(), jsonBuffer.capacity());
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
if (jsonBuffer.isNull()) {
|
||||
@@ -878,7 +894,7 @@ std::pair<String, uint16_t> discoverMQTTbroker() {
|
||||
Log.trace(F("Browsing for MQTT service" CR));
|
||||
int n = MDNS.queryService("mqtt", "tcp");
|
||||
if (n == 0) {
|
||||
Log.error(F("no services found" CR));
|
||||
Log.warning(F("no services found" CR));
|
||||
} else {
|
||||
Log.trace(F("%d service(s) found" CR), n);
|
||||
for (int i = 0; i < n; ++i) {
|
||||
@@ -889,7 +905,7 @@ std::pair<String, uint16_t> discoverMQTTbroker() {
|
||||
Log.trace(F("One MQTT server found setting parameters" CR));
|
||||
return {MDNS.IP(0).toString(), uint16_t(MDNS.port(0))};
|
||||
} else {
|
||||
Log.error(F("Several MQTT servers found, please deactivate mDNS and set your default server" CR));
|
||||
Log.warning(F("Several MQTT servers found, please deactivate mDNS and set your default server" CR));
|
||||
}
|
||||
}
|
||||
return {"", 0};
|
||||
@@ -1043,6 +1059,7 @@ void setupMQTT() {
|
||||
if (cnt_parameters_backup) {
|
||||
// this was the first attempt to connect to a new server and it failed, revert to old settings
|
||||
Log.error(F("MQTT connection failed, reverting to previous settings" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
cnt_parameters_array[cnt_index] = cnt_parameters_backup->parameters;
|
||||
cnt_index = cnt_parameters_backup->cnt_index;
|
||||
mqttSetupPending = true;
|
||||
@@ -1051,10 +1068,7 @@ void setupMQTT() {
|
||||
return;
|
||||
}
|
||||
|
||||
ErrorIndicatorON();
|
||||
delayWithOTA(5000);
|
||||
ErrorIndicatorOFF();
|
||||
delayWithOTA(5000);
|
||||
delayWithOTA(10000);
|
||||
|
||||
if (failure_number_mqtt > maxRetryWatchDog) {
|
||||
# ifndef ESPWifiManualSetup
|
||||
@@ -1114,12 +1128,14 @@ void setESPWifiProtocolTxPower() {
|
||||
# if WifiGMode == true
|
||||
if (esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G) != ESP_OK) {
|
||||
Log.error(F("Failed to change WifiMode." CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if WifiGMode == false
|
||||
if (esp_wifi_set_protocol(WIFI_IF_STA, WIFI_PROTOCOL_11B | WIFI_PROTOCOL_11G | WIFI_PROTOCOL_11N) != ESP_OK) {
|
||||
Log.error(F("Failed to change WifiMode." CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -1153,12 +1169,14 @@ void setESPWifiProtocolTxPower() {
|
||||
# if WifiGMode == true
|
||||
if (!wifi_set_phy_mode(PHY_MODE_11G)) {
|
||||
Log.error(F("Failed to change WifiMode." CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
# endif
|
||||
|
||||
# if WifiGMode == false
|
||||
if (!wifi_set_phy_mode(PHY_MODE_11N)) {
|
||||
Log.error(F("Failed to change WifiMode." CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
# endif
|
||||
|
||||
@@ -1190,6 +1208,88 @@ void setESPWifiProtocolTxPower() {
|
||||
}
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
void updateAndHandleLEDsTask(void* pvParameters) {
|
||||
for (;;) {
|
||||
updateAndHandleLEDsTask();
|
||||
vTaskDelay(pdMS_TO_TICKS(100));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
||||
void updateAndHandleLEDsTask() {
|
||||
static GatewayState previousGatewayState;
|
||||
if (previousGatewayState != gatewayState) {
|
||||
#ifdef LED_POWER
|
||||
ledManager.setMode(0, LED_POWER, LEDManager::STATIC, LED_POWER_COLOR, -1);
|
||||
#endif
|
||||
switch (gatewayState) {
|
||||
case PROCESSING:
|
||||
#ifdef LED_PROCESSING
|
||||
ledManager.setMode(0, LED_PROCESSING, LEDManager::BLINK, LED_PROCESSING_COLOR, 3);
|
||||
#endif
|
||||
break;
|
||||
case WAITING_ONBOARDING:
|
||||
#ifdef LED_BROKER
|
||||
ledManager.setMode(0, LED_BROKER, LEDManager::STATIC, LED_WAITING_ONBOARD_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case ONBOARDING:
|
||||
#ifdef LED_BROKER
|
||||
ledManager.setMode(0, LED_BROKER, LEDManager::STATIC, LED_ONBOARD_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case NTWK_CONNECTED:
|
||||
#ifdef LED_NETWORK
|
||||
ledManager.setMode(0, LED_NETWORK, LEDManager::STATIC, LED_NETWORK_OK_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case BROKER_CONNECTED:
|
||||
#ifdef LED_BROKER
|
||||
ledManager.setMode(0, LED_BROKER, LEDManager::STATIC, LED_BROKER_OK_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case NTWK_DISCONNECTED:
|
||||
#ifdef LED_NETWORK
|
||||
ledManager.setMode(0, LED_NETWORK, LEDManager::BLINK, LED_NETWORK_ERROR_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case BROKER_DISCONNECTED:
|
||||
#ifdef LED_BROKER
|
||||
ledManager.setMode(0, LED_BROKER, LEDManager::BLINK, LED_BROKER_ERROR_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case SLEEPING:
|
||||
ledManager.setMode(0, -1, LEDManager::OFF, 0, -1);
|
||||
break;
|
||||
case OFFLINE:
|
||||
#ifdef LED_NETWORK
|
||||
ledManager.setMode(0, LED_NETWORK, LEDManager::BLINK, LED_OFFLINE_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case LOCAL_OTA_IN_PROGRESS:
|
||||
#ifdef LED_PROCESSING
|
||||
ledManager.setMode(0, LED_PROCESSING, LEDManager::BLINK, LED_OTA_LOCAL_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case REMOTE_OTA_IN_PROGRESS:
|
||||
#ifdef LED_PROCESSING
|
||||
ledManager.setMode(0, LED_PROCESSING, LEDManager::BLINK, LED_OTA_REMOTE_COLOR, -1);
|
||||
#endif
|
||||
break;
|
||||
case ERROR:
|
||||
#ifdef LED_ERROR
|
||||
ledManager.setMode(0, LED_ERROR, LEDManager::BLINK, LED_ERROR_COLOR, 3);
|
||||
#endif
|
||||
break;
|
||||
default:
|
||||
break;
|
||||
}
|
||||
previousGatewayState = gatewayState;
|
||||
}
|
||||
ledManager.update();
|
||||
}
|
||||
|
||||
void setup() {
|
||||
//Launch serial for debugging purposes
|
||||
Serial.begin(SERIAL_BAUD);
|
||||
@@ -1208,12 +1308,17 @@ void setup() {
|
||||
if (SYSConfig.offline)
|
||||
gatewayState = GatewayState::OFFLINE;
|
||||
|
||||
//setup LED status
|
||||
SetupIndicatorError();
|
||||
SetupIndicatorSendReceive();
|
||||
SetupIndicatorInfo();
|
||||
SetupIndicators(); // For RGB Leds
|
||||
ONIndicatorON();
|
||||
#ifdef LED_ADDRESSABLE
|
||||
# ifdef LED_ADDRESSABLE_PIN1
|
||||
ledManager.addLEDStrip(LED_ADDRESSABLE_PIN1, LED_ADDRESSABLE_NUM);
|
||||
# endif
|
||||
# ifdef LED_ADDRESSABLE_PIN2
|
||||
ledManager.addLEDStrip(LED_ADDRESSABLE_PIN2, LED_ADDRESSABLE_NUM);
|
||||
# endif
|
||||
ledManager.setBrightness(SYSConfig.rgbbrightness);
|
||||
#elif LED_PIN
|
||||
ledManager.addLEDStrip(LED_PIN, 1);
|
||||
#endif
|
||||
|
||||
#ifdef ESP8266
|
||||
# ifndef ZgatewaySRFB // if we are not in sonoff rf bridge case we apply the ESP8266 GPIO optimization
|
||||
@@ -1221,6 +1326,7 @@ void setup() {
|
||||
Serial.begin(SERIAL_BAUD, SERIAL_8N1, SERIAL_TX_ONLY); // enable on ESP8266 to free some pin
|
||||
# endif
|
||||
#elif ESP32
|
||||
xTaskCreate(updateAndHandleLEDsTask, "updateAndHandleLEDsTask", 2500, NULL, 1, NULL);
|
||||
xQueueMutex = xSemaphoreCreateMutex();
|
||||
xMqttMutex = xSemaphoreCreateMutex();
|
||||
# if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH)
|
||||
@@ -1239,6 +1345,7 @@ void setup() {
|
||||
gpio_num_t wake_pin0 = static_cast<gpio_num_t>(ESP32_EXT0_WAKE_PIN);
|
||||
if (esp_sleep_enable_ext0_wakeup(wake_pin0, ESP32_EXT0_WAKE_PIN_STATE) != ESP_OK) {
|
||||
Log.error(F("Failed to set deep sleep EXT0 Wakeup." CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
#endif
|
||||
#ifdef ESP32_EXT1_WAKE_PIN
|
||||
@@ -1247,6 +1354,7 @@ void setup() {
|
||||
esp_sleep_ext1_wakeup_mode_t wake_state1 = static_cast<esp_sleep_ext1_wakeup_mode_t>(ESP32_EXT1_WAKE_PIN_STATE);
|
||||
if (esp_sleep_enable_ext1_wakeup(wake_pin_bitmask, wake_state1) != ESP_OK) {
|
||||
Log.error(F("Failed to set deep sleep EXT1 Wakeup." CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
#endif
|
||||
#ifdef ESP32
|
||||
@@ -1526,8 +1634,6 @@ void setOTA() {
|
||||
|
||||
ArduinoOTA.onStart([]() {
|
||||
Log.trace(F("Start OTA, lock other functions" CR));
|
||||
ErrorIndicatorON();
|
||||
SendReceiveIndicatorON();
|
||||
last_ota_activity_millis = millis();
|
||||
#ifdef ESP32
|
||||
ProcessLock = true;
|
||||
@@ -1540,24 +1646,18 @@ void setOTA() {
|
||||
ArduinoOTA.onEnd([]() {
|
||||
Log.trace(F("\nOTA done" CR));
|
||||
last_ota_activity_millis = 0;
|
||||
ErrorIndicatorOFF();
|
||||
SendReceiveIndicatorOFF();
|
||||
lpDisplayPrint("OTA done");
|
||||
ESPRestart(6);
|
||||
});
|
||||
ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) {
|
||||
Log.trace(F("Progress: %u%%\r" CR), (progress / (total / 100)));
|
||||
gatewayState = GatewayState::LOCAL_OTA_IN_PROGRESS;
|
||||
#ifdef ESP32
|
||||
//esp_task_wdt_reset();
|
||||
#endif
|
||||
last_ota_activity_millis = millis();
|
||||
});
|
||||
ArduinoOTA.onError([](ota_error_t error) {
|
||||
last_ota_activity_millis = millis();
|
||||
ErrorIndicatorOFF();
|
||||
SendReceiveIndicatorOFF();
|
||||
Serial.printf("Error[%u]: ", error);
|
||||
gatewayState = GatewayState::ERROR;
|
||||
if (error == OTA_AUTH_ERROR)
|
||||
Log.error(F("Auth Failed" CR));
|
||||
else if (error == OTA_BEGIN_ERROR)
|
||||
@@ -1592,6 +1692,7 @@ void setupTLS(int index) {
|
||||
Log.notice(F("Server cert found from ss_server_cert" CR));
|
||||
} else {
|
||||
Log.error(F("No server cert found" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
|
||||
# if AWS_IOT
|
||||
@@ -1609,6 +1710,7 @@ void setupTLS(int index) {
|
||||
Log.notice(F("Client cert found from ss_client_cert" CR));
|
||||
} else {
|
||||
Log.error(F("No client cert found" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
if (cnt_parameters_array[index].client_key.length() > MIN_CERT_LENGTH) {
|
||||
sClient->setPrivateKey(cnt_parameters_array[index].client_key.c_str());
|
||||
@@ -1618,6 +1720,7 @@ void setupTLS(int index) {
|
||||
Log.notice(F("Client key found from ss_client_key" CR));
|
||||
} else {
|
||||
Log.error(F("No client key found" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
# endif
|
||||
# elif defined(ESP8266)
|
||||
@@ -1696,6 +1799,7 @@ void setup_wifi() {
|
||||
|
||||
if (!WiFi.config(ip_adress, gateway_adress, subnet_adress, dns_adress)) {
|
||||
Log.error(F("Wifi STA Failed to configure" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
|
||||
# endif
|
||||
@@ -1757,11 +1861,6 @@ void blockingWaitForReset() {
|
||||
ActuatorTrigger();
|
||||
}
|
||||
# endif
|
||||
# ifdef ESP32
|
||||
//esp_task_wdt_delete(NULL);
|
||||
# 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()) {
|
||||
@@ -1892,6 +1991,7 @@ void saveConfig() {
|
||||
File configFile = SPIFFS.open("/config.json", "w");
|
||||
if (!configFile) {
|
||||
Log.error(F("failed to open config file for writing" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
|
||||
serializeJson(json, configFile);
|
||||
@@ -1920,6 +2020,7 @@ bool loadConfigFromFlash() {
|
||||
auto error = deserializeJson(json, configFile);
|
||||
if (error) {
|
||||
Log.error(F("deserialize config failed: %s, buffer capacity: %u" CR), error.c_str(), json.capacity());
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
if (!json.isNull()) {
|
||||
Log.trace(F("\nparsed json, size: %u" CR), json.memoryUsage());
|
||||
@@ -2155,8 +2256,6 @@ void setupwifi(bool reset_settings) {
|
||||
|
||||
if (!SYSConfig.offline && !wifi_reconnect_bypass()) // if we didn't connect with saved credential we start Wifimanager web portal
|
||||
{
|
||||
InfoIndicatorON();
|
||||
ErrorIndicatorON();
|
||||
Log.notice(F("Connect your phone to WIFI AP: %s with PWD: %s" CR), WifiManager_ssid, ota_pass);
|
||||
gatewayState = GatewayState::ONBOARDING;
|
||||
//fetches ssid and pass and tries to connect
|
||||
@@ -2189,11 +2288,10 @@ void setupwifi(bool reset_settings) {
|
||||
ESPRestart(3);
|
||||
}
|
||||
}
|
||||
InfoIndicatorOFF();
|
||||
ErrorIndicatorOFF();
|
||||
}
|
||||
|
||||
displayPrint("Network connected");
|
||||
gatewayState = GatewayState::NTWK_CONNECTED;
|
||||
|
||||
if (shouldSaveConfig) {
|
||||
//read updated parameters
|
||||
@@ -2276,6 +2374,7 @@ void setup_ethernet_esp32() {
|
||||
}
|
||||
} else {
|
||||
Log.error(F("Ethernet not started" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -2296,11 +2395,11 @@ void WiFiEvent(WiFiEvent_t event) {
|
||||
ethConnected = true;
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_DISCONNECTED:
|
||||
Log.error(F("Ethernet Disconnected" CR));
|
||||
Log.warning(F("Ethernet Disconnected" CR));
|
||||
ethConnected = false;
|
||||
break;
|
||||
case ARDUINO_EVENT_ETH_STOP:
|
||||
Log.error(F("Ethernet Stopped" CR));
|
||||
Log.warning(F("Ethernet Stopped" CR));
|
||||
ethConnected = false;
|
||||
break;
|
||||
default:
|
||||
@@ -2357,8 +2456,8 @@ void loop() {
|
||||
checkButton(); // check if a reset of wifi/mqtt settings is asked
|
||||
#endif
|
||||
|
||||
#ifdef ESP32
|
||||
//esp_task_wdt_reset();
|
||||
#ifdef ESP8266
|
||||
updateAndHandleLEDsTask(); // With ESP8266 we need to update the LEDs in the loop
|
||||
#endif
|
||||
if (!SYSConfig.offline) {
|
||||
if (mqttSetupPending) {
|
||||
@@ -2372,8 +2471,6 @@ void loop() {
|
||||
// Switch off of the LED after TimeLedON
|
||||
if (now > (timer_led_measures + (TimeLedON * 1000))) {
|
||||
timer_led_measures = millis();
|
||||
InfoIndicatorOFF();
|
||||
SendReceiveIndicatorOFF();
|
||||
}
|
||||
|
||||
if (ethConnected || WiFi.status() == WL_CONNECTED) {
|
||||
@@ -2387,7 +2484,6 @@ void loop() {
|
||||
#endif
|
||||
mqtt->loop();
|
||||
if (mqtt->connected()) { // MQTT client is still connected
|
||||
InfoIndicatorON();
|
||||
failure_number_ntwk = 0;
|
||||
|
||||
#ifdef ZmqttDiscovery
|
||||
@@ -2435,20 +2531,13 @@ void loop() {
|
||||
}
|
||||
}
|
||||
} else if (!SYSConfig.offline) { // disconnected from network
|
||||
#ifdef ESP32
|
||||
//esp_task_wdt_reset();
|
||||
#endif
|
||||
Log.warning(F("Network disconnected" CR));
|
||||
gatewayState = GatewayState::NTWK_DISCONNECTED;
|
||||
ErrorIndicatorON();
|
||||
delay(2000); // add a delay to avoid ESP32 crash and reset
|
||||
#ifdef ESP32
|
||||
//esp_task_wdt_reset();
|
||||
#endif
|
||||
ErrorIndicatorOFF();
|
||||
delay(2000);
|
||||
if (!wifi_reconnect_bypass())
|
||||
if (!wifi_reconnect_bypass()) {
|
||||
sleep();
|
||||
} else {
|
||||
gatewayState = GatewayState::NTWK_CONNECTED;
|
||||
}
|
||||
}
|
||||
// Function that doesn't need an active connection
|
||||
#if defined(ZboardM5STICKC) || defined(ZboardM5STICKCP) || defined(ZboardM5STACK) || defined(ZboardM5TOUGH)
|
||||
@@ -2641,7 +2730,7 @@ String stateMeasures() {
|
||||
SYSdata["uptime"] = uptime();
|
||||
|
||||
SYSdata["version"] = OMG_VERSION;
|
||||
#ifdef RGB_INDICATORS
|
||||
#ifdef LED_ADDRESSABLE
|
||||
SYSdata["rgbb"] = SYSConfig.rgbbrightness;
|
||||
#endif
|
||||
#ifdef ZmqttDiscovery
|
||||
@@ -2656,6 +2745,7 @@ String stateMeasures() {
|
||||
// Some RTL_433 decoders have memory leak, this is a temporary workaround
|
||||
if (freeMem < MinimumMemory) {
|
||||
Log.error(F("Not enough memory %d, restarting" CR), freeMem);
|
||||
gatewayState = GatewayState::ERROR;
|
||||
ESPRestart(8);
|
||||
}
|
||||
#endif
|
||||
@@ -2796,6 +2886,7 @@ void receivingMQTT(char* topicOri, char* datacallback) {
|
||||
auto error = deserializeJson(jsonBuffer, datacallback);
|
||||
if (error) {
|
||||
Log.error(F("deserialize MQTT data failed: %s" CR), error.c_str());
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -2873,7 +2964,6 @@ void receivingMQTT(char* topicOri, char* datacallback) {
|
||||
MQTTtoWebUI(topicOri, jsondata);
|
||||
# endif
|
||||
#endif
|
||||
SendReceiveIndicatorON();
|
||||
|
||||
MQTTtoSYS(topicOri, jsondata);
|
||||
} else { // not a json object --> simple decoding
|
||||
@@ -2950,11 +3040,13 @@ bool checkForUpdates() {
|
||||
auto error = deserializeJson(jsonBuffer, payload);
|
||||
if (error) {
|
||||
Log.error(F("Deserialize MQTT data failed: %s" CR), error.c_str());
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
Log.trace(F("HttpCode %d" CR), httpCode);
|
||||
Log.trace(F("Payload %s" CR), payload.c_str());
|
||||
} else {
|
||||
Log.error(F("Error on HTTP request"));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
}
|
||||
http.end(); //Free the resources
|
||||
Log.notice(F("Update check done, free heap: %d"), ESP.getFreeHeap());
|
||||
@@ -2994,6 +3086,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
if (url) {
|
||||
if (!strstr((url + (strlen(url) - 5)), ".bin")) {
|
||||
Log.error(F("Invalid firmware extension" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
# if MQTT_HTTPS_FW_UPDATE_USE_PASSWORD > 0
|
||||
@@ -3001,10 +3094,12 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
if (pwd) {
|
||||
if (strcmp(pwd, ota_pass) != 0) {
|
||||
Log.error(F("Invalid OTA password" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
} else {
|
||||
Log.error(F("No password sent" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
# endif
|
||||
@@ -3024,11 +3119,11 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
# endif
|
||||
} else {
|
||||
Log.error(F("Invalid URL" CR));
|
||||
gatewayState = GatewayState::ERROR;
|
||||
return;
|
||||
}
|
||||
# ifdef ESP32
|
||||
ProcessLock = true;
|
||||
//esp_task_wdt_delete(NULL); // Stop task watchdog during update
|
||||
# ifdef ZgatewayBT
|
||||
stopProcessing();
|
||||
# endif
|
||||
@@ -3036,8 +3131,6 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
Log.warning(F("Starting firmware update" CR));
|
||||
gatewayState = GatewayState::REMOTE_OTA_IN_PROGRESS;
|
||||
|
||||
SendReceiveIndicatorON();
|
||||
ErrorIndicatorON();
|
||||
StaticJsonDocument<JSON_MSG_BUFFER> jsondata;
|
||||
jsondata["release_summary"] = "Update in progress ...";
|
||||
jsondata["origin"] = subjectRLStoMQTT;
|
||||
@@ -3106,6 +3199,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
# elif ESP8266
|
||||
Log.error(F("HTTP_UPDATE_FAILED Error (%d): %s\n" CR), ESPhttpUpdate.getLastError(), ESPhttpUpdate.getLastErrorString().c_str());
|
||||
# endif
|
||||
gatewayState = GatewayState::ERROR;
|
||||
break;
|
||||
|
||||
case HTTP_UPDATE_NO_UPDATES:
|
||||
@@ -3129,9 +3223,6 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
break;
|
||||
}
|
||||
|
||||
SendReceiveIndicatorOFF();
|
||||
ErrorIndicatorOFF();
|
||||
|
||||
ESPRestart(6);
|
||||
}
|
||||
}
|
||||
@@ -3144,7 +3235,7 @@ void MQTTHttpsFWUpdate(char* topicOri, JsonObject& HttpsFwUpdateData) {
|
||||
*/
|
||||
void readCntParameters(int index) {
|
||||
if (index < 0 || index > 2) {
|
||||
Log.error(F("Invalid cnt index" CR));
|
||||
Log.warning(F("Invalid cnt index" CR));
|
||||
return;
|
||||
}
|
||||
StaticJsonDocument<JSON_MSG_BUFFER> jsonBuffer;
|
||||
@@ -3191,19 +3282,18 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
|
||||
stateMeasures();
|
||||
}
|
||||
}
|
||||
#ifdef RGB_INDICATORS
|
||||
#ifdef LED_ADDRESSABLE
|
||||
if (SYSdata.containsKey("rgbb") && SYSdata["rgbb"].is<float>()) {
|
||||
if (SYSdata["rgbb"] >= 0 && SYSdata["rgbb"] <= 255) {
|
||||
SYSConfig.rgbbrightness = TheengsUtils::round2(SYSdata["rgbb"]);
|
||||
leds.setBrightness(SYSConfig.rgbbrightness);
|
||||
leds.show();
|
||||
ledManager.setBrightness(SYSConfig.rgbbrightness);
|
||||
# ifdef ZactuatorONOFF
|
||||
updatePowerIndicator();
|
||||
# endif
|
||||
Log.notice(F("RGB brightness: %d" CR), SYSConfig.rgbbrightness);
|
||||
stateMeasures();
|
||||
} else {
|
||||
Log.error(F("RGB brightness value invalid - ignoring command" CR));
|
||||
Log.warning(F("RGB brightness value invalid - ignoring command" CR));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -3234,7 +3324,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
|
||||
WiFi.waitForConnectResult(WiFi_TimeOut * 1000);
|
||||
|
||||
if (WiFi.status() != WL_CONNECTED) {
|
||||
Log.error(F("Failed to connect to new AP; falling back" CR));
|
||||
Log.warning(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(WifiGMode) || defined(WifiPower)
|
||||
@@ -3290,7 +3380,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
|
||||
|
||||
if (SYSdata.containsKey("cnt_index") && SYSdata["cnt_index"].is<int>()) {
|
||||
if (SYSdata["cnt_index"].as<int>() < 0 || SYSdata["cnt_index"].as<int>() > 2) {
|
||||
Log.error(F("Invalid cnt index provided - ignoring command" CR));
|
||||
Log.warning(F("Invalid cnt index provided - ignoring command" CR));
|
||||
return;
|
||||
}
|
||||
|
||||
@@ -3413,7 +3503,7 @@ void MQTTtoSYS(char* topicOri, JsonObject& SYSdata) { // json object decoding
|
||||
if (SYSConfig.discovery)
|
||||
pubMqttDiscovery();
|
||||
} else {
|
||||
Log.error(F("Discovery command not a boolean" CR));
|
||||
Log.warning(F("Discovery command not a boolean" CR));
|
||||
}
|
||||
Log.notice(F("Discovery state: %T" CR), SYSConfig.discovery);
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user