Compare commits

...
Author SHA1 Message Date
ESPEasy release bot 1c5f8af083 automaticly updated release notes for mega-20180321 2018-03-21 04:00:08 +01:00
TD-er e7a9ee7eee Merge branch 'v2.0' into mega 2018-03-20 23:28:59 +01:00
Unknown 3edfdbf5f7 [wifi] Setup with factory settings could not complete 2018-03-20 23:27:39 +01:00
Gijs NoorlanderandGitHub 27bac2ca00 Merge pull request #1140 from TD-er/bugfix/connect_to_wifi_during_setup
[wifi] Setup with factory settings could not complete
2018-03-20 23:25:57 +01:00
Unknown 373f74e9f8 [wifi] Setup with factory settings could not complete 2018-03-20 23:25:23 +01:00
ESPEasy release bot 1220c565c8 automaticly updated release notes for v2.0-20180320 2018-03-20 04:00:23 +01:00
ESPEasy release bot 1931fe9e53 automaticly updated release notes for mega-20180320 2018-03-20 04:00:10 +01:00
Unknown 0eab6293dc Merge branch 'v2.0' into mega 2018-03-20 00:30:02 +01:00
Unknown f0987dab41 [issue #1097] WiFi connect with deepsleep enabled trigger watchdog reset
Did not allow for enough time to do background tasks while waiting for wifi connect with DeepSleep enabled.
2018-03-20 00:29:24 +01:00
Gijs NoorlanderandGitHub 51bd52603f Merge pull request #1134 from TD-er/bugfix/deepsleep_mqtt
[issue #1097] WiFi connect with deepsleep enabled trigger watchdog reset
2018-03-20 00:27:58 +01:00
Unknown 47f1fa145a [issue #1097] WiFi connect with deepsleep enabled trigger watchdog reset
Did not allow for enough time to do background tasks while waiting for wifi connect with DeepSleep enabled.
2018-03-20 00:26:48 +01:00
Unknown 605055d95a Merge branch 'v2.0' into mega 2018-03-19 22:52:36 +01:00
Unknown af3e353181 Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"
This reverts commit 8ccbdcadf0.
2018-03-19 22:51:23 +01:00
es-kaandUnknown c711d6ea51 Fix wiring description for SN75176 transceiver 2018-03-19 22:50:31 +01:00
Gijs NoorlanderandGitHub 20c23a2935 Merge pull request #1133 from TD-er/bugfix/undo_espeasy_globals.h
Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"
2018-03-19 22:48:51 +01:00
Gijs Noorlander bbfe254232 Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"
This reverts commit 8ccbdcadf0.
2018-03-19 22:47:42 +01:00
Gijs NoorlanderandGitHub 882c888f6d Merge pull request #1132 from es-ka/mega
Fix wiring description for SN75176 transceiver
2018-03-19 22:37:04 +01:00
es-kaandGitHub 0a754f072c Fix wiring description for SN75176 transceiver 2018-03-19 20:00:41 +01:00
ESPEasy release bot 1f084c51cc automaticly updated release notes for v2.0-20180319 2018-03-19 04:00:24 +01:00
ESPEasy release bot 89df0932c5 automaticly updated release notes for mega-20180319 2018-03-19 04:00:11 +01:00
Unknown 429fd3e4d0 Merge branch 'v2.0' into mega 2018-03-19 01:06:32 +01:00
Gijs NoorlanderandGitHub 85e8d98da8 Merge pull request #1121 from TD-er/merge/fixes_20180318_to_v2.0
Merge/fixes 20180318 to v2.0
2018-03-19 01:01:42 +01:00
Unknown 6d52a7e03a [merge] MIssing #endif due to merging. 2018-03-19 00:51:05 +01:00
Gijs Noorlander fa513b52f9 Merge pull request #1118 from TD-er/bugfix/mqtt_publish_after_deep_sleep
[issue #1097] MQTT publish after deep sleep
2018-03-19 00:46:03 +01:00
Unknown f98401524f Merge pull request #1116 from TD-er/feature/allow_own_defaults
[issue #1007] Allow user specific data in separate file
2018-03-19 00:45:52 +01:00
Unknown 4090b4f23c Merge pull request #1113 from TD-er/feature/reduce_impact_wifi_disconnect
[Relaxed WiFi] Perform WiFi initialization in steps
2018-03-19 00:42:58 +01:00
Gijs Noorlander b89c00008d Merge pull request #1114 from TD-er/feature/wifi_details_json
[JSON] Add uint name (#1099) and WiFi information (PR #1113)
2018-03-19 00:39:43 +01:00
Gijs Noorlander d57a617138 Merge pull request #1112 from uzi18/fix-p073
Fix p073 - #1111
2018-03-19 00:39:32 +01:00
Gijs Noorlander cefe6b4b7c Changed so that running all tasks immediately with deep sleep enabled… (#1110)
Changed so that running all tasks immediately with deep sleep enabled only happens on first iteration after wake up
2018-03-19 00:38:30 +01:00
Gijs Noorlander 2432740b41 - add encoder write command #1086 (#1103)
- add encoder write command #1086
2018-03-19 00:35:09 +01:00
Gijs Noorlander 44a934651c Add download button for current rule set (#1102)
Add download button for current rule set
2018-03-19 00:34:52 +01:00
Gijs NoorlanderandGitHub 95fb0d6e6c Merge pull request #1118 from TD-er/bugfix/mqtt_publish_after_deep_sleep
[issue #1097] MQTT publish after deep sleep
2018-03-19 00:29:37 +01:00
Gijs NoorlanderandGitHub 8ccbdcadf0 Merge pull request #1116 from TD-er/feature/allow_own_defaults
[issue #1007] Allow user specific data in separate file
2018-03-19 00:29:08 +01:00
Unknown 433aa6910a [issue #1097] MQTT publish after deep sleep
The MQTTConnect was only called after a while. This is a problem for deepsleep.
So now the MQTT connect is done at the first loop when deep sleep is enabled.
2018-03-19 00:18:29 +01:00
Unknown 2ebc733b63 [issue #1007] Add other defines as suggested by @uzi18 2018-03-18 23:17:57 +01:00
Unknown 21bc1a7814 #ifndef instead of #ifdef 2018-03-18 22:55:30 +01:00
Unknown 53b8009df6 [issue #1007] Allow user specific data in separate file
File will be ignored by git and can be simply included using `-D USE_OWN_DEFAULTS` in the build
2018-03-18 22:46:15 +01:00
Gijs NoorlanderandGitHub 68a8e5982e Merge pull request #1113 from TD-er/feature/reduce_impact_wifi_disconnect
[Relaxed WiFi] Perform WiFi initialization in steps
2018-03-18 21:53:33 +01:00
Gijs NoorlanderandGitHub 08acfeac97 Merge pull request #1114 from TD-er/feature/wifi_details_json
[JSON] Add uint name (#1099) and WiFi information (PR #1113)
2018-03-18 21:52:24 +01:00
Unknown 999a561515 [JSON] Add uint name (#1099) and WiFi information (PR #1113)
As suggested by @Grovkillen on PR #1113.
2018-03-18 21:51:46 +01:00
Gijs NoorlanderandGitHub 3ee1a4ed2e Merge pull request #1112 from uzi18/fix-p073
Fix p073 - #1111
2018-03-18 21:23:11 +01:00
Gijs NoorlanderandGitHub 05801db47c Changed so that running all tasks immediately with deep sleep enabled… (#1110)
Changed so that running all tasks immediately with deep sleep enabled only happens on first iteration after wake up
2018-03-18 21:22:43 +01:00
Gijs NoorlanderandGitHub 7bec632f15 Merge pull request #1109 from s0170071/memtracker
changed memory tracker to uint64_t for the ESP32
2018-03-18 21:21:18 +01:00
Gijs NoorlanderandGitHub 3f8fe11b47 - add encoder write command #1086 (#1103)
- add encoder write command #1086
2018-03-18 21:17:13 +01:00
Gijs NoorlanderandGitHub 4b8f1e4c1b Add download button for current rule set (#1102)
Add download button for current rule set
2018-03-18 21:13:26 +01:00
Unknown 573fd0f320 [Travis error] Some #include test that wasn't meant to be included
... in the commit.
2018-03-18 21:08:22 +01:00
Unknown 4fa5203c5b [Relaxed WiFi] Perform WiFi initialization in steps
Doing WiFi initialization in multiple steps, will reduce boot time a lot.
For deepsleep the Setup is waiting for wifi initialization to complete, but for normal use the wifi connection is initiated during setup and checked on regular intervals to see if it is available.
The same for WiFi reconnect, which will hopefully not affect the performance of the ESP module during reconnects.

Also added a check + event when connected to another accesspoint with different BSSID (MAC address of accesspoint). Also the last used BSSID is used to reconnect to try to connect to the same device over and over, which may be useful with WiFi repeaters.
2018-03-18 20:54:27 +01:00
Bartlomiej Zimon 9c9617f6ed - initialize pointer in P073 2018-03-18 20:30:47 +01:00
Bartlomiej Zimon bbbf6c483f - fix P073 success setting in PLUGIN_WRITE callback 2018-03-18 20:30:18 +01:00
Bartlomiej Zimon 668909e7b3 - fix success setting 2018-03-18 20:16:37 +01:00
Unknown c642848ef2 [WiFi] Try to minimize effect of WiFi interruptions
And send event when connected to a different accesspoint.
Currently the impact on WiFi reconnects is enorm. The ESP stalls, won't react on events, etc.
2018-03-18 02:51:59 +01:00
s0170071 6eea35aa81 Keep uint. Just change the init value. 2018-03-17 22:58:09 +01:00
Panayotis Kouvarakis 738a48213c Changed so that running all tasks immediately with deep sleep enabled only happens on first iteration after wake up 2018-03-17 23:33:21 +02:00
s0170071 d1c093d109 changed memory tracker to uint64_t for the ESP32 2018-03-17 20:15:48 +01:00
Bartlomiej Zimon 00166a1aad - add encoder write #1086 2018-03-16 19:54:24 +01:00
Bartlomiej Zimon 589238324b Add download button for current rule set 2018-03-16 18:15:52 +01:00
ESPEasy release bot 6787bc8c0e automaticly updated release notes for v2.0-20180316 2018-03-16 04:00:23 +01:00
ESPEasy release bot 6845a03741 automaticly updated release notes for mega-20180316 2018-03-16 04:00:11 +01:00
Unknown 6a4284f189 Merge branch 'v2.0' into mega 2018-03-16 00:44:54 +01:00
Gijs NoorlanderandGitHub cf644b45b1 Merge pull request #1095 from TD-er/merge/PR_1092_1093_1094
Merge/pr 1092 1093 1094
2018-03-16 00:43:16 +01:00
Unknown e6fe1c63a9 [issue #951] Changed System#Initialized => System#Wake
Changed System#Initialized  => System#Wake
New event name makes more sense and Initialized may be used later to indicate all needed connections, etc. are ready.
2018-03-16 00:38:00 +01:00
Unknown df978036f0 [issue #993] variable in MQTT subscribe topic
As [noted](https://github.com/letscontrolit/ESPEasy/issues/993#issuecomment-373140135) by @kluszcyn
2018-03-16 00:37:54 +01:00
Unknown 7cb375833d [issue #1057] AM PM display issue
X:XX PM (for hours 1...9)
X:XX AM (for hours 1...9)
XX:XX PM (for hours 10...12)
XX:XX AM (for hours 10...12)

Added for H:MM (without seconds) notations:
- `%systm_hm%`
-`%systm_hm_am%`
2018-03-16 00:37:45 +01:00
Gijs NoorlanderandGitHub 41c57f1ef9 Merge pull request #1094 from TD-er/bugfix/System_Wake_event
[issue #951] Changed System#Initialized  => System#Wake
2018-03-16 00:35:24 +01:00
Unknown 808b40bdba [issue #951] Changed System#Initialized => System#Wake
Changed System#Initialized  => System#Wake
New event name makes more sense and Initialized may be used later to indicate all needed connections, etc. are ready.
2018-03-16 00:34:32 +01:00
Gijs NoorlanderandGitHub 58b20615da Merge pull request #1093 from TD-er/bugfix/993_parse_sysvars
[issue #993] variable in MQTT subscribe topic
2018-03-15 23:57:01 +01:00
Unknown 13026b1cc4 [issue #993] variable in MQTT subscribe topic
As [noted](https://github.com/letscontrolit/ESPEasy/issues/993#issuecomment-373140135) by @kluszcyn
2018-03-15 23:56:01 +01:00
Gijs NoorlanderandGitHub 7f3460e492 Merge pull request #1092 from TD-er/bugfix/am_pm_time
[issue #1057] AM PM display issue
2018-03-15 23:44:18 +01:00
Unknown a222391f81 [issue #1057] AM PM display issue
X:XX PM (for hours 1...9)
X:XX AM (for hours 1...9)
XX:XX PM (for hours 10...12)
XX:XX AM (for hours 10...12)

Added for H:MM (without seconds) notations:
- `%systm_hm%`
-`%systm_hm_am%`
2018-03-15 23:43:14 +01:00
Unknown a8165531d5 Merge branch 'v2.0' into mega 2018-03-15 23:06:07 +01:00
Gijs NoorlanderandGitHub 3218ea9839 Merge pull request #1091 from TD-er/merge/fixes_1073_1079_1081 into v2.0
Merge/fixes 1073 1079 1081 into v2.0
2018-03-15 23:05:06 +01:00
Gijs Noorlander eca8901fca Fixed multi instance problem on SHT3x #433 (#1081)
Fixed multi instance problem on SHT3x #433
2018-03-15 23:02:04 +01:00
Gijs Noorlander 6635eafe91 [issue #1066] Fix Webserver handle_control (#1079)
[issue #1066] Fix Webserver handle_control
2018-03-15 23:01:52 +01:00
Gijs Noorlander fe4d1f952f MCP3221 allow values for calibration (#1073)
MCP3221 allow values for calibration
2018-03-15 23:01:39 +01:00
Gijs NoorlanderandGitHub 1abd31b421 Fixed multi instance problem on SHT3x #433 (#1081)
Fixed multi instance problem on SHT3x #433
2018-03-15 23:00:05 +01:00
Gijs NoorlanderandGitHub 72fe49d905 [issue #1066] Fix Webserver handle_control (#1079)
[issue #1066] Fix Webserver handle_control
2018-03-15 22:58:38 +01:00
Gijs NoorlanderandGitHub 9dd9f3befa MCP3221 allow values for calibration (#1073)
MCP3221 allow values for calibration
2018-03-15 22:57:14 +01:00
Unknown 471d76dbe6 Merge branch 'v2.0' into mega 2018-03-15 22:55:31 +01:00
Gijs NoorlanderandGitHub 4475a225cc Merge pull request #1090 from TD-er/merge/split_globals_v2.0
Merge/split globals v2.0
2018-03-15 22:46:46 +01:00
Gijs NoorlanderandGitHub 8b047490c4 Merge pull request #1089 from TD-er/merge/split_globals_Mega
Merge/split globals mega
2018-03-15 22:46:28 +01:00
Unknown 455f77d0ed Merge branch 'v2.0' into mega 2018-03-15 22:42:50 +01:00
Unknown 836fc4a875 Merge remote-tracking branch 'uzi18/mega' into merge/split_globals 2018-03-15 22:29:30 +01:00
Unknown 2aece1c143 [v2.0 split globals] Base split on v2.0 version of ESPEasy.ino 2018-03-15 22:23:59 +01:00
Bartlomiej ZimonandUnknown 70df225e7e Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega
# Conflicts:
#	src/ESPEasy.ino
2018-03-15 22:05:36 +01:00
Unknown 19af52a3ef - move all structs from ESPEasy.ino into header file
- add some fix for headers
- add const to rtttl notes array
2018-03-15 22:05:22 +01:00
Gijs NoorlanderandGitHub 3d396575ff Merge pull request #1088 from TD-er/merge/rules_fix__and_globalsync_toV2.0
Merge/rules fix  and globalsync to v2.0
2018-03-15 21:52:41 +01:00
ESPEasy release bot 873f8474b5 automaticly updated release notes for mega-20180315 2018-03-15 04:00:08 +01:00
mvdbroandUnknown 826deaac89 Rules fix 2018-03-14 21:28:24 +01:00
mvdbroandUnknown cce621cff8 #893, part 2 receiving 2018-03-14 21:28:15 +01:00
mvdbroandUnknown 57eb38dbd0 Custom controller GUI option 2018-03-14 21:28:08 +01:00
mvdbroandUnknown fd2451bb07 #893 part1, send messages 2018-03-14 21:27:50 +01:00
mvdbro c94e5cb903 Rules fix 2018-03-14 19:26:29 +01:00
Bartlomiej Zimon 27699f7192 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega
# Conflicts:
#	src/ESPEasy.ino
2018-03-14 19:09:46 +01:00
Bartlomiej Zimon 2eff001b14 Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega 2018-03-14 18:54:24 +01:00
mvdbro bd499c7a94 #893, part 2 receiving 2018-03-14 13:11:16 +01:00
JK 4da1e4fbdd Fixed #433
Not tested!
2018-03-14 12:19:57 +01:00
mvdbro 1d14770ea7 Custom controller GUI option 2018-03-14 10:45:15 +01:00
ESPEasy release bot 8b7574d298 automaticly updated release notes for mega-20180314 2018-03-14 04:00:11 +01:00
Unknown 14d87d95f6 [issue #1066] Fix Webserver handle_control
There wasn't a proper start/end for the streaming webserver.
See discussion on issue #1066
2018-03-14 01:30:49 +01:00
mvdbro 5a15288d80 #893 part1, send messages 2018-03-13 16:36:58 +01:00
Bartlomiej Zimon 869dff12ce - move all structs from ESPEasy.ino into header file
- add some fix for headers
- add const to rtttl notes array
2018-03-13 15:53:42 +01:00
ESPEasy release bot cc0b3dac26 automaticly updated release notes for v2.0-20180313 2018-03-13 04:00:23 +01:00
ESPEasy release bot 4208048fc1 automaticly updated release notes for mega-20180313 2018-03-13 04:00:11 +01:00
Unknown 06a2f47812 Merge branch 'v2.0' into mega 2018-03-12 23:20:59 +01:00
Gijs NoorlanderandGitHub d3434eb4d2 Merge/fix rules trailing spaces (#1065) #1074
Merge/fix rules trailing spaces (#1065)
2018-03-12 23:18:22 +01:00
Bartlomiej ZimonandUnknown bd2665041f - remove double trimm() 2018-03-12 23:15:48 +01:00
Bartlomiej ZimonandUnknown 1fd429a029 - fix for #1065 2018-03-12 23:15:40 +01:00
sassod 7b3a71bcc9 12bit ADC values acceted up to 4095
MCP3221 is a 12bit ADC so accepted values should be up to 40195 not 1024
2018-03-12 19:56:42 +01:00
mvdbroandGitHub 18e612dea2 Merge pull request #1067 from uzi18/mega
- fix for #1065
2018-03-12 19:35:51 +01:00
mvdbro f99593ed62 ESP32 C010 fix 2018-03-12 19:34:40 +01:00
sassod 2f7e96fa5b Merge remote-tracking branch 'refs/remotes/origin/mega' into letscontrolit/mega 2018-03-12 18:51:00 +01:00
Bartlomiej Zimon 25b4392dd5 - remove double trimm() 2018-03-12 12:09:07 +01:00
Bartlomiej Zimon ad4130a547 - fix for #1065 2018-03-12 11:42:00 +01:00
ESPEasy release bot e4d4463eab automaticly updated release notes for v2.0-20180312 2018-03-12 04:00:19 +01:00
ESPEasy release bot 991384822f automaticly updated release notes for mega-20180312 2018-03-12 04:00:07 +01:00
Gijs NoorlanderandGitHub b29f56c6f4 Merge pull request #1063 from TD-er/merge/rule_engine_fix
Rule Engine minor fix and added dev debugging
2018-03-12 00:55:49 +01:00
Unknown 779514481d Rule Engine minor fix and added dev debugging 2018-03-12 00:52:30 +01:00
Unknown 82ed319e59 Merge branch 'v2.0' into mega 2018-03-12 00:46:31 +01:00
Gijs NoorlanderandGitHub 0a752dd26f Merge pull request #1062 from TD-er/merge/issue_1039
Merge/issue 1039
2018-03-12 00:44:02 +01:00
Gijs NoorlanderandGitHub 2e4af86a99 Merge pull request #1061 from TD-er/bugfix/chunking_webserver
[webserver] Improve chunked transfer
2018-03-12 00:42:30 +01:00
Unknown 8112e0e67a [webserver] Improve chunked transfer
Do chunked transfer using full buffer on all data sent to the streaming webserver.
2018-03-12 00:42:08 +01:00
Unknown 89a9f842fd [issue #1039 ] Change CSS to show topmost SSID on large screens
For screens with > 960 pixels width.
To show all accesspoints on AP selection.
2018-03-12 00:41:44 +01:00
Gijs NoorlanderandGitHub b4791d3421 Merge pull request #1060 from TD-er/bugfix/selection_accesspoints
[issue #1039 ] Change CSS to show topmost SSID on large screens
2018-03-12 00:40:13 +01:00
Unknown 885c5394a3 [webserver] Improve chunked transfer
Do chunked transfer using full buffer on all data sent to the streaming webserver.
2018-03-12 00:34:51 +01:00
Unknown e35304e4e7 [issue #1039 ] Change CSS to show topmost SSID on large screens
For screens with > 960 pixels width.
To show all accesspoints on AP selection.
2018-03-12 00:32:46 +01:00
mvdbro 6561d577d4 Rule Engine minor fix and added dev debugging 2018-03-11 10:40:54 +01:00
ESPEasy release bot 92932fddb2 automaticly updated release notes for v2.0-20180311 2018-03-11 04:00:19 +01:00
ESPEasy release bot 02d8834763 automaticly updated release notes for mega-20180311 2018-03-11 04:00:06 +01:00
Gijs NoorlanderandGitHub e82080dc52 Merge pull request #1053 from letscontrolit/v2.0
V2.0
2018-03-11 02:07:27 +01:00
Unknown 89581fd0fb [issue #1039] Topmost SSID are covered on mobile Browser
Added <span> tags with a class around the error, which allow the CSS to position the content below the header.
2018-03-11 01:59:51 +01:00
Gijs NoorlanderandGitHub cfbf972c1b [issue #1039] Topmost SSID are covered on mobile Browser (#1052)
[issue #1039] Topmost SSID are covered on mobile Browser
2018-03-11 01:58:13 +01:00
Unknown e25ea52edc [issue #1039] Topmost SSID are covered on mobile Browser
Added <span> tags with a class around the error, which allow the CSS to position the content below the header.
2018-03-11 01:57:24 +01:00
Unknown 3f84a961ad [DNS lookup] Controllers sometimes try to connect to 0.0.0.0
See issue #824
2018-03-11 01:38:50 +01:00
Gijs NoorlanderandGitHub 7d8e5e5175 [DNS lookup] Controllers sometimes try to connect to 0.0.0.0 (#1051)
[DNS lookup] Controllers sometimes try to connect to 0.0.0.0
2018-03-11 01:37:38 +01:00
Unknown 3d39dec686 [DNS lookup] Controllers sometimes try to connect to 0.0.0.0
See issue #824
2018-03-11 01:36:29 +01:00
Unknown ff656593ec Merge branch 'v2.0' into mega 2018-03-10 23:07:53 +01:00
Unknown 96bfaa27f5 [OLED] fix drawProgressBar
See this PR: https://github.com/ThingPulse/esp8266-oled-ssd1306/pull/178
2018-03-10 23:04:03 +01:00
Unknown bcca0514dd [deepsleep] Make sure the 'shortcut' of running all services when sleep enabled
As pointed out on [the forum by arion_p](https://www.letscontrolit.com/forum/viewtopic.php?p=25771#p25771)
2018-03-10 23:03:55 +01:00
Gijs NoorlanderandGitHub 90b4e3438d [OLED] fix drawProgressBar (#1048)
[OLED] fix drawProgressBar
2018-03-10 22:58:25 +01:00
Gijs NoorlanderandGitHub 139f8905d0 [deepsleep] Use the 'shortcut' of running all when sleep enabled (#1047)
[deepsleep] Use the 'shortcut' of running all when sleep enabled
2018-03-10 22:55:59 +01:00
Unknown 6c1806fae6 [OLED] fix drawProgressBar
See this PR: https://github.com/ThingPulse/esp8266-oled-ssd1306/pull/178
2018-03-10 22:53:18 +01:00
Unknown e6b581e7ff [deepsleep] Make sure the 'shortcut' of running all services when sleep enabled
As pointed out on [the forum by arion_p](https://www.letscontrolit.com/forum/viewtopic.php?p=25771#p25771)
2018-03-10 22:42:04 +01:00
Gijs NoorlanderandGitHub bb9f8fc809 Merge pull request #1046 from TD-er/merge/mega_to_v2.0
Merge/mega to v2.0
2018-03-10 22:03:14 +01:00
Unknown 4d9504bce0 [P073] Remove tm1637_bitDelay()
Not used anymore
2018-03-10 22:01:27 +01:00
Unknown ff3a769033 Update P07 Plugin
added suppor for other version of TM1637 modules (4dgt+colon, 4dgt+dots,6dgt+dots)
2018-03-10 22:01:20 +01:00
Unknown e3de56a7a8 [AM/PM] Am/Pm notation doesn't have '0' hours
11.59 a.m. => 12.00 p.m.
12.59 p.m. => 1.00 p.m.
11.59 p.m. => 12.00 a.m.
2018-03-10 22:01:04 +01:00
Gijs NoorlanderandGitHub 873d639461 Update P073 Plugin - support extra versions of TM1637 modules (@Papperone) (#1043)
Update P073 Plugin - support extra versions of TM1637 modules  (@Papperone)
2018-03-10 21:58:14 +01:00
Gijs NoorlanderandGitHub edb2a6d3f6 [AM/PM] Am/Pm notation doesn't have '0' hours (#1044)
[AM/PM] Am/Pm notation doesn't have '0' hours
2018-03-10 21:56:42 +01:00
Gijs NoorlanderandGitHub 2682b0bd2f [v2.0] Merge/rules process speed improvements (#1045)
[v2.0] Merge/rules process speed improvements
2018-03-10 21:55:25 +01:00
Unknown 5097157a09 Final ruleset speed-up
It's now down from 100 mSec to 19 mSec for 1 fully loaded non matching ruleset.
2018-03-10 21:41:13 +01:00
Unknown 02ea957894 Add read buffer to rule processing to speedup parsing
On a full ruleset (2k), a non matching event takes 100 mSec instead of 170 mSec.
2018-03-10 21:39:51 +01:00
mvdbroandUnknown c2b0d76595 Rule Engine, stop waisting time on non matching rules 2018-03-10 21:38:01 +01:00
Unknown 91b7cbe075 Improve flash read performance 2018-03-10 21:37:47 +01:00
Unknown bff60a2e27 [P073] Remove tm1637_bitDelay()
Not used anymore
2018-03-10 21:28:09 +01:00
Unknown 61831e5962 [AM/PM] Am/Pm notation doesn't have '0' hours
11.59 a.m. => 12.00 p.m.
12.59 p.m. => 1.00 p.m.
11.59 p.m. => 12.00 a.m.
2018-03-10 21:19:35 +01:00
Unknown d105b47d44 Update P07 Plugin
added suppor for other version of TM1637 modules (4dgt+colon, 4dgt+dots,6dgt+dots)
2018-03-10 18:38:33 +01:00
mvdbro 449568bcc4 Final ruleset speed-up
It's now down from 100 mSec to 19 mSec for 1 fully loaded non matching ruleset.
2018-03-10 16:53:02 +01:00
mvdbro 3144077103 Add read buffer to rule processing to speedup parsing
On a full ruleset (2k), a non matching event takes 100 mSec instead of 170 mSec.
2018-03-10 15:48:56 +01:00
mvdbro 8f056be0a8 Rule Engine, stop waisting time on non matching rules 2018-03-10 10:48:03 +01:00
mvdbro e9cdc5693d Improve flash read performance 2018-03-10 08:51:35 +01:00
ESPEasy release bot 64b38df187 automaticly updated release notes for v2.0-20180310 2018-03-10 04:00:20 +01:00
ESPEasy release bot 377c50ec36 automaticly updated release notes for mega-20180310 2018-03-10 04:00:07 +01:00
Gijs NoorlanderandGitHub 76f6dfdc59 Merge Mega -> v2.0: conversions & delay wifi init (#1037)
Merge Mega -> v2.0: conversions  & delay wifi init
2018-03-09 23:20:47 +01:00
Unknown 3a6f7acd15 [Conversions] Use more decimals in conversions and add AM/PM for time.
See comments on #1015
2018-03-09 23:19:19 +01:00
Unknown d65b126f84 Move plugin init before WiFi init
As suggested at PR #1032 by @M0ebiu5
2018-03-09 23:18:10 +01:00
Gijs NoorlanderandGitHub 90a2a799da [Conversions] Use more decimals in conversions and add AM/PM for time. (#1036)
[Conversions] Use more decimals in conversions and add AM/PM for time.
2018-03-09 23:15:48 +01:00
Unknown feb419b6ae [Conversions] Use more decimals in conversions and add AM/PM for time.
See comments on #1015
2018-03-09 23:13:03 +01:00
Gijs NoorlanderandGitHub e83d8468b0 Move plugin init before WiFi init (#1035)
Move plugin init before WiFi init
2018-03-09 22:18:35 +01:00
Unknown 6eabaaa62d Move plugin init before WiFi init
As suggested at PR #1032 by @M0ebiu5
2018-03-09 22:10:25 +01:00
ESPEasy release bot 8299e38b24 automaticly updated release notes for v2.0-20180309 2018-03-09 04:00:22 +01:00
sassod eee55a92d9 Merge remote-tracking branch 'refs/remotes/letscontrolit/mega' into mega 2017-10-11 07:21:45 +02:00
sassod 21398fbf8a Merge remote-tracking branch 'refs/remotes/letscontrolit/mega' into mega 2017-09-23 20:05:30 +02:00
24 changed files with 2568 additions and 1724 deletions
+237
View File
@@ -1,3 +1,240 @@
-------------------------------------------------
Changes in release mega-20180321 (since mega-20180320)
-------------------------------------------------
Release date: Wed Mar 21 04:00:08 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180320
Unknown (2):
[wifi] Setup with factory settings could not complete
[wifi] Setup with factory settings could not complete
-------------------------------------------------
Changes in release mega-20180320 (since mega-20180319)
-------------------------------------------------
Release date: Tue Mar 20 04:00:10 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180319
Gijs Noorlander (1):
Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"
Unknown (3):
Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"
[issue #1097] WiFi connect with deepsleep enabled trigger watchdog reset
[issue #1097] WiFi connect with deepsleep enabled trigger watchdog reset
es-ka (2):
Fix wiring description for SN75176 transceiver
Fix wiring description for SN75176 transceiver
-------------------------------------------------
Changes in release mega-20180319 (since mega-20180316)
-------------------------------------------------
Release date: Mon Mar 19 04:00:11 CET 2018
Bartlomiej Zimon (5):
Add download button for current rule set
- add encoder write #1086
- fix success setting
- fix P073 success setting in PLUGIN_WRITE callback
- initialize pointer in P073
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180316
Gijs Noorlander (6):
Add download button for current rule set (#1102)
- add encoder write command #1086 (#1103)
Changed so that running all tasks immediately with deep sleep enabled… (#1110)
Merge pull request #1112 from uzi18/fix-p073
Merge pull request #1114 from TD-er/feature/wifi_details_json
Merge pull request #1118 from TD-er/bugfix/mqtt_publish_after_deep_sleep
Panayotis Kouvarakis (1):
Changed so that running all tasks immediately with deep sleep enabled only happens on first iteration after wake up
Unknown (11):
[WiFi] Try to minimize effect of WiFi interruptions
[Relaxed WiFi] Perform WiFi initialization in steps
[Travis error] Some #include test that wasn't meant to be included
[JSON] Add uint name (#1099) and WiFi information (PR #1113)
[issue #1007] Allow user specific data in separate file
#ifndef instead of #ifdef
[issue #1007] Add other defines as suggested by @uzi18
[issue #1097] MQTT publish after deep sleep
Merge pull request #1113 from TD-er/feature/reduce_impact_wifi_disconnect
Merge pull request #1116 from TD-er/feature/allow_own_defaults
[merge] MIssing #endif due to merging.
s0170071 (2):
changed memory tracker to uint64_t for the ESP32
Keep uint. Just change the init value.
-------------------------------------------------
Changes in release mega-20180316 (since mega-20180315)
-------------------------------------------------
Release date: Fri Mar 16 04:00:11 CET 2018
Bartlomiej Zimon (3):
- move all structs from ESPEasy.ino into header file - add some fix for headers - add const to rtttl notes array
Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega
Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180313
Gijs Noorlander (3):
MCP3221 allow values for calibration (#1073)
[issue #1066] Fix Webserver handle_control (#1079)
Fixed multi instance problem on SHT3x #433 (#1081)
JK (1):
Fixed #433
Unknown (9):
[issue #1066] Fix Webserver handle_control
- move all structs from ESPEasy.ino into header file
[v2.0 split globals] Base split on v2.0 version of ESPEasy.ino
[issue #1057] AM PM display issue
[issue #993] variable in MQTT subscribe topic
[issue #951] Changed System#Initialized => System#Wake
[issue #1057] AM PM display issue
[issue #993] variable in MQTT subscribe topic
[issue #951] Changed System#Initialized => System#Wake
mvdbro (4):
#893 part1, send messages
Custom controller GUI option
#893, part 2 receiving
Rules fix
sassod (1):
12bit ADC values acceted up to 4095
-------------------------------------------------
Changes in release mega-20180315 (since mega-20180314)
-------------------------------------------------
Release date: Thu Mar 15 04:00:08 CET 2018
mvdbro (3):
Custom controller GUI option
#893, part 2 receiving
Rules fix
-------------------------------------------------
Changes in release mega-20180314 (since mega-20180313)
-------------------------------------------------
Release date: Wed Mar 14 04:00:11 CET 2018
mvdbro (1):
#893 part1, send messages
-------------------------------------------------
Changes in release mega-20180313 (since mega-20180312)
-------------------------------------------------
Release date: Tue Mar 13 04:00:11 CET 2018
Bartlomiej Zimon (4):
- fix for #1065
- remove double trimm()
- fix for #1065
- remove double trimm()
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180312
Unknown (1):
Rule Engine minor fix and added dev debugging
mvdbro (1):
ESP32 C010 fix
-------------------------------------------------
Changes in release mega-20180312 (since mega-20180311)
-------------------------------------------------
Release date: Mon Mar 12 04:00:07 CET 2018
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180311
Unknown (4):
[issue #1039 ] Change CSS to show topmost SSID on large screens
[webserver] Improve chunked transfer
[issue #1039 ] Change CSS to show topmost SSID on large screens
[webserver] Improve chunked transfer
mvdbro (1):
Rule Engine minor fix and added dev debugging
-------------------------------------------------
Changes in release mega-20180311 (since mega-20180310)
-------------------------------------------------
Release date: Sun Mar 11 04:00:06 CET 2018
ESPEasy release bot (2):
automaticly updated release notes for v2.0-20180309
automaticly updated release notes for v2.0-20180310
Unknown (19):
Move plugin init before WiFi init
[Conversions] Use more decimals in conversions and add AM/PM for time.
Update P07 Plugin
[AM/PM] Am/Pm notation doesn't have '0' hours
[P073] Remove tm1637_bitDelay()
Improve flash read performance
Add read buffer to rule processing to speedup parsing
Final ruleset speed-up
[AM/PM] Am/Pm notation doesn't have '0' hours
Update P07 Plugin
[P073] Remove tm1637_bitDelay()
[deepsleep] Make sure the 'shortcut' of running all services when sleep enabled
[OLED] fix drawProgressBar
[deepsleep] Make sure the 'shortcut' of running all services when sleep enabled
[OLED] fix drawProgressBar
[DNS lookup] Controllers sometimes try to connect to 0.0.0.0
[DNS lookup] Controllers sometimes try to connect to 0.0.0.0
[issue #1039] Topmost SSID are covered on mobile Browser
[issue #1039] Topmost SSID are covered on mobile Browser
mvdbro (5):
Improve flash read performance
Rule Engine, stop waisting time on non matching rules
Add read buffer to rule processing to speedup parsing
Final ruleset speed-up
Rule Engine, stop waisting time on non matching rules
-------------------------------------------------
Changes in release mega-20180310 (since mega-20180309)
-------------------------------------------------
Release date: Sat Mar 10 04:00:07 CET 2018
Unknown (2):
Move plugin init before WiFi init
[Conversions] Use more decimals in conversions and add AM/PM for time.
-------------------------------------------------
Changes in release mega-20180309 (since mega-20180308)
-------------------------------------------------
@@ -22,6 +22,10 @@ SOFTWARE.
See more at http://blog.squix.ch
*/
#ifndef DIALOG_PLAIN_FONT_H
#define DIALOG_PLAIN_FONT_H
// OLED library version >= 3.0.0
// Created by http://oleddisplay.squix.ch/ Consider a donation
// In case of problems make sure that you are using the font file with the correct version!
@@ -481,3 +485,6 @@ const char Dialog_plain_12[] PROGMEM = {
0x00,0x00,0xFC,0x7F,0x40,0x04,0x20,0x08,0x20,0x08,0x60,0x0C,0xC0,0x07, // 254
0x00,0x00,0xE0,0x40,0x04,0x47,0x00,0x38,0x84,0x07,0xE0 // 255
};
#endif
+1 -1
View File
@@ -349,7 +349,7 @@ void OLEDDisplay::drawProgressBar(uint16_t x, uint16_t y, uint16_t width, uint16
drawHorizontalLine(xRadius, y + height, width - doubleRadius + 1);
drawCircleQuads(x + width - radius, yRadius, radius, 0b00001001);
uint16_t maxProgressWidth = (width - doubleRadius - 1) * progress / 100;
uint16_t maxProgressWidth = (width - doubleRadius + 1) * progress / 100;
fillCircle(xRadius, yRadius, innerRadius);
fillRect(xRadius + 1, y + 2, maxProgressWidth, height - 3);
@@ -1,3 +1,6 @@
#ifndef OLED_SSD1306_SH1106_IMAGES_H
#define OLED_SSD1306_SH1106_IMAGES_H
#define espeasy_logo_width 36
#define espeasy_logo_height 36
const char espeasy_logo_bits[] PROGMEM= {
@@ -38,3 +41,5 @@ const char inactiveSymbole[] PROGMEM = {
B00000000,
B00000000
};
#endif
+2 -5
View File
@@ -8,9 +8,6 @@ void sendData(struct EventStruct *event)
if (Settings.UseRules)
createRuleEvents(event->TaskIndex);
if (Settings.GlobalSync && Settings.TaskDeviceGlobalSync[event->TaskIndex])
SendUDPTaskData(0, event->TaskIndex, event->TaskIndex);
if (Settings.UseValueLogger && Settings.InitSPI && Settings.Pin_sd_cs >= 0)
SendValueLogger(event->TaskIndex);
@@ -138,7 +135,7 @@ bool MQTTConnect(int controller_idx)
String LWTTopic = ControllerSettings.Subscribe;
LWTTopic.replace(F("/#"), F("/status"));
LWTTopic.replace(F("%sysname%"), Settings.Name);
parseSystemVariables(LWTTopic, false);
LWTTopic += F("/LWT"); // Extend the topic for status updates of connected/disconnected status.
boolean MQTTresult = false;
@@ -247,7 +244,7 @@ void MQTTStatus(String& status)
LoadControllerSettings(enabledMqttController, (byte*)&ControllerSettings, sizeof(ControllerSettings));
String pubname = ControllerSettings.Subscribe;
pubname.replace(F("/#"), F("/status"));
pubname.replace(F("%sysname%"), Settings.Name);
parseSystemVariables(pubname, false);
MQTTpublish(enabledMqttController, pubname.c_str(), status.c_str(),Settings.MQTTRetainFlag);
}
}
+13 -10
View File
@@ -58,19 +58,22 @@ String centimeterToImperialLength(float cm) {
}
String millimeterToImperialLength(float mm) {
int inches = mm / 25.4;
float inches = mm / 25.4;
int feet = inches /12;
inches = inches % 12;
char imperial[20];
if (feet == 0)
sprintf_P(imperial, PSTR("%d%c"), inches, '"');
else
sprintf_P(imperial, PSTR("%d%c%d%c"), feet, '\'', inches, '"');
return imperial;
inches = inches - (feet * 12);
String result;
result.reserve(10);
if (feet != 0) {
result += feet;
result += '\'';
}
result += toString(inches,1);
result += '"';
return result;
}
int minutesToDay(int minutes) {
return minutes / 1440;
float minutesToDay(int minutes) {
return minutes / 1440.0;
}
String minutesToDayHour(int minutes) {
File diff suppressed because it is too large Load Diff
+47 -1089
View File
File diff suppressed because it is too large Load Diff
+8
View File
@@ -1,3 +1,6 @@
#ifndef ESPEASY_TIMETYPES_H_
#define ESPEASY_TIMETYPES_H_
#include <stdint.h>
struct timeStruct {
@@ -59,3 +62,8 @@ struct TimeChangeRule {
void applyTimeZone(uint32_t curTime = 0);
void setTimeZone(const TimeChangeRule& dstStart, const TimeChangeRule& stdStart, uint32_t curTime = 0);
uint32_t calcTimeChangeForRule(const TimeChangeRule& r, int yr);
String getTimeString(char delimiter, bool show_seconds=true);
String getTimeString_ampm(char delimiter, bool show_seconds=true);
#endif /* ESPEASY_TIMETYPES_H_ */
+174 -135
View File
@@ -27,8 +27,6 @@ bool isDeepSleepEnabled()
{
if (!Settings.deepSleep)
return false;
if (!timeOutReached(timerAwakeFromDeepSleep + 1000 * Settings.deepSleep))
return false;
//cancel deep sleep loop by pulling the pin GPIO16(D0) to GND
//recommended wiring: 3-pin-header with 1=RST, 2=D0, 3=GND
@@ -42,6 +40,13 @@ bool isDeepSleepEnabled()
return true;
}
bool readyForSleep()
{
if (!isDeepSleepEnabled())
return false;
return timeOutReached(timerAwakeFromDeepSleep + 1000 * Settings.deepSleep);
}
void deepSleep(int delay)
{
@@ -973,22 +978,11 @@ String ClearInFile(char* fname, int index, int datasize)
String LoadFromFile(char* fname, int index, byte* memAddress, int datasize)
{
checkRAM(F("LoadFromFile"));
// addLog(LOG_LEVEL_INFO, String(F("FILE : Load size "))+datasize);
fs::File f = SPIFFS.open(fname, "r+");
SPIFFS_CHECK(f, fname);
// addLog(LOG_LEVEL_INFO, String(F("FILE : File size "))+f.size());
SPIFFS_CHECK(f.seek(index, fs::SeekSet), fname);
byte *pointerToByteToRead = memAddress;
for (int x = 0; x < datasize; x++)
{
int readres=f.read();
SPIFFS_CHECK(readres >=0, fname);
*pointerToByteToRead = readres;
pointerToByteToRead++;// next byte
}
SPIFFS_CHECK(f.read(memAddress,datasize), fname);
f.close();
return(String());
@@ -1896,6 +1890,29 @@ int Calculate(const char *input, float* result)
}
void checkRuleSets(){
for (byte x=0; x < RULESETS_MAX; x++){
#if defined(ESP8266)
String fileName = F("rules");
#endif
#if defined(ESP32)
String fileName = F("/rules");
#endif
fileName += x+1;
fileName += F(".txt");
if (SPIFFS.exists(fileName))
activeRuleSets[x] = true;
else
activeRuleSets[x] = false;
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
Serial.print(fileName);
Serial.print(" ");
Serial.println(activeRuleSets[x]);
}
}
}
/********************************************************************************************\
Rules processing
@@ -1910,7 +1927,7 @@ void rulesProcessing(String& event)
log += event;
addLog(LOG_LEVEL_INFO, log);
for (byte x = 1; x < RULESETS_MAX + 1; x++)
for (byte x = 0; x < RULESETS_MAX; x++)
{
#if defined(ESP8266)
String fileName = F("rules");
@@ -1918,9 +1935,9 @@ void rulesProcessing(String& event)
#if defined(ESP32)
String fileName = F("/rules");
#endif
fileName += x;
fileName += x+1;
fileName += F(".txt");
if (SPIFFS.exists(fileName))
if(activeRuleSets[x])
rulesProcessingFile(fileName, event);
}
@@ -1937,6 +1954,11 @@ void rulesProcessing(String& event)
String rulesProcessingFile(String fileName, String& event)
{
checkRAM(F("rulesProcessingFile"));
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
Serial.print(F("RuleDebug Processing:"));
Serial.println(fileName);
Serial.println(F(" flags CMI parse output:"));
}
fs::File f = SPIFFS.open(fileName, "r+");
SPIFFS_CHECK(f, fileName.c_str());
@@ -1950,11 +1972,9 @@ String rulesProcessingFile(String fileName, String& event)
log = F("EVENT: Error: Nesting level exceeded!");
addLog(LOG_LEVEL_ERROR, log);
nestingLevel--;
return(log);
return (log);
}
// int pos = 0;
String line = "";
boolean match = false;
boolean codeBlock = false;
@@ -1963,148 +1983,167 @@ String rulesProcessingFile(String fileName, String& event)
boolean condition = false;
boolean ifBranche = false;
byte buf[RULES_BUFFER_SIZE];
int len = 0;
while (f.available())
{
data = f.read();
len = f.read((byte*)buf, RULES_BUFFER_SIZE);
for (int x = 0; x < len; x++) {
data = buf[x];
SPIFFS_CHECK(data >= 0, fileName.c_str());
SPIFFS_CHECK(data >= 0, fileName.c_str());
if (data != 10)
line += char(data);
if (data != 10)
line += char(data);
if (data == 10) // if line complete, parse this rule
{
line.replace("\r", "");
if (line.substring(0, 2) != "//" && line.length() > 0)
if (data == 10) // if line complete, parse this rule
{
isCommand = true;
int comment = line.indexOf("//");
if (comment > 0)
line = line.substring(0, comment);
line = parseTemplate(line, line.length());
line.trim();
String lineOrg = line; // store original line for future use
line.toLowerCase(); // convert all to lower case to make checks easier
String eventTrigger = "";
String action = "";
if (!codeBlock) // do not check "on" rules if a block of actions is to be processed
line.replace("\r", "");
if (line.substring(0, 2) != "//" && line.length() > 0)
{
if (line.startsWith("on "))
isCommand = true;
int comment = line.indexOf("//");
if (comment > 0)
line = line.substring(0, comment);
if (match || !codeBlock) {
// only parse [xxx#yyy] if we have a matching ruleblock or need to eval the "on" (no codeBlock)
// This to avoid waisting CPU time...
line = parseTemplate(line, line.length());
}
line.trim();
String lineOrg = line; // store original line for future use
line.toLowerCase(); // convert all to lower case to make checks easier
String eventTrigger = "";
String action = "";
if (!codeBlock) // do not check "on" rules if a block of actions is to be processed
{
line = line.substring(3);
int split = line.indexOf(" do");
if (line.startsWith("on "))
{
line = line.substring(3);
int split = line.indexOf(" do");
if (split != -1)
{
eventTrigger = line.substring(0, split);
action = lineOrg.substring(split + 7);
action.trim();
}
if (eventTrigger == "*") // wildcard, always process
match = true;
else
match = ruleMatch(event, eventTrigger);
if (action.length() > 0) // single on/do/action line, no block
{
isCommand = true;
codeBlock = false;
}
else
{
isCommand = false;
codeBlock = true;
}
}
}
else
{
action = lineOrg;
}
String lcAction = action;
lcAction.toLowerCase();
if (lcAction == "endon") // Check if action block has ended, then we will wait for a new "on" rule
{
isCommand = false;
codeBlock = false;
match = false;
}
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
Serial.print(F("RuleDebug: "));
Serial.print(codeBlock);
Serial.print(match);
Serial.print(isCommand);
Serial.print(": ");
Serial.println(line);
}
if (match) // rule matched for one action or a block of actions
{
int split = lcAction.indexOf("if "); // check for optional "if" condition
if (split != -1)
{
eventTrigger = line.substring(0, split);
action = lineOrg.substring(split + 7);
action.trim();
}
if (eventTrigger == "*") // wildcard, always process
match = true;
else
match = ruleMatch(event, eventTrigger);
if (action.length() > 0) // single on/do/action line, no block
{
isCommand = true;
codeBlock = false;
}
else
{
conditional = true;
String check = lcAction.substring(split + 3);
condition = conditionMatchExtended(check);
ifBranche = true;
isCommand = false;
codeBlock = true;
}
}
}
else
{
action = lineOrg;
}
String lcAction = action;
lcAction.toLowerCase();
if (lcAction == "endon") // Check if action block has ended, then we will wait for a new "on" rule
{
isCommand = false;
codeBlock = false;
}
if (match) // rule matched for one action or a block of actions
{
int split = lcAction.indexOf("if "); // check for optional "if" condition
if (split != -1)
{
conditional = true;
String check = lcAction.substring(split + 3);
condition = conditionMatchExtended(check);
ifBranche = true;
isCommand = false;
}
if (lcAction == "else") // in case of an "else" block of actions, set ifBranche to false
{
ifBranche = false;
isCommand = false;
}
if (lcAction == "endif") // conditional block ends here
{
conditional = false;
isCommand = false;
}
// process the action if it's a command and unconditional, or conditional and the condition matches the if or else block.
if (isCommand && ((!conditional) || (conditional && (condition == ifBranche))))
{
if (event.charAt(0) == '!')
if (lcAction == "else") // in case of an "else" block of actions, set ifBranche to false
{
action.replace(F("%eventvalue%"), event); // substitute %eventvalue% with literal event string if starting with '!'
ifBranche = false;
isCommand = false;
}
else
if (lcAction == "endif") // conditional block ends here
{
int equalsPos = event.indexOf("=");
if (equalsPos > 0)
conditional = false;
isCommand = false;
}
// process the action if it's a command and unconditional, or conditional and the condition matches the if or else block.
if (isCommand && ((!conditional) || (conditional && (condition == ifBranche))))
{
if (event.charAt(0) == '!')
{
String tmpString = event.substring(equalsPos + 1);
action.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% in actions with the actual value from the event
action.replace(F("%eventvalue%"), event); // substitute %eventvalue% with literal event string if starting with '!'
}
}
log = F("ACT : ");
log += action;
addLog(LOG_LEVEL_INFO, log);
else
{
int equalsPos = event.indexOf("=");
if (equalsPos > 0)
{
String tmpString = event.substring(equalsPos + 1);
action.replace(F("%eventvalue%"), tmpString); // substitute %eventvalue% in actions with the actual value from the event
}
}
log = F("ACT : ");
log += action;
addLog(LOG_LEVEL_INFO, log);
struct EventStruct TempEvent;
parseCommandString(&TempEvent, action);
yield();
// Use a tmp string to call PLUGIN_WRITE, since PluginCall may inadvertenly alter the string.
String tmpAction(action);
if (!PluginCall(PLUGIN_WRITE, &TempEvent, tmpAction)) {
if (!tmpAction.equals(action)) {
String log = F("PLUGIN_WRITE altered the string: ");
log += action;
log += F(" to: ");
log += tmpAction;
addLog(LOG_LEVEL_ERROR, log);
struct EventStruct TempEvent;
parseCommandString(&TempEvent, action);
yield();
// Use a tmp string to call PLUGIN_WRITE, since PluginCall may inadvertenly alter the string.
String tmpAction(action);
if (!PluginCall(PLUGIN_WRITE, &TempEvent, tmpAction)) {
if (!tmpAction.equals(action)) {
String log = F("PLUGIN_WRITE altered the string: ");
log += action;
log += F(" to: ");
log += tmpAction;
addLog(LOG_LEVEL_ERROR, log);
}
ExecuteCommand(VALUE_SOURCE_SYSTEM, action.c_str());
}
ExecuteCommand(VALUE_SOURCE_SYSTEM, action.c_str());
yield();
}
yield();
}
}
}
line = "";
line = "";
}
}
//pos++;
}
nestingLevel--;
checkRAM(F("rulesProcessingFile2"));
return(String());
return (String());
}
@@ -2482,7 +2521,7 @@ class RamTracker{
writePtr=0;
for (int i = 0; i< TRACES; i++) {
traces[i]="";
tracesMemory[i]=0xffff; // init with best case memory values, so they get replaced if memory goes lower
tracesMemory[i]=0xffffffff; // init with best case memory values, so they get replaced if memory goes lower
}
for (int i = 0; i< TRACEENTRIES; i++) {
nextAction[i]="startup";
@@ -2591,7 +2630,7 @@ void play_rtttl(uint8_t _pin, const char *p )
#define OCTAVE_OFFSET 0
// FIXME: Absolutely no error checking in here
int notes[] = { 0,
const int notes[] = { 0,
262, 277, 294, 311, 330, 349, 370, 392, 415, 440, 466, 494,
523, 554, 587, 622, 659, 698, 740, 784, 831, 880, 932, 988,
1047, 1109, 1175, 1245, 1319, 1397, 1480, 1568, 1661, 1760, 1865, 1976,
+6 -167
View File
@@ -36,35 +36,6 @@ void syslog(const char *message)
}
/*********************************************************************************************\
Structs for UDP messaging
\*********************************************************************************************/
struct infoStruct
{
byte header = 255;
byte ID = 3;
byte sourcelUnit;
byte destUnit;
byte sourceTaskIndex;
byte destTaskIndex;
byte deviceNumber;
char taskName[26];
char ValueNames[VARS_PER_TASK][26];
};
struct dataStruct
{
byte header = 255;
byte ID = 5;
byte sourcelUnit;
byte destUnit;
byte sourceTaskIndex;
byte destTaskIndex;
float Values[VARS_PER_TASK];
};
//TODO: add sysinfoStruct
/*********************************************************************************************\
Check UDP messages (ESPEasy propiertary protocol)
\*********************************************************************************************/
@@ -108,22 +79,10 @@ void checkUDP()
}
else
{
if (packetBuffer[1] > 1 && packetBuffer[1] < 6)
{
String log = (F("UDP : Sensor msg "));
for (byte x = 1; x < 6; x++)
{
log += " ";
log += (int)packetBuffer[x];
}
addLog(LOG_LEVEL_DEBUG_MORE, log);
}
// binary data!
switch (packetBuffer[1])
{
//TODO: use a nice struct for it
case 1: // sysinfo message
{
byte mac[6];
@@ -160,70 +119,13 @@ void checkUDP()
break;
}
case 2: // sensor info pull request
{
SendUDPTaskInfo(packetBuffer[2], packetBuffer[5], packetBuffer[4]);
break;
}
case 3: // sensor info
{
if (Settings.GlobalSync)
{
struct infoStruct infoReply;
memcpy((byte*)&infoReply, (byte*)&packetBuffer, sizeof(infoStruct));
// to prevent flash wear out (bugs in communication?) we can only write to an empty task
// so it will write only once and has to be cleared manually through webgui
if (Settings.TaskDeviceNumber[infoReply.destTaskIndex] == 0)
{
Settings.TaskDeviceNumber[infoReply.destTaskIndex] = infoReply.deviceNumber;
Settings.TaskDeviceDataFeed[infoReply.destTaskIndex] = 1; // remote feed
for (byte x=0; x < CONTROLLER_MAX; x++)
Settings.TaskDeviceSendData[x][infoReply.destTaskIndex] = false;
strcpy(ExtraTaskSettings.TaskDeviceName, infoReply.taskName);
for (byte x = 0; x < VARS_PER_TASK; x++)
strcpy( ExtraTaskSettings.TaskDeviceValueNames[x], infoReply.ValueNames[x]);
SaveTaskSettings(infoReply.destTaskIndex);
SaveSettings();
}
}
break;
}
case 4: // sensor data pull request
{
SendUDPTaskData(packetBuffer[2], packetBuffer[5], packetBuffer[4]);
break;
}
case 5: // sensor data
{
if (Settings.GlobalSync)
{
struct dataStruct dataReply;
memcpy((byte*)&dataReply, (byte*)&packetBuffer, sizeof(dataStruct));
// only if this task has a remote feed, update values
if (Settings.TaskDeviceDataFeed[dataReply.destTaskIndex] != 0)
{
for (byte x = 0; x < VARS_PER_TASK; x++)
{
UserVar[dataReply.destTaskIndex * VARS_PER_TASK + x] = dataReply.Values[x];
}
if (Settings.UseRules)
createRuleEvents(dataReply.destTaskIndex);
}
}
break;
}
default:
{
struct EventStruct TempEvent;
TempEvent.Data = (byte*)packetBuffer;
TempEvent.Par1 = remoteIP[3];
PluginCall(PLUGIN_UDP_IN, &TempEvent, dummyString);
CPluginCall(CPLUGIN_UDP_IN, &TempEvent);
break;
}
}
@@ -236,73 +138,6 @@ void checkUDP()
}
/*********************************************************************************************\
Send task info using UDP message
\*********************************************************************************************/
void SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskIndex)
{
if (!WiFiConnected(100)) {
return;
}
struct infoStruct infoReply;
infoReply.sourcelUnit = Settings.Unit;
infoReply.sourceTaskIndex = sourceTaskIndex;
infoReply.destTaskIndex = destTaskIndex;
LoadTaskSettings(infoReply.sourceTaskIndex);
infoReply.deviceNumber = Settings.TaskDeviceNumber[infoReply.sourceTaskIndex];
strcpy(infoReply.taskName, ExtraTaskSettings.TaskDeviceName);
for (byte x = 0; x < VARS_PER_TASK; x++)
strcpy(infoReply.ValueNames[x], ExtraTaskSettings.TaskDeviceValueNames[x]);
byte firstUnit = 1;
byte lastUnit = UNIT_MAX - 1;
if (destUnit != 0)
{
firstUnit = destUnit;
lastUnit = destUnit;
}
for (byte x = firstUnit; x <= lastUnit; x++)
{
infoReply.destUnit = x;
sendUDP(x, (byte*)&infoReply, sizeof(infoStruct));
delay(10);
}
delay(50);
}
/*********************************************************************************************\
Send task data using UDP message
\*********************************************************************************************/
void SendUDPTaskData(byte destUnit, byte sourceTaskIndex, byte destTaskIndex)
{
if (!WiFiConnected(100)) {
return;
}
struct dataStruct dataReply;
dataReply.sourcelUnit = Settings.Unit;
dataReply.sourceTaskIndex = sourceTaskIndex;
dataReply.destTaskIndex = destTaskIndex;
for (byte x = 0; x < VARS_PER_TASK; x++)
dataReply.Values[x] = UserVar[dataReply.sourceTaskIndex * VARS_PER_TASK + x];
byte firstUnit = 1;
byte lastUnit = UNIT_MAX - 1;
if (destUnit != 0)
{
firstUnit = destUnit;
lastUnit = destUnit;
}
for (byte x = firstUnit; x <= lastUnit; x++)
{
dataReply.destUnit = x;
sendUDP(x, (byte*) &dataReply, sizeof(dataStruct));
delay(10);
}
delay(50);
}
/*********************************************************************************************\
Send event using UDP message
\*********************************************************************************************/
@@ -761,6 +596,11 @@ bool WiFiConnected(uint32_t timeout_ms) {
yield(); // Allow at least once time for backgroundtasks
min_delay = 10;
}
if (!wifiConnected) {
// Apparently something needs network, perform check to see if it is ready now.
if (tryConnectWiFi())
checkWifiJustConnected();
}
while (WiFi.status() != WL_CONNECTED) {
if (timeOutReached(timer)) {
return false;
@@ -798,4 +638,3 @@ bool hostReachable(const String& hostname) {
addLog(LOG_LEVEL_ERROR, log);
return false;
}
+7 -3
View File
@@ -285,10 +285,13 @@ void parseSystemVariables(String& s, boolean useURLencode)
#if defined(ESP8266)
SMART_REPL(F("%mac_int%"), String(ESP.getChipId())) // Last 24 bit of MAC address as integer, to be used in rules.
#endif
if (s.indexOf(F("%sys")) != -1) {
SMART_REPL(F("%sysload%"), String(100 - (100 * loopCounterLast / loopCounterMax)))
SMART_REPL(F("%systm_hm%"), getTimeString(':', false))
SMART_REPL(F("%systm_hm_am%"), getTimeString_ampm(':', false))
SMART_REPL(F("%systime%"), getTimeString(':'))
SMART_REPL(F("%systime_am%"), getTimeString_ampm(':'))
repl(F("%sysname%"), Settings.Name, s, useURLencode);
// valueString is being used by the macro.
@@ -306,6 +309,7 @@ void parseSystemVariables(String& s, boolean useURLencode)
#undef SMART_REPL_TIME
}
SMART_REPL(F("%lcltime%"), getDateTimeString('-',':',' '))
SMART_REPL(F("%lcltime_am%"), getDateTimeString_ampm('-',':',' '))
SMART_REPL(F("%uptime%"), String(wdcounter / 2))
repl(F("%tskname%"), ExtraTaskSettings.TaskDeviceName, s, useURLencode);
@@ -367,11 +371,11 @@ void parseStandardConversions(String& s, boolean useURLencode) {
// The marker may occur more than once per string, but with different parameters.
#define SMART_CONV(T,FUN) while (getConvertArgument((T), s, arg, startIndex, endIndex)) { repl(s.substring(startIndex, endIndex), (FUN), s, useURLencode); }
SMART_CONV(F("%c_w_dir%"), getBearing(arg))
SMART_CONV(F("%c_c2f%"), String(CelsiusToFahrenheit(arg)))
SMART_CONV(F("%c_c2f%"), toString(CelsiusToFahrenheit(arg), 1))
SMART_CONV(F("%c_ms2Bft%"), String(m_secToBeaufort(arg)))
SMART_CONV(F("%c_cm2imp%"), centimeterToImperialLength(arg))
SMART_CONV(F("%c_mm2imp%"), millimeterToImperialLength(arg))
SMART_CONV(F("%c_m2day%"), String(minutesToDay(arg)))
SMART_CONV(F("%c_m2day%"), toString(minutesToDay(arg), 2))
SMART_CONV(F("%c_m2dh%"), minutesToDayHour(arg))
SMART_CONV(F("%c_m2dhm%"), minutesToDayHourMinute(arg))
SMART_CONV(F("%c_s2dhms%"), secondsToDayHourMinuteSecond(arg))
+40 -7
View File
@@ -390,16 +390,40 @@ String getDateString()
// returns the current Time separated by the given delimiter
// time format example with ':' delimiter: 23:59:59 (HH:MM:SS)
String getTimeString(const timeStruct& ts, char delimiter)
String getTimeString(const timeStruct& ts, char delimiter, bool am_pm, bool show_seconds)
{
char TimeString[20]; //19 digits plus the null char
sprintf_P(TimeString, PSTR("%02d%c%02d%c%02d"), ts.Hour, delimiter, ts.Minute, delimiter, ts.Second);
if (am_pm) {
uint8_t hour(ts.Hour % 12);
if (hour == 0) { hour = 12; }
const char a_or_p = ts.Hour < 12 ? 'A' : 'P';
if (show_seconds) {
sprintf_P(TimeString, PSTR("%d%c%02d%c%02d %cM"),
hour, delimiter, ts.Minute, delimiter, ts.Second, a_or_p);
} else {
sprintf_P(TimeString, PSTR("%d%c%02d %cM"),
hour, delimiter, ts.Minute, a_or_p);
}
} else {
if (show_seconds) {
sprintf_P(TimeString, PSTR("%02d%c%02d%c%02d"),
ts.Hour, delimiter, ts.Minute, delimiter, ts.Second);
} else {
sprintf_P(TimeString, PSTR("%d%c%02d"),
ts.Hour, delimiter, ts.Minute);
}
}
return TimeString;
}
String getTimeString(char delimiter)
String getTimeString(char delimiter, bool show_seconds /*=true*/)
{
return getTimeString(tm, delimiter);
return getTimeString(tm, delimiter, false, show_seconds);
}
String getTimeString_ampm(char delimiter, bool show_seconds /*=true*/)
{
return getTimeString(tm, delimiter, true, show_seconds);
}
// returns the current Time without delimiter
@@ -409,20 +433,29 @@ String getTimeString()
return getTimeString('\0');
}
String getTimeString_ampm()
{
return getTimeString_ampm('\0');
}
// returns the current Date and Time separated by the given delimiter
// if called like this: getDateTimeString('\0', '\0', '\0');
// it will give back this: 20161231235959 (YYYYMMDDHHMMSS)
String getDateTimeString(const timeStruct& ts, char dateDelimiter, char timeDelimiter, char dateTimeDelimiter)
String getDateTimeString(const timeStruct& ts, char dateDelimiter, char timeDelimiter, char dateTimeDelimiter, bool am_pm)
{
String ret = getDateString(ts, dateDelimiter);
if (dateTimeDelimiter != '\0')
ret += dateTimeDelimiter;
ret += getTimeString(ts, timeDelimiter);
ret += getTimeString(ts, timeDelimiter, am_pm, true);
return ret;
}
String getDateTimeString(char dateDelimiter, char timeDelimiter, char dateTimeDelimiter) {
return getDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter);
return getDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter, false);
}
String getDateTimeString_ampm(char dateDelimiter, char timeDelimiter, char dateTimeDelimiter) {
return getDateTimeString(tm, dateDelimiter, timeDelimiter, dateTimeDelimiter, true);
}
/********************************************************************************************\
+2 -2
View File
@@ -97,7 +97,7 @@ void logTimeZoneInfo() {
if (m_dstLoc != 0) {
timeStruct tmp;
breakTime(m_dstLoc, tmp);
log += getDateTimeString(tmp, '-', ':', ' ');
log += getDateTimeString(tmp, '-', ':', ' ', false);
}
log += F(" offset: ");
log += m_dst.offset;
@@ -108,7 +108,7 @@ void logTimeZoneInfo() {
if (m_stdLoc != 0) {
timeStruct tmp;
breakTime(m_stdLoc, tmp);
log += getDateTimeString(tmp, '-', ':', ' ');
log += getDateTimeString(tmp, '-', ':', ' ', false);
}
log += F(" offset: ");
log += m_std.offset;
+163 -116
View File
@@ -6,6 +6,7 @@
#define ONLY_IP_RANGE_ALLOWED 2
#define _HEAD false
#define _TAIL true
#define CHUNKED_BUFFER_SIZE 400
void sendContentBlocking(String& data);
void sendHeaderBlocking(bool json);
@@ -21,58 +22,72 @@ public:
uint32_t finalRam;
uint32_t maxCoreUsage;
uint32_t maxServerUsage;
unsigned int BufferSize;
unsigned int sentBytes;
String buf;
StreamingBuffer(void) : lowMemorySkip(false),
initialRam(0), beforeTXRam(0), duringTXRam(0), finalRam(0), maxCoreUsage(0),
maxServerUsage(0), BufferSize(400), sentBytes(0)
maxServerUsage(0), sentBytes(0)
{
buf.reserve(BufferSize + 100);
buf.reserve(CHUNKED_BUFFER_SIZE + 50);
buf = "";
}
StreamingBuffer operator= (String& a) { this->buf=a; checkFull(); return *this; }
StreamingBuffer operator= (const String& a) { this->buf=a; checkFull(); return *this; }
StreamingBuffer operator+= (long unsigned int a) { this->buf+=String(a); checkFull(); return *this; }
StreamingBuffer operator+= (float a) { this->buf+=String(a); checkFull(); return *this; }
StreamingBuffer operator+= (int a) { this->buf+=String(a); checkFull(); return *this; }
StreamingBuffer operator+= (uint32_t a) { this->buf+=String(a); checkFull(); return *this; }
StreamingBuffer operator+=(const String& a) {
StreamingBuffer operator= (String& a) { flush(); return addString(a); }
StreamingBuffer operator= (const String& a) { flush(); return addString(a); }
StreamingBuffer operator+= (long unsigned int a) { return addString(String(a)); }
StreamingBuffer operator+= (float a) { return addString(String(a)); }
StreamingBuffer operator+= (int a) { return addString(String(a)); }
StreamingBuffer operator+= (uint32_t a) { return addString(String(a)); }
StreamingBuffer operator+=(const String& a) { return addString(a); }
StreamingBuffer addString(const String& a) {
if (lowMemorySkip) return *this;
const int length = a.length();
if (((this->buf.length() + length) > BufferSize) &&
(this->buf.length() > 100))
sendContentBlocking(this->buf);
int flush_step = CHUNKED_BUFFER_SIZE - this->buf.length();
if (flush_step < 1) flush_step = 0;
int pos = 0;
int flush_step = BufferSize - this->buf.length();
if (flush_step < 1) flush_step = 1;
const int length = a.length();
while (pos < length) {
const char c = a[pos];
this->buf += c;
++pos;
--flush_step;
if (flush_step == 0) {
sendContentBlocking(this->buf);
flush_step = BufferSize;
flush_step = CHUNKED_BUFFER_SIZE;
}
this->buf += a[pos];
++pos;
--flush_step;
}
checkFull();
return *this;
}
void flush() {
if (lowMemorySkip) {
this->buf = "";
} else {
sendContentBlocking(this->buf);
}
}
void checkFull(void) {
if (lowMemorySkip) this->buf = "";
if (this->buf.length() > BufferSize) {
if (this->buf.length() > CHUNKED_BUFFER_SIZE) {
trackTotalMem();
sendContentBlocking(this->buf);
}
}
void startStream() {
startStream(false);
}
void startJsonStream() {
startStream(true);
}
private:
void startStream(bool json) {
maxCoreUsage = maxServerUsage = 0;
beforeTXRam = ESP.getFreeHeap();
initialRam = ESP.getFreeHeap();
beforeTXRam = initialRam;
sentBytes = 0;
buf = "";
if (beforeTXRam < 3000) {
@@ -83,7 +98,7 @@ public:
#endif
return;
} else
sendHeaderBlocking();
sendHeaderBlocking(json);
}
void trackTotalMem() {
@@ -92,6 +107,8 @@ public:
maxServerUsage = initialRam - beforeTXRam;
}
public:
void trackCoreMem() {
duringTXRam = ESP.getFreeHeap();
if ((initialRam - duringTXRam) > maxCoreUsage)
@@ -118,17 +135,18 @@ public:
void sendContentBlocking(String& data) {
checkRAM(F("sendContentBlocking"));
uint32_t freeBeforeSend = ESP.getFreeHeap();
String log = String("sendcontent free: ") + freeBeforeSend + " chunk size:" + data.length();
const uint32_t length = data.length();
String log = String("sendcontent free: ") + freeBeforeSend + " chunk size:" + length;
addLog(LOG_LEVEL_DEBUG_DEV, log);
freeBeforeSend = ESP.getFreeHeap();
if (TXBuffer.beforeTXRam > freeBeforeSend)
TXBuffer.beforeTXRam = freeBeforeSend;
TXBuffer.duringTXRam = freeBeforeSend;
#if defined(ESP8266) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
String size = String(data.length(), HEX) + "\r\n";
String size = String(length, HEX) + "\r\n";
// do chunked transfer encoding ourselves (WebServer doesn't support it)
WebServer.sendContent(size);
if (data.length()) WebServer.sendContent(data);
if (length > 0) WebServer.sendContent(data);
WebServer.sendContent("\r\n");
#else // ESP8266 2.4.0rc2 and higher and the ESP32 webserver supports chunked http transfer
unsigned int timeout = 0;
@@ -147,18 +165,18 @@ void sendContentBlocking(String& data) {
}
#endif
TXBuffer.sentBytes += data.length();
TXBuffer.sentBytes += length;
data = "";
}
void sendHeaderBlocking() {
void sendHeaderBlocking(bool json) {
checkRAM(F("sendHeaderBlocking"));
#if defined(ESP8266) && defined(ARDUINO_ESP8266_RELEASE_2_3_0)
WebServer.setContentLength(CONTENT_LENGTH_UNKNOWN);
WebServer.sendHeader("Content-Type", "text/html", true);
WebServer.sendHeader("Accept-Ranges", "none");
WebServer.sendHeader("Cache-Control", "no-cache");
WebServer.sendHeader("Transfer-Encoding", "chunked");
WebServer.sendHeader(F("Content-Type"), json ? F("application/json") : F("text/html"), true);
WebServer.sendHeader(F("Accept-Ranges"), F("none"));
WebServer.sendHeader(F("Cache-Control"), F("no-cache"));
WebServer.sendHeader(F("Transfer-Encoding"), F("chunked"));
WebServer.send(200);
#else
unsigned int timeout = 0;
@@ -167,8 +185,8 @@ void sendHeaderBlocking() {
if (freeBeforeSend < 4000) timeout = 1000;
const uint32_t beginWait = millis();
WebServer.setContentLength(CONTENT_LENGTH_UNKNOWN);
WebServer.sendHeader("Content-Type", "text/html", true);
WebServer.sendHeader("Cache-Control", "no-cache");
WebServer.sendHeader(F("Content-Type"), json ? F("application/json") : F("text/html"), true);
WebServer.sendHeader(F("Cache-Control"), F("no-cache"));
WebServer.send(200);
// dont wait on 2.3.0. Memory returns just too slow.
while ((ESP.getFreeHeap() < freeBeforeSend) &&
@@ -349,7 +367,7 @@ void clearAccessBlock()
//********************************************************************************
// Web Interface init
//********************************************************************************
#include "core_version.h"
//#include "core_version.h"
#define HTML_SYMBOL_WARNING "&#9888;"
#if defined(ESP8266)
@@ -380,6 +398,7 @@ static const char pgDefaultCSS[] PROGMEM = {
".note {color: #444; font-style: italic; }"
//header with title and menu
".headermenu {position: fixed; top: 0; left: 0; right: 0; height: 90px; padding: 8px 12px; background-color: #F8F8F8; border-bottom: 1px solid #DDD; }"
".apheader {padding: 8px 12px; background-color: #F8F8F8;}"
".bodymenu {margin-top: 96px; }"
// menu
".menubar {position: inherit; top: 55px; }"
@@ -494,11 +513,13 @@ void getWebPageTemplateDefault(const String& tmplName, String& tmpl)
"{{css}}"
"</head>"
"<body>"
"<header class='headermenu'>"
"<header class='apheader'>"
"<h1>Welcome to ESP Easy Mega AP</h1>"
"</header>"
"<section>"
"<span class='message error'>"
"{{error}}"
"</span>"
"{{content}}"
"</section>"
"<footer>"
@@ -521,7 +542,9 @@ void getWebPageTemplateDefault(const String& tmplName, String& tmpl)
"<h1>ESP Easy Mega: {{name}}</h1>"
"</header>"
"<section>"
"<span class='message error'>"
"{{error}}"
"</span>"
"{{content}}"
"</section>"
"<footer>"
@@ -658,13 +681,15 @@ void getWebPageTemplateVar(const String& varName )
// Send CSS per chunk to avoid sending either too short or too large strings.
String tmpString;
tmpString.reserve(64);
uint16_t tmpStringPos = 0;
for (unsigned int i = 0; i < strlen(pgDefaultCSS); i++)
{
const char c = (char)pgm_read_byte(&pgDefaultCSS[i]);
tmpString += c;
if (c == ';' || c == '{') {
tmpString += (char)pgm_read_byte(&pgDefaultCSS[i]);
++tmpStringPos;
if (tmpStringPos == 64) {
TXBuffer += tmpString;
tmpString = "";
tmpStringPos = 0;
}
} // saves 1k of ram
if (tmpString.length() > 0) {
@@ -1186,6 +1211,7 @@ void handle_controllers() {
copyFormPassword(F("controllerpassword"), SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0]));
strncpy(ControllerSettings.Subscribe, controllersubscribe.c_str(), sizeof(ControllerSettings.Subscribe));
strncpy(ControllerSettings.Publish, controllerpublish.c_str(), sizeof(ControllerSettings.Publish));
CPlugin_ptr[ProtocolIndex](CPLUGIN_INIT, &TempEvent, dummyString);
}
}
addHtmlError( TXBuffer.buf, SaveControllerSettings(controllerindex, (byte*)&ControllerSettings, sizeof(ControllerSettings)));
@@ -1264,57 +1290,61 @@ void handle_controllers() {
options[0] = F("Use IP address");
options[1] = F("Use Hostname");
addFormSelector(TXBuffer.buf, F("Locate Controller"), F("usedns"), 2, options, NULL, NULL, choice, true);
if (ControllerSettings.UseDNS)
{
addFormTextBox(TXBuffer.buf, F("Controller Hostname"), F("controllerhostname"), ControllerSettings.HostName, sizeof(ControllerSettings.HostName)-1);
}
else
{
addFormIPBox(TXBuffer.buf, F("Controller IP"), F("controllerip"), ControllerSettings.IP);
}
addFormNumericBox(TXBuffer.buf, F("Controller Port"), F("controllerport"), ControllerSettings.Port, 1, 65535);
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[controllerindex]);
if (Protocol[ProtocolIndex].usesAccount)
{
String protoDisplayName;
if (!getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_USER, protoDisplayName)) {
protoDisplayName = F("Controller User");
if (!Protocol[ProtocolIndex].Custom){
addFormSelector(TXBuffer.buf, F("Locate Controller"), F("usedns"), 2, options, NULL, NULL, choice, true);
if (ControllerSettings.UseDNS)
{
addFormTextBox(TXBuffer.buf, F("Controller Hostname"), F("controllerhostname"), ControllerSettings.HostName, sizeof(ControllerSettings.HostName)-1);
}
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controlleruser"), SecuritySettings.ControllerUser[controllerindex], sizeof(SecuritySettings.ControllerUser[0])-1);
}
if (Protocol[ProtocolIndex].usesPassword)
{
String protoDisplayName;
if (getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_PASS, protoDisplayName)) {
// It is not a regular password, thus use normal text field.
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controllerpassword"), SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0])-1);
} else {
addFormPasswordBox(TXBuffer.buf, F("Controller Password"), F("controllerpassword"), SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0])-1);
else
{
addFormIPBox(TXBuffer.buf, F("Controller IP"), F("controllerip"), ControllerSettings.IP);
}
addFormNumericBox(TXBuffer.buf, F("Controller Port"), F("controllerport"), ControllerSettings.Port, 1, 65535);
if (Protocol[ProtocolIndex].usesAccount)
{
String protoDisplayName;
if (!getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_USER, protoDisplayName)) {
protoDisplayName = F("Controller User");
}
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controlleruser"), SecuritySettings.ControllerUser[controllerindex], sizeof(SecuritySettings.ControllerUser[0])-1);
}
if (Protocol[ProtocolIndex].usesPassword)
{
String protoDisplayName;
if (getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_PASS, protoDisplayName)) {
// It is not a regular password, thus use normal text field.
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controllerpassword"), SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0])-1);
} else {
addFormPasswordBox(TXBuffer.buf, F("Controller Password"), F("controllerpassword"), SecuritySettings.ControllerPassword[controllerindex], sizeof(SecuritySettings.ControllerPassword[0])-1);
}
}
if (Protocol[ProtocolIndex].usesTemplate || Protocol[ProtocolIndex].usesMQTT)
{
String protoDisplayName;
if (!getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_SUBSCRIBE, protoDisplayName)) {
protoDisplayName = F("Controller Subscribe");
}
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controllersubscribe"), ControllerSettings.Subscribe, sizeof(ControllerSettings.Subscribe)-1);
}
if (Protocol[ProtocolIndex].usesTemplate || Protocol[ProtocolIndex].usesMQTT)
{
String protoDisplayName;
if (!getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_PUBLISH, protoDisplayName)) {
protoDisplayName = F("Controller Publish");
}
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controllerpublish"), ControllerSettings.Publish, sizeof(ControllerSettings.Publish)-1);
}
}
if (Protocol[ProtocolIndex].usesTemplate || Protocol[ProtocolIndex].usesMQTT)
{
String protoDisplayName;
if (!getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_SUBSCRIBE, protoDisplayName)) {
protoDisplayName = F("Controller Subscribe");
}
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controllersubscribe"), ControllerSettings.Subscribe, sizeof(ControllerSettings.Subscribe)-1);
}
if (Protocol[ProtocolIndex].usesTemplate || Protocol[ProtocolIndex].usesMQTT)
{
String protoDisplayName;
if (!getControllerProtocolDisplayName(ProtocolIndex, CONTROLLER_PUBLISH, protoDisplayName)) {
protoDisplayName = F("Controller Publish");
}
addFormTextBox(TXBuffer.buf, protoDisplayName, F("controllerpublish"), ControllerSettings.Publish, sizeof(ControllerSettings.Publish)-1);
}
addFormCheckBox(TXBuffer.buf, F("Enabled"), F("controllerenabled"), Settings.ControllerEnabled[controllerindex]);
TempEvent.ControllerIndex = controllerindex;
@@ -1825,18 +1855,6 @@ void handle_devices() {
if (Device[DeviceIndex].InverseLogicOption)
Settings.TaskDevicePin1Inversed[taskIndex] = (WebServer.arg(F("TDPI")) == F("on"));
if (Settings.GlobalSync)
{
if (Device[DeviceIndex].GlobalSyncOption)
Settings.TaskDeviceGlobalSync[taskIndex] = (WebServer.arg(F("TDGS")) == F("on"));
// Send task info if set global
if (Settings.TaskDeviceGlobalSync[taskIndex])
{
SendUDPTaskInfo(0, taskIndex, taskIndex);
}
}
for (byte varNr = 0; varNr < Device[DeviceIndex].ValueCount; varNr++)
{
@@ -1864,6 +1882,18 @@ void handle_devices() {
//allow the plugin to save plugin-specific form settings.
PluginCall(PLUGIN_WEBFORM_SAVE, &TempEvent, dummyString);
// notify controllers: CPLUGIN_TASK_CHANGE_NOTIFICATION
for (byte x=0; x < CONTROLLER_MAX; x++)
{
TempEvent.ControllerIndex = x;
if (Settings.TaskDeviceSendData[TempEvent.ControllerIndex][TempEvent.TaskIndex] &&
Settings.ControllerEnabled[TempEvent.ControllerIndex] && Settings.Protocol[TempEvent.ControllerIndex])
{
TempEvent.ProtocolIndex = getProtocolIndex(Settings.Protocol[TempEvent.ControllerIndex]);
CPlugin_ptr[TempEvent.ProtocolIndex](CPLUGIN_TASK_CHANGE_NOTIFICATION, &TempEvent, dummyString);
}
}
}
addHtmlError( SaveTaskSettings(taskIndex));
@@ -2062,11 +2092,6 @@ void handle_devices() {
addFormCheckBox(TXBuffer.buf, F("Enabled"), F("TDE"), Settings.TaskDeviceEnabled[taskIndex]); //="taskdeviceenabled"
if (Settings.GlobalSync && Device[DeviceIndex].GlobalSyncOption && Settings.TaskDeviceDataFeed[taskIndex] == 0 && Settings.UDPPort != 0)
{
addFormCheckBox(TXBuffer.buf, F("Global Sync"), F("TDGS"), Settings.TaskDeviceGlobalSync[taskIndex]); //="taskdeviceglobalsync"
}
// section: Sensor / Actuator
if (!Device[DeviceIndex].Custom && Settings.TaskDeviceDataFeed[taskIndex] == 0 &&
((Device[DeviceIndex].Ports != 0) || (Device[DeviceIndex].PullUpOption) || (Device[DeviceIndex].InverseLogicOption) || (Device[DeviceIndex].Type >= DEVICE_TYPE_SINGLE && Device[DeviceIndex].Type <= DEVICE_TYPE_TRIPLE)) )
@@ -3417,8 +3442,7 @@ void handle_control() {
checkRAM(F("handle_control"));
if (!clientIPallowed()) return;
//TXBuffer.startStream(true); // true= json
// sendHeadandTail(F("TmplStd"),_HEAD);
// sendHeadandTail(F("TmplStd"),_HEAD);
String webrequest = WebServer.arg(F("cmd"));
// in case of event, store to buffer and return...
@@ -3437,18 +3461,18 @@ void handle_control() {
printToWeb = true;
printWebString = "";
if (printToWebJSON)
TXBuffer.startJsonStream();
else
TXBuffer.startStream();
if (PluginCall(PLUGIN_WRITE, &TempEvent, webrequest));
else if (remoteConfig(&TempEvent, webrequest));
else
TXBuffer += F("Unknown or restricted command!");
TXBuffer += printWebString;
if (printToWebJSON)
WebServer.send(200, "application/json");
else
WebServer.send(200, "text/html");
TXBuffer += printWebString;
TXBuffer.endStream();
printWebString = "";
printToWeb = false;
@@ -3475,10 +3499,34 @@ void handle_json()
reply += F(",\n");
reply += to_json_object_value(F("Unit"), String(Settings.Unit));
reply += F(",\n");
reply += to_json_object_value(F("Name"), String(Settings.Name));
reply += F(",\n");
reply += to_json_object_value(F("Uptime"), String(wdcounter / 2));
reply += F(",\n");
reply += to_json_object_value(F("Free RAM"), String(ESP.getFreeHeap()));
reply += F("\n},\n");
reply += F("\"WiFi\":{\n");
reply += to_json_object_value(F("Hostname"), WiFi.hostname());
reply += F(",\n");
reply += to_json_object_value(F("IP"), WiFi.localIP().toString());
reply += F(",\n");
reply += to_json_object_value(F("Subnet Mask"), WiFi.subnetMask().toString());
reply += F(",\n");
reply += to_json_object_value(F("Gateway IP"), WiFi.gatewayIP().toString());
reply += F(",\n");
reply += to_json_object_value(F("MAC address"), WiFi.macAddress());
reply += F(",\n");
reply += to_json_object_value(F("DNS 1"), WiFi.dnsIP(0).toString());
reply += F(",\n");
reply += to_json_object_value(F("DNS 2"), WiFi.dnsIP(1).toString());
reply += F(",\n");
reply += to_json_object_value(F("SSID"), WiFi.SSID());
reply += F(",\n");
reply += to_json_object_value(F("BSSID"), WiFi.BSSIDstr());
reply += F(",\n");
reply += to_json_object_value(F("RSSI"), String(WiFi.RSSI()));
reply += F("\n},\n");
}
byte taskNr = tasknr.toInt();
@@ -3572,7 +3620,6 @@ void handle_advanced() {
String usessdp = WebServer.arg(F("usessdp"));
String edit = WebServer.arg(F("edit"));
String wireclockstretchlimit = WebServer.arg(F("wireclockstretchlimit"));
String globalsync = WebServer.arg(F("globalsync"));
String userules = WebServer.arg(F("userules"));
String cft = WebServer.arg(F("cft"));
String MQTTRetainFlag = WebServer.arg(F("mqttretainflag"));
@@ -3606,7 +3653,6 @@ void handle_advanced() {
Settings.UseSSDP = (usessdp == "on");
Settings.WireClockStretchLimit = wireclockstretchlimit.toInt();
Settings.UseRules = (userules == "on");
Settings.GlobalSync = (globalsync == "on");
Settings.ConnectionFailuresThreshold = cft.toInt();
Settings.MQTTRetainFlag = (MQTTRetainFlag == "on");
Settings.ArduinoOTAEnable = (ArduinoOTAEnable == "on");
@@ -3662,9 +3708,8 @@ void handle_advanced() {
addFormNumericBox(TXBuffer.buf, F("Baud Rate"), F("baudrate"), Settings.BaudRate, 0, 1000000);
addFormSubHeader(TXBuffer.buf, F("Inter-ESPEasy Network (experimental)"));
addFormSubHeader(TXBuffer.buf, F("Inter-ESPEasy Network"));
addFormCheckBox( TXBuffer.buf, F("Global Sync"), F("globalsync"), Settings.GlobalSync);
addFormNumericBox(TXBuffer.buf, F("UDP port"), F("udpport"), Settings.UDPPort, 0, 65535);
@@ -4143,7 +4188,7 @@ void handle_filelist() {
if (fdelete.length() > 0)
{
SPIFFS.remove(fdelete);
// flashCount();
checkRuleSets();
}
@@ -4617,6 +4662,7 @@ void handle_rules() {
TXBuffer += F("<TR><TD>Edit: ");
addSelector(TXBuffer.buf, F("set"), RULESETS_MAX, options, optionValues, NULL, choice, true);
addButton(TXBuffer.buf, fileName, F("Download to file"));
addHelpButton(TXBuffer.buf, F("Tutorial_Rules"));
// load form data from flash
@@ -4656,6 +4702,7 @@ void handle_rules() {
sendHeadandTail(F("TmplStd"),true);
TXBuffer.endStream();
checkRuleSets();
}
+248 -107
View File
@@ -80,10 +80,9 @@ void WifiAPMode(boolean state)
//********************************************************************************
// Configure network and connect to Wifi SSID and SSID2
// Set Wifi config
//********************************************************************************
boolean WifiConnect(byte connectAttempts)
{
void prepareWiFi() {
String log = "";
char hostname[40];
strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname));
@@ -106,131 +105,266 @@ boolean WifiConnect(byte connectAttempts)
const IPAddress dns = Settings.DNS;
WiFi.config(ip, gw, subnet, dns);
}
}
//try to connect to one of the access points
if (WifiConnectSSID(SecuritySettings.WifiSSID, SecuritySettings.WifiKey, connectAttempts) ||
WifiConnectSSID(SecuritySettings.WifiSSID2, SecuritySettings.WifiKey2, connectAttempts))
{
// fix octet?
if (Settings.IP_Octet != 0 && Settings.IP_Octet != 255)
{
IPAddress ip = WiFi.localIP();
IPAddress gw = WiFi.gatewayIP();
IPAddress subnet = WiFi.subnetMask();
ip[3] = Settings.IP_Octet;
log = F("IP : Fixed IP octet:");
log += ip;
addLog(LOG_LEVEL_INFO, log);
WiFi.config(ip, gw, subnet);
}
#ifdef FEATURE_MDNS
String log = F("WIFI : ");
if (MDNS.begin(WifiGetHostname().c_str(), WiFi.localIP())) {
log += F("mDNS started, with name: ");
log += WifiGetHostname();
log += F(".local");
//********************************************************************************
// Configure network and connect to Wifi SSID and SSID2
//********************************************************************************
boolean WifiConnect(byte connectAttempts)
{
prepareWiFi();
if (anyValidWifiSettings()) {
//try to connect to one of the access points
bool connected = WifiConnectAndWait(connectAttempts);
if (!connected) {
if (selectNextWiFiSettings()) {
connected = WifiConnectAndWait(connectAttempts);
}
else{
log += F("mDNS failed");
}
addLog(LOG_LEVEL_INFO, log);
#endif
if (Settings.UseRules)
{
String event = F("WiFi#Connected");
rulesProcessing(event);
}
return(true);
if (connected) {
return(true);
}
}
addLog(LOG_LEVEL_ERROR, F("WIFI : Could not connect to AP!"));
//everything failed, activate AP mode (will deactivate automatically after a while if its connected again)
WifiAPMode(true);
return(false);
}
//********************************************************************************
// Start connect to WiFi and check later to see if connected.
//********************************************************************************
void WiFiConnectRelaxed() {
prepareWiFi();
wifiConnected = false;
wifi_connect_attempt = 0;
if (anyValidWifiSettings()) {
tryConnectWiFi();
return;
}
addLog(LOG_LEVEL_ERROR, F("WIFI : Could not connect to AP, no valid WiFi settings!"));
//everything failed, activate AP mode (will deactivate automatically after a while if its connected again)
WifiAPMode(true);
}
//********************************************************************************
// Manage WiFi credentials
//********************************************************************************
const char* getLastWiFiSettingsSSID() {
return lastWiFiSettings == 0 ? SecuritySettings.WifiSSID : SecuritySettings.WifiSSID2;
}
const char* getLastWiFiSettingsPassphrase() {
return lastWiFiSettings == 0 ? SecuritySettings.WifiKey : SecuritySettings.WifiKey2;
}
bool anyValidWifiSettings() {
if (wifiSettingsValid(SecuritySettings.WifiSSID, SecuritySettings.WifiKey))
return true;
if (wifiSettingsValid(SecuritySettings.WifiSSID2, SecuritySettings.WifiKey2))
return true;
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid WiFi settings!"));
return false;
}
bool selectNextWiFiSettings() {
lastWiFiSettings = (lastWiFiSettings + 1) % 2;
if (!wifiSettingsValid(getLastWiFiSettingsSSID(), getLastWiFiSettingsPassphrase())) {
// other settings are not correct, switch back.
lastWiFiSettings = (lastWiFiSettings + 1) % 2;
return false; // Nothing changed.
}
return true;
}
bool wifiSettingsValid(const char* ssid, const char* pass) {
if (ssid[0] == 0 || (strcasecmp(ssid, "ssid") == 0)) {
return false;
}
if (pass[0] == 0) return false;
return true;
}
bool wifiConnectTimeoutReached() {
if (wifi_connect_attempt == 0) return true;
// wait until it connects + add some device specific random offset to prevent
// all nodes overloading the accesspoint when turning on at the same time.
const unsigned int randomOffset_in_sec = wifi_connect_attempt == 1 ? 0 : 1000 * ((ESP.getChipId() & 0xF));
return timeOutReached(wifi_connect_timer + 7000 + randomOffset_in_sec);
}
//********************************************************************************
// Simply start the WiFi connection sequence
//********************************************************************************
bool tryConnectWiFi() {
if (wifiSetup && !wifiSetupConnect)
return false;
if (WiFi.status() == WL_CONNECTED)
return(true); //already connected, need to disconnect first
if (!wifiConnectTimeoutReached())
return true; // timeout not reached yet, thus no need to retry again.
if (wifi_connect_attempt != 0 && ((wifi_connect_attempt % 3) == 0)) {
// Change to other wifi settings.
if (selectNextWiFiSettings())
WiFi.disconnect();
}
if (wifi_connect_attempt > 6) {
//everything failed, activate AP mode (will deactivate automatically after a while if its connected again)
WifiAPMode(true);
}
const char* ssid = getLastWiFiSettingsSSID();
const char* passphrase = getLastWiFiSettingsPassphrase();
String log = F("WIFI : Connecting ");
log += ssid;
log += F(" attempt #");
log += wifi_connect_attempt;
addLog(LOG_LEVEL_INFO, log);
wifi_connect_timer = millis();
switch (wifi_connect_attempt) {
case 0:
if (lastBSSID[0] == 0)
WiFi.begin(ssid, passphrase);
else
WiFi.begin(ssid, passphrase, 0, &lastBSSID[0]);
break;
default:
WiFi.begin(ssid, passphrase);
}
++wifi_connect_attempt;
switch (WiFi.status()) {
case WL_NO_SSID_AVAIL: {
log = F("WIFI : No SSID found matching: ");
log += ssid;
addLog(LOG_LEVEL_INFO, log);
return false;
}
case WL_CONNECT_FAILED: {
log = F("WIFI : Connection failed to: ");
log += ssid;
addLog(LOG_LEVEL_INFO, log);
return false;
}
case WL_CONNECTED:
checkWifiJustConnected();
break;
default:
break;
}
return true; // Sent
}
//********************************************************************************
// Connect to Wifi specific SSID
//********************************************************************************
boolean WifiConnectSSID(char WifiSSID[], char WifiKey[], byte connectAttempts)
boolean WifiConnectAndWait(byte connectAttempts)
{
String log;
//already connected, need to disconnect first
if (WiFi.status() == WL_CONNECTED)
return(true);
//no ssid specified
if ((WifiSSID[0] == 0) || (strcasecmp(WifiSSID, "ssid") == 0))
return(false);
for (byte tryConnect = 1; tryConnect <= connectAttempts; tryConnect++)
wifiConnected = false;
wifi_connect_attempt = 0;
for (byte tryConnect = 0; tryConnect < connectAttempts; tryConnect++)
{
log = F("WIFI : Connecting ");
log += WifiSSID;
log += F(" attempt #");
log += tryConnect;
addLog(LOG_LEVEL_INFO, log);
if (tryConnect == 1)
WiFi.begin(WifiSSID, WifiKey);
else
WiFi.begin();
//wait until it connects
for (byte x = 0; x < 200; x++)
{
if (!WiFiConnected(50))
{
statusLED(false);
// No delay needed, since the WiFi check has a delay
}
else
break;
}
if (WiFi.status() == WL_CONNECTED)
{
if (Settings.UseNTP) {
initTime();
}
log = F("WIFI : Connected! IP: ");
log += formatIP(WiFi.localIP());
log += F(" (");
log += WifiGetHostname();
log += F(")");
addLog(LOG_LEVEL_INFO, log);
statusLED(true);
return(true);
}
else
{
// log = F("WIFI : Disconnecting!");
// addLog(LOG_LEVEL_INFO, log);
#if defined(ESP8266)
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
#endif
for (byte x = 0; x < 20; x++)
{
statusLED(true);
if (tryConnectWiFi()) {
do {
if (checkWifiJustConnected())
return true;
delay(50);
}
} while (!wifiConnectTimeoutReached());
}
// log = F("WIFI : Disconnecting!");
// addLog(LOG_LEVEL_INFO, log);
#if defined(ESP8266)
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
#endif
for (byte x = 0; x < 20; x++)
{
statusLED(true);
delay(50);
}
}
return false;
}
bool checkWifiJustConnected() {
if (wifiConnected) return true;
if (WiFi.status() != WL_CONNECTED) {
statusLED(false);
delay(1);
return false;
}
wifiConnected = true;
String log = F("WIFI : WiFi connect attempt took: ");
log += timePassedSince(wifi_connect_timer);
log += F(" ms");
addLog(LOG_LEVEL_INFO, log);
// fix octet?
if (Settings.IP_Octet != 0 && Settings.IP_Octet != 255)
{
IPAddress ip = WiFi.localIP();
IPAddress gw = WiFi.gatewayIP();
IPAddress subnet = WiFi.subnetMask();
ip[3] = Settings.IP_Octet;
log = F("IP : Fixed IP octet:");
log += ip;
addLog(LOG_LEVEL_INFO, log);
WiFi.config(ip, gw, subnet);
}
#ifdef FEATURE_MDNS
String log = F("WIFI : ");
if (MDNS.begin(WifiGetHostname().c_str(), WiFi.localIP())) {
log += F("mDNS started, with name: ");
log += WifiGetHostname();
log += F(".local");
}
else{
log += F("mDNS failed");
}
addLog(LOG_LEVEL_INFO, log);
#endif
// First try to get the time, since that may be used in logs
if (Settings.UseNTP) {
initTime();
}
uint8_t* curBSSID = WiFi.BSSID();
bool changed = false;
for (byte i=0; i < 6; ++i) {
if (lastBSSID[i] != *(curBSSID + i)) {
changed = true;
lastBSSID[i] = *(curBSSID + i);
}
}
if (Settings.UseRules)
{
if (changed) {
String event = F("WiFi#ChangedAccesspoint");
rulesProcessing(event);
}
String event = F("WiFi#Connected");
rulesProcessing(event);
}
log = F("WIFI : Connected! IP: ");
log += formatIP(WiFi.localIP());
log += F(" (");
log += WifiGetHostname();
log += F(") AP: ");
log += WiFi.SSID();
log += F(" AP BSSID: ");
log += WiFi.BSSIDstr();
addLog(LOG_LEVEL_INFO, log);
statusLED(true);
return true;
}
//********************************************************************************
// Disconnect from Wifi AP
@@ -238,6 +372,7 @@ boolean WifiConnectSSID(char WifiSSID[], char WifiKey[], byte connectAttempts)
void WifiDisconnect()
{
WiFi.disconnect();
wifiConnected = false;
}
@@ -279,7 +414,6 @@ void WifiScan()
//********************************************************************************
void WifiCheck()
{
if(wifiSetup)
return;
@@ -289,8 +423,11 @@ void WifiCheck()
//give it time to automatically reconnect
if (NC_Count > 2)
{
WifiConnect(2);
if (wifiConnected) {
wifi_connect_attempt = 0;
wifiConnected = false;
WiFiConnectRelaxed();
}
C_Count=0;
NC_Count = 0;
}
@@ -305,6 +442,10 @@ void WifiCheck()
WifiAPMode(false);
}
}
if (!wifiConnected) {
if (tryConnectWiFi())
checkWifiJustConnected();
}
}
//********************************************************************************
+1 -1
View File
@@ -89,7 +89,7 @@ void C010_Send(struct EventStruct *event, byte varIndex, float value, unsigned l
if (WiFi.status() == WL_CONNECTED) {
ControllerSettings.beginPacket(portUDP);
portUDP.write(msg.c_str());
portUDP.write((uint8_t*)msg.c_str(),msg.length());
portUDP.endPacket();
}
+265
View File
@@ -0,0 +1,265 @@
//#######################################################################################################
//########################### Controller Plugin 013: ESPEasy P2P network ################################
//#######################################################################################################
#define CPLUGIN_013
#define CPLUGIN_ID_013 13
#define CPLUGIN_NAME_013 "ESPEasy P2P Networking"
WiFiUDP C013_portUDP;
struct infoStruct
{
byte header = 255;
byte ID = 3;
byte sourcelUnit;
byte destUnit;
byte sourceTaskIndex;
byte destTaskIndex;
byte deviceNumber;
char taskName[26];
char ValueNames[VARS_PER_TASK][26];
};
struct dataStruct
{
byte header = 255;
byte ID = 5;
byte sourcelUnit;
byte destUnit;
byte sourceTaskIndex;
byte destTaskIndex;
float Values[VARS_PER_TASK];
};
boolean CPlugin_013(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
switch (function)
{
case CPLUGIN_PROTOCOL_ADD:
{
Protocol[++protocolCount].Number = CPLUGIN_ID_013;
Protocol[protocolCount].usesMQTT = false;
Protocol[protocolCount].usesTemplate = false;
Protocol[protocolCount].usesAccount = false;
Protocol[protocolCount].usesPassword = false;
Protocol[protocolCount].defaultPort = 65501;
Protocol[protocolCount].usesID = false;
Protocol[protocolCount].Custom = true;
break;
}
case CPLUGIN_GET_DEVICENAME:
{
string = F(CPLUGIN_NAME_013);
break;
}
case CPLUGIN_PROTOCOL_TEMPLATE:
{
event->String1 = "";
event->String2 = "";
break;
}
case CPLUGIN_INIT:
{
//C013_portUDP.begin(Settings.UDPPort);
break;
}
case CPLUGIN_TASK_CHANGE_NOTIFICATION:
{
C013_SendUDPTaskInfo(0, event->TaskIndex, event->TaskIndex);
break;
}
case CPLUGIN_PROTOCOL_SEND:
{
C013_Send(event, 0, UserVar[event->BaseVarIndex], 0);
break;
}
case CPLUGIN_UDP_IN:
{
C013_Receive(event);
break;
}
}
return success;
}
//********************************************************************************
// Generic UDP message
//********************************************************************************
void C013_Send(struct EventStruct *event, byte varIndex, float value, unsigned long longValue)
{
ControllerSettingsStruct ControllerSettings;
LoadControllerSettings(event->ControllerIndex, (byte*)&ControllerSettings, sizeof(ControllerSettings));
statusLED(true);
C013_SendUDPTaskData(0, event->TaskIndex, event->TaskIndex);
}
void C013_SendUDPTaskInfo(byte destUnit, byte sourceTaskIndex, byte destTaskIndex)
{
if (!WiFiConnected(100)) {
return;
}
struct infoStruct infoReply;
infoReply.sourcelUnit = Settings.Unit;
infoReply.sourceTaskIndex = sourceTaskIndex;
infoReply.destTaskIndex = destTaskIndex;
LoadTaskSettings(infoReply.sourceTaskIndex);
infoReply.deviceNumber = Settings.TaskDeviceNumber[infoReply.sourceTaskIndex];
strcpy(infoReply.taskName, ExtraTaskSettings.TaskDeviceName);
for (byte x = 0; x < VARS_PER_TASK; x++)
strcpy(infoReply.ValueNames[x], ExtraTaskSettings.TaskDeviceValueNames[x]);
byte firstUnit = 1;
byte lastUnit = UNIT_MAX - 1;
if (destUnit != 0)
{
firstUnit = destUnit;
lastUnit = destUnit;
}
for (byte x = firstUnit; x <= lastUnit; x++)
{
if (x != Settings.Unit){
infoReply.destUnit = x;
C013_sendUDP(x, (byte*)&infoReply, sizeof(infoStruct));
delay(10);
}
}
delay(50);
}
void C013_SendUDPTaskData(byte destUnit, byte sourceTaskIndex, byte destTaskIndex)
{
if (!WiFiConnected(100)) {
return;
}
struct dataStruct dataReply;
dataReply.sourcelUnit = Settings.Unit;
dataReply.sourceTaskIndex = sourceTaskIndex;
dataReply.destTaskIndex = destTaskIndex;
for (byte x = 0; x < VARS_PER_TASK; x++)
dataReply.Values[x] = UserVar[dataReply.sourceTaskIndex * VARS_PER_TASK + x];
byte firstUnit = 1;
byte lastUnit = UNIT_MAX - 1;
if (destUnit != 0)
{
firstUnit = destUnit;
lastUnit = destUnit;
}
for (byte x = firstUnit; x <= lastUnit; x++)
{
if (x != Settings.Unit){
dataReply.destUnit = x;
C013_sendUDP(x, (byte*) &dataReply, sizeof(dataStruct));
delay(10);
}
}
delay(50);
}
/*********************************************************************************************\
Send UDP message (unit 255=broadcast)
\*********************************************************************************************/
void C013_sendUDP(byte unit, byte* data, byte size)
{
if (!WiFiConnected(100)) {
return;
}
if (unit != 255)
if (Nodes[unit].ip[0] == 0)
return;
String log = "C013 : Send UDP message to ";
log += unit;
addLog(LOG_LEVEL_DEBUG_MORE, log);
statusLED(true);
IPAddress remoteNodeIP;
if (unit == 255)
remoteNodeIP = {255, 255, 255, 255};
else
remoteNodeIP = Nodes[unit].ip;
C013_portUDP.beginPacket(remoteNodeIP, Settings.UDPPort);
C013_portUDP.write(data, size);
C013_portUDP.endPacket();
}
void C013_Receive(struct EventStruct *event) {
if (event->Data[1] > 1 && event->Data[1] < 6)
{
String log = (F("C013 : msg "));
for (byte x = 1; x < 6; x++)
{
log += " ";
log += (int)event->Data[x];
}
addLog(LOG_LEVEL_DEBUG_MORE, log);
}
switch (event->Data[1]) {
case 2: // sensor info pull request
{
//SendUDPTaskInfo(packetBuffer[2], packetBuffer[5], packetBuffer[4]);
break;
}
case 3: // sensor info
{
struct infoStruct infoReply;
memcpy((byte*)&infoReply, (byte*)event->Data, sizeof(infoStruct));
// to prevent flash wear out (bugs in communication?) we can only write to an empty task
// so it will write only once and has to be cleared manually through webgui
if (Settings.TaskDeviceNumber[infoReply.destTaskIndex] == 0)
{
Settings.TaskDeviceNumber[infoReply.destTaskIndex] = infoReply.deviceNumber;
Settings.TaskDeviceDataFeed[infoReply.destTaskIndex] = 1; // remote feed
for (byte x = 0; x < CONTROLLER_MAX; x++)
Settings.TaskDeviceSendData[x][infoReply.destTaskIndex] = false;
strcpy(ExtraTaskSettings.TaskDeviceName, infoReply.taskName);
for (byte x = 0; x < VARS_PER_TASK; x++)
strcpy( ExtraTaskSettings.TaskDeviceValueNames[x], infoReply.ValueNames[x]);
SaveTaskSettings(infoReply.destTaskIndex);
SaveSettings();
}
break;
}
case 4: // sensor data pull request
{
//SendUDPTaskData(packetBuffer[2], packetBuffer[5], packetBuffer[4]);
break;
}
case 5: // sensor data
{
struct dataStruct dataReply;
memcpy((byte*)&dataReply, (byte*)event->Data, sizeof(dataStruct));
// only if this task has a remote feed, update values
if (Settings.TaskDeviceDataFeed[dataReply.destTaskIndex] != 0)
{
for (byte x = 0; x < VARS_PER_TASK; x++)
{
UserVar[dataReply.destTaskIndex * VARS_PER_TASK + x] = dataReply.Values[x];
}
if (Settings.UseRules)
createRuleEvents(dataReply.destTaskIndex);
}
break;
}
}
}
+1 -1
View File
@@ -34,7 +34,7 @@
// Transceiver:
// SN75176 or MAX485 or LT1785 or ...
// Pin 5: GND
// Pin 2, 3, 5: +5V
// Pin 2, 3, 8: +5V
// Pin 4: to ESP D4
// Pin 6: DMX+ (hot)
// Pin 7: DMX- (cold)
+20
View File
@@ -166,6 +166,26 @@ boolean Plugin_059(byte function, struct EventStruct *event, String& string)
break;
}
case PLUGIN_WRITE:
{
if (Plugin_059_QE)
{
String log = "";
String command = parseString(string, 1);
if (command == F("encwrite"))
{
if (event->Par1 >= 0)
{
log = String(F("QEI : ")) + string;
addLog(LOG_LEVEL_INFO, log);
Plugin_059_QE->write(event->Par1);
success = true;
}
}
}
break;
}
}
return success;
}
+2 -2
View File
@@ -81,11 +81,11 @@ boolean Plugin_060(byte function, struct EventStruct *event, String& string)
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_060_cal"), CONFIG(3));
addFormNumericBox(string, F("Point 1"), F("plugin_060_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 1023);
addFormNumericBox(string, F("Point 1"), F("plugin_060_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 4095);
string += F(" &#8793; ");
addTextBox(string, F("plugin_060_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
addFormNumericBox(string, F("Point 2"), F("plugin_060_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 1023);
addFormNumericBox(string, F("Point 2"), F("plugin_060_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 4095);
string += F(" &#8793; ");
addTextBox(string, F("plugin_060_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
+8 -8
View File
@@ -87,7 +87,7 @@ void SHT3X::get()
#define CONFIG(n) (Settings.TaskDevicePluginConfig[event->TaskIndex][n])
#endif
SHT3X* Plugin_068_SHT3x = NULL;
SHT3X* Plugin_068_SHT3x[TASKS_MAX] = { NULL, };
//==============================================
@@ -148,9 +148,9 @@ boolean Plugin_068(byte function, struct EventStruct *event, String& string)
case PLUGIN_INIT:
{
if (Plugin_068_SHT3x)
delete Plugin_068_SHT3x;
Plugin_068_SHT3x = new SHT3X(CONFIG(0));
if (Plugin_068_SHT3x[event->TaskIndex])
delete Plugin_068_SHT3x[event->TaskIndex];
Plugin_068_SHT3x[event->TaskIndex] = new SHT3X(CONFIG(0));
success = true;
break;
@@ -158,12 +158,12 @@ boolean Plugin_068(byte function, struct EventStruct *event, String& string)
case PLUGIN_READ:
{
if (!Plugin_068_SHT3x)
if (!Plugin_068_SHT3x[event->TaskIndex])
return success;
Plugin_068_SHT3x->get();
UserVar[event->BaseVarIndex + 0] = Plugin_068_SHT3x->tmp;
UserVar[event->BaseVarIndex + 1] = Plugin_068_SHT3x->hum;
Plugin_068_SHT3x[event->TaskIndex]->get();
UserVar[event->BaseVarIndex + 0] = Plugin_068_SHT3x[event->TaskIndex]->tmp;
UserVar[event->BaseVarIndex + 1] = Plugin_068_SHT3x[event->TaskIndex]->hum;
String log = F("SHT3x: Temperature: ");
log += UserVar[event->BaseVarIndex + 0];
addLog(LOG_LEVEL_INFO, log);
+225 -70
View File
@@ -2,21 +2,24 @@
//################### Plugin 073 - 7-segment display plugin TM1637/MAX7219 ######################
//#######################################################################################################
//
// Chip supported:
// - TM1637 -- 2 pins - 4 digits and colon in the middle (XX:XX)
// - MAX7219/21 -- 3 pins - 8 digits and dot on each digit
// Chips/displays supported:
// 0 - TM1637 -- 2 pins - 4 digits and colon in the middle (XX:XX)
// 1 - TM1637 -- 2 pins - 4 digits and dot on each digit (X.X.X.X.)
// 2 - TM1637 -- 2 pins - 6 digits and dot on each digit (X.X.X.X.X.X.)
// 3 - MAX7219/21 -- 3 pins - 8 digits and dot on each digit (X.X.X.X.)
//
// Plugin can be setup as:
// - Manual -- display is manually updated sending commands
// "7dn,<number>" (number can be negative or positive)
// "7dn,<number>" (number can be negative or positive, even with decimal)
// "7dt,<temperature>" (temperature can be negative or positive and containing decimals)
// - Clock-Blink -- display is automatically updated with current time and blinking dot/lines
// - Clock-NoBlink -- display is automatically updated with current time and steady dot/lines
// - Date -- display is automatically updated with current date
//
// Generic commands:
// - "7don" -- turn ON the display
// - "7doff" -- turn OFF the display
// - "7db,<0-15> -- set brightness to specifi value between 0 and 15
// - "7db,<0-15> -- set brightness to specific value between 0 and 15
//
#ifdef PLUGIN_BUILD_TESTING
@@ -24,7 +27,7 @@
#define PLUGIN_073
#define PLUGIN_ID_073 73
#define PLUGIN_NAME_073 "Display - 7-segment display [TESTING]"
#define PLUGIN_073_DEBUG true //activate extra log info in the debug
#define PLUGIN_073_DEBUG false //activate extra log info in the debug
//---------------------------------------------------
// Class used by plugin
@@ -38,16 +41,19 @@ class p073_7dgt
byte brightness;
boolean timesep;
};
p073_7dgt *Plugin_073_7dgt;
p073_7dgt *Plugin_073_7dgt = NULL;
//---------------------------------------------------
uint8_t p073_showbuffer[8];
byte p073_spidata[2];
byte p073_dotpos;
bool p073_shift;
#define TM1637_POWER_ON 0b10001000
#define TM1637_POWER_OFF 0b10000000
#define TM1637_BIT_DELAY 50
#define TM1637_POWER_ON B10001000
#define TM1637_POWER_OFF B10000000
#define TM1637_CLOCKDELAY 40
#define TM1637_4DIGIT 4
#define TM1637_6DIGIT 2
// each char table is specific for each display and maps all numbers/symbols needed:
// - pos 0-9 - Numbers from 0 to 9
@@ -90,8 +96,8 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
{
addFormNote(string, F("TM1637: 1st=CLK-Pin, 2nd=DIO-Pin"));
addFormNote(string, F("MAX7219: 1st=DIN-Pin, 2nd=CLK-Pin, 3rd=CS-Pin"));
String displtype[3] = { F("TM1637 - 4 digit"), F("MAX7219 - 8 digit")};
addFormSelector(string, F("Display Type"), F("plugin_073_displtype"), 2, displtype, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
String displtype[5] = { F("TM1637 - 4 digit (colon)"), F("TM1637 - 4 digit (dots)"), F("TM1637 - 6 digit"), F("MAX7219 - 8 digit")};
addFormSelector(string, F("Display Type"), F("plugin_073_displtype"), 4, displtype, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
String displout[4] = { F("Manual"), F("Clock - Blink"), F("Clock - No Blink"), F("Date") };
addFormSelector(string, F("Display Output"), F("plugin_073_displout"), 4, displout, NULL, Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormNumericBox(string, F("Brightness"), F("plugin_073_brightness"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 15);
@@ -115,6 +121,8 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
switch (Settings.TaskDevicePluginConfig[event->TaskIndex][0])
{
case 0: // set brightness of TM1637
case 1:
case 2:
{
int tm1637_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][2] / 2;
tm1637_SetPowerBrightness(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex], tm1637_bright, true);
@@ -122,7 +130,7 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
tm1637_ClearDisplay(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex]);
break;
}
case 1: // set brightness of MAX7219
case 3: // set brightness of MAX7219
{
max7219_SetPowerBrightness(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex], Settings.TaskDevicePin3[event->TaskIndex], Settings.TaskDevicePluginConfig[event->TaskIndex][2], true);
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] == 0)
@@ -148,13 +156,15 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
switch (Settings.TaskDevicePluginConfig[event->TaskIndex][0])
{
case 0:
case 1:
case 2:
{
tm1637_InitDisplay(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex]);
int tm1637_bright = Settings.TaskDevicePluginConfig[event->TaskIndex][2] / 2;
tm1637_SetPowerBrightness(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex], tm1637_bright, true);
break;
}
case 1:
case 3:
{
max7219_InitDisplay(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex], Settings.TaskDevicePin3[event->TaskIndex]);
max7219_SetPowerBrightness(Settings.TaskDevicePin1[event->TaskIndex], Settings.TaskDevicePin2[event->TaskIndex], Settings.TaskDevicePin3[event->TaskIndex], Settings.TaskDevicePluginConfig[event->TaskIndex][2], true);
@@ -182,18 +192,38 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
if (tmpString.equalsIgnoreCase(F("7dn"))) {
if (Plugin_073_7dgt->output != 0)
break;
String log = F("7DGT : Show Number=");
log += event->Par1;
addLog(LOG_LEVEL_INFO, log);
switch (Plugin_073_7dgt->type)
{
case 0:
{
if (event->Par1 > -1000 && event->Par1 < 10000)
p073_FillBufferWithNumber(String(int(event->Par1)));
else
p073_FillBufferWithDash();
tm1637_ShowBuffer(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2);
tm1637_ShowBuffer(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, TM1637_4DIGIT);
break;
case 1:
{
if (event->Par1 > -1000 && event->Par1 < 10000)
p073_FillBufferWithNumber(tmpStr.substring(comma1+1).c_str());
else
p073_FillBufferWithDash();
tm1637_ShowBuffer(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, TM1637_4DIGIT);
break;
}
case 1:
case 2:
{
if (event->Par1 > -100000 && event->Par1 < 1000000)
p073_FillBufferWithNumber(tmpStr.substring(comma1+1).c_str());
else
p073_FillBufferWithDash();
tm1637_SwapDigitInBuffer(); // only needed for 6-digits displays
tm1637_ShowBuffer(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, TM1637_6DIGIT);
break;
}
case 3:
{
if (comma1 > 0) {
if (event->Par1 > -10000000 && event->Par1 < 100000000) {
@@ -206,6 +236,7 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
break;
}
}
success = true;
} else if (tmpString.equalsIgnoreCase(F("7dt"))) {
if (Plugin_073_7dgt->output != 0)
break;
@@ -213,9 +244,13 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
bool p073_tempflagdot = false;
if (comma1 > 0)
p073_temptemp = atof(tmpStr.substring(comma1+1).c_str());
String log = F("7DGT : Show Temperature=");
log += p073_temptemp;
addLog(LOG_LEVEL_INFO, log);
switch (Plugin_073_7dgt->type)
{
case 0:
case 1:
{
if (p073_temptemp > 999 || p073_temptemp < -99.9)
p073_FillBufferWithDash();
@@ -228,10 +263,26 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
if (p073_temptemp == 0 && p073_tempflagdot)
p073_showbuffer[5] = 0;
}
tm1637_ShowTimeTemp(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, p073_tempflagdot, 4);
tm1637_ShowTimeTemp4(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, p073_tempflagdot, 4);
break;
}
case 1:
case 2:
{
if (p073_temptemp > 999 || p073_temptemp < -99.9)
p073_FillBufferWithDash();
else {
if (p073_temptemp < 100 && p073_temptemp > -10) {
p073_temptemp = int(p073_temptemp*10);
p073_tempflagdot = true;
}
p073_FillBufferWithTemp(p073_temptemp);
if (p073_temptemp == 0 && p073_tempflagdot)
p073_showbuffer[5] = 0;
}
tm1637_ShowTemp6(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, p073_tempflagdot);
break;
}
case 3:
{
p073_temptemp = int(p073_temptemp*10);
p073_FillBufferWithTemp(p073_temptemp);
@@ -241,38 +292,48 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
break;
}
}
success = true;
} else {
bool p073_validcmd = false;
bool p073_displayon;
if (tmpString.equalsIgnoreCase(F("7don"))) {
String log = F("7DGT : Display ON");
addLog(LOG_LEVEL_INFO, log);
p073_displayon = true;
p073_validcmd = true;
}
else if (tmpString.equalsIgnoreCase(F("7doff"))) {
String log = F("7DGT : Display OFF");
addLog(LOG_LEVEL_INFO, log);
p073_displayon = false;
p073_validcmd = true;
}
else if (tmpString.equalsIgnoreCase(F("7db"))) {
if (event->Par1 >= 0 && event->Par1 < 16) {
String log = F("7DGT : Brightness=");
log += event->Par1;
addLog(LOG_LEVEL_INFO, log);
Plugin_073_7dgt->brightness = event->Par1;
p073_displayon = true;
p073_validcmd = true;
}
}
if (p073_validcmd) {
success = true;
switch (Plugin_073_7dgt->type)
{
case 0:
case 1:
case 2:
{ int tm1637_bright = Plugin_073_7dgt->brightness / 2;
tm1637_SetPowerBrightness(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, tm1637_bright, p073_displayon);
break; }
case 1:
case 3:
{ max7219_SetPowerBrightness(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, Plugin_073_7dgt->pin3, Plugin_073_7dgt->brightness, p073_displayon);
break; }
}
}
}
success = true;
break;
}
@@ -294,11 +355,20 @@ boolean Plugin_073(byte function, struct EventStruct *event, String& string)
switch (Plugin_073_7dgt->type)
{
case 0:
case 1:
{
tm1637_ShowTimeTemp(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, Plugin_073_7dgt->timesep, 0);
tm1637_ShowTimeTemp4(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, Plugin_073_7dgt->timesep, 0);
break;
}
case 1:
case 2:
{
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] == 3)
tm1637_ShowDate6(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, Plugin_073_7dgt->timesep);
else
tm1637_ShowTime6(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, Plugin_073_7dgt->timesep);
break;
}
case 3:
{
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] == 3)
max7219_ShowDate(Plugin_073_7dgt->pin1, Plugin_073_7dgt->pin2, Plugin_073_7dgt->pin3);
@@ -410,68 +480,90 @@ void p073_FillBufferWithDash() // in case of error show all dashes
#define DIO_HIGH() pinMode(dio_pin, INPUT)
#define DIO_LOW() pinMode(dio_pin, OUTPUT)
void tm1637_bitDelay(){
delayMicroseconds(TM1637_BIT_DELAY);
}
void tm1637_i2cStart (uint8_t clk_pin, uint8_t dio_pin)
{
CLK_HIGH();
if (PLUGIN_073_DEBUG) {
String log = F("7DGT : Comm Start");
addLog(LOG_LEVEL_INFO, log);
}
DIO_HIGH();
tm1637_bitDelay();
CLK_HIGH();
delayMicroseconds(TM1637_CLOCKDELAY);
DIO_LOW();
}
void tm1637_i2cStop (uint8_t clk_pin, uint8_t dio_pin)
{
if (PLUGIN_073_DEBUG) {
String log = F("7DGT : Comm Stop");
addLog(LOG_LEVEL_INFO, log);
}
CLK_LOW();
tm1637_bitDelay();
delayMicroseconds(TM1637_CLOCKDELAY);
DIO_LOW();
tm1637_bitDelay();
delayMicroseconds(TM1637_CLOCKDELAY);
CLK_HIGH();
tm1637_bitDelay();
delayMicroseconds(TM1637_CLOCKDELAY);
DIO_HIGH();
}
void tm1637_i2cAck (uint8_t clk_pin, uint8_t dio_pin)
{
bool dummyAck = false;
CLK_LOW();
DIO_HIGH();
tm1637_bitDelay();
while(digitalRead(dio_pin));
pinMode(dio_pin, INPUT_PULLUP);
//DIO_HIGH();
delayMicroseconds(TM1637_CLOCKDELAY);
//while(digitalRead(dio_pin));
dummyAck = digitalRead(dio_pin);
if (PLUGIN_073_DEBUG) {
String log = F("7DGT : Comm ACK=");
if (dummyAck == 0) { log += F("TRUE"); } else { log += F("FALSE"); }
addLog(LOG_LEVEL_INFO, log);
}
CLK_HIGH();
tm1637_bitDelay();
delayMicroseconds(TM1637_CLOCKDELAY);
CLK_LOW();
pinMode(dio_pin, OUTPUT);
}
void tm1637_i2cWrite (uint8_t clk_pin, uint8_t dio_pin, uint8_t bytetoprint)
{
if (PLUGIN_073_DEBUG) {
String log = F("7DGT : WriteByte");
addLog(LOG_LEVEL_INFO, log);
}
uint8_t i;
for(i=0; i<8; i++)
{
CLK_LOW();
(bytetoprint & B00000001)? DIO_HIGH() : DIO_LOW();
tm1637_bitDelay();
delayMicroseconds(TM1637_CLOCKDELAY);
bytetoprint = bytetoprint >> 1;
CLK_HIGH();
tm1637_bitDelay();
delayMicroseconds(TM1637_CLOCKDELAY);
}
}
void tm1637_ClearDisplay (uint8_t clk_pin, uint8_t dio_pin)
{
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0);
tm1637_i2cAck(clk_pin, dio_pin); tm1637_i2cWrite(clk_pin, dio_pin, 0);
tm1637_i2cAck(clk_pin, dio_pin); tm1637_i2cWrite(clk_pin, dio_pin, 0);
tm1637_i2cAck(clk_pin, dio_pin); tm1637_i2cWrite(clk_pin, dio_pin, 0);
tm1637_i2cAck(clk_pin, dio_pin); tm1637_i2cWrite(clk_pin, dio_pin, 0);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cStop(clk_pin, dio_pin);
}
void tm1637_SetPowerBrightness (uint8_t clk_pin, uint8_t dio_pin, uint8_t brightlvl, bool poweron)
{
if (PLUGIN_073_DEBUG) {
String log = F("7DGT : Set BRIGHT");
addLog(LOG_LEVEL_INFO, log);
}
uint8_t brightvalue = (brightlvl & 0b111);
if (poweron)
brightvalue = TM1637_POWER_ON | brightvalue;
@@ -485,10 +577,12 @@ void tm1637_SetPowerBrightness (uint8_t clk_pin, uint8_t dio_pin, uint8_t bright
void tm1637_InitDisplay(uint8_t clk_pin, uint8_t dio_pin)
{
pinMode(dio_pin, OUTPUT);
digitalWrite(dio_pin, LOW);
pinMode(dio_pin, INPUT_PULLUP);
pinMode(clk_pin, OUTPUT);
pinMode(dio_pin, OUTPUT);
CLK_HIGH();
DIO_HIGH();
// pinMode(dio_pin, INPUT_PULLUP);
// pinMode(clk_pin, OUTPUT);
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0x40);
tm1637_i2cAck(clk_pin, dio_pin);
@@ -496,38 +590,99 @@ void tm1637_InitDisplay(uint8_t clk_pin, uint8_t dio_pin)
tm1637_ClearDisplay(clk_pin, dio_pin);
}
void tm1637_ShowTimeTemp(uint8_t clk_pin, uint8_t dio_pin, bool sep, byte bufoffset)
void tm1637_ShowTime6(uint8_t clk_pin, uint8_t dio_pin, bool sep)
{
byte p073_datashowpos1;
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xc0);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[0+bufoffset]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[2]]); tm1637_i2cAck(clk_pin, dio_pin);
// add bit for colon on second digit if required
byte p073_datashowpos1 = CharTableTM1637[p073_showbuffer[1+bufoffset]];
p073_datashowpos1 = CharTableTM1637[p073_showbuffer[1]];
if (sep) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[2+bufoffset]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[3+bufoffset]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[0]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[5]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[4]]); tm1637_i2cAck(clk_pin, dio_pin);
// add bit for colon on fourth digit if required
p073_datashowpos1 = CharTableTM1637[p073_showbuffer[3]];
if (sep) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cStop(clk_pin, dio_pin);
}
void tm1637_ShowBuffer(uint8_t clk_pin, uint8_t dio_pin)
void tm1637_ShowDate6(uint8_t clk_pin, uint8_t dio_pin, bool sep)
{
byte p073_datashowpos1;
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[2]]); tm1637_i2cAck(clk_pin, dio_pin);
// add bit for colon on second digit if required
p073_datashowpos1 = CharTableTM1637[p073_showbuffer[1]];
if (sep) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[0]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[7]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[6]]); tm1637_i2cAck(clk_pin, dio_pin);
// add bit for colon on fourth digit if required
p073_datashowpos1 = CharTableTM1637[p073_showbuffer[3]];
if (sep) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cStop(clk_pin, dio_pin);
}
void tm1637_ShowTemp6(uint8_t clk_pin, uint8_t dio_pin, bool sep)
{
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xc0);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[4]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[5]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[6]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[7]]);
tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0); tm1637_i2cAck(clk_pin, dio_pin);
// add bit for colon on second digit if required
byte p073_datashowpos1 = CharTableTM1637[p073_showbuffer[5]];
if (sep) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[4]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[10]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[10]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[7]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[6]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cStop(clk_pin, dio_pin);
}
void tm1637_ShowTimeTemp4(uint8_t clk_pin, uint8_t dio_pin, bool sep, byte bufoffset)
{
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[0+bufoffset]]); tm1637_i2cAck(clk_pin, dio_pin);
// add bit for colon on second digit if required
byte p073_datashowpos1 = CharTableTM1637[p073_showbuffer[1+bufoffset]];
if (sep) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[2+bufoffset]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, CharTableTM1637[p073_showbuffer[3+bufoffset]]); tm1637_i2cAck(clk_pin, dio_pin);
tm1637_i2cStop(clk_pin, dio_pin);
}
void tm1637_SwapDigitInBuffer() {
uint8_t p073_temp;
p073_temp = p073_showbuffer[4]; p073_showbuffer[4] = p073_showbuffer[2]; p073_showbuffer[2] = p073_temp;
p073_temp = p073_showbuffer[5]; p073_showbuffer[5] = p073_showbuffer[7]; p073_showbuffer[7] = p073_temp;
switch (p073_dotpos)
{
case 2: { p073_dotpos = 4; break; }
case 4: { p073_dotpos = 2; break; }
case 5: { p073_dotpos = 7; break; }
case 7: { p073_dotpos = 5; break; }
}
}
void tm1637_ShowBuffer(uint8_t clk_pin, uint8_t dio_pin, byte digits)
{
byte p073_datashowpos1;
tm1637_i2cStart(clk_pin, dio_pin);
tm1637_i2cWrite(clk_pin, dio_pin, 0xC0); tm1637_i2cAck(clk_pin, dio_pin);
for(int i=digits;i<8;i++) {
p073_datashowpos1 = CharTableTM1637[p073_showbuffer[i]];
if (p073_dotpos == i) p073_datashowpos1 |= 0b10000000;
tm1637_i2cWrite(clk_pin, dio_pin, p073_datashowpos1); tm1637_i2cAck(clk_pin, dio_pin);
}
tm1637_i2cStop(clk_pin, dio_pin);
}
+12
View File
@@ -133,6 +133,7 @@ void CPluginInit(void)
#endif
CPluginCall(CPLUGIN_PROTOCOL_ADD, 0);
CPluginCall(CPLUGIN_INIT, 0);
}
byte CPluginCall(byte Function, struct EventStruct *event)
@@ -154,6 +155,17 @@ byte CPluginCall(byte Function, struct EventStruct *event)
}
return true;
break;
// calls to active plugins
case CPLUGIN_INIT:
case CPLUGIN_UDP_IN:
for (byte x=0; x < CONTROLLER_MAX; x++)
if (Settings.Protocol[x] != 0 && Settings.ControllerEnabled[x]) {
event->ProtocolIndex = getProtocolIndex(Settings.Protocol[x]);
CPlugin_ptr[event->ProtocolIndex](Function, event, dummyString);
}
return true;
break;
}
return false;