40 Commits

Author SHA1 Message Date
7251e229b6 pre-release bin & small fixes 2023-10-31 15:20:54 +03:00
Климов Андрей Николаевич
e9355ef142 modbus v2 fix 2023-10-31 00:13:09 +03:00
Климов Андрей Николаевич
7836876fcd crosscompilation fix 2023-10-30 20:36:30 +03:00
Климов Андрей Николаевич
8e7bbee96a Merge branch 'master' of https://github.com/anklimov/lighthub 2023-10-30 20:12:26 +03:00
Климов Андрей Николаевич
456f6b8ad4 modbus v1 retry optimisation 2023-10-30 20:12:16 +03:00
c4af5e92f9 Update README.md 2023-10-30 14:33:44 +03:00
Климов Андрей Николаевич
896a22862f 1-wire errors/reset improved, cleaned up 2023-10-30 00:00:11 +03:00
Климов Андрей Николаевич
83e8639034 Merge branch 'master' of https://github.com/anklimov/lighthub 2023-10-29 15:36:51 +03:00
Климов Андрей Николаевич
256ab175ce 1-w refactoring 2023-10-29 15:36:04 +03:00
199a80cbb9 pre-release binaries, all archs 2023-10-25 01:28:58 +03:00
Климов Андрей Николаевич
9204bd0898 +counter to Mega slim 2023-10-25 00:52:49 +03:00
Климов Андрей Николаевич
df4bf02e8d Merge branch 'master' of https://github.com/anklimov/lighthub 2023-10-25 00:29:14 +03:00
Климов Андрей Николаевич
45d925ba88 pins protection,core fixes for grp ch stat& sched 2023-10-25 00:28:26 +03:00
0a3bbcd7f9 binaries 2023-10-23 21:57:41 +03:00
Климов Андрей Николаевич
1e58ad90eb config reload issues fixed 2023-10-23 21:34:17 +03:00
a0ad782257 Update README.md 2023-10-21 22:55:33 +03:00
65556ed39d Update README.md 2023-10-21 22:19:57 +03:00
7bf685a0d4 cross-compiled & binaries 2023-10-21 21:52:57 +03:00
Климов Андрей Николаевич
f6a57348eb text chan types, comp options, counter fixed 2023-10-21 21:06:00 +03:00
Климов Андрей Николаевич
e93e52702e XNova CRYPT,SHAREDSECRET,PROTECTED_PINS,PULSEPIN12 2023-10-08 17:43:30 +03:00
Климов Андрей Николаевич
6cd4f1d82a mbus coils, discr inputs, new logic. AC - feedback 2023-08-13 23:49:35 +03:00
Климов Андрей Николаевич
3907158437 mac save&AC swmode fixes, sha256 sign for cmd tst 2023-07-16 20:29:59 +03:00
Климов Андрей Николаевич
eb68556012 STM32 persistent MVP, cross-compiled & binaries 2023-05-06 02:53:01 +03:00
Климов Андрей Николаевич
30f7b36a9c Multi-AC 2023-04-10 19:19:45 +03:00
Климов Андрей Николаевич
927272824c counter fix 2023-04-10 00:01:20 +03:00
Климов Андрей Николаевич
bab472d2d1 JSON RAM optimization (update libs needed), HTTP 2023-04-09 21:37:37 +03:00
Климов Андрей Николаевич
ec306c4934 Cumulative changes/pre-release 2023-04-02 17:27:02 +03:00
Климов Андрей Николаевич
3e0566cf07 ENABLE & DISABLE to separate topic and XON timer 2023-01-30 01:10:34 +03:00
Климов Андрей Николаевич
86d0d784a0 Mercury electricity counter driver, refactoring 2023-01-29 12:33:22 +03:00
Климов Андрей Николаевич
b06dad9395 noSerial option, DHT fix, 8266 slim to fit Sonoff 2022-12-16 17:14:59 +03:00
a974290389 Complex MBUS mapping, PID fix 2022-12-04 03:19:07 +03:00
2da04b45bf PID fixes/improvements and MBUS improvements 2022-11-28 14:57:43 +03:00
724eabc22f API CORS = * 2022-11-24 02:00:20 +03:00
c70a4eaac9 bin flash update fix (after revorking) & bins 2022-11-22 01:01:47 +03:00
a956b6f8e2 RAM optim to save huge configs to flash, PID min/max 2022-11-19 23:30:02 +03:00
07688f53ae core fixes (int & tens val<1), mbus optimization 2022-11-05 16:40:31 +03:00
6d28cb9f34 null mapping fix 2022-11-01 01:48:01 +03:00
d7e93177d6 possibility to turn val mapping off ("val":null) 2022-11-01 00:49:54 +03:00
c23543b213 PID & Modbus fine tuning 2022-10-31 23:56:51 +03:00
b94ab723ee modbus negative register fix 2022-10-13 08:22:06 +03:00
139 changed files with 71878 additions and 54184 deletions

View File

@@ -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

View File

@@ -3,4 +3,5 @@
-DWiz5100 -DWiz5100
#-DPID_DISABLE #-DPID_DISABLE
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"

View File

@@ -1,7 +1,7 @@
#-DW5500_CS_PIN=53 #-DW5500_CS_PIN=53
-DDMX_SMOOTH -DDMX_SMOOTH
-DSYSLOG_ENABLE -DSYSLOG_ENABLE
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 #-DMODBUS_SERIAL_PARAM=SERIAL_8E1
-DARTNET_ENABLE -DARTNET_ENABLE
-DOTA -DOTA
-DSTATUSLED -DSTATUSLED
@@ -10,8 +10,10 @@
-DARDUINO_OTA_MDNS_DISABLE -DARDUINO_OTA_MDNS_DISABLE
-DMDNS_ENABLE -DMDNS_ENABLE
-DMCP23017 -DMCP23017
-DCORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-DTIMER_INT -DTIMER_INT
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-DOTA_PORT=80 -DOTA_PORT=80
-DMERCURY_ENABLE

View File

@@ -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
@@ -26,6 +26,10 @@
#-DmodbusSerial=Serial1 #-DmodbusSerial=Serial1
#-DMODBUS_DEBUG #-DMODBUS_DEBUG
#-DMODBUS_UART_RX_PIN=16
#-DMODBUS_UART_TX_PIN=17
#-DmodbusSerial=Serial2
# Use default pins for modbus UART # Use default pins for modbus UART
#-DMODBUS_UART_RX_PIN=-1 #-DMODBUS_UART_RX_PIN=-1
#-DMODBUS_UART_TX_PIN=-1 #-DMODBUS_UART_TX_PIN=-1
@@ -46,5 +50,11 @@
-DFS_PREPARE -DFS_PREPARE
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" #-D CORS=\"http://lazyhome.ru\"
-DOTA_PORT=80 -DOTA_PORT=80
-DMQTT_KEEPALIVE=10
-DMQTT_SOCKET_TIMEOUT=20
-D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
#-DMERCURY_ENABLE

View File

@@ -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
@@ -17,8 +16,31 @@
-DFS_PREPARE -DFS_PREPARE
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
#-D CORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-DOTA_PORT=80 -DOTA_PORT=80
#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

View File

@@ -12,8 +12,8 @@
-DTIMER_INT -DTIMER_INT
#-DFLASH_OFFSET=-256 #-DFLASH_OFFSET=-256
# Serial parameters for LEGACY Modbus # default MODBUS Serial parameters for LEGACY Modbus and MODBUS over IP
-DMODBUS_DIMMER_PARAM=SERIAL_8E1 #-DMODBUS_SERIAL_PARAM=SERIAL_8E1
#Set Logariphmic law for DMX channels bright #Set Logariphmic law for DMX channels bright
-DBRIGHT_LOG -DBRIGHT_LOG
@@ -34,5 +34,9 @@
#-DdebugSerialPort=Serial #-DdebugSerialPort=Serial
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" #-D CORS=\"http://lazyhome.ru\"
-DOTA_PORT=80 -DOTA_PORT=80
-D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-D MERCURY_ENABLE
#-D IPMODBUS

View File

@@ -19,5 +19,6 @@
-DOTA -DOTA
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-DOTA_PORT=80 -DOTA_PORT=80

View File

@@ -1,4 +1,4 @@
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 #-DMODBUS_SERIAL_PARAM=SERIAL_8E1
-DAVR_DMXOUT_PIN=18 -DAVR_DMXOUT_PIN=18
-DSYSLOG_ENABLE -DSYSLOG_ENABLE
-DWiz5100 -DWiz5100
@@ -7,5 +7,6 @@
-DMDNS_ENABLE -DMDNS_ENABLE
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-DOTA_PORT=80 -D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-DOTA_PORT=80

View File

@@ -1,11 +1,18 @@
-DWiz5500 -DWiz5500
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 #-DMODBUS_SERIAL_PARAM=SERIAL_8E1
-DAVR_DMXOUT_PIN=18 -DAVR_DMXOUT_PIN=18
-DSYSLOG_ENABLE -DSYSLOG_ENABLE
#-DPID_DISABLE #-DPID_DISABLE
-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=\"http://lazyhome.ru\" -D CORS=\"*\"
-DOTA_PORT=80 -D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-DOTA_PORT=80

View File

@@ -1,5 +1,5 @@
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 #-DMODBUS_SERIAL_PARAM=SERIAL_8E1
#-DAVR_DMXOUT_PIN=18 #-DAVR_DMXOUT_PIN=18
-DDMX_DISABLE -DDMX_DISABLE
-DMODBUS_DISABLE -DMODBUS_DISABLE
@@ -15,13 +15,16 @@
-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
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
# Example of UARTBRIDGE configuration # Example of UARTBRIDGE configuration
#-DUARTBRIDGE_ENABLE #-DUARTBRIDGE_ENABLE
-DOTA_PORT=80 -DOTA_PORT=80
#-DMERCURY_ENABLE

View File

@@ -1,12 +1,12 @@
#-DMODBUS_DIMMER_PARAM=SERIAL_8E1 #-DMODBUS_SERIAL_PARAM=SERIAL_8E1
#-DAVR_DMXOUT_PIN=18 #-DAVR_DMXOUT_PIN=18
-DDMX_DISABLE -DDMX_DISABLE
-DMODBUS_DISABLE -DMODBUS_DISABLE
#-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
@@ -19,7 +19,8 @@
-DARDUINO_OTA_MDNS_DISABLE -DARDUINO_OTA_MDNS_DISABLE
#-DMDNS_ENABLE #-DMDNS_ENABLE
-DRESTART_LAN_ON_MQTT_ERRORS -DRESTART_LAN_ON_MQTT_ERRORS
-D CORS=\"http://lazyhome.ru\" -D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
-DOTA_PORT=80 -DOTA_PORT=80
-DHSV_DISABLE -DHSV_DISABLE
-DMULTIVENT_DISABLE -DMULTIVENT_DISABLE

View File

@@ -14,3 +14,6 @@
-DPID_DISABLE -DPID_DISABLE
#-DMCP23017 #-DMCP23017
-D CORS=\"*\"
-D REDIRECTION_URL=\"http://lazyhome.ru/pwa\"
#-DMERCURY_ENABLE

View File

@@ -9,15 +9,32 @@
-DSPILED_DISABLE -DSPILED_DISABLE
-DAC_DISABLE -DAC_DISABLE
-DPID_DISABLE -DPID_DISABLE
-DdebugSerialPort=SerialUSB
-DSerialPortType=USBSerial
-DSERIAL_BAUD=0
-DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC -DENABLE_HWSERIAL1
-DUSBCON -DdebugSerialPort=Serial1
#-DFLASH_BASE_ADDRESS
#-DFLASH_DATA_SECTOR
#-DFLASH_PAGE_NUMBER
-D PIO_FRAMEWORK_ARDUINO_ENABLE_MASS_STORAGE
-D PIO_FRAMEWORK_ARDUINO_ENABLE_CDC_AND_MSC
#-DdebugSerialPort=SerialUSB
#-DSerialPortType=USBSerial
#-DSERIAL_BAUD=0
#-DPIO_FRAMEWORK_ARDUINO_ENABLE_CDC
#-DUSBCON
#-DUSBD_VID=0x0483 #-DUSBD_VID=0x0483
#-DUSBD_PID=0x5740 #-DUSBD_PID=0x5740
#-DUSB_MANUFACTURER="Unknown" #-DUSB_MANUFACTURER="Unknown"
#-DUSB_PRODUCT="\"BLUEPILL_F103C8\"" #-DUSB_PRODUCT="\"BLUEPILL_F103C8\""
#-DHAL_PCD_MODULE_ENABLED #-DHAL_PCD_MODULE_ENABLED
#-D USBD_USE_CDC #-D USBD_USE_CDC
-D HAL_CAN_MODULE_ENABLED
#HAL_ETH_MODULE_DISABLED
#HAL_SD_MODULE_DISABLED
#HAL_DAC_MODULE_DISABLED
#-DMERCURY_ENABLE

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
..\tools\win\tool-avrdude\avrdude -C ../tools/mac/tool-avrdude/avrdude.conf -v -V -P com8 -patmega2560 -cwiring -b115200 -D -Uflash:w:firmware.hex:i

View File

@@ -0,0 +1 @@
..\tools\arduinoOTA.exe -address 192.168.11.213 -port 80 -username arduino -password password -sketch firmware.bin -b -upload /sketch

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -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

View File

@@ -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

Binary file not shown.

View 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.

Binary file not shown.

View 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

View File

@@ -0,0 +1 @@
../../tools/mac/arduinoOTA -address 192.168.11.208 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin

View File

@@ -0,0 +1 @@
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
View File

@@ -0,0 +1 @@
../tools/mac/arduinoOTA -address 192.168.11.208 -port 80 -username arduino -password password -b -upload /sketch -sketch firmware.bin

View File

@@ -0,0 +1 @@
wmic PATH Win32_SerialPort get DeviceID

Binary file not shown.

View File

@@ -0,0 +1,91 @@
@ECHO off
REM Wait X second for memory on Arduino Due is erased.
SET WAIT_ERASED=4
ECHO ------ External tool BossacArduinoDue started ------
REM number of command line arguments ok?
REM IF [%1]==[] GOTO error_args
REM IF [%2]==[] GOTO error_args
REM set command line arguments
SET BOSSACPATH=..\tools\win\tool-bossac\bossac.exe
SET BINFILE=firmware.bin
REM parse command line arguments
SET BOSSACPATH=%BOSSACPATH:"=%
SET BINFILE=%BINFILE:"=%
REM workeround for bug in Atmel Studio 6.0.1996 Service Pack 2
SET BINFILE=%BINFILE:\\=\%
SET BINFILE=%BINFILE:.cproj=%
REM bossac path exist?
IF NOT EXIST "%BOSSACPATH%" GOTO error_arg1
REM bin file exist?
IF NOT EXIST "%BINFILE%" GOTO error_binfile
REM fetch DeviceID of Arduino Due Programming Port from WMI Service
FOR /f "tokens=* skip=1" %%a IN ('wmic PATH Win32_SerialPort Where "Caption LIKE '%%BOSSA%%'" get DeviceID') DO (
SET COMX=%%a
GOTO exit1
)
REM Arduino Due Programming Port not exist
GOTO error_comport
:exit1
REM remove blank
SET COMPORT=%COMX: =%
REM report in Atmel Studio 6.0 IDE output window
ECHO BossacPath=%BOSSACPATH%
ECHO BinFile=%BINFILE%
ECHO Arduino Due Programming Port is detected as %COMPORT%.
REM The bossac bootloader only runs if the memory on Arduino Due is erased.
REM The Arduino IDE does this by opening and closing the COM port at 1200 baud.
REM This causes the Due to execute a soft erase command.
ECHO Forcing reset using 1200bps open/close on port
ECHO MODE %COMPORT%:1200,N,8,1
MODE %COMPORT%:1200,N,8,1
REM Wait X second for memory on Arduino Due is erased.
ECHO Wait for memory on Arduino Due is erased...
PING -n %WAIT_ERASED% 127.0.0.1>NUL
REM Execute bossac.exe
ECHO Execute bossac with command line:
"%BOSSACPATH%" -i --port=%COMPORT% --unlock -R
REM START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -u -e -w -v -b "%BINFILE%" -R
GOTO end
:error_args
ECHO Error: wrong number of command line arguments passed!
GOTO end
:error_arg1
ECHO Error: command line argument 1 - path to bossac.exe not exist! - "C:\Program Files (x86)\arduino-1.5.2\hardware\tools\bossac.exe"
ECHO Error: command line argument 1 - argument passed = %1
GOTO end
:error_arg2
ECHO Error: command line argument 2 - path to bin file not exist! - use $(OutputDirectory)\$(OutputFileName).bin
ECHO Error: command line argument 2 - argument passed = %1
GOTO end
:error_binfile
ECHO Error: bin file "%BINFILE%" not exist!
GOTO end
:error_comport
ECHO Error: Arduino Due Programming Port not found!
:end
ECHO ======================== Done ========================

View File

@@ -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
) )
@@ -59,8 +59,8 @@ PING -n %WAIT_ERASED% 127.0.0.1>NUL
REM Execute bossac.exe REM Execute bossac.exe
ECHO Execute bossac with command line: ECHO Execute bossac with command line:
ECHO "%BOSSACPATH%" -i -d --port=%COMPORT% -U false -e -w -v -b "%BINFILE%" -R "%BOSSACPATH%" -i --port=%COMPORT% -U false -w -v -b "%BINFILE%" -R
START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -U false -e -w -v -b "%BINFILE%" -R REM START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -U false -e -w -v -b "%BINFILE%" -R
GOTO end GOTO end

View File

@@ -0,0 +1,91 @@
@ECHO off
REM Wait X second for memory on Arduino Due is erased.
SET WAIT_ERASED=4
ECHO ------ External tool BossacArduinoDue started ------
REM number of command line arguments ok?
REM IF [%1]==[] GOTO error_args
REM IF [%2]==[] GOTO error_args
REM set command line arguments
SET BOSSACPATH=..\tools\win\tool-bossac\bossac.exe
SET BINFILE=firmware.bin
REM parse command line arguments
SET BOSSACPATH=%BOSSACPATH:"=%
SET BINFILE=%BINFILE:"=%
REM workeround for bug in Atmel Studio 6.0.1996 Service Pack 2
SET BINFILE=%BINFILE:\\=\%
SET BINFILE=%BINFILE:.cproj=%
REM bossac path exist?
IF NOT EXIST "%BOSSACPATH%" GOTO error_arg1
REM bin file exist?
IF NOT EXIST "%BINFILE%" GOTO error_binfile
REM fetch DeviceID of Arduino Due Programming Port from WMI Service
FOR /f "tokens=* skip=1" %%a IN ('wmic PATH Win32_SerialPort Where "Caption LIKE '%%BOSSA%%'" get DeviceID') DO (
SET COMX=%%a
GOTO exit1
)
REM Arduino Due Programming Port not exist
GOTO error_comport
:exit1
REM remove blank
SET COMPORT=%COMX: =%
REM report in Atmel Studio 6.0 IDE output window
ECHO BossacPath=%BOSSACPATH%
ECHO BinFile=%BINFILE%
ECHO Arduino Due Programming Port is detected as %COMPORT%.
REM The bossac bootloader only runs if the memory on Arduino Due is erased.
REM The Arduino IDE does this by opening and closing the COM port at 1200 baud.
REM This causes the Due to execute a soft erase command.
ECHO Forcing reset using 1200bps open/close on port
ECHO MODE %COMPORT%:1200,N,8,1
MODE %COMPORT%:1200,N,8,1
REM Wait X second for memory on Arduino Due is erased.
ECHO Wait for memory on Arduino Due is erased...
PING -n %WAIT_ERASED% 127.0.0.1>NUL
REM Execute bossac.exe
ECHO Execute bossac with command line:
"%BOSSACPATH%" -i --port=%COMPORT% -w -v -b "%BINFILE%" -R
REM START /WAIT "" "%BOSSACPATH%" -i --port=%COMPORT% -u -e -w -v -b "%BINFILE%" -R
GOTO end
:error_args
ECHO Error: wrong number of command line arguments passed!
GOTO end
:error_arg1
ECHO Error: command line argument 1 - path to bossac.exe not exist! - "C:\Program Files (x86)\arduino-1.5.2\hardware\tools\bossac.exe"
ECHO Error: command line argument 1 - argument passed = %1
GOTO end
:error_arg2
ECHO Error: command line argument 2 - path to bin file not exist! - use $(OutputDirectory)\$(OutputFileName).bin
ECHO Error: command line argument 2 - argument passed = %1
GOTO end
:error_binfile
ECHO Error: bin file "%BINFILE%" not exist!
GOTO end
:error_comport
ECHO Error: Arduino Due Programming Port not found!
:end
ECHO ======================== Done ========================

View 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

File diff suppressed because it is too large Load Diff

View File

@@ -0,0 +1 @@
cp ../../.pio/build/lighthub21/firmware.bin .

6597
compiled/nrf52840-5500 Normal file

File diff suppressed because it is too large Load Diff

File diff suppressed because it is too large Load Diff

Binary file not shown.

Binary file not shown.

Binary file not shown.

9862
compiled/stm32/firmware.map Normal file

File diff suppressed because it is too large Load Diff

BIN
compiled/tools/arduinoOTA Normal file

Binary file not shown.

Binary file not shown.

Binary file not shown.

Binary file not shown.

16
compiled/update_bin.bat Normal file
View File

@@ -0,0 +1,16 @@
copy ..\.pio\build\due\firmware.bin due
copy ..\.pio\build\controllino\firmware.hex controllino
copy ..\.pio\build\m5stack\firmware.bin m5stack
copy ..\.pio\build\mega2560slim-5100\firmware.hex mega2560slim-5100
copy ..\.pio\build\mega2560slim-5100\firmware.bin mega2560slim-5100
copy ..\.pio\build\mega2560slim2\firmware.hex mega2560slim2
copy ..\.pio\build\mega2560slim2\firmware.bin mega2560slim2
copy ..\.pio\build\due-5100\firmware.bin due-5100
copy ..\.pio\build\mega2560-5100\firmware.hex mega2560-5100
copy ..\.pio\build\due-5500\firmware.bin due-5500
copy ..\.pio\build\nrf52840\firmware.hex nrf52840-5500
copy ..\.pio\build\esp32-wifi\firmware.bin esp32-wifi
copy ..\.pio\build\stm32-enc2860\firmware.bin stm32-enc2860
copy ..\.pio\build\esp8266-wifi\firmware.bin esp8266-wifi
copy ..\.pio\build\lighthub21\firmware.bin lighthub21
copy ..\.pio\build\mega2560-5500\firmware.hex mega2560-5500

View File

@@ -0,0 +1,25 @@
{
"syslog":["95.31.43.9"],
"items": {
"ledhum":[6,-13],
"reghum": [13, [
[50, 10, 0, 60, 250, 200], [{"item": "relayhum"}, {"item":"ledhum"}]
], 30, 12],
"relayhum": [16, [12, 1200], 255, 2]
},
"in":{
"0":{"T":0,
"click":{ "item":"reghum","icmd":"TOGGLE"},
"dclick":{ "emit":"myhome/light-d2/light","ecmd":"TOGGLE"}
},
"3":{"T":4,
"temp":{"emit":"plugtemp"},
"hum":{"item":"reghum/val","emit":"plughum"}
}
},
"mqtt":["plug00","192.168.88.2"]
}

Binary file not shown.

Binary file not shown.

Binary file not shown.

View File

@@ -0,0 +1,3 @@
mode com3:1200,n,8,1
pause
..\tools\win\tool-bossac\bossac.exe -i --port=com3 -U false -e -w -v -b firmware.bin -R

View File

@@ -1,6 +1,8 @@
import os
Import("env") Import("env")
script = env.GetProjectOption("_upload_command")
script = env.GetProjectOption("_upload_command")
spath = os.path.abspath(script)
#env.Replace( #env.Replace(
# UPLOADER="executable or path to executable", # UPLOADER="executable or path to executable",
# UPLOADCMD=script # UPLOADCMD=script
@@ -8,5 +10,4 @@ script = env.GetProjectOption("_upload_command")
env.AddCustomTarget( env.AddCustomTarget(
"ota", "ota",
"$BUILD_DIR/${PROGNAME}.bin", "$BUILD_DIR/${PROGNAME}.bin",
script spath)
)

18
ldscripts/bootloader.ld Normal file
View File

@@ -0,0 +1,18 @@
/*
* Linker script for Generic STM32F103RE boards, using the generic bootloader (which takes the lower 8k of memory)
*/
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
rom (rx) : ORIGIN = 0x08002000, LENGTH = 504K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

220
ldscripts/common.inc Normal file
View File

@@ -0,0 +1,220 @@
/*
* Linker script for libmaple.
*
* Original author "lanchon" from ST forums, with modifications by LeafLabs.
*/
OUTPUT_FORMAT ("elf32-littlearm", "elf32-bigarm", "elf32-littlearm")
/*
* Configure other libraries we want in the link.
*
* libgcc, libc, and libm are common across supported toolchains.
* However, some toolchains require additional archives which aren't
* present everywhere (e.g. ARM's gcc-arm-embedded releases).
*
* To hack around this, we let the build system specify additional
* archives by putting the right extra_libs.inc (in a directory under
* toolchains/) in our search path.
*/
GROUP(libgcc.a libc.a libm.a)
INCLUDE ldscripts/extra_libs.inc
/*
* These force the linker to search for vector table symbols.
*
* These symbols vary by STM32 family (and also within families).
* It's up to the build system to configure the link's search path
* properly for the target MCU.
*/
INCLUDE ldscripts/vector_symbols.inc
/* STM32 vector table. */
EXTERN(__stm32_vector_table)
/* C runtime initialization function. */
EXTERN(start_c)
/* main entry point */
EXTERN(main)
/* Initial stack pointer value. */
EXTERN(__msp_init)
PROVIDE(__msp_init = ORIGIN(ram) + LENGTH(ram));
/* Reset vector and chip reset entry point */
EXTERN(__start__)
ENTRY(__start__)
PROVIDE(__exc_reset = __start__);
/* Heap boundaries, for libmaple */
EXTERN(_lm_heap_start);
EXTERN(_lm_heap_end);
SECTIONS
{
.text :
{
__text_start__ = .;
/*
* STM32 vector table. Leave this here. Yes, really.
*/
*(.stm32.interrupt_vector)
/*
* Program code and vague linking
*/
*(.text .text.* .gnu.linkonce.t.*)
*(.plt)
*(.gnu.warning)
*(.glue_7t) *(.glue_7) *(.vfp11_veneer)
*(.ARM.extab* .gnu.linkonce.armextab.*)
*(.gcc_except_table)
*(.eh_frame_hdr)
*(.eh_frame)
. = ALIGN(4);
KEEP(*(.init))
. = ALIGN(4);
__preinit_array_start = .;
KEEP (*(.preinit_array))
__preinit_array_end = .;
. = ALIGN(4);
__init_array_start = .;
KEEP (*(SORT(.init_array.*)))
KEEP (*(.init_array))
__init_array_end = .;
. = ALIGN(0x4);
KEEP (*crtbegin.o(.ctors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .ctors))
KEEP (*(SORT(.ctors.*)))
KEEP (*crtend.o(.ctors))
. = ALIGN(4);
KEEP(*(.fini))
. = ALIGN(4);
__fini_array_start = .;
KEEP (*(.fini_array))
KEEP (*(SORT(.fini_array.*)))
__fini_array_end = .;
KEEP (*crtbegin.o(.dtors))
KEEP (*(EXCLUDE_FILE (*crtend.o) .dtors))
KEEP (*(SORT(.dtors.*)))
KEEP (*crtend.o(.dtors))
} > REGION_TEXT
/*
* End of text
*/
.text.align :
{
. = ALIGN(8);
__text_end__ = .;
} > REGION_TEXT
/*
* .ARM.exidx exception unwinding; mandated by ARM's C++ ABI
*/
__exidx_start = .;
.ARM.exidx :
{
*(.ARM.exidx* .gnu.linkonce.armexidx.*)
} > REGION_RODATA
__exidx_end = .;
/*
* .data
*/
.data :
{
__data_start__ = .;
LONG(0)
. = ALIGN(8);
*(.got.plt) *(.got)
*(.data .data.* .gnu.linkonce.d.*)
. = ALIGN(8);
__data_end__ = .;
} > REGION_DATA AT> REGION_RODATA
/*
* Read-only data
*/
.rodata :
{
*(.rodata .rodata.* .gnu.linkonce.r.*)
/* .USER_FLASH: We allow users to allocate into Flash here */
*(.USER_FLASH)
/* ROM image configuration; for C startup */
. = ALIGN(4);
_lm_rom_img_cfgp = .;
LONG(LOADADDR(.data));
/*
* Heap: Linker scripts may choose a custom heap by overriding
* _lm_heap_start and _lm_heap_end. Otherwise, the heap is in
* internal SRAM, beginning after .bss, and growing towards
* the stack.
*
* I'm shoving these here naively; there's probably a cleaner way
* to go about this. [mbolivar]
*/
_lm_heap_start = DEFINED(_lm_heap_start) ? _lm_heap_start : _end;
_lm_heap_end = DEFINED(_lm_heap_end) ? _lm_heap_end : __msp_init;
} > REGION_RODATA
/*
* .bss
*/
.bss :
{
. = ALIGN(8);
__bss_start__ = .;
*(.bss .bss.* .gnu.linkonce.b.*)
*(COMMON)
. = ALIGN (8);
__bss_end__ = .;
_end = __bss_end__;
} > REGION_BSS
/*
* Debugging sections
*/
.stab 0 (NOLOAD) : { *(.stab) }
.stabstr 0 (NOLOAD) : { *(.stabstr) }
/* DWARF debug sections.
* Symbols in the DWARF debugging sections are relative to the beginning
* of the section so we begin them at 0. */
/* DWARF 1 */
.debug 0 : { *(.debug) }
.line 0 : { *(.line) }
/* GNU DWARF 1 extensions */
.debug_srcinfo 0 : { *(.debug_srcinfo) }
.debug_sfnames 0 : { *(.debug_sfnames) }
/* DWARF 1.1 and DWARF 2 */
.debug_aranges 0 : { *(.debug_aranges) }
.debug_pubnames 0 : { *(.debug_pubnames) }
/* DWARF 2 */
.debug_info 0 : { *(.debug_info .gnu.linkonce.wi.*) }
.debug_abbrev 0 : { *(.debug_abbrev) }
.debug_line 0 : { *(.debug_line) }
.debug_frame 0 : { *(.debug_frame) }
.debug_str 0 : { *(.debug_str) }
.debug_loc 0 : { *(.debug_loc) }
.debug_macinfo 0 : { *(.debug_macinfo) }
/* SGI/MIPS DWARF 2 extensions */
.debug_weaknames 0 : { *(.debug_weaknames) }
.debug_funcnames 0 : { *(.debug_funcnames) }
.debug_typenames 0 : { *(.debug_typenames) }
.debug_varnames 0 : { *(.debug_varnames) }
.note.gnu.arm.ident 0 : { KEEP (*(.note.gnu.arm.ident)) }
.ARM.attributes 0 : { KEEP (*(.ARM.attributes)) }
/DISCARD/ : { *(.note.GNU-stack) }
}

7
ldscripts/extra_libs.inc Normal file
View File

@@ -0,0 +1,7 @@
/*
* Extra archives needed by ARM's GCC ARM Embedded arm-none-eabi-
* releases (https://launchpad.net/gcc-arm-embedded/).
*/
/* This is for the provided newlib. */
GROUP(libnosys.a)

26
ldscripts/flash.ld Normal file
View File

@@ -0,0 +1,26 @@
/*
* libmaple linker script for "Flash" builds.
*
* A Flash build puts .text (and .rodata) in Flash, and
* .data/.bss/heap (of course) in SRAM, but offsets the sections by
* enough space to store the Maple bootloader, which lives in low
* Flash and uses low memory.
*/
/*
* This pulls in the appropriate MEMORY declaration from the right
* subdirectory of stm32/mem/ (the environment must call ld with the
* right include directory flags to make this happen). Boards can also
* use this file to use any of libmaple's memory-related hooks (like
* where the heap should live).
*/
INCLUDE mem-flash.inc
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

31
ldscripts/jtag.ld Normal file
View File

@@ -0,0 +1,31 @@
/*
* libmaple linker script for "JTAG" builds.
*
* A "JTAG" build puts .text (and .rodata) in Flash, and
* .data/.bss/heap (of course) in SRAM, but links starting at the
* Flash and SRAM starting addresses (0x08000000 and 0x20000000
* respectively). This will wipe out a Maple bootloader if there's one
* on the board, so only use this if you know what you're doing.
*
* Of course, a "JTAG" build is perfectly usable for upload over SWD,
* the system memory bootloader, etc. The name is just a historical
* artifact.
*/
/*
* This pulls in the appropriate MEMORY declaration from the right
* subdirectory of stm32/mem/ (the environment must call ld with the
* right include directory flags to make this happen). Boards can also
* use this file to use any of libmaple's memory-related hooks (like
* where the heap should live).
*/
INCLUDE mem-jtag.inc
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

46
ldscripts/ldscript.ld Normal file
View File

@@ -0,0 +1,46 @@
/*
!!!!!!!!!!!! STM32Duino default linker script
* This script extends the default linker script to add a .noinit
* section. This section is just mapped to RAM, but it is emitted
* separately from the .data and .bss sections (both of which are
* initialized by startup code), so any variables in this section are
* untouched on startup (so they survive across resets).
*
* This script is intended to supplied to the linker's -T / --script
* option as the primary linker script. When the linker sees an INSERT
* command, this will cause it to *also* read the default linker script
* (after reading this script) and then executing the INSERT commands
* after both scripts have been read.
*
* Note that parsing of linker scripts is a bit peculiar, e.g. INSERT
* does not textually inserts, it inserts any generated output sections.
* Also, because this script is read *first*, we cannot refer to things
* in the default script. In particular, it would make sense to add >
* RAM to the output section below to ensure that the section is mapped
* into RAM, but the RAM region is not defined yet (I think it would
* work though, but produces warnings). Instead, we just rely on the
* defaults used by the linker: If no region is defined for an output
* section, it will just map to first address after the previous section
* (.bss in this case, which is fine).
*/
SECTIONS
{
/* Define a noinit output section and mark it as NOLOAD to prevent
* putting its contents into the resulting .bin file (which is the
* default). */
.noinit (NOLOAD) :
{
/* Ensure output is aligned */
. = ALIGN(4);
/* Define a global _snoinit (and _enoinit below) symbol just in case
* code wants to iterate over all noinit variables for some reason */
_snoinit = .;
/* Actually import the .noinit and .noinit* import sections */
*(.noinit)
*(.noinit*)
. = ALIGN(4);
_enoinit = .;
}
}
INSERT AFTER .bss;

5
ldscripts/mem-flash.inc Normal file
View File

@@ -0,0 +1,5 @@
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 492K
}

5
ldscripts/mem-jtag.inc Normal file
View File

@@ -0,0 +1,5 @@
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}

5
ldscripts/mem-ram.inc Normal file
View File

@@ -0,0 +1,5 @@
MEMORY
{
ram (rwx) : ORIGIN = 0x20000C00, LENGTH = 61K
rom (rx) : ORIGIN = 0x08005000, LENGTH = 0K
}

25
ldscripts/ram.ld Normal file
View File

@@ -0,0 +1,25 @@
/*
* libmaple linker script for RAM builds.
*
* A Flash build puts .text, .rodata, and .data/.bss/heap (of course)
* in SRAM, but offsets the sections by enough space to store the
* Maple bootloader, which uses low memory.
*/
/*
* This pulls in the appropriate MEMORY declaration from the right
* subdirectory of stm32/mem/ (the environment must call ld with the
* right include directory flags to make this happen). Boards can also
* use this file to use any of libmaple's memory-related hooks (like
* where the heap should live).
*/
INCLUDE mem-ram.inc
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", ram);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", ram);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

18
ldscripts/stm32f103rb.ld Normal file
View File

@@ -0,0 +1,18 @@
/*
* Linker script for Generic STM32F103RB boards.
*/
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 128K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

View File

@@ -0,0 +1,17 @@
/*
* Linker script for Generic STM32F103RB boards, using the generic bootloader (which takes the lower 8k of memory)
*/
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 20K
rom (rx) : ORIGIN = 0x08002000, LENGTH = 120K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

18
ldscripts/stm32f103rc.ld Normal file
View File

@@ -0,0 +1,18 @@
/*
* Linker script for Generic STM32F103RC boards.
*/
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 256K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

View File

@@ -0,0 +1,18 @@
/*
* Linker script for Generic STM32F103RC boards, using the generic bootloader (which takes the lower 8k of memory)
*/
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 48K
rom (rx) : ORIGIN = 0x08002000, LENGTH = 248K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

18
ldscripts/stm32f103re.ld Normal file
View File

@@ -0,0 +1,18 @@
/*
* Linker script for Generic STM32F103RE boards.
*/
MEMORY
{
ram (rwx) : ORIGIN = 0x20000000, LENGTH = 64K
rom (rx) : ORIGIN = 0x08000000, LENGTH = 512K
}
/* Provide memory region aliases for common.inc */
REGION_ALIAS("REGION_TEXT", rom);
REGION_ALIAS("REGION_DATA", ram);
REGION_ALIAS("REGION_BSS", ram);
REGION_ALIAS("REGION_RODATA", rom);
/* Let common.inc handle the real work. */
INCLUDE ldscripts/common.inc

View File

@@ -0,0 +1,78 @@
EXTERN(__msp_init)
EXTERN(__exc_reset)
EXTERN(__exc_nmi)
EXTERN(__exc_hardfault)
EXTERN(__exc_memmanage)
EXTERN(__exc_busfault)
EXTERN(__exc_usagefault)
EXTERN(__stm32reservedexception7)
EXTERN(__stm32reservedexception8)
EXTERN(__stm32reservedexception9)
EXTERN(__stm32reservedexception10)
EXTERN(__exc_svc)
EXTERN(__exc_debug_monitor)
EXTERN(__stm32reservedexception13)
EXTERN(__exc_pendsv)
EXTERN(__exc_systick)
EXTERN(__irq_wwdg)
EXTERN(__irq_pvd)
EXTERN(__irq_tamper)
EXTERN(__irq_rtc)
EXTERN(__irq_flash)
EXTERN(__irq_rcc)
EXTERN(__irq_exti0)
EXTERN(__irq_exti1)
EXTERN(__irq_exti2)
EXTERN(__irq_exti3)
EXTERN(__irq_exti4)
EXTERN(__irq_dma1_channel1)
EXTERN(__irq_dma1_channel2)
EXTERN(__irq_dma1_channel3)
EXTERN(__irq_dma1_channel4)
EXTERN(__irq_dma1_channel5)
EXTERN(__irq_dma1_channel6)
EXTERN(__irq_dma1_channel7)
EXTERN(__irq_adc)
EXTERN(__irq_usb_hp_can_tx)
EXTERN(__irq_usb_lp_can_rx0)
EXTERN(__irq_can_rx1)
EXTERN(__irq_can_sce)
EXTERN(__irq_exti9_5)
EXTERN(__irq_tim1_brk)
EXTERN(__irq_tim1_up)
EXTERN(__irq_tim1_trg_com)
EXTERN(__irq_tim1_cc)
EXTERN(__irq_tim2)
EXTERN(__irq_tim3)
EXTERN(__irq_tim4)
EXTERN(__irq_i2c1_ev)
EXTERN(__irq_i2c1_er)
EXTERN(__irq_i2c2_ev)
EXTERN(__irq_i2c2_er)
EXTERN(__irq_spi1)
EXTERN(__irq_spi2)
EXTERN(__irq_usart1)
EXTERN(__irq_usart2)
EXTERN(__irq_usart3)
EXTERN(__irq_exti15_10)
EXTERN(__irq_rtcalarm)
EXTERN(__irq_usbwakeup)
EXTERN(__irq_tim8_brk)
EXTERN(__irq_tim8_up)
EXTERN(__irq_tim8_trg_com)
EXTERN(__irq_tim8_cc)
EXTERN(__irq_adc3)
EXTERN(__irq_fsmc)
EXTERN(__irq_sdio)
EXTERN(__irq_tim5)
EXTERN(__irq_spi3)
EXTERN(__irq_uart4)
EXTERN(__irq_uart5)
EXTERN(__irq_tim6)
EXTERN(__irq_tim7)
EXTERN(__irq_dma2_channel1)
EXTERN(__irq_dma2_channel2)
EXTERN(__irq_dma2_channel3)
EXTERN(__irq_dma2_channel4_5)

View File

@@ -10,7 +10,7 @@ extern PubSubClient mqttClient;
extern int8_t ethernetIdleCount; extern int8_t ethernetIdleCount;
int abstractCh::publishTopic(const char* topic, long value, const char* subtopic) int abstractCh::publishTopic(const char* topic, long value, const char* subtopic)
{ {
char valstr[16]; char valstr[16];
printUlongValueToStr(valstr, value); printUlongValueToStr(valstr, value);
return publishTopic(topic, valstr,subtopic); return publishTopic(topic, valstr,subtopic);
@@ -19,7 +19,7 @@ int abstractCh::publishTopic(const char* topic, long value, const char* subtopic
int abstractCh::publishTopic(const char* topic, float value, const char* subtopic) int abstractCh::publishTopic(const char* topic, float value, const char* subtopic)
{ {
char valstr[16]; char valstr[16];
printFloatValueToStr(value, valstr); printFloatValueToStr(valstr, value);
return publishTopic(topic, valstr,subtopic); return publishTopic(topic, valstr,subtopic);
}; };

View File

@@ -3,7 +3,7 @@
#define CST_UNKNOWN 0 #define CST_UNKNOWN 0
#define CST_INITIALIZED 1 #define CST_INITIALIZED 1
#define CST_FAILED 2 #define CST_FAILED -1
class abstractCh { class abstractCh {
public: public:

View File

@@ -20,7 +20,7 @@ int abstractIn::publish(long value, const char* subtopic)
int abstractIn::publish(float value, const char* subtopic) int abstractIn::publish(float value, const char* subtopic)
{ {
char valstr[16]; char valstr[16];
printFloatValueToStr(value, valstr); printFloatValueToStr(valstr, value);
return publish(valstr,subtopic); return publish(valstr,subtopic);
}; };

View File

@@ -1,3 +1,5 @@
#pragma once #pragma once
#include "Arduino.h" #include "Arduino.h"
#include "abstractch.h" #include "abstractch.h"

View File

@@ -12,6 +12,8 @@ int abstractOut::isActive()
case CMD_VOID: case CMD_VOID:
return 0; return 0;
break; break;
case CMD_ON: //trying (PWM ON set=0 issue)
return 1;
default: default:
st.loadItem(item); st.loadItem(item);
return st.getPercents255(); return st.getPercents255();

View File

@@ -8,8 +8,9 @@ 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 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

View File

@@ -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,27 +60,28 @@ 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(SEND_PARAMETERS | SEND_DEFFERED); item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
}; };
PixelCtrl(cmd,subItem, true); PixelCtrl(cmd,subItem, true, authorized);
// item->SendStatus(SEND_COMMAND | SEND_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(SEND_COMMAND); // item->SendStatus(FLAG_COMMAND);
return 1; return 1;
default: default:

View File

@@ -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:

View File

@@ -30,7 +30,7 @@ bool systemConfig::isValidSysConf()
stream->close(); stream->close();
return false; return false;
} }
stream->close(); stream->close();
return true; return true;
}; };
@@ -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));
@@ -293,6 +293,19 @@ bool systemConfig::setConfigFlags(systemConfigFlags flags)
return setConfigFlags(flags); return setConfigFlags(flags);
} }
bool systemConfig::getDHCPfallback()
{
systemConfigFlags flags = getConfigFlags();
return flags.dhcpFallback;
}
bool systemConfig::setDHCPfallback(bool flag)
{
systemConfigFlags flags = getConfigFlags();
flags.dhcpFallback=flag;
return setConfigFlags(flags);
}
bool systemConfig::getLoadHTTPConfig() bool systemConfig::getLoadHTTPConfig()
{ {
systemConfigFlags flags = getConfigFlags(); systemConfigFlags flags = getConfigFlags();

View File

@@ -61,6 +61,9 @@ class systemConfig {
bool saveETAG(); bool saveETAG();
bool loadETAG(); bool loadETAG();
bool getDHCPfallback();
bool setDHCPfallback(bool flag);
systemConfigFlags getConfigFlags(); systemConfigFlags getConfigFlags();
bool setConfigFlags(systemConfigFlags flags); bool setConfigFlags(systemConfigFlags flags);

View File

@@ -8,7 +8,7 @@
#endif #endif
#if defined(ARDUINO_ARCH_AVR) #if defined(ARDUINO_ARCH_AVR)
#include <EEPROM.h> #include <EEPROM.h>
#endif #endif
@@ -23,30 +23,21 @@
#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;
#endif
#if defined(__SAM3X8E__)
DueFlashStorage EEPROM; DueFlashStorage EEPROM;
static char samBuffer[64];
short samBufferPos = 0;
#endif #endif
#ifdef NRF5 #ifdef NRF5
#include <NRFFlashStorage.h> //STUB
NRFFlashStorage EEPROM; NRFFlashStorage EEPROM;
#endif #endif
#ifdef ARDUINO_ARCH_STM32 #ifdef ARDUINO_ARCH_STM32
NRFFlashStorage EEPROM; //NRFFlashStorage EEPROM;
#include <EEPROM.h>
#define DATA_LENGTH E2END
//FLASH_PAGE_SIZE = 0x400
#endif #endif
#if defined(FS_STORAGE) #if defined(FS_STORAGE)
@@ -114,7 +105,7 @@ NRFFlashStorage EEPROM;
debugSerial<<(F(" Res:"))<<res<<endl; debugSerial<<(F(" Res:"))<<res<<endl;
return res; return res;
}; };
void flashStream::close() {fs.close(); debugSerial<<filename<<" Closed\n";}; void flashStream::close() {fs.flush();fs.close(); debugSerial<<filename<<" Closed\n";};
void flashStream::flush() {fs.flush(); debugSerial<<filename<<" Flushed\n";}; void flashStream::flush() {fs.flush(); debugSerial<<filename<<" Flushed\n";};
size_t flashStream::write(uint8_t ch) size_t flashStream::write(uint8_t ch)
{ {
@@ -129,6 +120,15 @@ NRFFlashStorage EEPROM;
int flashStream::open(short fileNum, char mode) int flashStream::open(short fileNum, char mode)
{ {
#if defined(__SAM3X8E__) //|| defined (ARDUINO_ARCH_STM32)
if (samBufferPos) flush();
samBufferPos = 0;
#endif
#if defined (ARDUINO_ARCH_STM32)
eeprom_buffer_fill();
#endif
switch (fileNum) { switch (fileNum) {
case FN_CONFIG_JSON: case FN_CONFIG_JSON:
pos = 0; pos = 0;
@@ -138,6 +138,7 @@ NRFFlashStorage EEPROM;
#ifdef OTA #ifdef OTA
contentType = HTTP_TEXT_JSON; contentType = HTTP_TEXT_JSON;
#endif #endif
openmode = mode;
return 1; return 1;
case FN_CONFIG_BIN: case FN_CONFIG_BIN:
@@ -148,6 +149,7 @@ NRFFlashStorage EEPROM;
#ifdef OTA #ifdef OTA
contentType = HTTP_OCTET_STREAM; contentType = HTTP_OCTET_STREAM;
#endif #endif
openmode = mode;
return 1; return 1;
default: default:
@@ -171,8 +173,20 @@ NRFFlashStorage EEPROM;
}; };
unsigned int flashStream::seek(unsigned int _pos) unsigned int flashStream::seek(unsigned int _pos)
{ pos=min(_pos, streamSize); {
//debugSerial<<F("Seek:")<<pos<<endl;
#if defined(__SAM3X8E__) //|| defined (ARDUINO_ARCH_STM32)
if (samBufferPos) flush();
#endif
#if defined (ARDUINO_ARCH_STM32)
//eeprom_buffer_flush();
#endif
pos=min(_pos, streamSize);
//Serial.print("StartPos=");Serial.println(startPos);
//Serial.print("Pos=");Serial.println(pos);
//Serial.print("streamSize=");Serial.println(streamSize);
return pos; return pos;
}; };
@@ -196,27 +210,58 @@ NRFFlashStorage EEPROM;
else return -1; else return -1;
}; };
void flashStream::flush() { void flashStream::flush() {
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
if (EEPROM.commitReset()) if (EEPROM.commitReset())
infoSerial<<"Commited to FLASH"<<endl; infoSerial<<"Commited to FLASH"<<endl;
else errorSerial<<"Commit error. len:"<<EEPROM.length()<<endl; else errorSerial<<"Commit error. len:"<<EEPROM.length()<<endl;
#elif defined(__SAM3X8E__) //|| defined (ARDUINO_ARCH_STM32)
if (samBufferPos)
EEPROM.write(startPos+pos-samBufferPos,(byte*)samBuffer,samBufferPos);
samBufferPos=0;
#elif defined (ARDUINO_ARCH_STM32)
eeprom_buffer_flush();
#endif #endif
}; };
size_t flashStream::write(uint8_t ch) size_t flashStream::write(uint8_t ch)
{ {
#if defined(__AVR__) #if defined(__AVR__)
EEPROM.update(startPos+pos++,(char)ch); EEPROM.update(startPos+pos++,(char)ch);
return 1; return 1;
#elif defined(__SAM3X8E__) #elif defined(__SAM3X8E__)// || defined (ARDUINO_ARCH_STM32)
return EEPROM.write(startPos+pos++,(char)ch);
if (samBufferPos==sizeof(samBuffer))
{
samBufferPos = 0;
EEPROM.write(startPos+pos-sizeof(samBuffer),(byte*)samBuffer,sizeof(samBuffer));
}
samBuffer[samBufferPos++]=ch;
pos++;
return 1;
// return EEPROM.write(startPos+pos++,(char)ch);
#elif defined (ARDUINO_ARCH_STM32)
if (startPos+pos<=DATA_LENGTH)
{
eeprom_buffered_write_byte(startPos+pos++,(char)ch);
return 1;
}
else
{
errorSerial<<F("Flash sector exceeded")<<endl;
return 0;
}
#else #else
EEPROM.write(startPos+pos++,(char)ch); EEPROM.write(startPos+pos++,(char)ch);
return 1; return 1;
#endif #endif
}; };
/*
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
size_t flashStream::write(const uint8_t *buffer, size_t size) size_t flashStream::write(const uint8_t *buffer, size_t size)
{ {
@@ -226,7 +271,7 @@ NRFFlashStorage EEPROM;
}; };
#endif #endif
*/
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
void flashStream::putEOF() void flashStream::putEOF()
{ {
@@ -237,7 +282,14 @@ NRFFlashStorage EEPROM;
void flashStream::close() void flashStream::close()
{ {
putEOF(); if (openmode == 'w')
{
putEOF();
debugSerial<<F("EOF")<<endl;
}
#if defined(__SAM3X8E__)
if (samBufferPos) flush();
#endif
} }

View File

@@ -53,9 +53,10 @@ class flashStream : public seekableStream
protected: protected:
unsigned int pos; unsigned int pos;
unsigned int startPos; unsigned int startPos;
char openmode ;
public: public:
flashStream():seekableStream(MAX_STREAM_SIZE){}; flashStream():seekableStream(MAX_STREAM_SIZE){openmode = '\0';};
void setSize(unsigned int _size); void setSize(unsigned int _size);
int open(short fileNum, char mode='\0') ; int open(short fileNum, char mode='\0') ;
virtual int open(String _filename, char mode='\0') override; virtual int open(String _filename, char mode='\0') override;
@@ -66,11 +67,11 @@ public:
virtual void flush(); virtual void flush();
virtual size_t write(uint8_t ch) ; virtual size_t write(uint8_t ch) ;
#if defined(__SAM3X8E__) //#if defined(__SAM3X8E__)
virtual size_t write(const uint8_t *buffer, size_t size) override; //virtual size_t write(const uint8_t *buffer, size_t size) override;
#else //#else
using Print::write;//(const uint8_t *buffer, size_t size); using Print::write;//(const uint8_t *buffer, size_t size);
#endif //#endif
#if defined(ESP8266) || defined(ESP32) #if defined(ESP8266) || defined(ESP32)
virtual void putEOF() override ; virtual void putEOF() override ;

View File

@@ -464,6 +464,8 @@ void Input::dht22Poll() {
#if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32) #if defined(ARDUINO_ARCH_ESP8266) || defined(ARDUINO_ARCH_ESP32)
DHTesp dhtSensor; DHTesp dhtSensor;
dhtSensor.setup(pin, DHTesp::DHT22); dhtSensor.setup(pin, DHTesp::DHT22);
//pinMode(pin, INPUT_PULLUP);
//digitalWrite(pin, LOW); // Switch bus to receive data
TempAndHumidity dhtSensorData = dhtSensor.getTempAndHumidity(); TempAndHumidity dhtSensorData = dhtSensor.getTempAndHumidity();
float temp = roundf(dhtSensorData.temperature * 10) / 10; float temp = roundf(dhtSensorData.temperature * 10) / 10;
float humidity = roundf(dhtSensorData.humidity); float humidity = roundf(dhtSensorData.humidity);
@@ -479,8 +481,8 @@ debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") <<
// New tyle unified activities // New tyle unified activities
aJsonObject *actT = aJson.getObjectItem(inputObj, "temp"); aJsonObject *actT = aJson.getObjectItem(inputObj, "temp");
aJsonObject *actH = aJson.getObjectItem(inputObj, "hum"); aJsonObject *actH = aJson.getObjectItem(inputObj, "hum");
executeCommand(actT,-1,itemCmd(temp)); if (!isnan(temp)) executeCommand(actT,-1,itemCmd(temp));
executeCommand(actH,-1,itemCmd(humidity)); if (!isnan(humidity)) executeCommand(actH,-1,itemCmd(humidity));
//Legacy action conf - TODO - remove in further releases //Legacy action conf - TODO - remove in further releases
aJsonObject *emit = aJson.getObjectItem(inputObj, "emit"); aJsonObject *emit = aJson.getObjectItem(inputObj, "emit");
@@ -503,11 +505,11 @@ debugSerial << F("IN:") << pin << F(" DHT22 type. T=") << temp << F("°C H=") <<
strncpy(addrstr, emit->valuestring, sizeof(addrstr)); strncpy(addrstr, emit->valuestring, sizeof(addrstr));
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
strcat(addrstr, "T"); strcat(addrstr, "T");
printFloatValueToStr(temp, valstr); printFloatValueToStr(valstr, temp);
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
mqttClient.publish(addrstr, valstr); mqttClient.publish(addrstr, valstr);
addrstr[strlen(addrstr) - 1] = 'H'; addrstr[strlen(addrstr) - 1] = 'H';
printFloatValueToStr(humidity, valstr); printFloatValueToStr(valstr, humidity);
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
mqttClient.publish(addrstr, valstr); mqttClient.publish(addrstr, valstr);
@@ -1021,7 +1023,7 @@ void Input::onAnalogChanged(itemCmd newValue) {
strncpy(addrstr,emit->valuestring,sizeof(addrstr)); strncpy(addrstr,emit->valuestring,sizeof(addrstr));
if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring); if (!strchr(addrstr,'/')) setTopic(addrstr,sizeof(addrstr),T_OUT,emit->valuestring);
char strVal[16]; char strVal[16];
newValue.toString(strVal,sizeof(strVal),SEND_PARAMETERS); newValue.toString(strVal,sizeof(strVal),FLAG_PARAMETERS);
if (mqttClient.connected() && !ethernetIdleCount) if (mqttClient.connected() && !ethernetIdleCount)
mqttClient.publish(addrstr, strVal, true); mqttClient.publish(addrstr, strVal, true);

View File

@@ -541,9 +541,9 @@ void setupIpmodbus(){
// Calculate Modbus RTU character timeout and frame delay // Calculate Modbus RTU character timeout and frame delay
byte bits = // number of bits per character (11 in default Modbus RTU settings) byte bits = // number of bits per character (11 in default Modbus RTU settings)
1 + // start bit 1 + // start bit
(((MODBUS_DIMMER_PARAM & 0x06) >> 1) + 5) + // data bits (((MODBUS_SERIAL_PARAM & 0x06) >> 1) + 5) + // data bits
(((MODBUS_DIMMER_PARAM & 0x08) >> 3) + 1); // stop bits (((MODBUS_SERIAL_PARAM & 0x08) >> 3) + 1); // stop bits
if (((MODBUS_DIMMER_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present) if (((MODBUS_SERIAL_PARAM & 0x30) >> 4) > 1) bits += 1; // parity bit (if present)
//bits = 11; //bits = 11;
int T = ((unsigned long)bits * 1000000UL) / MODBUS_SERIAL_BAUD; // time to send 1 character over serial in microseconds int T = ((unsigned long)bits * 1000000UL) / MODBUS_SERIAL_BAUD; // time to send 1 character over serial in microseconds

File diff suppressed because it is too large Load Diff

View File

@@ -31,11 +31,13 @@ e-mail anklimov@gmail.com
#define S_RGB 6 #define S_RGB 6
#define S_FAN 7 #define S_FAN 7
#define S_MODE 8 #define S_MODE 8
#define S_HUE 9 #define S_CTRL 9
#define S_SAT 10 #define S_HUE 10
#define S_TEMP 11 #define S_SAT 11
#define S_RAW 12 #define S_TEMP 12
#define S_ADDITIONAL 12 #define S_RAW 13
#define S_ADDITIONAL 13
#define CH_DIMMER 0 //DMX 1-4 ch #define CH_DIMMER 0 //DMX 1-4 ch
#define CH_RGBW 1 //DMX 4 ch #define CH_RGBW 1 //DMX 4 ch
@@ -59,6 +61,7 @@ e-mail anklimov@gmail.com
#define CH_ELEVATOR 19 #define CH_ELEVATOR 19
#define CH_COUNTER 20 #define CH_COUNTER 20
#define CH_HUMIDIFIER 21 #define CH_HUMIDIFIER 21
#define CH_MERCURY 22
//#define CHANNEL_TYPES 13 //#define CHANNEL_TYPES 13
@@ -100,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:
@@ -116,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);
@@ -131,9 +134,9 @@ class Item
chPersistent * getPersistent(); chPersistent * getPersistent();
chPersistent * setPersistent(chPersistent * par); chPersistent * setPersistent(chPersistent * par);
void setCmd(uint8_t cmdValue); void setCmd(uint8_t cmdValue);
short getFlag (short flag=FLAG_MASK); uint32_t getFlag (uint32_t flag=FLAG_MASK);
void setFlag (short flag); void setFlag (uint32_t flag);
void clearFlag (short flag); void clearFlag (uint32_t flag);
void setVal(long int par); void setVal(long int par);
void setFloatVal(float par); void setFloatVal(float par);
void setSubtype(uint8_t par); void setSubtype(uint8_t par);
@@ -145,6 +148,9 @@ 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, bool authorized);
int scheduleOppositeCommand(itemCmd cmd,bool isActiveNow,bool authorized);
int isScheduled();
protected: protected:
long int limitSetValue(); long int limitSetValue();
@@ -158,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();

View File

@@ -4,6 +4,7 @@
#include "Streaming.h" #include "Streaming.h"
#include "item.h" #include "item.h"
#include "bright.h" #include "bright.h"
#include <utility/stringbuffer.h>>
#ifndef HSV_DISABLE #ifndef HSV_DISABLE
#ifdef ADAFRUIT_LED #ifdef ADAFRUIT_LED
@@ -38,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)
@@ -108,6 +123,7 @@ uint8_t itemCmd::getStoragetypeByChanType(short chanType)
case CH_PWM: case CH_PWM:
case CH_VC: case CH_VC:
case CH_MODBUS: case CH_MODBUS:
//case CH_RELAY:
//case CH_GROUP: //case CH_GROUP:
return ST_PERCENTS255; return ST_PERCENTS255;
break; break;
@@ -1047,18 +1063,22 @@ bool itemCmd::loadItem(Item * item, uint16_t optionsFlag)
if (item && item->isValid()) if (item && item->isValid())
{ {
short subtype =item->getSubtype(); short subtype =item->getSubtype();
if (optionsFlag & SEND_COMMAND) cmd.cmdCode = item->getCmd(); if (optionsFlag & FLAG_COMMAND) cmd.cmdCode = item->getCmd();
//if (optionsFlag & FLAG_FLAGS)
// if (item->getFlag(FLAG_DISABLED))
// cmd.cmdCode = CMD_DISABLE;
if (subtype) if (subtype)
{ {
cmd.itemArgType= subtype; cmd.itemArgType= subtype;
if (optionsFlag & SEND_PARAMETERS) param.asInt32 = item->itemVal->valueint; if (optionsFlag & FLAG_PARAMETERS) param.asInt32 = item->itemVal->valueint;
//debugSerial<<F("Loaded :"); //debugSerial<<F("Loaded :");
//debugOut(); //debugOut();
return true; return true;
} }
if (optionsFlag & SEND_PARAMETERS) if (optionsFlag & FLAG_PARAMETERS)
switch (item->itemVal->type) switch (item->itemVal->type)
{ {
case aJson_Int: case aJson_Int:
@@ -1091,7 +1111,7 @@ bool itemCmd::loadItemDef(Item * item, uint16_t optionsFlag)
setDefault(); setDefault();
saveItem(item); saveItem(item);
debugOut(); debugOut();
item->SendStatus(SEND_PARAMETERS | SEND_DEFFERED); item->SendStatus(FLAG_PARAMETERS | FLAG_SEND_DEFFERED);
return false; return false;
} }
return true; return true;
@@ -1101,8 +1121,38 @@ bool itemCmd::saveItem(Item * item, uint16_t optionsFlag)
{ {
if (item && item->isValid()) if (item && item->isValid())
{ {
if (optionsFlag & SEND_COMMAND) item->setCmd(cmd.cmdCode);
if (optionsFlag & SEND_PARAMETERS) if (optionsFlag & FLAG_FLAGS)
switch (cmd.cmdCode)
{
case CMD_DISABLE:
item->setFlag(FLAG_DISABLED);
break;
case CMD_ENABLE:
item->clearFlag(FLAG_DISABLED);
item->clearFlag(FLAG_FREEZED);
break;
case CMD_FREEZE:
item->setFlag(FLAG_FREEZED);
break;
case CMD_UNFREEZE:
item->clearFlag(FLAG_FREEZED);
break;
}
if (optionsFlag & FLAG_COMMAND)
switch (cmd.cmdCode)
{
case CMD_DISABLE:
case CMD_ENABLE:
case CMD_FREEZE:
case CMD_UNFREEZE:
break;
default:
item->setCmd(cmd.cmdCode);
}
if (optionsFlag & FLAG_PARAMETERS)
switch (cmd.itemArgType) switch (cmd.itemArgType)
{ {
case ST_FLOAT: case ST_FLOAT:
@@ -1135,7 +1185,7 @@ return false;
int cmd = txt2cmd(verb->valuestring); int cmd = txt2cmd(verb->valuestring);
if (cmd>0) if (cmd>0)
{ {
free(verb->valuestring); freeString(verb->valuestring);
verb->valueint=cmd; verb->valueint=cmd;
verb->type=aJson_Int; verb->type=aJson_Int;
return verb->valueint; return verb->valueint;
@@ -1144,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)
{ {
@@ -1181,6 +1247,7 @@ return false;
i=i->next; i=i->next;
} }
} }
break;
case aJson_String: case aJson_String:
if (strcmp(cmdMapping->valuestring,"fan")==0) if (strcmp(cmdMapping->valuestring,"fan")==0)
switch (getCmd()) switch (getCmd())
@@ -1209,7 +1276,10 @@ return false;
} //switch } //switch
if (matchedCmd) return itemCmd().Int((uint32_t)matchedCmd->valueint); if (matchedCmd && matchedCmd->type != aJson_NULL)
{
return itemCmd().Int((uint32_t)matchedCmd->valueint);
}
aJsonObject *valMapping = aJson.getObjectItem(mappingData, "val"); aJsonObject *valMapping = aJson.getObjectItem(mappingData, "val");
if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMapping) == 4) if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMapping) == 4)
@@ -1220,6 +1290,7 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
aJson.getArrayItem(valMapping,0)->valueint,aJson.getArrayItem(valMapping,1)->valueint, aJson.getArrayItem(valMapping,0)->valueint,aJson.getArrayItem(valMapping,1)->valueint,
aJson.getArrayItem(valMapping,2)->valueint,aJson.getArrayItem(valMapping,3)->valueint)); aJson.getArrayItem(valMapping,2)->valueint,aJson.getArrayItem(valMapping,3)->valueint));
} }
else if (valMapping && valMapping->type == aJson_NULL) return itemCmd(ST_VOID,CMD_VOID);
return *this; return *this;
} }
@@ -1237,10 +1308,10 @@ if (isValue() && valMapping && valMapping->type == aJson_Array && aJson.getArray
case aJson_Array: case aJson_Array:
{ {
aJsonObject *i = cmdMapping->child; aJsonObject *i = cmdMapping->child;
//if first array element is not array - this is default mapping value //if first array element is not array - this is default mapping value, no reverse mapping, skipping
if (i && i->type==aJson_Int) if (i && i->type==aJson_Int)
{ {
matchedCmd = i; //matchedCmd = i;
i=i->next; i=i->next;
} }
@@ -1296,6 +1367,7 @@ if (valMapping && valMapping->type == aJson_Array && aJson.getArraySize(valMappi
int diff = ((b-a)/(d-c))/2; int diff = ((b-a)/(d-c))/2;
return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255)); return itemCmd().Int((uint32_t) constrain(map(getInt(),c,d,a,b)+diff,0,255));
} }
if (valMapping && valMapping->type == aJson_NULL) return itemCmd();
return *this; return *this;
} }
@@ -1306,17 +1378,17 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
if (!Buffer || !bufLen) return NULL; if (!Buffer || !bufLen) return NULL;
*Buffer=0; *Buffer=0;
char * argPtr=Buffer; char * argPtr=Buffer;
if (isCommand() && (sendFlags & SEND_COMMAND)) if (isCommand() && (sendFlags & FLAG_COMMAND))
{ {
int len; int len;
strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen); strncpy_P(Buffer, commands_P[cmd.cmdCode], bufLen);
if (isValue() && (sendFlags & SEND_PARAMETERS)) strncat(Buffer, " ", bufLen); if (isValue() && (sendFlags & FLAG_PARAMETERS)) strncat(Buffer, " ", bufLen);
len=strlen(Buffer); len=strlen(Buffer);
argPtr+=len; argPtr+=len;
bufLen-=len; bufLen-=len;
bufLen--; bufLen--;
} }
if (isValue() && (sendFlags & SEND_PARAMETERS)) if (isValue() && (sendFlags & FLAG_PARAMETERS))
{ {
//strncat(Buffer, " ", bufLen); //strncat(Buffer, " ", bufLen);
//bufLen--; //bufLen--;
@@ -1335,7 +1407,10 @@ char * itemCmd::toString(char * Buffer, int bufLen, int sendFlags, bool scale100
snprintf(argPtr, bufLen, "%ld", param.asInt32); snprintf(argPtr, bufLen, "%ld", param.asInt32);
break; break;
case ST_TENS: case ST_TENS:
snprintf(argPtr, bufLen, "%ld.%0"QUOTE(TENS_FRACT_LEN)"d", param.asInt32/TENS_BASE, abs(param.asInt32 % TENS_BASE)); if (param.asInt32<0)
snprintf(argPtr, bufLen, "-%ld.%0"QUOTE(TENS_FRACT_LEN)"d", abs(param.asInt32)/TENS_BASE, abs(param.asInt32 % TENS_BASE));
else
snprintf(argPtr, bufLen, "%ld.%0"QUOTE(TENS_FRACT_LEN)"d", param.asInt32/TENS_BASE, abs(param.asInt32 % TENS_BASE));
break; break;
case ST_HSV255: case ST_HSV255:
colorTemp=getColorTemp(); colorTemp=getColorTemp();

View File

@@ -26,11 +26,44 @@ typedef char cmdstr[9];
const cmdstr commands_P[] PROGMEM = const cmdstr commands_P[] PROGMEM =
{ {
"","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE", "","ON","OFF","REST","TOGGLE","HALT","XON","XOFF","INCREASE","DECREASE",
"HEAT","COOL","AUTO","FAN_ONLY","DRY","STOP","HIGH","MEDIUM","LOW","ENABLE","DISABLE", "ENABLE","DISABLE","UNFREEZE","FREEZE",
"TRUE","FALSE","RGB","HSV" "AUTO","FAN_ONLY",
"HIGH","MEDIUM","LOW",
"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
@@ -41,37 +74,50 @@ const cmdstr commands_P[] PROGMEM =
#define CMD_XOFF 7 /// OFF only if was previously turned on by CMD_XON #define CMD_XOFF 7 /// OFF only if was previously turned on by CMD_XON
#define CMD_UP 8 /// increase #define CMD_UP 8 /// increase
#define CMD_DN 9 /// decrease #define CMD_DN 9 /// decrease
#define CMD_HEAT 0xa /// Thermostat/AC set to HEATing mode
#define CMD_COOL 0xb /// Thermostat/AC set to COOLing mode #define CMD_ENABLE 0xa /// for PID regulator and XON/XOFF - chan limitation
#define CMD_AUTO 0xc /// Thermostat/AC set to Auto mode #define CMD_DISABLE 0xb /// for PID regulator
#define CMD_FAN 0xd /// AC set to Fan-only mode #define CMD_UNFREEZE 0xc ///
#define CMD_DRY 0xe /// AC set to Dry mode #define CMD_FREEZE 0xd ///
#define CMD_STOP 0xf /// stop dimming (for further use)
#define CMD_AUTO 0xe /// Thermostat/AC set to Auto mode
#define CMD_FAN 0xf /// AC set to Fan-only mode
#define CMD_HIGH 0x10 /// AC/Vent fan level HIGH #define CMD_HIGH 0x10 /// AC/Vent fan level HIGH
#define CMD_MED 0x11 /// AC/Vent fan level MEDIUM #define CMD_MED 0x11 /// AC/Vent fan level MEDIUM
#define CMD_LOW 0x12 /// AC/Vent fan level LOW #define CMD_LOW 0x12 /// AC/Vent fan level LOW
#define CMD_ENABLE 0x13 /// for PID regulator
#define CMD_DISABLE 0x14 /// for PID regulator #define CMD_HEAT 0x13 /// Thermostat/AC set to HEATing mode
#define CMD_TRUE 0x15 /// Aliase for ON #define CMD_COOL 0x14 /// Thermostat/AC set to COOLing mode
#define CMD_FALSE 0x16 /// Aliase for OFF #define CMD_DRY 0x15 /// AC set to Dry mode
#define CMD_STOP 0x16 /// stop dimming (for further use)
#define CMD_RGB 0x17 #define CMD_RGB 0x17
#define CMD_HSV 0x18 #define CMD_HSV 0x18
#define CMD_MASK 0xff #define CMD_MASK 0xffUL
#define FLAG_MASK 0xff00 #define FLAG_MASK 0x00ffff00UL
//#define STATE_MASK 0xff0000
#define CMD_VOID 0 #define CMD_VOID 0
#define CMD_UNKNOWN -1 #define CMD_UNKNOWN -1
#define CMD_JSON -2 #define CMD_JSON -2
#define SEND_IMMEDIATE 0x1 //FLAGS
#define SEND_COMMAND 0x100 #define FLAG_SEND_IMMEDIATE 0x1UL
#define SEND_PARAMETERS 0x200 #define FLAG_COMMAND 0x100UL
#define SEND_RETRY 0x400 #define FLAG_PARAMETERS 0x200UL
#define SEND_DEFFERED 0x800 #define FLAG_FLAGS 0x400UL
#define SEND_DELAYED 0x1000 #define FLAG_SEND_RETRY 0x800UL
#define ACTION_NEEDED 0x2000 #define FLAG_SEND_DEFFERED 0x1000UL
#define ACTION_IN_PROCESS 0x4000 #define FLAG_SEND_DELAYED 0x2000UL
#define FLAG_ACTION_NEEDED 0x4000UL
#define FLAG_ACTION_IN_PROCESS 0x8000UL
#define FLAG_DISABLED 0x10000UL
#define FLAG_FREEZED 0x20000UL
#define FLAG_HALTED 0x40000UL
#define FLAG_XON 0x80000UL
@@ -161,9 +207,9 @@ public:
itemCmd assignFrom(itemCmd from, short chanType=-1); itemCmd assignFrom(itemCmd from, short chanType=-1);
bool loadItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS); bool loadItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
bool loadItemDef(Item * item, uint16_t optionsFlag=SEND_PARAMETERS ); bool loadItemDef(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS );
bool saveItem(Item * item, uint16_t optionsFlag=SEND_PARAMETERS); bool saveItem(Item * item, uint16_t optionsFlag=FLAG_PARAMETERS);
itemCmd Int(int32_t i); itemCmd Int(int32_t i);
itemCmd Int(uint32_t i); itemCmd Int(uint32_t i);
@@ -209,7 +255,7 @@ public:
uint8_t getCmd(); uint8_t getCmd();
uint8_t getArgType(); uint8_t getArgType();
uint8_t getCmdParam(); uint8_t getCmdParam();
char * toString(char * Buffer, int bufLen, int sendFlags = SEND_COMMAND | SEND_PARAMETERS, bool scale100 = false); char * toString(char * Buffer, int bufLen, int sendFlags = FLAG_COMMAND | FLAG_PARAMETERS, bool scale100 = false);
bool isCommand(); bool isCommand();
bool isChannelCommand(); bool isChannelCommand();
@@ -226,4 +272,5 @@ public:
}; };
int replaceTypeToInt(aJsonObject* verb);
#pragma pack(pop) #pragma pack(pop)

View File

@@ -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>
@@ -39,13 +42,26 @@ e-mail anklimov@gmail.com
Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_BSD); Syslog udpSyslog(udpSyslogClient, SYSLOG_PROTO_BSD);
static char syslogDeviceHostname[16]; static char syslogDeviceHostname[16];
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog); #if defined(debugSerialPort) && !defined(NOSERIAL)
Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED); Streamlog debugSerial(&debugSerialPort,LOG_DEBUG,&udpSyslog);
Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog); Streamlog errorSerial(&debugSerialPort,LOG_ERROR,&udpSyslog,ledRED);
Streamlog infoSerial (&debugSerialPort,LOG_INFO,&udpSyslog);
#else
Streamlog debugSerial(NULL,LOG_DEBUG,&udpSyslog);
Streamlog errorSerial(NULL,LOG_ERROR,&udpSyslog,ledRED);
Streamlog infoSerial (NULL,LOG_INFO,&udpSyslog);
#endif
#else #else
Streamlog debugSerial(&debugSerialPort,LOG_DEBUG); #if defined(debugSerialPort) && !defined(NOSERIAL)
Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED); Streamlog debugSerial(&debugSerialPort,LOG_DEBUG);
Streamlog infoSerial (&debugSerialPort,LOG_INFO); Streamlog errorSerial(&debugSerialPort,LOG_ERROR, ledRED);
Streamlog infoSerial (&debugSerialPort,LOG_INFO);
#else
Streamlog debugSerial(NULL,LOG_DEBUG);
Streamlog errorSerial(NULL,LOG_ERROR, ledRED);
Streamlog infoSerial (NULL,LOG_INFO);
#endif
#endif #endif
flashStream sysConfStream; flashStream sysConfStream;
@@ -82,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
@@ -119,6 +139,7 @@ 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;
aJsonObject *pollingItem = NULL; aJsonObject *pollingItem = NULL;
@@ -126,6 +147,7 @@ bool owReady = false;
bool configOk = false; // At least once connected to MQTT bool configOk = false; // At least once connected to MQTT
bool configLoaded = false; bool configLoaded = false;
bool initializedListeners = false; bool initializedListeners = false;
uint8_t DHCP_failures = 0;
volatile int8_t ethernetIdleCount =0; volatile int8_t ethernetIdleCount =0;
volatile int8_t configLocked = 0; volatile int8_t configLocked = 0;
@@ -143,10 +165,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))
@@ -170,6 +194,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++;
@@ -179,19 +204,16 @@ 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();
yield(); yield();
} }
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);
@@ -247,9 +269,9 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
ArduinoOTA.sendHttpResponse(client,301,false); // Send only HTTP header, no close socket ArduinoOTA.sendHttpResponse(client,301,false); // Send only HTTP header, no close socket
client.println( client.println(
#ifdef CORS #ifdef REDIRECTION_URL
//Redirect to cloud PWA application //Redirect to cloud PWA application
String(F("Location: " CORS "/pwa")) String(F("Location: " REDIRECTION_URL))
#else #else
String(F("Location: /index.html")) String(F("Location: /index.html"))
#endif #endif
@@ -276,7 +298,7 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
if (!item.isValid() || !item.Ctrl((char*) body.c_str())) return 400; if (!item.isValid() || !item.Ctrl((char*) body.c_str())) return 400;
itemCmd ic; itemCmd ic;
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS); ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
char buf[32]; char buf[32];
response=ic.toString(buf, sizeof(buf)); response=ic.toString(buf, sizeof(buf));
return 200 | HTTP_TEXT_PLAIN; return 200 | HTTP_TEXT_PLAIN;
@@ -292,7 +314,7 @@ uint16_t httpHandler(Client& client, String request, uint8_t method, long conten
{if (item.isActive()) item.setCmd(CMD_ON); else item.setCmd(CMD_OFF);} {if (item.isActive()) item.setCmd(CMD_ON); else item.setCmd(CMD_OFF);}
itemCmd ic; itemCmd ic;
ic.loadItem(&item,SEND_COMMAND|SEND_PARAMETERS); ic.loadItem(&item,FLAG_COMMAND|FLAG_PARAMETERS);
char buf[32]; char buf[32];
response=ic.toString(buf, sizeof(buf)); response=ic.toString(buf, sizeof(buf));
@@ -400,12 +422,11 @@ if (lanStatus == RETAINING_COLLECTING)
{ {
if (mqttClient.isRetained()) if (mqttClient.isRetained())
{ {
pfxlen=inTopic(topic,T_BCST); //pfxlen=inTopic(topic,T_BCST); //Dont delete bcast topics (just skip on restore retaining)
if (!pfxlen) pfxlen = inTopic(topic,T_DEV); //if (!pfxlen) pfxlen = inTopic(topic,T_DEV);
if (!pfxlen) return; // Not command topic ever pfxlen = inTopic(topic,T_DEV);
//itemName=topic+pfxlen; if (!pfxlen) return; // Not command topic
if (strrchr(topic,'$')) return; if (strrchr(topic,'$')) return;
//if (itemName[0]=='$') return;// -6; //Skipping homie stuff
debugSerial<<F("CleanUp retained topic ")<<topic<<endl; debugSerial<<F("CleanUp retained topic ")<<topic<<endl;
mqttClient.deleteTopic(topic); mqttClient.deleteTopic(topic);
} }
@@ -585,6 +606,7 @@ lan_status lanLoop() {
if (isTimeOver(WiFiAwaitingTime,millis(),WIFI_TIMEOUT)) if (isTimeOver(WiFiAwaitingTime,millis(),WIFI_TIMEOUT))
{ {
errorSerial<<F("\nProblem with WiFi!"); errorSerial<<F("\nProblem with WiFi!");
WiFi.reconnect();
return lanStatus = DO_REINIT; return lanStatus = DO_REINIT;
} }
#else #else
@@ -664,6 +686,14 @@ lan_status lanLoop() {
setTopic(buf,sizeof(buf),T_OUT); setTopic(buf,sizeof(buf),T_OUT);
strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics strncat(buf, "+/+/#", sizeof(buf)); // Subscribing only on separated command/parameters topics
mqttClient.unsubscribe(buf); mqttClient.unsubscribe(buf);
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");
@@ -695,6 +725,19 @@ lan_status lanLoop() {
if (mqttClient.connected()) mqttClient.disconnect(); if (mqttClient.connected()) mqttClient.disconnect();
timerLanCheckTime = millis();// + 5000; timerLanCheckTime = millis();// + 5000;
lanStatus = RECONNECT; lanStatus = RECONNECT;
/*
#if defined(WIFI_ENABLE)
if (WiFi.status() != WL_CONNECTED)
{
infoSerial<<"Reconnecting WiFi"<<endl;
lanStatus = INITIAL_STATE;
WiFi.disconnect();
WiFi.reconnect();
}
#endif
*/
break; break;
case RECONNECT: case RECONNECT:
@@ -704,22 +747,19 @@ 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
debugSerial<<F("Restoring config from EEPROM")<<endl; if (isTimeOver(timerLanCheckTime,millis(),TIMEOUT_RELOAD))
if (loadConfigFromEEPROM()) lanStatus = IP_READY_CONFIG_LOADED_CONNECTING_TO_BROKER;//2; {
else { errorSerial<<F("30s EEPROM is not reloaded. Reboot");
//timerLanCheckTime = millis();// + 5000; softRebootFunc();
lanStatus = DO_REINIT;//-10; }
}
}
break; break;
case DO_NOTHING: case DO_NOTHING:
@@ -734,7 +774,8 @@ lan_status lanLoop() {
wdt_dis(); wdt_dis();
if (lanStatus >= HAVE_IP_ADDRESS) if (lanStatus >= HAVE_IP_ADDRESS)
{ {
int etherStatus = Ethernet.maintain(); int etherStatus = 0;
if (!DHCP_failures) etherStatus = Ethernet.maintain();
#ifndef Wiz5500 #ifndef Wiz5500
#define NO_LINK 5 #define NO_LINK 5
@@ -809,6 +850,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));
@@ -922,6 +973,7 @@ void ip_ready_config_loaded_connecting_to_broker() {
if (mqttClient.connected()) if (mqttClient.connected())
{ {
//mqttClient.setKeepAlive(10);
lanStatus = RETAINING_COLLECTING; lanStatus = RETAINING_COLLECTING;
return; return;
} }
@@ -999,10 +1051,10 @@ void ip_ready_config_loaded_connecting_to_broker() {
setTopic(buf,sizeof(buf),T_DEV); setTopic(buf,sizeof(buf),T_DEV);
strncat(buf, "#", sizeof(buf)); strncat(buf, "#", sizeof(buf));
debugSerialPort.println(buf); debugSerial.println(buf);
mqttClient.subscribe(buf); mqttClient.subscribe(buf);
onMQTTConnect(); //onMQTTConnect();
// if (_once) {DMXput(); _once=0;} // if (_once) {DMXput(); _once=0;}
lanStatus = RETAINING_COLLECTING;//4; lanStatus = RETAINING_COLLECTING;//4;
timerLanCheckTime = millis();// + 5000; timerLanCheckTime = millis();// + 5000;
@@ -1079,7 +1131,11 @@ if (WiFi.status() == WL_CONNECTED) {
IPAddress ip, dns, gw, mask; IPAddress ip, dns, gw, mask;
int res = 1; int res = 1;
infoSerial<<F("Starting lan")<<endl; infoSerial<<F("Starting lan")<<endl;
if (sysConf.getIP(ip)) { bool loadAddressRes = sysConf.getIP(ip);
if ( loadAddressRes &&
(!sysConf.getDHCPfallback() || (DHCP_failures >= DHCP_ATTEMPTS_FALLBACK))
)
{
infoSerial<<F("Loaded from flash IP:"); infoSerial<<F("Loaded from flash IP:");
printIPAddress(ip); printIPAddress(ip);
if (sysConf.getDNS(dns)) { if (sysConf.getDNS(dns)) {
@@ -1113,6 +1169,7 @@ if (WiFi.status() == WL_CONNECTED) {
if (res == 0) { if (res == 0) {
errorSerial<<F("Failed to configure Ethernet using DHCP. You can set ip manually!")<<F("'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n"); errorSerial<<F("Failed to configure Ethernet using DHCP. You can set ip manually!")<<F("'ip [ip[,dns[,gw[,subnet]]]]' - set static IP\n");
DHCP_failures++;
lanStatus = DO_REINIT;//-10; lanStatus = DO_REINIT;//-10;
//timerLanCheckTime = millis();// + DHCP_RETRY_INTERVAL; //timerLanCheckTime = millis();// + DHCP_RETRY_INTERVAL;
#ifdef RESET_PIN #ifdef RESET_PIN
@@ -1120,8 +1177,25 @@ if (WiFi.status() == WL_CONNECTED) {
#endif #endif
} else { } else {
infoSerial<<F("Got IP address:"); infoSerial<<F("Got IP address:");
printIPAddress(Ethernet.localIP()); ip=Ethernet.localIP();
printIPAddress(ip);
infoSerial<<endl; infoSerial<<endl;
sysConf.setIP(ip);
dns=Ethernet.dnsServerIP();
sysConf.setDNS(dns);
gw=Ethernet.gatewayIP();
sysConf.setGW(gw);
mask=Ethernet.subnetMask();
sysConf.setMask(mask);
sysConf.setDHCPfallback(true);
DHCP_failures = 0;
lanStatus = HAVE_IP_ADDRESS; lanStatus = HAVE_IP_ADDRESS;
} }
}//DHCP }//DHCP
@@ -1162,63 +1236,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)
{ {
@@ -1236,6 +1253,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;
} }
@@ -1265,6 +1286,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++;
@@ -1329,20 +1359,8 @@ setupSyslog();
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
@@ -1363,8 +1381,11 @@ setupSyslog();
switch (it.itemType) { switch (it.itemType) {
case CH_THERMO: case CH_THERMO:
if (cmd<1) it.setCmd(CMD_OFF); if (cmd<1) it.setCmd(CMD_OFF);
it.setFlag(SEND_COMMAND); it.setFlag(FLAG_COMMAND);
if (it.itemVal) it.setFlag(SEND_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(";");
@@ -1373,11 +1394,15 @@ setupSyslog();
{ {
int k; int k;
pinMode(pin, OUTPUT); pinMode(pin, OUTPUT);
if (inverse) if (isProtectedPin(pin)) digitalWrite (pin,LOW);
digitalWrite(pin, k = ((cmd == CMD_ON) ? LOW : HIGH));
else else
digitalWrite(pin, k = ((cmd == CMD_ON) ? HIGH : LOW)); {
debugSerial<<F("Pin:")<<pin<<F("=")<<k<<F(";"); if (inverse)
digitalWrite(pin, k = ((cmd == CMD_ON) ? LOW : HIGH));
else
digitalWrite(pin, k = ((cmd == CMD_ON) ? HIGH : LOW));
debugSerial<<F("Pin:")<<pin<<F("=")<<k<<F(";");
}
} }
break; break;
} //switch } //switch
@@ -1436,12 +1461,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;
} }
@@ -1449,6 +1476,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');
@@ -1457,17 +1486,20 @@ int loadConfigFromEEPROM()
#endif #endif
if (sysConfStream.peek() == '{') { if (sysConfStream.peek() == '{') {
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
@@ -1480,6 +1512,7 @@ int loadConfigFromEEPROM()
} }
sysConfStream.close(); sysConfStream.close();
infoSerial<<F("No stored config")<<endl; infoSerial<<F("No stored config")<<endl;
configLocked--;
return 0; return 0;
} }
@@ -1497,35 +1530,13 @@ if (arg_cnt>1)
#else #else
sysConfStream.open(FN_CONFIG_JSON,'w'); sysConfStream.open(FN_CONFIG_JSON,'w');
#endif #endif
#if defined(__SAM3X8E__)
long configBufSize = min(MAX_JSON_CONF_SIZE,freeRam()-1024);
debugSerial<<"Allocate "<<configBufSize<<" bytes for buffer"<<endl;
char* outBuf = (char*) malloc(configBufSize); /* XXX: Dynamic size. */
if (!outBuf)
{
sysConfStream.close();
errorSerial<<"Can't allocate RAM"<<endl;
return 500;
}
infoSerial<<F("Saving config to EEPROM..")<<endl;
aJsonStringStream stringStream(NULL, outBuf, configBufSize);
aJson.print(root, &stringStream);
int len = strlen(outBuf);
outBuf[len++]= EOFchar;
size_t res = sysConfStream.write((byte*) outBuf,len);
free (outBuf);
infoSerial<<res<< F(" bytes from ")<<len<<F(" are saved to EEPROM")<<endl;
#else
aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream); aJsonStream jsonEEPROMStream = aJsonStream(&sysConfStream);
infoSerial<<F("Saving config to EEPROM.."); infoSerial<<F("Saving config to EEPROM..");
aJson.print(root, &jsonEEPROMStream); aJson.print(root, &jsonEEPROMStream);
//sysConfStream.putEOF();
//sysConfStream.flush();
sysConfStream.close(); sysConfStream.close();
infoSerial<<F("Saved to EEPROM")<<endl; infoSerial<<F("Saved to EEPROM")<<endl;
#endif //#endif
sysConf.saveETAG(); sysConf.saveETAG();
return 200; return 200;
} }
@@ -1601,6 +1612,7 @@ int cmdFunctionIp(int arg_cnt, char **args)
printIPAddress(current_mask); */ printIPAddress(current_mask); */
//} //}
infoSerial<<F("Saved\n"); infoSerial<<F("Saved\n");
sysConf.setDHCPfallback(false);
return 200; return 200;
} }
@@ -1750,7 +1762,7 @@ if (!sysConf.getServer(configServer,sizeof(configServer)))
// FILE is the return STREAM type of the HTTPClient // FILE is the return STREAM type of the HTTPClient
configStream = hclient.getURI(URI,NULL,get_header); configStream = hclient.getURI(URI,NULL,get_header);
responseStatusCode = hclient.getLastReturnCode(); responseStatusCode = hclient.getLastReturnCode();
//debugSerial<<F("http retcode ")<<responseStatusCode<<endl;delay(100); debugSerial<<F("http retcode ")<<responseStatusCode<<endl;delay(100);
//wdt_en(); //wdt_en();
if (configStream != NULL) { if (configStream != NULL) {
@@ -1759,7 +1771,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
@@ -1831,7 +1843,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());
@@ -1904,7 +1916,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);
@@ -1993,13 +2005,163 @@ 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 (ESP32)
void WiFiEvent(WiFiEvent_t event, WiFiEventInfo_t info)
{
debugSerial.printf("[WiFi-event] event: %d\n", event);
switch (event) {
case SYSTEM_EVENT_WIFI_READY:
debugSerial.println("WiFi interface ready");
break;
case SYSTEM_EVENT_SCAN_DONE:
debugSerial.println("Completed scan for access points");
break;
case SYSTEM_EVENT_STA_START:
debugSerial.println("WiFi client started");
break;
case SYSTEM_EVENT_STA_STOP:
debugSerial.println("WiFi client stopped");
//changeState(MYSTATE_OFFLINE);
break;
case SYSTEM_EVENT_STA_CONNECTED:
debugSerial.println("Connected to access point");
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
debugSerial.println("Disconnected from WiFi access point");
WiFi.reconnect();
break;
case SYSTEM_EVENT_STA_AUTHMODE_CHANGE:
debugSerial.println("Authentication mode of access point has changed");
break;
case SYSTEM_EVENT_STA_GOT_IP:
debugSerial.print("Obtained IP address: ");
//Serial.println(WiFi.localIP());
//Serial.println("WiFi connected");
//Serial.print("IP address: ");
debugSerial.println(IPAddress(info.got_ip.ip_info.ip.addr));
//changeState(MYSTATE_ONLINE);
break;
case SYSTEM_EVENT_STA_LOST_IP:
debugSerial.println("Lost IP address and IP address is reset to 0");
//changeState(MYSTATE_OFFLINE);
break;
case SYSTEM_EVENT_STA_WPS_ER_SUCCESS:
debugSerial.println("WiFi Protected Setup (WPS): succeeded in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_FAILED:
debugSerial.println("WiFi Protected Setup (WPS): failed in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_TIMEOUT:
debugSerial.println("WiFi Protected Setup (WPS): timeout in enrollee mode");
break;
case SYSTEM_EVENT_STA_WPS_ER_PIN:
debugSerial.println("WiFi Protected Setup (WPS): pin code in enrollee mode");
break;
case SYSTEM_EVENT_AP_START:
debugSerial.println("WiFi access point started");
break;
case SYSTEM_EVENT_AP_STOP:
debugSerial.println("WiFi access point stopped");
break;
case SYSTEM_EVENT_AP_STACONNECTED:
debugSerial.println("Client connected");
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
debugSerial.println("Client disconnected");
break;
case SYSTEM_EVENT_AP_STAIPASSIGNED:
debugSerial.println("Assigned IP address to client");
break;
case SYSTEM_EVENT_AP_PROBEREQRECVED:
debugSerial.println("Received probe request");
break;
case SYSTEM_EVENT_GOT_IP6:
debugSerial.println("IPv6 is preferred");
break;
case SYSTEM_EVENT_ETH_START:
debugSerial.println("Ethernet started");
break;
case SYSTEM_EVENT_ETH_STOP:
debugSerial.println("Ethernet stopped");
break;
case SYSTEM_EVENT_ETH_CONNECTED:
debugSerial.println("Ethernet connected");
break;
case SYSTEM_EVENT_ETH_DISCONNECTED:
debugSerial.println("Ethernet disconnected");
break;
case SYSTEM_EVENT_ETH_GOT_IP:
debugSerial.println("Obtained IP address");
break;
default: break;
}
}
#endif
#endif
void setup_main() { void setup_main() {
#if (SERIAL_BAUD) #if (SERIAL_BAUD)
debugSerialPort.begin(SERIAL_BAUD); #if defined(debugSerialPort) && !defined(NOSERIAL)
debugSerialPort.begin(SERIAL_BAUD);
#endif
#else #else
#if not defined (__SAM3X8E__) #if not defined (__SAM3X8E__) && defined (debugSerialPort) && !defined(NOSERIAL)
debugSerialPort.begin(); debugSerialPort.begin();
#endif #endif
delay(1000); delay(1000);
@@ -2018,11 +2180,15 @@ void setup_main() {
if(SPIFFS.begin()) if(SPIFFS.begin())
#endif #endif
{ {
#if defined(debugSerialPort) && !defined(NOSERIAL)
debugSerialPort.println("SPIFFS Initialize....ok"); debugSerialPort.println("SPIFFS Initialize....ok");
#endif
} }
else else
{ {
#if defined(debugSerialPort) && !defined(NOSERIAL)
debugSerialPort.println("SPIFFS Initialization...failed"); debugSerialPort.println("SPIFFS Initialization...failed");
#endif
} }
#endif #endif
#else #else
@@ -2035,21 +2201,45 @@ 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)
{ {
debugSerialPort.println(F("No valid EEPROM data. Initializing.")); #if defined(debugSerialPort) && !defined(NOSERIAL)
sysConf.clear(); debugSerialPort.println(F("Initializing EEPROM."));
} #endif
cmdFunctionClearEEPROM(0, NULL);
//sysConf.clear();
}
else debugSerial << F("EEPROM signature ok")<<endl;
// scan_i2c_bus(); // scan_i2c_bus();
serialDebugLevel=sysConf.getSerialDebuglevel(); serialDebugLevel=sysConf.getSerialDebuglevel();
udpDebugLevel=sysConf.getUdpDebuglevel(); udpDebugLevel=sysConf.getUdpDebuglevel();
#if defined(__SAM3X8E__) #if defined(__SAM3X8E__)
memset(&UniqueID,0,sizeof(UniqueID)); memset(&UniqueID,0,sizeof(UniqueID));
#endif #endif
#if defined(M5STACK) #if defined(M5STACK)
// Initialize the M5Stack object // Initialize the M5Stack object
M5.begin(); M5.begin();
#endif #endif
@@ -2061,7 +2251,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
@@ -2072,7 +2264,7 @@ void setup_main() {
#else #else
pinMode(TXEnablePin, OUTPUT); pinMode(TXEnablePin, OUTPUT);
#endif #endif
modbusSerial.begin(MODBUS_SERIAL_BAUD,dimPar); modbusSerial.begin(MODBUS_SERIAL_BAUD,MODBUS_SERIAL_PARAM);
node.idle(&modbusIdle); node.idle(&modbusIdle);
node.preTransmission(preTransmission); node.preTransmission(preTransmission);
node.postTransmission(postTransmission); node.postTransmission(postTransmission);
@@ -2090,6 +2282,11 @@ void setup_main() {
//#ifdef _artnet //#ifdef _artnet
// artnetSetup(); // artnetSetup();
//#endif //#endif
#if defined(WIFI_ENABLE)
#if defined (ESP32)
WiFi.onEvent(WiFiEvent);
#endif
#endif
#if defined(WIFI_ENABLE) and not defined(WIFI_MANAGER_DISABLE) #if defined(WIFI_ENABLE) and not defined(WIFI_MANAGER_DISABLE)
// WiFiManager wifiManager; // WiFiManager wifiManager;
@@ -2110,8 +2307,8 @@ void setup_main() {
infoSerial<<F("Use W5500 pin: "); infoSerial<<F("Use W5500 pin: ");
infoSerial<<QUOTE(W5500_CS_PIN)<<endl; infoSerial<<QUOTE(W5500_CS_PIN)<<endl;
#endif #endif
loadConfigFromEEPROM(); loadConfigFromEEPROM();
} }
void printFirmwareVersionAndBuildOptions() { void printFirmwareVersionAndBuildOptions() {
@@ -2159,11 +2356,17 @@ infoSerial<<F("\nFirmware MAC Address " QUOTE(CUSTOM_FIRMWARE_MAC));
#endif #endif
#ifdef _modbus #ifdef _modbus
infoSerial<<F("\n(+)MODBUS " QUOTE(MODBUS_DIMMER_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_SERIAL_BAUD)); infoSerial<<F("\n(+)MODBUS " QUOTE(MODBUS_SERIAL_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_SERIAL_BAUD));
#else #else
infoSerial<<F("\n(-)MODBUS"); infoSerial<<F("\n(-)MODBUS");
#endif #endif
#ifdef IPMODBUS
infoSerial<<F("\n(+)IPMODBUS ");// QUOTE(MODBUS_TCP_PARAM) " at " QUOTE(modbusSerial) " speed:" QUOTE(MODBUS_TCP_BAUD));
#else
infoSerial<<F("\n(-)IPMODBUS");
#endif
#ifndef OWIRE_DISABLE #ifndef OWIRE_DISABLE
infoSerial<<F("\n(+)OWIRE"); infoSerial<<F("\n(+)OWIRE");
#ifdef USE_1W_PIN #ifdef USE_1W_PIN
@@ -2282,9 +2485,17 @@ infoSerial<<F("\n(-)MULTIVENT");
infoSerial<<F("\n(+)HUMIDIFIER"); infoSerial<<F("\n(+)HUMIDIFIER");
#endif #endif
#ifdef NOSERIAL
infoSerial<<F("\nNOSERIAL");
#endif
#ifdef ELEVATOR_ENABLE #ifdef ELEVATOR_ENABLE
infoSerial<<F("\n(+)ELEVATOR"); infoSerial<<F("\n(+)ELEVATOR");
#endif #endif
//#ifdef IPMODBUS
//infoSerial<<F("\n(+)IPMODBUS");
//#endif
infoSerial<<endl; infoSerial<<endl;
// WDT_Disable( WDT ) ; // WDT_Disable( WDT ) ;
@@ -2310,22 +2521,38 @@ void publishStat(){
uint32_t ut = millis()/1000UL; uint32_t ut = millis()/1000UL;
if (!mqttClient.connected() || ethernetIdleCount) return; if (!mqttClient.connected() || ethernetIdleCount) return;
setTopic(topic,sizeof(topic),T_DEV); setTopic(topic,sizeof(topic),T_DEV);
strncat_P(topic, stats_P, sizeof(topic)); strncat_P(topic, stats_P, sizeof(topic)-1);
strncat(topic, "/", sizeof(topic)); strncat(topic, "/", sizeof(topic));
strncat_P(topic, freeheap_P, sizeof(topic)); strncat_P(topic, freeheap_P, sizeof(topic)-1);
printUlongValueToStr(intbuf, fr); printUlongValueToStr(intbuf, fr);
mqttClient.publish(topic,intbuf,true); mqttClient.publish(topic,intbuf,true);
setTopic(topic,sizeof(topic),T_DEV); setTopic(topic,sizeof(topic),T_DEV);
strncat_P(topic, stats_P, sizeof(topic)); strncat_P(topic, stats_P, sizeof(topic)-1);
strncat(topic, "/", sizeof(topic)); strncat(topic, "/", sizeof(topic));
strncat_P(topic, uptime_P, sizeof(topic)); strncat_P(topic, uptime_P, sizeof(topic)-1);
printUlongValueToStr(intbuf, ut); printUlongValueToStr(intbuf, ut);
mqttClient.publish(topic,intbuf,true); mqttClient.publish(topic,intbuf,true);
setTopic(topic,sizeof(topic),T_DEV);
strncat_P(topic, state_P, sizeof(topic)-1);
strncpy_P(intbuf, ready_P, sizeof(intbuf)-1);
mqttClient.publish(topic,intbuf,true);
#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");
@@ -2375,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() {
@@ -2586,6 +2817,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--;
} }
@@ -2644,6 +2877,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)
@@ -2687,7 +2921,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;
@@ -2703,7 +2939,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

Some files were not shown because too many files have changed in this diff Show More