mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Compare commits
11 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
eb68556012 | ||
|
|
30f7b36a9c | ||
|
|
927272824c | ||
|
|
bab472d2d1 | ||
|
|
ec306c4934 | ||
|
|
3e0566cf07 | ||
|
|
86d0d784a0 | ||
|
|
b06dad9395 | ||
| a974290389 | |||
| 2da04b45bf | |||
| 724eabc22f |
@@ -3,4 +3,5 @@
|
||||
-DWiz5100
|
||||
#-DPID_DISABLE
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#-DW5500_CS_PIN=53
|
||||
-DDMX_SMOOTH
|
||||
-DSYSLOG_ENABLE
|
||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
||||
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||
-DARTNET_ENABLE
|
||||
-DOTA
|
||||
-DSTATUSLED
|
||||
@@ -10,7 +10,8 @@
|
||||
-DARDUINO_OTA_MDNS_DISABLE
|
||||
-DMDNS_ENABLE
|
||||
-DMCP23017
|
||||
-DCORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-DTIMER_INT
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
|
||||
@@ -26,6 +26,10 @@
|
||||
#-DmodbusSerial=Serial1
|
||||
#-DMODBUS_DEBUG
|
||||
|
||||
#-DMODBUS_UART_RX_PIN=16
|
||||
#-DMODBUS_UART_TX_PIN=17
|
||||
#-DmodbusSerial=Serial2
|
||||
|
||||
# Use default pins for modbus UART
|
||||
#-DMODBUS_UART_RX_PIN=-1
|
||||
#-DMODBUS_UART_TX_PIN=-1
|
||||
@@ -46,5 +50,10 @@
|
||||
-DFS_PREPARE
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
#-D CORS=\"http://lazyhome.ru\"
|
||||
-DOTA_PORT=80
|
||||
|
||||
-DMQTT_KEEPALIVE=10
|
||||
-DMQTT_SOCKET_TIMEOUT=20
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
@@ -17,7 +17,8 @@
|
||||
-DFS_PREPARE
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
#-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-DOTA_PORT=80
|
||||
|
||||
#oct22 - violation in Publish/OnMQTTConnect while publish homie info
|
||||
|
||||
@@ -12,8 +12,8 @@
|
||||
-DTIMER_INT
|
||||
#-DFLASH_OFFSET=-256
|
||||
|
||||
# Serial parameters for LEGACY Modbus
|
||||
-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
||||
# default MODBUS Serial parameters for LEGACY Modbus and MODBUS over IP
|
||||
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||
|
||||
#Set Logariphmic law for DMX channels bright
|
||||
-DBRIGHT_LOG
|
||||
@@ -34,5 +34,9 @@
|
||||
#-DdebugSerialPort=Serial
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
#-D CORS=\"http://lazyhome.ru\"
|
||||
-DOTA_PORT=80
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
#-D MERCURY_ENABLE
|
||||
#-D IPMODBUS
|
||||
@@ -19,5 +19,6 @@
|
||||
|
||||
-DOTA
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-DOTA_PORT=80
|
||||
@@ -1,4 +1,4 @@
|
||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
||||
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||
-DAVR_DMXOUT_PIN=18
|
||||
-DSYSLOG_ENABLE
|
||||
-DWiz5100
|
||||
@@ -7,5 +7,6 @@
|
||||
-DMDNS_ENABLE
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-DOTA_PORT=80
|
||||
@@ -1,5 +1,5 @@
|
||||
-DWiz5500
|
||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
||||
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||
-DAVR_DMXOUT_PIN=18
|
||||
-DSYSLOG_ENABLE
|
||||
#-DPID_DISABLE
|
||||
@@ -7,5 +7,6 @@
|
||||
-DMDNS_ENABLE
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-DOTA_PORT=80
|
||||
@@ -1,5 +1,5 @@
|
||||
|
||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
||||
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||
#-DAVR_DMXOUT_PIN=18
|
||||
-DDMX_DISABLE
|
||||
-DMODBUS_DISABLE
|
||||
@@ -20,7 +20,8 @@
|
||||
-DMDNS_ENABLE
|
||||
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
|
||||
# Example of UARTBRIDGE configuration
|
||||
#-DUARTBRIDGE_ENABLE
|
||||
|
||||
@@ -1,9 +1,9 @@
|
||||
|
||||
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1
|
||||
#-DMODBUS_SERIAL_PARAM=SERIAL_8E1
|
||||
#-DAVR_DMXOUT_PIN=18
|
||||
-DDMX_DISABLE
|
||||
-DMODBUS_DISABLE
|
||||
#-DMBUS_DISABLE
|
||||
-DMBUS_DISABLE
|
||||
#-DOWIRE_DISABLE
|
||||
-DDHT_DISABLE
|
||||
-DCOUNTER_DISABLE
|
||||
@@ -19,7 +19,8 @@
|
||||
-DARDUINO_OTA_MDNS_DISABLE
|
||||
#-DMDNS_ENABLE
|
||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||
-D CORS=\"http://lazyhome.ru\"
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
-DOTA_PORT=80
|
||||
-DHSV_DISABLE
|
||||
-DMULTIVENT_DISABLE
|
||||
|
||||
@@ -14,3 +14,5 @@
|
||||
-DPID_DISABLE
|
||||
#-DMCP23017
|
||||
|
||||
-D CORS=\"*\"
|
||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||
@@ -9,15 +9,31 @@
|
||||
-DSPILED_DISABLE
|
||||
-DAC_DISABLE
|
||||
-DPID_DISABLE
|
||||
-DdebugSerialPort=SerialUSB
|
||||
-DSerialPortType=USBSerial
|
||||
-DSERIAL_BAUD=0
|
||||
|
||||
-DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC
|
||||
-DUSBCON
|
||||
-DENABLE_HWSERIAL1
|
||||
-DdebugSerialPort=Serial1
|
||||
|
||||
#-DFLASH_BASE_ADDRESS
|
||||
#-DFLASH_DATA_SECTOR
|
||||
#-DFLASH_PAGE_NUMBER
|
||||
|
||||
-D PIO_FRAMEWORK_ARDUINO_ENABLE_MASS_STORAGE
|
||||
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC_AND_MSC
|
||||
|
||||
#-DdebugSerialPort=SerialUSB
|
||||
#-DSerialPortType=USBSerial
|
||||
#-DSERIAL_BAUD=0
|
||||
|
||||
#-DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC
|
||||
#-DUSBCON
|
||||
#-DUSBD_VID=0x0483
|
||||
#-DUSBD_PID=0x5740
|
||||
#-DUSB_MANUFACTURER="Unknown"
|
||||
#-DUSB_PRODUCT="\"BLUEPILL_F103C8\""
|
||||
#-DHAL_PCD_MODULE_ENABLED
|
||||
#-D USBD_USE_CDC
|
||||
|
||||
-D HAL_CAN_MODULE_ENABLED
|
||||
#HAL_ETH_MODULE_DISABLED
|
||||
#HAL_SD_MODULE_DISABLED
|
||||
#HAL_DAC_MODULE_DISABLED
|
||||
Binary file not shown.
BIN
compiled/Mega2560-optiboot/firmware.elf
Normal file
BIN
compiled/Mega2560-optiboot/firmware.elf
Normal file
Binary file not shown.
File diff suppressed because it is too large
Load Diff
1
compiled/Mega2560-optiboot/upload.bat
Normal file
1
compiled/Mega2560-optiboot/upload.bat
Normal file
@@ -0,0 +1 @@
|
||||
..\tools\win\tool-avrdude\avrdude -C ../tools/mac/tool-avrdude/avrdude.conf -v -V -P com8 -patmega2560 -cwiring -b115200 -D -Uflash:w:firmware.hex:i
|
||||
1
compiled/Mega2560-optiboot/uploadOTA.bat
Normal file
1
compiled/Mega2560-optiboot/uploadOTA.bat
Normal file
@@ -0,0 +1 @@
|
||||
..\tools\arduinoOTA.exe -address 192.168.11.213 -port 80 -username arduino -password password -sketch firmware.bin -b -upload /sketch
|
||||
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
Binary file not shown.
1
compiled/esp8266-wifi/ota.bat
Normal file
1
compiled/esp8266-wifi/ota.bat
Normal file
@@ -0,0 +1 @@
|
||||
arduinoOTA -address 192.168.88.54 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin
|
||||
Binary file not shown.
91
compiled/lighthub21/unlock.bat
Normal file
91
compiled/lighthub21/unlock.bat
Normal file
@@ -0,0 +1,91 @@
|
||||
@ECHO off
|
||||
|
||||
REM Wait X second for memory on Arduino Due is erased.
|
||||
SET WAIT_ERASED=4
|
||||
|
||||
ECHO ------ External tool BossacArduinoDue started ------
|
||||
|
||||
REM number of command line arguments ok?
|
||||
REM IF [%1]==[] GOTO error_args
|
||||
REM IF [%2]==[] GOTO error_args
|
||||
|
||||
REM set command line arguments
|
||||
SET BOSSACPATH=..\tools\win\tool-bossac\bossac.exe
|
||||
SET BINFILE=firmware.bin
|
||||
|
||||
REM parse command line arguments
|
||||
SET BOSSACPATH=%BOSSACPATH:"=%
|
||||
SET BINFILE=%BINFILE:"=%
|
||||
|
||||
REM workeround for bug in Atmel Studio 6.0.1996 Service Pack 2
|
||||
SET BINFILE=%BINFILE:\\=\%
|
||||
SET BINFILE=%BINFILE:.cproj=%
|
||||
|
||||
REM bossac path exist?
|
||||
IF NOT EXIST "%BOSSACPATH%" GOTO error_arg1
|
||||
|
||||
REM bin file exist?
|
||||
IF NOT EXIST "%BINFILE%" GOTO error_binfile
|
||||
|
||||
REM fetch DeviceID of Arduino Due Programming Port from WMI Service
|
||||
FOR /f "tokens=* skip=1" %%a IN ('wmic PATH Win32_SerialPort Where "Caption LIKE '%%BOSSA%%'" get DeviceID') DO (
|
||||
SET COMX=%%a
|
||||
GOTO exit1
|
||||
)
|
||||
|
||||
REM Arduino Due Programming Port not exist
|
||||
GOTO error_comport
|
||||
|
||||
:exit1
|
||||
|
||||
REM remove blank
|
||||
SET COMPORT=%COMX: =%
|
||||
|
||||
REM report in Atmel Studio 6.0 IDE output window
|
||||
ECHO BossacPath=%BOSSACPATH%
|
||||
ECHO BinFile=%BINFILE%
|
||||
ECHO Arduino Due Programming Port is detected as %COMPORT%.
|
||||
|
||||
REM The bossac bootloader only runs if the memory on Arduino Due is erased.
|
||||
REM The Arduino IDE does this by opening and closing the COM port at 1200 baud.
|
||||
REM This causes the Due to execute a soft erase command.
|
||||
ECHO Forcing reset using 1200bps open/close on port
|
||||
ECHO MODE %COMPORT%:1200,N,8,1
|
||||
MODE %COMPORT%:1200,N,8,1
|
||||
|
||||
REM Wait X second for memory on Arduino Due is erased.
|
||||
ECHO Wait for memory on Arduino Due is erased...
|
||||
PING -n %WAIT_ERASED% 127.0.0.1>NUL
|
||||
|
||||
REM Execute bossac.exe
|
||||
ECHO Execute bossac with command line:
|
||||
|
||||
"%BOSSACPATH%" -i --port=%COMPORT% --unlock -R
|
||||
REM START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -u -e -w -v -b "%BINFILE%" -R
|
||||
|
||||
GOTO end
|
||||
|
||||
:error_args
|
||||
ECHO Error: wrong number of command line arguments passed!
|
||||
GOTO end
|
||||
|
||||
:error_arg1
|
||||
ECHO Error: command line argument 1 - path to bossac.exe not exist! - "C:\Program Files (x86)\arduino-1.5.2\hardware\tools\bossac.exe"
|
||||
ECHO Error: command line argument 1 - argument passed = %1
|
||||
GOTO end
|
||||
|
||||
:error_arg2
|
||||
ECHO Error: command line argument 2 - path to bin file not exist! - use $(OutputDirectory)\$(OutputFileName).bin
|
||||
ECHO Error: command line argument 2 - argument passed = %1
|
||||
GOTO end
|
||||
|
||||
:error_binfile
|
||||
ECHO Error: bin file "%BINFILE%" not exist!
|
||||
GOTO end
|
||||
|
||||
:error_comport
|
||||
ECHO Error: Arduino Due Programming Port not found!
|
||||
|
||||
:end
|
||||
|
||||
ECHO ======================== Done ========================
|
||||
@@ -59,8 +59,8 @@ PING -n %WAIT_ERASED% 127.0.0.1>NUL
|
||||
|
||||
REM Execute bossac.exe
|
||||
ECHO Execute bossac with command line:
|
||||
ECHO "%BOSSACPATH%" -i -d --port=%COMPORT% -U false -e -w -v -b "%BINFILE%" -R
|
||||
START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -U false -e -w -v -b "%BINFILE%" -R
|
||||
"%BOSSACPATH%" -i --port=%COMPORT% -U false -w -v -b "%BINFILE%" -R
|
||||
REM START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -U false -e -w -v -b "%BINFILE%" -R
|
||||
|
||||
GOTO end
|
||||
|
||||
|
||||
91
compiled/lighthub21/uploadNative.bat
Normal file
91
compiled/lighthub21/uploadNative.bat
Normal file
@@ -0,0 +1,91 @@
|
||||
@ECHO off
|
||||
|
||||
REM Wait X second for memory on Arduino Due is erased.
|
||||
SET WAIT_ERASED=4
|
||||
|
||||
ECHO ------ External tool BossacArduinoDue started ------
|
||||
|
||||
REM number of command line arguments ok?
|
||||
REM IF [%1]==[] GOTO error_args
|
||||
REM IF [%2]==[] GOTO error_args
|
||||
|
||||
REM set command line arguments
|
||||
SET BOSSACPATH=..\tools\win\tool-bossac\bossac.exe
|
||||
SET BINFILE=firmware.bin
|
||||
|
||||
REM parse command line arguments
|
||||
SET BOSSACPATH=%BOSSACPATH:"=%
|
||||
SET BINFILE=%BINFILE:"=%
|
||||
|
||||
REM workeround for bug in Atmel Studio 6.0.1996 Service Pack 2
|
||||
SET BINFILE=%BINFILE:\\=\%
|
||||
SET BINFILE=%BINFILE:.cproj=%
|
||||
|
||||
REM bossac path exist?
|
||||
IF NOT EXIST "%BOSSACPATH%" GOTO error_arg1
|
||||
|
||||
REM bin file exist?
|
||||
IF NOT EXIST "%BINFILE%" GOTO error_binfile
|
||||
|
||||
REM fetch DeviceID of Arduino Due Programming Port from WMI Service
|
||||
FOR /f "tokens=* skip=1" %%a IN ('wmic PATH Win32_SerialPort Where "Caption LIKE '%%BOSSA%%'" get DeviceID') DO (
|
||||
SET COMX=%%a
|
||||
GOTO exit1
|
||||
)
|
||||
|
||||
REM Arduino Due Programming Port not exist
|
||||
GOTO error_comport
|
||||
|
||||
:exit1
|
||||
|
||||
REM remove blank
|
||||
SET COMPORT=%COMX: =%
|
||||
|
||||
REM report in Atmel Studio 6.0 IDE output window
|
||||
ECHO BossacPath=%BOSSACPATH%
|
||||
ECHO BinFile=%BINFILE%
|
||||
ECHO Arduino Due Programming Port is detected as %COMPORT%.
|
||||
|
||||
REM The bossac bootloader only runs if the memory on Arduino Due is erased.
|
||||
REM The Arduino IDE does this by opening and closing the COM port at 1200 baud.
|
||||
REM This causes the Due to execute a soft erase command.
|
||||
ECHO Forcing reset using 1200bps open/close on port
|
||||
ECHO MODE %COMPORT%:1200,N,8,1
|
||||
MODE %COMPORT%:1200,N,8,1
|
||||
|
||||
REM Wait X second for memory on Arduino Due is erased.
|
||||
ECHO Wait for memory on Arduino Due is erased...
|
||||
PING -n %WAIT_ERASED% 127.0.0.1>NUL
|
||||
|
||||
REM Execute bossac.exe
|
||||
ECHO Execute bossac with command line:
|
||||
|
||||
"%BOSSACPATH%" -i --port=%COMPORT% -w -v -b "%BINFILE%" -R
|
||||
REM START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -u -e -w -v -b "%BINFILE%" -R
|
||||
|
||||
GOTO end
|
||||
|
||||
:error_args
|
||||
ECHO Error: wrong number of command line arguments passed!
|
||||
GOTO end
|
||||
|
||||
:error_arg1
|
||||
ECHO Error: command line argument 1 - path to bossac.exe not exist! - "C:\Program Files (x86)\arduino-1.5.2\hardware\tools\bossac.exe"
|
||||
ECHO Error: command line argument 1 - argument passed = %1
|
||||
GOTO end
|
||||
|
||||
:error_arg2
|
||||
ECHO Error: command line argument 2 - path to bin file not exist! - use $(OutputDirectory)\$(OutputFileName).bin
|
||||
ECHO Error: command line argument 2 - argument passed = %1
|
||||
GOTO end
|
||||
|
||||
:error_binfile
|
||||
ECHO Error: bin file "%BINFILE%" not exist!
|
||||
GOTO end
|
||||
|
||||
:error_comport
|
||||
ECHO Error: Arduino Due Programming Port not found!
|
||||
|
||||
:end
|
||||
|
||||
ECHO ======================== Done ========================
|
||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
File diff suppressed because it is too large
Load Diff
1
compiled/mega2560slim-5100/update_bin.sh
Normal file
1
compiled/mega2560slim-5100/update_bin.sh
Normal file
@@ -0,0 +1 @@
|
||||
cp ../../.pio/build/lighthub21/firmware.bin .
|
||||
6597
compiled/nrf52840-5500
Normal file
6597
compiled/nrf52840-5500
Normal file
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Binary file not shown.
Binary file not shown.
BIN
compiled/tools/arduinoOTA
Normal file
BIN
compiled/tools/arduinoOTA
Normal file
Binary file not shown.
BIN
compiled/tools/arduinoOTA.exe
Normal file
BIN
compiled/tools/arduinoOTA.exe
Normal file
Binary file not shown.
BIN
compiled/tools/mac/tool-esptool/avrdude
Normal file
BIN
compiled/tools/mac/tool-esptool/avrdude
Normal file
Binary file not shown.
BIN
compiled/tools/win/tool-esptool/esptool
Normal file
BIN
compiled/tools/win/tool-esptool/esptool
Normal file
Binary file not shown.
16
compiled/update_bin.bat
Normal file
16
compiled/update_bin.bat
Normal file
@@ -0,0 +1,16 @@
|
||||
copy ..\.pio\build\due\firmware.bin due
|
||||
copy ..\.pio\build\controllino\firmware.hex controllino
|
||||
copy ..\.pio\build\m5stack\firmware.bin m5stack
|
||||
copy ..\.pio\build\mega2560slim-5100\firmware.hex mega2560slim-5100
|
||||
copy ..\.pio\build\mega2560slim-5100\firmware.bin mega2560slim-5100
|
||||
copy ..\.pio\build\mega2560slim2\firmware.hex mega2560slim2
|
||||
copy ..\.pio\build\mega2560slim2\firmware.bin mega2560slim2
|
||||
copy ..\.pio\build\due-5100\firmware.bin due-5100
|
||||
copy ..\.pio\build\mega2560-5100\firmware.hex mega2560-5100
|
||||
copy ..\.pio\build\due-5500\firmware.bin due-5500
|
||||
copy ..\.pio\build\nrf52840\firmware.hex nrf52840-5500
|
||||
copy ..\.pio\build\esp32-wifi\firmware.bin esp32-wifi
|
||||
copy ..\.pio\build\stm32-enc2860\firmware.bin stm32-enc2860
|
||||
copy ..\.pio\build\esp8266-wifi\firmware.bin esp8266-wifi
|
||||
copy ..\.pio\build\lighthub21\firmware.bin lighthub21
|
||||
copy ..\.pio\build\mega2560-5500\firmware.hex mega2560-5500
|
||||
25
config-examples/sonoff_s26_humidity_controller.json
Normal file
25
config-examples/sonoff_s26_humidity_controller.json
Normal file
@@ -0,0 +1,25 @@
|
||||
{
|
||||
"syslog":["95.31.43.9"],
|
||||
"items": {
|
||||
"ledhum":[6,-13],
|
||||
"reghum": [13, [
|
||||
[50, 10, 0, 60, 250, 200], [{"item": "relayhum"}, {"item":"ledhum"}]
|
||||
], 30, 12],
|
||||
|
||||
"relayhum": [16, [12, 1200], 255, 2]
|
||||
},
|
||||
"in":{
|
||||
"0":{"T":0,
|
||||
"click":{ "item":"reghum","icmd":"TOGGLE"},
|
||||
"dclick":{ "emit":"myhome/light-d2/light","ecmd":"TOGGLE"}
|
||||
},
|
||||
|
||||
"3":{"T":4,
|
||||
"temp":{"emit":"plugtemp"},
|
||||
"hum":{"item":"reghum/val","emit":"plughum"}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
"mqtt":["plug00","192.168.88.2"]
|
||||
}
|
||||
BIN
docs/html/mkspiffs_espressif32_arduino.exe
Normal file
BIN
docs/html/mkspiffs_espressif32_arduino.exe
Normal file
Binary file not shown.
BIN
docs/html/mkspiffs_espressif8266_arduino.exe
Normal file
BIN
docs/html/mkspiffs_espressif8266_arduino.exe
Normal file
Binary file not shown.
BIN
docs/html/search/firmware.bin
Normal file
BIN
docs/html/search/firmware.bin
Normal file
Binary file not shown.
3
docs/html/search/upload.bat
Normal file
3
docs/html/search/upload.bat
Normal file
@@ -0,0 +1,3 @@
|
||||
mode com3:1200,n,8,1
|
||||
pause
|
||||
..\tools\win\tool-bossac\bossac.exe -i --port=com3 -U false -e -w -v -b firmware.bin -R
|
||||
@@ -1,6 +1,8 @@
|
||||
import os
|
||||
Import("env")
|
||||
script = env.GetProjectOption("_upload_command")
|
||||
|
||||
script = env.GetProjectOption("_upload_command")
|
||||
spath = os.path.abspath(script)
|
||||
#env.Replace(
|
||||
# UPLOADER="executable or path to executable",
|
||||
# UPLOADCMD=script
|
||||
@@ -8,5 +10,4 @@ script = env.GetProjectOption("_upload_command")
|
||||
env.AddCustomTarget(
|
||||
"ota",
|
||||
"$BUILD_DIR/${PROGNAME}.bin",
|
||||
script
|
||||
)
|
||||
spath)
|
||||
|
||||
18
ldscripts/bootloader.ld
Normal file
18
ldscripts/bootloader.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Linker script for Generic STM32F103RE boards, using the generic bootloader (which takes the lower 8k of memory)
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
rom (rx) : ORIGIN = 0x08002000, LENGTH = 504K
|
||||
}
|
||||
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
220
ldscripts/common.inc
Normal file
220
ldscripts/common.inc
Normal file
@@ -0,0 +1,220 @@
|
||||
/*
|
||||
* Linker script for libmaple.
|
||||
*
|
||||
* Original author "lanchon" from ST forums, with modifications by LeafLabs.
|
||||
*/
|
||||
|
||||
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
|
||||
|
||||
/*
|
||||
* Configure other libraries we want in the link.
|
||||
*
|
||||
* libgcc, libc, and libm are common across supported toolchains.
|
||||
* However, some toolchains require additional archives which aren't
|
||||
* present everywhere (e.g. ARM's gcc-arm-embedded releases).
|
||||
*
|
||||
* To hack around this, we let the build system specify additional
|
||||
* archives by putting the right extra_libs.inc (in a directory under
|
||||
* toolchains/) in our search path.
|
||||
*/
|
||||
GROUP(libgcc.a libc.a libm.a)
|
||||
INCLUDE ldscripts/extra_libs.inc
|
||||
|
||||
/*
|
||||
* These force the linker to search for vector table symbols.
|
||||
*
|
||||
* These symbols vary by STM32 family (and also within families).
|
||||
* It's up to the build system to configure the link's search path
|
||||
* properly for the target MCU.
|
||||
*/
|
||||
INCLUDE ldscripts/vector_symbols.inc
|
||||
|
||||
/* STM32 vector table. */
|
||||
EXTERN(__stm32_vector_table)
|
||||
|
||||
/* C runtime initialization function. */
|
||||
EXTERN(start_c)
|
||||
|
||||
/* main entry point */
|
||||
EXTERN(main)
|
||||
|
||||
/* Initial stack pointer value. */
|
||||
EXTERN(__msp_init)
|
||||
PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram));
|
||||
|
||||
/* Reset vector and chip reset entry point */
|
||||
EXTERN(__start__)
|
||||
ENTRY(__start__)
|
||||
PROVIDE(__exc_reset = __start__);
|
||||
|
||||
/* Heap boundaries, for libmaple */
|
||||
EXTERN(_lm_heap_start);
|
||||
EXTERN(_lm_heap_end);
|
||||
|
||||
SECTIONS
|
||||
{
|
||||
.text :
|
||||
{
|
||||
__text_start__ = .;
|
||||
/*
|
||||
* STM32 vector table. Leave this here. Yes, really.
|
||||
*/
|
||||
*(.stm32.interrupt_vector)
|
||||
|
||||
/*
|
||||
* Program code and vague linking
|
||||
*/
|
||||
*(.text .text.* .gnu.linkonce.t.*)
|
||||
*(.plt)
|
||||
*(.gnu.warning)
|
||||
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
|
||||
|
||||
*(.ARM.extab* .gnu.linkonce.armextab.*)
|
||||
*(.gcc_except_table)
|
||||
*(.eh_frame_hdr)
|
||||
*(.eh_frame)
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.init))
|
||||
|
||||
. = ALIGN(4);
|
||||
__preinit_array_start = .;
|
||||
KEEP (*(.preinit_array))
|
||||
__preinit_array_end = .;
|
||||
|
||||
. = ALIGN(4);
|
||||
__init_array_start = .;
|
||||
KEEP (*(SORT(.init_array.*)))
|
||||
KEEP (*(.init_array))
|
||||
__init_array_end = .;
|
||||
|
||||
. = ALIGN(0x4);
|
||||
KEEP (*crtbegin.o(.ctors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
|
||||
KEEP (*(SORT(.ctors.*)))
|
||||
KEEP (*crtend.o(.ctors))
|
||||
|
||||
. = ALIGN(4);
|
||||
KEEP(*(.fini))
|
||||
|
||||
. = ALIGN(4);
|
||||
__fini_array_start = .;
|
||||
KEEP (*(.fini_array))
|
||||
KEEP (*(SORT(.fini_array.*)))
|
||||
__fini_array_end = .;
|
||||
|
||||
KEEP (*crtbegin.o(.dtors))
|
||||
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
|
||||
KEEP (*(SORT(.dtors.*)))
|
||||
KEEP (*crtend.o(.dtors))
|
||||
} > REGION_TEXT
|
||||
|
||||
/*
|
||||
* End of text
|
||||
*/
|
||||
.text.align :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__text_end__ = .;
|
||||
} > REGION_TEXT
|
||||
|
||||
/*
|
||||
* .ARM.exidx exception unwinding; mandated by ARM's C++ ABI
|
||||
*/
|
||||
__exidx_start = .;
|
||||
.ARM.exidx :
|
||||
{
|
||||
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
|
||||
} > REGION_RODATA
|
||||
__exidx_end = .;
|
||||
|
||||
/*
|
||||
* .data
|
||||
*/
|
||||
.data :
|
||||
{
|
||||
__data_start__ = .;
|
||||
LONG(0)
|
||||
. = ALIGN(8);
|
||||
|
||||
*(.got.plt) *(.got)
|
||||
*(.data .data.* .gnu.linkonce.d.*)
|
||||
|
||||
. = ALIGN(8);
|
||||
__data_end__ = .;
|
||||
} > REGION_DATA AT> REGION_RODATA
|
||||
|
||||
/*
|
||||
* Read-only data
|
||||
*/
|
||||
.rodata :
|
||||
{
|
||||
*(.rodata .rodata.* .gnu.linkonce.r.*)
|
||||
/* .USER_FLASH: We allow users to allocate into Flash here */
|
||||
*(.USER_FLASH)
|
||||
/* ROM image configuration; for C startup */
|
||||
. = ALIGN(4);
|
||||
_lm_rom_img_cfgp = .;
|
||||
LONG(LOADADDR(.data));
|
||||
/*
|
||||
* Heap: Linker scripts may choose a custom heap by overriding
|
||||
* _lm_heap_start and _lm_heap_end. Otherwise, the heap is in
|
||||
* internal SRAM, beginning after .bss, and growing towards
|
||||
* the stack.
|
||||
*
|
||||
* I'm shoving these here naively; there's probably a cleaner way
|
||||
* to go about this. [mbolivar]
|
||||
*/
|
||||
_lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end;
|
||||
_lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init;
|
||||
} > REGION_RODATA
|
||||
|
||||
/*
|
||||
* .bss
|
||||
*/
|
||||
.bss :
|
||||
{
|
||||
. = ALIGN(8);
|
||||
__bss_start__ = .;
|
||||
*(.bss .bss.* .gnu.linkonce.b.*)
|
||||
*(COMMON)
|
||||
. = ALIGN (8);
|
||||
__bss_end__ = .;
|
||||
_end = __bss_end__;
|
||||
} > REGION_BSS
|
||||
|
||||
/*
|
||||
* Debugging sections
|
||||
*/
|
||||
.stab 0 (NOLOAD) : { *(.stab) }
|
||||
.stabstr 0 (NOLOAD) : { *(.stabstr) }
|
||||
/* DWARF debug sections.
|
||||
* Symbols in the DWARF debugging sections are relative to the beginning
|
||||
* of the section so we begin them at 0. */
|
||||
/* DWARF 1 */
|
||||
.debug 0 : { *(.debug) }
|
||||
.line 0 : { *(.line) }
|
||||
/* GNU DWARF 1 extensions */
|
||||
.debug_srcinfo 0 : { *(.debug_srcinfo) }
|
||||
.debug_sfnames 0 : { *(.debug_sfnames) }
|
||||
/* DWARF 1.1 and DWARF 2 */
|
||||
.debug_aranges 0 : { *(.debug_aranges) }
|
||||
.debug_pubnames 0 : { *(.debug_pubnames) }
|
||||
/* DWARF 2 */
|
||||
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
|
||||
.debug_abbrev 0 : { *(.debug_abbrev) }
|
||||
.debug_line 0 : { *(.debug_line) }
|
||||
.debug_frame 0 : { *(.debug_frame) }
|
||||
.debug_str 0 : { *(.debug_str) }
|
||||
.debug_loc 0 : { *(.debug_loc) }
|
||||
.debug_macinfo 0 : { *(.debug_macinfo) }
|
||||
/* SGI/MIPS DWARF 2 extensions */
|
||||
.debug_weaknames 0 : { *(.debug_weaknames) }
|
||||
.debug_funcnames 0 : { *(.debug_funcnames) }
|
||||
.debug_typenames 0 : { *(.debug_typenames) }
|
||||
.debug_varnames 0 : { *(.debug_varnames) }
|
||||
|
||||
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
|
||||
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
|
||||
/DISCARD/ : { *(.note.GNU-stack) }
|
||||
}
|
||||
7
ldscripts/extra_libs.inc
Normal file
7
ldscripts/extra_libs.inc
Normal file
@@ -0,0 +1,7 @@
|
||||
/*
|
||||
* Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi-
|
||||
* releases (https://launchpad.net/gcc-arm-embedded/).
|
||||
*/
|
||||
|
||||
/* This is for the provided newlib. */
|
||||
GROUP(libnosys.a)
|
||||
26
ldscripts/flash.ld
Normal file
26
ldscripts/flash.ld
Normal file
@@ -0,0 +1,26 @@
|
||||
/*
|
||||
* libmaple linker script for "Flash" builds.
|
||||
*
|
||||
* A Flash build puts .text (and .rodata) in Flash, and
|
||||
* .data/.bss/heap (of course) in SRAM, but offsets the sections by
|
||||
* enough space to store the Maple bootloader, which lives in low
|
||||
* Flash and uses low memory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This pulls in the appropriate MEMORY declaration from the right
|
||||
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||
* right include directory flags to make this happen). Boards can also
|
||||
* use this file to use any of libmaple's memory-related hooks (like
|
||||
* where the heap should live).
|
||||
*/
|
||||
INCLUDE mem-flash.inc
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
31
ldscripts/jtag.ld
Normal file
31
ldscripts/jtag.ld
Normal file
@@ -0,0 +1,31 @@
|
||||
/*
|
||||
* libmaple linker script for "JTAG" builds.
|
||||
*
|
||||
* A "JTAG" build puts .text (and .rodata) in Flash, and
|
||||
* .data/.bss/heap (of course) in SRAM, but links starting at the
|
||||
* Flash and SRAM starting addresses (0x08000000 and 0x20000000
|
||||
* respectively). This will wipe out a Maple bootloader if there's one
|
||||
* on the board, so only use this if you know what you're doing.
|
||||
*
|
||||
* Of course, a "JTAG" build is perfectly usable for upload over SWD,
|
||||
* the system memory bootloader, etc. The name is just a historical
|
||||
* artifact.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This pulls in the appropriate MEMORY declaration from the right
|
||||
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||
* right include directory flags to make this happen). Boards can also
|
||||
* use this file to use any of libmaple's memory-related hooks (like
|
||||
* where the heap should live).
|
||||
*/
|
||||
INCLUDE mem-jtag.inc
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
46
ldscripts/ldscript.ld
Normal file
46
ldscripts/ldscript.ld
Normal file
@@ -0,0 +1,46 @@
|
||||
/*
|
||||
!!!!!!!!!!!! STM32Duino default linker script
|
||||
|
||||
* This script extends the default linker script to add a .noinit
|
||||
* section. This section is just mapped to RAM, but it is emitted
|
||||
* separately from the .data and .bss sections (both of which are
|
||||
* initialized by startup code), so any variables in this section are
|
||||
* untouched on startup (so they survive across resets).
|
||||
*
|
||||
* This script is intended to supplied to the linker's -T / --script
|
||||
* option as the primary linker script. When the linker sees an INSERT
|
||||
* command, this will cause it to *also* read the default linker script
|
||||
* (after reading this script) and then executing the INSERT commands
|
||||
* after both scripts have been read.
|
||||
*
|
||||
* Note that parsing of linker scripts is a bit peculiar, e.g. INSERT
|
||||
* does not textually inserts, it inserts any generated output sections.
|
||||
* Also, because this script is read *first*, we cannot refer to things
|
||||
* in the default script. In particular, it would make sense to add >
|
||||
* RAM to the output section below to ensure that the section is mapped
|
||||
* into RAM, but the RAM region is not defined yet (I think it would
|
||||
* work though, but produces warnings). Instead, we just rely on the
|
||||
* defaults used by the linker: If no region is defined for an output
|
||||
* section, it will just map to first address after the previous section
|
||||
* (.bss in this case, which is fine).
|
||||
*/
|
||||
SECTIONS
|
||||
{
|
||||
/* Define a noinit output section and mark it as NOLOAD to prevent
|
||||
* putting its contents into the resulting .bin file (which is the
|
||||
* default). */
|
||||
.noinit (NOLOAD) :
|
||||
{
|
||||
/* Ensure output is aligned */
|
||||
. = ALIGN(4);
|
||||
/* Define a global _snoinit (and _enoinit below) symbol just in case
|
||||
* code wants to iterate over all noinit variables for some reason */
|
||||
_snoinit = .;
|
||||
/* Actually import the .noinit and .noinit* import sections */
|
||||
*(.noinit)
|
||||
*(.noinit*)
|
||||
. = ALIGN(4);
|
||||
_enoinit = .;
|
||||
}
|
||||
}
|
||||
INSERT AFTER .bss;
|
||||
5
ldscripts/mem-flash.inc
Normal file
5
ldscripts/mem-flash.inc
Normal file
@@ -0,0 +1,5 @@
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
|
||||
rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K
|
||||
}
|
||||
5
ldscripts/mem-jtag.inc
Normal file
5
ldscripts/mem-jtag.inc
Normal file
@@ -0,0 +1,5 @@
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||
}
|
||||
5
ldscripts/mem-ram.inc
Normal file
5
ldscripts/mem-ram.inc
Normal file
@@ -0,0 +1,5 @@
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
|
||||
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
|
||||
}
|
||||
25
ldscripts/ram.ld
Normal file
25
ldscripts/ram.ld
Normal file
@@ -0,0 +1,25 @@
|
||||
/*
|
||||
* libmaple linker script for RAM builds.
|
||||
*
|
||||
* A Flash build puts .text, .rodata, and .data/.bss/heap (of course)
|
||||
* in SRAM, but offsets the sections by enough space to store the
|
||||
* Maple bootloader, which uses low memory.
|
||||
*/
|
||||
|
||||
/*
|
||||
* This pulls in the appropriate MEMORY declaration from the right
|
||||
* subdirectory of stm32/mem/ (the environment must call ld with the
|
||||
* right include directory flags to make this happen). Boards can also
|
||||
* use this file to use any of libmaple's memory-related hooks (like
|
||||
* where the heap should live).
|
||||
*/
|
||||
INCLUDE mem-ram.inc
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", ram);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", ram);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
18
ldscripts/stm32f103rb.ld
Normal file
18
ldscripts/stm32f103rb.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Linker script for Generic STM32F103RB boards.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
|
||||
}
|
||||
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
17
ldscripts/stm32f103rb_bootloader.ld
Normal file
17
ldscripts/stm32f103rb_bootloader.ld
Normal file
@@ -0,0 +1,17 @@
|
||||
/*
|
||||
* Linker script for Generic STM32F103RB boards, using the generic bootloader (which takes the lower 8k of memory)
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
|
||||
rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K
|
||||
}
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
18
ldscripts/stm32f103rc.ld
Normal file
18
ldscripts/stm32f103rc.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Linker script for Generic STM32F103RC boards.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
|
||||
}
|
||||
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
18
ldscripts/stm32f103rc_bootloader.ld
Normal file
18
ldscripts/stm32f103rc_bootloader.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Linker script for Generic STM32F103RC boards, using the generic bootloader (which takes the lower 8k of memory)
|
||||
*/
|
||||
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
|
||||
rom (rx) : ORIGIN = 0x08002000, LENGTH = 248K
|
||||
}
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
18
ldscripts/stm32f103re.ld
Normal file
18
ldscripts/stm32f103re.ld
Normal file
@@ -0,0 +1,18 @@
|
||||
/*
|
||||
* Linker script for Generic STM32F103RE boards.
|
||||
*/
|
||||
MEMORY
|
||||
{
|
||||
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
|
||||
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
|
||||
}
|
||||
|
||||
|
||||
/* Provide memory region aliases for common.inc */
|
||||
REGION_ALIAS("REGION_TEXT", rom);
|
||||
REGION_ALIAS("REGION_DATA", ram);
|
||||
REGION_ALIAS("REGION_BSS", ram);
|
||||
REGION_ALIAS("REGION_RODATA", rom);
|
||||
|
||||
/* Let common.inc handle the real work. */
|
||||
INCLUDE ldscripts/common.inc
|
||||
78
ldscripts/vector_symbols.inc
Normal file
78
ldscripts/vector_symbols.inc
Normal file
@@ -0,0 +1,78 @@
|
||||
EXTERN(__msp_init)
|
||||
EXTERN(__exc_reset)
|
||||
EXTERN(__exc_nmi)
|
||||
EXTERN(__exc_hardfault)
|
||||
EXTERN(__exc_memmanage)
|
||||
EXTERN(__exc_busfault)
|
||||
EXTERN(__exc_usagefault)
|
||||
EXTERN(__stm32reservedexception7)
|
||||
EXTERN(__stm32reservedexception8)
|
||||
EXTERN(__stm32reservedexception9)
|
||||
EXTERN(__stm32reservedexception10)
|
||||
EXTERN(__exc_svc)
|
||||
EXTERN(__exc_debug_monitor)
|
||||
EXTERN(__stm32reservedexception13)
|
||||
EXTERN(__exc_pendsv)
|
||||
EXTERN(__exc_systick)
|
||||
|
||||
EXTERN(__irq_wwdg)
|
||||
EXTERN(__irq_pvd)
|
||||
EXTERN(__irq_tamper)
|
||||
EXTERN(__irq_rtc)
|
||||
EXTERN(__irq_flash)
|
||||
EXTERN(__irq_rcc)
|
||||
EXTERN(__irq_exti0)
|
||||
EXTERN(__irq_exti1)
|
||||
EXTERN(__irq_exti2)
|
||||
EXTERN(__irq_exti3)
|
||||
EXTERN(__irq_exti4)
|
||||
EXTERN(__irq_dma1_channel1)
|
||||
EXTERN(__irq_dma1_channel2)
|
||||
EXTERN(__irq_dma1_channel3)
|
||||
EXTERN(__irq_dma1_channel4)
|
||||
EXTERN(__irq_dma1_channel5)
|
||||
EXTERN(__irq_dma1_channel6)
|
||||
EXTERN(__irq_dma1_channel7)
|
||||
EXTERN(__irq_adc)
|
||||
EXTERN(__irq_usb_hp_can_tx)
|
||||
EXTERN(__irq_usb_lp_can_rx0)
|
||||
EXTERN(__irq_can_rx1)
|
||||
EXTERN(__irq_can_sce)
|
||||
EXTERN(__irq_exti9_5)
|
||||
EXTERN(__irq_tim1_brk)
|
||||
EXTERN(__irq_tim1_up)
|
||||
EXTERN(__irq_tim1_trg_com)
|
||||
EXTERN(__irq_tim1_cc)
|
||||
EXTERN(__irq_tim2)
|
||||
EXTERN(__irq_tim3)
|
||||
EXTERN(__irq_tim4)
|
||||
EXTERN(__irq_i2c1_ev)
|
||||
EXTERN(__irq_i2c1_er)
|
||||
EXTERN(__irq_i2c2_ev)
|
||||
EXTERN(__irq_i2c2_er)
|
||||
EXTERN(__irq_spi1)
|
||||
EXTERN(__irq_spi2)
|
||||
EXTERN(__irq_usart1)
|
||||
EXTERN(__irq_usart2)
|
||||
EXTERN(__irq_usart3)
|
||||
EXTERN(__irq_exti15_10)
|
||||
EXTERN(__irq_rtcalarm)
|
||||
EXTERN(__irq_usbwakeup)
|
||||
|
||||
EXTERN(__irq_tim8_brk)
|
||||
EXTERN(__irq_tim8_up)
|
||||
EXTERN(__irq_tim8_trg_com)
|
||||
EXTERN(__irq_tim8_cc)
|
||||
EXTERN(__irq_adc3)
|
||||
EXTERN(__irq_fsmc)
|
||||
EXTERN(__irq_sdio)
|
||||
EXTERN(__irq_tim5)
|
||||
EXTERN(__irq_spi3)
|
||||
EXTERN(__irq_uart4)
|
||||
EXTERN(__irq_uart5)
|
||||
EXTERN(__irq_tim6)
|
||||
EXTERN(__irq_tim7)
|
||||
EXTERN(__irq_dma2_channel1)
|
||||
EXTERN(__irq_dma2_channel2)
|
||||
EXTERN(__irq_dma2_channel3)
|
||||
EXTERN(__irq_dma2_channel4_5)
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
#define CST_UNKNOWN 0
|
||||
#define CST_INITIALIZED 1
|
||||
#define CST_FAILED 2
|
||||
#define CST_FAILED -1
|
||||
|
||||
class abstractCh {
|
||||
public:
|
||||
|
||||
@@ -12,6 +12,8 @@ int abstractOut::isActive()
|
||||
case CMD_VOID:
|
||||
return 0;
|
||||
break;
|
||||
case CMD_ON: //trying (PWM ON set=0 issue)
|
||||
return 1;
|
||||
default:
|
||||
st.loadItem(item);
|
||||
return st.getPercents255();
|
||||
|
||||
@@ -10,6 +10,7 @@ public:
|
||||
abstractOut(Item * _item):abstractCh(){item=_item;};
|
||||
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) =0;
|
||||
virtual int isActive();
|
||||
virtual bool isAllowed(itemCmd cmd){return true;};
|
||||
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
||||
virtual int getChanType(){return 0;}
|
||||
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
||||
|
||||
@@ -71,16 +71,16 @@ case S_CMD:
|
||||
{
|
||||
cmd.setPercents(INIT_VOLUME);
|
||||
cmd.saveItem(item);
|
||||
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
};
|
||||
PixelCtrl(cmd,subItem, true);
|
||||
// item->SendStatus(SEND_COMMAND | SEND_PARAMETERS );
|
||||
// item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS );
|
||||
return 1;
|
||||
|
||||
case CMD_OFF:
|
||||
cmd.param.asInt32=0;
|
||||
PixelCtrl(cmd, subItem, true);
|
||||
// item->SendStatus(SEND_COMMAND);
|
||||
// item->SendStatus(FLAG_COMMAND);
|
||||
return 1;
|
||||
|
||||
default:
|
||||
|
||||
@@ -293,6 +293,19 @@ bool systemConfig::setConfigFlags(systemConfigFlags flags)
|
||||
return setConfigFlags(flags);
|
||||
}
|
||||
|
||||
bool systemConfig::getDHCPfallback()
|
||||
{
|
||||
systemConfigFlags flags = getConfigFlags();
|
||||
return flags.dhcpFallback;
|
||||
}
|
||||
|
||||
bool systemConfig::setDHCPfallback(bool flag)
|
||||
{
|
||||
systemConfigFlags flags = getConfigFlags();
|
||||
flags.dhcpFallback=flag;
|
||||
return setConfigFlags(flags);
|
||||
}
|
||||
|
||||
bool systemConfig::getLoadHTTPConfig()
|
||||
{
|
||||
systemConfigFlags flags = getConfigFlags();
|
||||
|
||||
@@ -61,6 +61,9 @@ class systemConfig {
|
||||
bool saveETAG();
|
||||
bool loadETAG();
|
||||
|
||||
bool getDHCPfallback();
|
||||
bool setDHCPfallback(bool flag);
|
||||
|
||||
systemConfigFlags getConfigFlags();
|
||||
bool setConfigFlags(systemConfigFlags flags);
|
||||
|
||||
|
||||
@@ -31,10 +31,13 @@ extern DueFlashStorage EEPROM;
|
||||
extern NRFFlashStorage EEPROM;
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_STM32
|
||||
#include <NRFFlashStorage.h> //STUB
|
||||
extern NRFFlashStorage EEPROM;
|
||||
#endif
|
||||
//#ifdef ARDUINO_ARCH_STM32
|
||||
//#include <NRFFlashStorage.h> //STUB
|
||||
//extern NRFFlashStorage EEPROM;
|
||||
|
||||
// static char samBuffer[64];
|
||||
// short samBufferPos = 0;
|
||||
//#endif
|
||||
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
@@ -48,7 +51,10 @@ NRFFlashStorage EEPROM;
|
||||
#endif
|
||||
|
||||
#ifdef ARDUINO_ARCH_STM32
|
||||
NRFFlashStorage EEPROM;
|
||||
//NRFFlashStorage EEPROM;
|
||||
#include <EEPROM.h>
|
||||
#define DATA_LENGTH E2END
|
||||
//FLASH_PAGE_SIZE = 0x400
|
||||
#endif
|
||||
|
||||
#if defined(FS_STORAGE)
|
||||
@@ -116,7 +122,7 @@ NRFFlashStorage EEPROM;
|
||||
debugSerial<<(F(" Res:"))<<res<<endl;
|
||||
return res;
|
||||
};
|
||||
void flashStream::close() {fs.close(); debugSerial<<filename<<" Closed\n";};
|
||||
void flashStream::close() {fs.flush();fs.close(); debugSerial<<filename<<" Closed\n";};
|
||||
void flashStream::flush() {fs.flush(); debugSerial<<filename<<" Flushed\n";};
|
||||
size_t flashStream::write(uint8_t ch)
|
||||
{
|
||||
@@ -131,11 +137,15 @@ NRFFlashStorage EEPROM;
|
||||
int flashStream::open(short fileNum, char mode)
|
||||
{
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#if defined(__SAM3X8E__) //|| defined (ARDUINO_ARCH_STM32)
|
||||
if (samBufferPos) flush();
|
||||
samBufferPos = 0;
|
||||
#endif
|
||||
|
||||
#if defined (ARDUINO_ARCH_STM32)
|
||||
eeprom_buffer_fill();
|
||||
#endif
|
||||
|
||||
switch (fileNum) {
|
||||
case FN_CONFIG_JSON:
|
||||
pos = 0;
|
||||
@@ -182,10 +192,14 @@ NRFFlashStorage EEPROM;
|
||||
unsigned int flashStream::seek(unsigned int _pos)
|
||||
{
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
#if defined(__SAM3X8E__) //|| defined (ARDUINO_ARCH_STM32)
|
||||
if (samBufferPos) flush();
|
||||
#endif
|
||||
|
||||
#if defined (ARDUINO_ARCH_STM32)
|
||||
//eeprom_buffer_flush();
|
||||
#endif
|
||||
|
||||
pos=min(_pos, streamSize);
|
||||
//debugSerial<<F("Seek:")<<pos<<endl;
|
||||
return pos;
|
||||
@@ -217,10 +231,12 @@ NRFFlashStorage EEPROM;
|
||||
if (EEPROM.commitReset())
|
||||
infoSerial<<"Commited to FLASH"<<endl;
|
||||
else errorSerial<<"Commit error. len:"<<EEPROM.length()<<endl;
|
||||
#elif defined(__SAM3X8E__)
|
||||
#elif defined(__SAM3X8E__) //|| defined (ARDUINO_ARCH_STM32)
|
||||
if (samBufferPos)
|
||||
EEPROM.write(startPos+pos-samBufferPos,(byte*)samBuffer,samBufferPos);
|
||||
samBufferPos=0;
|
||||
#elif defined (ARDUINO_ARCH_STM32)
|
||||
eeprom_buffer_flush();
|
||||
#endif
|
||||
};
|
||||
|
||||
@@ -230,12 +246,13 @@ NRFFlashStorage EEPROM;
|
||||
#if defined(__AVR__)
|
||||
EEPROM.update(startPos+pos++,(char)ch);
|
||||
return 1;
|
||||
#elif defined(__SAM3X8E__)
|
||||
#elif defined(__SAM3X8E__)// || defined (ARDUINO_ARCH_STM32)
|
||||
|
||||
if (samBufferPos==sizeof(samBuffer))
|
||||
{
|
||||
samBufferPos = 0;
|
||||
EEPROM.write(startPos+pos-sizeof(samBuffer),(byte*)samBuffer,sizeof(samBuffer));
|
||||
|
||||
}
|
||||
|
||||
samBuffer[samBufferPos++]=ch;
|
||||
@@ -243,12 +260,23 @@ NRFFlashStorage EEPROM;
|
||||
return 1;
|
||||
// return EEPROM.write(startPos+pos++,(char)ch);
|
||||
|
||||
#elif defined (ARDUINO_ARCH_STM32)
|
||||
if (startPos+pos<=DATA_LENGTH)
|
||||
{
|
||||
eeprom_buffered_write_byte(startPos+pos++,(char)ch);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{
|
||||
errorSerial<<F("Flash sector exceeded")<<endl;
|
||||
return 0;
|
||||
}
|
||||
#else
|
||||
EEPROM.write(startPos+pos++,(char)ch);
|
||||
return 1;
|
||||
#endif
|
||||
};
|
||||
|
||||
/*
|
||||
#if defined(__SAM3X8E__)
|
||||
size_t flashStream::write(const uint8_t *buffer, size_t size)
|
||||
{
|
||||
@@ -258,7 +286,7 @@ NRFFlashStorage EEPROM;
|
||||
};
|
||||
|
||||
#endif
|
||||
|
||||
*/
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
void flashStream::putEOF()
|
||||
{
|
||||
@@ -269,7 +297,11 @@ NRFFlashStorage EEPROM;
|
||||
|
||||
void flashStream::close()
|
||||
{
|
||||
if (openmode == 'w') putEOF();
|
||||
if (openmode == 'w')
|
||||
{
|
||||
putEOF();
|
||||
debugSerial<<F("EOF")<<endl;
|
||||
}
|
||||
#if defined(__SAM3X8E__)
|
||||
if (samBufferPos) flush();
|
||||
#endif
|
||||
|
||||
@@ -67,11 +67,11 @@ public:
|
||||
virtual void flush();
|
||||
virtual size_t write(uint8_t ch) ;
|
||||
|
||||
#if defined(__SAM3X8E__)
|
||||
virtual size_t write(const uint8_t *buffer, size_t size) override;
|
||||
#else
|
||||
//#if defined(__SAM3X8E__)
|
||||
//virtual size_t write(const uint8_t *buffer, size_t size) override;
|
||||
//#else
|
||||
using Print::write;//(const uint8_t *buffer, size_t size);
|
||||
#endif
|
||||
//#endif
|
||||
|
||||
#if defined(ESP8266) || defined(ESP32)
|
||||
virtual void putEOF() override ;
|
||||
|
||||
@@ -464,6 +464,8 @@ void Input::dht22Poll() {
|
||||
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
|
||||
DHTesp dhtSensor;
|
||||
dhtSensor.setup(pin, DHTesp::DHT22);
|
||||
//pinMode(pin, INPUT_PULLUP);
|
||||
//digitalWrite(pin, LOW); // Switch bus to receive data
|
||||
TempAndHumidity dhtSensorData = dhtSensor.getTempAndHumidity();
|
||||
float temp = roundf(dhtSensorData.temperature * 10) / 10;
|
||||
float humidity = roundf(dhtSensorData.humidity);
|
||||
@@ -479,8 +481,8 @@ debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") <<
|
||||
// New tyle unified activities
|
||||
aJsonObject *actT = aJson.getObjectItem(inputObj, "temp");
|
||||
aJsonObject *actH = aJson.getObjectItem(inputObj, "hum");
|
||||
executeCommand(actT,-1,itemCmd(temp));
|
||||
executeCommand(actH,-1,itemCmd(humidity));
|
||||
if (!isnan(temp)) executeCommand(actT,-1,itemCmd(temp));
|
||||
if (!isnan(humidity)) executeCommand(actH,-1,itemCmd(humidity));
|
||||
|
||||
//Legacy action conf - TODO - remove in further releases
|
||||
aJsonObject *emit = aJson.getObjectItem(inputObj, "emit");
|
||||
@@ -1021,7 +1023,7 @@ void Input::onAnalogChanged(itemCmd newValue) {
|
||||
strncpy(addrstr,emit->valuestring,sizeof(addrstr));
|
||||
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
|
||||
char strVal[16];
|
||||
newValue.toString(strVal,sizeof(strVal),SEND_PARAMETERS);
|
||||
newValue.toString(strVal,sizeof(strVal),FLAG_PARAMETERS);
|
||||
|
||||
if (mqttClient.connected() && !ethernetIdleCount)
|
||||
mqttClient.publish(addrstr, strVal, true);
|
||||
|
||||
@@ -541,9 +541,9 @@ void setupIpmodbus(){
|
||||
// Calculate Modbus RTU character timeout and frame delay
|
||||
byte bits = // number of bits per character (11 in default Modbus RTU settings)
|
||||
1 + // start bit
|
||||
(((MODBUS_DIMMER_PARAM & 0x06) >> 1) + 5) + // data bits
|
||||
(((MODBUS_DIMMER_PARAM & 0x08) >> 3) + 1); // stop bits
|
||||
if (((MODBUS_DIMMER_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present)
|
||||
(((MODBUS_SERIAL_PARAM & 0x06) >> 1) + 5) + // data bits
|
||||
(((MODBUS_SERIAL_PARAM & 0x08) >> 3) + 1); // stop bits
|
||||
if (((MODBUS_SERIAL_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present)
|
||||
//bits = 11;
|
||||
|
||||
int T = ((unsigned long)bits * 1000000UL) / MODBUS_SERIAL_BAUD; // time to send 1 character over serial in microseconds
|
||||
|
||||
File diff suppressed because it is too large
Load Diff
@@ -31,11 +31,13 @@ e-mail anklimov@gmail.com
|
||||
#define S_RGB 6
|
||||
#define S_FAN 7
|
||||
#define S_MODE 8
|
||||
#define S_HUE 9
|
||||
#define S_SAT 10
|
||||
#define S_TEMP 11
|
||||
#define S_RAW 12
|
||||
#define S_ADDITIONAL 12
|
||||
#define S_CTRL 9
|
||||
#define S_HUE 10
|
||||
#define S_SAT 11
|
||||
#define S_TEMP 12
|
||||
#define S_RAW 13
|
||||
|
||||
#define S_ADDITIONAL 13
|
||||
|
||||
#define CH_DIMMER 0 //DMX 1-4 ch
|
||||
#define CH_RGBW 1 //DMX 4 ch
|
||||
@@ -59,6 +61,7 @@ e-mail anklimov@gmail.com
|
||||
#define CH_ELEVATOR 19
|
||||
#define CH_COUNTER 20
|
||||
#define CH_HUMIDIFIER 21
|
||||
#define CH_MERCURY 22
|
||||
|
||||
//#define CHANNEL_TYPES 13
|
||||
|
||||
@@ -131,9 +134,9 @@ class Item
|
||||
chPersistent * getPersistent();
|
||||
chPersistent * setPersistent(chPersistent * par);
|
||||
void setCmd(uint8_t cmdValue);
|
||||
short getFlag (short flag=FLAG_MASK);
|
||||
void setFlag (short flag);
|
||||
void clearFlag (short flag);
|
||||
uint32_t getFlag (uint32_t flag=FLAG_MASK);
|
||||
void setFlag (uint32_t flag);
|
||||
void clearFlag (uint32_t flag);
|
||||
void setVal(long int par);
|
||||
void setFloatVal(float par);
|
||||
void setSubtype(uint8_t par);
|
||||
@@ -145,6 +148,9 @@ class Item
|
||||
inline int On (){return Ctrl(itemCmd(ST_VOID,CMD_ON));};
|
||||
inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
|
||||
inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
|
||||
int scheduleCommand(itemCmd cmd);
|
||||
int scheduleOppositeCommand(itemCmd cmd);
|
||||
int isScheduled();
|
||||
|
||||
protected:
|
||||
long int limitSetValue();
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
#include "Streaming.h"
|
||||
#include "item.h"
|
||||
#include "bright.h"
|
||||
#include <utility/stringbuffer.h>>
|
||||
|
||||
#ifndef HSV_DISABLE
|
||||
#ifdef ADAFRUIT_LED
|
||||
@@ -108,6 +109,7 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
|
||||
case CH_PWM:
|
||||
case CH_VC:
|
||||
case CH_MODBUS:
|
||||
//case CH_RELAY:
|
||||
//case CH_GROUP:
|
||||
return ST_PERCENTS255;
|
||||
break;
|
||||
@@ -1047,18 +1049,22 @@ bool itemCmd::loadItem(Item * item, uint16_t optionsFlag)
|
||||
if (item && item->isValid())
|
||||
{
|
||||
short subtype =item->getSubtype();
|
||||
if (optionsFlag & SEND_COMMAND) cmd.cmdCode = item->getCmd();
|
||||
if (optionsFlag & FLAG_COMMAND) cmd.cmdCode = item->getCmd();
|
||||
|
||||
//if (optionsFlag & FLAG_FLAGS)
|
||||
// if (item->getFlag(FLAG_DISABLED))
|
||||
// cmd.cmdCode = CMD_DISABLE;
|
||||
|
||||
if (subtype)
|
||||
{
|
||||
cmd.itemArgType= subtype;
|
||||
if (optionsFlag & SEND_PARAMETERS) param.asInt32 = item->itemVal->valueint;
|
||||
if (optionsFlag & FLAG_PARAMETERS) param.asInt32 = item->itemVal->valueint;
|
||||
//debugSerial<<F("Loaded :");
|
||||
//debugOut();
|
||||
return true;
|
||||
}
|
||||
|
||||
if (optionsFlag & SEND_PARAMETERS)
|
||||
if (optionsFlag & FLAG_PARAMETERS)
|
||||
switch (item->itemVal->type)
|
||||
{
|
||||
case aJson_Int:
|
||||
@@ -1091,7 +1097,7 @@ bool itemCmd::loadItemDef(Item * item, uint16_t optionsFlag)
|
||||
setDefault();
|
||||
saveItem(item);
|
||||
debugOut();
|
||||
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
@@ -1101,8 +1107,38 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
|
||||
{
|
||||
if (item && item->isValid())
|
||||
{
|
||||
if (optionsFlag & SEND_COMMAND) item->setCmd(cmd.cmdCode);
|
||||
if (optionsFlag & SEND_PARAMETERS)
|
||||
|
||||
if (optionsFlag & FLAG_FLAGS)
|
||||
switch (cmd.cmdCode)
|
||||
{
|
||||
case CMD_DISABLE:
|
||||
item->setFlag(FLAG_DISABLED);
|
||||
break;
|
||||
|
||||
case CMD_ENABLE:
|
||||
item->clearFlag(FLAG_DISABLED);
|
||||
item->clearFlag(FLAG_FREEZED);
|
||||
break;
|
||||
case CMD_FREEZE:
|
||||
item->setFlag(FLAG_FREEZED);
|
||||
break;
|
||||
|
||||
case CMD_UNFREEZE:
|
||||
item->clearFlag(FLAG_FREEZED);
|
||||
break;
|
||||
}
|
||||
if (optionsFlag & FLAG_COMMAND)
|
||||
switch (cmd.cmdCode)
|
||||
{
|
||||
case CMD_DISABLE:
|
||||
case CMD_ENABLE:
|
||||
case CMD_FREEZE:
|
||||
case CMD_UNFREEZE:
|
||||
break;
|
||||
default:
|
||||
item->setCmd(cmd.cmdCode);
|
||||
}
|
||||
if (optionsFlag & FLAG_PARAMETERS)
|
||||
switch (cmd.itemArgType)
|
||||
{
|
||||
case ST_FLOAT:
|
||||
@@ -1135,7 +1171,7 @@ return false;
|
||||
int cmd = txt2cmd(verb->valuestring);
|
||||
if (cmd>0)
|
||||
{
|
||||
free(verb->valuestring);
|
||||
freeString(verb->valuestring);
|
||||
verb->valueint=cmd;
|
||||
verb->type=aJson_Int;
|
||||
return verb->valueint;
|
||||
@@ -1242,10 +1278,10 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
|
||||
case aJson_Array:
|
||||
{
|
||||
aJsonObject *i = cmdMapping->child;
|
||||
//if first array element is not array - this is default mapping value
|
||||
//if first array element is not array - this is default mapping value, no reverse mapping, skipping
|
||||
if (i && i->type==aJson_Int)
|
||||
{
|
||||
matchedCmd = i;
|
||||
//matchedCmd = i;
|
||||
i=i->next;
|
||||
}
|
||||
|
||||
@@ -1301,6 +1337,7 @@ if (valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMappi
|
||||
int diff = ((b-a)/(d-c))/2;
|
||||
return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255));
|
||||
}
|
||||
if (valMapping && valMapping->type == aJson_NULL) return itemCmd();
|
||||
return *this;
|
||||
}
|
||||
|
||||
@@ -1311,17 +1348,17 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
|
||||
if (!Buffer || !bufLen) return NULL;
|
||||
*Buffer=0;
|
||||
char * argPtr=Buffer;
|
||||
if (isCommand() && (sendFlags & SEND_COMMAND))
|
||||
if (isCommand() && (sendFlags & FLAG_COMMAND))
|
||||
{
|
||||
int len;
|
||||
strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen);
|
||||
if (isValue() && (sendFlags & SEND_PARAMETERS)) strncat(Buffer, " ", bufLen);
|
||||
if (isValue() && (sendFlags & FLAG_PARAMETERS)) strncat(Buffer, " ", bufLen);
|
||||
len=strlen(Buffer);
|
||||
argPtr+=len;
|
||||
bufLen-=len;
|
||||
bufLen--;
|
||||
}
|
||||
if (isValue() && (sendFlags & SEND_PARAMETERS))
|
||||
if (isValue() && (sendFlags & FLAG_PARAMETERS))
|
||||
{
|
||||
//strncat(Buffer, " ", bufLen);
|
||||
//bufLen--;
|
||||
|
||||
@@ -26,8 +26,10 @@ typedef char cmdstr[9];
|
||||
const cmdstr commands_P[] PROGMEM =
|
||||
{
|
||||
"","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE",
|
||||
"HEAT","COOL","AUTO","FAN_ONLY","DRY","STOP","HIGH","MEDIUM","LOW","ENABLE","DISABLE",
|
||||
"TRUE","FALSE","RGB","HSV"
|
||||
"ENABLE","DISABLE","UNFREEZE","FREEZE",
|
||||
"AUTO","FAN_ONLY",
|
||||
"HIGH","MEDIUM","LOW",
|
||||
"HEAT","COOL","DRY","STOP","RGB","HSV"
|
||||
};
|
||||
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
||||
|
||||
@@ -41,37 +43,50 @@ const cmdstr commands_P[] PROGMEM =
|
||||
#define CMD_XOFF 7 /// OFF only if was previously turned on by CMD_XON
|
||||
#define CMD_UP 8 /// increase
|
||||
#define CMD_DN 9 /// decrease
|
||||
#define CMD_HEAT 0xa /// Thermostat/AC set to HEATing mode
|
||||
#define CMD_COOL 0xb /// Thermostat/AC set to COOLing mode
|
||||
#define CMD_AUTO 0xc /// Thermostat/AC set to Auto mode
|
||||
#define CMD_FAN 0xd /// AC set to Fan-only mode
|
||||
#define CMD_DRY 0xe /// AC set to Dry mode
|
||||
#define CMD_STOP 0xf /// stop dimming (for further use)
|
||||
|
||||
#define CMD_ENABLE 0xa /// for PID regulator and XON/XOFF - chan limitation
|
||||
#define CMD_DISABLE 0xb /// for PID regulator
|
||||
#define CMD_UNFREEZE 0xc /// Aliase for ON
|
||||
#define CMD_FREEZE 0xd /// Aliase for OFF
|
||||
|
||||
#define CMD_AUTO 0xe /// Thermostat/AC set to Auto mode
|
||||
#define CMD_FAN 0xf /// AC set to Fan-only mode
|
||||
|
||||
#define CMD_HIGH 0x10 /// AC/Vent fan level HIGH
|
||||
#define CMD_MED 0x11 /// AC/Vent fan level MEDIUM
|
||||
#define CMD_LOW 0x12 /// AC/Vent fan level LOW
|
||||
#define CMD_ENABLE 0x13 /// for PID regulator
|
||||
#define CMD_DISABLE 0x14 /// for PID regulator
|
||||
#define CMD_TRUE 0x15 /// Aliase for ON
|
||||
#define CMD_FALSE 0x16 /// Aliase for OFF
|
||||
|
||||
#define CMD_HEAT 0x13 /// Thermostat/AC set to HEATing mode
|
||||
#define CMD_COOL 0x14 /// Thermostat/AC set to COOLing mode
|
||||
#define CMD_DRY 0x15 /// AC set to Dry mode
|
||||
#define CMD_STOP 0x16 /// stop dimming (for further use)
|
||||
|
||||
#define CMD_RGB 0x17
|
||||
#define CMD_HSV 0x18
|
||||
|
||||
#define CMD_MASK 0xff
|
||||
#define FLAG_MASK 0xff00
|
||||
#define CMD_MASK 0xffUL
|
||||
#define FLAG_MASK 0x00ffff00UL
|
||||
//#define STATE_MASK 0xff0000
|
||||
|
||||
#define CMD_VOID 0
|
||||
#define CMD_UNKNOWN -1
|
||||
#define CMD_JSON -2
|
||||
|
||||
#define SEND_IMMEDIATE 0x1
|
||||
#define SEND_COMMAND 0x100
|
||||
#define SEND_PARAMETERS 0x200
|
||||
#define SEND_RETRY 0x400
|
||||
#define SEND_DEFFERED 0x800
|
||||
#define SEND_DELAYED 0x1000
|
||||
#define ACTION_NEEDED 0x2000
|
||||
#define ACTION_IN_PROCESS 0x4000
|
||||
//FLAGS
|
||||
#define FLAG_SEND_IMMEDIATE 0x1UL
|
||||
#define FLAG_COMMAND 0x100UL
|
||||
#define FLAG_PARAMETERS 0x200UL
|
||||
#define FLAG_FLAGS 0x400UL
|
||||
#define FLAG_SEND_RETRY 0x800UL
|
||||
#define FLAG_SEND_DEFFERED 0x1000UL
|
||||
#define FLAG_SEND_DELAYED 0x2000UL
|
||||
#define FLAG_ACTION_NEEDED 0x4000UL
|
||||
#define FLAG_ACTION_IN_PROCESS 0x8000UL
|
||||
|
||||
#define FLAG_DISABLED 0x10000UL
|
||||
#define FLAG_FREEZED 0x20000UL
|
||||
#define FLAG_HALTED 0x40000UL
|
||||
#define FLAG_XON 0x80000UL
|
||||
|
||||
|
||||
|
||||
@@ -161,9 +176,9 @@ public:
|
||||
|
||||
itemCmd assignFrom(itemCmd from, short chanType=-1);
|
||||
|
||||
bool loadItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS);
|
||||
bool loadItemDef(Item * item, uint16_t optionsFlag=SEND_PARAMETERS );
|
||||
bool saveItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS);
|
||||
bool loadItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
|
||||
bool loadItemDef(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS );
|
||||
bool saveItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
|
||||
|
||||
itemCmd Int(int32_t i);
|
||||
itemCmd Int(uint32_t i);
|
||||
@@ -209,7 +224,7 @@ public:
|
||||
uint8_t getCmd();
|
||||
uint8_t getArgType();
|
||||
uint8_t getCmdParam();
|
||||
char * toString(char * Buffer, int bufLen, int sendFlags = SEND_COMMAND | SEND_PARAMETERS, bool scale100 = false);
|
||||
char * toString(char * Buffer, int bufLen, int sendFlags = FLAG_COMMAND | FLAG_PARAMETERS, bool scale100 = false);
|
||||
|
||||
bool isCommand();
|
||||
bool isChannelCommand();
|
||||
|
||||
@@ -39,13 +39,26 @@ e-mail anklimov@gmail.com
|
||||
Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_BSD);
|
||||
static char syslogDeviceHostname[16];
|
||||
|
||||
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog);
|
||||
Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED);
|
||||
Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog);
|
||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog);
|
||||
Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED);
|
||||
Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog);
|
||||
#else
|
||||
Streamlog debugSerial(NULL,LOG_DEBUG,&udpSyslog);
|
||||
Streamlog errorSerial(NULL,LOG_ERROR,&udpSyslog,ledRED);
|
||||
Streamlog infoSerial (NULL,LOG_INFO,&udpSyslog);
|
||||
#endif
|
||||
|
||||
#else
|
||||
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG);
|
||||
Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED);
|
||||
Streamlog infoSerial (&debugSerialPort,LOG_INFO);
|
||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG);
|
||||
Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED);
|
||||
Streamlog infoSerial (&debugSerialPort,LOG_INFO);
|
||||
#else
|
||||
Streamlog debugSerial(NULL,LOG_DEBUG);
|
||||
Streamlog errorSerial(NULL,LOG_ERROR, ledRED);
|
||||
Streamlog infoSerial (NULL,LOG_INFO);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
flashStream sysConfStream;
|
||||
@@ -126,6 +139,7 @@ bool owReady = false;
|
||||
bool configOk = false; // At least once connected to MQTT
|
||||
bool configLoaded = false;
|
||||
bool initializedListeners = false;
|
||||
uint8_t DHCP_failures = 0;
|
||||
volatile int8_t ethernetIdleCount =0;
|
||||
volatile int8_t configLocked = 0;
|
||||
|
||||
@@ -247,9 +261,9 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
|
||||
|
||||
ArduinoOTA.sendHttpResponse(client,301,false); // Send only HTTP header, no close socket
|
||||
client.println(
|
||||
#ifdef CORS
|
||||
#ifdef REDIRECTION_URL
|
||||
//Redirect to cloud PWA application
|
||||
String(F("Location: " CORS "/pwa"))
|
||||
String(F("Location: " REDIRECTION_URL))
|
||||
#else
|
||||
String(F("Location: /index.html"))
|
||||
#endif
|
||||
@@ -276,7 +290,7 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
|
||||
if (!item.isValid() || !item.Ctrl((char*) body.c_str())) return 400;
|
||||
|
||||
itemCmd ic;
|
||||
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS);
|
||||
ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
|
||||
char buf[32];
|
||||
response=ic.toString(buf, sizeof(buf));
|
||||
return 200 | HTTP_TEXT_PLAIN;
|
||||
@@ -292,7 +306,7 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
|
||||
{if (item.isActive()) item.setCmd(CMD_ON); else item.setCmd(CMD_OFF);}
|
||||
|
||||
itemCmd ic;
|
||||
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS);
|
||||
ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
|
||||
|
||||
char buf[32];
|
||||
response=ic.toString(buf, sizeof(buf));
|
||||
@@ -400,12 +414,11 @@ if (lanStatus == RETAINING_COLLECTING)
|
||||
{
|
||||
if (mqttClient.isRetained())
|
||||
{
|
||||
pfxlen=inTopic(topic,T_BCST);
|
||||
if (!pfxlen) pfxlen = inTopic(topic,T_DEV);
|
||||
if (!pfxlen) return; // Not command topic ever
|
||||
//itemName=topic+pfxlen;
|
||||
//pfxlen=inTopic(topic,T_BCST); //Dont delete bcast topics (just skip on restore retaining)
|
||||
//if (!pfxlen) pfxlen = inTopic(topic,T_DEV);
|
||||
pfxlen = inTopic(topic,T_DEV);
|
||||
if (!pfxlen) return; // Not command topic
|
||||
if (strrchr(topic,'$')) return;
|
||||
//if (itemName[0]=='$') return;// -6; //Skipping homie stuff
|
||||
debugSerial<<F("CleanUp retained topic ")<<topic<<endl;
|
||||
mqttClient.deleteTopic(topic);
|
||||
}
|
||||
@@ -585,6 +598,7 @@ lan_status lanLoop() {
|
||||
if (isTimeOver(WiFiAwaitingTime,millis(),WIFI_TIMEOUT))
|
||||
{
|
||||
errorSerial<<F("\nProblem with WiFi!");
|
||||
WiFi.reconnect();
|
||||
return lanStatus = DO_REINIT;
|
||||
}
|
||||
#else
|
||||
@@ -697,6 +711,19 @@ lan_status lanLoop() {
|
||||
if (mqttClient.connected()) mqttClient.disconnect();
|
||||
timerLanCheckTime = millis();// + 5000;
|
||||
lanStatus = RECONNECT;
|
||||
|
||||
/*
|
||||
#if defined(WIFI_ENABLE)
|
||||
if (WiFi.status() != WL_CONNECTED)
|
||||
{
|
||||
infoSerial<<"Reconnecting WiFi"<<endl;
|
||||
lanStatus = INITIAL_STATE;
|
||||
WiFi.disconnect();
|
||||
WiFi.reconnect();
|
||||
}
|
||||
|
||||
#endif
|
||||
*/
|
||||
break;
|
||||
|
||||
case RECONNECT:
|
||||
@@ -736,7 +763,8 @@ lan_status lanLoop() {
|
||||
wdt_dis();
|
||||
if (lanStatus >= HAVE_IP_ADDRESS)
|
||||
{
|
||||
int etherStatus = Ethernet.maintain();
|
||||
int etherStatus = 0;
|
||||
if (!DHCP_failures) etherStatus = Ethernet.maintain();
|
||||
|
||||
#ifndef Wiz5500
|
||||
#define NO_LINK 5
|
||||
@@ -924,6 +952,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
|
||||
|
||||
if (mqttClient.connected())
|
||||
{
|
||||
//mqttClient.setKeepAlive(10);
|
||||
lanStatus = RETAINING_COLLECTING;
|
||||
return;
|
||||
}
|
||||
@@ -1001,7 +1030,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
|
||||
|
||||
setTopic(buf,sizeof(buf),T_DEV);
|
||||
strncat(buf, "#", sizeof(buf));
|
||||
debugSerialPort.println(buf);
|
||||
debugSerial.println(buf);
|
||||
mqttClient.subscribe(buf);
|
||||
|
||||
//onMQTTConnect();
|
||||
@@ -1081,7 +1110,11 @@ if (WiFi.status() == WL_CONNECTED) {
|
||||
IPAddress ip, dns, gw, mask;
|
||||
int res = 1;
|
||||
infoSerial<<F("Starting lan")<<endl;
|
||||
if (sysConf.getIP(ip)) {
|
||||
bool loadAddressRes = sysConf.getIP(ip);
|
||||
if ( loadAddressRes &&
|
||||
(!sysConf.getDHCPfallback() || (DHCP_failures >= DHCP_ATTEMPTS_FALLBACK))
|
||||
)
|
||||
{
|
||||
infoSerial<<F("Loaded from flash IP:");
|
||||
printIPAddress(ip);
|
||||
if (sysConf.getDNS(dns)) {
|
||||
@@ -1115,6 +1148,7 @@ if (WiFi.status() == WL_CONNECTED) {
|
||||
|
||||
if (res == 0) {
|
||||
errorSerial<<F("Failed to configure Ethernet using DHCP. You can set ip manually!")<<F("'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n");
|
||||
DHCP_failures++;
|
||||
lanStatus = DO_REINIT;//-10;
|
||||
//timerLanCheckTime = millis();// + DHCP_RETRY_INTERVAL;
|
||||
#ifdef RESET_PIN
|
||||
@@ -1122,8 +1156,25 @@ if (WiFi.status() == WL_CONNECTED) {
|
||||
#endif
|
||||
} else {
|
||||
infoSerial<<F("Got IP address:");
|
||||
printIPAddress(Ethernet.localIP());
|
||||
ip=Ethernet.localIP();
|
||||
printIPAddress(ip);
|
||||
|
||||
infoSerial<<endl;
|
||||
|
||||
sysConf.setIP(ip);
|
||||
|
||||
dns=Ethernet.dnsServerIP();
|
||||
sysConf.setDNS(dns);
|
||||
|
||||
gw=Ethernet.gatewayIP();
|
||||
sysConf.setGW(gw);
|
||||
|
||||
mask=Ethernet.subnetMask();
|
||||
sysConf.setMask(mask);
|
||||
|
||||
sysConf.setDHCPfallback(true);
|
||||
|
||||
DHCP_failures = 0;
|
||||
lanStatus = HAVE_IP_ADDRESS;
|
||||
}
|
||||
}//DHCP
|
||||
@@ -1365,8 +1416,8 @@ setupSyslog();
|
||||
switch (it.itemType) {
|
||||
case CH_THERMO:
|
||||
if (cmd<1) it.setCmd(CMD_OFF);
|
||||
it.setFlag(SEND_COMMAND);
|
||||
if (it.itemVal) it.setFlag(SEND_PARAMETERS);
|
||||
it.setFlag(FLAG_COMMAND);
|
||||
if (it.itemVal) it.setFlag(FLAG_PARAMETERS);
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin, false); //Initially, all thermostates are LOW (OFF for electho heaters, open for water NO)
|
||||
debugSerial<<F("Thermo:")<<pin<<F("=LOW")<<F(";");
|
||||
@@ -1459,6 +1510,7 @@ int loadConfigFromEEPROM()
|
||||
#endif
|
||||
|
||||
if (sysConfStream.peek() == '{') {
|
||||
debugSerial<<F("Trying Load from EEPROM")<<endl;
|
||||
aJsonStream as = aJsonStream(&sysConfStream);
|
||||
cleanConf();
|
||||
root = aJson.parse(&as);
|
||||
@@ -1499,27 +1551,6 @@ if (arg_cnt>1)
|
||||
#else
|
||||
sysConfStream.open(FN_CONFIG_JSON,'w');
|
||||
#endif
|
||||
/*
|
||||
#if defined(__SAM3X8E__)
|
||||
long configBufSize = min(MAX_JSON_CONF_SIZE,freeRam()-1024);
|
||||
debugSerial<<"Allocate "<<configBufSize<<" bytes for buffer"<<endl;
|
||||
char* outBuf = (char*) malloc(configBufSize);
|
||||
if (!outBuf)
|
||||
{
|
||||
sysConfStream.close();
|
||||
errorSerial<<"Can't allocate RAM"<<endl;
|
||||
return 500;
|
||||
}
|
||||
infoSerial<<F("Saving config to EEPROM..")<<endl;
|
||||
aJsonStringStream stringStream(NULL, outBuf, configBufSize-2);
|
||||
aJson.print(root, &stringStream);
|
||||
int len = strlen(outBuf);
|
||||
outBuf[len++]= EOFchar;
|
||||
infoSerial<<len<< F(" bytes collected")<<endl;
|
||||
size_t res = sysConfStream.write((byte*) outBuf,len);
|
||||
free (outBuf);
|
||||
infoSerial<<res<< F(" bytes are saved to EEPROM")<<endl;
|
||||
#else */
|
||||
|
||||
aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream);
|
||||
infoSerial<<F("Saving config to EEPROM..");
|
||||
@@ -1602,6 +1633,7 @@ int cmdFunctionIp(int arg_cnt, char **args)
|
||||
printIPAddress(current_mask); */
|
||||
//}
|
||||
infoSerial<<F("Saved\n");
|
||||
sysConf.setDHCPfallback(false);
|
||||
return 200;
|
||||
}
|
||||
|
||||
@@ -1751,7 +1783,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
||||
// FILE is the return STREAM type of the HTTPClient
|
||||
configStream = hclient.getURI(URI,NULL,get_header);
|
||||
responseStatusCode = hclient.getLastReturnCode();
|
||||
//debugSerial<<F("http retcode ")<<responseStatusCode<<endl;delay(100);
|
||||
debugSerial<<F("http retcode ")<<responseStatusCode<<endl;delay(100);
|
||||
//wdt_en();
|
||||
|
||||
if (configStream != NULL) {
|
||||
@@ -1994,13 +2026,113 @@ int16_t attachTimer(double microseconds, timerCallback callback, const char* Tim
|
||||
}
|
||||
#endif
|
||||
|
||||
#if defined(WIFI_ENABLE)
|
||||
#if defined (ESP32)
|
||||
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
||||
{
|
||||
debugSerial.printf("[WiFi-event] event: %d\n", event);
|
||||
|
||||
switch (event) {
|
||||
case SYSTEM_EVENT_WIFI_READY:
|
||||
debugSerial.println("WiFi interface ready");
|
||||
break;
|
||||
case SYSTEM_EVENT_SCAN_DONE:
|
||||
debugSerial.println("Completed scan for access points");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_START:
|
||||
debugSerial.println("WiFi client started");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_STOP:
|
||||
debugSerial.println("WiFi client stopped");
|
||||
//changeState(MYSTATE_OFFLINE);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_CONNECTED:
|
||||
debugSerial.println("Connected to access point");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_DISCONNECTED:
|
||||
debugSerial.println("Disconnected from WiFi access point");
|
||||
WiFi.reconnect();
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
|
||||
debugSerial.println("Authentication mode of access point has changed");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_GOT_IP:
|
||||
debugSerial.print("Obtained IP address: ");
|
||||
//Serial.println(WiFi.localIP());
|
||||
//Serial.println("WiFi connected");
|
||||
//Serial.print("IP address: ");
|
||||
debugSerial.println(IPAddress(info.got_ip.ip_info.ip.addr));
|
||||
|
||||
//changeState(MYSTATE_ONLINE);
|
||||
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_LOST_IP:
|
||||
debugSerial.println("Lost IP address and IP address is reset to 0");
|
||||
//changeState(MYSTATE_OFFLINE);
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
|
||||
debugSerial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
|
||||
debugSerial.println("WiFi Protected Setup (WPS): failed in enrollee mode");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
|
||||
debugSerial.println("WiFi Protected Setup (WPS): timeout in enrollee mode");
|
||||
break;
|
||||
case SYSTEM_EVENT_STA_WPS_ER_PIN:
|
||||
debugSerial.println("WiFi Protected Setup (WPS): pin code in enrollee mode");
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_START:
|
||||
debugSerial.println("WiFi access point started");
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STOP:
|
||||
debugSerial.println("WiFi access point stopped");
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STACONNECTED:
|
||||
debugSerial.println("Client connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STADISCONNECTED:
|
||||
debugSerial.println("Client disconnected");
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_STAIPASSIGNED:
|
||||
debugSerial.println("Assigned IP address to client");
|
||||
break;
|
||||
case SYSTEM_EVENT_AP_PROBEREQRECVED:
|
||||
debugSerial.println("Received probe request");
|
||||
break;
|
||||
case SYSTEM_EVENT_GOT_IP6:
|
||||
debugSerial.println("IPv6 is preferred");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_START:
|
||||
debugSerial.println("Ethernet started");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_STOP:
|
||||
debugSerial.println("Ethernet stopped");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_CONNECTED:
|
||||
debugSerial.println("Ethernet connected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_DISCONNECTED:
|
||||
debugSerial.println("Ethernet disconnected");
|
||||
break;
|
||||
case SYSTEM_EVENT_ETH_GOT_IP:
|
||||
debugSerial.println("Obtained IP address");
|
||||
break;
|
||||
default: break;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
#endif
|
||||
|
||||
void setup_main() {
|
||||
|
||||
#if (SERIAL_BAUD)
|
||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||
debugSerialPort.begin(SERIAL_BAUD);
|
||||
#endif
|
||||
#else
|
||||
|
||||
#if not defined (__SAM3X8E__)
|
||||
#if not defined (__SAM3X8E__) && defined (debugSerialPort) && !defined(NOSERIAL)
|
||||
debugSerialPort.begin();
|
||||
#endif
|
||||
delay(1000);
|
||||
@@ -2019,11 +2151,15 @@ void setup_main() {
|
||||
if(SPIFFS.begin())
|
||||
#endif
|
||||
{
|
||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||
debugSerialPort.println("SPIFFS Initialize....ok");
|
||||
#endif
|
||||
}
|
||||
else
|
||||
{
|
||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||
debugSerialPort.println("SPIFFS Initialization...failed");
|
||||
#endif
|
||||
}
|
||||
#endif
|
||||
#else
|
||||
@@ -2038,7 +2174,9 @@ void setup_main() {
|
||||
|
||||
if (!sysConf.isValidSysConf())
|
||||
{
|
||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||
debugSerialPort.println(F("No valid EEPROM data. Initializing."));
|
||||
#endif
|
||||
sysConf.clear();
|
||||
}
|
||||
// scan_i2c_bus();
|
||||
@@ -2073,7 +2211,7 @@ void setup_main() {
|
||||
#else
|
||||
pinMode(TXEnablePin, OUTPUT);
|
||||
#endif
|
||||
modbusSerial.begin(MODBUS_SERIAL_BAUD,dimPar);
|
||||
modbusSerial.begin(MODBUS_SERIAL_BAUD,MODBUS_SERIAL_PARAM);
|
||||
node.idle(&modbusIdle);
|
||||
node.preTransmission(preTransmission);
|
||||
node.postTransmission(postTransmission);
|
||||
@@ -2091,6 +2229,11 @@ void setup_main() {
|
||||
//#ifdef _artnet
|
||||
// artnetSetup();
|
||||
//#endif
|
||||
#if defined(WIFI_ENABLE)
|
||||
#if defined (ESP32)
|
||||
WiFi.onEvent(WiFiEvent);
|
||||
#endif
|
||||
#endif
|
||||
|
||||
#if defined(WIFI_ENABLE) and not defined(WIFI_MANAGER_DISABLE)
|
||||
// WiFiManager wifiManager;
|
||||
@@ -2160,11 +2303,17 @@ infoSerial<<F("\nFirmware MAC Address " QUOTE(CUSTOM_FIRMWARE_MAC));
|
||||
#endif
|
||||
|
||||
#ifdef _modbus
|
||||
infoSerial<<F("\n(+)MODBUS " QUOTE(MODBUS_DIMMER_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_SERIAL_BAUD));
|
||||
infoSerial<<F("\n(+)MODBUS " QUOTE(MODBUS_SERIAL_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_SERIAL_BAUD));
|
||||
#else
|
||||
infoSerial<<F("\n(-)MODBUS");
|
||||
#endif
|
||||
|
||||
#ifdef IPMODBUS
|
||||
infoSerial<<F("\n(+)IPMODBUS ");// QUOTE(MODBUS_TCP_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_TCP_BAUD));
|
||||
#else
|
||||
infoSerial<<F("\n(-)IPMODBUS");
|
||||
#endif
|
||||
|
||||
#ifndef OWIRE_DISABLE
|
||||
infoSerial<<F("\n(+)OWIRE");
|
||||
#ifdef USE_1W_PIN
|
||||
@@ -2283,13 +2432,17 @@ infoSerial<<F("\n(-)MULTIVENT");
|
||||
infoSerial<<F("\n(+)HUMIDIFIER");
|
||||
#endif
|
||||
|
||||
#ifdef NOSERIAL
|
||||
infoSerial<<F("\nNOSERIAL");
|
||||
#endif
|
||||
|
||||
#ifdef ELEVATOR_ENABLE
|
||||
infoSerial<<F("\n(+)ELEVATOR");
|
||||
#endif
|
||||
|
||||
#ifdef IPMODBUS
|
||||
infoSerial<<F("\n(+)IPMODBUS");
|
||||
#endif
|
||||
//#ifdef IPMODBUS
|
||||
//infoSerial<<F("\n(+)IPMODBUS");
|
||||
//#endif
|
||||
infoSerial<<endl;
|
||||
|
||||
// WDT_Disable( WDT ) ;
|
||||
@@ -2315,18 +2468,23 @@ void publishStat(){
|
||||
uint32_t ut = millis()/1000UL;
|
||||
if (!mqttClient.connected() || ethernetIdleCount) return;
|
||||
setTopic(topic,sizeof(topic),T_DEV);
|
||||
strncat_P(topic, stats_P, sizeof(topic));
|
||||
strncat_P(topic, stats_P, sizeof(topic)-1);
|
||||
strncat(topic, "/", sizeof(topic));
|
||||
strncat_P(topic, freeheap_P, sizeof(topic));
|
||||
strncat_P(topic, freeheap_P, sizeof(topic)-1);
|
||||
printUlongValueToStr(intbuf, fr);
|
||||
mqttClient.publish(topic,intbuf,true);
|
||||
|
||||
setTopic(topic,sizeof(topic),T_DEV);
|
||||
strncat_P(topic, stats_P, sizeof(topic));
|
||||
strncat_P(topic, stats_P, sizeof(topic)-1);
|
||||
strncat(topic, "/", sizeof(topic));
|
||||
strncat_P(topic, uptime_P, sizeof(topic));
|
||||
strncat_P(topic, uptime_P, sizeof(topic)-1);
|
||||
printUlongValueToStr(intbuf, ut);
|
||||
mqttClient.publish(topic,intbuf,true);
|
||||
|
||||
setTopic(topic,sizeof(topic),T_DEV);
|
||||
strncat_P(topic, state_P, sizeof(topic)-1);
|
||||
strncpy_P(intbuf, ready_P, sizeof(intbuf)-1);
|
||||
mqttClient.publish(topic,intbuf,true);
|
||||
}
|
||||
|
||||
void setupMacAddress() {
|
||||
|
||||
@@ -21,16 +21,21 @@ static bool CCS811ready = false;
|
||||
|
||||
int in_ccs811::Setup()
|
||||
{
|
||||
if (CCS811ready) {debugSerial<<F("ccs811 is already initialized")<<endl; return 0;}
|
||||
if (CCS811ready) {errorSerial<<F("ccs811 is already initialized")<<endl; return 0;}
|
||||
|
||||
#ifdef WAK_PIN
|
||||
pinMode(WAK_PIN,OUTPUT);
|
||||
digitalWrite(WAK_PIN,LOW);
|
||||
#endif
|
||||
|
||||
debugSerial.println("CCS811 Init");
|
||||
infoSerial.println("CCS811 Init");
|
||||
|
||||
#if defined (TWI_SCL) && defined (TWI_SDA)
|
||||
Wire.begin(TWI_SDA,TWI_SCL); //Inialize I2C Harware
|
||||
#else
|
||||
Wire.begin(); //Inialize I2C Harware
|
||||
#endif
|
||||
|
||||
Wire.setClock(4000);
|
||||
|
||||
//It is recommended to check return status on .begin(), but it is not
|
||||
@@ -40,7 +45,7 @@ Wire.setClock(4000);
|
||||
if (returnCode != CCS811Core::SENSOR_SUCCESS)
|
||||
//if (returnCode != CCS811Core::CCS811_Stat_SUCCESS)
|
||||
{
|
||||
Serial.print("CCS811 Init error ");
|
||||
errorSerial.print("CCS811 Init error ");
|
||||
//debugSerial.println(ccs811.statusString(returnCode));
|
||||
printDriverError(returnCode);
|
||||
return 0;
|
||||
@@ -116,8 +121,8 @@ if (reg!=0xff)
|
||||
// New tyle unified activities
|
||||
aJsonObject *actT = aJson.getObjectItem(in->inputObj, "temp");
|
||||
aJsonObject *actH = aJson.getObjectItem(in->inputObj, "hum");
|
||||
executeCommand(actT,-1,itemCmd(t));
|
||||
executeCommand(actH,-1,itemCmd(h));
|
||||
if (!isnan(t)) executeCommand(actT,-1,itemCmd(t));
|
||||
if (!isnan(t)) executeCommand(actH,-1,itemCmd(h));
|
||||
|
||||
publish(t,"/T");
|
||||
publish(h,"/H");
|
||||
|
||||
@@ -11,14 +11,21 @@
|
||||
#define CCS811_ADDR 0x5A //Alternate I2C Address
|
||||
|
||||
#if defined (ARDUINO_ARCH_ESP8266)
|
||||
#define twi_scl D1
|
||||
#ifndef WAK_PIN
|
||||
#define WAK_PIN D3
|
||||
#endif
|
||||
|
||||
#define SCL_LOW() (GPES = (1 << twi_scl))
|
||||
#define SCL_HIGH() (GPEC = (1 << twi_scl))
|
||||
#define SCL_RESET
|
||||
#if not defined (TWI_SCL) && defined (D1)
|
||||
#define TWI_SCL D1
|
||||
#endif
|
||||
|
||||
#if not defined (WAK_PIN) && defined (D3)
|
||||
#define WAK_PIN D3
|
||||
#endif
|
||||
|
||||
#if defined (TWI_SCL)
|
||||
#define SCL_LOW() (GPES = (1 << TWI_SCL))
|
||||
#define SCL_HIGH() (GPEC = (1 << TWI_SCL))
|
||||
#define SCL_RESET
|
||||
#endif
|
||||
|
||||
#endif
|
||||
|
||||
/*
|
||||
|
||||
@@ -8,27 +8,25 @@
|
||||
#include "textconst.h"
|
||||
#include "main.h"
|
||||
|
||||
#include "config.h"
|
||||
#include "streamlog.h"
|
||||
extern systemConfig sysConf;
|
||||
extern bool disableCMD;
|
||||
|
||||
#ifndef AC_Serial
|
||||
#define AC_Serial Serial3
|
||||
#endif
|
||||
|
||||
#define INTERVAL_AC_POLLING 5000L
|
||||
|
||||
static int driverStatus = CST_UNKNOWN;
|
||||
#define AC_FAILED 15
|
||||
#define AC_UNKNOWN CST_UNKNOWN
|
||||
#define AC_IDLE CST_INITIALIZED
|
||||
#define AC_SENDING 2
|
||||
|
||||
static int fresh =0;
|
||||
static int power = 0;
|
||||
static int swing =0;
|
||||
static int lock_rem =0;
|
||||
static int cur_tmp = 0;
|
||||
static int set_tmp = 0;
|
||||
static int fan_spd = 0;
|
||||
static int mode = 0;
|
||||
|
||||
long prevPolling = 0;
|
||||
byte inCheck = 0;
|
||||
byte qstn[] = {255,255,10,0,0,0,0,0,1,1,77,1,90}; // Команда опроса
|
||||
byte data[37] = {}; //Массив данных
|
||||
|
||||
byte on[] = {255,255,10,0,0,0,0,0,1,1,77,2,91}; // Включение кондиционера
|
||||
byte off[] = {255,255,10,0,0,0,0,0,1,1,77,3,92}; // Выключение кондиционера
|
||||
byte lock[] = {255,255,10,0,0,0,0,0,1,3,0,0,14}; // Блокировка пульта
|
||||
@@ -39,16 +37,55 @@ const char QUIET_P[] PROGMEM = "queit";
|
||||
const char SWING_P[] PROGMEM = "swing";
|
||||
const char RAW_P[] PROGMEM = "raw";
|
||||
|
||||
void out_AC::getConfig(){
|
||||
|
||||
ACSerial=&AC_Serial;
|
||||
if (!item) return;
|
||||
|
||||
if (item->getArgCount())
|
||||
|
||||
switch(portNum=item->getArg(0)){
|
||||
case 0: ACSerial=&Serial;
|
||||
|
||||
break;
|
||||
#if not defined (AVR) || defined (DMX_DISABLE)
|
||||
case 1: ACSerial=&Serial1;
|
||||
break;
|
||||
#endif
|
||||
#if defined (HAVE_HWSERIAL2) || defined (__SAM3X8E__) || defined (ESP32)
|
||||
case 2: ACSerial=&Serial2;
|
||||
break;
|
||||
#endif
|
||||
#if defined (HAVE_HWSERIAL3) || defined (__SAM3X8E__)
|
||||
case 3: ACSerial=&Serial3;
|
||||
break;
|
||||
#endif
|
||||
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
void out_AC::InsertData(byte data[], size_t size){
|
||||
|
||||
int fresh =0;
|
||||
|
||||
int swing =0;
|
||||
int lock_rem =0;
|
||||
int cur_tmp = 0;
|
||||
int set_tmp = 0;
|
||||
int fan_spd = 0;
|
||||
|
||||
|
||||
char s_mode[10];
|
||||
|
||||
set_tmp = data[B_SET_TMP]+16;
|
||||
if (set_tmp>40 || set_tmp<16) return;
|
||||
cur_tmp = data[B_CUR_TMP];
|
||||
mode = data[B_MODE];
|
||||
store->mode = data[B_MODE];
|
||||
fan_spd = data[B_FAN_SPD];
|
||||
swing = data[B_SWING];
|
||||
power = data[B_POWER];
|
||||
store->power = data[B_POWER];
|
||||
lock_rem = data[B_LOCK_REM];
|
||||
fresh = data[B_FRESH];
|
||||
/////////////////////////////////
|
||||
@@ -73,15 +110,15 @@ void out_AC::InsertData(byte data[], size_t size){
|
||||
}
|
||||
*/
|
||||
|
||||
debugSerial.print ("Power=");
|
||||
debugSerial.println(power);
|
||||
debugSerial.print ("AC: Power=");
|
||||
debugSerial.println(store->power);
|
||||
|
||||
if (power & 0x08)
|
||||
if (store->power & 0x08)
|
||||
publishTopic(item->itemArr->name, "ON", "/quiet");
|
||||
else publishTopic(item->itemArr->name, "OFF" , "/quiet");
|
||||
|
||||
|
||||
if (power & 0x02) //Compressor on
|
||||
if (store->power & 0x02) //Compressor on
|
||||
publishTopic(item->itemArr->name, "ON","/compressor");
|
||||
else
|
||||
publishTopic(item->itemArr->name, "OFF","/compressor");
|
||||
@@ -124,28 +161,28 @@ void out_AC::InsertData(byte data[], size_t size){
|
||||
////////////////////////////////////
|
||||
s_mode[0]='\0';
|
||||
|
||||
if (mode == 0x00){
|
||||
if (store->mode == 0x00){
|
||||
strcpy_P(s_mode,AUTO_P);
|
||||
}
|
||||
else if (mode == 0x01){
|
||||
else if (store->mode == 0x01){
|
||||
strcpy_P(s_mode,COOL_P);
|
||||
}
|
||||
else if (mode == 0x02){
|
||||
else if (store->mode == 0x02){
|
||||
strcpy_P(s_mode,HEAT_P);
|
||||
}
|
||||
else if (mode == 0x03){
|
||||
else if (store->mode == 0x03){
|
||||
strcpy_P(s_mode,FAN_ONLY_P);
|
||||
}
|
||||
else if (mode == 0x04){
|
||||
else if (store->mode == 0x04){
|
||||
strcpy_P(s_mode,DRY_P);
|
||||
}
|
||||
else if (mode == 109){
|
||||
else if (store->mode == 109){
|
||||
strcpy_P(s_mode,ERROR_P);
|
||||
}
|
||||
|
||||
publishTopic(item->itemArr->name, (long) mode, "/mode");
|
||||
publishTopic(item->itemArr->name, (long) store->mode, "/mode");
|
||||
|
||||
if (power & 0x01)
|
||||
if (store->power & 0x01)
|
||||
publishTopic(item->itemArr->name, s_mode,"/cmd");
|
||||
|
||||
else publishTopic(item->itemArr->name, "OFF","/cmd");
|
||||
@@ -177,11 +214,17 @@ byte getCRC(byte req[], size_t size){
|
||||
}
|
||||
|
||||
void out_AC::SendData(byte req[], size_t size){
|
||||
AC_Serial.write(req, size - 1);
|
||||
AC_Serial.write(getCRC(req, size-1));
|
||||
//AC_Serial.flush();
|
||||
item->setExt(millisNZ());
|
||||
debugSerial.print("AirCon<<");
|
||||
if (!store || !item) return;
|
||||
if (item->itemArr->subtype == AC_SENDING)
|
||||
{
|
||||
while (store->timestamp && !isTimeOver(store->timestamp,millis(),150)) yield();
|
||||
}
|
||||
|
||||
ACSerial->write(req, size - 1);
|
||||
ACSerial->write(getCRC(req, size-1));
|
||||
//ACSerial->flush();
|
||||
store->timestamp=millisNZ();
|
||||
debugSerial<<F("AC: ")<<portNum<<F(" <<");
|
||||
for (int i=0; i < size-1; i++)
|
||||
{
|
||||
if (req[i] < 10){
|
||||
@@ -194,7 +237,7 @@ void out_AC::SendData(byte req[], size_t size){
|
||||
}
|
||||
}
|
||||
debugSerial.println();
|
||||
|
||||
item->itemArr->subtype = AC_SENDING;
|
||||
}
|
||||
|
||||
inline unsigned char toHex( char ch ){
|
||||
@@ -206,50 +249,120 @@ inline unsigned char toHex( char ch ){
|
||||
int out_AC::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
debugSerial<<F("AC Init")<<endl;
|
||||
AC_Serial.begin(9600);
|
||||
driverStatus = CST_INITIALIZED;
|
||||
if (!item) return 0;
|
||||
debugSerial<<F("AC: Init: ")<<portNum<<endl;
|
||||
|
||||
if (!store) store= (acPersistent *)item->setPersistent(new acPersistent);
|
||||
if (!store)
|
||||
{ errorSerial<<F("AC: Out of memory")<<endl;
|
||||
return 0;}
|
||||
|
||||
memset(store->data,0,sizeof(acPersistent::data));
|
||||
store->mode=0;
|
||||
store->power=0;
|
||||
store->inCheck=0;
|
||||
store->timestamp=millisNZ();
|
||||
|
||||
if (!portNum)// && (g_APinDescription[0].ulPinType == PIO_PA8A_URXD))
|
||||
{
|
||||
pinMode(0, INPUT_PULLUP);
|
||||
#if debugSerial == Serial
|
||||
infoSerial<<F("AC: Serial used by AC - disabling serial logging and cmd")<<endl;
|
||||
//sysConf.setSerialDebuglevel(0);
|
||||
serialDebugLevel = 0;
|
||||
disableCMD=true;
|
||||
#endif
|
||||
}
|
||||
ACSerial->begin(9600);
|
||||
item->itemArr->subtype = AC_IDLE;
|
||||
|
||||
//driverStatus = CST_INITIALIZED;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int out_AC::Stop()
|
||||
{
|
||||
debugSerial<<F("AC De-Init")<<endl;
|
||||
|
||||
driverStatus = CST_UNKNOWN;
|
||||
if (!item) return 0;
|
||||
debugSerial<<F("AC: De-Init: ")<<portNum<<endl;
|
||||
delete store;
|
||||
item->setPersistent(NULL);
|
||||
store = NULL;
|
||||
item->itemArr->subtype = CST_UNKNOWN;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int out_AC::Status()
|
||||
{
|
||||
return driverStatus;
|
||||
if (!item) return 0;
|
||||
switch (item->itemArr->subtype)
|
||||
{
|
||||
case AC_FAILED: return CST_FAILED;
|
||||
case AC_UNKNOWN: return CST_UNKNOWN;
|
||||
default:
|
||||
return CST_INITIALIZED;
|
||||
//return item->itemArr->subtype;
|
||||
}
|
||||
}
|
||||
|
||||
int out_AC::isActive()
|
||||
{
|
||||
return (power & 1);
|
||||
if (!store) return 0;
|
||||
return (store->power & 1);
|
||||
}
|
||||
|
||||
int out_AC::Poll(short cause)
|
||||
{
|
||||
if (!store) return -1;
|
||||
|
||||
switch (item->itemArr->subtype)
|
||||
{
|
||||
case AC_FAILED: return -1;
|
||||
case AC_UNKNOWN: return -1;
|
||||
case AC_SENDING:
|
||||
{
|
||||
if (store->timestamp && isTimeOver(store->timestamp,millis(),150))
|
||||
{
|
||||
item->itemArr->subtype = AC_IDLE;
|
||||
store->timestamp=millisNZ();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
if (cause!=POLLING_SLOW) return false;
|
||||
|
||||
if (isTimeOver(prevPolling,millis(),INTERVAL_AC_POLLING)) {
|
||||
prevPolling = millisNZ();
|
||||
debugSerial.println(F("Polling"));
|
||||
if ((item->itemArr->subtype == AC_IDLE) && isTimeOver(store->timestamp,millis(),INTERVAL_AC_POLLING))
|
||||
{
|
||||
debugSerial.println(F("AC: Polling"));
|
||||
SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера
|
||||
}
|
||||
|
||||
if(AC_Serial.available() >= 37){ //was 0
|
||||
AC_Serial.readBytes(data, 37);
|
||||
while(AC_Serial.available()){
|
||||
if(ACSerial->available() >= 37){ //was 0
|
||||
ACSerial->readBytes(store->data, 37);
|
||||
while(ACSerial->available()){
|
||||
delay(2);
|
||||
AC_Serial.read();
|
||||
ACSerial->read();
|
||||
}
|
||||
if (data[36] != inCheck){
|
||||
inCheck = data[36];
|
||||
InsertData(data, 37);
|
||||
|
||||
debugSerial<<F("AC: ")<<portNum<<F(" >> ");
|
||||
for (int i=0; i < 37-1; i++)
|
||||
{
|
||||
if (store->data[i] < 10){
|
||||
debugSerial.print("0");
|
||||
debugSerial.print(store->data[i], HEX);
|
||||
}
|
||||
else
|
||||
{
|
||||
debugSerial.print(store->data[i], HEX);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (store->data[36] != store->inCheck){
|
||||
store->inCheck = store->data[36];
|
||||
InsertData(store->data, 37);
|
||||
debugSerial<<F("AC: OK");
|
||||
}
|
||||
|
||||
debugSerial.println();
|
||||
}
|
||||
return true;
|
||||
};
|
||||
@@ -273,14 +386,16 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
switch(suffixCode)
|
||||
{
|
||||
case S_SET:
|
||||
set_tmp = cmd.getInt();
|
||||
{
|
||||
byte set_tmp = cmd.getInt();
|
||||
if (set_tmp >= 16 && set_tmp <= 40)
|
||||
{
|
||||
//if (set_tmp>40 || set_tmp<16) set_temp=21;
|
||||
data[B_SET_TMP] = set_tmp -16;
|
||||
store->data[B_SET_TMP] = set_tmp -16;
|
||||
publishTopic(item->itemArr->name,(long) set_tmp,"/set");
|
||||
}
|
||||
else return -1;
|
||||
}
|
||||
break;
|
||||
|
||||
case S_CMD:
|
||||
@@ -289,52 +404,52 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
{
|
||||
case CMD_ON:
|
||||
case CMD_XON:
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] |= 1;
|
||||
SendData(on, sizeof(on)/sizeof(byte));
|
||||
// publishTopic(item->itemArr->name,"ON","/cmd");
|
||||
return 1;
|
||||
break;
|
||||
case CMD_OFF:
|
||||
case CMD_HALT:
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] &= ~1;
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] &= ~1;
|
||||
SendData(off, sizeof(off)/sizeof(byte));
|
||||
// publishTopic(item->itemArr->name,"OFF","/cmd");
|
||||
return 1;
|
||||
break;
|
||||
case CMD_AUTO:
|
||||
data[B_MODE] = 0;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
store->data[B_MODE] = 0;
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] |= 1;
|
||||
// strcpy_P(s_mode,AUTO_P);
|
||||
break;
|
||||
case CMD_COOL:
|
||||
data[B_MODE] = 1;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
store->data[B_MODE] = 1;
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] |= 1;
|
||||
// strcpy_P(s_mode,COOL_P);
|
||||
break;
|
||||
case CMD_HEAT:
|
||||
data[B_MODE] = 2;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
store->data[B_MODE] = 2;
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] |= 1;
|
||||
// strcpy_P(s_mode,HEAT_P);
|
||||
break;
|
||||
case CMD_DRY:
|
||||
data[B_MODE] = 4;
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
store->data[B_MODE] = 4;
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] |= 1;
|
||||
// strcpy_P(s_mode,DRY_P);
|
||||
break;
|
||||
case CMD_FAN:
|
||||
data[B_MODE] = 3;
|
||||
store->data[B_MODE] = 3;
|
||||
// debugSerial<<"fan\n";
|
||||
data[B_POWER] = power;
|
||||
data[B_POWER] |= 1;
|
||||
if (data[B_FAN_SPD] == 3)
|
||||
store->data[B_POWER] = store->power;
|
||||
store->data[B_POWER] |= 1;
|
||||
if (store->data[B_FAN_SPD] == 3)
|
||||
{
|
||||
data[B_FAN_SPD] = 2; //Auto - fan speed in Ventilation mode not working
|
||||
store->data[B_FAN_SPD] = 2; //Auto - fan speed in Ventilation mode not working
|
||||
}
|
||||
// strcpy_P(s_mode,FAN_ONLY_P);
|
||||
break;
|
||||
@@ -351,24 +466,24 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_AUTO:
|
||||
data[B_FAN_SPD] = 3;
|
||||
store->data[B_FAN_SPD] = 3;
|
||||
strcpy_P(s_speed,AUTO_P);
|
||||
break;
|
||||
case CMD_HIGH:
|
||||
data[B_FAN_SPD] = 0;
|
||||
store->data[B_FAN_SPD] = 0;
|
||||
strcpy_P(s_speed,HIGH_P);
|
||||
break;
|
||||
case CMD_MED:
|
||||
data[B_FAN_SPD] = 1;
|
||||
store->data[B_FAN_SPD] = 1;
|
||||
strcpy_P(s_speed,MED_P);
|
||||
break;
|
||||
case CMD_LOW:
|
||||
data[B_FAN_SPD] = 2;
|
||||
store->data[B_FAN_SPD] = 2;
|
||||
strcpy_P(s_speed,LOW_P);
|
||||
break;
|
||||
default:
|
||||
//if (n) data[B_FAN_SPD] = Parameters[0];
|
||||
data[B_FAN_SPD] = cmd.getInt();
|
||||
store->data[B_FAN_SPD] = cmd.getInt();
|
||||
//TODO - mapping digits to speed
|
||||
}
|
||||
publishTopic(item->itemArr->name,s_speed,"/fan");
|
||||
@@ -376,17 +491,17 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
|
||||
case S_MODE:
|
||||
//data[B_MODE] = Parameters[0];
|
||||
data[B_MODE] = cmd.getInt();
|
||||
store->data[B_MODE] = cmd.getInt();
|
||||
break;
|
||||
|
||||
case S_LOCK:
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
data[B_LOCK_REM] = 80;
|
||||
store->data[B_LOCK_REM] = 80;
|
||||
break;
|
||||
case CMD_OFF:
|
||||
data[B_LOCK_REM] = 0;
|
||||
store->data[B_LOCK_REM] = 0;
|
||||
break;
|
||||
}
|
||||
break;
|
||||
@@ -395,16 +510,16 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
data[B_SWING] = 3;
|
||||
store->data[B_SWING] = 3;
|
||||
publishTopic(item->itemArr->name,"ON","/swing");
|
||||
break;
|
||||
case CMD_OFF:
|
||||
data[B_SWING] = 0;
|
||||
store->data[B_SWING] = 0;
|
||||
publishTopic(item->itemArr->name,"OFF","/swing");
|
||||
break;
|
||||
default:
|
||||
//if (n) data[B_SWING] = Parameters[0];
|
||||
data[B_SWING] = cmd.getInt();
|
||||
store->data[B_SWING] = cmd.getInt();
|
||||
}
|
||||
|
||||
break;
|
||||
@@ -413,10 +528,10 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
data[B_POWER] |= 8;
|
||||
store->data[B_POWER] |= 8;
|
||||
break;
|
||||
case CMD_OFF:
|
||||
data[B_POWER] &= ~8;
|
||||
store->data[B_POWER] &= ~8;
|
||||
break;
|
||||
}
|
||||
|
||||
@@ -434,8 +549,8 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
hexbyte[0] = buf[i] ;
|
||||
hexbyte[1] = buf[i+1] ;
|
||||
data[i/2] = (toHex(hexbyte[0]) << 4) | toHex(hexbyte[1]);
|
||||
AC_Serial.write(data, 37);
|
||||
AC_Serial.flush();
|
||||
ACSerial->write(data, 37);
|
||||
ACSerial->flush();
|
||||
publishTopic("RAW", buf);
|
||||
}
|
||||
*/
|
||||
@@ -470,16 +585,18 @@ int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
|
||||
//if (strTopic == "/myhome/in/Conditioner/RAW")
|
||||
|
||||
data[B_CMD] = 0;
|
||||
data[9] = 1;
|
||||
data[10] = 77;
|
||||
data[11] = 95;
|
||||
AC_Serial.flush();
|
||||
uint32_t ts=item->getExt();
|
||||
while (ts && !isTimeOver(ts,millis(),100)) yield();
|
||||
SendData(data, sizeof(data)/sizeof(byte));
|
||||
store->data[B_CMD] = 0;
|
||||
store->data[9] = 1;
|
||||
store->data[10] = 77;
|
||||
store->data[11] = 95;
|
||||
|
||||
///ACSerial->flush();
|
||||
|
||||
//uint32_t ts=item->getExt();
|
||||
//while (ts && !isTimeOver(ts,millis(),100)) yield();
|
||||
SendData(store->data, sizeof(store->data)/sizeof(byte));
|
||||
//InsertData(data, sizeof(data)/sizeof(byte));
|
||||
//AC_Serial.flush();
|
||||
//ACSerial->flush();
|
||||
//item->setExt(millisNZ());
|
||||
return 1;
|
||||
}
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
#pragma once
|
||||
#ifndef AC_DISABLE
|
||||
#include <abstractout.h>
|
||||
#include <item.h>
|
||||
#include "itemCmd.h"
|
||||
|
||||
#define LEN_B 37
|
||||
@@ -21,10 +22,21 @@
|
||||
//#define S_RAW S_ADDITIONAL+4
|
||||
|
||||
extern void modbusIdle(void) ;
|
||||
|
||||
class acPersistent : public chPersistent {
|
||||
public:
|
||||
byte data[37];
|
||||
byte power;
|
||||
byte mode;
|
||||
byte inCheck;
|
||||
uint32_t timestamp;
|
||||
};
|
||||
|
||||
class out_AC : public abstractOut {
|
||||
public:
|
||||
|
||||
out_AC(Item * _item):abstractOut(_item){};
|
||||
out_AC(Item * _item):abstractOut(_item){store = (acPersistent *) item->getPersistent(); getConfig();};
|
||||
void getConfig();
|
||||
int Setup() override;
|
||||
int Poll(short cause) override;
|
||||
int Stop() override;
|
||||
@@ -35,7 +47,15 @@ public:
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
||||
|
||||
protected:
|
||||
acPersistent * store;
|
||||
void InsertData(byte data[], size_t size);
|
||||
void SendData(byte req[], size_t size);
|
||||
uint8_t portNum;
|
||||
#if defined (__SAM3X8E__)
|
||||
UARTClass *ACSerial;
|
||||
#else
|
||||
HardwareSerial *ACSerial;
|
||||
#endif
|
||||
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -13,7 +13,8 @@ static int driverStatus = CST_UNKNOWN;
|
||||
void out_counter::getConfig()
|
||||
{
|
||||
if (!item) return;
|
||||
impulse = item->getFloatArg(0);
|
||||
impulse = item->getFloatArg(0)*TENS_BASE;
|
||||
|
||||
period = item->getFloatArg(1)*1000.0;
|
||||
//debugSerial<<"CTR: imp:"<<impulse<<" period:"<<period<<endl;
|
||||
}
|
||||
@@ -50,16 +51,18 @@ uint32_t timer = item->getExt();
|
||||
item->setExt(millisNZ());
|
||||
|
||||
itemCmd st;
|
||||
st.loadItem(item,SEND_PARAMETERS|SEND_COMMAND);
|
||||
float val = st.getFloat();
|
||||
st.loadItem(item,FLAG_PARAMETERS|FLAG_COMMAND);
|
||||
//float val = st.getFloat();
|
||||
uint32_t val = st.getTens_raw();
|
||||
//short cmd = st.getCmd();
|
||||
debugSerial<<"CTR: tick val:"<<val<<endl;
|
||||
debugSerial<<"CTR: tick val:"<<val<< " + "<< impulse << endl;
|
||||
|
||||
val+=impulse;
|
||||
st.Float(val);
|
||||
//st.Float(val);
|
||||
st.Tens_raw(val);
|
||||
st.saveItem(item);
|
||||
debugSerial<<"CTR: tick saved val:"<<val<<endl;
|
||||
item->SendStatus(SEND_PARAMETERS);
|
||||
item->SendStatus(FLAG_PARAMETERS);
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -20,7 +20,8 @@ public:
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
||||
|
||||
protected:
|
||||
float impulse;
|
||||
//float impulse;
|
||||
uint32_t impulse;
|
||||
uint32_t period;
|
||||
};
|
||||
#endif
|
||||
|
||||
489
lighthub/modules/out_mercury.cpp
Normal file
489
lighthub/modules/out_mercury.cpp
Normal file
@@ -0,0 +1,489 @@
|
||||
//Спецификация протокола тут
|
||||
//https://ftp.owen.ru/CoDeSys3/04_Library/05_3.5.11.5/02_Libraries/02_vendor_protocols/merkuriy-sistema-komand-sogl-1-2021-02-02.pdf
|
||||
// Использованы фрагменты кода отсюда: https://arduino.ru/forum/pesochnitsa-razdel-dlya-novichkov/arduino-mega-merkurii-2032t-rs485
|
||||
#ifdef MERCURY_ENABLE
|
||||
|
||||
#include "modules/out_mercury.h"
|
||||
#include "Arduino.h"
|
||||
#include "options.h"
|
||||
#include "utils.h"
|
||||
#include "Streaming.h"
|
||||
|
||||
#include "item.h"
|
||||
#include <ModbusMaster.h>
|
||||
#include "main.h"
|
||||
#include <HardwareSerial.h>
|
||||
|
||||
extern aJsonObject *modbusObj;
|
||||
extern ModbusMaster node;
|
||||
extern short modbusBusy;
|
||||
extern void modbusIdle(void) ;
|
||||
extern uint32_t mbusSlenceTimer;
|
||||
|
||||
|
||||
|
||||
bool out_Mercury::getConfig()
|
||||
{
|
||||
if (!store || !item || !item->itemArg || (item->itemArg->type != aJson_Array) || aJson.getArraySize(item->itemArg)<6)
|
||||
{
|
||||
errorSerial<<F("Mercury: config failed:")<<(bool)store<<F(",")<<(bool)item<<F(",")<<(bool)item->itemArg<<F(",")<<(item->itemArg->type != aJson_Array)<<F(",")<< (aJson.getArraySize(item->itemArg)<6)<<endl;
|
||||
return false;
|
||||
}
|
||||
|
||||
aJsonObject * delayObj=aJson.getArrayItem(item->itemArg, 5);
|
||||
if (delayObj) pollingInterval = delayObj->valueint;
|
||||
else pollingInterval = 10000;
|
||||
|
||||
return true;
|
||||
}
|
||||
|
||||
void out_Mercury::initLine(bool full)
|
||||
{
|
||||
int baud;
|
||||
serialParamType serialParam;
|
||||
|
||||
aJsonObject * serialParamObj=aJson.getArrayItem(item->itemArg, 2);
|
||||
if (serialParamObj && serialParamObj->type == aJson_String) serialParam = str2SerialParam(serialParamObj->valuestring);
|
||||
else serialParam = SERIAL_8N1;
|
||||
|
||||
aJsonObject * baudObj=aJson.getArrayItem(item->itemArg, 1);
|
||||
if (baudObj && baudObj->type == aJson_Int && baudObj->valueint) baud = baudObj->valueint;
|
||||
else baud = 9600;
|
||||
|
||||
#if defined (__SAM3X8E__)
|
||||
modbusSerial.begin(baud, static_cast <USARTClass::USARTModes> (serialParam));
|
||||
#elif defined (ARDUINO_ARCH_ESP8266)
|
||||
modbusSerial.begin(baud, static_cast <SerialConfig>(serialParam));
|
||||
#elif defined (ESP32)
|
||||
if (full) modbusSerial.begin(store->baud, (serialParam),MODBUS_UART_RX_PIN,MODBUS_UART_TX_PIN);
|
||||
else modbusSerial.updateBaudRate (baud); //Some terrible error in ESP32 core with uart reinit
|
||||
#else
|
||||
modbusSerial.begin(baud, (serialParam));
|
||||
#endif
|
||||
//debugSerial<<F("Mercury: ")<< baud << F(" <")<< serialParam<< F("> addr:")<<item->getArg(0)<<endl;
|
||||
node.begin(item->getArg(0), modbusSerial);
|
||||
}
|
||||
|
||||
|
||||
|
||||
int out_Mercury::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
if (!store) store= (mercuryPersistent *)item->setPersistent(new mercuryPersistent);
|
||||
if (!store)
|
||||
{ errorSerial<<F("Mercury: Out of memory")<<endl;
|
||||
return 0;}
|
||||
|
||||
store->timestamp=millisNZ();
|
||||
if (getConfig())
|
||||
{
|
||||
infoSerial<<F("Mercury: config loaded ")<< item->itemArr->name<<endl;
|
||||
store->driverStatus = CST_INITIALIZED;
|
||||
store->lastSuccessTS = 0;
|
||||
initLine(true);
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ errorSerial<<F("Mercury: config error")<<endl;
|
||||
store->driverStatus = CST_FAILED;
|
||||
return 0;
|
||||
}
|
||||
|
||||
}
|
||||
|
||||
int out_Mercury::Stop()
|
||||
{
|
||||
debugSerial.println("Mercury: De-Init");
|
||||
disconnectMercury();
|
||||
delete store;
|
||||
item->setPersistent(NULL);
|
||||
store = NULL;
|
||||
return 1;
|
||||
}
|
||||
|
||||
int out_Mercury::Status()
|
||||
{
|
||||
if (store)
|
||||
return store->driverStatus;
|
||||
return CST_UNKNOWN;
|
||||
}
|
||||
|
||||
|
||||
void out_Mercury::setStatus(short status)
|
||||
{
|
||||
if (store) store->driverStatus=status;
|
||||
}
|
||||
|
||||
short out_Mercury::connectMercury()
|
||||
{
|
||||
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
|
||||
uint8_t buffer[10];
|
||||
uint8_t ret;
|
||||
modbusBusy=1;
|
||||
initLine();
|
||||
|
||||
buffer[1]=1; //Login
|
||||
|
||||
aJsonObject * levelObj=aJson.getArrayItem(item->itemArg, 3);
|
||||
if (levelObj && levelObj->type == aJson_Int) buffer[2] = levelObj->valueint;
|
||||
else errorSerial<<F("Mercury: wrong accesslevel")<<endl;
|
||||
|
||||
aJsonObject * passObj=aJson.getArrayItem(item->itemArg, 4);
|
||||
if (passObj && passObj->type == aJson_String && (strlen (passObj->valuestring) == 6)) memcpy((char*) buffer+3,passObj->valuestring,6);
|
||||
else if (passObj && passObj->type == aJson_Array && (aJson.getArraySize (passObj) == 6))
|
||||
{
|
||||
//debugSerial<<F("Mercury: Pass :");
|
||||
for(short i=0;i<6;i++)
|
||||
{
|
||||
aJsonObject * digitObj=aJson.getArrayItem(passObj,i);
|
||||
if (digitObj && digitObj->type==aJson_Int)
|
||||
{
|
||||
buffer[3+i]=digitObj->valueint;
|
||||
//debugSerial<< digitObj->valueint<< F(",");
|
||||
}
|
||||
}
|
||||
debugSerial<<endl;
|
||||
}
|
||||
else errorSerial<<F("Mercury: passwort must be ether String[6] or Array[6]")<<endl;
|
||||
|
||||
|
||||
debugSerial<<F("Mercury: Connect ")<< item->itemArr->name<<F(" level:")<< buffer[2] ;//<< F(" pass:")<< passObj->valuestring;
|
||||
ret=node.ModbusRawTransaction(buffer,9,4);
|
||||
modbusBusy=0;
|
||||
if (!ret) ret = buffer[1];
|
||||
debugSerial<<F(" res:")<< ret << endl;
|
||||
mbusSlenceTimer = millisNZ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
short out_Mercury::disconnectMercury()
|
||||
{
|
||||
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
|
||||
uint8_t buffer[4];
|
||||
uint8_t ret;
|
||||
modbusBusy=1;
|
||||
initLine();
|
||||
|
||||
buffer[1]=2; //Close
|
||||
ret=node.ModbusRawTransaction(buffer,2,4);
|
||||
modbusBusy=0;
|
||||
|
||||
if (!ret) ret = buffer[1];
|
||||
debugSerial<<F("Mercury: Disconnect ")<< item->itemArr->name<<F(" res:")<< ret << endl;
|
||||
mbusSlenceTimer = millisNZ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
///////////////////// команды//////////////////////////////////////////////////////
|
||||
//byte testConnect[] = { 0x00, 0x00 }; //тест связи
|
||||
//byte Sn[] = { 0x00, 0x08, 0x05 }; //запрос сетевого адреса
|
||||
//byte Open[] = { 0x00, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01}; //открыть канал с паролеи
|
||||
//byte Close[] = { 0x00, 0x02 }; // закрыть канал (а то ждать 4 минуты)
|
||||
//byte activPower[] = { 0x00, 0x05, 0x00, 0x00 }; //суммарная энергия прямая + обратная + активная + реактивная
|
||||
//byte ind[] = { 0x00, 0x03, 0x01, 0x01, 0x00, 0x01, 0x00, 0x1F, 0x00, 0x1F, 0x00 }; //маска индикации работает только для автоматического режима
|
||||
//byte Angle[] = { 0x00, 0x08, 0x16, 0x51 }; // углы между фазами 1и2, 1и3, 2и3
|
||||
|
||||
|
||||
////////////////////////подпрограмма чтения показаний счётчика////////////////////////////////////
|
||||
#define M_BEGIN_YESTERDAY 0xD0 // показания на начало вчерашних суток
|
||||
#define M_BEGIN_TODAY 0x21 // показания на начало сегодняшних суток
|
||||
#define M_NOW 0x00 // показания на сейчас
|
||||
//2.5.17 Запросы на чтение массивов регистров накопленной энергии
|
||||
short out_Mercury::getCounters(byte when, String topic, int divisor)
|
||||
{
|
||||
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
|
||||
modbusBusy=1;
|
||||
initLine();
|
||||
|
||||
uint8_t response[19]{}; //1+4+4+4+4+2
|
||||
response[1]=0x05;
|
||||
response[2]=when; // показания на начало вчерашних суток 0xD0
|
||||
|
||||
uint8_t ret=node.ModbusRawTransaction(response, 4 , sizeof(response));
|
||||
if (!ret)
|
||||
|
||||
{
|
||||
unsigned long r = 0;
|
||||
r |= (unsigned long)response[2]<<24;
|
||||
r |= (unsigned long)response[1]<<16;
|
||||
r |= (unsigned long)response[4]<<8;
|
||||
r |= (unsigned long)response[3];
|
||||
|
||||
publishTopic(item->itemArr->name, (float) r/1000,(topic+"/Active").c_str());
|
||||
//Обратную (5-8) пропускаем
|
||||
r = 0;
|
||||
r |= (unsigned long)response[10]<<24;
|
||||
r |= (unsigned long)response[9]<<16;
|
||||
r |= (unsigned long)response[12]<<8;
|
||||
r |= (unsigned long)response[11];
|
||||
publishTopic(item->itemArr->name, (float) r/1000,(topic+"/Reactive").c_str());
|
||||
//Обратную (13-16) пропускаем
|
||||
};
|
||||
|
||||
debugSerial<<F("Mercury: getCounters ")<< item->itemArr->name << F(" res:")<< ret << endl;
|
||||
modbusBusy=0;
|
||||
mbusSlenceTimer = millisNZ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
/////////////////////////углы, напряжения токи по фазам//////////////////////////////////////////////////
|
||||
#define VOLTAGE 0x11 //0x11 напряжения пофазно, 100делитель
|
||||
#define CURRENT 0x21 //0x21 токи пофазно
|
||||
#define ANGLES 0x51 //0x51 углы между напряжениями фаз, 100делитель
|
||||
|
||||
|
||||
#define M_COSF 0x31
|
||||
#define M_ANGLE_DEF 0x30
|
||||
#define M_PWR 0x00
|
||||
short out_Mercury::getCurrentVal12(byte param, String topic, int divisor)
|
||||
|
||||
{
|
||||
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
|
||||
modbusBusy=1;
|
||||
initLine();
|
||||
|
||||
uint8_t response[12]{};
|
||||
|
||||
response[1]=0x08; //2.6 Запросы на чтение параметров
|
||||
response[2]=0x16; //2.6.16 Чтение вспомогательных параметров: мгновенной активной,реактивной, полной мощности,
|
||||
// фазных и линейных, напряжений,тока, коэффициента мощности,частоты, небаланса
|
||||
// Ответ 12 (9) двоичных байт. Два старших разряда старшего байта указывают положение вектора полной мощности и
|
||||
// должны маскироваться (см. п. 1.5)
|
||||
response[3]=param;
|
||||
|
||||
uint8_t ret=node.ModbusRawTransaction(response, 4 , sizeof(response));
|
||||
if (!ret)
|
||||
{
|
||||
long r = 0;
|
||||
r |= (long)response[1]<<16;
|
||||
r |= (long)response[3]<<8;
|
||||
r |= (long)response[2];
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/A").c_str());
|
||||
|
||||
r = 0;
|
||||
r |= (long)response[4]<<16;
|
||||
r |= (long)response[6]<<8;
|
||||
r |= (long)response[5];
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/B").c_str());
|
||||
|
||||
r=0;
|
||||
r |= (long)response[7]<<16;
|
||||
r |= (long)response[9]<<8;
|
||||
r |= (long)response[8];
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/C").c_str());
|
||||
}
|
||||
debugSerial<<F("Mercury: getCurrentVal12 ")<< item->itemArr->name << F(" res:")<< ret << endl;
|
||||
modbusBusy=0;
|
||||
mbusSlenceTimer = millisNZ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
//cosSN(); //0x31 углы между напряжениями фазы и током COSf
|
||||
/////////////////////////COSf по фазам//////////////////////////////////////////////////
|
||||
short out_Mercury::getCurrentVal15(byte param, String topic, int divisor)
|
||||
{
|
||||
if (!item || !item->itemArg || modbusBusy) return RET_INTERROR;
|
||||
|
||||
modbusBusy=1;
|
||||
initLine();
|
||||
|
||||
uint8_t response[15]{};
|
||||
|
||||
response[1]=0x08;
|
||||
response[2]=0x16;
|
||||
response[3]=param;
|
||||
|
||||
uint8_t ret=node.ModbusRawTransaction(response, 4 , sizeof(response));
|
||||
|
||||
if (!ret)
|
||||
{
|
||||
long r = 0;
|
||||
r |= (long)response[1]<<16;
|
||||
r |= (long)response[3]<<8;
|
||||
r |= (long)response[2];
|
||||
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/sum").c_str());
|
||||
|
||||
r = 0;
|
||||
r |= (long)response[4]<<16;
|
||||
r |= (long)response[6]<<8;
|
||||
r |= (long)response[5];
|
||||
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/A").c_str());
|
||||
|
||||
r = 0;
|
||||
r |= (long)response[7]<<16;
|
||||
r |= (long)response[9]<<8;
|
||||
r |= (long)response[8];
|
||||
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/B").c_str());
|
||||
|
||||
r=0;
|
||||
r |= (long)response[10]<<16;
|
||||
r |= (long)response[12]<<8;
|
||||
r |= (long)response[11];
|
||||
|
||||
publishTopic(item->itemArr->name, (float) r/divisor,(topic+"/C").c_str());
|
||||
}
|
||||
debugSerial<<F("Mercury: getCurrentVal15 ")<< item->itemArr->name << F(" res:")<< ret << endl;
|
||||
modbusBusy=0;
|
||||
mbusSlenceTimer = millisNZ();
|
||||
return ret;
|
||||
}
|
||||
|
||||
int out_Mercury::Poll(short cause)
|
||||
{
|
||||
//bool lineInitialized = false;
|
||||
if (cause==POLLING_SLOW) return 0;
|
||||
if (modbusBusy || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100))) return 0;
|
||||
if (!getConfig()) return 0;
|
||||
|
||||
switch (Status())
|
||||
{
|
||||
case CST_INITIALIZED:
|
||||
if (isTimeOver(store->timestamp,millis(),10000UL)) setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
case M_CONNECTING:
|
||||
switch (connectMercury())
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_CONNECTED);
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(CST_FAILED);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case M_CONNECTED:
|
||||
if (isTimeOver(store->lastSuccessTS,millis(),240000UL)) setStatus(CST_INITIALIZED);
|
||||
if (isTimeOver(store->timestamp,millis(),pollingInterval)) setStatus(M_POLLING1);
|
||||
break;
|
||||
|
||||
case M_POLLING1:
|
||||
switch (getCurrentVal12(VOLTAGE,"/voltage",100))
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_POLLING2);
|
||||
store->timestamp=millisNZ();
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
}
|
||||
break;
|
||||
|
||||
case M_POLLING2:
|
||||
switch (getCurrentVal12(CURRENT,"/current",1000))
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_POLLING3);
|
||||
store->timestamp=millisNZ();
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
}
|
||||
break;
|
||||
|
||||
case M_POLLING3:
|
||||
switch (getCurrentVal12(ANGLES,"/angles",100))
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_POLLING4);
|
||||
store->timestamp=millisNZ();
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
}
|
||||
break;
|
||||
|
||||
case M_POLLING4:
|
||||
switch (getCounters(M_NOW,"/counters",1000))
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_POLLING5);
|
||||
store->timestamp=millisNZ();
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
}
|
||||
break;
|
||||
|
||||
case M_POLLING5:
|
||||
switch (getCurrentVal12(M_PWR+1,"/power",100))
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_POLLING6);
|
||||
store->timestamp=millisNZ();
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
}
|
||||
break;
|
||||
case M_POLLING6:
|
||||
switch (getCurrentVal12(M_COSF,"/cosf",1000))
|
||||
{
|
||||
case RET_SUCCESS: setStatus(M_CONNECTED);
|
||||
store->timestamp=millisNZ();
|
||||
store->lastSuccessTS=millisNZ();
|
||||
break;
|
||||
|
||||
case RET_NOT_CONNECTED: setStatus(M_CONNECTING);
|
||||
break;
|
||||
|
||||
default:
|
||||
setStatus(CST_INITIALIZED);
|
||||
}
|
||||
break;
|
||||
}
|
||||
|
||||
return pollingInterval;
|
||||
};
|
||||
|
||||
int out_Mercury::getChanType()
|
||||
{
|
||||
return CH_MBUS;
|
||||
}
|
||||
|
||||
|
||||
|
||||
//!Control unified item
|
||||
int out_Mercury::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
||||
{
|
||||
if (!store) return -1;
|
||||
|
||||
int suffixCode = cmd.getSuffix();
|
||||
int res = -1;
|
||||
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
|
||||
#endif
|
||||
69
lighthub/modules/out_mercury.h
Normal file
69
lighthub/modules/out_mercury.h
Normal file
@@ -0,0 +1,69 @@
|
||||
#pragma once
|
||||
#include "options.h"
|
||||
#ifdef MERCURY_ENABLE
|
||||
#include <abstractout.h>
|
||||
#include <item.h>
|
||||
#include "itemCmd.h"
|
||||
#include <utils.h>
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
|
||||
class mercuryPersistent : public chPersistent {
|
||||
|
||||
public:
|
||||
int8_t driverStatus;
|
||||
uint32_t timestamp;
|
||||
uint32_t lastSuccessTS;
|
||||
};
|
||||
|
||||
#define MB_NEED_SEND 8
|
||||
#define MB_SEND_ERROR 4
|
||||
#define MB_SEND_ATTEMPTS 3
|
||||
|
||||
#define M_CONNECTING 10
|
||||
#define M_CONNECTED 11
|
||||
#define M_POLLING1 12
|
||||
#define M_POLLING2 13
|
||||
#define M_POLLING3 14
|
||||
#define M_POLLING4 15
|
||||
#define M_POLLING5 16
|
||||
#define M_POLLING6 17
|
||||
#define M_POLLING7 18
|
||||
#define M_POLLING8 19
|
||||
|
||||
#define RET_SUCCESS 0
|
||||
#define RET_INVALID_PARAM 1
|
||||
#define RET_INTERROR 2
|
||||
#define RET_ACCESS_LEVEL 3
|
||||
#define RET_RTC_ERR 4
|
||||
#define RET_NOT_CONNECTED 3
|
||||
|
||||
|
||||
class out_Mercury : public abstractOut {
|
||||
public:
|
||||
|
||||
out_Mercury(Item * _item):abstractOut(_item){store = (mercuryPersistent *) item->getPersistent();};
|
||||
int Setup() override;
|
||||
int Poll(short cause) override;
|
||||
int Stop() override;
|
||||
int Status() override;
|
||||
int getChanType() override;
|
||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
||||
int getDefaultStorageType(){return ST_INT32;};
|
||||
|
||||
|
||||
protected:
|
||||
mercuryPersistent * store;
|
||||
uint16_t pollingInterval;
|
||||
bool getConfig();
|
||||
void initLine(bool full = false);
|
||||
void setStatus(short);
|
||||
short connectMercury();
|
||||
short disconnectMercury();
|
||||
short getCurrentVal12(byte param, String topic,int divisor=1);
|
||||
short getCurrentVal15(byte param, String topic,int divisor=1);
|
||||
short getCounters (byte when, String topic,int divisor=1);
|
||||
|
||||
};
|
||||
#endif
|
||||
@@ -15,7 +15,7 @@ extern aJsonObject *modbusObj;
|
||||
extern ModbusMaster node;
|
||||
extern short modbusBusy;
|
||||
extern void modbusIdle(void) ;
|
||||
static uint32_t mbusSlenceTimer = 0;
|
||||
uint32_t mbusSlenceTimer = 0;
|
||||
|
||||
struct reg_t
|
||||
{
|
||||
@@ -97,6 +97,7 @@ serialParamType str2SerialParam(char * str)
|
||||
return static_cast<serialParamType> (SERIAL_8N1);
|
||||
}
|
||||
*/
|
||||
uint16_t swap (uint16_t x) {return ((x & 0xff) << 8) | ((x & 0xff00) >> 8);}
|
||||
|
||||
int str2regSize(char * str)
|
||||
{
|
||||
@@ -231,10 +232,15 @@ return (result == node.ku8MBSuccess);
|
||||
|
||||
|
||||
|
||||
int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uint8_t regType, uint16_t registerFrom, uint16_t registerTo, bool doExecution, bool * submitParam)
|
||||
{
|
||||
aJsonObject * paramObj = store->parameters->child;
|
||||
bool is8bit = false;
|
||||
|
||||
bool tmpSubmitParam;
|
||||
if (!submitParam) submitParam=&tmpSubmitParam;
|
||||
*submitParam=true;
|
||||
|
||||
//bool is8bit = false;
|
||||
while (paramObj)
|
||||
{
|
||||
aJsonObject *regObj=NULL;
|
||||
@@ -248,11 +254,14 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
{
|
||||
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
|
||||
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
||||
aJsonObject *idObj = aJson.getObjectItem(paramObj, "id");
|
||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
uint16_t data = node.getResponseBuffer(posInBuffer);
|
||||
int8_t regType = PAR_I16;
|
||||
uint32_t param =0;
|
||||
itemCmd mappedParam;
|
||||
bool executeWithoutCheck=false; //Afler recurrent check, all dublicatess and suppressing checked by recurrent
|
||||
bool submitRecurrentOut = false; //false if recurrent check find duplicates
|
||||
char buf[16];
|
||||
|
||||
//bool isSigned=false;
|
||||
@@ -271,12 +280,12 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
break;
|
||||
case PAR_I32:
|
||||
//isSigned=true;
|
||||
param = data | (node.getResponseBuffer(posInBuffer+1)<<16);
|
||||
param = swap(data ) | swap(node.getResponseBuffer(posInBuffer+1)<<16);
|
||||
mappedParam.Int((int32_t)param);
|
||||
break;
|
||||
|
||||
case PAR_U32:
|
||||
param = data | (node.getResponseBuffer(posInBuffer+1)<<16);
|
||||
param = swap(data )| swap (node.getResponseBuffer(posInBuffer+1)<<16 );
|
||||
mappedParam.Int((uint32_t)param);
|
||||
break;
|
||||
|
||||
@@ -308,56 +317,98 @@ int out_Modbus::findRegister(int registerNum, int posInBuffer, int regType)
|
||||
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
|
||||
{
|
||||
mappedParam=mappedParam.doReverseMapping(mapObj);
|
||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
if (!mappedParam.isCommand() && !mappedParam.isValue()) //Not mapped
|
||||
{
|
||||
aJsonObject *nextRegObj = NULL;
|
||||
int registerType = 0;
|
||||
|
||||
nextRegObj = aJson.getObjectItem(paramObj, "nextreg");
|
||||
if (nextRegObj) registerType=MODBUS_HOLDING_REG_TYPE;
|
||||
else
|
||||
{
|
||||
nextRegObj = aJson.getObjectItem(paramObj, "nextir");
|
||||
if (nextRegObj) registerType=MODBUS_INPUT_REG_TYPE;
|
||||
}
|
||||
|
||||
if (registerType && (nextRegObj->type) ==aJson_Int && (nextRegObj->valueint>= registerFrom) && (nextRegObj->valueint<=registerTo))
|
||||
{
|
||||
debugSerial<<F("Recurrent searching nextreg")<<endl;
|
||||
mappedParam = findRegister(nextRegObj->valueint,nextRegObj->valueint-registerFrom,registerType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||
executeWithoutCheck=true;
|
||||
}
|
||||
else errorSerial<<F("nextreg out of range")<<endl;
|
||||
}
|
||||
else
|
||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||
} //mapping
|
||||
|
||||
if (doExecution && idObj && idObj->type==aJson_Int)
|
||||
switch (idObj->valueint)
|
||||
{
|
||||
case S_CMD:
|
||||
mappedParam.saveItem(item,FLAG_COMMAND);
|
||||
break;
|
||||
case S_SET:
|
||||
mappedParam.saveItem(item,FLAG_PARAMETERS);
|
||||
}
|
||||
|
||||
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,paramObj->name);
|
||||
if (execObj)
|
||||
{
|
||||
bool submitParam=true;
|
||||
aJsonObject * markObj = execObj;
|
||||
if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||
//Retrive previous data
|
||||
aJsonObject *lastMeasured = aJson.getObjectItem(execObj,"@S");
|
||||
aJsonObject *lastMeasured = aJson.getObjectItem(markObj,"@S");
|
||||
if (lastMeasured)
|
||||
{
|
||||
if (lastMeasured->type == aJson_Int)
|
||||
{
|
||||
if (lastMeasured->valueint == param)
|
||||
submitParam=false; //supress repeating execution for same val
|
||||
*submitParam=false; //supress repeating execution for same val
|
||||
else lastMeasured->valueint=param;
|
||||
}
|
||||
}
|
||||
else //No container to store value yet
|
||||
{
|
||||
debugSerial<<F("MBUS: Add @S: ")<<paramObj->name<<endl;
|
||||
aJson.addNumberToObject(execObj, "@S", (long) param);
|
||||
aJson.addNumberToObject(markObj, "@S", (long) param);
|
||||
}
|
||||
if (submitParam)
|
||||
|
||||
|
||||
if (executeWithoutCheck)
|
||||
{
|
||||
|
||||
if (doExecution && (submitRecurrentOut || *submitParam)) executeCommand(execObj, -1, mappedParam);
|
||||
return mappedParam;
|
||||
}
|
||||
|
||||
if (*submitParam)
|
||||
{
|
||||
//#ifdef MB_SUPPRESS_OUT_EQ_IN
|
||||
// Compare with last submitted val (if @V NOT marked as NULL in config)
|
||||
aJsonObject *settedValue = aJson.getObjectItem(execObj,"@V");
|
||||
aJsonObject *settedValue = aJson.getObjectItem(markObj,"@V");
|
||||
if (settedValue && settedValue->type==aJson_Int && (settedValue->valueint == param))
|
||||
{
|
||||
debugSerial<<F("MBUSD: Ignored - equal with setted val")<<endl;
|
||||
*submitParam=false;
|
||||
}
|
||||
else
|
||||
{
|
||||
executeCommand(execObj, -1, mappedParam);
|
||||
if (doExecution) executeCommand(execObj, -1, mappedParam);
|
||||
// if param updated by device and no new value queued to send - update @V to avoid "Ignored - equal with setted val"
|
||||
if (settedValue && !(execObj->subtype & MB_NEED_SEND))
|
||||
settedValue->valueint=param;
|
||||
}
|
||||
//#endif
|
||||
}
|
||||
}
|
||||
}
|
||||
if (!is8bit) return 1;
|
||||
return mappedParam;
|
||||
}
|
||||
paramObj=paramObj->next;
|
||||
}
|
||||
return is8bit;
|
||||
return itemCmd();
|
||||
}
|
||||
|
||||
|
||||
@@ -376,7 +427,7 @@ return is8bit;
|
||||
//if (readModbus(registerNum,MODBUS_HOLDING_REG_TYPE,1))
|
||||
if (readModbus(registerNum,regType,1))
|
||||
{
|
||||
findRegister(registerNum,0,regType);
|
||||
findRegister(registerNum,0,regType,registerNum,registerNum);
|
||||
// data = node.getResponseBuffer(j);
|
||||
}
|
||||
}
|
||||
@@ -392,7 +443,7 @@ return is8bit;
|
||||
{ debugSerial<<endl;
|
||||
for(int i=registerFrom;i<=registerTo;i++)
|
||||
{
|
||||
findRegister(i,i-registerFrom,regType);
|
||||
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
|
||||
}
|
||||
//data = node.getResponseBuffer(j);
|
||||
}
|
||||
@@ -424,11 +475,14 @@ void out_Modbus::initLine()
|
||||
|
||||
int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
||||
{
|
||||
if (!store) return -1;
|
||||
if (!store) {errorSerial<<F(" internal send error - no store")<<endl; return -1;}
|
||||
|
||||
aJsonObject * templateParamObj = aJson.getObjectItem(store->parameters, paramName);
|
||||
if (!templateParamObj) return -1;
|
||||
if (!templateParamObj) {errorSerial<<F(" internal send error - no template")<<endl; return -1;}
|
||||
|
||||
aJsonObject * regObj = aJson.getObjectItem(templateParamObj, "reg");
|
||||
if (!regObj) return -2;
|
||||
if (!regObj) {errorSerial<<F(" internal send error - no regObj")<<endl; return -2;}
|
||||
|
||||
int res = -1;
|
||||
|
||||
// int8_t regType = PAR_I16;
|
||||
@@ -446,8 +500,8 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
||||
break;
|
||||
case PAR_I32:
|
||||
case PAR_U32:
|
||||
res = node.writeSingleRegister(regObj->valueint,value & 0xFFFF);
|
||||
res += node.writeSingleRegister(regObj->valueint+1,value >> 16) ;
|
||||
res = node.writeSingleRegister(regObj->valueint,swap(value & 0xFFFF));
|
||||
res += node.writeSingleRegister(regObj->valueint+1,swap(value >> 16)) ;
|
||||
break;
|
||||
|
||||
case PAR_U8L:
|
||||
@@ -476,11 +530,16 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = itemParametersObj->child;
|
||||
while (execObj && execObj->type == aJson_Object)
|
||||
while (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array) )
|
||||
{
|
||||
|
||||
if ((execObj->subtype & MB_NEED_SEND) && !(execObj->subtype & MB_SEND_ERROR))
|
||||
{
|
||||
aJsonObject *outValue = aJson.getObjectItem(execObj,"@V");
|
||||
|
||||
aJsonObject * markObj = execObj;
|
||||
if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||
|
||||
aJsonObject *outValue = aJson.getObjectItem(markObj,"@V");
|
||||
if (outValue)
|
||||
{
|
||||
modbusBusy=1;
|
||||
@@ -518,11 +577,11 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenceTimer || isTimeOver(mbusSlenceTimer,millis(),100)))
|
||||
{
|
||||
|
||||
// Clean_up SEND_ERROR flag
|
||||
// Clean_up FLAG_SEND_ERROR flag
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = itemParametersObj->child;
|
||||
while (execObj && execObj->type == aJson_Object)
|
||||
while (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array))
|
||||
{
|
||||
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
||||
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS)
|
||||
@@ -618,7 +677,7 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{
|
||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
||||
if (execObj && execObj->type == aJson_Object)
|
||||
if (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array))
|
||||
{
|
||||
/*
|
||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
||||
@@ -631,7 +690,10 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
{ //Schedule update
|
||||
execObj->subtype |= MB_NEED_SEND;
|
||||
|
||||
aJsonObject *outValue = aJson.getObjectItem(execObj,"@V");
|
||||
aJsonObject * markObj = execObj;
|
||||
if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||
|
||||
aJsonObject *outValue = aJson.getObjectItem(markObj,"@V");
|
||||
if (outValue) // Existant. Preserve original @type
|
||||
{
|
||||
outValue->valueint=Value;
|
||||
@@ -641,12 +703,12 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||
// If no @V in config - creating with INT type - normal behavior - no supress in-to-out
|
||||
{
|
||||
debugSerial<<F("Add @V: ")<<execObj->name<<endl;
|
||||
aJson.addNumberToObject(execObj, "@V", Value);
|
||||
outValue = aJson.getObjectItem(execObj,"@V");
|
||||
aJson.addNumberToObject(markObj, "@V", Value);
|
||||
outValue = aJson.getObjectItem(markObj,"@V");
|
||||
if (outValue) outValue->subtype =regType & 0xF;
|
||||
}
|
||||
|
||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
||||
aJsonObject *polledValue = aJson.getObjectItem(markObj,"@S");
|
||||
if (polledValue && outValue->type == aJson_Int) polledValue->valueint=Value; //to pevent suppressing to change back to previously polled value if this occurs before next polling
|
||||
|
||||
}
|
||||
|
||||
@@ -43,7 +43,7 @@ public:
|
||||
protected:
|
||||
mbPersistent * store;
|
||||
bool getConfig();
|
||||
int findRegister(int registerNum, int posInBuffer, int regType);
|
||||
itemCmd findRegister(uint16_t registerNum, uint16_t posInBuffer, uint8_t regType, uint16_t registerFrom, uint16_t registerTo, bool doExecution = true, bool * submitParam = NULL);
|
||||
void pollModbus(aJsonObject * reg, int regType);
|
||||
void initLine();
|
||||
int sendModbus(char * paramName, int32_t value, uint8_t regType);
|
||||
|
||||
@@ -50,7 +50,7 @@ int out_Motor::Setup()
|
||||
{
|
||||
abstractOut::Setup();
|
||||
getConfig();
|
||||
debugSerial.println("Motor Init");
|
||||
debugSerial.println("Motor: Init");
|
||||
pinMode(pinUp,OUTPUT);
|
||||
pinMode(pinDown,OUTPUT);
|
||||
|
||||
@@ -61,8 +61,8 @@ digitalWrite(pinDown,INACTIVE);
|
||||
|
||||
pinMode(pinFeedback, INPUT);
|
||||
item->setExt(0);
|
||||
item->clearFlag(ACTION_NEEDED);
|
||||
item->clearFlag(ACTION_IN_PROCESS);
|
||||
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||
item->clearFlag(FLAG_ACTION_IN_PROCESS);
|
||||
driverStatus = CST_INITIALIZED;
|
||||
motorQuote = MOTOR_QUOTE;
|
||||
return 1;
|
||||
@@ -70,7 +70,7 @@ return 1;
|
||||
|
||||
int out_Motor::Stop()
|
||||
{
|
||||
debugSerial.println("Motor De-Init");
|
||||
debugSerial.println("Motor: De-Init");
|
||||
digitalWrite(pinUp,INACTIVE);
|
||||
digitalWrite(pinDown,INACTIVE);
|
||||
|
||||
@@ -105,13 +105,13 @@ if (cause==POLLING_SLOW) return 0;
|
||||
int curPos = -1;
|
||||
int targetPos = -1;
|
||||
int dif;
|
||||
if (!item->getFlag(ACTION_NEEDED)) return 0;
|
||||
if (!item->getFlag(FLAG_ACTION_NEEDED)) return 0;
|
||||
|
||||
if (!item->getFlag(ACTION_IN_PROCESS))
|
||||
if (!item->getFlag(FLAG_ACTION_IN_PROCESS))
|
||||
{
|
||||
if (motorQuote)
|
||||
{
|
||||
item->setFlag(ACTION_IN_PROCESS);
|
||||
item->setFlag(FLAG_ACTION_IN_PROCESS);
|
||||
motorQuote--;
|
||||
}
|
||||
else return 0;
|
||||
@@ -145,13 +145,13 @@ if (curPos>255) curPos=255;
|
||||
}
|
||||
|
||||
if (motorOfftime && isTimeOver(motorOfftime,millis(),maxOnTime))
|
||||
{dif = 0; debugSerial<<F("Motor timeout")<<endl;}
|
||||
{dif = 0; debugSerial<<F("Motor: timeout")<<endl;}
|
||||
else if (curPos>=0)
|
||||
dif=targetPos-curPos;
|
||||
else
|
||||
dif=targetPos-255/2; // Have No feedback
|
||||
|
||||
debugSerial<<F("In:")<<pinFeedback<<F(" Val:")<<fb<<F("/")<<curPos<<F("->")<<targetPos<<F(" delta:")<<dif<<endl;
|
||||
debugSerial<<F("Motor: in:")<<pinFeedback<<F(" Val:")<<fb<<F("/")<<curPos<<F("->")<<targetPos<<F(" delta:")<<dif<<endl;
|
||||
|
||||
if (dif<-POS_ERR)
|
||||
{
|
||||
@@ -241,12 +241,12 @@ else
|
||||
|
||||
}
|
||||
else //Target zone
|
||||
{ debugSerial.println("Target");
|
||||
{ debugSerial.println("Motor: Target");
|
||||
digitalWrite(pinUp,INACTIVE);
|
||||
digitalWrite(pinDown,INACTIVE);
|
||||
item->setExt(0);
|
||||
item->clearFlag(ACTION_NEEDED);
|
||||
item->clearFlag(ACTION_IN_PROCESS);
|
||||
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||
item->clearFlag(FLAG_ACTION_IN_PROCESS);
|
||||
motorQuote++;
|
||||
}
|
||||
|
||||
@@ -263,43 +263,25 @@ int out_Motor::getChanType()
|
||||
|
||||
int out_Motor::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
{
|
||||
//int chActive = item->isActive();
|
||||
//bool toExecute = (chActive>0);
|
||||
int suffixCode = cmd.getSuffix();
|
||||
//itemCmd st(ST_PERCENTS,CMD_VOID);
|
||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||
|
||||
item->setFlag(ACTION_NEEDED);
|
||||
item->setFlag(FLAG_ACTION_NEEDED);
|
||||
|
||||
switch(suffixCode)
|
||||
{
|
||||
case S_NOTFOUND:
|
||||
// turn on and set
|
||||
toExecute = true;
|
||||
debugSerial<<F("Forced execution");
|
||||
debugSerial<<F("Motor: Forced execution");
|
||||
case S_SET:
|
||||
//case S_ESET:
|
||||
if (!cmd.isValue()) return 0;
|
||||
// item->setVal(cmd.getPercents());
|
||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
||||
/*
|
||||
st.assignFrom(cmd);
|
||||
//Store
|
||||
st.saveItem(item);
|
||||
if (!suffixCode)
|
||||
{
|
||||
if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF);
|
||||
if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON);
|
||||
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED);
|
||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
||||
}
|
||||
else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
*/
|
||||
return 1;
|
||||
//break;
|
||||
|
||||
case S_CMD:
|
||||
//item->setCmd(cmd.getCmd());
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
@@ -307,7 +289,6 @@ case S_CMD:
|
||||
return 1;
|
||||
|
||||
case CMD_OFF:
|
||||
////item->SendStatus(SEND_COMMAND);
|
||||
if (item->getExt()) item->setExt(millisNZ()); //Extend motor time
|
||||
return 1;
|
||||
|
||||
|
||||
@@ -97,6 +97,7 @@ int out_Multivent::getChanType()
|
||||
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
||||
{
|
||||
|
||||
if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
||||
int suffixCode = cmd.getSuffix();
|
||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||
|
||||
@@ -155,14 +156,14 @@ while (i)
|
||||
case CMD_OFF:
|
||||
cmd.Percents255(0);
|
||||
}
|
||||
if (cmdObj->valueint == CMD_ON && setObj->valueint<20)
|
||||
if (isNotRetainingStatus() && (cmdObj->valueint == CMD_ON) && (setObj->valueint<20))
|
||||
{
|
||||
setObj->valueint=30;
|
||||
cmd.Percents255(30);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_PARAMETERS,i->name);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_COMMAND|SEND_PARAMETERS,i->name);
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_COMMAND|FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
|
||||
else if (setObj && cmdObj && suffixCode == S_FAN && cmd.isValue())
|
||||
@@ -175,7 +176,7 @@ while (i)
|
||||
debugSerial<<"Turning ON"<<endl;
|
||||
cmdObj->valueint = CMD_ON;
|
||||
cmd.Cmd(CMD_ON);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),SEND_COMMAND,i->name);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_ON),FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
setObj->valueint = cmd.getInt();
|
||||
@@ -186,20 +187,20 @@ while (i)
|
||||
{ debugSerial<<"Turning OFF"<<endl;
|
||||
cmdObj->valueint = CMD_OFF;
|
||||
cmd.Cmd(CMD_OFF);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),SEND_COMMAND,i->name);
|
||||
//if (isNotRetainingStatus()) item->SendStatusImmediate(itemCmd().Cmd(CMD_OFF),FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
setObj->valueint = 0;
|
||||
}
|
||||
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_PARAMETERS|SEND_COMMAND,i->name);
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS|FLAG_COMMAND,i->name);
|
||||
}
|
||||
|
||||
else if (setObj && cmd.isValue())
|
||||
{
|
||||
setObj->valueint = cmd.getPercents255();
|
||||
//publishTopic(i->name,setObj->valueint,"/set");
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,SEND_PARAMETERS,i->name);
|
||||
if (isNotRetainingStatus()) item->SendStatusImmediate(cmd,FLAG_PARAMETERS,i->name);
|
||||
}
|
||||
if (cascadeObj) executeCommand(cascadeObj,-1,cmd);
|
||||
}
|
||||
@@ -229,6 +230,9 @@ debugSerial << F("Total V:")<<totalV<<F(" active V:")<<activeV/255<< F(" fan%:")
|
||||
|
||||
executeCommand(aJson.getObjectItem(gatesObj, ""),-1,itemCmd().Percents255(fanV).Cmd((fanV)?CMD_ON:CMD_OFF));
|
||||
|
||||
//Move gates only if fan is actually on
|
||||
if (!fanV) return 1;
|
||||
|
||||
i=NULL;
|
||||
if (gatesObj) i = gatesObj->child; //Pass 2: re-distribute airflow
|
||||
|
||||
@@ -250,8 +254,8 @@ while (i)
|
||||
debugSerial<<i->name<<(" Req:")<<requestedV/255<<F(" Out:")<<out<<endl;
|
||||
}
|
||||
|
||||
// executeCommand(i,-1,itemCmd().Percents255(out));
|
||||
if (out != outObj->valueint)
|
||||
|
||||
if ((out != outObj->valueint))
|
||||
{
|
||||
//report out
|
||||
executeCommand(i,-1,itemCmd().Percents255(out));
|
||||
@@ -262,37 +266,6 @@ while (i)
|
||||
}
|
||||
|
||||
return 1;
|
||||
|
||||
switch(suffixCode)
|
||||
{
|
||||
case S_NOTFOUND:
|
||||
// turn on and set
|
||||
toExecute = true;
|
||||
debugSerial<<F("Forced execution");
|
||||
case S_SET:
|
||||
if (!cmd.isValue()) return 0;
|
||||
|
||||
return 1;
|
||||
//break;
|
||||
|
||||
case S_CMD:
|
||||
//item->setCmd(cmd.getCmd());
|
||||
switch (cmd.getCmd())
|
||||
{
|
||||
case CMD_ON:
|
||||
|
||||
return 1;
|
||||
|
||||
case CMD_OFF:
|
||||
|
||||
return 1;
|
||||
|
||||
} //switch cmd
|
||||
|
||||
break;
|
||||
} //switch suffix
|
||||
debugSerial<<F("Unknown cmd")<<endl;
|
||||
return 0;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
@@ -26,7 +26,7 @@ bool out_pid::getConfig()
|
||||
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
||||
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
||||
{
|
||||
errorSerial<<F("Invalid PID param array.")<<endl;
|
||||
errorSerial<<F("PID: Invalid param array.")<<endl;
|
||||
return false;
|
||||
}
|
||||
double outMin=0.;
|
||||
@@ -103,7 +103,7 @@ bool out_pid::getConfig()
|
||||
if (limits) store->pid->SetOutputLimits(outMin,outMax);
|
||||
store->pid->SetSampleTime(dT*1000.0);
|
||||
return true;}
|
||||
else errorSerial<<F("PID already initialized")<<endl;
|
||||
else errorSerial<<F("PID: already initialized")<<endl;
|
||||
|
||||
return false;
|
||||
}
|
||||
@@ -120,16 +120,16 @@ store->pid=NULL;
|
||||
//store->timestamp=millis();
|
||||
if (getConfig())
|
||||
{
|
||||
infoSerial<<F("PID config loaded ")<< item->itemArr->name<<endl;
|
||||
infoSerial<<F("PID: config loaded ")<< item->itemArr->name<<endl;
|
||||
//item->On(); // Turn ON pid by default
|
||||
// if (item->getCmd()) item->setFlag(SEND_COMMAND);
|
||||
// if (item->itemVal) item->setFlag(SEND_PARAMETERS);
|
||||
// if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||
// if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||
store->prevOut = -2.0;
|
||||
store->driverStatus = CST_INITIALIZED;
|
||||
return 1;
|
||||
}
|
||||
else
|
||||
{ errorSerial<<F("PID config error")<<endl;
|
||||
{ errorSerial<<F("PID: config error")<<endl;
|
||||
store->driverStatus = CST_FAILED;
|
||||
return 0;
|
||||
}
|
||||
@@ -138,7 +138,7 @@ else
|
||||
|
||||
int out_pid::Stop()
|
||||
{
|
||||
debugSerial.println("PID De-Init");
|
||||
debugSerial.println("PID: De-Init");
|
||||
if (store) delete (store->pid);
|
||||
delete store;
|
||||
item->setPersistent(NULL);
|
||||
@@ -164,24 +164,32 @@ int out_pid::Poll(short cause)
|
||||
if (cause==POLLING_SLOW) return 0;
|
||||
if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCmd()!=CMD_OFF))
|
||||
{
|
||||
//double prevOut=store->output;
|
||||
//itemCmd st;
|
||||
//st.loadItem(item);
|
||||
//short cmd = st.getCmd();
|
||||
if (item->getCmd() != CMD_OFF && item->getCmd() != CMD_DISABLE)
|
||||
if (item->getCmd() != CMD_OFF && ! item->getFlag(FLAG_DISABLED))
|
||||
{
|
||||
if(store->pid->Compute() )
|
||||
{
|
||||
int alarmVal;
|
||||
if (store->alarmArmed && (alarmVal=getAlarmVal()>=0)) store->output=alarmVal;
|
||||
debugSerial<<F("PID ")<<item->itemArr->name<<F(" set:")<<store->setpoint<<F(" in:")<<store->input<<(" out:") << store->output <<F(" P:")<<store->pid->GetKp() <<F(" I:")<<store->pid->GetKi() <<F(" D:")<<store->pid->GetKd();
|
||||
if (store->alarmArmed) debugSerial << F(" Alarm");
|
||||
float alarmVal;
|
||||
if (store->alarmArmed && ((alarmVal=getAlarmVal())>=0.)) store->output=alarmVal;
|
||||
|
||||
debugSerial<<F("PID: ")<<item->itemArr->name<<F(" set:")<<store->setpoint<<F(" in:")<<store->input<<(" out:") << store->output <<F(" P:")<<store->pid->GetKp() <<F(" I:")<<store->pid->GetKi() <<F(" D:")<<store->pid->GetKd();
|
||||
//if (item->getFlag(FLAG_DISABLED)) debugSerial << F(" <DIS>");
|
||||
if (store->alarmArmed) debugSerial << F(" <ALM>");
|
||||
debugSerial<<endl;
|
||||
|
||||
if ((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) && !store->alarmArmed)
|
||||
if (((abs(store->output-store->prevOut)>OUTPUT_TRESHOLD) || (item->getFlag(FLAG_ACTION_NEEDED))) && !store->alarmArmed)
|
||||
{
|
||||
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
||||
itemCmd value((float) (store->output));// * (100./255.)));
|
||||
|
||||
if (((store->prevOut == 0.) && (store->output>0)) || item->getFlag(FLAG_ACTION_NEEDED))
|
||||
// if ((item->getFlag(FLAG_ACTION_NEEDED)) && (store->output>0.))
|
||||
{
|
||||
executeCommand(oCmd,-1,itemCmd().Cmd(CMD_ON));
|
||||
// item->clearFlag(FLAG_ACTION_NEEDED);
|
||||
}
|
||||
|
||||
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||
|
||||
itemCmd value((float) (store->output));
|
||||
value.setSuffix(S_SET);
|
||||
executeCommand(oCmd,-1,value);
|
||||
store->prevOut=store->output;
|
||||
@@ -195,19 +203,20 @@ if (store && store->pid && (Status() == CST_INITIALIZED) && item && (item->getCm
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
return 1;//store->pollingInterval;
|
||||
};
|
||||
|
||||
int out_pid::getAlarmVal()
|
||||
float out_pid::getAlarmVal()
|
||||
{
|
||||
aJsonObject * kPIDObj = aJson.getArrayItem(item->itemArg, 0);
|
||||
if (!kPIDObj || kPIDObj->type != aJson_Array)
|
||||
{
|
||||
errorSerial<<F("Invalid PID param array.")<<endl;
|
||||
return -1;
|
||||
errorSerial<<F("PID: Invalid param array.")<<endl;
|
||||
return -1.;
|
||||
}
|
||||
|
||||
int outAlarm=0;
|
||||
float outAlarm=0.;
|
||||
double kP=0.;
|
||||
|
||||
bool alarmValDefined = false;
|
||||
@@ -232,13 +241,14 @@ int out_pid::getAlarmVal()
|
||||
if (param->type == aJson_Float) kP=param->valuefloat;
|
||||
else if (param->type == aJson_Int) kP=param->valueint;
|
||||
{
|
||||
if (kP<0)
|
||||
if (kP<0.)
|
||||
{
|
||||
if (!alarmValDefined) outAlarm = 0.;
|
||||
}
|
||||
else if (!alarmValDefined) outAlarm = 255.;
|
||||
}
|
||||
}
|
||||
// debugSerial<<F("Alarm value: ")<<outAlarm<< " ";
|
||||
return outAlarm;
|
||||
}
|
||||
|
||||
@@ -250,7 +260,7 @@ if (!item || !item->itemArg) return;
|
||||
{
|
||||
float outAlarm=getAlarmVal();
|
||||
errorSerial<<item->itemArr->name<<F(" PID alarm. ")<<endl;
|
||||
if (outAlarm>=0)
|
||||
if (outAlarm>=0.)
|
||||
{
|
||||
errorSerial<<F("Set out to ")<<outAlarm<<endl;
|
||||
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
||||
@@ -289,7 +299,7 @@ case S_VAL:
|
||||
// Input value for PID
|
||||
if (!cmd.isValue()) return 0;
|
||||
store->input=cmd.getFloat();
|
||||
debugSerial<<F("Input value:")<<store->input<<endl;
|
||||
debugSerial<<F("PID: ")<< item->itemArr->name <<F(" Input value:")<<store->input<<endl;
|
||||
|
||||
store->alarmTimer=millis();
|
||||
if (store->alarmArmed)
|
||||
@@ -303,11 +313,11 @@ return 1;
|
||||
|
||||
case S_NOTFOUND:
|
||||
case S_SET:
|
||||
//case S_ESET:
|
||||
|
||||
// Setpoint for PID
|
||||
if (!cmd.isValue()) return 0;
|
||||
store->setpoint=cmd.getFloat();
|
||||
debugSerial<<F("Setpoint:")<<store->setpoint<<endl;
|
||||
debugSerial<<F("PID: ")<< item->itemArr->name <<F(" Setpoint:")<<store->setpoint<<endl;
|
||||
|
||||
{
|
||||
aJsonObject * itemCascadeObj = aJson.getArrayItem(item->itemArg, 2);
|
||||
@@ -315,11 +325,12 @@ if (itemCascadeObj) executeCommand(itemCascadeObj,-1,cmd);
|
||||
}
|
||||
|
||||
//cmd.saveItem(item);
|
||||
//item->SendStatus(SEND_PARAMETERS);
|
||||
//item->SendStatus(FLAG_PARAMETERS);
|
||||
return 1;
|
||||
//break;
|
||||
|
||||
case S_CMD:
|
||||
case S_CTRL:
|
||||
{
|
||||
aJsonObject * oCmd = aJson.getArrayItem(item->itemArg, 1);
|
||||
short command = cmd.getCmd();
|
||||
@@ -338,17 +349,22 @@ case S_CMD:
|
||||
case CMD_DRY:
|
||||
|
||||
executeCommand(oCmd,-1,value);
|
||||
executeCommand(oCmd,-1,itemCmd().Cmd((item->getFlag(FLAG_DISABLED))?CMD_DISABLE:CMD_ENABLE));
|
||||
item->SendStatus(FLAG_FLAGS);
|
||||
return 1;
|
||||
|
||||
case CMD_ENABLE:
|
||||
item->setCmd(CMD_ENABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
//executeCommand(oCmd,-1,value);
|
||||
//item->setCmd(CMD_ENABLE);
|
||||
//item->SendStatus(FLAG_COMMAND);
|
||||
item->setFlag(FLAG_ACTION_NEEDED);
|
||||
executeCommand(oCmd,-1,value);
|
||||
store->prevOut=-2.0;
|
||||
return 1;
|
||||
|
||||
case CMD_DISABLE:
|
||||
item->setCmd(CMD_DISABLE);
|
||||
item->SendStatus(SEND_COMMAND);
|
||||
//executeCommand(oCmd,-1,value);
|
||||
//item->setCmd(CMD_DISABLE);
|
||||
//item->SendStatus(FLAG_COMMAND);
|
||||
executeCommand(oCmd,-1,value);
|
||||
return 1;
|
||||
/*
|
||||
case CMD_OFF:
|
||||
@@ -361,11 +377,11 @@ case S_CMD:
|
||||
} */
|
||||
|
||||
default:
|
||||
debugSerial<<F("Unknown cmd ")<<cmd.getCmd()<<endl;
|
||||
debugSerial<<F("PID: Unknown cmd ")<<cmd.getCmd()<<endl;
|
||||
} //switch cmd
|
||||
}
|
||||
default:
|
||||
debugSerial<<F("Unknown suffix ")<<suffixCode<<endl;
|
||||
debugSerial<<F("PID: Unknown suffix ")<<suffixCode<<endl;
|
||||
} //switch suffix
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -41,6 +41,6 @@ public:
|
||||
protected:
|
||||
pidPersistent * store;
|
||||
bool getConfig();
|
||||
int getAlarmVal();
|
||||
float getAlarmVal();
|
||||
};
|
||||
#endif
|
||||
|
||||
@@ -41,8 +41,8 @@ debugSerial<<F("Relay-Out #")<<pin<<F(" init")<<endl;
|
||||
pinMode(pin, OUTPUT);
|
||||
digitalWrite(pin,INACTIVE);
|
||||
if (item) item->setExt(0);
|
||||
//if (item->getCmd()) item->setFlag(SEND_COMMAND);
|
||||
//if (item->itemVal) item->setFlag(SEND_PARAMETERS);
|
||||
//if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||
//if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||
driverStatus = CST_INITIALIZED;
|
||||
if (item->isActive()>0) ///????
|
||||
{
|
||||
|
||||
@@ -209,9 +209,9 @@ case S_HSV:
|
||||
{
|
||||
if (chActive>0 && !st.getPercents()) item->setCmd(CMD_OFF);
|
||||
if (chActive==0 && st.getPercents()) item->setCmd(CMD_ON);
|
||||
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS | SEND_DEFFERED);
|
||||
item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
}
|
||||
else item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED);
|
||||
else item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||
}
|
||||
return 1;
|
||||
//break;
|
||||
@@ -234,7 +234,7 @@ case S_CMD:
|
||||
|
||||
if (st.getInt() ) //Stored smthng
|
||||
{
|
||||
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS);
|
||||
item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS);
|
||||
debugSerial<<F("Restored: ")<<st.param.h<<F(",")<<st.param.s<<F(",")<<st.param.v<<endl;
|
||||
}
|
||||
else
|
||||
@@ -245,7 +245,7 @@ case S_CMD:
|
||||
// Store
|
||||
//item->setVal(st.getInt());
|
||||
st.saveItem(item);
|
||||
item->SendStatus(SEND_COMMAND | SEND_PARAMETERS );
|
||||
item->SendStatus(SEND_COMMAND | FLAG_PARAMETERS );
|
||||
}
|
||||
|
||||
PixelCtrl(st,from,to);
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
#pragma once
|
||||
#include <Arduino.h>
|
||||
|
||||
|
||||
#define DHCP_ATTEMPTS_FALLBACK 3
|
||||
#define TENS_FRACT_LEN 2
|
||||
#define TENS_BASE 100
|
||||
|
||||
@@ -138,12 +138,22 @@
|
||||
#define MODBUS_SERIAL_BAUD 9600
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_DIMMER_PARAM
|
||||
#define MODBUS_DIMMER_PARAM SERIAL_8N1
|
||||
#ifndef MODBUS_SERIAL_PARAM
|
||||
#define MODBUS_SERIAL_PARAM SERIAL_8N1
|
||||
#endif
|
||||
|
||||
#define dimPar MODBUS_DIMMER_PARAM
|
||||
#define fmPar SERIAL_8N1
|
||||
/*
|
||||
#ifndef MODBUS_TCP_BAUD
|
||||
#define MODBUS_TCP_BAUD 9600
|
||||
#endif
|
||||
|
||||
#ifndef MODBUS_TCP_PARAM
|
||||
#define MODBUS_TCP_PARAM SERIAL_8N1
|
||||
#endif
|
||||
*/
|
||||
|
||||
#define MODBUS_FM_BAUD 9600
|
||||
#define MODBUS_FM_PARAM SERIAL_8N1
|
||||
|
||||
#ifndef SERIAL_BAUD
|
||||
#define SERIAL_BAUD 115200
|
||||
@@ -303,12 +313,14 @@
|
||||
//#ifdef M5STACK
|
||||
//#define debugSerial M5.Lcd
|
||||
//#endif
|
||||
|
||||
#ifndef debugSerialPort
|
||||
#define debugSerialPort Serial
|
||||
#ifdef NOSERIAL
|
||||
#undef debugSerialPort
|
||||
#else
|
||||
#ifndef debugSerialPort
|
||||
#define debugSerialPort Serial
|
||||
#endif
|
||||
#endif
|
||||
|
||||
|
||||
#ifndef Wiz5500
|
||||
#define W5100_ETHERNET_SHIELD
|
||||
#else
|
||||
@@ -344,3 +356,9 @@
|
||||
//#define PINS_COUNT NUM_DIGITAL_PINS
|
||||
#define isAnalogPin(p) ((p >= 14) && (p<=21))
|
||||
#endif
|
||||
|
||||
#ifdef AVR
|
||||
#define minimalMemory 200
|
||||
#else
|
||||
#define minimalMemory 1200
|
||||
#endif
|
||||
@@ -30,7 +30,7 @@ Streamlog::Streamlog (SerialPortType * _serialPort, uint8_t _severity, uint8_t
|
||||
severity=_severity;
|
||||
}
|
||||
#endif
|
||||
|
||||
/*
|
||||
void Streamlog::begin(unsigned long speed)
|
||||
{
|
||||
if (serialPort) serialPort->begin(speed);
|
||||
@@ -40,6 +40,7 @@ void Streamlog::end()
|
||||
{
|
||||
if (serialPort) serialPort->end();
|
||||
};
|
||||
*/
|
||||
|
||||
int Streamlog::available(void)
|
||||
{
|
||||
@@ -79,7 +80,7 @@ if (syslogInitialized && (udpDebugLevel>=severity))
|
||||
}
|
||||
else
|
||||
{
|
||||
if (logBufferPos<LOGBUFFER_SIZE-1 && (ch!='\r')) logBuffer[logBufferPos++]=ch;
|
||||
if ((logBufferPos<LOGBUFFER_SIZE-1) && (ch!='\r')) logBuffer[logBufferPos++]=ch;
|
||||
}
|
||||
}
|
||||
#endif
|
||||
@@ -87,8 +88,8 @@ if (syslogInitialized && (udpDebugLevel>=severity))
|
||||
#if defined (STATUSLED)
|
||||
if ((ch=='\n') && ledPattern) statusLED.flash(ledPattern);
|
||||
#endif
|
||||
|
||||
if (serialPort && (serialDebugLevel>=severity)) return serialPort->write(ch);
|
||||
|
||||
#if !defined(noSerial)
|
||||
if (serialPort && (serialDebugLevel>=severity)) serialPort->write(ch);
|
||||
#endif
|
||||
return 1;
|
||||
};
|
||||
|
||||
@@ -36,8 +36,8 @@ class Streamlog : public Print
|
||||
#else
|
||||
Streamlog (SerialPortType * _serialPort, uint8_t _severity = LOG_DEBUG, uint8_t _ledPattern = 0);
|
||||
#endif
|
||||
void begin(unsigned long speed);
|
||||
void end() ;
|
||||
//void begin(unsigned long speed);
|
||||
//void end() ;
|
||||
|
||||
int available(void);
|
||||
int peek(void);
|
||||
|
||||
@@ -27,7 +27,8 @@ const char EEPROM_signature[] = EEPROM_SIGNATURE;
|
||||
uint8_t notGetConfigFromHTTP:1;
|
||||
uint8_t udpDebugLevel:3;
|
||||
uint8_t notSaveSuccedConfig:1;
|
||||
uint8_t spare2;
|
||||
uint8_t dhcpFallback:1;
|
||||
uint8_t spare2:7;
|
||||
uint16_t sysConfigHash;
|
||||
};
|
||||
} systemConfigFlags;
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user