mirror of
https://github.com/anklimov/lighthub
synced 2025-12-06 11:49:51 +03:00
Compare commits
29 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 90298cd5a3 | |||
| 5719ba209a | |||
| 2e21362fd8 | |||
| fe054c3c4e | |||
| e3d84a1a02 | |||
| ca457a2a05 | |||
| 6d4f76c642 | |||
| 7251e229b6 | |||
|
|
e9355ef142 | ||
|
|
7836876fcd | ||
|
|
8e7bbee96a | ||
|
|
456f6b8ad4 | ||
| c4af5e92f9 | |||
|
|
896a22862f | ||
|
|
83e8639034 | ||
|
|
256ab175ce | ||
| 199a80cbb9 | |||
|
|
9204bd0898 | ||
|
|
df4bf02e8d | ||
|
|
45d925ba88 | ||
| 0a3bbcd7f9 | |||
|
|
1e58ad90eb | ||
| a0ad782257 | |||
| 65556ed39d | |||
| 7bf685a0d4 | |||
|
|
f6a57348eb | ||
|
|
e93e52702e | ||
|
|
6cd4f1d82a | ||
|
|
3907158437 |
22
README.md
22
README.md
@@ -1,5 +1,15 @@
|
|||||||
# LightHub
|
# LightHub
|
||||||
is Flexible, Arduino-Mega/Arduino DUE/ESP8266/ESP32 open-software and open-hardware SmartHome controller. [RU](https://geektimes.ru/post/295109/) [HOME-site RU](http://lazyhome.ru)
|
is Flexible, Arduino-Mega/Arduino DUE/ESP8266/ESP32 open-software and open-hardware SmartHome controller.
|
||||||
|
Useful links:
|
||||||
|
|
||||||
|
* [Article/RU](https://geektimes.ru/post/295109/)
|
||||||
|
|
||||||
|
* [HOME-site/RU](http://lazyhome.ru)
|
||||||
|
|
||||||
|
* [WIKI/RU](https://www.lazyhome.ru/dokuwiki/doku.php?id=start)
|
||||||
|
|
||||||
|
* [Doxigen autodocumentation for developers](https://anklimov.github.io/lighthub/docs/html/index.html) (litle bit outdated)
|
||||||
|
|
||||||
It may operate both:
|
It may operate both:
|
||||||
* On [especially designed hardware board](http://www.lazyhome.ru/index.php/featurerequest) with 16 optocoupled digital inputs, 16 ESD protected digital/analog Inputs/outputs, 8 open-collector outputs (up to 0.5A/50V), DMX IN/OUT, MODBUS RTU and hardware 1-wire support circuit.
|
* On [especially designed hardware board](http://www.lazyhome.ru/index.php/featurerequest) with 16 optocoupled digital inputs, 16 ESD protected digital/analog Inputs/outputs, 8 open-collector outputs (up to 0.5A/50V), DMX IN/OUT, MODBUS RTU and hardware 1-wire support circuit.
|
||||||
* On plain Arduino MEGA 2560, Arduino DUE, ESP8266, ESP32 and even on [Controllino](http://controllino.biz/)
|
* On plain Arduino MEGA 2560, Arduino DUE, ESP8266, ESP32 and even on [Controllino](http://controllino.biz/)
|
||||||
@@ -12,7 +22,7 @@ Lighthub allows connecting together:
|
|||||||
* Temperature/Humidity/CO2 sensors: DHT22, CS811, HDC1080 and any type of Modbus connected devices
|
* Temperature/Humidity/CO2 sensors: DHT22, CS811, HDC1080 and any type of Modbus connected devices
|
||||||
* Standard nonexpensive Relay board with TTL inputs, [like this](http://ali.pub/2zlosh) to control AC powered lamps, floor heaters, boilers etc
|
* Standard nonexpensive Relay board with TTL inputs, [like this](http://ali.pub/2zlosh) to control AC powered lamps, floor heaters, boilers etc
|
||||||
* [Standard nonexpensive LED dimmers](http://ali.pub/2zlokp) and [AC DMX-512 dimmers](http://ali.pub/2zlont)
|
* [Standard nonexpensive LED dimmers](http://ali.pub/2zlokp) and [AC DMX-512 dimmers](http://ali.pub/2zlont)
|
||||||
* Modbus RTU devices (Currently, possible to control two types of Modbus devices: AC Dimmer and Ventilation set (Based on [Vacon 10 controller](http://files.danfoss.com/download/Drives/Vacon-10-Quick-Guide-DPD00714F1-UK.pdf)) and configure polling of virtually any Modbus device.
|
* Modbus RTU devices (Currently, possible to control any type of Modbus devices - e.c dimmers, sensors, wall climate panels, HVAC e.t.c
|
||||||
* Simple DMX wall sensor panel [like this](http://ali.pub/2zlohe)
|
* Simple DMX wall sensor panel [like this](http://ali.pub/2zlohe)
|
||||||
|
|
||||||
[List of non-expensive compatible components from AliExpress here](http://ppv.alipromo.com/custom/promo.php?hash=pjagwaovaero6vkeabjpkpvy4gznbgkc&landing_id=39661)
|
[List of non-expensive compatible components from AliExpress here](http://ppv.alipromo.com/custom/promo.php?hash=pjagwaovaero6vkeabjpkpvy4gznbgkc&landing_id=39661)
|
||||||
@@ -43,14 +53,16 @@ Scalability of Lighthub is virtually unlimited: Setup so many controllers you ne
|
|||||||
|
|
||||||
# Platforms specific details:
|
# Platforms specific details:
|
||||||
|
|
||||||
**AVR** version (Arduino Mega) is basic, long time in production and have all functions
|
**AVR** version (Arduino Mega) is basic, long time in production and have most functions
|
||||||
* DMX-out is software (DMXSimple) on pin3, can be re-defined to PIN 18 (USART1 TX)
|
* DMX-out is software (DMXSimple) on pin3, can be re-defined to PIN 18 (USART1 TX)
|
||||||
* DMX-in - hardware
|
* DMX-in - hardware
|
||||||
* WIZNET 5100 and 5500 Ethernets are supported
|
* WIZNET 5100 and 5500 Ethernets are supported
|
||||||
* Modbus on USART2
|
* Modbus on USART2
|
||||||
|
* Very limited in terms of RAM available
|
||||||
|
* OptiBoot bootloader recommended
|
||||||
|
|
||||||
**SAM3X8E** (Arduino DUE): (Tested. In production. Recomended hardware at current moment)
|
**SAM3X8E** (Arduino DUE): (Tested. In production. Recomended hardware at current moment)
|
||||||
* default PWM out frequency
|
* Reachest funcionality from all possible options
|
||||||
* both, DMX-in and DMX-out are hardware USART based. Use USART1 (pins 18 and 19) for DMX-out and DMX-in
|
* both, DMX-in and DMX-out are hardware USART based. Use USART1 (pins 18 and 19) for DMX-out and DMX-in
|
||||||
* WIZNET 5100 and 5500 Ethernets are supported
|
* WIZNET 5100 and 5500 Ethernets are supported
|
||||||
* Modbus on USART2
|
* Modbus on USART2
|
||||||
@@ -58,7 +70,7 @@ Scalability of Lighthub is virtually unlimited: Setup so many controllers you ne
|
|||||||
**ESP8266, ESP32**: (Tested)
|
**ESP8266, ESP32**: (Tested)
|
||||||
* DMX-OUT on USART1 TX
|
* DMX-OUT on USART1 TX
|
||||||
* DMX-IN - disabled - not possible to deploy in ESP8266
|
* DMX-IN - disabled - not possible to deploy in ESP8266
|
||||||
* Modbus - disabled on ESP8266, Might be configured in future on USART0 instead CLI/DEBUG, on ESP32 binded with UART2
|
* Modbus - disabled on ESP8266, Might be configured on USART0 instead CLI/DEBUG, on ESP32 binded with UART2
|
||||||
* Uses Wifi interface instead wired connection
|
* Uses Wifi interface instead wired connection
|
||||||
|
|
||||||
**NRF52840** : Still early development stage
|
**NRF52840** : Still early development stage
|
||||||
|
|||||||
@@ -16,3 +16,4 @@
|
|||||||
|
|
||||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||||
-DOTA_PORT=80
|
-DOTA_PORT=80
|
||||||
|
-DMERCURY_ENABLE
|
||||||
@@ -5,7 +5,7 @@
|
|||||||
#-DAC_DISABLE
|
#-DAC_DISABLE
|
||||||
-DMODBUS_DISABLE
|
-DMODBUS_DISABLE
|
||||||
#-DMBUS_DISABLE
|
#-DMBUS_DISABLE
|
||||||
-DCOUNTER_DISABLE
|
#-DCOUNTER_DISABLE
|
||||||
-DSYSLOG_ENABLE
|
-DSYSLOG_ENABLE
|
||||||
# - udp errors
|
# - udp errors
|
||||||
-DOTA
|
-DOTA
|
||||||
@@ -57,3 +57,4 @@
|
|||||||
-DMQTT_SOCKET_TIMEOUT=20
|
-DMQTT_SOCKET_TIMEOUT=20
|
||||||
-D CORS=\"*\"
|
-D CORS=\"*\"
|
||||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||||
|
#-DMERCURY_ENABLE
|
||||||
@@ -7,7 +7,6 @@
|
|||||||
-DARTNET_ENABLE
|
-DARTNET_ENABLE
|
||||||
-DUSE_1W_PIN=16
|
-DUSE_1W_PIN=16
|
||||||
-DW5500_CS_PIN=15
|
-DW5500_CS_PIN=15
|
||||||
#-DPID_DISABLE
|
|
||||||
-DARDUINO_OTA_MDNS_DISABLE
|
-DARDUINO_OTA_MDNS_DISABLE
|
||||||
-DMDNS_ENABLE
|
-DMDNS_ENABLE
|
||||||
-DWM_MDNS
|
-DWM_MDNS
|
||||||
@@ -23,3 +22,25 @@
|
|||||||
|
|
||||||
#oct22 - violation in Publish/OnMQTTConnect while publish homie info
|
#oct22 - violation in Publish/OnMQTTConnect while publish homie info
|
||||||
-DNO_HOMIE
|
-DNO_HOMIE
|
||||||
|
|
||||||
|
#options to fit firmware to Sonoff-S26 (uncomment it)
|
||||||
|
|
||||||
|
##Disabling debug log and move I2C to 1-3 pins
|
||||||
|
#-DnoSerial
|
||||||
|
#-D TWI_SCL=1
|
||||||
|
#-D TWI_SDA=3
|
||||||
|
##Slimming firmware to fit 50% of 1m flash
|
||||||
|
-DDMX_DISABLE
|
||||||
|
-UDARTNET_ENABLE
|
||||||
|
-DMODBUS_DISABLE
|
||||||
|
-DMBUS_DISABLE
|
||||||
|
-DOWIRE_DISABLE
|
||||||
|
-DCOUNTER_DISABLE
|
||||||
|
-DAC_DISABLE
|
||||||
|
-DMOTOR_DISABLE
|
||||||
|
-DMULTIVENT_DISABLE
|
||||||
|
-DHSV_DISABLE
|
||||||
|
-UMCP23017
|
||||||
|
-D BEARSSL_SSL_BASIC
|
||||||
|
-D SPILED_DISABLE
|
||||||
|
-D PWM_DISABLE
|
||||||
@@ -38,5 +38,5 @@
|
|||||||
-DOTA_PORT=80
|
-DOTA_PORT=80
|
||||||
-D CORS=\"*\"
|
-D CORS=\"*\"
|
||||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||||
#-D MERCURY_ENABLE
|
-D MERCURY_ENABLE
|
||||||
#-D IPMODBUS
|
#-D IPMODBUS
|
||||||
@@ -6,6 +6,12 @@
|
|||||||
-DARDUINO_OTA_MDNS_DISABLE
|
-DARDUINO_OTA_MDNS_DISABLE
|
||||||
-DMDNS_ENABLE
|
-DMDNS_ENABLE
|
||||||
|
|
||||||
|
-DNO_HOMIE
|
||||||
|
-DCSSHDC_DISABLE
|
||||||
|
-DSPILED_DISABLE
|
||||||
|
-DAC_DISABLE
|
||||||
|
|
||||||
|
|
||||||
-DRESTART_LAN_ON_MQTT_ERRORS
|
-DRESTART_LAN_ON_MQTT_ERRORS
|
||||||
-D CORS=\"*\"
|
-D CORS=\"*\"
|
||||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||||
|
|||||||
@@ -15,6 +15,7 @@
|
|||||||
-DPID_DISABLE
|
-DPID_DISABLE
|
||||||
-DOTA
|
-DOTA
|
||||||
-DMOTOR_DISABLE
|
-DMOTOR_DISABLE
|
||||||
|
-DMULTIVENT_DISABLE
|
||||||
#-DWiz5100
|
#-DWiz5100
|
||||||
-DARDUINO_OTA_MDNS_DISABLE
|
-DARDUINO_OTA_MDNS_DISABLE
|
||||||
-DMDNS_ENABLE
|
-DMDNS_ENABLE
|
||||||
@@ -26,3 +27,4 @@
|
|||||||
# Example of UARTBRIDGE configuration
|
# Example of UARTBRIDGE configuration
|
||||||
#-DUARTBRIDGE_ENABLE
|
#-DUARTBRIDGE_ENABLE
|
||||||
-DOTA_PORT=80
|
-DOTA_PORT=80
|
||||||
|
#-DMERCURY_ENABLE
|
||||||
|
|||||||
@@ -6,14 +6,14 @@
|
|||||||
-DMBUS_DISABLE
|
-DMBUS_DISABLE
|
||||||
#-DOWIRE_DISABLE
|
#-DOWIRE_DISABLE
|
||||||
-DDHT_DISABLE
|
-DDHT_DISABLE
|
||||||
-DCOUNTER_DISABLE
|
#-DCOUNTER_DISABLE
|
||||||
-DNO_HOMIE
|
-DNO_HOMIE
|
||||||
-DCSSHDC_DISABLE
|
-DCSSHDC_DISABLE
|
||||||
-DSPILED_DISABLE
|
-DSPILED_DISABLE
|
||||||
-DAC_DISABLE
|
-DAC_DISABLE
|
||||||
-DSYSLOG_ENABLE
|
-DSYSLOG_ENABLE
|
||||||
-DPID_DISABLE
|
-DPID_DISABLE
|
||||||
-DWiz5100
|
#-DWiz5100
|
||||||
-DMOTOR_DISABLE
|
-DMOTOR_DISABLE
|
||||||
-DOTA
|
-DOTA
|
||||||
-DARDUINO_OTA_MDNS_DISABLE
|
-DARDUINO_OTA_MDNS_DISABLE
|
||||||
@@ -27,4 +27,4 @@
|
|||||||
-DPID_DISABLE
|
-DPID_DISABLE
|
||||||
-DPWM_DISABLE
|
-DPWM_DISABLE
|
||||||
-DSPILED_DISABLE
|
-DSPILED_DISABLE
|
||||||
-DOW_DEVICES_LIMIT=17
|
#-DOW_DEVICES_LIMIT=17
|
||||||
@@ -16,3 +16,4 @@
|
|||||||
|
|
||||||
-D CORS=\"*\"
|
-D CORS=\"*\"
|
||||||
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
|
||||||
|
#-DMERCURY_ENABLE
|
||||||
@@ -37,3 +37,4 @@
|
|||||||
#HAL_ETH_MODULE_DISABLED
|
#HAL_ETH_MODULE_DISABLED
|
||||||
#HAL_SD_MODULE_DISABLED
|
#HAL_SD_MODULE_DISABLED
|
||||||
#HAL_DAC_MODULE_DISABLED
|
#HAL_DAC_MODULE_DISABLED
|
||||||
|
#-DMERCURY_ENABLE
|
||||||
16
compiled/DUE_16u2_reflash/reflash16u2DUE.bat
Normal file
16
compiled/DUE_16u2_reflash/reflash16u2DUE.bat
Normal file
@@ -0,0 +1,16 @@
|
|||||||
|
REM fetch DeviceID of Arduino Port from WMI Service
|
||||||
|
FOR /f "tokens=* skip=1" %%a IN ('wmic PATH Win32_SerialPort Where "Caption LIKE '%%Arduino Uno%%'" 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: =%
|
||||||
|
|
||||||
|
|
||||||
|
..\tools\win\tool-avrdude\avrdude -C ..\tools\win\tool-avrdude\avrdude.conf -c arduino -P %COMPORT% -b 19200 -p m16u2 -vvv -U flash:w:16u2.hex:i
|
||||||
Binary file not shown.
File diff suppressed because it is too large
Load Diff
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.
Binary file not shown.
@@ -1,2 +1,2 @@
|
|||||||
~/.platformio/packages/tool-mkspiffs/mkspiffs_espressif32_arduino -s 20480 -c data data.bin
|
~/.platformio/packages/tool-mkspiffs/mkspiffs_espressif32_arduino -s 20480 -c data data.bin
|
||||||
../tools/mac/arduinoOTA -v -address 192.168.88.50 -port 65280 -username arduino -password password -sketch data.bin -upload /data -b
|
../tools/mac/arduinoOTA -v -address 192.168.88.50 -port 80 -username arduino -password password -sketch data.bin -upload /data -b
|
||||||
@@ -1 +1 @@
|
|||||||
../tools/mac/arduinoOTA -v -address 192.168.88.50 -port 65280 -username arduino -password password -sketch firmware.bin -upload /sketch -b
|
../tools/mac/arduinoOTA -v -address 192.168.11.207 -port 80 -username arduino -password password -sketch firmware.bin -upload /sketch -b
|
||||||
BIN
compiled/esp8266-wifi/esp12-noserial/firmware.bin
Normal file
BIN
compiled/esp8266-wifi/esp12-noserial/firmware.bin
Normal file
Binary file not shown.
31
compiled/esp8266-wifi/esp12-noserial/options.txt
Normal file
31
compiled/esp8266-wifi/esp12-noserial/options.txt
Normal file
@@ -0,0 +1,31 @@
|
|||||||
|
Компактная сборка с набором опций, умещающаяся в 50 процентов flash ESP12
|
||||||
|
CLI и отладочная информация на serial0 отключена для возможности использования PIN0-1
|
||||||
|
|
||||||
|
(-)MULTIVENT
|
||||||
|
(+)PWM_RELAY
|
||||||
|
(+)MDNS
|
||||||
|
(-)UARTBRIDGE
|
||||||
|
(+)SYSLOG
|
||||||
|
(+)PID
|
||||||
|
(-)MCP23017
|
||||||
|
(-)ARTNET
|
||||||
|
(+)OTA
|
||||||
|
(-)SPI LED
|
||||||
|
(-)MOTOR CTR
|
||||||
|
(+)AC HAIER
|
||||||
|
(+)CCS811 & HDC1080
|
||||||
|
(+)RESTART_LAN_ON_MQTT_ERRORS
|
||||||
|
(-)HARDRESET, using soft
|
||||||
|
(-)COUNTER
|
||||||
|
(+)DHT
|
||||||
|
(-)OWIRE
|
||||||
|
(-)IPMODBUS
|
||||||
|
(-)MODBUS
|
||||||
|
(-)DMX
|
||||||
|
(+)WiFi
|
||||||
|
(+)FreeRam printing
|
||||||
|
(+)WATCHDOG
|
||||||
|
|
||||||
|
Config server:lazyhome.ru
|
||||||
|
201703L C++
|
||||||
|
version:e9355ef_2023-10-31
|
||||||
Binary file not shown.
BIN
compiled/esp8266-wifi/full/firmware.bin
Normal file
BIN
compiled/esp8266-wifi/full/firmware.bin
Normal file
Binary file not shown.
32
compiled/esp8266-wifi/full/options.txt
Normal file
32
compiled/esp8266-wifi/full/options.txt
Normal file
@@ -0,0 +1,32 @@
|
|||||||
|
Полная версия прошивки
|
||||||
|
|
||||||
|
(+)MULTIVENT
|
||||||
|
(+)PWM_RELAY
|
||||||
|
(+)MDNS
|
||||||
|
(-)UARTBRIDGE
|
||||||
|
(+)SYSLOG
|
||||||
|
(+)PID
|
||||||
|
(+)MCP23017
|
||||||
|
(+)ARTNET
|
||||||
|
(+)OTA
|
||||||
|
(+)SPI LED
|
||||||
|
(+)MOTOR CTR
|
||||||
|
(+)AC HAIER
|
||||||
|
(+)CCS811 & HDC1080
|
||||||
|
(+)RESTART_LAN_ON_MQTT_ERRORS
|
||||||
|
(-)HARDRESET, using soft
|
||||||
|
(+)COUNTER
|
||||||
|
(+)DHT
|
||||||
|
(-)DS2482-100 USE_1W_PIN
|
||||||
|
(+)OWIRE
|
||||||
|
(-)IPMODBUS
|
||||||
|
(+)MODBUS SERIAL_8N1 at Serial1 speed:9600
|
||||||
|
(+)ADAFRUIT LED
|
||||||
|
(+)DMX
|
||||||
|
(+)WiFi
|
||||||
|
(+)FreeRam printing
|
||||||
|
(+)WATCHDOG
|
||||||
|
|
||||||
|
lazyhome.ru
|
||||||
|
Config server:
|
||||||
|
201703L C++ version:e9355ef_2023-10-31
|
||||||
1
compiled/esp8266-wifi/full/ota.sh
Executable file
1
compiled/esp8266-wifi/full/ota.sh
Executable file
@@ -0,0 +1 @@
|
|||||||
|
../../tools/mac/arduinoOTA -address 192.168.11.208 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin
|
||||||
@@ -1 +1 @@
|
|||||||
arduinoOTA -address 192.168.88.54 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin
|
arduinoOTA -address 192.168.11.208 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin
|
||||||
1
compiled/esp8266-wifi/ota.sh
Executable file
1
compiled/esp8266-wifi/ota.sh
Executable file
@@ -0,0 +1 @@
|
|||||||
|
../tools/mac/arduinoOTA -address 192.168.11.208 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin
|
||||||
1
compiled/lighthub21/ListSerialPorts.bat
Normal file
1
compiled/lighthub21/ListSerialPorts.bat
Normal file
@@ -0,0 +1 @@
|
|||||||
|
wmic PATH Win32_SerialPort get DeviceID
|
||||||
Binary file not shown.
@@ -28,7 +28,7 @@ REM bin file exist?
|
|||||||
IF NOT EXIST "%BINFILE%" GOTO error_binfile
|
IF NOT EXIST "%BINFILE%" GOTO error_binfile
|
||||||
|
|
||||||
REM fetch DeviceID of Arduino Due Programming Port from WMI Service
|
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 '%%USB%%'" get DeviceID') DO (
|
FOR /f "tokens=* skip=1" %%a IN ('wmic PATH Win32_SerialPort Where "Caption LIKE '%%Due%%'" get DeviceID') DO (
|
||||||
SET COMX=%%a
|
SET COMX=%%a
|
||||||
GOTO exit1
|
GOTO exit1
|
||||||
)
|
)
|
||||||
|
|||||||
1
compiled/lighthub21/uploadOTA.BAT
Normal file
1
compiled/lighthub21/uploadOTA.BAT
Normal file
@@ -0,0 +1 @@
|
|||||||
|
..\tools\arduinoOTA -address 192.168.11.204 -port 80 -username arduino -password password -sketch firmware.bin -b -upload /sketch
|
||||||
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
BIN
compiled/mega2560slim/firmware.bin
Executable file
BIN
compiled/mega2560slim/firmware.bin
Executable file
Binary file not shown.
7074
compiled/mega2560slim/firmware.hex
Normal file
7074
compiled/mega2560slim/firmware.hex
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/stm32/firmware.elf
Executable file
BIN
compiled/stm32/firmware.elf
Executable file
Binary file not shown.
9850
compiled/stm32/firmware.map
Normal file
9850
compiled/stm32/firmware.map
Normal file
File diff suppressed because it is too large
Load Diff
0
compiled/tools/arduinoOTA
Normal file → Executable file
0
compiled/tools/arduinoOTA
Normal file → Executable file
@@ -1,8 +1,8 @@
|
|||||||
copy ..\.pio\build\due\firmware.bin due
|
copy ..\.pio\build\due\firmware.bin due
|
||||||
copy ..\.pio\build\controllino\firmware.hex controllino
|
copy ..\.pio\build\controllino\firmware.hex controllino
|
||||||
copy ..\.pio\build\m5stack\firmware.bin m5stack
|
copy ..\.pio\build\m5stack\firmware.bin m5stack
|
||||||
copy ..\.pio\build\mega2560slim-5100\firmware.hex mega2560slim-5100
|
copy ..\.pio\build\mega2560slim\firmware.hex mega2560slim
|
||||||
copy ..\.pio\build\mega2560slim-5100\firmware.bin mega2560slim-5100
|
copy ..\.pio\build\mega2560slim\firmware.bin mega2560slim
|
||||||
copy ..\.pio\build\mega2560slim2\firmware.hex mega2560slim2
|
copy ..\.pio\build\mega2560slim2\firmware.hex mega2560slim2
|
||||||
copy ..\.pio\build\mega2560slim2\firmware.bin mega2560slim2
|
copy ..\.pio\build\mega2560slim2\firmware.bin mega2560slim2
|
||||||
copy ..\.pio\build\due-5100\firmware.bin due-5100
|
copy ..\.pio\build\due-5100\firmware.bin due-5100
|
||||||
|
|||||||
@@ -1,8 +1,8 @@
|
|||||||
cp ../.pio/build/due/firmware.bin due
|
cp ../.pio/build/due/firmware.bin due
|
||||||
cp ../.pio/build/controllino/firmware.hex controllino
|
cp ../.pio/build/controllino/firmware.hex controllino
|
||||||
cp ../.pio/build/m5stack/firmware.bin m5stack
|
cp ../.pio/build/m5stack/firmware.bin m5stack
|
||||||
cp ../.pio/build/mega2560slim-5100/firmware.hex mega2560slim-5100
|
cp ../.pio/build/mega2560slim/firmware.hex mega2560slim
|
||||||
cp ../.pio/build/mega2560slim-5100/firmware.bin mega2560slim-5100
|
cp ../.pio/build/mega2560slim/firmware.bin mega2560slim
|
||||||
cp ../.pio/build/mega2560-optiboot/firmware.hex mega2560-optiboot
|
cp ../.pio/build/mega2560-optiboot/firmware.hex mega2560-optiboot
|
||||||
cp ../.pio/build/mega2560-optiboot/firmware.bin mega2560-optiboot
|
cp ../.pio/build/mega2560-optiboot/firmware.bin mega2560-optiboot
|
||||||
cp ../.pio/build/mega2560-5100/firmware.hex mega2560-5100
|
cp ../.pio/build/mega2560-5100/firmware.hex mega2560-5100
|
||||||
|
|||||||
@@ -2,8 +2,8 @@
|
|||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
|
|
||||||
#define CST_UNKNOWN 0
|
#define CST_UNKNOWN 0
|
||||||
#define CST_INITIALIZED 1
|
#define CST_FAILED 1
|
||||||
#define CST_FAILED -1
|
#define CST_INITIALIZED 2
|
||||||
|
|
||||||
class abstractCh {
|
class abstractCh {
|
||||||
public:
|
public:
|
||||||
@@ -14,6 +14,7 @@ public:
|
|||||||
virtual int Anounce () {return 0;};
|
virtual int Anounce () {return 0;};
|
||||||
virtual int Stop() {return 0;}; //Should free resources
|
virtual int Stop() {return 0;}; //Should free resources
|
||||||
virtual int Status() {return CST_UNKNOWN;}
|
virtual int Status() {return CST_UNKNOWN;}
|
||||||
|
virtual void setStatus(uint8_t status) {}
|
||||||
|
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -1,3 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
#pragma once
|
#pragma once
|
||||||
#include "Arduino.h"
|
#include "Arduino.h"
|
||||||
#include "abstractch.h"
|
#include "abstractch.h"
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
|
|
||||||
|
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "abstractout.h"
|
#include "abstractout.h"
|
||||||
#include "itemCmd.h"
|
#include "itemCmd.h"
|
||||||
@@ -25,3 +26,15 @@ int abstractOut::Setup()
|
|||||||
if (item && (item->getCmd()==-1)) item->setCmd(CMD_OFF);
|
if (item && (item->getCmd()==-1)) item->setCmd(CMD_OFF);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int abstractOut::Status()
|
||||||
|
{
|
||||||
|
if (item && item->itemArr)
|
||||||
|
return item->itemArr->subtype;
|
||||||
|
return CST_UNKNOWN;
|
||||||
|
}
|
||||||
|
|
||||||
|
void abstractOut::setStatus(uint8_t status)
|
||||||
|
{
|
||||||
|
if (item && item->itemArr) item->itemArr->subtype = status & 0xF;
|
||||||
|
}
|
||||||
@@ -8,12 +8,14 @@ class chPersistent {};
|
|||||||
class abstractOut : public abstractCh{
|
class abstractOut : public abstractCh{
|
||||||
public:
|
public:
|
||||||
abstractOut(Item * _item):abstractCh(){item=_item;};
|
abstractOut(Item * _item):abstractCh(){item=_item;};
|
||||||
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) =0;
|
virtual int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) =0;
|
||||||
virtual int isActive();
|
virtual int isActive();
|
||||||
virtual bool isAllowed(itemCmd cmd){return true;};
|
virtual bool isAllowed(itemCmd cmd){return true;};
|
||||||
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
virtual itemCmd getDefaultOnVal(){return itemCmd().Percents255(255);};
|
||||||
virtual int getChanType(){return 0;}
|
virtual int getChanType(){return 0;}
|
||||||
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
virtual int getDefaultStorageType(){return 0;} /// Remove?? Now getChanType used instead
|
||||||
|
virtual int Status() override;
|
||||||
|
virtual void setStatus(uint8_t status) override;
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
protected:
|
protected:
|
||||||
Item * item;
|
Item * item;
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ return val;
|
|||||||
}
|
}
|
||||||
*/
|
*/
|
||||||
|
|
||||||
int colorChannel::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int colorChannel::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authorized)
|
||||||
{
|
{
|
||||||
debugSerial<<F("clrCtr: ");
|
debugSerial<<F("clrCtr: ");
|
||||||
cmd.debugOut();
|
cmd.debugOut();
|
||||||
@@ -60,26 +60,27 @@ toExecute = true;
|
|||||||
case S_SET:
|
case S_SET:
|
||||||
//case S_ESET:
|
//case S_ESET:
|
||||||
case S_HSV:
|
case S_HSV:
|
||||||
PixelCtrl(cmd, subItem, toExecute);
|
PixelCtrl(cmd, subItem, toExecute, authorized);
|
||||||
return 1;
|
return 1;
|
||||||
case S_CMD:
|
case S_CMD:
|
||||||
//item->setCmd(cmd.getCmd());
|
//item->setCmd(cmd.getCmd());
|
||||||
switch (cmd.getCmd())
|
switch (cmd.getCmd())
|
||||||
{
|
{
|
||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
if (vol=cmd.getPercents()<MIN_VOLUME && vol>=0)
|
vol=cmd.getPercents();
|
||||||
|
if (vol<MIN_VOLUME && vol>=0)
|
||||||
{
|
{
|
||||||
cmd.setPercents(INIT_VOLUME);
|
cmd.setPercents(INIT_VOLUME);
|
||||||
cmd.saveItem(item);
|
cmd.saveItem(item);
|
||||||
item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
|
||||||
};
|
};
|
||||||
PixelCtrl(cmd,subItem, true);
|
PixelCtrl(cmd,subItem, true, authorized);
|
||||||
// item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS );
|
// item->SendStatus(FLAG_COMMAND | FLAG_PARAMETERS );
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
case CMD_OFF:
|
case CMD_OFF:
|
||||||
cmd.param.asInt32=0;
|
cmd.param.asInt32=0;
|
||||||
PixelCtrl(cmd, subItem, true);
|
PixelCtrl(cmd, subItem, true,authorized);
|
||||||
// item->SendStatus(FLAG_COMMAND);
|
// item->SendStatus(FLAG_COMMAND);
|
||||||
return 1;
|
return 1;
|
||||||
|
|
||||||
|
|||||||
@@ -14,9 +14,9 @@ public:
|
|||||||
if (iaddr<0) iaddr=-iaddr;
|
if (iaddr<0) iaddr=-iaddr;
|
||||||
numArgs = item->getArgCount(); // and how many addresses is configured
|
numArgs = item->getArgCount(); // and how many addresses is configured
|
||||||
};
|
};
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized=false) override;
|
||||||
int getDefaultStorageType()override;
|
int getDefaultStorageType()override;
|
||||||
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) =0;
|
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) =0;
|
||||||
short getChannelAddr(short n =0);
|
short getChannelAddr(short n =0);
|
||||||
// int isActive() override;
|
// int isActive() override;
|
||||||
protected:
|
protected:
|
||||||
|
|||||||
@@ -44,7 +44,7 @@ bool systemConfig::isValidSysConf()
|
|||||||
bool isMacValid = false;
|
bool isMacValid = false;
|
||||||
for (short i = 0; i < 6; i++) {
|
for (short i = 0; i < 6; i++) {
|
||||||
mac[i] = stream->read();
|
mac[i] = stream->read();
|
||||||
if (mac[i] != 0 && mac[i] != 0xff) isMacValid = true;
|
if ((mac[i] != 0) && (mac[i] != 0xff)) isMacValid = true;
|
||||||
}
|
}
|
||||||
stream->close();
|
stream->close();
|
||||||
return isMacValid;
|
return isMacValid;
|
||||||
@@ -53,7 +53,7 @@ bool systemConfig::isValidSysConf()
|
|||||||
bool systemConfig::setMAC(macAddress& _mac)
|
bool systemConfig::setMAC(macAddress& _mac)
|
||||||
{
|
{
|
||||||
if (!stream || !isValidSysConf()) return false;
|
if (!stream || !isValidSysConf()) return false;
|
||||||
openStream('a');
|
openStream('r'); //was 'a'
|
||||||
stream->seek(offsetof(systemConfigData,mac));
|
stream->seek(offsetof(systemConfigData,mac));
|
||||||
stream->write ((const uint8_t *)&_mac,sizeof(_mac));
|
stream->write ((const uint8_t *)&_mac,sizeof(_mac));
|
||||||
memcpy(mac, _mac, sizeof(mac));
|
memcpy(mac, _mac, sizeof(mac));
|
||||||
|
|||||||
@@ -23,30 +23,13 @@
|
|||||||
|
|
||||||
#if defined(__SAM3X8E__)
|
#if defined(__SAM3X8E__)
|
||||||
#include <DueFlashStorage.h>
|
#include <DueFlashStorage.h>
|
||||||
extern DueFlashStorage EEPROM;
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef NRF5
|
|
||||||
#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__)
|
|
||||||
DueFlashStorage EEPROM;
|
DueFlashStorage EEPROM;
|
||||||
static char samBuffer[64];
|
static char samBuffer[64];
|
||||||
short samBufferPos = 0;
|
short samBufferPos = 0;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#ifdef NRF5
|
#ifdef NRF5
|
||||||
|
#include <NRFFlashStorage.h> //STUB
|
||||||
NRFFlashStorage EEPROM;
|
NRFFlashStorage EEPROM;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -201,7 +184,9 @@ NRFFlashStorage EEPROM;
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
pos=min(_pos, streamSize);
|
pos=min(_pos, streamSize);
|
||||||
//debugSerial<<F("Seek:")<<pos<<endl;
|
//Serial.print("StartPos=");Serial.println(startPos);
|
||||||
|
//Serial.print("Pos=");Serial.println(pos);
|
||||||
|
//Serial.print("streamSize=");Serial.println(streamSize);
|
||||||
return pos;
|
return pos;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -26,6 +26,7 @@ e-mail anklimov@gmail.com
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "bright.h"
|
#include "bright.h"
|
||||||
#include "itemCmd.h"
|
#include "itemCmd.h"
|
||||||
|
//#include "SHA256.h"
|
||||||
|
|
||||||
#ifdef _dmxout
|
#ifdef _dmxout
|
||||||
#include "dmx.h"
|
#include "dmx.h"
|
||||||
@@ -66,7 +67,7 @@ e-mail anklimov@gmail.com
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
short modbusBusy = 0;
|
short modbusBusy = 0;
|
||||||
bool isPendedModbusWrites = false;
|
//bool isPendedModbusWrites = false;
|
||||||
|
|
||||||
extern aJsonObject *pollingItem;
|
extern aJsonObject *pollingItem;
|
||||||
extern PubSubClient mqttClient;
|
extern PubSubClient mqttClient;
|
||||||
@@ -139,7 +140,8 @@ void Item::Parse() {
|
|||||||
for (int i = aJson.getArraySize(itemArr); i < 4; i++)
|
for (int i = aJson.getArraySize(itemArr); i < 4; i++)
|
||||||
aJson.addItemToArray(itemArr, aJson.createNull());//( (long int) 0));
|
aJson.addItemToArray(itemArr, aJson.createNull());//( (long int) 0));
|
||||||
// int(defval[i]) )); //Enlarge item to 4 elements. VAL=int if no other definition in conf
|
// int(defval[i]) )); //Enlarge item to 4 elements. VAL=int if no other definition in conf
|
||||||
itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint;
|
//itemType = aJson.getArrayItem(itemArr, I_TYPE)->valueint;
|
||||||
|
itemType = replaceTypeToInt (aJson.getArrayItem(itemArr, I_TYPE));
|
||||||
itemArg = aJson.getArrayItem(itemArr, I_ARG);
|
itemArg = aJson.getArrayItem(itemArr, I_ARG);
|
||||||
itemVal = aJson.getArrayItem(itemArr, I_VAL);
|
itemVal = aJson.getArrayItem(itemArr, I_VAL);
|
||||||
itemExt = aJson.getArrayItem(itemArr, I_EXT);
|
itemExt = aJson.getArrayItem(itemArr, I_EXT);
|
||||||
@@ -368,21 +370,21 @@ int Item::getArg(short n) //Return arg int or first array element if Arg is arra
|
|||||||
|
|
||||||
float Item::getFloatArg(short n) //Return arg float or first array element if Arg is array
|
float Item::getFloatArg(short n) //Return arg float or first array element if Arg is array
|
||||||
{
|
{
|
||||||
if (!itemArg) return 0;//-1;
|
if (!itemArg) return 0.0;//-1;
|
||||||
if ((itemArg->type == aJson_Array) && ( n < aJson.getArraySize(itemArg)))
|
if ((itemArg->type == aJson_Array) && ( n < aJson.getArraySize(itemArg)))
|
||||||
{
|
{
|
||||||
aJsonObject * obj = aJson.getArrayItem(itemArg, n);
|
aJsonObject * obj = aJson.getArrayItem(itemArg, n);
|
||||||
if (obj && obj->type == aJson_Int) return obj->valueint;
|
if (obj && obj->type == aJson_Int) return static_cast<float> (obj->valueint);
|
||||||
if (obj && obj->type == aJson_Float) return obj->valuefloat;
|
if (obj && obj->type == aJson_Float) return obj->valuefloat;
|
||||||
return 0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
else if (!n)
|
else if (!n)
|
||||||
{
|
{
|
||||||
if (itemArg->type == aJson_Int) return itemArg->valueint;
|
if (itemArg->type == aJson_Int) return static_cast<float>(itemArg->valueint);
|
||||||
else if (itemArg->type == aJson_Float) return itemArg->valuefloat;
|
else if (itemArg->type == aJson_Float) return itemArg->valuefloat;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0.0;
|
||||||
}
|
}
|
||||||
|
|
||||||
short Item::getArgCount()
|
short Item::getArgCount()
|
||||||
@@ -596,12 +598,20 @@ if (suffixCode == S_RAW)
|
|||||||
ic.setSuffix(suffixCode);
|
ic.setSuffix(suffixCode);
|
||||||
return Ctrl(ic,subItem);
|
return Ctrl(ic,subItem);
|
||||||
}
|
}
|
||||||
//debugSerial<<F("SuffixCode: ")<<suffixCode<<endl;
|
|
||||||
|
bool authorized = false;
|
||||||
|
char * authPos = strchr(payload,'@');
|
||||||
|
if (authPos)
|
||||||
|
{
|
||||||
|
*authPos=0;
|
||||||
|
authorized = checkToken(payload,authPos+1);
|
||||||
|
payload=authPos+1;
|
||||||
|
}
|
||||||
|
|
||||||
int i=0;
|
int i=0;
|
||||||
while (payload[i]) {payload[i]=toupper(payload[i]);i++;};
|
while (payload[i]) {payload[i]=toupper(payload[i]);i++;};
|
||||||
|
|
||||||
int cmd = txt2cmd(payload);
|
int cmd = txt2cmd(payload);
|
||||||
//debugSerial<<F("Txt2Cmd:")<<cmd<<endl;
|
|
||||||
|
|
||||||
itemCmd st(ST_VOID,cmd);
|
itemCmd st(ST_VOID,cmd);
|
||||||
|
|
||||||
@@ -660,7 +670,7 @@ st.setSuffix(suffixCode);
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ctrl(st,subItem);
|
return Ctrl(st,subItem,true,authorized);
|
||||||
} //Void command
|
} //Void command
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -684,7 +694,7 @@ st.setSuffix(suffixCode);
|
|||||||
default:;
|
default:;
|
||||||
}
|
}
|
||||||
|
|
||||||
return Ctrl(st,subItem);
|
return Ctrl(st,subItem,true,authorized);
|
||||||
}
|
}
|
||||||
case CMD_UP:
|
case CMD_UP:
|
||||||
case CMD_DN:
|
case CMD_DN:
|
||||||
@@ -692,13 +702,13 @@ st.setSuffix(suffixCode);
|
|||||||
itemCmd Par0 = getNumber((char **) &payload);
|
itemCmd Par0 = getNumber((char **) &payload);
|
||||||
Par0.Cmd(cmd);
|
Par0.Cmd(cmd);
|
||||||
Par0.setSuffix(suffixCode);
|
Par0.setSuffix(suffixCode);
|
||||||
return Ctrl(Par0, subItem);
|
return Ctrl(Par0, subItem,true,authorized);
|
||||||
}
|
}
|
||||||
default: //some known command
|
default: //some known command
|
||||||
{
|
{
|
||||||
int32_t intParam = getInt((char **) &payload);
|
int32_t intParam = getInt((char **) &payload);
|
||||||
if (intParam) st.Int(intParam);
|
if (intParam) st.Int(intParam);
|
||||||
return Ctrl(st, subItem);
|
return Ctrl(st,NULL, true, authorized);
|
||||||
}
|
}
|
||||||
} //ctrl
|
} //ctrl
|
||||||
return 0;
|
return 0;
|
||||||
@@ -707,7 +717,7 @@ return 0;
|
|||||||
// Recursive function with small stack consumption
|
// Recursive function with small stack consumption
|
||||||
// if cmd defined - execute Ctrl for any group members recursively
|
// if cmd defined - execute Ctrl for any group members recursively
|
||||||
// else performs Activity check for group members and return true if any member is active
|
// else performs Activity check for group members and return true if any member is active
|
||||||
bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem)
|
bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem, bool authorized)
|
||||||
{ if (!itemArr || itemArr->type!=aJson_Array) return false;
|
{ if (!itemArr || itemArr->type!=aJson_Array) return false;
|
||||||
// Iterate across array of names
|
// Iterate across array of names
|
||||||
aJsonObject *i = itemArr->child;
|
aJsonObject *i = itemArr->child;
|
||||||
@@ -719,13 +729,13 @@ bool digGroup (aJsonObject *itemArr, itemCmd *cmd, char* subItem)
|
|||||||
if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item
|
if (nextItem && nextItem->type == aJson_Array) //nextItem is correct item
|
||||||
{
|
{
|
||||||
Item it(nextItem);
|
Item it(nextItem);
|
||||||
if (cmd && it.isValid()) it.Ctrl(*cmd,subItem,false); //Execute (non recursive)
|
if (cmd && it.isValid()) it.Ctrl(*cmd,subItem,false,authorized); //Execute (non recursive)
|
||||||
//Retrieve itemType
|
//Retrieve itemType
|
||||||
aJsonObject * itemtype = aJson.getArrayItem(nextItem,0);
|
aJsonObject * itemtype = aJson.getArrayItem(nextItem,0);
|
||||||
if (itemtype && itemtype->type == aJson_Int && itemtype->valueint == CH_GROUP)
|
if (itemtype && itemtype->type == aJson_Int && itemtype->valueint == CH_GROUP)
|
||||||
{ //is Group
|
{ //is Group
|
||||||
aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1);
|
aJsonObject * itemSubArray = aJson.getArrayItem(nextItem,1);
|
||||||
short res = digGroup(itemSubArray,cmd,subItem);
|
short res = digGroup(itemSubArray,cmd,subItem,authorized);
|
||||||
if (!cmd && res)
|
if (!cmd && res)
|
||||||
{
|
{
|
||||||
configLocked--;
|
configLocked--;
|
||||||
@@ -757,40 +767,62 @@ aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Item::scheduleOppositeCommand(itemCmd cmd)
|
int Item::scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized)
|
||||||
{
|
{
|
||||||
itemCmd nextCmd=cmd;
|
itemCmd nextCmd=cmd;
|
||||||
|
|
||||||
switch (cmd.getCmd()){
|
switch (cmd.getCmd()){
|
||||||
case CMD_XON: nextCmd.Cmd(CMD_XOFF);
|
case CMD_XON:
|
||||||
|
if (isActiveNow && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_XOFF);
|
||||||
break;
|
break;
|
||||||
case CMD_XOFF: nextCmd.Cmd(CMD_XON);
|
case CMD_XOFF:
|
||||||
|
if (!isActiveNow && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_XON);
|
||||||
break;
|
break;
|
||||||
case CMD_ON: nextCmd.Cmd(CMD_OFF);
|
case CMD_ON:
|
||||||
|
if (isActiveNow && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_OFF);
|
||||||
break;
|
break;
|
||||||
case CMD_OFF: nextCmd.Cmd(CMD_ON);
|
case CMD_OFF:
|
||||||
|
if (!isActiveNow && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_ON);
|
||||||
break;
|
break;
|
||||||
case CMD_ENABLE: nextCmd.Cmd(CMD_DISABLE);
|
case CMD_ENABLE:
|
||||||
|
if (!getFlag(FLAG_DISABLED) && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_DISABLE);
|
||||||
break;
|
break;
|
||||||
case CMD_DISABLE: nextCmd.Cmd(CMD_ENABLE);
|
case CMD_DISABLE:
|
||||||
|
if (getFlag(FLAG_DISABLED) && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_ENABLE);
|
||||||
break;
|
break;
|
||||||
case CMD_FREEZE: nextCmd.Cmd(CMD_UNFREEZE);
|
case CMD_FREEZE:
|
||||||
|
if (getFlag(FLAG_FREEZED) && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_UNFREEZE);
|
||||||
break;
|
break;
|
||||||
case CMD_UNFREEZE: nextCmd.Cmd(CMD_FREEZE);
|
case CMD_UNFREEZE:
|
||||||
|
if (!getFlag(FLAG_FREEZED) && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_FREEZE);
|
||||||
break;
|
break;
|
||||||
case CMD_HALT: nextCmd.Cmd(CMD_RESTORE);
|
case CMD_HALT:
|
||||||
|
if (!isActiveNow && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_RESTORE);
|
||||||
break;
|
break;
|
||||||
case CMD_RESTORE: nextCmd.Cmd(CMD_HALT);
|
case CMD_RESTORE:
|
||||||
|
if (isActiveNow && !isScheduled()) return 0;
|
||||||
|
nextCmd.Cmd(CMD_HALT);
|
||||||
|
break;
|
||||||
|
case CMD_TOGGLE: nextCmd.Cmd(CMD_TOGGLE);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default: return 0;
|
default: return 0;
|
||||||
}
|
}
|
||||||
debugSerial<<F("CTRL: Schedule cmd ")<<nextCmd.getCmd()<<F(" for (ms):")<<nextCmd.getInt()<<endl;
|
debugSerial<<F("CTRL: Schedule cmd ")<<nextCmd.getCmd()<<F(" for (ms):")<<nextCmd.getInt()<<endl;
|
||||||
scheduleCommand(nextCmd);
|
scheduleCommand(nextCmd,authorized);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int Item::scheduleCommand(itemCmd cmd)
|
int Item::scheduleCommand(itemCmd cmd,bool authorized)
|
||||||
{
|
{
|
||||||
if (!itemArr) return 0;
|
if (!itemArr) return 0;
|
||||||
|
|
||||||
@@ -800,11 +832,12 @@ int Item::scheduleCommand(itemCmd cmd)
|
|||||||
aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
||||||
if (timestampObj && cmd.getCmd()<=0xf)
|
if (timestampObj && cmd.getCmd()<=0xf)
|
||||||
{
|
{
|
||||||
if ((cmd.getInt()>0) && (timestampObj->type == aJson_Int || timestampObj->type == aJson_NULL))
|
if ((cmd.getInt()>0) && (timestampObj->type == aJson_Int || timestampObj->type == aJson_NULL || timestampObj->type == aJson_Reserved))
|
||||||
{
|
{
|
||||||
timestampObj->valueint = millis()+cmd.getInt();
|
timestampObj->valueint = millis()+cmd.getInt();
|
||||||
timestampObj->type = aJson_Int;
|
timestampObj->type = (authorized?aJson_Reserved:aJson_Int);
|
||||||
timestampObj->subtype=cmd.getCmd();
|
timestampObj->subtype=(cmd.getCmd() & 0xF);
|
||||||
|
|
||||||
debugSerial<<F( "Armed for ")<< cmd.getInt() << F(" ms :")<<timestampObj->valueint<<endl;
|
debugSerial<<F( "Armed for ")<< cmd.getInt() << F(" ms :")<<timestampObj->valueint<<endl;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
@@ -824,7 +857,8 @@ int Item::scheduleCommand(itemCmd cmd)
|
|||||||
// -3 ignored
|
// -3 ignored
|
||||||
// -1 system error
|
// -1 system error
|
||||||
// -4 invalid argument
|
// -4 invalid argument
|
||||||
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
// -5 unauthorized
|
||||||
|
int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion, bool authorized)
|
||||||
{
|
{
|
||||||
int fr = freeRam();
|
int fr = freeRam();
|
||||||
if (fr < minimalMemory)
|
if (fr < minimalMemory)
|
||||||
@@ -864,7 +898,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
/// DELAYED COMMANDS processing
|
/// DELAYED COMMANDS processing
|
||||||
if (suffixCode == S_DELAYED)
|
if (suffixCode == S_DELAYED)
|
||||||
{
|
{
|
||||||
return scheduleCommand(cmd);
|
return scheduleCommand(cmd,authorized);
|
||||||
}
|
}
|
||||||
///
|
///
|
||||||
int8_t chActive = -1;
|
int8_t chActive = -1;
|
||||||
@@ -945,6 +979,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CMD_TOGGLE:
|
case CMD_TOGGLE:
|
||||||
|
if (suffixCode != S_CTRL)
|
||||||
|
{
|
||||||
chActive=(isActive()>0);
|
chActive=(isActive()>0);
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
|
|
||||||
@@ -955,6 +991,13 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
cmd.Cmd(CMD_ON);
|
cmd.Cmd(CMD_ON);
|
||||||
}
|
}
|
||||||
status2Send |=FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |=FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
if (getFlag(FLAG_DISABLED)) clearFlag(FLAG_DISABLED); else setFlag(FLAG_DISABLED);
|
||||||
|
status2Send |= FLAG_FLAGS | FLAG_SEND_IMMEDIATE;
|
||||||
|
res=1;
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
|
||||||
@@ -991,14 +1034,14 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
{
|
{
|
||||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||||
cmd.setSuffix(S_SET);
|
cmd.setSuffix(S_SET);
|
||||||
} else {cmd=fallbackCmd;invalidArgument=true;}
|
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
|
||||||
break;
|
break;
|
||||||
case S_SAT:
|
case S_SAT:
|
||||||
if (cmd.incrementS(step))
|
if (cmd.incrementS(step))
|
||||||
{
|
{
|
||||||
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
status2Send |= FLAG_PARAMETERS | FLAG_SEND_DEFFERED;
|
||||||
cmd.setSuffix(S_SET);
|
cmd.setSuffix(S_SET);
|
||||||
} else {cmd=fallbackCmd;invalidArgument=true;}
|
} else {cmd=fallbackCmd;invalidArgument=true; errorSerial << F("Invalid arg")<<endl;}
|
||||||
} //switch suffix
|
} //switch suffix
|
||||||
|
|
||||||
} //Case UP/DOWN
|
} //Case UP/DOWN
|
||||||
@@ -1007,6 +1050,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
if (itemType==CH_GROUP)
|
if (itemType==CH_GROUP)
|
||||||
{
|
{
|
||||||
|
bool scheduledOppositeCommand = false;
|
||||||
if (fr<350)
|
if (fr<350)
|
||||||
{
|
{
|
||||||
errorSerial<<F("CTRL: Not enough memory for group operation")<<endl;
|
errorSerial<<F("CTRL: Not enough memory for group operation")<<endl;
|
||||||
@@ -1015,17 +1059,24 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
if (allowRecursion && itemArg->type == aJson_Array && operation)
|
if (allowRecursion && itemArg->type == aJson_Array && operation)
|
||||||
{
|
{
|
||||||
chActive=(isActive()>0);
|
chActive=(isActive()>0);
|
||||||
digGroup(itemArg,&cmd,subItem);
|
digGroup(itemArg,&cmd,subItem,authorized);
|
||||||
|
|
||||||
|
if ((suffixCode==S_CMD) && cmd.isValue())
|
||||||
|
{
|
||||||
|
scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
|
scheduledOppositeCommand = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
res=1;
|
res=1;
|
||||||
|
|
||||||
|
|
||||||
// Post-processing of group command - converting HALT,REST,XON,XOFF to conventional ON/OFF for status
|
// Post-processing of group command - converting HALT,REST,XON,XOFF to conventional ON/OFF for status
|
||||||
switch (cmd.getCmd()) {
|
switch (cmd.getCmd()) {
|
||||||
int t;
|
int t;
|
||||||
case CMD_RESTORE: // individual for group members
|
case CMD_RESTORE: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_HALT: //previous command was HALT ?
|
case CMD_HALT: //previous command was HALT ?
|
||||||
if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
///if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
|
||||||
debugSerial << F("CTRL: Restored from:") << t << endl;
|
debugSerial << F("CTRL: Restored from:") << t << endl;
|
||||||
cmd.loadItemDef(this);
|
cmd.loadItemDef(this);
|
||||||
cmd.Cmd(CMD_ON); //turning on
|
cmd.Cmd(CMD_ON); //turning on
|
||||||
@@ -1039,7 +1090,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_XOFF: // individual for group members
|
case CMD_XOFF: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_XON: //previous command was CMD_XON ?
|
case CMD_XON: //previous command was CMD_XON ?
|
||||||
if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
///if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
|
||||||
debugSerial << F("CTRL: Turned off from:") << t << endl;
|
debugSerial << F("CTRL: Turned off from:") << t << endl;
|
||||||
cmd.Cmd(CMD_OFF); //turning Off
|
cmd.Cmd(CMD_OFF); //turning Off
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
@@ -1056,7 +1107,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
{
|
{
|
||||||
if (chActive == -1) chActive=(isActive()>0);
|
if (chActive == -1) chActive=(isActive()>0);
|
||||||
|
|
||||||
if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
///if ((suffixCode==S_CMD) && cmd.isValue() && (!chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
|
||||||
|
|
||||||
|
|
||||||
if (!chActive) //if channel was'nt active before CMD_XON
|
if (!chActive) //if channel was'nt active before CMD_XON
|
||||||
@@ -1083,7 +1134,7 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
break;
|
break;
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
if (chActive == -1) chActive=(isActive()>0);
|
if (chActive == -1) chActive=(isActive()>0);
|
||||||
if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd);
|
///if ((suffixCode==S_CMD) && cmd.isValue() && (chActive || isScheduled())) scheduleOppositeCommand(cmd,authorized);
|
||||||
if (chActive) //if channel was active before CMD_HALT /// HERE bug - if cmd == On but 0 = active
|
if (chActive) //if channel was active before CMD_HALT /// HERE bug - if cmd == On but 0 = active
|
||||||
{
|
{
|
||||||
cmd.Cmd(CMD_OFF);
|
cmd.Cmd(CMD_OFF);
|
||||||
@@ -1100,7 +1151,12 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
|
|
||||||
status2Send |= FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_SEND_IMMEDIATE;
|
||||||
if (cmd.isChannelCommand()) status2Send |= FLAG_COMMAND;
|
if (cmd.isChannelCommand()) status2Send |= FLAG_COMMAND;
|
||||||
if (cmd.isValue() || cmd.loadItem(this,FLAG_PARAMETERS)) status2Send |= FLAG_PARAMETERS; ;
|
if (cmd.isValue() || cmd.loadItem(this,FLAG_PARAMETERS)) status2Send |= FLAG_PARAMETERS;
|
||||||
|
|
||||||
|
if (scheduledOppositeCommand) status2Send &=~FLAG_PARAMETERS;
|
||||||
|
|
||||||
|
// UPDATE internal variables for GROUP
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
} // end GROUP
|
} // end GROUP
|
||||||
|
|
||||||
else
|
else
|
||||||
@@ -1126,11 +1182,11 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
}
|
}
|
||||||
else // Fast track for commands to subitems
|
else // Fast track for commands to subitems
|
||||||
{
|
{
|
||||||
if (driver) return driver->Ctrl(cmd,subItem,toExecute);
|
if (driver) return driver->Ctrl(cmd,subItem,toExecute,authorized);
|
||||||
return 0;
|
///// return 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
bool oppositeCommandToBeSchedulled = (suffixCode==S_CMD) && allowRecursion && cmd.isValue();
|
||||||
// Commands for NON GROUP
|
// Commands for NON GROUP
|
||||||
//threating Restore, XOFF (special conditional commands)/ convert to ON, OFF and SET values
|
//threating Restore, XOFF (special conditional commands)/ convert to ON, OFF and SET values
|
||||||
switch (cmd.getCmd()) {
|
switch (cmd.getCmd()) {
|
||||||
@@ -1138,8 +1194,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_RESTORE: // individual for group members
|
case CMD_RESTORE: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_HALT: //previous command was HALT ?
|
case CMD_HALT: //previous command was HALT ?
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
// if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
|
|
||||||
debugSerial << F("CTRL: Restored from:") << t << endl;
|
debugSerial << F("CTRL: Restored from:") << t << endl;
|
||||||
cmd.loadItemDef(this);
|
cmd.loadItemDef(this);
|
||||||
@@ -1156,8 +1212,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_XOFF: // individual for group members
|
case CMD_XOFF: // individual for group members
|
||||||
switch (t = getCmd()) {
|
switch (t = getCmd()) {
|
||||||
case CMD_XON: //previous command was CMD_XON ?
|
case CMD_XON: //previous command was CMD_XON ?
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
debugSerial << F("CTRL: Turned off from:") << t << endl;
|
debugSerial << F("CTRL: Turned off from:") << t << endl;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
cmd.Cmd(CMD_OFF); //turning Off
|
cmd.Cmd(CMD_OFF); //turning Off
|
||||||
@@ -1173,8 +1229,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
case CMD_XON:
|
case CMD_XON:
|
||||||
if (!getFlag(FLAG_DISABLED))
|
if (!getFlag(FLAG_DISABLED))
|
||||||
{
|
{
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
|
|
||||||
if (!chActive) //if channel was'nt active before CMD_XON
|
if (!chActive) //if channel was'nt active before CMD_XON
|
||||||
{
|
{
|
||||||
@@ -1200,8 +1256,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
if (chActive) //if channel was active before CMD_HALT
|
if (chActive) //if channel was active before CMD_HALT
|
||||||
{
|
{
|
||||||
cmd.Cmd(CMD_OFF);
|
cmd.Cmd(CMD_OFF);
|
||||||
@@ -1225,16 +1281,16 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
|
|
||||||
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
|
if (getCmd() == CMD_HALT) return 3; //Halted, ignore OFF
|
||||||
|
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_ON:
|
case CMD_ON:
|
||||||
|
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!chActive || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
|
|
||||||
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
if (!cmd.isChannelCommand()) //Command for driver, not for whole channel
|
||||||
{
|
{
|
||||||
@@ -1276,8 +1332,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
status2Send |= FLAG_FLAGS;
|
status2Send |= FLAG_FLAGS;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
if (allowRecursion && cmd.isValue() && (getFlag(FLAG_DISABLED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if (allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_DISABLE:
|
case CMD_DISABLE:
|
||||||
@@ -1285,8 +1341,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
status2Send |= FLAG_FLAGS;
|
status2Send |= FLAG_FLAGS;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!getFlag(FLAG_DISABLED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_UNFREEZE:
|
case CMD_UNFREEZE:
|
||||||
@@ -1294,8 +1350,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
status2Send = FLAG_FLAGS;
|
status2Send = FLAG_FLAGS;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (getFlag(FLAG_FREEZED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CMD_FREEZE:
|
case CMD_FREEZE:
|
||||||
@@ -1304,8 +1360,8 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
command2Set = 0;
|
command2Set = 0;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
//debugSerial<<F("Disable Flag is:")<<getFlag(FLAG_DISABLED)<<endl;
|
||||||
if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue() && (!getFlag(FLAG_FREEZED) || isScheduled())) //invoked not as group part, delayed, non Active or re-schedule
|
//if ((suffixCode==S_CMD) && allowRecursion && cmd.isValue()) //invoked not as group part, delayed, non Active or re-schedule
|
||||||
scheduleOppositeCommand(cmd);
|
// scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@@ -1313,18 +1369,24 @@ int Item::Ctrl(itemCmd cmd, char* subItem, bool allowRecursion)
|
|||||||
if (cmd.isValue()) status2Send |= FLAG_PARAMETERS;
|
if (cmd.isValue()) status2Send |= FLAG_PARAMETERS;
|
||||||
toExecute=true;
|
toExecute=true;
|
||||||
} //Switch commands
|
} //Switch commands
|
||||||
|
|
||||||
|
if (oppositeCommandToBeSchedulled) //invoked not as group part, delayed
|
||||||
|
{
|
||||||
|
scheduleOppositeCommand(cmd,chActive,authorized);
|
||||||
|
status2Send &=~FLAG_PARAMETERS;
|
||||||
|
}
|
||||||
} // NO GROUP
|
} // NO GROUP
|
||||||
if (invalidArgument) return -4;
|
if (invalidArgument) return -4;
|
||||||
|
|
||||||
if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
||||||
{
|
{
|
||||||
// UPDATE internal variables
|
|
||||||
if (status2Send) cmd.saveItem(this,status2Send);
|
|
||||||
//debugSerial<<F("sts:")<<status2Send<<endl;
|
|
||||||
|
|
||||||
if (driver) //New style modular code
|
if (driver) //New style modular code
|
||||||
{
|
{
|
||||||
res = driver->Ctrl(cmd, subItem, toExecute);
|
// UPDATE internal variables
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
|
|
||||||
|
res = driver->Ctrl(cmd, subItem, toExecute,authorized);
|
||||||
if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE;
|
if (driver->getChanType() == CH_THERMO) status2Send |= FLAG_SEND_IMMEDIATE;
|
||||||
//if (res==-1) status2Send=0; ///////not working
|
//if (res==-1) status2Send=0; ///////not working
|
||||||
if (status2Send & FLAG_FLAGS) res =1; //ENABLE & DISABLE processed by core
|
if (status2Send & FLAG_FLAGS) res =1; //ENABLE & DISABLE processed by core
|
||||||
@@ -1340,6 +1402,10 @@ if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
|||||||
|
|
||||||
short iaddr=getArg();
|
short iaddr=getArg();
|
||||||
short icmd =cmd.getCmd();
|
short icmd =cmd.getCmd();
|
||||||
|
if (!authorized && isProtectedPin(iaddr)) {errorSerial<<F("Unauthorized")<<endl; return -5;}
|
||||||
|
|
||||||
|
// UPDATE internal variables
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
|
|
||||||
if (iaddr)
|
if (iaddr)
|
||||||
{
|
{
|
||||||
@@ -1376,6 +1442,7 @@ if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
|||||||
|
|
||||||
*/
|
*/
|
||||||
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
||||||
|
if (isProtectedPin(iaddr) && !isScheduled()) attachMaturaTimer();
|
||||||
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
status2Send |= FLAG_COMMAND | FLAG_SEND_IMMEDIATE;
|
||||||
res=1;
|
res=1;
|
||||||
}
|
}
|
||||||
@@ -1384,6 +1451,9 @@ if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
|||||||
}
|
}
|
||||||
|
|
||||||
case CH_THERMO:
|
case CH_THERMO:
|
||||||
|
// UPDATE internal variables
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
|
|
||||||
switch (suffixCode)
|
switch (suffixCode)
|
||||||
{
|
{
|
||||||
case S_VAL:
|
case S_VAL:
|
||||||
@@ -1413,6 +1483,9 @@ if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
|||||||
|
|
||||||
#ifndef MODBUS_DISABLE
|
#ifndef MODBUS_DISABLE
|
||||||
case CH_MODBUS:
|
case CH_MODBUS:
|
||||||
|
// UPDATE internal variables
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
|
|
||||||
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue()))
|
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue()))
|
||||||
{
|
{
|
||||||
int vol;
|
int vol;
|
||||||
@@ -1426,9 +1499,13 @@ if ((!driver || driver->isAllowed(cmd)) && (!getFlag(FLAG_FREEZED)))
|
|||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
case CH_VC:
|
case CH_VC:
|
||||||
|
// UPDATE internal variables
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetFan(cmd);
|
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetFan(cmd);
|
||||||
break;
|
break;
|
||||||
case CH_VCTEMP:
|
case CH_VCTEMP:
|
||||||
|
// UPDATE internal variables
|
||||||
|
if (status2Send) cmd.saveItem(this,status2Send);
|
||||||
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetHeat(cmd);
|
if (toExecute && !(chActive && cmd.getCmd()==CMD_ON && !cmd.isValue())) res=VacomSetHeat(cmd);
|
||||||
break;
|
break;
|
||||||
#endif
|
#endif
|
||||||
@@ -1538,12 +1615,15 @@ int Item::isActive() {
|
|||||||
|
|
||||||
int Item::Poll(int cause) {
|
int Item::Poll(int cause) {
|
||||||
|
|
||||||
if (isPendedModbusWrites) resumeModbus();
|
//if (isPendedModbusWrites) resumeModbus();
|
||||||
|
checkRetry();
|
||||||
|
|
||||||
aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
aJsonObject *timestampObj = aJson.getArrayItem(itemArr, I_TIMESTAMP);
|
||||||
if (timestampObj)
|
if (timestampObj)
|
||||||
{
|
{
|
||||||
uint8_t cmd = timestampObj->subtype;
|
uint8_t cmd = timestampObj->subtype & 0xF;
|
||||||
|
bool authorized = (timestampObj->type==aJson_Reserved);
|
||||||
|
|
||||||
int32_t remain = (uint32_t) timestampObj->valueint - (uint32_t)millis();
|
int32_t remain = (uint32_t) timestampObj->valueint - (uint32_t)millis();
|
||||||
|
|
||||||
if (cmd) {
|
if (cmd) {
|
||||||
@@ -1567,9 +1647,9 @@ if (timestampObj)
|
|||||||
errorSerial<<F("CTRL/poll: OutOfMemory: ")<<fr<<endl;
|
errorSerial<<F("CTRL/poll: OutOfMemory: ")<<fr<<endl;
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
Ctrl(itemCmd(ST_VOID,cmd));
|
|
||||||
timestampObj->subtype=0;
|
timestampObj->subtype=0;
|
||||||
|
Ctrl(itemCmd(ST_VOID,cmd),NULL,true,authorized);
|
||||||
|
//timestampObj->subtype=0; ////
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -1856,9 +1936,9 @@ return itemType;
|
|||||||
|
|
||||||
// Setup FLAG_SEND_RETRY flag to repeat unsucsessfull modbus tranzaction after release line
|
// Setup FLAG_SEND_RETRY flag to repeat unsucsessfull modbus tranzaction after release line
|
||||||
void Item::mb_fail(int result) {
|
void Item::mb_fail(int result) {
|
||||||
debugSerial<<F("Modbus op failed:")<<_HEX(result)<<endl;
|
debugSerial<<F("Modbus op ")<<itemArr->name<<F(" failed:")<<_HEX(result)<<endl;
|
||||||
setFlag(FLAG_SEND_RETRY);
|
setFlag(FLAG_SEND_RETRY);
|
||||||
isPendedModbusWrites=true;
|
// isPendedModbusWrites=true;
|
||||||
}
|
}
|
||||||
|
|
||||||
#define M_SUCCESS 1
|
#define M_SUCCESS 1
|
||||||
@@ -1873,26 +1953,40 @@ void Item::mb_fail(int result) {
|
|||||||
//M_BUSY (-1) - Modbus busy
|
//M_BUSY (-1) - Modbus busy
|
||||||
//M_CLEAN (2) - Clean. Not needed to repeat
|
//M_CLEAN (2) - Clean. Not needed to repeat
|
||||||
|
|
||||||
int Item::checkModbusRetry() {
|
int Item::checkRetry() {
|
||||||
int result = -1;
|
int result = -1;
|
||||||
if (modbusBusy) return M_BUSY;
|
|
||||||
if (getFlag(FLAG_SEND_RETRY)) { // if last sending attempt of command was failed
|
if (getFlag(FLAG_SEND_RETRY))
|
||||||
|
{ // if last sending attempt of command was failed
|
||||||
itemCmd val(ST_VOID,CMD_VOID);
|
itemCmd val(ST_VOID,CMD_VOID);
|
||||||
val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
val.loadItem(this, FLAG_COMMAND | FLAG_PARAMETERS);
|
||||||
debugSerial<<F("Retrying modbus CMD\n");
|
|
||||||
|
if (driver)
|
||||||
|
{
|
||||||
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
||||||
if (driver) result=driver->Ctrl(val);
|
debugSerial<<F("Retrying CMD\n");
|
||||||
|
result=driver->Ctrl(val);
|
||||||
|
}
|
||||||
#ifndef MODBUS_DISABLE
|
#ifndef MODBUS_DISABLE
|
||||||
else switch (itemType)
|
else switch (itemType)
|
||||||
{
|
{
|
||||||
|
|
||||||
case CH_MODBUS:
|
case CH_MODBUS:
|
||||||
|
if (modbusBusy) return M_BUSY;
|
||||||
|
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
||||||
|
debugSerial<<F("Retrying modbus CMD\n");
|
||||||
result=modbusDimmerSet(val);
|
result=modbusDimmerSet(val);
|
||||||
break;
|
break;
|
||||||
case CH_VC:
|
case CH_VC:
|
||||||
|
if (modbusBusy) return M_BUSY;
|
||||||
|
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
||||||
|
debugSerial<<F("Retrying VC CMD\n");
|
||||||
result=VacomSetFan(val);
|
result=VacomSetFan(val);
|
||||||
break;
|
break;
|
||||||
case CH_VCTEMP:
|
case CH_VCTEMP:
|
||||||
|
if (modbusBusy) return M_BUSY;
|
||||||
|
clearFlag(FLAG_SEND_RETRY); // Clean retry flag
|
||||||
|
debugSerial<<F("Retrying VCTEMP CMD\n");
|
||||||
result=VacomSetHeat(val);
|
result=VacomSetHeat(val);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
@@ -1912,6 +2006,7 @@ int Item::checkModbusRetry() {
|
|||||||
return M_CLEAN;
|
return M_CLEAN;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
bool Item::resumeModbus()
|
bool Item::resumeModbus()
|
||||||
{
|
{
|
||||||
|
|
||||||
@@ -1941,6 +2036,8 @@ configLocked--;
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
*/
|
||||||
|
|
||||||
//////////////////// Begin of legacy MODBUS code - to be moved in separate module /////////////////////
|
//////////////////// Begin of legacy MODBUS code - to be moved in separate module /////////////////////
|
||||||
|
|
||||||
|
|
||||||
@@ -2035,7 +2132,7 @@ int Item::VacomSetFan(itemCmd st) {
|
|||||||
}
|
}
|
||||||
uint8_t result;
|
uint8_t result;
|
||||||
int addr = getArg();
|
int addr = getArg();
|
||||||
debugSerial<<F("VC#")<<addr<<F("=")<<val<<endl;
|
debugSerial<<F("MB: VC#")<<addr<<F("=")<<val<<endl;
|
||||||
if (modbusBusy) {
|
if (modbusBusy) {
|
||||||
// setCmd(cmd);
|
// setCmd(cmd);
|
||||||
// setVal(val);
|
// setVal(val);
|
||||||
@@ -2055,7 +2152,7 @@ int Item::VacomSetFan(itemCmd st) {
|
|||||||
//node.writeSingleRegister(2001-1,1);
|
//node.writeSingleRegister(2001-1,1);
|
||||||
} else result=node.writeSingleRegister(2001 - 1, 0);
|
} else result=node.writeSingleRegister(2001 - 1, 0);
|
||||||
delay(100);
|
delay(100);
|
||||||
if (result == node.ku8MBSuccess) debugSerial << F("MB ok")<<endl;
|
if (result == node.ku8MBSuccess) debugSerial << F("MB: ok")<<endl;
|
||||||
result = node.writeSingleRegister(2003 - 1, val * 100);
|
result = node.writeSingleRegister(2003 - 1, val * 100);
|
||||||
modbusBusy = 0;
|
modbusBusy = 0;
|
||||||
//resumeModbus();
|
//resumeModbus();
|
||||||
@@ -2068,7 +2165,7 @@ int Item::VacomSetFan(itemCmd st) {
|
|||||||
#define a 0.1842f
|
#define a 0.1842f
|
||||||
#define b -36.68f
|
#define b -36.68f
|
||||||
|
|
||||||
///move to float todo
|
|
||||||
int Item::VacomSetHeat(itemCmd st)
|
int Item::VacomSetHeat(itemCmd st)
|
||||||
{
|
{
|
||||||
float val=st.getFloat();
|
float val=st.getFloat();
|
||||||
@@ -2079,10 +2176,13 @@ int addr;
|
|||||||
if (itemArg->type != aJson_String) return 0;
|
if (itemArg->type != aJson_String) return 0;
|
||||||
|
|
||||||
Item it(itemArg->valuestring);
|
Item it(itemArg->valuestring);
|
||||||
if (it.isValid() && it.itemType == CH_VC) addr=it.getArg();
|
if (it.isValid() && it.itemType == CH_VC)
|
||||||
|
{
|
||||||
|
addr=it.getArg();
|
||||||
|
}
|
||||||
else return 0;
|
else return 0;
|
||||||
|
|
||||||
debugSerial<<F("VC_heat#")<<addr<<F("=")<<val<<F(" cmd=")<<cmd<<endl;
|
debugSerial<<F("MB: VC_heat#")<<addr<<F("=")<<val<<F(" cmd=")<<cmd<<endl;
|
||||||
if (modbusBusy) {
|
if (modbusBusy) {
|
||||||
//setCmd(cmd);
|
//setCmd(cmd);
|
||||||
//setVal(val);
|
//setVal(val);
|
||||||
@@ -2100,17 +2200,18 @@ int addr;
|
|||||||
switch (cmd) {
|
switch (cmd) {
|
||||||
case CMD_OFF:
|
case CMD_OFF:
|
||||||
case CMD_HALT:
|
case CMD_HALT:
|
||||||
|
case CMD_FAN:
|
||||||
regval = 0;
|
regval = 0;
|
||||||
|
it.itemArr->subtype = 0;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
it.itemArr->subtype = 1;
|
||||||
regval = round(( val - b) * 10 / a);
|
regval = round(( val - b) * 10 / a);
|
||||||
}
|
}
|
||||||
|
|
||||||
//debugSerial<<regval);
|
|
||||||
result=node.writeSingleRegister(2004 - 1, regval);
|
result=node.writeSingleRegister(2004 - 1, regval);
|
||||||
modbusBusy = 0;
|
modbusBusy = 0;
|
||||||
//resumeModbus();
|
|
||||||
if (result == node.ku8MBSuccess) return 1;
|
if (result == node.ku8MBSuccess) return 1;
|
||||||
mb_fail(result);
|
mb_fail(result);
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2122,7 +2223,7 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint
|
|||||||
if (_regType != MODBUS_COIL_REG_TYPE || _regType != MODBUS_HOLDING_REG_TYPE) {
|
if (_regType != MODBUS_COIL_REG_TYPE || _regType != MODBUS_HOLDING_REG_TYPE) {
|
||||||
|
|
||||||
}
|
}
|
||||||
|
debugSerial<<F("MB: Addr:")<<addr<<F(" Reg:0x")<<_HEX(_reg)<<F(" T:")<<_regType<<F(" Val:0x")<<_HEX(value)<<endl;
|
||||||
if (modbusBusy) {
|
if (modbusBusy) {
|
||||||
mb_fail();
|
mb_fail();
|
||||||
return 0;
|
return 0;
|
||||||
@@ -2154,7 +2255,7 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint
|
|||||||
|
|
||||||
|
|
||||||
}
|
}
|
||||||
debugSerial<<F("Addr:")<<addr<<F(" Reg:0x")<<_HEX(_reg)<<F(" T:")<<_regType<<F(" Val:0x")<<_HEX(value)<<endl;
|
|
||||||
switch (_regType) {
|
switch (_regType) {
|
||||||
case MODBUS_HOLDING_REG_TYPE:
|
case MODBUS_HOLDING_REG_TYPE:
|
||||||
result = node.writeSingleRegister(_reg, value);
|
result = node.writeSingleRegister(_reg, value);
|
||||||
@@ -2163,7 +2264,7 @@ int Item::modbusDimmerSet(int addr, uint16_t _reg, int _regType, int _mask, uint
|
|||||||
result = node.writeSingleCoil(_reg, value);
|
result = node.writeSingleCoil(_reg, value);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debugSerial<<F("Not supported reg type\n");
|
debugSerial<<F("MB: Not supported reg type\n");
|
||||||
}
|
}
|
||||||
modbusBusy = 0;
|
modbusBusy = 0;
|
||||||
//resumeModbus();
|
//resumeModbus();
|
||||||
@@ -2200,12 +2301,13 @@ int Item::checkFM() {
|
|||||||
modbusSerial.begin(MODBUS_FM_BAUD, MODBUS_FM_PARAM);
|
modbusSerial.begin(MODBUS_FM_BAUD, MODBUS_FM_PARAM);
|
||||||
node.begin(getArg(), modbusSerial);
|
node.begin(getArg(), modbusSerial);
|
||||||
|
|
||||||
|
debugSerial << F("MB: polling FM ") << itemArr->name<< endl;
|
||||||
|
delay(50);
|
||||||
result = node.readHoldingRegisters(2101 - 1, 10);
|
result = node.readHoldingRegisters(2101 - 1, 10);
|
||||||
|
|
||||||
// do something with data if read is successful
|
// do something with data if read is successful
|
||||||
if (result == node.ku8MBSuccess) {
|
if (result == node.ku8MBSuccess) {
|
||||||
debugSerial<<F(" FM Val :");
|
debugSerial<<F("MB: FM Val :");
|
||||||
for (j = 0; j < 10; j++) {
|
for (j = 0; j < 10; j++) {
|
||||||
data = node.getResponseBuffer(j);
|
data = node.getResponseBuffer(j);
|
||||||
debugSerial<<_HEX(data)<<F("-");
|
debugSerial<<_HEX(data)<<F("-");
|
||||||
@@ -2233,10 +2335,12 @@ int Item::checkFM() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
debugSerial << F("Modbus polling error=") << _HEX(result) << endl;
|
debugSerial << F("MB: polling ") << itemArr->name<< F(" error=") << _HEX(result) << endl;
|
||||||
|
|
||||||
if (node.getResponseBuffer(0) & 8) //Active fault
|
if (node.getResponseBuffer(0) & 8) //Active fault
|
||||||
{
|
{
|
||||||
|
debugSerial << F("MB: polling FM fault ") << itemArr->name<< endl;
|
||||||
|
delay(50);
|
||||||
result = node.readHoldingRegisters(2111 - 1, 1);
|
result = node.readHoldingRegisters(2111 - 1, 1);
|
||||||
if (result == node.ku8MBSuccess) aJson.addNumberToObject(out, "flt", (long int) node.getResponseBuffer(0));
|
if (result == node.ku8MBSuccess) aJson.addNumberToObject(out, "flt", (long int) node.getResponseBuffer(0));
|
||||||
modbusBusy=0;
|
modbusBusy=0;
|
||||||
@@ -2246,12 +2350,13 @@ int Item::checkFM() {
|
|||||||
modbusBusy=1;
|
modbusBusy=1;
|
||||||
} else aJson.addNumberToObject(out, "flt", (long int)0);
|
} else aJson.addNumberToObject(out, "flt", (long int)0);
|
||||||
|
|
||||||
|
debugSerial << F("MB: polling PI ") << itemArr->name<< endl;
|
||||||
delay(50);
|
delay(50);
|
||||||
result = node.readHoldingRegisters(20 - 1, 4);
|
result = node.readHoldingRegisters(20 - 1, 4);
|
||||||
|
|
||||||
// do something with data if read is successful
|
// do something with data if read is successful
|
||||||
if (result == node.ku8MBSuccess) {
|
if (result == node.ku8MBSuccess) {
|
||||||
debugSerial << F(" PI Val :");
|
debugSerial << F("MB: PI Val :");
|
||||||
for (j = 0; j < 4; j++) {
|
for (j = 0; j < 4; j++) {
|
||||||
data = node.getResponseBuffer(j);
|
data = node.getResponseBuffer(j);
|
||||||
debugSerial << data << F("-");
|
debugSerial << data << F("-");
|
||||||
@@ -2274,7 +2379,8 @@ int Item::checkFM() {
|
|||||||
Off(); //Shut down
|
Off(); //Shut down
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
debugSerial << F("Modbus polling error=") << _HEX(result);
|
debugSerial << F("MB: polling PI ") << itemArr->name<< F(" error=") << _HEX(result) << endl;
|
||||||
|
|
||||||
outch = aJson.print(out);
|
outch = aJson.print(out);
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
mqttClient.publish(addrstr, outch);
|
mqttClient.publish(addrstr, outch);
|
||||||
@@ -2291,7 +2397,7 @@ int Item::checkModbusDimmer() {
|
|||||||
|
|
||||||
short numpar = 0;
|
short numpar = 0;
|
||||||
if ((itemArg->type != aJson_Array) || ((numpar = aJson.getArraySize(itemArg)) < 2)) {
|
if ((itemArg->type != aJson_Array) || ((numpar = aJson.getArraySize(itemArg)) < 2)) {
|
||||||
debugSerial<<F("Illegal arguments\n");
|
debugSerial<<F("MB: Illegal arguments\n");
|
||||||
return -4;
|
return -4;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -2318,7 +2424,7 @@ int Item::checkModbusDimmer() {
|
|||||||
|
|
||||||
modbusSerial.begin(MODBUS_SERIAL_BAUD, MODBUS_SERIAL_PARAM);
|
modbusSerial.begin(MODBUS_SERIAL_BAUD, MODBUS_SERIAL_PARAM);
|
||||||
node.begin(addr, modbusSerial);
|
node.begin(addr, modbusSerial);
|
||||||
|
debugSerial << F("MB: polling dimmer ") << itemArr->name<< endl;
|
||||||
switch (_regType) {
|
switch (_regType) {
|
||||||
case MODBUS_HOLDING_REG_TYPE:
|
case MODBUS_HOLDING_REG_TYPE:
|
||||||
result = node.readHoldingRegisters(reg, 1);
|
result = node.readHoldingRegisters(reg, 1);
|
||||||
@@ -2333,7 +2439,7 @@ int Item::checkModbusDimmer() {
|
|||||||
result = node.readInputRegisters(reg, 1);
|
result = node.readInputRegisters(reg, 1);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
debugSerial<<F("Not supported reg type\n");
|
debugSerial<<F("MB: Not supported reg type\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (result == node.ku8MBSuccess) {
|
if (result == node.ku8MBSuccess) {
|
||||||
@@ -2351,7 +2457,8 @@ int Item::checkModbusDimmer() {
|
|||||||
pollingItem = items->child;
|
pollingItem = items->child;
|
||||||
}
|
}
|
||||||
} else
|
} else
|
||||||
debugSerial << F("Modbus polling error=") << _HEX(result) << endl;
|
debugSerial << F("MB: polling ") << itemArr->name<< F(" error=") << _HEX(result) << endl;
|
||||||
|
|
||||||
modbusBusy = 0;
|
modbusBusy = 0;
|
||||||
//resumeModbus();
|
//resumeModbus();
|
||||||
|
|
||||||
@@ -2360,6 +2467,8 @@ return 1;
|
|||||||
|
|
||||||
|
|
||||||
int Item::checkModbusDimmer(int data) {
|
int Item::checkModbusDimmer(int data) {
|
||||||
|
if (getFlag(FLAG_SEND_RETRY)) return 0; //Active send transaction
|
||||||
|
|
||||||
short mask = getArg(2);
|
short mask = getArg(2);
|
||||||
itemCmd st;
|
itemCmd st;
|
||||||
|
|
||||||
|
|||||||
@@ -103,7 +103,7 @@ extern aJsonObject *items;
|
|||||||
extern short thermoSetCurTemp(char *name, float t);
|
extern short thermoSetCurTemp(char *name, float t);
|
||||||
|
|
||||||
int txt2cmd (char * payload);
|
int txt2cmd (char * payload);
|
||||||
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL);
|
bool digGroup (aJsonObject *itemArr, itemCmd *cmd = NULL, char* subItem = NULL, bool authorized = false);
|
||||||
class Item
|
class Item
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
@@ -119,7 +119,7 @@ class Item
|
|||||||
boolean Setup();
|
boolean Setup();
|
||||||
void Stop();
|
void Stop();
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL);
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool allowRecursion = true);
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool allowRecursion = true, bool authorized=false);
|
||||||
int Ctrl(char * payload, char * subItem=NULL);
|
int Ctrl(char * payload, char * subItem=NULL);
|
||||||
|
|
||||||
int getArg(short n=0);
|
int getArg(short n=0);
|
||||||
@@ -148,8 +148,8 @@ class Item
|
|||||||
inline int On (){return Ctrl(itemCmd(ST_VOID,CMD_ON));};
|
inline int On (){return Ctrl(itemCmd(ST_VOID,CMD_ON));};
|
||||||
inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
|
inline int Off(){return Ctrl(itemCmd(ST_VOID,CMD_OFF));};
|
||||||
inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
|
inline int Toggle(){return Ctrl(itemCmd(ST_VOID,CMD_TOGGLE));};
|
||||||
int scheduleCommand(itemCmd cmd);
|
int scheduleCommand(itemCmd cmd, bool authorized);
|
||||||
int scheduleOppositeCommand(itemCmd cmd);
|
int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized);
|
||||||
int isScheduled();
|
int isScheduled();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
@@ -164,11 +164,11 @@ class Item
|
|||||||
int checkModbusDimmer();
|
int checkModbusDimmer();
|
||||||
int checkModbusDimmer(int data);
|
int checkModbusDimmer(int data);
|
||||||
|
|
||||||
int checkModbusRetry();
|
int checkRetry();
|
||||||
//boolean checkVCRetry();
|
//boolean checkVCRetry();
|
||||||
//boolean checkHeatRetry();
|
//boolean checkHeatRetry();
|
||||||
void sendDelayedStatus();
|
void sendDelayedStatus();
|
||||||
bool resumeModbus();
|
//bool resumeModbus();
|
||||||
|
|
||||||
|
|
||||||
int checkFM();
|
int checkFM();
|
||||||
|
|||||||
@@ -39,6 +39,20 @@ int txt2cmd(char *payload) {
|
|||||||
return cmd;
|
return cmd;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int type2num(char *payload) {
|
||||||
|
if (!payload || !payload[0]) return -1;
|
||||||
|
|
||||||
|
for(uint8_t i=0; i<ch_typeNum ;i++)
|
||||||
|
if (strncmp_P(payload, ch_type_P[i], strlen_P(ch_type_P[i])) == 0)
|
||||||
|
{
|
||||||
|
return i;
|
||||||
|
}
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
/*!
|
/*!
|
||||||
\brief Constructor with definition of type and command
|
\brief Constructor with definition of type and command
|
||||||
\param type - type of value (ST_???, ST_VOID by default)
|
\param type - type of value (ST_???, ST_VOID by default)
|
||||||
@@ -1180,6 +1194,22 @@ return false;
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int replaceTypeToInt(aJsonObject* verb)
|
||||||
|
{
|
||||||
|
if (verb && verb->type == aJson_String)
|
||||||
|
{
|
||||||
|
int type = type2num(verb->valuestring);
|
||||||
|
if (type>=0)
|
||||||
|
{
|
||||||
|
freeString(verb->valuestring);
|
||||||
|
verb->valueint=type;
|
||||||
|
verb->type=aJson_Int;
|
||||||
|
return verb->valueint;
|
||||||
|
}
|
||||||
|
} else if (verb && verb->type == aJson_Int) return verb->valueint;
|
||||||
|
return -1;
|
||||||
|
}
|
||||||
|
|
||||||
// Mapping from unified itemCmd object to some specific device-depended value
|
// Mapping from unified itemCmd object to some specific device-depended value
|
||||||
itemCmd itemCmd::doMapping(aJsonObject *mappingData)
|
itemCmd itemCmd::doMapping(aJsonObject *mappingData)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -31,8 +31,39 @@ const cmdstr commands_P[] PROGMEM =
|
|||||||
"HIGH","MEDIUM","LOW",
|
"HIGH","MEDIUM","LOW",
|
||||||
"HEAT","COOL","DRY","STOP","RGB","HSV"
|
"HEAT","COOL","DRY","STOP","RGB","HSV"
|
||||||
};
|
};
|
||||||
|
|
||||||
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
#define commandsNum sizeof(commands_P)/sizeof(cmdstr)
|
||||||
|
|
||||||
|
typedef char ch_type[9];
|
||||||
|
const ch_type ch_type_P[] PROGMEM =
|
||||||
|
{
|
||||||
|
"DMX", // 0 //DMX 1-4 ch
|
||||||
|
"DMXRGBW",// 1 //DMX 4 ch
|
||||||
|
"DMXRGB", // 2 //DMX 3 ch
|
||||||
|
"PWM", // 3 //PWM output directly to PIN 1-4 CH
|
||||||
|
"MBUSDIM",// 4 //Modbus AC Dimmer
|
||||||
|
"THERMO", // 5 //Simple ON/OFF thermostat
|
||||||
|
"RELAY", // 6 //ON_OFF relay output
|
||||||
|
"GROUP", // 7 //Group pseudochannel
|
||||||
|
"VCTEMP", // 8 //Vacom PID regulator
|
||||||
|
"MBUSVC", // 9 //Vacom modbus motor regulator
|
||||||
|
"ACHAIER",// 10 //AC Haier
|
||||||
|
"SPILED", // 11 //SPI led strip
|
||||||
|
"MOTOR", // 12 //Motorized gate with feedback resistor
|
||||||
|
"PID", // 13 //PID regulator
|
||||||
|
"MBUS", // 14 //Universal Modbus Master channel
|
||||||
|
"UARTBRDG", // 15 //Bridge between 2 UARTS with reporting PDUs to Wireshark via UDP
|
||||||
|
"RELAYPWM", // 16 //Slow PWM relay to control objects with inertia
|
||||||
|
"DMXRGBWW", // 17 //DMX RGBWW channel (warm&cold white)
|
||||||
|
"VENTS", // 18 //Multichannel ventilation
|
||||||
|
"ELEVATOR", // 19 //
|
||||||
|
"COUNTER", // 20 //Generic counter
|
||||||
|
"HUM", // 21 //Humidifier
|
||||||
|
"MERCURY" // 22 //Mercury energy meter/RS485 interface
|
||||||
|
};
|
||||||
|
|
||||||
|
#define ch_typeNum sizeof(ch_type_P)/sizeof(ch_type)
|
||||||
|
|
||||||
/// Definition of Commands
|
/// Definition of Commands
|
||||||
#define CMD_ON 1 /// Turn channel ON
|
#define CMD_ON 1 /// Turn channel ON
|
||||||
#define CMD_OFF 2 /// Turn channel OFF
|
#define CMD_OFF 2 /// Turn channel OFF
|
||||||
@@ -46,8 +77,8 @@ const cmdstr commands_P[] PROGMEM =
|
|||||||
|
|
||||||
#define CMD_ENABLE 0xa /// for PID regulator and XON/XOFF - chan limitation
|
#define CMD_ENABLE 0xa /// for PID regulator and XON/XOFF - chan limitation
|
||||||
#define CMD_DISABLE 0xb /// for PID regulator
|
#define CMD_DISABLE 0xb /// for PID regulator
|
||||||
#define CMD_UNFREEZE 0xc /// Aliase for ON
|
#define CMD_UNFREEZE 0xc ///
|
||||||
#define CMD_FREEZE 0xd /// Aliase for OFF
|
#define CMD_FREEZE 0xd ///
|
||||||
|
|
||||||
#define CMD_AUTO 0xe /// Thermostat/AC set to Auto mode
|
#define CMD_AUTO 0xe /// Thermostat/AC set to Auto mode
|
||||||
#define CMD_FAN 0xf /// AC set to Fan-only mode
|
#define CMD_FAN 0xf /// AC set to Fan-only mode
|
||||||
@@ -241,4 +272,5 @@ public:
|
|||||||
|
|
||||||
};
|
};
|
||||||
|
|
||||||
|
int replaceTypeToInt(aJsonObject* verb);
|
||||||
#pragma pack(pop)
|
#pragma pack(pop)
|
||||||
|
|||||||
@@ -27,6 +27,9 @@ e-mail anklimov@gmail.com
|
|||||||
#include "TimerInterrupt_Generic.h"
|
#include "TimerInterrupt_Generic.h"
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
#include "RNG.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifdef SYSLOG_ENABLE
|
#ifdef SYSLOG_ENABLE
|
||||||
#include <Syslog.h>
|
#include <Syslog.h>
|
||||||
@@ -95,6 +98,10 @@ lan_status lanStatus = INITIAL_STATE;
|
|||||||
const char configserver[] PROGMEM = CONFIG_SERVER;
|
const char configserver[] PROGMEM = CONFIG_SERVER;
|
||||||
const char verval_P[] PROGMEM = QUOTE(PIO_SRC_REV);
|
const char verval_P[] PROGMEM = QUOTE(PIO_SRC_REV);
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
char cryptoKey[] = QUOTE(SHAREDSECRET);
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(__SAM3X8E__)
|
#if defined(__SAM3X8E__)
|
||||||
UID UniqueID;
|
UID UniqueID;
|
||||||
#endif
|
#endif
|
||||||
@@ -132,6 +139,8 @@ volatile uint32_t timerSensorCheck =0;
|
|||||||
volatile unsigned long timerCount=0;
|
volatile unsigned long timerCount=0;
|
||||||
volatile int16_t timerNumber=-1;
|
volatile int16_t timerNumber=-1;
|
||||||
volatile int8_t timerHandlerBusy=0;
|
volatile int8_t timerHandlerBusy=0;
|
||||||
|
volatile uint32_t cryptoSalt=0;
|
||||||
|
//uint32_t timerCtr=0;
|
||||||
|
|
||||||
aJsonObject *pollingItem = NULL;
|
aJsonObject *pollingItem = NULL;
|
||||||
|
|
||||||
@@ -157,10 +166,12 @@ int8_t mqttErrorRate=0;
|
|||||||
void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE
|
void watchdogSetup(void) {} //Do not remove - strong re-definition WDT Init for DUE
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
bool cleanConf()
|
bool cleanConf(bool wait)
|
||||||
{
|
{
|
||||||
if (!root) return true;
|
if (!root) return true;
|
||||||
bool clean = true;
|
bool clean = true;
|
||||||
|
if (wait)
|
||||||
|
{
|
||||||
debugSerial<<F("Unlocking config ...")<<endl;
|
debugSerial<<F("Unlocking config ...")<<endl;
|
||||||
uint32_t stamp=millis();
|
uint32_t stamp=millis();
|
||||||
while (configLocked && !isTimeOver(stamp,millis(),10000))
|
while (configLocked && !isTimeOver(stamp,millis(),10000))
|
||||||
@@ -184,6 +195,7 @@ if (configLocked)
|
|||||||
errorSerial<<F("Not unlocked in 10s - continue ...")<<endl;
|
errorSerial<<F("Not unlocked in 10s - continue ...")<<endl;
|
||||||
clean = false;
|
clean = false;
|
||||||
}
|
}
|
||||||
|
} //wait
|
||||||
|
|
||||||
debugSerial<<F("Stopping channels ...")<<endl;
|
debugSerial<<F("Stopping channels ...")<<endl;
|
||||||
timerHandlerBusy++;
|
timerHandlerBusy++;
|
||||||
@@ -193,9 +205,7 @@ if (items)
|
|||||||
aJsonObject * item = items->child;
|
aJsonObject * item = items->child;
|
||||||
while (item)
|
while (item)
|
||||||
{
|
{
|
||||||
if (item->type == aJson_Array && aJson.getArraySize(item)>0)
|
if (item->type == aJson_Array && (aJson.getArraySize(item)>0))
|
||||||
{
|
|
||||||
if (item->type == aJson_Array && aJson.getArraySize(item)>0)
|
|
||||||
{
|
{
|
||||||
Item it(item->name);
|
Item it(item->name);
|
||||||
if (it.isValid()) it.Stop();
|
if (it.isValid()) it.Stop();
|
||||||
@@ -204,8 +214,7 @@ aJsonObject * item = items->child;
|
|||||||
}
|
}
|
||||||
item = item->next;
|
item = item->next;
|
||||||
}
|
}
|
||||||
}
|
} else debugSerial<<F("nothing to stop")<<endl;
|
||||||
}
|
|
||||||
pollingItem = NULL;
|
pollingItem = NULL;
|
||||||
debugSerial<<F("Stopped")<<endl;
|
debugSerial<<F("Stopped")<<endl;
|
||||||
delay(100);
|
delay(100);
|
||||||
@@ -681,6 +690,12 @@ lan_status lanLoop() {
|
|||||||
|
|
||||||
onMQTTConnect();
|
onMQTTConnect();
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
//setTopic(buf,sizeof(buf),T_OUT);
|
||||||
|
strncpy(buf, "+/+/$salt", sizeof(buf)); // Only on separated cmd/val topics
|
||||||
|
mqttClient.subscribe(buf);
|
||||||
|
#endif
|
||||||
|
|
||||||
lanStatus = OPERATION;//3;
|
lanStatus = OPERATION;//3;
|
||||||
infoSerial<<F("Accepting commands...\n");
|
infoSerial<<F("Accepting commands...\n");
|
||||||
}
|
}
|
||||||
@@ -733,21 +748,18 @@ lan_status lanLoop() {
|
|||||||
lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2;
|
lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DO_READ_RE_CONFIG: // Pause and re-read EEPROM
|
case DO_READ_RE_CONFIG:
|
||||||
timerLanCheckTime = millis();
|
timerLanCheckTime = millis();
|
||||||
lanStatus = READ_RE_CONFIG;
|
lanStatus=READ_RE_CONFIG;
|
||||||
//statusLED.set(ledRED|((configLoaded)?ledBLINK:0));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
|
case READ_RE_CONFIG: // Restore config from FLASH, re-init LAN
|
||||||
if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_REINIT))
|
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;
|
||||||
|
else
|
||||||
|
if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RELOAD))
|
||||||
{
|
{
|
||||||
debugSerial<<F("Restoring config from EEPROM")<<endl;
|
errorSerial<<F("30s EEPROM is not reloaded. Reboot");
|
||||||
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2;
|
softRebootFunc();
|
||||||
else {
|
|
||||||
//timerLanCheckTime = millis();// + 5000;
|
|
||||||
lanStatus = DO_REINIT;//-10;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@@ -839,6 +851,16 @@ void onMQTTConnect(){
|
|||||||
strncpy_P(buf, statsval_P, sizeof(buf)-1);
|
strncpy_P(buf, statsval_P, sizeof(buf)-1);
|
||||||
mqttClient.publish(topic,buf,true);
|
mqttClient.publish(topic,buf,true);
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
RNG.rand((uint8_t *) &cryptoSalt,sizeof(cryptoSalt));
|
||||||
|
setTopic(topic,sizeof(topic),T_DEV);
|
||||||
|
//strncat_P(topic, stats_P, sizeof(topic)-1);
|
||||||
|
//strncat(topic, "/", sizeof(topic));
|
||||||
|
strncat_P(topic, salt_P, sizeof(topic)-1);
|
||||||
|
printUlongValueToStr(buf, cryptoSalt);
|
||||||
|
mqttClient.publish(topic,buf,true);
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef NO_HOMIE
|
#ifndef NO_HOMIE
|
||||||
|
|
||||||
// strncpy_P(topic, outprefix, sizeof(topic));
|
// strncpy_P(topic, outprefix, sizeof(topic));
|
||||||
@@ -1215,63 +1237,6 @@ void resetHard() {
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef _owire
|
|
||||||
|
|
||||||
void Changed(int i, DeviceAddress addr, float currentTemp) {
|
|
||||||
char addrstr[32] = "NIL";
|
|
||||||
//char addrbuf[17];
|
|
||||||
//char valstr[16] = "NIL";
|
|
||||||
//char *owEmitString = NULL;
|
|
||||||
//char *owItem = NULL;
|
|
||||||
|
|
||||||
SetBytes(addr, 8, addrstr);
|
|
||||||
addrstr[17] = 0;
|
|
||||||
if (!root) return;
|
|
||||||
//printFloatValueToStr(currentTemp,valstr);
|
|
||||||
debugSerial<<endl<<F("T:")<<currentTemp<<F("<")<<addrstr<<F(">")<<endl;
|
|
||||||
aJsonObject *owObj = aJson.getObjectItem(owArr, addrstr);
|
|
||||||
if ((currentTemp != -127.0) && (currentTemp != 85.0) && (currentTemp != 0.0))
|
|
||||||
executeCommand(owObj,-1,itemCmd(currentTemp).setSuffix(S_VAL));
|
|
||||||
|
|
||||||
/*
|
|
||||||
if (owObj) {
|
|
||||||
owEmitString = getStringFromConfig(owObj, "emit");
|
|
||||||
debugSerial<<owEmitString<<F(">")<<endl;
|
|
||||||
if ((currentTemp != -127.0) && (currentTemp != 85.0) && (currentTemp != 0.0))
|
|
||||||
{
|
|
||||||
if (owEmitString) // publish temperature to MQTT if configured
|
|
||||||
{
|
|
||||||
|
|
||||||
#ifdef WITH_DOMOTICZ
|
|
||||||
aJsonObject *idx = aJson.getObjectItem(owObj, "idx");
|
|
||||||
if (idx && && idx->type ==aJson_String && idx->valuestring) {//DOMOTICZ json format support
|
|
||||||
debugSerial << endl << idx->valuestring << F(" Domoticz valstr:");
|
|
||||||
char valstr[50];
|
|
||||||
sprintf(valstr, "{\"idx\":%s,\"svalue\":\"%.1f\"}", idx->valuestring, currentTemp);
|
|
||||||
debugSerial << valstr;
|
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
|
||||||
mqttClient.publish(owEmitString, valstr);
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
//strcpy_P(addrstr, outprefix);
|
|
||||||
setTopic(addrstr,sizeof(addrstr),T_OUT);
|
|
||||||
strncat(addrstr, owEmitString, sizeof(addrstr));
|
|
||||||
if (mqttClient.connected() && !ethernetIdleCount)
|
|
||||||
mqttClient.publish(addrstr, valstr);
|
|
||||||
}
|
|
||||||
// And translate temp to internal items
|
|
||||||
owItem = getStringFromConfig(owObj, "item");
|
|
||||||
if (owItem)
|
|
||||||
thermoSetCurTemp(owItem, currentTemp); ///TODO: Refactore using Items interface
|
|
||||||
} // if valid temperature
|
|
||||||
} // if Address in config
|
|
||||||
else debugSerial<<addrstr<<F(">")<<endl; // No item found
|
|
||||||
*/
|
|
||||||
}
|
|
||||||
|
|
||||||
#endif //_owire
|
|
||||||
|
|
||||||
int cmdFunctionHelp(int arg_cnt, char **args)
|
int cmdFunctionHelp(int arg_cnt, char **args)
|
||||||
{
|
{
|
||||||
@@ -1289,6 +1254,10 @@ int cmdFunctionHelp(int arg_cnt, char **args)
|
|||||||
"'log [serial_loglevel] [udp_loglevel]' - define log level (0..7)\n"
|
"'log [serial_loglevel] [udp_loglevel]' - define log level (0..7)\n"
|
||||||
"'kill' - test watchdog\n"
|
"'kill' - test watchdog\n"
|
||||||
"'clear' - clear EEPROM\n"
|
"'clear' - clear EEPROM\n"
|
||||||
|
|
||||||
|
#ifndef OWIRE_DISABLE
|
||||||
|
"'search' - search 1-wire dev\n"
|
||||||
|
#endif
|
||||||
"'reboot' - reboot controller");
|
"'reboot' - reboot controller");
|
||||||
return 200;
|
return 200;
|
||||||
}
|
}
|
||||||
@@ -1318,6 +1287,15 @@ int cmdFunctionReboot(int arg_cnt, char **args) {
|
|||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifndef OWIRE_DISABLE
|
||||||
|
|
||||||
|
int cmdFunctionSearch(int arg_cnt, char **args) {
|
||||||
|
//infoSerial<<F("searching");
|
||||||
|
owSearch();
|
||||||
|
return 200;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
void applyConfig() {
|
void applyConfig() {
|
||||||
if (!root || configLocked) return;
|
if (!root || configLocked) return;
|
||||||
configLocked++;
|
configLocked++;
|
||||||
@@ -1381,21 +1359,9 @@ setupSyslog();
|
|||||||
#ifdef _owire
|
#ifdef _owire
|
||||||
owArr = aJson.getObjectItem(root, "ow");
|
owArr = aJson.getObjectItem(root, "ow");
|
||||||
if (owArr && !owReady) {
|
if (owArr && !owReady) {
|
||||||
aJsonObject *item = owArr->child;
|
//aJsonObject *item = owArr->child;
|
||||||
owReady = owSetup(&Changed);
|
owReady = owSetup();
|
||||||
if (owReady) infoSerial<<F("One wire Ready\n");
|
if (owReady) infoSerial<<F("One wire Ready\n");
|
||||||
t_count = 0;
|
|
||||||
|
|
||||||
while (item && owReady) {
|
|
||||||
if ((item->type == aJson_Object)) {
|
|
||||||
DeviceAddress addr;
|
|
||||||
//infoSerial<<F("Add:")),infoSerial<<item->name);
|
|
||||||
SetAddr(item->name, addr);
|
|
||||||
owAdd(addr);
|
|
||||||
}
|
|
||||||
yield();
|
|
||||||
item = item->next;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
@@ -1418,6 +1384,9 @@ setupSyslog();
|
|||||||
if (cmd<1) it.setCmd(CMD_OFF);
|
if (cmd<1) it.setCmd(CMD_OFF);
|
||||||
it.setFlag(FLAG_COMMAND);
|
it.setFlag(FLAG_COMMAND);
|
||||||
if (it.itemVal) it.setFlag(FLAG_PARAMETERS);
|
if (it.itemVal) it.setFlag(FLAG_PARAMETERS);
|
||||||
|
|
||||||
|
if (isProtectedPin(pin)) {errorSerial<<F("pin protected: ")<<pin<<endl; break;}
|
||||||
|
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
digitalWrite(pin, false); //Initially, all thermostates are LOW (OFF for electho heaters, open for water NO)
|
digitalWrite(pin, false); //Initially, all thermostates are LOW (OFF for electho heaters, open for water NO)
|
||||||
debugSerial<<F("Thermo:")<<pin<<F("=LOW")<<F(";");
|
debugSerial<<F("Thermo:")<<pin<<F("=LOW")<<F(";");
|
||||||
@@ -1426,12 +1395,16 @@ setupSyslog();
|
|||||||
{
|
{
|
||||||
int k;
|
int k;
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
|
if (isProtectedPin(pin)) digitalWrite (pin,LOW);
|
||||||
|
else
|
||||||
|
{
|
||||||
if (inverse)
|
if (inverse)
|
||||||
digitalWrite(pin, k = ((cmd == CMD_ON) ? LOW : HIGH));
|
digitalWrite(pin, k = ((cmd == CMD_ON) ? LOW : HIGH));
|
||||||
else
|
else
|
||||||
digitalWrite(pin, k = ((cmd == CMD_ON) ? HIGH : LOW));
|
digitalWrite(pin, k = ((cmd == CMD_ON) ? HIGH : LOW));
|
||||||
debugSerial<<F("Pin:")<<pin<<F("=")<<k<<F(";");
|
debugSerial<<F("Pin:")<<pin<<F("=")<<k<<F(";");
|
||||||
}
|
}
|
||||||
|
}
|
||||||
break;
|
break;
|
||||||
} //switch
|
} //switch
|
||||||
} //isValid
|
} //isValid
|
||||||
@@ -1489,12 +1462,14 @@ void printConfigSummary() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
int cmdFunctionLoad(int arg_cnt, char **args) {
|
int cmdFunctionLoad(int arg_cnt, char **args) {
|
||||||
|
/*
|
||||||
if (!loadConfigFromEEPROM())
|
if (!loadConfigFromEEPROM())
|
||||||
{
|
{
|
||||||
lanStatus=DO_REINIT;
|
lanStatus=DO_REINIT;
|
||||||
return 500;
|
return 500;
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
lanStatus=DO_READ_RE_CONFIG;
|
||||||
return 200;
|
return 200;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1502,6 +1477,8 @@ int cmdFunctionLoad(int arg_cnt, char **args) {
|
|||||||
int loadConfigFromEEPROM()
|
int loadConfigFromEEPROM()
|
||||||
{
|
{
|
||||||
if (configLocked) return 0;
|
if (configLocked) return 0;
|
||||||
|
configLocked++;
|
||||||
|
|
||||||
infoSerial<<F("Loading Config from EEPROM")<<endl;
|
infoSerial<<F("Loading Config from EEPROM")<<endl;
|
||||||
#if defined(FS_STORAGE)
|
#if defined(FS_STORAGE)
|
||||||
sysConfStream.open("/config.json",'r');
|
sysConfStream.open("/config.json",'r');
|
||||||
@@ -1510,18 +1487,20 @@ int loadConfigFromEEPROM()
|
|||||||
#endif
|
#endif
|
||||||
|
|
||||||
if (sysConfStream.peek() == '{') {
|
if (sysConfStream.peek() == '{') {
|
||||||
debugSerial<<F("Trying Load from EEPROM")<<endl;
|
debugSerial<<F("JSON detected")<<endl;
|
||||||
aJsonStream as = aJsonStream(&sysConfStream);
|
aJsonStream as = aJsonStream(&sysConfStream);
|
||||||
cleanConf();
|
cleanConf(false);
|
||||||
root = aJson.parse(&as);
|
root = aJson.parse(&as);
|
||||||
sysConfStream.close();
|
sysConfStream.close();
|
||||||
if (!root) {
|
if (!root) {
|
||||||
errorSerial<<F("load failed")<<endl;
|
errorSerial<<F("load failed")<<endl;
|
||||||
sysConf.setETAG("");
|
sysConf.setETAG("");
|
||||||
// sysConfStream.close();
|
// sysConfStream.close();
|
||||||
|
configLocked--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
infoSerial<<F("Loaded from EEPROM")<<endl;
|
infoSerial<<F("Loaded from EEPROM")<<endl;
|
||||||
|
configLocked--;
|
||||||
applyConfig();
|
applyConfig();
|
||||||
sysConf.loadETAG();
|
sysConf.loadETAG();
|
||||||
//ethClient.stop(); //Refresh MQTT connect to get retained info
|
//ethClient.stop(); //Refresh MQTT connect to get retained info
|
||||||
@@ -1534,6 +1513,7 @@ int loadConfigFromEEPROM()
|
|||||||
}
|
}
|
||||||
sysConfStream.close();
|
sysConfStream.close();
|
||||||
infoSerial<<F("No stored config")<<endl;
|
infoSerial<<F("No stored config")<<endl;
|
||||||
|
configLocked--;
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -1792,7 +1772,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
|||||||
infoSerial<<F("got Config\n"); delay(500);
|
infoSerial<<F("got Config\n"); delay(500);
|
||||||
aJsonFileStream as = aJsonFileStream(configStream);
|
aJsonFileStream as = aJsonFileStream(configStream);
|
||||||
noInterrupts();
|
noInterrupts();
|
||||||
cleanConf();
|
cleanConf(true);
|
||||||
root = aJson.parse(&as);
|
root = aJson.parse(&as);
|
||||||
interrupts();
|
interrupts();
|
||||||
hclient.closeStream(configStream); // this is very important -- be sure to close the STREAM
|
hclient.closeStream(configStream); // this is very important -- be sure to close the STREAM
|
||||||
@@ -1864,7 +1844,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
|||||||
if (responseStatusCode == 200) {
|
if (responseStatusCode == 200) {
|
||||||
aJsonStream socketStream = aJsonStream(&htclient);
|
aJsonStream socketStream = aJsonStream(&htclient);
|
||||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||||
cleanConf();
|
cleanConf(true);
|
||||||
debugSerial<<F("Configuration cleaned")<<endl;
|
debugSerial<<F("Configuration cleaned")<<endl;
|
||||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||||
//root = aJson.parse((char *) response.c_str());
|
//root = aJson.parse((char *) response.c_str());
|
||||||
@@ -1937,7 +1917,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
|
|||||||
sysConf.setETAG(httpClient.header("ETag"));
|
sysConf.setETAG(httpClient.header("ETag"));
|
||||||
//String response = httpClient.getString();
|
//String response = httpClient.getString();
|
||||||
//debugSerial<<response;
|
//debugSerial<<response;
|
||||||
cleanConf();
|
cleanConf(true);
|
||||||
//root = aJson.parse((char *) response.c_str());
|
//root = aJson.parse((char *) response.c_str());
|
||||||
root = aJson.parse(&socketStream);
|
root = aJson.parse(&socketStream);
|
||||||
|
|
||||||
@@ -1999,18 +1979,19 @@ void postTransmission() {
|
|||||||
|
|
||||||
void TimerHandler(void)
|
void TimerHandler(void)
|
||||||
{
|
{
|
||||||
timerHandlerBusy++;
|
|
||||||
interrupts();
|
|
||||||
timerCount=micros();
|
timerCount=micros();
|
||||||
if (configLoaded && !timerHandlerBusy)
|
if (configLoaded && !timerHandlerBusy)
|
||||||
{
|
{
|
||||||
|
timerHandlerBusy++;
|
||||||
|
interrupts();
|
||||||
|
|
||||||
inputLoop(CHECK_INTERRUPT);
|
inputLoop(CHECK_INTERRUPT);
|
||||||
#ifdef DMX_SMOOTH
|
#ifdef DMX_SMOOTH
|
||||||
DMXOUT_propagate();
|
DMXOUT_propagate();
|
||||||
#endif
|
#endif
|
||||||
|
timerHandlerBusy--;
|
||||||
}
|
}
|
||||||
timerCount=micros()-timerCount;
|
timerCount=micros()-timerCount;
|
||||||
timerHandlerBusy--;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(__SAM3X8E__) && defined (TIMER_INT)
|
#if defined(__SAM3X8E__) && defined (TIMER_INT)
|
||||||
@@ -2026,6 +2007,56 @@ int16_t attachTimer(double microseconds, timerCallback callback, const char* Tim
|
|||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if defined(__SAM3X8E__) && defined (PULSEPIN12)
|
||||||
|
#define MATURA_PULSE 100
|
||||||
|
#define MATURA_PERIOD 2500
|
||||||
|
|
||||||
|
void maturaTimerHandler(void){ }
|
||||||
|
|
||||||
|
volatile int maturaTimerNumber = -1;
|
||||||
|
int16_t attachMaturaTimer()
|
||||||
|
{
|
||||||
|
if (maturaTimerNumber==-1)
|
||||||
|
{
|
||||||
|
DueTimerInterrupt dueTimerInterrupt = DueTimerInterrupt(8);
|
||||||
|
dueTimerInterrupt.attachInterruptInterval(MATURA_PERIOD*1000, maturaTimerHandler);
|
||||||
|
maturaTimerNumber = dueTimerInterrupt.getTimerNumber();
|
||||||
|
TC_SetRB(TC2,2,REG_TC2_RC2 - (REG_TC2_RC2 / MATURA_PERIOD * MATURA_PULSE));
|
||||||
|
REG_TC2_CMR2 |= TC_CMR_BCPB_SET | TC_CMR_BCPC_CLEAR | TC_CMR_EEVT_XC0; // on CTR==A -> SET; on CTR == C - CLEAR pin, enable TIOB as out
|
||||||
|
}
|
||||||
|
debugSerial<<F("Matura attached to Timer(")<<maturaTimerNumber<<F(")")<<endl;
|
||||||
|
//pinMode(11,OUTPUT); //PIO_PD7B_TIOA8 PERIPH_B //T7
|
||||||
|
pinMode(12,OUTPUT); //PIO_PD8B_TIOB8 PERIPH_B //T8
|
||||||
|
|
||||||
|
// Memo for some future use timers:
|
||||||
|
//pinMode(2,OUTPUT); //PIO_PB25B_TIOA0 PERIPH_B
|
||||||
|
//pinMode(13,OUTPUT);//PIO_PB27B_TIOB0 PERIPH_B
|
||||||
|
|
||||||
|
//pinMode(3,OUTPUT); //PIO_PC28B_TIOA7 PERIPH_B
|
||||||
|
//pinMode(10,OUTPUT);//PIO_PC29B_TIOB7 PERIPH_B
|
||||||
|
|
||||||
|
//pinMode(5,OUTPUT); //PIO_PC25B_TIOA6 PERIPH_B
|
||||||
|
//pinMode(4,OUTPUT); //PIO_PC26B_TIOB6 PERIPH_B
|
||||||
|
|
||||||
|
// 11 & 12 pins example (TC2 ch2 (#8) A & B channels for some future use)
|
||||||
|
//REG_PIOD_PDR = PIO_PD7 | PIO_PD8;
|
||||||
|
//REG_PIOD_ABSR |= PIO_PD7 | PIO_PD8;
|
||||||
|
//REG_TC2_CMR2 |= TC_CMR_ACPA_SET | TC_CMR_ACPC_CLEAR | TC_CMR_BCPB_SET | TC_CMR_BCPC_CLEAR | TC_CMR_EEVT_XC0;
|
||||||
|
//TC_SetRA(TC2,2,1000000);TC_SetRB(TC2,2,1500000);
|
||||||
|
|
||||||
|
REG_PIOD_PDR = PIO_PD8; //Disabling PD8 IO - move to pereferia
|
||||||
|
REG_PIOD_ABSR |= PIO_PD8; //Select Pereferia B
|
||||||
|
//REG_TC2_CMR2 |= TC_CMR_BCPB_SET | TC_CMR_BCPC_CLEAR | TC_CMR_EEVT_XC0; // on CTR==A -> SET; on CTR == C - CLEAR pin, enable TIOB as out
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
//REG_PIOD_WPMR = PIO_WPMR_WPKEY(0x50494f) | 1; //Write protect whole IOD
|
||||||
|
return maturaTimerNumber;
|
||||||
|
}
|
||||||
|
#else
|
||||||
|
int16_t attachMaturaTimer(){return 0;};
|
||||||
|
#endif
|
||||||
|
|
||||||
#if defined(WIFI_ENABLE)
|
#if defined(WIFI_ENABLE)
|
||||||
#if defined (ESP32)
|
#if defined (ESP32)
|
||||||
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
|
||||||
@@ -2172,13 +2203,35 @@ void setup_main() {
|
|||||||
#endif
|
#endif
|
||||||
//debugSerialPort << "Checkin EEPROM integrity (signature)"<<endl;
|
//debugSerialPort << "Checkin EEPROM integrity (signature)"<<endl;
|
||||||
|
|
||||||
if (!sysConf.isValidSysConf())
|
bool needClean = false;
|
||||||
|
#ifdef CONFIG_CLEAN_PIN
|
||||||
|
pinMode(CONFIG_CLEAN_PIN,INPUT_PULLUP);
|
||||||
|
int i = 0;
|
||||||
|
while ((digitalRead(CONFIG_CLEAN_PIN)==LOW) && !needClean)
|
||||||
|
{
|
||||||
|
|
||||||
|
statusLED.set(ledRED);
|
||||||
|
delay(500);
|
||||||
|
statusLED.set(ledGREEN);
|
||||||
|
delay(500);
|
||||||
|
statusLED.set(ledBLUE);
|
||||||
|
delay(500);
|
||||||
|
if (i>4) needClean = true;
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
|
||||||
|
//if (needClean) cmdFunctionClearEEPROM(0, NULL);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!sysConf.isValidSysConf() || needClean)
|
||||||
{
|
{
|
||||||
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
#if defined(debugSerialPort) && !defined(NOSERIAL)
|
||||||
debugSerialPort.println(F("No valid EEPROM data. Initializing."));
|
debugSerialPort.println(F("Initializing EEPROM."));
|
||||||
#endif
|
#endif
|
||||||
sysConf.clear();
|
cmdFunctionClearEEPROM(0, NULL);
|
||||||
|
//sysConf.clear();
|
||||||
}
|
}
|
||||||
|
else debugSerial << F("EEPROM signature ok")<<endl;
|
||||||
// scan_i2c_bus();
|
// scan_i2c_bus();
|
||||||
|
|
||||||
serialDebugLevel=sysConf.getSerialDebuglevel();
|
serialDebugLevel=sysConf.getSerialDebuglevel();
|
||||||
@@ -2200,7 +2253,9 @@ void setup_main() {
|
|||||||
#ifdef SD_CARD_INSERTED
|
#ifdef SD_CARD_INSERTED
|
||||||
sd_card_w5100_setup();
|
sd_card_w5100_setup();
|
||||||
#endif
|
#endif
|
||||||
setupMacAddress();
|
// Serial.print("Sig4=");
|
||||||
|
// Serial.println(FLASH_START[0],HEX);
|
||||||
|
setupMacAddress(); //тут почему-то не считывается из флэш
|
||||||
|
|
||||||
#ifdef _modbus
|
#ifdef _modbus
|
||||||
#ifdef CONTROLLINO
|
#ifdef CONTROLLINO
|
||||||
@@ -2220,9 +2275,7 @@ void setup_main() {
|
|||||||
delay(20);
|
delay(20);
|
||||||
//owReady = 0;
|
//owReady = 0;
|
||||||
|
|
||||||
#ifdef _owire
|
|
||||||
setupOwIdle(&owIdle);
|
|
||||||
#endif
|
|
||||||
|
|
||||||
mqttClient.setCallback(mqttCallback);
|
mqttClient.setCallback(mqttCallback);
|
||||||
|
|
||||||
@@ -2485,10 +2538,21 @@ void publishStat(){
|
|||||||
strncat_P(topic, state_P, sizeof(topic)-1);
|
strncat_P(topic, state_P, sizeof(topic)-1);
|
||||||
strncpy_P(intbuf, ready_P, sizeof(intbuf)-1);
|
strncpy_P(intbuf, ready_P, sizeof(intbuf)-1);
|
||||||
mqttClient.publish(topic,intbuf,true);
|
mqttClient.publish(topic,intbuf,true);
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
RNG.rand((uint8_t *) &cryptoSalt,sizeof(cryptoSalt));
|
||||||
|
setTopic(topic,sizeof(topic),T_DEV);
|
||||||
|
//strncat_P(topic, stats_P, sizeof(topic)-1);
|
||||||
|
//strncat(topic, "/", sizeof(topic));
|
||||||
|
strncat_P(topic, salt_P, sizeof(topic)-1);
|
||||||
|
printUlongValueToStr(intbuf, cryptoSalt);
|
||||||
|
mqttClient.publish(topic,intbuf,true);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void setupMacAddress() {
|
void setupMacAddress() {
|
||||||
//Check MAC, stored in NVRAM
|
//Check MAC, stored in NVRAM
|
||||||
|
|
||||||
if (!sysConf.getMAC()) {
|
if (!sysConf.getMAC()) {
|
||||||
infoSerial<<F("No MAC configured: set firmware's MAC\n");
|
infoSerial<<F("No MAC configured: set firmware's MAC\n");
|
||||||
|
|
||||||
@@ -2538,6 +2602,10 @@ void setupCmdArduino() {
|
|||||||
cmdAdd("clear",cmdFunctionClearEEPROM);
|
cmdAdd("clear",cmdFunctionClearEEPROM);
|
||||||
cmdAdd("reboot",cmdFunctionReboot);
|
cmdAdd("reboot",cmdFunctionReboot);
|
||||||
cmdAdd("log",cmdFunctionLoglevel);
|
cmdAdd("log",cmdFunctionLoglevel);
|
||||||
|
|
||||||
|
#ifndef OWIRE_DISABLE
|
||||||
|
cmdAdd("search",cmdFunctionSearch);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void loop_main() {
|
void loop_main() {
|
||||||
@@ -2593,6 +2661,8 @@ void loop_main() {
|
|||||||
yield();
|
yield();
|
||||||
inputLoop(CHECK_INPUT);
|
inputLoop(CHECK_INPUT);
|
||||||
|
|
||||||
|
yield();
|
||||||
|
inputSensorsLoop();
|
||||||
#if defined (_espdmx)
|
#if defined (_espdmx)
|
||||||
yield();
|
yield();
|
||||||
dmxout.update();
|
dmxout.update();
|
||||||
@@ -2604,13 +2674,32 @@ if (initializedListeners) ipmodbusLoop();
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//static uint32_t tm=0;
|
||||||
|
|
||||||
void owIdle(void) {
|
void owIdle(void) {
|
||||||
|
// timerCtr++;
|
||||||
#ifdef _artnet
|
#ifdef _artnet
|
||||||
if (artnet && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
|
if (artnet && (lanStatus>=HAVE_IP_ADDRESS)) artnet->read();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
wdt_res();
|
wdt_res();
|
||||||
inputLoop(CHECK_INTERRUPT);
|
inputLoop(CHECK_INPUT);
|
||||||
|
//inputLoop(CHECK_INTERRUPT);
|
||||||
|
/*
|
||||||
|
if (isTimeOver(tm,millis(),100))
|
||||||
|
{
|
||||||
|
tm=millis();
|
||||||
|
debugSerial<<F("1WT: Tick")<<endl;
|
||||||
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
#if defined (_espdmx)
|
||||||
|
yield();
|
||||||
|
dmxout.update();
|
||||||
|
#endif
|
||||||
|
|
||||||
return; //?????
|
return; //?????
|
||||||
|
|
||||||
#ifdef _dmxin
|
#ifdef _dmxin
|
||||||
@@ -2618,10 +2707,7 @@ inputLoop(CHECK_INTERRUPT);
|
|||||||
DMXCheck();
|
DMXCheck();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
#if defined (_espdmx)
|
|
||||||
yield();
|
|
||||||
dmxout.update();
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#ifdef IPMODBUS
|
#ifdef IPMODBUS
|
||||||
if (initializedListeners) ipmodbusLoop();
|
if (initializedListeners) ipmodbusLoop();
|
||||||
@@ -2637,7 +2723,9 @@ ethernetIdleCount++;
|
|||||||
ethernetIdleCount--;
|
ethernetIdleCount--;
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
void modbusIdle(void) {
|
void modbusIdle(void) {
|
||||||
|
|
||||||
wdt_res();
|
wdt_res();
|
||||||
statusLED.poll();
|
statusLED.poll();
|
||||||
yield();
|
yield();
|
||||||
@@ -2714,9 +2802,16 @@ configLocked++;
|
|||||||
if (cause != CHECK_INTERRUPT) timerInputCheck = millis();// + INTERVAL_CHECK_INPUT;
|
if (cause != CHECK_INTERRUPT) timerInputCheck = millis();// + INTERVAL_CHECK_INPUT;
|
||||||
inCache.invalidateInputCache();
|
inCache.invalidateInputCache();
|
||||||
}
|
}
|
||||||
|
configLocked--;
|
||||||
|
inputLoopBusy--;
|
||||||
|
}
|
||||||
|
|
||||||
//if (millis() > timerSensorCheck)
|
|
||||||
if (cause != CHECK_INTERRUPT && isTimeOver(timerSensorCheck,millis(),INTERVAL_CHECK_SENSOR))
|
void inputSensorsLoop() {
|
||||||
|
if (!inputs || inputLoopBusy) return;
|
||||||
|
//inputLoopBusy++;
|
||||||
|
configLocked++;
|
||||||
|
if (isTimeOver(timerSensorCheck,millis(),INTERVAL_CHECK_SENSOR))
|
||||||
{
|
{
|
||||||
aJsonObject *input = inputs->child;
|
aJsonObject *input = inputs->child;
|
||||||
while (input) {
|
while (input) {
|
||||||
@@ -2725,15 +2820,17 @@ configLocked++;
|
|||||||
in.Poll(CHECK_SENSOR);
|
in.Poll(CHECK_SENSOR);
|
||||||
}
|
}
|
||||||
yield();
|
yield();
|
||||||
|
inputLoop(CHECK_INPUT);
|
||||||
input = input->next;
|
input = input->next;
|
||||||
}
|
}
|
||||||
timerSensorCheck = millis();// + INTERVAL_CHECK_SENSOR;
|
timerSensorCheck = millis();
|
||||||
}
|
}
|
||||||
configLocked--;
|
configLocked--;
|
||||||
inputLoopBusy--;
|
//inputLoopBusy--;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
void inputSetup(void) {
|
void inputSetup(void) {
|
||||||
if (!inputs) return;
|
if (!inputs) return;
|
||||||
configLocked++;
|
configLocked++;
|
||||||
@@ -2749,6 +2846,8 @@ configLocked++;
|
|||||||
#if defined(__SAM3X8E__) && defined (TIMER_INT)
|
#if defined(__SAM3X8E__) && defined (TIMER_INT)
|
||||||
// Interval in microsecs
|
// Interval in microsecs
|
||||||
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
|
attachTimer(TIMER_CHECK_INPUT * 1000, TimerHandler, "ITimer");
|
||||||
|
attachMaturaTimer();
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
configLocked--;
|
configLocked--;
|
||||||
}
|
}
|
||||||
@@ -2807,6 +2906,7 @@ enum heaterMode {HEATER_HEAT,HEATER_OFF,HEATER_ERROR};
|
|||||||
void thermoRelay(int pin, heaterMode on)
|
void thermoRelay(int pin, heaterMode on)
|
||||||
{
|
{
|
||||||
int thermoPin = abs(pin);
|
int thermoPin = abs(pin);
|
||||||
|
if(isProtectedPin(thermoPin)) {errorSerial<<F("pin disabled ")<<thermoPin<<endl;return;}
|
||||||
pinMode(thermoPin, OUTPUT);
|
pinMode(thermoPin, OUTPUT);
|
||||||
|
|
||||||
if (on == HEATER_ERROR)
|
if (on == HEATER_ERROR)
|
||||||
@@ -2850,7 +2950,9 @@ void thermoLoop(void) {
|
|||||||
int thermoStateCommand = thermostat.getCmd();
|
int thermoStateCommand = thermostat.getCmd();
|
||||||
float curTemp = (float) tStore.tempX100/100.;
|
float curTemp = (float) tStore.tempX100/100.;
|
||||||
bool active = thermostat.isActive();
|
bool active = thermostat.isActive();
|
||||||
|
//float overHeatTemp = thermostat.getFloatArg(1);
|
||||||
|
//if (overHeatTemp == 0.) overHeatTemp = THERMO_OVERHEAT_CELSIUS;
|
||||||
|
float overHeatTemp = THERMO_OVERHEAT_CELSIUS;
|
||||||
debugSerial << F(" Set:") << thermoSetting << F(" Cur:") << curTemp
|
debugSerial << F(" Set:") << thermoSetting << F(" Cur:") << curTemp
|
||||||
<< F(" cmd:") << thermoStateCommand;
|
<< F(" cmd:") << thermoStateCommand;
|
||||||
|
|
||||||
@@ -2866,7 +2968,7 @@ void thermoLoop(void) {
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ // Not expired yet
|
{ // Not expired yet
|
||||||
if (curTemp > THERMO_OVERHEAT_CELSIUS) mqttClient.publish("/alarm/ovrht", thermoItem->name);
|
if (curTemp > overHeatTemp) mqttClient.publish("/alarm/ovrht", thermoItem->name);
|
||||||
|
|
||||||
if (!active) thermoRelay(thermoPin,HEATER_OFF);//OFF
|
if (!active) thermoRelay(thermoPin,HEATER_OFF);//OFF
|
||||||
else if (curTemp < thermoSetting - THERMO_GIST_CELSIUS) thermoRelay(thermoPin,HEATER_HEAT);//ON
|
else if (curTemp < thermoSetting - THERMO_GIST_CELSIUS) thermoRelay(thermoPin,HEATER_HEAT);//ON
|
||||||
|
|||||||
@@ -287,6 +287,8 @@ void modbusIdle(void);
|
|||||||
|
|
||||||
void inputLoop(short);
|
void inputLoop(short);
|
||||||
|
|
||||||
|
void inputSensorsLoop();
|
||||||
|
|
||||||
void inputSetup(void);
|
void inputSetup(void);
|
||||||
|
|
||||||
void pollingLoop(void);
|
void pollingLoop(void);
|
||||||
@@ -319,4 +321,6 @@ void printCurentLanConfig();
|
|||||||
|
|
||||||
void onMQTTConnect();
|
void onMQTTConnect();
|
||||||
|
|
||||||
|
int16_t attachMaturaTimer();
|
||||||
|
|
||||||
//void printFreeRam();
|
//void printFreeRam();
|
||||||
|
|||||||
@@ -4,6 +4,7 @@
|
|||||||
#include "Streaming.h"
|
#include "Streaming.h"
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "Wire.h"
|
||||||
|
|
||||||
#if defined(M5STACK)
|
#if defined(M5STACK)
|
||||||
#include <M5Stack.h>
|
#include <M5Stack.h>
|
||||||
@@ -63,8 +64,10 @@ delay(2000); */
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int in_hdc1080::Setup()
|
int in_hdc1080::Setup()
|
||||||
{
|
{
|
||||||
|
//i2cReset();
|
||||||
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
|
if (HDC1080ready) {debugSerial<<F("hdc1080 is already initialized")<<endl; return 0;}
|
||||||
debugSerial.println("HDC1080 Init ");
|
debugSerial.println("HDC1080 Init ");
|
||||||
Wire.begin(); //Inialize I2C Harware
|
Wire.begin(); //Inialize I2C Harware
|
||||||
@@ -81,14 +84,7 @@ HDC1080ready = true;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
void i2cReset(){
|
|
||||||
Wire.endTransmission(true);
|
|
||||||
#if defined (SCL_RESET)
|
|
||||||
SCL_LOW();
|
|
||||||
delay(300);
|
|
||||||
SCL_HIGH();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
int in_hdc1080::Poll(short cause)
|
int in_hdc1080::Poll(short cause)
|
||||||
{
|
{
|
||||||
@@ -130,7 +126,6 @@ if (reg!=0xff)
|
|||||||
}
|
}
|
||||||
else //ESP I2C glitch
|
else //ESP I2C glitch
|
||||||
{
|
{
|
||||||
debugSerial.println("I2C Reset");
|
|
||||||
i2cReset();
|
i2cReset();
|
||||||
}
|
}
|
||||||
return INTERVAL_SLOW_POLLING;
|
return INTERVAL_SLOW_POLLING;
|
||||||
|
|||||||
@@ -19,12 +19,12 @@ extern bool disableCMD;
|
|||||||
|
|
||||||
#define INTERVAL_AC_POLLING 5000L
|
#define INTERVAL_AC_POLLING 5000L
|
||||||
|
|
||||||
#define AC_FAILED 15
|
#define AC_FAILED CST_FAILED
|
||||||
#define AC_UNKNOWN CST_UNKNOWN
|
#define AC_UNKNOWN CST_UNKNOWN
|
||||||
#define AC_IDLE CST_INITIALIZED
|
#define AC_IDLE CST_INITIALIZED
|
||||||
#define AC_SENDING 2
|
#define AC_SENDING 3
|
||||||
|
|
||||||
byte inCheck = 0;
|
//byte inCheck = 0;
|
||||||
byte qstn[] = {255,255,10,0,0,0,0,0,1,1,77,1,90}; // Команда опроса
|
byte qstn[] = {255,255,10,0,0,0,0,0,1,1,77,1,90}; // Команда опроса
|
||||||
|
|
||||||
byte on[] = {255,255,10,0,0,0,0,0,1,1,77,2,91}; // Включение кондиционера
|
byte on[] = {255,255,10,0,0,0,0,0,1,1,77,2,91}; // Включение кондиционера
|
||||||
@@ -66,6 +66,20 @@ void out_AC::getConfig(){
|
|||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
void out_AC::SubmitParameters(const char * name, itemCmd value){
|
||||||
|
|
||||||
|
if (!item || !item->itemArg) return;
|
||||||
|
if ((item->itemArg->type == aJson_Array) && ( 1 < aJson.getArraySize(item->itemArg)))
|
||||||
|
{
|
||||||
|
aJsonObject * callbackObj = aJson.getArrayItem(item->itemArg, 1);
|
||||||
|
if (callbackObj && callbackObj->type == aJson_Object)
|
||||||
|
{
|
||||||
|
aJsonObject * execObj = aJson.getObjectItem(callbackObj,name);
|
||||||
|
if (execObj) executeCommand(execObj,-1,value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
void out_AC::InsertData(byte data[], size_t size){
|
void out_AC::InsertData(byte data[], size_t size){
|
||||||
|
|
||||||
int fresh =0;
|
int fresh =0;
|
||||||
@@ -77,7 +91,8 @@ void out_AC::InsertData(byte data[], size_t size){
|
|||||||
int fan_spd = 0;
|
int fan_spd = 0;
|
||||||
|
|
||||||
|
|
||||||
char s_mode[10];
|
char s_buffer[10];
|
||||||
|
itemCmd icmd;
|
||||||
|
|
||||||
set_tmp = data[B_SET_TMP]+16;
|
set_tmp = data[B_SET_TMP]+16;
|
||||||
if (set_tmp>40 || set_tmp<16) return;
|
if (set_tmp>40 || set_tmp<16) return;
|
||||||
@@ -124,22 +139,51 @@ void out_AC::InsertData(byte data[], size_t size){
|
|||||||
publishTopic(item->itemArr->name, "OFF","/compressor");
|
publishTopic(item->itemArr->name, "OFF","/compressor");
|
||||||
|
|
||||||
|
|
||||||
publishTopic(item->itemArr->name, (long) swing,"/swing");
|
//publishTopic(item->itemArr->name, (long) swing,"/swing");
|
||||||
//publishTopic(item->itemArr->name, (long) fan_spd,"/fan");
|
//publishTopic(item->itemArr->name, (long) fan_spd,"/fan");
|
||||||
|
|
||||||
/////////////////////////////////
|
/////////////////////////////////
|
||||||
|
s_buffer[0]='\0';
|
||||||
|
switch (fan_spd){
|
||||||
|
case 0x00:
|
||||||
|
strcpy_P(s_buffer,HIGH_P);
|
||||||
|
icmd.Cmd(CMD_HIGH);
|
||||||
|
break;
|
||||||
|
case 0x01:
|
||||||
|
strcpy_P(s_buffer,MED_P);
|
||||||
|
icmd.Cmd(CMD_MED);
|
||||||
|
break;
|
||||||
|
case 0x02:
|
||||||
|
strcpy_P(s_buffer,LOW_P);
|
||||||
|
icmd.Cmd(CMD_LOW);
|
||||||
|
break;
|
||||||
|
case 0x03:
|
||||||
|
strcpy_P(s_buffer,AUTO_P);
|
||||||
|
icmd.Cmd(CMD_AUTO);
|
||||||
|
break;
|
||||||
|
default:
|
||||||
|
strcpy_P(s_buffer,ERROR_P);
|
||||||
|
icmd.Cmd(CMD_VOID);
|
||||||
|
}
|
||||||
|
publishTopic(item->itemArr->name, s_buffer,"/fan");
|
||||||
|
SubmitParameters("fan",icmd);
|
||||||
|
|
||||||
|
/*
|
||||||
if (fan_spd == 0x00){
|
if (fan_spd == 0x00){
|
||||||
publishTopic(item->itemArr->name, "high","/fan");
|
publishTopic(item->itemArr->name, "high","/fan");
|
||||||
|
SubmitParameters("fan","")
|
||||||
}
|
}
|
||||||
if (fan_spd == 0x01){
|
if (fan_spd == 0x01){
|
||||||
publishTopic(item->itemArr->name, "medium","/fan");
|
publishTopic(item->itemArr->name, "medium","/fan");
|
||||||
}
|
}
|
||||||
|
|
||||||
if (fan_spd == 0x02){
|
if (fan_spd == 0x02){
|
||||||
publishTopic(item->itemArr->name, "low","/fan");
|
publishTopic(item->itemArr->name, "low","/fan");
|
||||||
}
|
}
|
||||||
if (fan_spd == 0x03){
|
if (fan_spd == 0x03){
|
||||||
publishTopic(item->itemArr->name, "auto","/fan");
|
publishTopic(item->itemArr->name, "auto","/fan");
|
||||||
}
|
}
|
||||||
|
*/
|
||||||
|
|
||||||
if (swing == 0x00)
|
if (swing == 0x00)
|
||||||
publishTopic(item->itemArr->name, "OFF","/swing");
|
publishTopic(item->itemArr->name, "OFF","/swing");
|
||||||
@@ -159,33 +203,47 @@ void out_AC::InsertData(byte data[], size_t size){
|
|||||||
publishTopic(item->itemArr->name,(long)set_tmp,"/set");
|
publishTopic(item->itemArr->name,(long)set_tmp,"/set");
|
||||||
if (cur_tmp!=255) publishTopic(item->itemArr->name, (long)cur_tmp, "/temp");
|
if (cur_tmp!=255) publishTopic(item->itemArr->name, (long)cur_tmp, "/temp");
|
||||||
////////////////////////////////////
|
////////////////////////////////////
|
||||||
s_mode[0]='\0';
|
|
||||||
|
//itoa(set_tmp,s_buffer,10);
|
||||||
|
//SubmitParameters("set",itemCmd().Int((int32_t)set_tmp).setSuffix(S_SET));
|
||||||
|
SubmitParameters("set",itemCmd().Int((int32_t)set_tmp));
|
||||||
|
|
||||||
|
//itoa(cur_tmp,s_buffer,10);
|
||||||
|
SubmitParameters("temp",itemCmd().Int((int32_t)cur_tmp).setSuffix(S_VAL));
|
||||||
|
|
||||||
|
s_buffer[0]='\0';
|
||||||
|
|
||||||
if (store->mode == 0x00){
|
if (store->mode == 0x00){
|
||||||
strcpy_P(s_mode,AUTO_P);
|
strcpy_P(s_buffer,AUTO_P);icmd.Cmd(CMD_AUTO);
|
||||||
}
|
}
|
||||||
else if (store->mode == 0x01){
|
else if (store->mode == 0x01){
|
||||||
strcpy_P(s_mode,COOL_P);
|
strcpy_P(s_buffer,COOL_P);icmd.Cmd(CMD_COOL);
|
||||||
}
|
}
|
||||||
else if (store->mode == 0x02){
|
else if (store->mode == 0x02){
|
||||||
strcpy_P(s_mode,HEAT_P);
|
strcpy_P(s_buffer,HEAT_P);icmd.Cmd(CMD_HEAT);
|
||||||
}
|
}
|
||||||
else if (store->mode == 0x03){
|
else if (store->mode == 0x03){
|
||||||
strcpy_P(s_mode,FAN_ONLY_P);
|
strcpy_P(s_buffer,FAN_ONLY_P);icmd.Cmd(CMD_FAN);
|
||||||
}
|
}
|
||||||
else if (store->mode == 0x04){
|
else if (store->mode == 0x04){
|
||||||
strcpy_P(s_mode,DRY_P);
|
strcpy_P(s_buffer,DRY_P);icmd.Cmd(CMD_DRY);
|
||||||
}
|
}
|
||||||
else if (store->mode == 109){
|
else if (store->mode == 109){
|
||||||
strcpy_P(s_mode,ERROR_P);
|
strcpy_P(s_buffer,ERROR_P);icmd.Cmd(CMD_VOID);
|
||||||
}
|
}
|
||||||
|
|
||||||
publishTopic(item->itemArr->name, (long) store->mode, "/mode");
|
publishTopic(item->itemArr->name, (long) store->mode, "/mode");
|
||||||
|
|
||||||
|
if (!(store->power & 0x01)) {strcpy_P(s_buffer,OFF_P);icmd.Cmd(CMD_OFF);}
|
||||||
|
publishTopic(item->itemArr->name, s_buffer,"/cmd");
|
||||||
|
SubmitParameters("cmd",icmd);
|
||||||
|
/*
|
||||||
if (store->power & 0x01)
|
if (store->power & 0x01)
|
||||||
publishTopic(item->itemArr->name, s_mode,"/cmd");
|
publishTopic(item->itemArr->name, s_buffer,"/cmd");
|
||||||
|
|
||||||
else publishTopic(item->itemArr->name, "OFF","/cmd");
|
else publishTopic(item->itemArr->name, "OFF","/cmd");
|
||||||
|
*/
|
||||||
|
|
||||||
/*
|
/*
|
||||||
String raw_str;
|
String raw_str;
|
||||||
char raw[75];
|
char raw[75];
|
||||||
@@ -215,11 +273,15 @@ byte getCRC(byte req[], size_t size){
|
|||||||
|
|
||||||
void out_AC::SendData(byte req[], size_t size){
|
void out_AC::SendData(byte req[], size_t size){
|
||||||
if (!store || !item) return;
|
if (!store || !item) return;
|
||||||
if (item->itemArr->subtype == AC_SENDING)
|
if (Status() == AC_SENDING)
|
||||||
{
|
{
|
||||||
while (store->timestamp && !isTimeOver(store->timestamp,millis(),150)) yield();
|
while (store->timestamp && !isTimeOver(store->timestamp,millis(),150)) yield();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
//#if defined (__SAM3X8E__)
|
||||||
|
//if (item->getArg(0)==2) preTransmission();
|
||||||
|
//#endif
|
||||||
|
|
||||||
ACSerial->write(req, size - 1);
|
ACSerial->write(req, size - 1);
|
||||||
ACSerial->write(getCRC(req, size-1));
|
ACSerial->write(getCRC(req, size-1));
|
||||||
//ACSerial->flush();
|
//ACSerial->flush();
|
||||||
@@ -237,7 +299,10 @@ if (item->itemArr->subtype == AC_SENDING)
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
debugSerial.println();
|
debugSerial.println();
|
||||||
item->itemArr->subtype = AC_SENDING;
|
setStatus(AC_SENDING);
|
||||||
|
// #if defined (__SAM3X8E__)
|
||||||
|
// if (item->getArg(0)==2) postTransmission();
|
||||||
|
// #endif
|
||||||
}
|
}
|
||||||
|
|
||||||
inline unsigned char toHex( char ch ){
|
inline unsigned char toHex( char ch ){
|
||||||
@@ -268,15 +333,16 @@ if (!portNum)// && (g_APinDescription[0].ulPinType == PIO_PA8A_URXD))
|
|||||||
pinMode(0, INPUT_PULLUP);
|
pinMode(0, INPUT_PULLUP);
|
||||||
#if debugSerial == Serial
|
#if debugSerial == Serial
|
||||||
infoSerial<<F("AC: Serial used by AC - disabling serial logging and cmd")<<endl;
|
infoSerial<<F("AC: Serial used by AC - disabling serial logging and cmd")<<endl;
|
||||||
|
Serial.flush();
|
||||||
//sysConf.setSerialDebuglevel(0);
|
//sysConf.setSerialDebuglevel(0);
|
||||||
serialDebugLevel = 0;
|
serialDebugLevel = 0;
|
||||||
disableCMD=true;
|
disableCMD=true;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
ACSerial->begin(9600);
|
ACSerial->begin(9600);
|
||||||
item->itemArr->subtype = AC_IDLE;
|
setStatus (AC_IDLE);
|
||||||
|
|
||||||
|
|
||||||
//driverStatus = CST_INITIALIZED;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -287,10 +353,11 @@ debugSerial<<F("AC: De-Init: ")<<portNum<<endl;
|
|||||||
delete store;
|
delete store;
|
||||||
item->setPersistent(NULL);
|
item->setPersistent(NULL);
|
||||||
store = NULL;
|
store = NULL;
|
||||||
item->itemArr->subtype = CST_UNKNOWN;
|
setStatus (CST_UNKNOWN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/*
|
||||||
int out_AC::Status()
|
int out_AC::Status()
|
||||||
{
|
{
|
||||||
if (!item) return 0;
|
if (!item) return 0;
|
||||||
@@ -302,7 +369,8 @@ default:
|
|||||||
return CST_INITIALIZED;
|
return CST_INITIALIZED;
|
||||||
//return item->itemArr->subtype;
|
//return item->itemArr->subtype;
|
||||||
}
|
}
|
||||||
}
|
}*/
|
||||||
|
|
||||||
int out_AC::isActive()
|
int out_AC::isActive()
|
||||||
{
|
{
|
||||||
if (!store) return 0;
|
if (!store) return 0;
|
||||||
@@ -313,7 +381,7 @@ int out_AC::Poll(short cause)
|
|||||||
{
|
{
|
||||||
if (!store) return -1;
|
if (!store) return -1;
|
||||||
|
|
||||||
switch (item->itemArr->subtype)
|
switch (Status())
|
||||||
{
|
{
|
||||||
case AC_FAILED: return -1;
|
case AC_FAILED: return -1;
|
||||||
case AC_UNKNOWN: return -1;
|
case AC_UNKNOWN: return -1;
|
||||||
@@ -321,7 +389,7 @@ case AC_SENDING:
|
|||||||
{
|
{
|
||||||
if (store->timestamp && isTimeOver(store->timestamp,millis(),150))
|
if (store->timestamp && isTimeOver(store->timestamp,millis(),150))
|
||||||
{
|
{
|
||||||
item->itemArr->subtype = AC_IDLE;
|
setStatus(AC_IDLE);
|
||||||
store->timestamp=millisNZ();
|
store->timestamp=millisNZ();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -329,7 +397,7 @@ case AC_SENDING:
|
|||||||
|
|
||||||
if (cause!=POLLING_SLOW) return false;
|
if (cause!=POLLING_SLOW) return false;
|
||||||
|
|
||||||
if ((item->itemArr->subtype == AC_IDLE) && isTimeOver(store->timestamp,millis(),INTERVAL_AC_POLLING))
|
if ((Status() == AC_IDLE) && isTimeOver(store->timestamp,millis(),INTERVAL_AC_POLLING))
|
||||||
{
|
{
|
||||||
debugSerial.println(F("AC: Polling"));
|
debugSerial.println(F("AC: Polling"));
|
||||||
SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера
|
SendData(qstn, sizeof(qstn)/sizeof(byte)); //Опрос кондиционера
|
||||||
@@ -367,7 +435,7 @@ debugSerial<<F("AC: ")<<portNum<<F(" >> ");
|
|||||||
return true;
|
return true;
|
||||||
};
|
};
|
||||||
|
|
||||||
int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
int out_AC::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
|
||||||
{
|
{
|
||||||
//char s_mode[10];
|
//char s_mode[10];
|
||||||
char s_speed[10];
|
char s_speed[10];
|
||||||
|
|||||||
@@ -40,11 +40,11 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
int isActive() override;
|
int isActive() override;
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
int getDefaultStorageType(){return ST_FLOAT_CELSIUS;};
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
|
void SubmitParameters(const char * name, itemCmd value);
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
acPersistent * store;
|
acPersistent * store;
|
||||||
|
|||||||
@@ -6,36 +6,22 @@
|
|||||||
|
|
||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
//#include "dmx.h"
|
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
void out_counter::getConfig()
|
|
||||||
{
|
|
||||||
if (!item) return;
|
|
||||||
impulse = item->getFloatArg(0)*TENS_BASE;
|
|
||||||
|
|
||||||
period = item->getFloatArg(1)*1000.0;
|
|
||||||
//debugSerial<<"CTR: imp:"<<impulse<<" period:"<<period<<endl;
|
|
||||||
}
|
|
||||||
|
|
||||||
int out_counter::Setup()
|
int out_counter::Setup()
|
||||||
{
|
{
|
||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_counter::Stop()
|
int out_counter::Stop()
|
||||||
{
|
{
|
||||||
driverStatus = CST_UNKNOWN;
|
setStatus(CST_UNKNOWN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_counter::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int out_counter::Poll(short cause)
|
int out_counter::Poll(short cause)
|
||||||
@@ -43,22 +29,18 @@ int out_counter::Poll(short cause)
|
|||||||
if (cause==POLLING_SLOW || cause==POLLING_INT) return 0;
|
if (cause==POLLING_SLOW || cause==POLLING_INT) return 0;
|
||||||
if (!item) return 0;
|
if (!item) return 0;
|
||||||
|
|
||||||
|
uint32_t timer = item->getExt();
|
||||||
uint32_t timer = item->getExt();
|
uint32_t period = item->getFloatArg(1)*1000.0;
|
||||||
|
|
||||||
if (timer && period && isTimeOver(timer,millis(),period))
|
if (timer && period && isTimeOver(timer,millis(),period))
|
||||||
{
|
{
|
||||||
|
uint32_t impulse = item->getFloatArg(0)*TENS_BASE;
|
||||||
item->setExt(millisNZ());
|
item->setExt(millisNZ());
|
||||||
|
|
||||||
itemCmd st;
|
itemCmd st;
|
||||||
st.loadItem(item,FLAG_PARAMETERS|FLAG_COMMAND);
|
st.loadItem(item,FLAG_PARAMETERS|FLAG_COMMAND);
|
||||||
//float val = st.getFloat();
|
|
||||||
uint32_t val = st.getTens_raw();
|
uint32_t val = st.getTens_raw();
|
||||||
//short cmd = st.getCmd();
|
|
||||||
debugSerial<<"CTR: tick val:"<<val<< " + "<< impulse << endl;
|
debugSerial<<"CTR: tick val:"<<val<< " + "<< impulse << endl;
|
||||||
|
|
||||||
val+=impulse;
|
val+=impulse;
|
||||||
//st.Float(val);
|
|
||||||
st.Tens_raw(val);
|
st.Tens_raw(val);
|
||||||
st.saveItem(item);
|
st.saveItem(item);
|
||||||
debugSerial<<"CTR: tick saved val:"<<val<<endl;
|
debugSerial<<"CTR: tick saved val:"<<val<<endl;
|
||||||
@@ -69,7 +51,7 @@ uint32_t timer = item->getExt();
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int out_counter::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_counter::Ctrl(itemCmd cmd, char* subItem, bool toExecute,bool authorized)
|
||||||
{
|
{
|
||||||
debugSerial<<F("Counter: ");
|
debugSerial<<F("Counter: ");
|
||||||
cmd.debugOut();
|
cmd.debugOut();
|
||||||
|
|||||||
@@ -9,19 +9,11 @@
|
|||||||
class out_counter : public abstractOut {
|
class out_counter : public abstractOut {
|
||||||
public:
|
public:
|
||||||
|
|
||||||
out_counter(Item * _item):abstractOut(_item){ getConfig();};
|
out_counter(Item * _item):abstractOut(_item){};
|
||||||
void getConfig();
|
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
|
|
||||||
protected:
|
|
||||||
//float impulse;
|
|
||||||
uint32_t impulse;
|
|
||||||
uint32_t period;
|
|
||||||
};
|
};
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -9,28 +9,22 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "dmx.h"
|
#include "dmx.h"
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
int out_dmx::Setup()
|
int out_dmx::Setup()
|
||||||
{
|
{
|
||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
debugSerial<<F("DMX-Out Init: ")<< item->itemArr->name <<endl;
|
debugSerial<<F("DMX-Out Init: ")<< item->itemArr->name <<endl;
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_dmx::Stop()
|
int out_dmx::Stop()
|
||||||
{
|
{
|
||||||
debugSerial<<F("DMX-Out stop: ")<< item->itemArr->name << endl;
|
debugSerial<<F("DMX-Out stop: ")<< item->itemArr->name << endl;
|
||||||
driverStatus = CST_UNKNOWN;
|
setStatus(CST_UNKNOWN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_dmx::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
int out_dmx::getChanType()
|
int out_dmx::getChanType()
|
||||||
{
|
{
|
||||||
if (item)
|
if (item)
|
||||||
@@ -51,7 +45,7 @@ int out_dmx::getChanType()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_dmx::PixelCtrl(itemCmd cmd, char* subItem, bool show)
|
int out_dmx::PixelCtrl(itemCmd cmd, char* subItem, bool show, bool authorized)
|
||||||
//int out_dmx::PixelCtrl(itemCmd cmd)
|
//int out_dmx::PixelCtrl(itemCmd cmd)
|
||||||
{
|
{
|
||||||
if (!item || !show) return 0;
|
if (!item || !show) return 0;
|
||||||
|
|||||||
@@ -13,12 +13,11 @@ public:
|
|||||||
out_dmx(Item * _item):colorChannel(_item){};
|
out_dmx(Item * _item):colorChannel(_item){};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
// int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
// int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
||||||
// int PixelCtrl(itemCmd cmd) override;
|
// int PixelCtrl(itemCmd cmd) override;
|
||||||
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) override;
|
virtual int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
};
|
};
|
||||||
|
|||||||
@@ -55,7 +55,7 @@ void out_Mercury::initLine(bool full)
|
|||||||
#elif defined (ARDUINO_ARCH_ESP8266)
|
#elif defined (ARDUINO_ARCH_ESP8266)
|
||||||
modbusSerial.begin(baud, static_cast <SerialConfig>(serialParam));
|
modbusSerial.begin(baud, static_cast <SerialConfig>(serialParam));
|
||||||
#elif defined (ESP32)
|
#elif defined (ESP32)
|
||||||
if (full) modbusSerial.begin(store->baud, (serialParam),MODBUS_UART_RX_PIN,MODBUS_UART_TX_PIN);
|
if (full) modbusSerial.begin(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.updateBaudRate (baud); //Some terrible error in ESP32 core with uart reinit
|
||||||
#else
|
#else
|
||||||
modbusSerial.begin(baud, (serialParam));
|
modbusSerial.begin(baud, (serialParam));
|
||||||
@@ -78,14 +78,14 @@ store->timestamp=millisNZ();
|
|||||||
if (getConfig())
|
if (getConfig())
|
||||||
{
|
{
|
||||||
infoSerial<<F("Mercury: config loaded ")<< item->itemArr->name<<endl;
|
infoSerial<<F("Mercury: config loaded ")<< item->itemArr->name<<endl;
|
||||||
store->driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
store->lastSuccessTS = 0;
|
store->lastSuccessTS = 0;
|
||||||
initLine(true);
|
initLine(true);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ errorSerial<<F("Mercury: config error")<<endl;
|
{ errorSerial<<F("Mercury: config error")<<endl;
|
||||||
store->driverStatus = CST_FAILED;
|
setStatus(CST_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -101,18 +101,6 @@ store = NULL;
|
|||||||
return 1;
|
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()
|
short out_Mercury::connectMercury()
|
||||||
{
|
{
|
||||||
@@ -337,6 +325,7 @@ int out_Mercury::Poll(short cause)
|
|||||||
//bool lineInitialized = false;
|
//bool lineInitialized = false;
|
||||||
if (cause==POLLING_SLOW) return 0;
|
if (cause==POLLING_SLOW) return 0;
|
||||||
if (modbusBusy || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100))) return 0;
|
if (modbusBusy || ( mbusSlenceTimer && !isTimeOver(mbusSlenceTimer,millis(),100))) return 0;
|
||||||
|
if (Status() == CST_FAILED) return 0;
|
||||||
if (!getConfig()) return 0;
|
if (!getConfig()) return 0;
|
||||||
|
|
||||||
switch (Status())
|
switch (Status())
|
||||||
@@ -474,7 +463,7 @@ int out_Mercury::getChanType()
|
|||||||
|
|
||||||
|
|
||||||
//!Control unified item
|
//!Control unified item
|
||||||
int out_Mercury::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_Mercury::Ctrl(itemCmd cmd, char* subItem, bool toExecute,bool authorized)
|
||||||
{
|
{
|
||||||
if (!store) return -1;
|
if (!store) return -1;
|
||||||
|
|
||||||
|
|||||||
@@ -12,7 +12,6 @@
|
|||||||
class mercuryPersistent : public chPersistent {
|
class mercuryPersistent : public chPersistent {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
int8_t driverStatus;
|
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
uint32_t lastSuccessTS;
|
uint32_t lastSuccessTS;
|
||||||
};
|
};
|
||||||
@@ -47,9 +46,8 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
int getDefaultStorageType(){return ST_INT32;};
|
int getDefaultStorageType(){return ST_INT32;};
|
||||||
|
|
||||||
|
|
||||||
@@ -58,7 +56,6 @@ protected:
|
|||||||
uint16_t pollingInterval;
|
uint16_t pollingInterval;
|
||||||
bool getConfig();
|
bool getConfig();
|
||||||
void initLine(bool full = false);
|
void initLine(bool full = false);
|
||||||
void setStatus(short);
|
|
||||||
short connectMercury();
|
short connectMercury();
|
||||||
short disconnectMercury();
|
short disconnectMercury();
|
||||||
short getCurrentVal12(byte param, String topic,int divisor=1);
|
short getCurrentVal12(byte param, String topic,int divisor=1);
|
||||||
|
|||||||
@@ -41,6 +41,7 @@ struct serial_t
|
|||||||
#define PAR_U8L 8
|
#define PAR_U8L 8
|
||||||
#define PAR_TENS 9
|
#define PAR_TENS 9
|
||||||
#define PAR_100 10
|
#define PAR_100 10
|
||||||
|
#define PAR_COIL 11
|
||||||
|
|
||||||
|
|
||||||
const reg_t regSize_P[] PROGMEM =
|
const reg_t regSize_P[] PROGMEM =
|
||||||
@@ -55,6 +56,7 @@ const reg_t regSize_P[] PROGMEM =
|
|||||||
{ "u8l", (uint8_t) PAR_U8L },
|
{ "u8l", (uint8_t) PAR_U8L },
|
||||||
{ "x10", (uint8_t) PAR_TENS },
|
{ "x10", (uint8_t) PAR_TENS },
|
||||||
{ "100", (uint8_t) PAR_100 }
|
{ "100", (uint8_t) PAR_100 }
|
||||||
|
// { "bit", (uint8_t) PAR_COIL }
|
||||||
} ;
|
} ;
|
||||||
#define regSizeNum sizeof(regSize_P)/sizeof(reg_t)
|
#define regSizeNum sizeof(regSize_P)/sizeof(reg_t)
|
||||||
|
|
||||||
@@ -151,6 +153,8 @@ bool out_Modbus::getConfig()
|
|||||||
{
|
{
|
||||||
store->pollingRegisters=aJson.getObjectItem(pollObj, "regs");
|
store->pollingRegisters=aJson.getObjectItem(pollObj, "regs");
|
||||||
store->pollingIrs=aJson.getObjectItem(pollObj, "irs");
|
store->pollingIrs=aJson.getObjectItem(pollObj, "irs");
|
||||||
|
store->pollingCoils=aJson.getObjectItem(pollObj, "coils");
|
||||||
|
store->poolingDiscreteIns=aJson.getObjectItem(pollObj, "dins");
|
||||||
aJsonObject * delayObj= aJson.getObjectItem(pollObj, "delay");
|
aJsonObject * delayObj= aJson.getObjectItem(pollObj, "delay");
|
||||||
if (delayObj) store->pollingInterval = delayObj->valueint;
|
if (delayObj) store->pollingInterval = delayObj->valueint;
|
||||||
else store->pollingInterval = 1000;
|
else store->pollingInterval = 1000;
|
||||||
@@ -176,12 +180,12 @@ store->timestamp=millisNZ();
|
|||||||
if (getConfig())
|
if (getConfig())
|
||||||
{
|
{
|
||||||
infoSerial<<F("MBUS: config loaded ")<< item->itemArr->name<<endl;
|
infoSerial<<F("MBUS: config loaded ")<< item->itemArr->name<<endl;
|
||||||
store->driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ errorSerial<<F("MBUS: config error")<<endl;
|
{ errorSerial<<F("MBUS: config error")<<endl;
|
||||||
store->driverStatus = CST_FAILED;
|
setStatus(CST_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -189,20 +193,15 @@ else
|
|||||||
|
|
||||||
int out_Modbus::Stop()
|
int out_Modbus::Stop()
|
||||||
{
|
{
|
||||||
debugSerial.println("MBUS: De-Init");
|
debugSerial.print("MBUS: De-Init ");
|
||||||
|
debugSerial.println(item->itemArr->name);
|
||||||
|
|
||||||
delete store;
|
if (store) delete store;
|
||||||
item->setPersistent(NULL);
|
item->setPersistent(NULL);
|
||||||
store = NULL;
|
store = NULL;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_Modbus::Status()
|
|
||||||
{
|
|
||||||
if (store)
|
|
||||||
return store->driverStatus;
|
|
||||||
return CST_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
@@ -243,30 +242,40 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
//bool is8bit = false;
|
//bool is8bit = false;
|
||||||
while (paramObj)
|
while (paramObj)
|
||||||
{
|
{
|
||||||
|
int8_t parType = PAR_I16;
|
||||||
aJsonObject *regObj=NULL;
|
aJsonObject *regObj=NULL;
|
||||||
switch (regType) {
|
switch (regType) {
|
||||||
case MODBUS_HOLDING_REG_TYPE: regObj = aJson.getObjectItem(paramObj, "reg");
|
case MODBUS_HOLDING_REG_TYPE:
|
||||||
|
regObj = aJson.getObjectItem(paramObj, "reg");
|
||||||
break;
|
break;
|
||||||
case MODBUS_INPUT_REG_TYPE: regObj = aJson.getObjectItem(paramObj, "ir");
|
case MODBUS_INPUT_REG_TYPE:
|
||||||
|
regObj = aJson.getObjectItem(paramObj, "ir");
|
||||||
|
break;
|
||||||
|
case MODBUS_COIL_REG_TYPE:
|
||||||
|
regObj = aJson.getObjectItem(paramObj, "coil");
|
||||||
|
parType = PAR_COIL;
|
||||||
|
break;
|
||||||
|
case MODBUS_DISCRETE_REG_TYPE:
|
||||||
|
regObj = aJson.getObjectItem(paramObj, "din");
|
||||||
|
parType = PAR_COIL;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (regObj && regObj->valueint ==registerNum)
|
if (regObj && regObj->valueint ==registerNum)
|
||||||
{
|
{
|
||||||
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
|
|
||||||
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
|
||||||
aJsonObject *idObj = aJson.getObjectItem(paramObj, "id");
|
aJsonObject *idObj = aJson.getObjectItem(paramObj, "id");
|
||||||
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
||||||
uint16_t data = node.getResponseBuffer(posInBuffer);
|
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 executeWithoutCheck=false; //Afler recurrent check, all dublicatess and suppressing checked by recurrent
|
||||||
bool submitRecurrentOut = false; //false if recurrent check find duplicates
|
bool submitRecurrentOut = false; //false if recurrent check find duplicates
|
||||||
char buf[16];
|
char buf[16];
|
||||||
|
|
||||||
//bool isSigned=false;
|
uint32_t param =0;
|
||||||
if (typeObj && typeObj->type == aJson_String) regType=str2regSize(typeObj->valuestring);
|
itemCmd mappedParam;
|
||||||
switch(regType) {
|
aJsonObject *typeObj = aJson.getObjectItem(paramObj, "type");
|
||||||
|
aJsonObject *mapObj = aJson.getObjectItem(paramObj, "map");
|
||||||
|
|
||||||
|
if (typeObj && typeObj->type == aJson_String) parType=str2regSize(typeObj->valuestring);
|
||||||
|
switch(parType) {
|
||||||
|
|
||||||
case PAR_I16:
|
case PAR_I16:
|
||||||
//isSigned=true;
|
//isSigned=true;
|
||||||
@@ -278,6 +287,7 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
param=data;
|
param=data;
|
||||||
mappedParam.Int((uint32_t)data);
|
mappedParam.Int((uint32_t)data);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case PAR_I32:
|
case PAR_I32:
|
||||||
//isSigned=true;
|
//isSigned=true;
|
||||||
param = swap(data ) | swap(node.getResponseBuffer(posInBuffer+1)<<16);
|
param = swap(data ) | swap(node.getResponseBuffer(posInBuffer+1)<<16);
|
||||||
@@ -310,15 +320,104 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
param=data;
|
param=data;
|
||||||
mappedParam.Tens_raw((int16_t) data * (TENS_BASE/100));
|
mappedParam.Tens_raw((int16_t) data * (TENS_BASE/100));
|
||||||
mappedParam.Float((int32_t) (int16_t) data/100.);
|
mappedParam.Float((int32_t) (int16_t) data/100.);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAR_COIL:
|
||||||
|
param = (node.getResponseBuffer(posInBuffer/16) >> (posInBuffer % 16)) & 1;
|
||||||
|
mappedParam.Int((uint32_t)param);
|
||||||
}
|
}
|
||||||
|
|
||||||
debugSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from ")<<regType<<F(":")<<paramObj->name<<endl;
|
debugSerial << F("MBUSD: got ")<<mappedParam.toString(buf,sizeof(buf))<< F(" from type ")<<parType<<F(":")<<paramObj->name<<endl;
|
||||||
|
|
||||||
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
|
if (mapObj && (mapObj->type==aJson_Array || mapObj->type==aJson_Object))
|
||||||
{
|
{
|
||||||
mappedParam=mappedParam.doReverseMapping(mapObj);
|
mappedParam=mappedParam.doReverseMapping(mapObj);
|
||||||
if (!mappedParam.isCommand() && !mappedParam.isValue()) //Not mapped
|
if (!mappedParam.isCommand() && !mappedParam.isValue()) //Not mapped
|
||||||
{
|
{
|
||||||
|
aJsonObject *defMappingObj;
|
||||||
|
defMappingObj = aJson.getObjectItem(mapObj, "def");
|
||||||
|
if (defMappingObj)
|
||||||
|
{
|
||||||
|
switch (defMappingObj->type)
|
||||||
|
{
|
||||||
|
case aJson_Int: //register/coil/.. number
|
||||||
|
debugSerial<<F("Searching reg#")<<defMappingObj->valueint<<endl;
|
||||||
|
if ((defMappingObj->valueint>= registerFrom) && (defMappingObj->valueint<=registerTo))
|
||||||
|
{
|
||||||
|
mappedParam = findRegister(defMappingObj->valueint,defMappingObj->valueint-registerFrom,regType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||||
|
executeWithoutCheck=true;
|
||||||
|
}
|
||||||
|
else errorSerial<<F("reg# out of range")<<endl;
|
||||||
|
|
||||||
|
break;
|
||||||
|
case aJson_String: // parameter name
|
||||||
|
debugSerial<<F("Searching reg: ")<<defMappingObj->valuestring<<endl;
|
||||||
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
|
{
|
||||||
|
//Searching item param for nested mapping
|
||||||
|
aJsonObject *itemParObj = aJson.getObjectItem(itemParametersObj,defMappingObj->valuestring);
|
||||||
|
if (itemParObj)
|
||||||
|
{
|
||||||
|
//aJsonObject * markObj = execObj;
|
||||||
|
//if (execObj->type == aJson_Array) markObj = execObj->child;
|
||||||
|
//Retrive previous data
|
||||||
|
aJsonObject *lastMeasured = aJson.getObjectItem(itemParObj,"@S");
|
||||||
|
if (lastMeasured && lastMeasured->type ==aJson_Int)
|
||||||
|
{
|
||||||
|
debugSerial<<F("LastKnown value: ")<<lastMeasured->valueint<<endl;
|
||||||
|
//Searching template param for nested mapping
|
||||||
|
aJsonObject * templateParObj = aJson.getObjectItem(store->parameters,defMappingObj->valuestring);
|
||||||
|
if (templateParObj)
|
||||||
|
{
|
||||||
|
int8_t nestedParType = PAR_I16;
|
||||||
|
|
||||||
|
aJsonObject * nestedTypeObj = aJson.getObjectItem(templateParObj, "type");
|
||||||
|
if (nestedTypeObj && nestedTypeObj->type == aJson_String) parType=str2regSize(nestedTypeObj->valuestring);
|
||||||
|
|
||||||
|
switch(nestedParType) {
|
||||||
|
case PAR_I16:
|
||||||
|
case PAR_I32:
|
||||||
|
mappedParam.Int((int32_t)lastMeasured->valueint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAR_U32:
|
||||||
|
case PAR_U16:
|
||||||
|
case PAR_U8L:
|
||||||
|
case PAR_U8H:
|
||||||
|
case PAR_COIL:
|
||||||
|
mappedParam.Int((uint32_t)lastMeasured->valueint);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAR_TENS:
|
||||||
|
mappedParam.Tens((int16_t) data);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case PAR_100:
|
||||||
|
mappedParam.Tens_raw((int16_t) lastMeasured->valueint * (TENS_BASE/100));
|
||||||
|
mappedParam.Float((int32_t) (int16_t) lastMeasured->valueint/100.);
|
||||||
|
break;
|
||||||
|
default: errorSerial<<F("Invalid regtype")<<endl;
|
||||||
|
}
|
||||||
|
|
||||||
|
aJsonObject * nestedMapObj = aJson.getObjectItem(templateParObj, "map");
|
||||||
|
if (nestedMapObj && (nestedMapObj->type==aJson_Array || nestedMapObj->type==aJson_Object)) mappedParam=mappedParam.doReverseMapping(nestedMapObj);
|
||||||
|
debugSerial << F("MBUSD: NestedMapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||||
|
|
||||||
|
if (!(lastMeasured->subtype & MB_VALUE_OUTDATED))
|
||||||
|
{
|
||||||
|
executeWithoutCheck=true;
|
||||||
|
submitRecurrentOut=true;
|
||||||
|
lastMeasured->subtype|= MB_VALUE_OUTDATED;
|
||||||
|
}
|
||||||
|
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
/*
|
||||||
aJsonObject *nextRegObj = NULL;
|
aJsonObject *nextRegObj = NULL;
|
||||||
int registerType = 0;
|
int registerType = 0;
|
||||||
|
|
||||||
@@ -328,15 +427,26 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
{
|
{
|
||||||
nextRegObj = aJson.getObjectItem(paramObj, "nextir");
|
nextRegObj = aJson.getObjectItem(paramObj, "nextir");
|
||||||
if (nextRegObj) registerType=MODBUS_INPUT_REG_TYPE;
|
if (nextRegObj) registerType=MODBUS_INPUT_REG_TYPE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextRegObj = aJson.getObjectItem(paramObj, "nextcoil");
|
||||||
|
if (nextRegObj) registerType=MODBUS_COIL_REG_TYPE;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
nextRegObj = aJson.getObjectItem(paramObj, "nextdin");
|
||||||
|
if (nextRegObj) registerType=MODBUS_DISCRETE_REG_TYPE;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (registerType && (nextRegObj->type) ==aJson_Int && (nextRegObj->valueint>= registerFrom) && (nextRegObj->valueint<=registerTo))
|
if (registerType && nextRegObj && (nextRegObj->type) ==aJson_Int && (nextRegObj->valueint>= registerFrom) && (nextRegObj->valueint<=registerTo))
|
||||||
{
|
{
|
||||||
debugSerial<<F("Recurrent searching nextreg")<<endl;
|
debugSerial<<F("Recurrent searching nextreg")<<endl;
|
||||||
mappedParam = findRegister(nextRegObj->valueint,nextRegObj->valueint-registerFrom,registerType,registerFrom,registerTo,false,&submitRecurrentOut);
|
mappedParam = findRegister(nextRegObj->valueint,nextRegObj->valueint-registerFrom,registerType,registerFrom,registerTo,false,&submitRecurrentOut);
|
||||||
executeWithoutCheck=true;
|
executeWithoutCheck=true;
|
||||||
}
|
}
|
||||||
else errorSerial<<F("nextreg out of range")<<endl;
|
else errorSerial<<F("nextreg out of range")<<endl;
|
||||||
|
*/
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
debugSerial << F("MBUSD: Mapped:")<<mappedParam.toString(buf,sizeof(buf))<<endl;
|
||||||
@@ -368,7 +478,11 @@ itemCmd out_Modbus::findRegister(uint16_t registerNum, uint16_t posInBuffer, uin
|
|||||||
{
|
{
|
||||||
if (lastMeasured->valueint == param)
|
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
|
||||||
|
{
|
||||||
|
lastMeasured->valueint=param;
|
||||||
|
lastMeasured->subtype&=~MB_VALUE_OUTDATED;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else //No container to store value yet
|
else //No container to store value yet
|
||||||
@@ -416,7 +530,6 @@ return itemCmd();
|
|||||||
{
|
{
|
||||||
if (!reg) return;
|
if (!reg) return;
|
||||||
reg=reg->child;
|
reg=reg->child;
|
||||||
//aJsonObject * reg = store->pollingRegisters->child;
|
|
||||||
while (reg)
|
while (reg)
|
||||||
{
|
{
|
||||||
switch (reg->type)
|
switch (reg->type)
|
||||||
@@ -424,11 +537,9 @@ return itemCmd();
|
|||||||
case aJson_Int:
|
case aJson_Int:
|
||||||
{
|
{
|
||||||
int registerNum = reg->valueint;
|
int registerNum = reg->valueint;
|
||||||
//if (readModbus(registerNum,MODBUS_HOLDING_REG_TYPE,1))
|
|
||||||
if (readModbus(registerNum,regType,1))
|
if (readModbus(registerNum,regType,1))
|
||||||
{
|
{
|
||||||
findRegister(registerNum,0,regType,registerNum,registerNum);
|
findRegister(registerNum,0,regType,registerNum,registerNum);
|
||||||
// data = node.getResponseBuffer(j);
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
@@ -438,14 +549,12 @@ return itemCmd();
|
|||||||
int registerFrom=aJson.getArrayItem(reg, 0)->valueint;
|
int registerFrom=aJson.getArrayItem(reg, 0)->valueint;
|
||||||
int registerTo=aJson.getArrayItem(reg, 1)->valueint;
|
int registerTo=aJson.getArrayItem(reg, 1)->valueint;
|
||||||
|
|
||||||
//if (readModbus(registerFrom,MODBUS_HOLDING_REG_TYPE,registerTo-registerFrom+1))
|
|
||||||
if (readModbus(registerFrom,regType,registerTo-registerFrom+1))
|
if (readModbus(registerFrom,regType,registerTo-registerFrom+1))
|
||||||
{ debugSerial<<endl;
|
{ debugSerial<<endl;
|
||||||
for(int i=registerFrom;i<=registerTo;i++)
|
for(int i=registerFrom;i<=registerTo;i++)
|
||||||
{
|
{
|
||||||
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
|
findRegister(i,i-registerFrom,regType,registerFrom,registerTo);
|
||||||
}
|
}
|
||||||
//data = node.getResponseBuffer(j);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
@@ -481,7 +590,13 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
|||||||
if (!templateParamObj) {errorSerial<<F(" internal send error - no template")<<endl; return -1;}
|
if (!templateParamObj) {errorSerial<<F(" internal send error - no template")<<endl; return -1;}
|
||||||
|
|
||||||
aJsonObject * regObj = aJson.getObjectItem(templateParamObj, "reg");
|
aJsonObject * regObj = aJson.getObjectItem(templateParamObj, "reg");
|
||||||
if (!regObj) {errorSerial<<F(" internal send error - no regObj")<<endl; return -2;}
|
|
||||||
|
if (!regObj)
|
||||||
|
{
|
||||||
|
regObj = aJson.getObjectItem(templateParamObj, "coil");
|
||||||
|
if (!regObj) {errorSerial<<F(" internal send error - no reg/coil")<<endl; return -2;}
|
||||||
|
else regType = PAR_COIL;
|
||||||
|
}
|
||||||
|
|
||||||
int res = -1;
|
int res = -1;
|
||||||
|
|
||||||
@@ -513,6 +628,9 @@ int out_Modbus::sendModbus(char * paramName, int32_t value, uint8_t regType)
|
|||||||
case PAR_I8H:
|
case PAR_I8H:
|
||||||
res = node.writeSingleRegister(regObj->valueint,(value & 0xFFFF)>> 8);
|
res = node.writeSingleRegister(regObj->valueint,(value & 0xFFFF)>> 8);
|
||||||
break;
|
break;
|
||||||
|
case PAR_COIL:
|
||||||
|
res = node.writeSingleCoil (regObj->valueint,value);
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
mbusSlenceTimer = millisNZ();
|
mbusSlenceTimer = millisNZ();
|
||||||
debugSerial<<F("Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
|
debugSerial<<F("Res: ")<<res<<F(" ")<<paramName<<" reg:"<<regObj->valueint<<F(" val:")<<value<<endl;
|
||||||
@@ -530,7 +648,8 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
|||||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
{
|
{
|
||||||
aJsonObject *execObj = itemParametersObj->child;
|
aJsonObject *execObj = itemParametersObj->child;
|
||||||
while (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array) )
|
bool onceSendOk=false;
|
||||||
|
while (execObj && ((execObj->type == aJson_Object) || (execObj->type == aJson_Array)) && !onceSendOk)
|
||||||
{
|
{
|
||||||
|
|
||||||
if ((execObj->subtype & MB_NEED_SEND) && !(execObj->subtype & MB_SEND_ERROR))
|
if ((execObj->subtype & MB_NEED_SEND) && !(execObj->subtype & MB_SEND_ERROR))
|
||||||
@@ -553,6 +672,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
|||||||
{
|
{
|
||||||
case 1: //success
|
case 1: //success
|
||||||
execObj->subtype&=~ MB_NEED_SEND;
|
execObj->subtype&=~ MB_NEED_SEND;
|
||||||
|
onceSendOk=true;
|
||||||
///return 1; //relax
|
///return 1; //relax
|
||||||
|
|
||||||
break;
|
break;
|
||||||
@@ -581,14 +701,14 @@ if (isTimeOver(store->timestamp,millis(),store->pollingInterval) && ( !mbusSlenc
|
|||||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
{
|
{
|
||||||
aJsonObject *execObj = itemParametersObj->child;
|
aJsonObject *execObj = itemParametersObj->child;
|
||||||
while (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array))
|
while (execObj && ((execObj->type == aJson_Object) || (execObj->type == aJson_Array)))
|
||||||
{
|
{
|
||||||
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
if (execObj->subtype & MB_SEND_ERROR) execObj->subtype&=~ MB_SEND_ERROR;
|
||||||
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS)
|
if ((execObj->subtype & 0x3) >= MB_SEND_ATTEMPTS)
|
||||||
{
|
{
|
||||||
//execObj->subtype&=~ MB_NEED_SEND;
|
//execObj->subtype&=~ MB_NEED_SEND;
|
||||||
//Clean ERROR, NEED, Attempts
|
//Clean ERROR, NEED, Attempts
|
||||||
errorSerial<<"MBUS: send failed "<<item->itemArr->name<<endl;
|
errorSerial<<"MBUS: send failed "<<item->itemArr->name<<"/"<<execObj->name<<endl;
|
||||||
execObj->subtype = 0;
|
execObj->subtype = 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -597,7 +717,7 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// if some polling configured
|
// if some polling configured
|
||||||
if (store->pollingRegisters || store->pollingIrs)
|
if (store->pollingRegisters || store->pollingIrs || store->pollingCoils || store->poolingDiscreteIns)
|
||||||
{
|
{
|
||||||
debugSerial<<F("MBUSD: Poll ")<< item->itemArr->name << endl;
|
debugSerial<<F("MBUSD: Poll ")<< item->itemArr->name << endl;
|
||||||
modbusBusy=1;
|
modbusBusy=1;
|
||||||
@@ -610,6 +730,8 @@ if (store->pollingRegisters || store->pollingIrs)
|
|||||||
|
|
||||||
pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE);
|
pollModbus(store->pollingRegisters,MODBUS_HOLDING_REG_TYPE);
|
||||||
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
|
pollModbus(store->pollingIrs,MODBUS_INPUT_REG_TYPE);
|
||||||
|
pollModbus(store->pollingCoils,MODBUS_COIL_REG_TYPE);
|
||||||
|
pollModbus(store->poolingDiscreteIns ,MODBUS_DISCRETE_REG_TYPE);
|
||||||
debugSerial<<F("MBUSD: endPoll ")<< item->itemArr->name << endl;
|
debugSerial<<F("MBUSD: endPoll ")<< item->itemArr->name << endl;
|
||||||
|
|
||||||
//Non blocking waiting to release line
|
//Non blocking waiting to release line
|
||||||
@@ -677,7 +799,7 @@ aJsonObject * itemParametersObj = aJson.getArrayItem(item->itemArg, 2);
|
|||||||
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
||||||
{
|
{
|
||||||
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
aJsonObject *execObj = aJson.getObjectItem(itemParametersObj,suffixStr);
|
||||||
if (execObj && (execObj->type == aJson_Object) || (execObj->type == aJson_Array))
|
if (execObj && ((execObj->type == aJson_Object) || (execObj->type == aJson_Array)))
|
||||||
{
|
{
|
||||||
/*
|
/*
|
||||||
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
aJsonObject *polledValue = aJson.getObjectItem(execObj,"@S");
|
||||||
@@ -709,7 +831,11 @@ if (itemParametersObj && itemParametersObj->type ==aJson_Object)
|
|||||||
}
|
}
|
||||||
|
|
||||||
aJsonObject *polledValue = aJson.getObjectItem(markObj,"@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
|
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
|
||||||
|
polledValue->subtype&=~MB_VALUE_OUTDATED;
|
||||||
|
}
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -725,7 +851,7 @@ else return 0;
|
|||||||
// 2. custom textual subItem
|
// 2. custom textual subItem
|
||||||
// 3. non-standard numeric suffix Code equal param id
|
// 3. non-standard numeric suffix Code equal param id
|
||||||
|
|
||||||
int out_Modbus::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_Modbus::Ctrl(itemCmd cmd, char* subItem, bool toExecute,bool authorized)
|
||||||
{
|
{
|
||||||
if (!store) return -1;
|
if (!store) return -1;
|
||||||
|
|
||||||
|
|||||||
@@ -11,20 +11,22 @@
|
|||||||
class mbPersistent : public chPersistent {
|
class mbPersistent : public chPersistent {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// int addr
|
|
||||||
int8_t driverStatus;
|
|
||||||
int baud;
|
int baud;
|
||||||
serialParamType serialParam;
|
serialParamType serialParam;
|
||||||
uint16_t pollingInterval;
|
uint16_t pollingInterval;
|
||||||
uint32_t timestamp;
|
uint32_t timestamp;
|
||||||
aJsonObject * pollingRegisters;
|
aJsonObject * pollingRegisters;
|
||||||
aJsonObject * pollingIrs;
|
aJsonObject * pollingIrs;
|
||||||
|
aJsonObject * pollingCoils;
|
||||||
|
aJsonObject * poolingDiscreteIns;
|
||||||
aJsonObject * parameters;
|
aJsonObject * parameters;
|
||||||
};
|
};
|
||||||
|
|
||||||
#define MB_NEED_SEND 8
|
#define MB_NEED_SEND 8
|
||||||
#define MB_SEND_ERROR 4
|
#define MB_SEND_ERROR 4
|
||||||
#define MB_SEND_ATTEMPTS 3
|
#define MB_SEND_ATTEMPTS 3
|
||||||
|
#define MB_VALUE_OUTDATED 1
|
||||||
|
|
||||||
|
|
||||||
class out_Modbus : public abstractOut {
|
class out_Modbus : public abstractOut {
|
||||||
@@ -34,9 +36,8 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
int getDefaultStorageType(){return ST_INT32;};
|
int getDefaultStorageType(){return ST_INT32;};
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
void out_Motor::getConfig()
|
void out_Motor::getConfig()
|
||||||
{
|
{
|
||||||
@@ -51,6 +50,7 @@ int out_Motor::Setup()
|
|||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
getConfig();
|
getConfig();
|
||||||
debugSerial.println("Motor: Init");
|
debugSerial.println("Motor: Init");
|
||||||
|
if (isProtectedPin(pinUp)||isProtectedPin(pinDown)) {errorSerial<<F("pin disabled")<<endl;return 0;}
|
||||||
pinMode(pinUp,OUTPUT);
|
pinMode(pinUp,OUTPUT);
|
||||||
pinMode(pinDown,OUTPUT);
|
pinMode(pinDown,OUTPUT);
|
||||||
|
|
||||||
@@ -63,7 +63,7 @@ pinMode(pinFeedback, INPUT);
|
|||||||
item->setExt(0);
|
item->setExt(0);
|
||||||
item->clearFlag(FLAG_ACTION_NEEDED);
|
item->clearFlag(FLAG_ACTION_NEEDED);
|
||||||
item->clearFlag(FLAG_ACTION_IN_PROCESS);
|
item->clearFlag(FLAG_ACTION_IN_PROCESS);
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
motorQuote = MOTOR_QUOTE;
|
motorQuote = MOTOR_QUOTE;
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
@@ -71,34 +71,16 @@ return 1;
|
|||||||
int out_Motor::Stop()
|
int out_Motor::Stop()
|
||||||
{
|
{
|
||||||
debugSerial.println("Motor: De-Init");
|
debugSerial.println("Motor: De-Init");
|
||||||
|
item->setExt(0);
|
||||||
|
setStatus(CST_UNKNOWN);
|
||||||
|
|
||||||
|
if (isProtectedPin(pinUp)||isProtectedPin(pinDown)) {errorSerial<<F("pin disabled")<<endl;return 0;}
|
||||||
digitalWrite(pinUp,INACTIVE);
|
digitalWrite(pinUp,INACTIVE);
|
||||||
digitalWrite(pinDown,INACTIVE);
|
digitalWrite(pinDown,INACTIVE);
|
||||||
|
|
||||||
item->setExt(0);
|
|
||||||
driverStatus = CST_UNKNOWN;
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_Motor::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
int out_Motor::isActive()
|
|
||||||
{
|
|
||||||
itemCmd st;
|
|
||||||
switch (item->getCmd())
|
|
||||||
{
|
|
||||||
case CMD_OFF:
|
|
||||||
case CMD_HALT:
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
st.loadItem(item);
|
|
||||||
return st.getPercents255();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int out_Motor::Poll(short cause)
|
int out_Motor::Poll(short cause)
|
||||||
{
|
{
|
||||||
if (cause==POLLING_SLOW) return 0;
|
if (cause==POLLING_SLOW) return 0;
|
||||||
@@ -117,6 +99,8 @@ if (!item->getFlag(FLAG_ACTION_IN_PROCESS))
|
|||||||
else return 0;
|
else return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (isProtectedPin(pinUp)||isProtectedPin(pinDown)) {return 0;}
|
||||||
|
|
||||||
uint32_t motorOfftime = item->getExt();
|
uint32_t motorOfftime = item->getExt();
|
||||||
itemCmd st;
|
itemCmd st;
|
||||||
st.loadItem(item);
|
st.loadItem(item);
|
||||||
@@ -151,7 +135,7 @@ else if (curPos>=0)
|
|||||||
else
|
else
|
||||||
dif=targetPos-255/2; // Have No feedback
|
dif=targetPos-255/2; // Have No feedback
|
||||||
|
|
||||||
debugSerial<<F("Motor: 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)
|
if (dif<-POS_ERR)
|
||||||
{
|
{
|
||||||
@@ -261,7 +245,7 @@ int out_Motor::getChanType()
|
|||||||
|
|
||||||
|
|
||||||
|
|
||||||
int out_Motor::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
int out_Motor::Ctrl(itemCmd cmd, char* subItem , bool toExecute,bool authorized)
|
||||||
{
|
{
|
||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
if (cmd.isCommand() && !suffixCode) suffixCode=S_CMD; //if some known command find, but w/o correct suffix - got it
|
||||||
|
|||||||
@@ -12,7 +12,7 @@
|
|||||||
#define MIN_PWM 70
|
#define MIN_PWM 70
|
||||||
// The number of simultaniusly working motors
|
// The number of simultaniusly working motors
|
||||||
#ifndef MOTOR_QUOTE
|
#ifndef MOTOR_QUOTE
|
||||||
#define MOTOR_QUOTE 1
|
#define MOTOR_QUOTE 2
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
static int8_t motorQuote = MOTOR_QUOTE;
|
static int8_t motorQuote = MOTOR_QUOTE;
|
||||||
@@ -24,12 +24,11 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
//int isActive() override;
|
//int isActive() override;
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int getDefaultStorageType(){return ST_PERCENTS255;};
|
int getDefaultStorageType(){return ST_PERCENTS255;};
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
|
|
||||||
int8_t pinUp;
|
int8_t pinUp;
|
||||||
int8_t pinDown;
|
int8_t pinDown;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "item.h"
|
#include "item.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
void out_Multivent::getConfig()
|
void out_Multivent::getConfig()
|
||||||
{
|
{
|
||||||
@@ -46,7 +45,7 @@ if (gatesObj /*&& aJson.getArraySize(item->itemArg)>=2*/)
|
|||||||
i=i->next;
|
i=i->next;
|
||||||
}
|
}
|
||||||
debugSerial << F ("MultiVent init")<< endl;
|
debugSerial << F ("MultiVent init")<< endl;
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -58,30 +57,10 @@ return 0;
|
|||||||
int out_Multivent::Stop()
|
int out_Multivent::Stop()
|
||||||
{
|
{
|
||||||
debugSerial << F ("Multivent De-Init") << endl;
|
debugSerial << F ("Multivent De-Init") << endl;
|
||||||
driverStatus = CST_UNKNOWN;
|
setStatus(CST_UNKNOWN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_Multivent::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
int out_Multivent::isActive()
|
|
||||||
{
|
|
||||||
itemCmd st;
|
|
||||||
switch (item->getCmd())
|
|
||||||
{
|
|
||||||
case CMD_OFF:
|
|
||||||
case CMD_HALT:
|
|
||||||
return 0;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
st.loadItem(item);
|
|
||||||
return st.getPercents255();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
*/
|
|
||||||
int out_Multivent::Poll(short cause)
|
int out_Multivent::Poll(short cause)
|
||||||
{
|
{
|
||||||
return 0;
|
return 0;
|
||||||
@@ -93,8 +72,7 @@ int out_Multivent::getChanType()
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute, bool authorized)
|
||||||
int out_Multivent::Ctrl(itemCmd cmd, char* subItem , bool toExecute)
|
|
||||||
{
|
{
|
||||||
|
|
||||||
if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
if (cmd.getCmd()==CMD_DISABLE || cmd.getCmd()==CMD_ENABLE) return 0;
|
||||||
|
|||||||
@@ -15,11 +15,10 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
//int isActive() override;
|
//int isActive() override;
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int getDefaultStorageType(){return ST_PERCENTS255;};
|
int getDefaultStorageType(){return ST_PERCENTS255;};
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
protected:
|
protected:
|
||||||
void getConfig();
|
void getConfig();
|
||||||
aJsonObject * gatesObj;
|
aJsonObject * gatesObj;
|
||||||
|
|||||||
@@ -125,12 +125,12 @@ if (getConfig())
|
|||||||
// if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
// if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||||
// if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
// if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||||
store->prevOut = -2.0;
|
store->prevOut = -2.0;
|
||||||
store->driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ errorSerial<<F("PID: config error")<<endl;
|
{ errorSerial<<F("PID: config error")<<endl;
|
||||||
store->driverStatus = CST_FAILED;
|
setStatus(CST_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -138,7 +138,8 @@ else
|
|||||||
|
|
||||||
int out_pid::Stop()
|
int out_pid::Stop()
|
||||||
{
|
{
|
||||||
debugSerial.println("PID: De-Init");
|
debugSerial.print(F("PID: De-Init "));
|
||||||
|
debugSerial.println(item->itemArr->name);
|
||||||
if (store) delete (store->pid);
|
if (store) delete (store->pid);
|
||||||
delete store;
|
delete store;
|
||||||
item->setPersistent(NULL);
|
item->setPersistent(NULL);
|
||||||
@@ -146,12 +147,6 @@ store = NULL;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_pid::Status()
|
|
||||||
{
|
|
||||||
if (store)
|
|
||||||
return store->driverStatus;
|
|
||||||
return CST_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
int out_pid::isActive()
|
int out_pid::isActive()
|
||||||
{
|
{
|
||||||
@@ -286,7 +281,7 @@ int out_pid::getChanType()
|
|||||||
// /val suffix - to put value into controller
|
// /val suffix - to put value into controller
|
||||||
// accept ON and OFF commands
|
// accept ON and OFF commands
|
||||||
|
|
||||||
int out_pid::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_pid::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authorized)
|
||||||
{
|
{
|
||||||
if (!store || !store->pid || (Status() != CST_INITIALIZED)) return 0;
|
if (!store || !store->pid || (Status() != CST_INITIALIZED)) return 0;
|
||||||
int suffixCode = cmd.getSuffix();
|
int suffixCode = cmd.getSuffix();
|
||||||
|
|||||||
@@ -15,7 +15,6 @@ public:
|
|||||||
double input;
|
double input;
|
||||||
double setpoint;
|
double setpoint;
|
||||||
float prevOut;
|
float prevOut;
|
||||||
int driverStatus;
|
|
||||||
uint32_t alarmTimer;
|
uint32_t alarmTimer;
|
||||||
bool alarmArmed;
|
bool alarmArmed;
|
||||||
uint16_t alarmTimeout; //in sec
|
uint16_t alarmTimeout; //in sec
|
||||||
@@ -30,11 +29,10 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
int isActive() override;
|
int isActive() override;
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int getDefaultStorageType(){return ST_FLOAT;};
|
int getDefaultStorageType(){return ST_FLOAT;};
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
void alarm(bool);
|
void alarm(bool);
|
||||||
|
|
||||||
|
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "dmx.h"
|
#include "dmx.h"
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
#if defined(ARDUINO_ARCH_ESP32)
|
#if defined(ARDUINO_ARCH_ESP32)
|
||||||
void analogWrite(int pin, int val)
|
void analogWrite(int pin, int val)
|
||||||
@@ -20,7 +19,7 @@ void analogWrite(int pin, int val)
|
|||||||
int out_pwm::Setup()
|
int out_pwm::Setup()
|
||||||
{
|
{
|
||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
debugSerial<<F("PWM-Out #")<<iaddr<<F(" init")<<endl;
|
debugSerial<<F("PWM-Out #")<<iaddr<<F(" ")<<item->itemArr->name<<F(" init")<<endl;
|
||||||
if (!item || iaddr) return 0;
|
if (!item || iaddr) return 0;
|
||||||
|
|
||||||
switch (getChanType())
|
switch (getChanType())
|
||||||
@@ -55,13 +54,13 @@ switch (getChanType())
|
|||||||
TCCR3B |= tval;
|
TCCR3B |= tval;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_pwm::Stop()
|
int out_pwm::Stop()
|
||||||
{
|
{
|
||||||
debugSerial<<F("PWM-Out #")<<iaddr<<F(" stop")<<endl;
|
debugSerial<<F("PWM-Out #")<<iaddr<<F(" ")<<item->itemArr->name<<F(" stop")<<endl;
|
||||||
|
|
||||||
switch (getChanType())
|
switch (getChanType())
|
||||||
{
|
{
|
||||||
@@ -75,15 +74,10 @@ switch (getChanType())
|
|||||||
default:
|
default:
|
||||||
pinMode(iaddr, INPUT);
|
pinMode(iaddr, INPUT);
|
||||||
}
|
}
|
||||||
driverStatus = CST_UNKNOWN;
|
setStatus(CST_UNKNOWN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_pwm::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int out_pwm::getChanType()
|
int out_pwm::getChanType()
|
||||||
{
|
{
|
||||||
@@ -112,7 +106,7 @@ int out_pwm::getChanType()
|
|||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_pwm::PixelCtrl(itemCmd cmd, char* subItem, bool show)
|
int out_pwm::PixelCtrl(itemCmd cmd, char* subItem, bool show, bool authorized)
|
||||||
{
|
{
|
||||||
if (!item || !iaddr || !show) return 0;
|
if (!item || !iaddr || !show) return 0;
|
||||||
|
|
||||||
@@ -132,6 +126,7 @@ switch (cmd.getCmd()){
|
|||||||
{
|
{
|
||||||
case CH_PWM:
|
case CH_PWM:
|
||||||
{ short k;
|
{ short k;
|
||||||
|
if (authorized || !isProtectedPin(iaddr))
|
||||||
analogWrite(iaddr, k=cmd.getPercents255(inverse));
|
analogWrite(iaddr, k=cmd.getPercents255(inverse));
|
||||||
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
debugSerial<<F("Pin:")<<iaddr<<F("=")<<k<<endl;
|
||||||
return 1;
|
return 1;
|
||||||
@@ -151,13 +146,20 @@ itemCmd st(storageType,CMD_VOID);
|
|||||||
st.assignFrom(cmd);
|
st.assignFrom(cmd);
|
||||||
|
|
||||||
switch (cType)
|
switch (cType)
|
||||||
{
|
{ short pin;
|
||||||
case CH_RGBW:
|
case CH_RGBW:
|
||||||
analogWrite(getChannelAddr(3), st.param.w);
|
pin=getChannelAddr(3);
|
||||||
|
if (authorized || !isProtectedPin(pin)) analogWrite(pin, st.param.w);
|
||||||
|
|
||||||
case CH_RGB:
|
case CH_RGB:
|
||||||
analogWrite(iaddr, st.param.r);
|
|
||||||
analogWrite(getChannelAddr(1), st.param.g);
|
if (authorized || !isProtectedPin(iaddr)) analogWrite(iaddr, st.param.r);
|
||||||
analogWrite(getChannelAddr(2), st.param.b);
|
|
||||||
|
pin=getChannelAddr(1);
|
||||||
|
if (authorized || !isProtectedPin(pin)) analogWrite(pin, st.param.g);
|
||||||
|
|
||||||
|
pin=getChannelAddr(2);
|
||||||
|
if (authorized || !isProtectedPin(pin)) analogWrite(pin, st.param.b);
|
||||||
break;
|
break;
|
||||||
default: ;
|
default: ;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -13,11 +13,11 @@ public:
|
|||||||
out_pwm(Item * _item):colorChannel(_item){numChannels=0;};
|
out_pwm(Item * _item):colorChannel(_item){numChannels=0;};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
||||||
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) override;
|
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
short numChannels;
|
short numChannels;
|
||||||
|
|||||||
@@ -8,7 +8,6 @@
|
|||||||
#include "main.h"
|
#include "main.h"
|
||||||
#include "dmx.h"
|
#include "dmx.h"
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
void out_relay::getConfig()
|
void out_relay::getConfig()
|
||||||
{
|
{
|
||||||
@@ -37,13 +36,13 @@ int out_relay::Setup()
|
|||||||
abstractOut::Setup();
|
abstractOut::Setup();
|
||||||
|
|
||||||
debugSerial<<F("Relay-Out #")<<pin<<F(" init")<<endl;
|
debugSerial<<F("Relay-Out #")<<pin<<F(" init")<<endl;
|
||||||
|
if (isProtectedPin(pin)) {errorSerial<<F("pin disabled")<<endl;return 0;}
|
||||||
pinMode(pin, OUTPUT);
|
pinMode(pin, OUTPUT);
|
||||||
digitalWrite(pin,INACTIVE);
|
digitalWrite(pin,INACTIVE);
|
||||||
if (item) item->setExt(0);
|
if (item) item->setExt(0);
|
||||||
//if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
//if (item->getCmd()) item->setFlag(FLAG_COMMAND);
|
||||||
//if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
//if (item->itemVal) item->setFlag(FLAG_PARAMETERS);
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
if (item->isActive()>0) ///????
|
if (item->isActive()>0) ///????
|
||||||
{
|
{
|
||||||
item->setExt(millisNZ());
|
item->setExt(millisNZ());
|
||||||
@@ -55,24 +54,10 @@ int out_relay::Stop()
|
|||||||
{
|
{
|
||||||
debugSerial<<F("Relay-Out #")<<pin<<F(" stop")<<endl;
|
debugSerial<<F("Relay-Out #")<<pin<<F(" stop")<<endl;
|
||||||
pinMode(pin, INPUT);
|
pinMode(pin, INPUT);
|
||||||
driverStatus = CST_UNKNOWN;
|
setStatus(CST_UNKNOWN);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_relay::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
/*
|
|
||||||
const char action_P[] PROGMEM = "action";
|
|
||||||
const char cooling_P[] PROGMEM = "cooling";
|
|
||||||
const char heating_P[] PROGMEM = "heating";
|
|
||||||
const char drying_P[] PROGMEM = "drying";
|
|
||||||
const char idle_P[] PROGMEM = "idle";
|
|
||||||
const char fan_P[] PROGMEM = "fan";
|
|
||||||
const char off_P[] PROGMEM = "off";
|
|
||||||
*/
|
|
||||||
|
|
||||||
void out_relay::relay(bool state)
|
void out_relay::relay(bool state)
|
||||||
{
|
{
|
||||||
char subtopic[10]="/";
|
char subtopic[10]="/";
|
||||||
@@ -143,11 +128,14 @@ bool needToOff = isTimeOver(timer,millis(),period*val/255);
|
|||||||
};
|
};
|
||||||
|
|
||||||
|
|
||||||
int out_relay::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_relay::Ctrl(itemCmd cmd, char* subItem, bool toExecute,bool authorized)
|
||||||
{
|
{
|
||||||
debugSerial<<F("relayCtr: ");
|
debugSerial<<F("relayCtr: ");
|
||||||
cmd.debugOut();
|
cmd.debugOut();
|
||||||
if ((subItem && !strcmp_P(subItem,action_P)) || !item) return 0;
|
if ((subItem && !strcmp_P(subItem,action_P)) || !item) return 0;
|
||||||
|
|
||||||
|
if (isProtectedPin(pin)) {return 0;}
|
||||||
|
|
||||||
int suffixCode;
|
int suffixCode;
|
||||||
if (cmd.isCommand()) suffixCode = S_CMD;
|
if (cmd.isCommand()) suffixCode = S_CMD;
|
||||||
else suffixCode = cmd.getSuffix();
|
else suffixCode = cmd.getSuffix();
|
||||||
|
|||||||
@@ -15,10 +15,9 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
short pin;
|
short pin;
|
||||||
|
|||||||
@@ -24,7 +24,6 @@ static CRGB *leds = NULL;
|
|||||||
|
|
||||||
#define NUM_LEDS 43
|
#define NUM_LEDS 43
|
||||||
|
|
||||||
static int driverStatus = CST_UNKNOWN;
|
|
||||||
|
|
||||||
void out_SPILed::getConfig()
|
void out_SPILed::getConfig()
|
||||||
{
|
{
|
||||||
@@ -63,7 +62,7 @@ FastLED.addLeds<CONTROLLER, DATA_PIN, ORDER>(leds, numLeds);
|
|||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED);
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -78,15 +77,11 @@ delete leds;
|
|||||||
FastLED.clear(true);
|
FastLED.clear(true);
|
||||||
delete [] leds;
|
delete [] leds;
|
||||||
#endif
|
#endif
|
||||||
driverStatus = CST_UNKNOWN;
|
setStatus(CST_UNKNOWN);
|
||||||
|
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_SPILed::Status()
|
|
||||||
{
|
|
||||||
return driverStatus;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
|
||||||
int out_SPILed::getChanType()
|
int out_SPILed::getChanType()
|
||||||
@@ -98,7 +93,7 @@ int out_SPILed::getChanType()
|
|||||||
return CH_RGBW;
|
return CH_RGBW;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_SPILed::PixelCtrl(itemCmd cmd, char* subItem, bool show )
|
int out_SPILed::PixelCtrl(itemCmd cmd, char* subItem, bool show, bool authorized )
|
||||||
//int out_SPILed::PixelCtrl(itemCmd cmd, int from, int to, bool show)
|
//int out_SPILed::PixelCtrl(itemCmd cmd, int from, int to, bool show)
|
||||||
{
|
{
|
||||||
|
|
||||||
|
|||||||
@@ -18,11 +18,10 @@ public:
|
|||||||
out_SPILed(Item * _item):colorChannel(_item){getConfig();};
|
out_SPILed(Item * _item):colorChannel(_item){getConfig();};
|
||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||||
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
//int Ctrl(itemCmd cmd, char* subItem=NULL) override;
|
||||||
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true ) override;
|
int PixelCtrl(itemCmd cmd, char* subItem=NULL, bool show=true, bool authorized = false ) override;
|
||||||
//int PixelCtrl(itemCmd cmd, int from =0 , int to = 1024, bool show = 1) override;
|
//int PixelCtrl(itemCmd cmd, int from =0 , int to = 1024, bool show = 1) override;
|
||||||
int numLeds;
|
int numLeds;
|
||||||
int8_t pin;
|
int8_t pin;
|
||||||
|
|||||||
@@ -121,12 +121,12 @@ if (!store)
|
|||||||
if (getConfig())
|
if (getConfig())
|
||||||
{
|
{
|
||||||
infoSerial<<F("UARTbridge config loaded ")<< item->itemArr->name<<endl;
|
infoSerial<<F("UARTbridge config loaded ")<< item->itemArr->name<<endl;
|
||||||
store->driverStatus = CST_INITIALIZED;
|
setStatus(CST_INITIALIZED)
|
||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{ errorSerial<<F("UARTbridge config error")<<endl;
|
{ errorSerial<<F("UARTbridge config error")<<endl;
|
||||||
store->driverStatus = CST_FAILED;
|
setStatus(CST_FAILED);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -146,12 +146,6 @@ store = NULL;
|
|||||||
return 1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
int out_UARTbridge::Status()
|
|
||||||
{
|
|
||||||
if (store)
|
|
||||||
return store->driverStatus;
|
|
||||||
return CST_UNKNOWN;
|
|
||||||
}
|
|
||||||
|
|
||||||
String _RR_A;
|
String _RR_A;
|
||||||
String _WR_A;
|
String _WR_A;
|
||||||
@@ -389,7 +383,7 @@ int out_UARTbridge::getChanType()
|
|||||||
// 2. custom textual subItem
|
// 2. custom textual subItem
|
||||||
// 3. non-standard numeric suffix Code equal param id
|
// 3. non-standard numeric suffix Code equal param id
|
||||||
|
|
||||||
int out_UARTbridge::Ctrl(itemCmd cmd, char* subItem, bool toExecute)
|
int out_UARTbridge::Ctrl(itemCmd cmd, char* subItem, bool toExecute, bool authorized)
|
||||||
{
|
{
|
||||||
//int chActive = item->isActive();
|
//int chActive = item->isActive();
|
||||||
//bool toExecute = (chActive>0);
|
//bool toExecute = (chActive>0);
|
||||||
|
|||||||
@@ -43,8 +43,7 @@
|
|||||||
class ubPersistent : public chPersistent {
|
class ubPersistent : public chPersistent {
|
||||||
|
|
||||||
public:
|
public:
|
||||||
// int addr
|
|
||||||
int8_t driverStatus;
|
|
||||||
int baud;
|
int baud;
|
||||||
serialParamType serialParam;
|
serialParamType serialParam;
|
||||||
//uint16_t pollingInterval;
|
//uint16_t pollingInterval;
|
||||||
@@ -63,9 +62,8 @@ public:
|
|||||||
int Setup() override;
|
int Setup() override;
|
||||||
int Poll(short cause) override;
|
int Poll(short cause) override;
|
||||||
int Stop() override;
|
int Stop() override;
|
||||||
int Status() override;
|
|
||||||
int getChanType() override;
|
int getChanType() override;
|
||||||
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true) override;
|
int Ctrl(itemCmd cmd, char* subItem=NULL, bool toExecute=true, bool authorized = false) override;
|
||||||
int getDefaultStorageType(){return ST_INT32;};
|
int getDefaultStorageType(){return ST_INT32;};
|
||||||
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
//int Ctrl(short cmd, short n=0, int * Parameters=NULL, int suffixCode=0, char* subItem=NULL) override;
|
||||||
|
|
||||||
|
|||||||
@@ -75,6 +75,7 @@
|
|||||||
#define WIFI_TIMEOUT 60000UL
|
#define WIFI_TIMEOUT 60000UL
|
||||||
#define TIMEOUT_RECONNECT 10000UL
|
#define TIMEOUT_RECONNECT 10000UL
|
||||||
#define TIMEOUT_REINIT 5000UL
|
#define TIMEOUT_REINIT 5000UL
|
||||||
|
#define TIMEOUT_RELOAD 30000UL
|
||||||
#define TIMEOUT_RETAIN 8000UL
|
#define TIMEOUT_RETAIN 8000UL
|
||||||
#define INTERVAL_1W 5000UL
|
#define INTERVAL_1W 5000UL
|
||||||
#define PERIOD_THERMOSTAT_FAILED (600 * 1000UL)
|
#define PERIOD_THERMOSTAT_FAILED (600 * 1000UL)
|
||||||
@@ -362,3 +363,17 @@
|
|||||||
#else
|
#else
|
||||||
#define minimalMemory 1200
|
#define minimalMemory 1200
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
#if not defined PROTECTED_PINS
|
||||||
|
#define PROTECTED_PINS
|
||||||
|
#endif
|
||||||
|
|
||||||
|
const short protectedPins[]={PROTECTED_PINS};
|
||||||
|
#define protectedPinsNum (sizeof(protectedPins)/sizeof(short))
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
#if not defined SHAREDSECRET
|
||||||
|
#define SHAREDSECRET "12345678"
|
||||||
|
#endif
|
||||||
|
|
||||||
|
#endif
|
||||||
@@ -25,20 +25,22 @@ e-mail anklimov@gmail.com
|
|||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "options.h"
|
#include "options.h"
|
||||||
#include "main.h"
|
#include "main.h"
|
||||||
|
#include "aJSON.h"
|
||||||
|
//#include "twi.h"
|
||||||
|
|
||||||
|
extern aJsonObject *owArr;
|
||||||
|
extern uint32_t timerCtr;
|
||||||
|
aJsonObject *dev2Check = NULL;
|
||||||
|
|
||||||
OneWire *oneWire = NULL;
|
OneWire *oneWire = NULL;
|
||||||
|
|
||||||
DeviceAddress *term = NULL;
|
|
||||||
|
|
||||||
uint16_t *wstat = NULL;
|
|
||||||
DallasTemperature *sensors = NULL;
|
DallasTemperature *sensors = NULL;
|
||||||
|
|
||||||
short si = 0;
|
|
||||||
int t_count = 0;
|
|
||||||
unsigned long owTimer = 0;
|
unsigned long owTimer = 0;
|
||||||
|
|
||||||
owChangedType owChanged;
|
void owSearch()
|
||||||
|
{
|
||||||
|
owUpdate();
|
||||||
|
}
|
||||||
|
|
||||||
bool zero(const uint8_t *addr, uint8_t len)
|
bool zero(const uint8_t *addr, uint8_t len)
|
||||||
{
|
{
|
||||||
@@ -47,62 +49,84 @@ bool zero(const uint8_t *addr, uint8_t len)
|
|||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
char * getReadableNote(aJsonObject * owObj)
|
||||||
|
{
|
||||||
|
if (owObj && owObj->child)
|
||||||
|
{
|
||||||
|
if (owObj->child->type==aJson_String && owObj->child->valuestring) return owObj->child->valuestring;
|
||||||
|
if (owObj->child->child && owObj->child->child->type==aJson_String && owObj->child->child->valuestring) return owObj->child->child->valuestring;
|
||||||
|
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
void processTemp(aJsonObject * owObj, float currentTemp) {
|
||||||
|
if (!owObj || !owArr) return;
|
||||||
|
char* note = getReadableNote(owObj);
|
||||||
|
debugSerial<<endl<<F("1WT:")<<currentTemp<<F(" <")<<owObj->name<<F("> ");
|
||||||
|
if ((currentTemp != -127.0) && (currentTemp != 85.0) && (currentTemp != 0.0))
|
||||||
|
{
|
||||||
|
if (note) debugSerial<<note;
|
||||||
|
debugSerial<<endl;
|
||||||
|
executeCommand(owObj,-1,itemCmd(currentTemp).setSuffix(S_VAL));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
if (note) debugSerial<<F(" read error for ")<<note<<endl;
|
||||||
|
|
||||||
|
/*
|
||||||
|
#ifdef WITH_DOMOTICZ
|
||||||
|
aJsonObject *idx = aJson.getObjectItem(owObj, "idx");
|
||||||
|
if (idx && && idx->type ==aJson_String && idx->valuestring) {//DOMOTICZ json format support
|
||||||
|
debugSerial << endl << idx->valuestring << F(" Domoticz valstr:");
|
||||||
|
char valstr[50];
|
||||||
|
sprintf(valstr, "{\"idx\":%s,\"svalue\":\"%.1f\"}", idx->valuestring, currentTemp);
|
||||||
|
debugSerial << valstr;
|
||||||
|
if (mqttClient.connected() && !ethernetIdleCount)
|
||||||
|
mqttClient.publish(owEmitString, valstr);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
*/
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int owUpdate() {
|
int owUpdate() {
|
||||||
#ifndef OWIRE_DISABLE
|
#ifndef OWIRE_DISABLE
|
||||||
unsigned long finish = millis();// + OW_UPDATE_INTERVAL;
|
DeviceAddress dev;
|
||||||
/*
|
if (!oneWire || !owArr) return 0;
|
||||||
if (oneWire->getError() == DS2482_ERROR_SHORT)
|
oneWire->reset_search();
|
||||||
|
infoSerial << F("1WT: Searching dev")<<endl;
|
||||||
|
while (oneWire->wireSearch(dev) > 0)
|
||||||
{
|
{
|
||||||
debugSerial<<F("1-wire shorted.")<<endl;
|
wdt_res();
|
||||||
return false;
|
// owIdle();
|
||||||
|
char addrstr[17];
|
||||||
|
SetBytes(dev, 8, addrstr);
|
||||||
|
addrstr[16] = 0;
|
||||||
|
aJsonObject * owObj=aJson.getObjectItem(owArr,addrstr);
|
||||||
|
infoSerial<<F("1WT:")<<addrstr;
|
||||||
|
if (owObj)
|
||||||
|
{
|
||||||
|
char * note = getReadableNote(owObj);
|
||||||
|
if (note) infoSerial<<F(" is ")<<note<<endl;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
infoSerial<<F(" new")<<endl;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
*/
|
|
||||||
//Serial.println(F("Searching"));
|
|
||||||
if (oneWire) oneWire->reset_search();
|
|
||||||
for (short i = 0; i < t_count; i++) wstat[i] &= ~SW_FIND; //absent
|
|
||||||
|
|
||||||
while (oneWire && oneWire->wireSearch(term[t_count]) > 0 && (t_count < t_max) && !isTimeOver(finish,millis(), OW_UPDATE_INTERVAL))//&& finish > millis())
|
|
||||||
{
|
|
||||||
short ifind = -1;
|
|
||||||
if (oneWire->crc8(term[t_count], 7) == term[t_count][7]) {
|
|
||||||
for (short i = 0; i < t_count; i++)
|
|
||||||
if (!memcmp(term[i], term[t_count], 8)) {
|
|
||||||
ifind = i;
|
|
||||||
wstat[i] |= SW_FIND;
|
|
||||||
debugSerial.print(F(" Node:"));
|
|
||||||
PrintBytes(term[t_count], 8,0);
|
|
||||||
debugSerial.println(F(" alive"));
|
|
||||||
break;
|
|
||||||
}; //alive
|
|
||||||
if (ifind < 0 && sensors && !zero(term[t_count],8))
|
|
||||||
{
|
|
||||||
wstat[t_count] = SW_FIND; //Newly detected
|
|
||||||
debugSerial<<F("dev#")<<t_count<<F(" Addr:");
|
|
||||||
PrintBytes(term[t_count], 8,0);
|
|
||||||
debugSerial.println();
|
|
||||||
if (term[t_count][0] == 0x28) {
|
|
||||||
sensors->setResolution(term[t_count], TEMPERATURE_PRECISION);
|
|
||||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
|
||||||
oneWire->setStrongPullup();
|
|
||||||
#endif
|
|
||||||
// sensors.requestTemperaturesByAddress(term[t_count]);
|
|
||||||
}
|
|
||||||
t_count++;
|
|
||||||
}
|
|
||||||
}//if
|
|
||||||
} //while
|
|
||||||
|
|
||||||
debugSerial<<F("1-wire count: ")<<t_count<<endl;
|
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int owSetup(owChangedType owCh) {
|
int owSetup() {
|
||||||
#ifndef OWIRE_DISABLE
|
#ifndef OWIRE_DISABLE
|
||||||
//// todo - move memory allocation to here
|
//// todo - move memory allocation to here
|
||||||
if (oneWire) return true; // Already initialized
|
if (oneWire) return true; // Already initialized
|
||||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||||
|
|
||||||
debugSerial<<F("DS2482_100_I2C_TO_1W_BRIDGE init")<<endl;
|
debugSerial<<F("DS2482_100_I2C_TO_1W_BRIDGE init")<<endl;
|
||||||
debugSerial<<F("Free:")<<freeRam()<<endl;
|
debugSerial<<F("Free:")<<freeRam()<<endl;
|
||||||
oneWire = new OneWire;
|
oneWire = new OneWire;
|
||||||
@@ -114,29 +138,15 @@ int owSetup(owChangedType owCh) {
|
|||||||
|
|
||||||
if (!oneWire)
|
if (!oneWire)
|
||||||
{
|
{
|
||||||
errorSerial<<F("Error 1-w init #1")<<endl;
|
errorSerial<<F("Error 1-w init")<<endl;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
// Pass our oneWire reference to Dallas Temperature.
|
|
||||||
// sensors = new DallasTemperature(oneWire);
|
|
||||||
|
|
||||||
term = new DeviceAddress[t_max];
|
|
||||||
debugSerial<<F("Term. Free:")<<freeRam()<<endl;
|
|
||||||
//regs = new int [t_max];
|
|
||||||
wstat = new uint16_t[t_max];
|
|
||||||
debugSerial<<F("wstat. Free:")<<freeRam()<<endl;
|
|
||||||
if (!term || ! wstat)
|
|
||||||
{
|
|
||||||
errorSerial<<F("Error 1-w init #2 Free:")<<freeRam()<<endl;
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
owChanged = owCh;
|
|
||||||
|
|
||||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||||
Wire.begin();
|
Wire.begin();
|
||||||
if (oneWire->checkPresence()) {
|
if (oneWire->checkPresence()) {
|
||||||
debugSerial.println(F("DS2482-100 present"));
|
infoSerial.println(F("1WT: DS2482-100 present"));
|
||||||
oneWire->deviceReset();
|
oneWire->deviceReset();
|
||||||
#ifdef APU_OFF
|
#ifdef APU_OFF
|
||||||
debugSerial.println(F("APU off"));
|
debugSerial.println(F("APU off"));
|
||||||
@@ -147,71 +157,141 @@ if (!term || ! wstat)
|
|||||||
debugSerial.println(F("\tChecking for 1-Wire devices..."));
|
debugSerial.println(F("\tChecking for 1-Wire devices..."));
|
||||||
if (oneWire->wireReset())
|
if (oneWire->wireReset())
|
||||||
debugSerial.println(F("\tReset done"));
|
debugSerial.println(F("\tReset done"));
|
||||||
return true;
|
else
|
||||||
|
debugSerial.println(F("\tDS2482 reset error"));
|
||||||
|
//return true;
|
||||||
}
|
}
|
||||||
debugSerial.println(F("\tDS2482 error"));
|
else
|
||||||
|
{
|
||||||
|
i2cReset();
|
||||||
|
if (oneWire->checkPresence())
|
||||||
|
infoSerial<<F("1WT: DS2482-100 I2C restored")<<endl;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
errorSerial.println(F("1WT: DS2482-100 not present"));
|
||||||
return false;
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
#else
|
#else
|
||||||
// software driver
|
// software driver
|
||||||
oneWire->reset();
|
oneWire->reset();
|
||||||
delay(500);
|
delay(500);
|
||||||
return true;
|
// return true;
|
||||||
#endif //DS2482-100
|
#endif //DS2482-100
|
||||||
|
|
||||||
#endif //1w is not disabled
|
if (!owArr) return false;
|
||||||
return false;
|
|
||||||
}
|
|
||||||
|
|
||||||
|
if (!sensors)
|
||||||
int sensors_loop(void) {
|
|
||||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
|
||||||
if (oneWire->getError() == DS2482_ERROR_SHORT)
|
|
||||||
{
|
|
||||||
debugSerial<<F("1-wire shorted")<<endl;
|
|
||||||
oneWire->wireReset();
|
|
||||||
return 10000;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
|
|
||||||
if (!sensors)
|
|
||||||
{
|
{
|
||||||
// Setup sensors library and resolution
|
// Setup sensors library and resolution
|
||||||
sensors = new DallasTemperature(oneWire);
|
sensors = new DallasTemperature(oneWire);
|
||||||
sensors->begin();
|
sensors->begin();
|
||||||
// IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
|
// IC Default 9 bit. If you have troubles consider upping it 12. Ups the delay giving the IC more time to process the temperature measurement
|
||||||
for (short i = 0; i < t_count; i++) sensors->setResolution(term[i],TEMPERATURE_PRECISION);
|
|
||||||
|
//for (short i = 0; i < t_count; i++) sensors->setResolution(term[i],TEMPERATURE_PRECISION);
|
||||||
sensors->setWaitForConversion(false);
|
sensors->setWaitForConversion(false);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (si >= t_count) {
|
aJsonObject *item = owArr->child;
|
||||||
owUpdate(); //every check circle - scan for new devices
|
DeviceAddress curDev;
|
||||||
si = 0;
|
while (owArr && item && SetAddr(item->name,curDev) )
|
||||||
return 8000;
|
{
|
||||||
|
debugSerial<<F("1WT: setup resolution ")<<item->name<<endl;
|
||||||
|
sensors->setResolution(curDev,TEMPERATURE_PRECISION);
|
||||||
|
item=item->next;
|
||||||
|
}
|
||||||
|
|
||||||
|
//owUpdate();
|
||||||
|
|
||||||
|
return true;
|
||||||
|
|
||||||
|
#else //1w is not disabled
|
||||||
|
|
||||||
|
return false;
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int sensors_loop(void) {
|
||||||
|
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||||
|
switch (oneWire->getError())
|
||||||
|
{
|
||||||
|
case 0:
|
||||||
|
break;
|
||||||
|
|
||||||
|
case DS2482_ERROR_SHORT:
|
||||||
|
errorSerial<<F("1WT: 1-wire shorted")<<endl;
|
||||||
|
oneWire->wireReset();
|
||||||
|
return INTERVAL_1W;
|
||||||
|
|
||||||
|
case DS2482_ERROR_CONFIG:
|
||||||
|
errorSerial<<F("1WT: DS2482_ERROR_CONFIG")<<endl;
|
||||||
|
oneWire->wireReset();
|
||||||
|
return INTERVAL_1W;
|
||||||
|
|
||||||
|
case DS2482_ERROR_TIMEOUT:
|
||||||
|
errorSerial<<F("1WT: 1-wire shorted")<<endl;
|
||||||
|
oneWire->wireReset();
|
||||||
|
return INTERVAL_1W;
|
||||||
|
|
||||||
|
default:
|
||||||
|
errorSerial<<F("1WT: error")<<endl;
|
||||||
|
oneWire->wireReset();
|
||||||
|
return INTERVAL_1W;
|
||||||
|
}
|
||||||
|
if (!oneWire->checkPresence())
|
||||||
|
{
|
||||||
|
infoSerial.println(F("1WT: lost DS2482-100"));
|
||||||
|
i2cReset();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
||||||
|
if (!sensors || !owArr)
|
||||||
|
{
|
||||||
|
errorSerial<<F("1WT: not init")<<endl;
|
||||||
|
return INTERVAL_1W;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (!dev2Check && owArr)
|
||||||
|
{
|
||||||
|
if (owArr && owArr->type == aJson_Object && owArr->child) dev2Check = owArr->child;
|
||||||
|
///owUpdate(); //every check circle - scan for new devices
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
setupOwIdle(&owIdle);
|
||||||
|
DeviceAddress curDev;
|
||||||
|
|
||||||
|
if (dev2Check && SetAddr(dev2Check->name,curDev))
|
||||||
|
{
|
||||||
float t;
|
float t;
|
||||||
switch (term[si][0]) {
|
switch (curDev[0]) {
|
||||||
|
|
||||||
case 0x28: // Thermomerer
|
case 0x28: // Thermomerer
|
||||||
t = sensors->getTempC(term[si]);//*10.0;
|
//debugSerial<<millis()<<" "<<timerCtr<<endl;
|
||||||
if (owChanged) owChanged(si, term[si], t);
|
|
||||||
sensors->requestTemperaturesByAddress(term[si]);
|
|
||||||
si++;
|
|
||||||
return 2500;
|
|
||||||
|
|
||||||
// default
|
t = sensors->getTempC(curDev);//*10.0;
|
||||||
// return sensors_ext();
|
//owIdle();
|
||||||
|
//debugSerial<<millis()<<" "<<timerCtr<<endl;
|
||||||
|
processTemp(dev2Check, t);
|
||||||
|
//owIdle();
|
||||||
|
|
||||||
|
sensors->requestTemperaturesByAddress(curDev);
|
||||||
|
//owIdle();
|
||||||
|
//debugSerial<<millis()<<" "<<timerCtr<<endl;
|
||||||
} //switch
|
} //switch
|
||||||
|
}
|
||||||
|
|
||||||
|
//si++;
|
||||||
si++;
|
dev2Check=dev2Check->next;
|
||||||
return check_circle;
|
return INTERVAL_1W;
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
void owLoop() {
|
void owLoop() {
|
||||||
//if (millis() >= owTimer) owTimer = millis() + sensors_loop();
|
|
||||||
if (isTimeOver(owTimer,millis(),INTERVAL_1W))
|
if (isTimeOver(owTimer,millis(),INTERVAL_1W))
|
||||||
{
|
{
|
||||||
sensors_loop();
|
sensors_loop();
|
||||||
@@ -220,31 +300,6 @@ void owLoop() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
int owFind(DeviceAddress addr) {
|
|
||||||
for (short i = 0; i < t_count; i++) if (!memcmp(term[i], addr, 8)) return i;//find
|
|
||||||
return -1;
|
|
||||||
}
|
|
||||||
|
|
||||||
void owAdd(DeviceAddress addr) {
|
|
||||||
#ifndef OWIRE_DISABLE
|
|
||||||
infoSerial<<F("dev#")<<t_count<<F(" Addr:");
|
|
||||||
PrintBytes(term[t_count], 8,0);
|
|
||||||
infoSerial<<endl;
|
|
||||||
|
|
||||||
if (t_count>=t_max) return;
|
|
||||||
if (zero(term[t_count],8)) return;
|
|
||||||
|
|
||||||
wstat[t_count] = SW_FIND; //Newly detected
|
|
||||||
memcpy(term[t_count], addr, 8);
|
|
||||||
|
|
||||||
|
|
||||||
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
|
||||||
if (term[t_count][0] == 0x28)
|
|
||||||
oneWire->setStrongPullup();
|
|
||||||
#endif
|
|
||||||
t_count++;
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
void setupOwIdle (void (*ptr)())
|
void setupOwIdle (void (*ptr)())
|
||||||
@@ -253,3 +308,4 @@ void setupOwIdle (void (*ptr)())
|
|||||||
if (oneWire) oneWire->idle(ptr);
|
if (oneWire) oneWire->idle(ptr);
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -30,8 +30,8 @@ e-mail anklimov@gmail.com
|
|||||||
#define SW_MASK 0xF
|
#define SW_MASK 0xF
|
||||||
#define SW_INMASK 0xFC
|
#define SW_INMASK 0xFC
|
||||||
|
|
||||||
#define recheck_interval 5
|
//#define recheck_interval 5
|
||||||
#define check_circle 2000/t_count
|
//#define check_circle 2000/t_count
|
||||||
|
|
||||||
#define SW_FIND 1
|
#define SW_FIND 1
|
||||||
#define SW_DOUBLECHECK 2 //Doublecheck required
|
#define SW_DOUBLECHECK 2 //Doublecheck required
|
||||||
@@ -45,8 +45,8 @@ e-mail anklimov@gmail.com
|
|||||||
#define SW_PULSE1_R 0x200 //Pulse Reset requested
|
#define SW_PULSE1_R 0x200 //Pulse Reset requested
|
||||||
|
|
||||||
|
|
||||||
#define recheck_interval 5
|
//#define recheck_interval 5
|
||||||
#define check_circle 2000/t_count
|
//#define check_circle 2000/t_count
|
||||||
|
|
||||||
#if not defined (OW_DEVICES_LIMIT)
|
#if not defined (OW_DEVICES_LIMIT)
|
||||||
#define t_max 20 //Maximum number of 1w devices
|
#define t_max 20 //Maximum number of 1w devices
|
||||||
@@ -63,7 +63,7 @@ e-mail anklimov@gmail.com
|
|||||||
|
|
||||||
extern aJsonObject *owArr;
|
extern aJsonObject *owArr;
|
||||||
|
|
||||||
typedef void (*owChangedType) (int , DeviceAddress, float) ;
|
//typedef void (*owChangedType) (int , DeviceAddress, float) ;
|
||||||
|
|
||||||
#ifndef USE_1W_PIN
|
#ifndef USE_1W_PIN
|
||||||
#define DS2482_100_I2C_TO_1W_BRIDGE // HW driver
|
#define DS2482_100_I2C_TO_1W_BRIDGE // HW driver
|
||||||
@@ -79,23 +79,12 @@ typedef void (*owChangedType) (int , DeviceAddress, float) ;
|
|||||||
|
|
||||||
|
|
||||||
extern OneWire *oneWire;
|
extern OneWire *oneWire;
|
||||||
|
|
||||||
extern DallasTemperature *sensors;
|
extern DallasTemperature *sensors;
|
||||||
extern DeviceAddress *term ;
|
|
||||||
extern int *regs ;
|
|
||||||
extern uint16_t *wstat;
|
|
||||||
extern int t_count;
|
|
||||||
extern short si;
|
|
||||||
|
|
||||||
extern owChangedType owChanged;
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
int owUpdate();
|
int owUpdate();
|
||||||
int owSetup(owChangedType owCh);
|
int owSetup();
|
||||||
void owLoop();
|
void owLoop();
|
||||||
void setupOwIdle(void (*)()) ;
|
void setupOwIdle(void (*)()) ;
|
||||||
int owFind(DeviceAddress addr);
|
void owSearch();
|
||||||
void owAdd (DeviceAddress addr);
|
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
const char state_P[] PROGMEM = "$state";
|
const char state_P[] PROGMEM = "$state";
|
||||||
const char disconnected_P[] PROGMEM = "disconnected";
|
const char disconnected_P[] PROGMEM = "disconnected";
|
||||||
const char ready_P[] PROGMEM = "ready";
|
const char ready_P[] PROGMEM = "ready";
|
||||||
|
const char salt_P[] PROGMEM = "$salt";
|
||||||
|
|
||||||
const char homie_P[] PROGMEM = "$homie";
|
const char homie_P[] PROGMEM = "$homie";
|
||||||
const char homiever_P[] PROGMEM = "3.0.1";
|
const char homiever_P[] PROGMEM = "3.0.1";
|
||||||
|
|||||||
@@ -28,6 +28,10 @@ e-mail anklimov@gmail.com
|
|||||||
#include <PubSubClient.h>
|
#include <PubSubClient.h>
|
||||||
#include <HardwareSerial.h>
|
#include <HardwareSerial.h>
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
#include "SHA256.h"
|
||||||
|
#endif
|
||||||
|
|
||||||
#ifndef debugSerialPort
|
#ifndef debugSerialPort
|
||||||
#define debugSerialPort Serial
|
#define debugSerialPort Serial
|
||||||
#endif
|
#endif
|
||||||
@@ -56,6 +60,7 @@ extern aJsonObject *topics;
|
|||||||
|
|
||||||
|
|
||||||
void PrintBytes(uint8_t *addr, uint8_t count, bool newline) {
|
void PrintBytes(uint8_t *addr, uint8_t count, bool newline) {
|
||||||
|
if (!addr) return;
|
||||||
for (uint8_t i = 0; i < count; i++) {
|
for (uint8_t i = 0; i < count; i++) {
|
||||||
infoSerial<< _HEX(addr[i] >> 4);
|
infoSerial<< _HEX(addr[i] >> 4);
|
||||||
infoSerial<< _HEX(addr[i] & 0x0f);
|
infoSerial<< _HEX(addr[i] & 0x0f);
|
||||||
@@ -68,6 +73,7 @@ const char HEXSTR[] = "0123456789ABCDEF";
|
|||||||
|
|
||||||
void SetBytes(uint8_t *addr, uint8_t count, char *out) {
|
void SetBytes(uint8_t *addr, uint8_t count, char *out) {
|
||||||
// debugSerialPort.println("SB:");
|
// debugSerialPort.println("SB:");
|
||||||
|
if (!addr || !out) return;
|
||||||
for (uint8_t i = 0; i < count; i++) {
|
for (uint8_t i = 0; i < count; i++) {
|
||||||
*(out++) = HEXSTR[(addr[i] >> 4)];
|
*(out++) = HEXSTR[(addr[i] >> 4)];
|
||||||
*(out++) = HEXSTR[(addr[i] & 0x0f)];
|
*(out++) = HEXSTR[(addr[i] & 0x0f)];
|
||||||
@@ -77,30 +83,33 @@ void SetBytes(uint8_t *addr, uint8_t count, char *out) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
byte HEX2DEC(char i) {
|
byte HEX2DEC(char i, bool *err) {
|
||||||
byte v=0;
|
byte v=0;
|
||||||
if ('a' <= i && i <= 'f') { v = i - 97 + 10; }
|
if ('a' <= i && i <= 'f') { v = i - 97 + 10; }
|
||||||
else if ('A' <= i && i <= 'F') { v = i - 65 + 10; }
|
else if ('A' <= i && i <= 'F') { v = i - 65 + 10; }
|
||||||
else if ('0' <= i && i <= '9') { v = i - 48; }
|
else if ('0' <= i && i <= '9') { v = i - 48; }
|
||||||
|
else if (err) *err = true;
|
||||||
return v;
|
return v;
|
||||||
}
|
}
|
||||||
|
|
||||||
void SetAddr(char *out, uint8_t *addr) {
|
bool SetAddr(char *in, uint8_t *addr) {
|
||||||
|
bool err=false;
|
||||||
|
if (!addr || !in) return false;
|
||||||
for (uint8_t i = 0; i < 8; i++) {
|
for (uint8_t i = 0; i < 8; i++) {
|
||||||
*addr = HEX2DEC(*out++) << 4;
|
*addr = HEX2DEC(*in++,&err) << 4;
|
||||||
*addr++ |= HEX2DEC(*out++);
|
*addr++ |= HEX2DEC(*in++,&err);
|
||||||
}
|
}
|
||||||
|
return !err;
|
||||||
}
|
}
|
||||||
|
|
||||||
// chan is pointer to pointer to string
|
// chan is pointer to pointer to string
|
||||||
// Function return first retrived integer and move pointer to position next after ','
|
// Function return first retrived integer and move pointer to position next after ','
|
||||||
int getInt(char **chan) {
|
long getInt(char **chan) {
|
||||||
if (chan && *chan && **chan)
|
if (chan && *chan && **chan)
|
||||||
{
|
{
|
||||||
//Skip non-numeric values
|
//Skip non-numeric values
|
||||||
while (**chan && !(**chan == '-' || (**chan >= '0' && **chan<='9'))) *chan += 1;
|
while (**chan && !(**chan == '-' || (**chan >= '0' && **chan<='9'))) *chan += 1;
|
||||||
int ch = atoi(*chan);
|
long ch = atol(*chan);
|
||||||
|
|
||||||
//Move pointer to next element (after ,)
|
//Move pointer to next element (after ,)
|
||||||
*chan = strchr(*chan, ',');
|
*chan = strchr(*chan, ',');
|
||||||
@@ -324,8 +333,8 @@ Awesome work Mark T!*/
|
|||||||
|
|
||||||
|
|
||||||
__attribute__ ((section (".ramfunc")))
|
__attribute__ ((section (".ramfunc")))
|
||||||
|
// #pragma optimize("", off)
|
||||||
void ReadUniqueID( uint32_t * pdwUniqueID )
|
uint32_t ReadUniqueID( uint32_t * pdwUniqueID )
|
||||||
{
|
{
|
||||||
unsigned int status ;
|
unsigned int status ;
|
||||||
|
|
||||||
@@ -354,8 +363,15 @@ void ReadUniqueID( uint32_t * pdwUniqueID )
|
|||||||
{
|
{
|
||||||
status = EFC1->EEFC_FSR ;
|
status = EFC1->EEFC_FSR ;
|
||||||
} while ( (status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ) ;
|
} while ( (status & EEFC_FSR_FRDY) != EEFC_FSR_FRDY ) ;
|
||||||
|
|
||||||
|
|
||||||
|
return *(uint32_t *)(IFLASH1_ADDR + 128); // dont remove: SAM defect workaround - MPU dont leave Unique Identifier mode until read flash out UID of range
|
||||||
|
|
||||||
|
#else
|
||||||
|
return 0;
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
//#pragma optimize("", on)
|
||||||
|
|
||||||
|
|
||||||
int _inet_aton(const char* aIPAddrString, IPAddress& aResult)
|
int _inet_aton(const char* aIPAddrString, IPAddress& aResult)
|
||||||
@@ -805,6 +821,100 @@ bool getPinVal(uint8_t pin)
|
|||||||
return (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin)));
|
return (0!=(*portOutputRegister( digitalPinToPort(pin) ) & digitalPinToBitMask(pin)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef CRYPT
|
||||||
|
#define HASH_SIZE 32
|
||||||
|
SHA256 sha256;
|
||||||
|
extern uint32_t cryptoSalt;
|
||||||
|
extern char cryptoKey[];
|
||||||
|
|
||||||
|
bool checkToken(char * token, char * data)
|
||||||
|
{
|
||||||
|
// Make valid random salted data
|
||||||
|
char saltStr[32];
|
||||||
|
printUlongValueToStr(saltStr, cryptoSalt);
|
||||||
|
|
||||||
|
|
||||||
|
// get hash
|
||||||
|
uint8_t result[HASH_SIZE];
|
||||||
|
memset(result, 0xAA, sizeof(result));
|
||||||
|
|
||||||
|
sha256.reset();
|
||||||
|
sha256.update(saltStr,strlen(saltStr));
|
||||||
|
sha256.update(cryptoKey,strlen(cryptoKey));
|
||||||
|
if (data) sha256.update(data,strlen(data));
|
||||||
|
sha256.finalize(result,sizeof(result));
|
||||||
|
sha256.clear();
|
||||||
|
//hmac<SHA256>(result, HASH_SIZE, cryptoKey, strlen(cryptoKey), testData, strlen(testData));
|
||||||
|
|
||||||
|
//for (int i=0;i<HASH_SIZE;i++) {if(result[i]<0x10) debugSerial.print('0'); debugSerial.print(result[i],HEX);}
|
||||||
|
//debugSerial.println();
|
||||||
|
for (unsigned int i=0;i<strlen(token)/2;i++)
|
||||||
|
{
|
||||||
|
uint8_t digit = ((((token[i*2] <= '9') ? token[i*2] - '0' : (token[i*2] & 0x7) + 9) << 4) +
|
||||||
|
((token[i*2+1] <= '9') ? token[i*2+1] - '0' : (token[i*2+1] & 0x7) + 9));
|
||||||
|
//debugSerial.print(digit,HEX);
|
||||||
|
|
||||||
|
if (digit!=result[i])
|
||||||
|
{
|
||||||
|
debugSerial.println(F("signature Failed"));
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
debugSerial.println(F("signature Passed"));
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
#else
|
||||||
|
bool checkToken(char * token, char * data)
|
||||||
|
{return true;}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
bool isProtectedPin(short pin)
|
||||||
|
{
|
||||||
|
for (short i=0; i<protectedPinsNum; i++)
|
||||||
|
if (pin==protectedPins[i]) return true;
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
bool i2cReset(){
|
||||||
|
debugSerial.println("I2C Reset");
|
||||||
|
|
||||||
|
Wire.endTransmission(true);
|
||||||
|
#if !defined(ARDUINO_ARCH_ESP8266)
|
||||||
|
Wire.end();
|
||||||
|
#endif
|
||||||
|
pinMode(SCL,OUTPUT);
|
||||||
|
pinMode(SDA,INPUT);
|
||||||
|
//10 сигналов клок
|
||||||
|
bool pulse=false;
|
||||||
|
for (int i=0; i<20;i++) {
|
||||||
|
//i2c_scl_toggle(i2c);
|
||||||
|
digitalWrite(SCL,pulse?HIGH:LOW);
|
||||||
|
pulse=!pulse;
|
||||||
|
delay(10);//10us мкс
|
||||||
|
}
|
||||||
|
Wire.begin();
|
||||||
|
|
||||||
|
#ifdef DS2482_100_I2C_TO_1W_BRIDGE
|
||||||
|
if (oneWire && oneWire->checkPresence())
|
||||||
|
{
|
||||||
|
oneWire->deviceReset();
|
||||||
|
#ifndef APU_OFF
|
||||||
|
oneWire->setActivePullup();
|
||||||
|
#endif
|
||||||
|
if (oneWire->wireReset())
|
||||||
|
debugSerial.println(F("\tReset done"));
|
||||||
|
else
|
||||||
|
debugSerial.println(F("\tDS2482 reset error"));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
#pragma message(VAR_NAME_VALUE(debugSerial))
|
#pragma message(VAR_NAME_VALUE(debugSerial))
|
||||||
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
#pragma message(VAR_NAME_VALUE(SERIAL_BAUD))
|
||||||
|
|||||||
@@ -51,15 +51,15 @@ enum topicType {
|
|||||||
|
|
||||||
void PrintBytes(uint8_t* addr, uint8_t count, bool newline);
|
void PrintBytes(uint8_t* addr, uint8_t count, bool newline);
|
||||||
void SetBytes(uint8_t* addr, uint8_t count, char * out);
|
void SetBytes(uint8_t* addr, uint8_t count, char * out);
|
||||||
void SetAddr(char * out, uint8_t* addr);
|
bool SetAddr(char * in, uint8_t* addr);
|
||||||
uint8_t HEX2DEC(char i);
|
uint8_t HEX2DEC(char i, bool* err);
|
||||||
int getInt(char ** chan);
|
long getInt(char ** chan);
|
||||||
itemCmd getNumber(char ** chan);
|
itemCmd getNumber(char ** chan);
|
||||||
unsigned long freeRam ();
|
unsigned long freeRam ();
|
||||||
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);
|
void parseBytes(const char* str, char separator, byte* bytes, int maxBytes, int base);
|
||||||
int log(const char *str, ...);
|
int log(const char *str, ...);
|
||||||
void printFloatValueToStr(char *valstr, float value);
|
void printFloatValueToStr(char *valstr, float value);
|
||||||
void ReadUniqueID( uint32_t * pdwUniqueID );
|
uint32_t ReadUniqueID( uint32_t * pdwUniqueID );
|
||||||
int _inet_aton(const char* aIPAddrString, IPAddress& aResult);
|
int _inet_aton(const char* aIPAddrString, IPAddress& aResult);
|
||||||
char *_inet_ntoa_r(IPAddress addr, char *buf, int buflen);
|
char *_inet_ntoa_r(IPAddress addr, char *buf, int buflen);
|
||||||
void printIPAddress(IPAddress ipAddress);
|
void printIPAddress(IPAddress ipAddress);
|
||||||
@@ -77,3 +77,7 @@ serialParamType str2SerialParam(char * str);
|
|||||||
String toString(const IPAddress& address);
|
String toString(const IPAddress& address);
|
||||||
bool getPinVal(uint8_t pin);
|
bool getPinVal(uint8_t pin);
|
||||||
int str2regSize(char * str);
|
int str2regSize(char * str);
|
||||||
|
bool checkToken(char * token, char * data);
|
||||||
|
bool isProtectedPin(short pin);
|
||||||
|
bool i2cReset();
|
||||||
|
|
||||||
|
|||||||
@@ -13,9 +13,9 @@ src_dir = lighthub
|
|||||||
default_envs =
|
default_envs =
|
||||||
; ****** UNCOMMENT single environment name for target platform below *******
|
; ****** UNCOMMENT single environment name for target platform below *******
|
||||||
|
|
||||||
; Arduino Mega compact build + Ethernet shield Wiznet 5100, 1-wire, thermostates.
|
; Arduino Mega compact build + Ethernet shield Wiznet 5X00, 1-wire, thermostates.
|
||||||
; Without DMX, Wiznet 5100 network driver
|
; Without DMX, Wiznet network driver
|
||||||
; mega2560slim-5100
|
; mega2560slim
|
||||||
|
|
||||||
; Another Arduino Mega compact build without 1-wire, DMX, but with OTA
|
; Another Arduino Mega compact build without 1-wire, DMX, but with OTA
|
||||||
; OPTIBOOT bootloader required! https://github.com/MCUdude/MegaCore
|
; OPTIBOOT bootloader required! https://github.com/MCUdude/MegaCore
|
||||||
@@ -325,15 +325,16 @@ lib_deps =
|
|||||||
br3ttb/PID@^1.2.1
|
br3ttb/PID@^1.2.1
|
||||||
ArduinoMDNS
|
ArduinoMDNS
|
||||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||||
|
rweather/Crypto
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
[env:mega2560slim-5100]
|
[env:mega2560slim]
|
||||||
platform = atmelavr
|
platform = atmelavr
|
||||||
board = megaatmega2560
|
board = megaatmega2560
|
||||||
upload_port = net:192.168.88.2:23000
|
upload_port = net:192.168.88.2:23000
|
||||||
_upload_command = custom-build-flags/upload_mega2560slim-5100 $SOURCE
|
_upload_command = custom-build-flags/upload_mega2560slim $SOURCE
|
||||||
framework = arduino
|
framework = arduino
|
||||||
build_flags = !python get_build_flags.py mega2560slim-5100
|
build_flags = !python get_build_flags.py mega2560slim
|
||||||
extra_scripts = post:toBin.py
|
extra_scripts = post:toBin.py
|
||||||
lib_ignore =
|
lib_ignore =
|
||||||
;DS2482_OneWire //UNCOMMENT for software 1-wire driver
|
;DS2482_OneWire //UNCOMMENT for software 1-wire driver
|
||||||
@@ -368,8 +369,9 @@ lib_deps =
|
|||||||
https://github.com/anklimov/CmdArduino
|
https://github.com/anklimov/CmdArduino
|
||||||
;https://github.com/anklimov/ModbusMaster
|
;https://github.com/anklimov/ModbusMaster
|
||||||
;https://github.com/anklimov/DMXSerial
|
;https://github.com/anklimov/DMXSerial
|
||||||
https://github.com/anklimov/Ethernet5100
|
;https://github.com/anklimov/Ethernet5100
|
||||||
;5100 lib have ~90 bytes less footprint of RAM
|
;5100 lib have ~90 bytes less footprint of RAM
|
||||||
|
https://github.com/anklimov/Ethernet.git
|
||||||
https://github.com/anklimov/pubsubclient.git
|
https://github.com/anklimov/pubsubclient.git
|
||||||
;https://github.com/anklimov/Artnet.git
|
;https://github.com/anklimov/Artnet.git
|
||||||
;FastLED@3.3.2
|
;FastLED@3.3.2
|
||||||
@@ -460,6 +462,7 @@ lib_deps =
|
|||||||
br3ttb/PID@^1.2.1
|
br3ttb/PID@^1.2.1
|
||||||
ArduinoMDNS
|
ArduinoMDNS
|
||||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||||
|
rweather/Crypto
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
@@ -713,7 +716,7 @@ lib_deps =
|
|||||||
ArduinoMDNS
|
ArduinoMDNS
|
||||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||||
https://github.com/rlogiacco/CircularBuffer
|
https://github.com/rlogiacco/CircularBuffer
|
||||||
|
rweather/Crypto
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
[env:controllino]
|
[env:controllino]
|
||||||
@@ -801,12 +804,13 @@ lib_ignore =
|
|||||||
DS2482_OneWire
|
DS2482_OneWire
|
||||||
ModbusMaster
|
ModbusMaster
|
||||||
Syslog
|
Syslog
|
||||||
EEPROM
|
;EEPROM
|
||||||
ClosedCube HDC1080
|
ClosedCube HDC1080
|
||||||
SparkFun CCS811 Arduino Library
|
SparkFun CCS811 Arduino Library
|
||||||
M5Stack
|
M5Stack
|
||||||
ArduinoOTA
|
ArduinoOTA
|
||||||
lib_deps =
|
lib_deps =
|
||||||
|
EEPROM
|
||||||
https://github.com/anklimov/aJson
|
https://github.com/anklimov/aJson
|
||||||
https://github.com/anklimov/CmdArduino
|
https://github.com/anklimov/CmdArduino
|
||||||
ArduinoHttpClient
|
ArduinoHttpClient
|
||||||
@@ -889,6 +893,7 @@ lib_deps =
|
|||||||
br3ttb/PID@^1.2.1
|
br3ttb/PID@^1.2.1
|
||||||
ArduinoMDNS
|
ArduinoMDNS
|
||||||
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
https://github.com/khoih-prog/TimerInterrupt_Generic.git
|
||||||
|
;https://github.com/anklimov/ModbusMaster
|
||||||
|
|
||||||
monitor_speed = 115200
|
monitor_speed = 115200
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user