Compare commits

...
Author SHA1 Message Date
ESPEasy release bot 7f393af2a0 automaticly updated release notes for mega-20180417 2018-04-17 04:00:09 +02:00
Gijs NoorlanderandGitHub 3e22607276 Merge pull request #1264 from TD-er/feature/nextion_port_from_playground
Feature/nextion port from playground
2018-04-17 01:35:06 +02:00
TD-er 4de720382d [wifi] Fix build error for ESP32
Shared function was declared within #ifdef scope.
2018-04-17 01:34:07 +02:00
TD-er a718572688 [P075] Nextion plugin (testing)
Added Nextion plugin for testing from the Playground.
It is not yet tested on real hardware, but it has been in development for a while on the forum and playground.
Also requested in issue #1256 and by several others.
2018-04-17 01:29:31 +02:00
Unknown 2d66c9fefa [Nextion] Initial support for Nextion displays
Code taken from playground P117 and added minimal changes.
Still need some work to check and test with real display.
Not tested yet, myself.
2018-04-16 23:47:12 +02:00
Gijs NoorlanderandGitHub de51a130b3 Merge pull request #1262 from TD-er/bugfix/json_oled
[issue #1260] parentheses error on the json page
2018-04-16 23:28:53 +02:00
TD-er a8020c9011 [issue #1260] parentheses error on the json page 2018-04-16 23:28:02 +02:00
Gijs NoorlanderandGitHub a2cbc6d474 Merge pull request #1261 from TD-er/bugfix/fix_disconnects_static_ip
[wifi] Fix wifi reconnects with static IP
2018-04-16 23:03:05 +02:00
TD-er ea5c99431c [NTP] Add more information in the log when connecting to NTP server fail 2018-04-16 22:49:07 +02:00
TD-er 6f68d87f50 [wifi] Fix wifi reconnects with static IP
When a fixed IP setting is used, there will be no "Got IP" event, which will lead to a timeout and thus reconnect.
As a fix, the "Connected" event will also act like when a "Got IP" event was received when configured to use static IP.
2018-04-16 22:48:23 +02:00
Gijs NoorlanderandGitHub 4aa9c5e0ba Merge pull request #1259 from Grovkillen/Updating-gui
Updating gui (max width etc)
2018-04-16 20:49:07 +02:00
GrovkillenandGitHub 7e4666afed "Ctr (IDX)" was accidentally removed, now added 2018-04-16 17:23:37 +02:00
GrovkillenandGitHub 7651a07efc Added max widths for inputs 2018-04-16 17:02:31 +02:00
GrovkillenandGitHub f961a9f331 Made IDX column wider (device list) 2018-04-16 16:37:39 +02:00
GrovkillenandGitHub bb49cbdc89 Added number input to CSS (width 100px) 2018-04-16 16:34:00 +02:00
GrovkillenandGitHub 7fe1b41ea5 Made input type password part of "wide" 2018-04-16 16:26:18 +02:00
GrovkillenandGitHub 358e9f1e24 Change enable "off" to a nicer X 2018-04-16 16:20:14 +02:00
GrovkillenandGitHub 8f77ffc871 Made controller symbols a bit bigger (1)(2)(3) 2018-04-16 16:09:14 +02:00
GrovkillenandGitHub 60faa58894 Moved help button on hardware page
Moved it up (from right of the submit button which wasn't a good place for it)
2018-04-16 14:40:52 +02:00
GrovkillenandGitHub aba095b25d Moved help button for sleep 2018-04-16 14:00:17 +02:00
GrovkillenandGitHub 617ebe96de Re-arranged Rules page
Button moved down
Edit text removed
2018-04-16 13:45:57 +02:00
GrovkillenandGitHub a1bf42dde1 Put borders around checkboxes
Suggested here: #1253
2018-04-16 13:20:04 +02:00
ESPEasy release bot b0b83543eb automaticly updated release notes for mega-20180416 2018-04-16 04:00:09 +02:00
Gijs NoorlanderandGitHub b97be9c718 Merge pull request #1250 from TD-er/bugfix/wifi_start_ap_mode
[wifi] Prevent starting AP+STA mode with correct settings
2018-04-16 00:51:04 +02:00
TD-er 33831b072b [info] Added FW information to help diagnose issues
A lot of issue reports do not include information about the used version of the core libraries and 'normal', 'dev', etc. 
Since this information helps narrowing down the possible causes of the reported issues, it is best to add them in the general log.
2018-04-16 00:49:17 +02:00
TD-er a5f94298d8 [wifi] Proper log of static IP configuration 2018-04-15 14:41:41 +02:00
TD-er d0dc959d31 [Wifi] force STA mode at boot
I finally have one node acting as described by others and this one reported a disconnect before a connect attempt was made.

Now forcing the wifi in STA mode, should resolve this issue.
2018-04-15 14:10:02 +02:00
TD-er 644aa2f65e [wifi] Prevent starting AP+STA mode with correct settings
WiFi persistent settings were disabled after initialisation of the event handler.
This allowed the firmware to start WiFi connection with settings stored in the flash (not our settings, the settings kept by the core library). If these fail, then a connection failed event would occur before a connect attempt was started from ESPeasy, which would lead to strange results on some nodes while others work just fine.
2018-04-15 12:05:07 +02:00
ESPEasy release bot e457fe7597 automaticly updated release notes for mega-20180415 2018-04-15 04:00:08 +02:00
Gijs NoorlanderandGitHub dcd409e9d9 Merge pull request #1249 from TD-er/bugfix/Webserver_appendingStrings
A lot of functions in Webserver.ino were just appending to a ever increasing string. These strings were eventually sent to TXBuffer of the Webinterface.
So why not directly send them to the streaming buffer and thus reduce memory usage and gain speed.
2018-04-15 02:06:34 +02:00
TD-er c227c13ba2 [Merge] Easier to merge, rebased on Mega branch. 2018-04-15 01:55:22 +02:00
TD-er c64566ce49 [PR #1248] Fixed textarea sizes
See #1248
2018-04-15 01:45:52 +02:00
TD-er a9366c8f23 [PR #1247 ] Merged PR into the refactoring of Webserver 2018-04-15 01:45:52 +02:00
TD-er bbf470c61d [WebServer] Cleanup of all functions appending to a big string
A lot of functions in Webserver.ino were just appending to a ever increasing string. These strings were eventually sent to TXBuffer of the Webinterface.
So why not directly send them to the streaming buffer and thus reduce memory usage and gain speed.
2018-04-15 01:45:30 +02:00
GrovkillenandGitHub 1c1211c4f3 Bumped delay timer for MQTT pub 10mSec
Tests showed that instead of publishing "now" a 10mSec delay made the unit respond better and publish faster.
2018-04-15 00:50:30 +02:00
Gijs NoorlanderandGitHub 7da0bc4a44 Merge pull request #1247 from Grovkillen/Fix-some-html
Fix some html
2018-04-14 21:19:52 +02:00
GrovkillenandGitHub 91a0c51ff8 Made addFormSeparator function a lot cleaner
Thanks to da man @TD-er
2018-04-14 21:15:33 +02:00
GrovkillenandGitHub 0aa523a329 Updated some more stuff
Made the call for the function work without the extra (not used) "extra text"... it's still in the base function for future use.
2018-04-14 20:55:52 +02:00
Gijs NoorlanderandGitHub cac7275eb9 Merge pull request #1245 from susisstrolch/ds18b20
ignore power-on reset value (85.0 °C)
2018-04-14 17:29:50 +02:00
Susis Strolch 109eaf7d25 DS_readTemp: handle power-on reset value
return false if DS_readTemp is power-on reset value
(0xaa for DS1820|DS18B20, 0x550 for DS18B20|DS1825|DS1822)
2018-04-14 15:38:11 +02:00
GrovkillenandGitHub 9ba15f2c19 Added column width for separator...
Now variable
2018-04-14 13:51:06 +02:00
GrovkillenandGitHub 1c07d787c5 Fixed missed update. 2018-04-14 13:45:13 +02:00
GrovkillenandGitHub b7ae2ea5fe Made checkmarks CSS
The   is made to be able to have text after the custom checkbox... the text itself is not yet styled since we're not using labels like that yet.
2018-04-14 13:40:49 +02:00
Gijs NoorlanderandGitHub b75bb204e3 Merge pull request #1209 from nunofgs/enhancement/replace-ultrasonic-plugin-with-newping-lib
Replace ultrasonic plugin with NewPing lib
2018-04-14 13:11:14 +02:00
Gijs NoorlanderandGitHub bfc8006205 Merge pull request #1242 from susisstrolch/stringConverter
system variables %sysheap%, %syssec_d
2018-04-14 13:08:28 +02:00
Gijs NoorlanderandGitHub aab2e4a442 Added C013 2018-04-14 12:56:41 +02:00
Gijs NoorlanderandGitHub abfdfe014e Merge pull request #1243 from susisstrolch/defineUses
add missing USES_XXX to _C*.ino, _N*.ino
2018-04-14 12:53:42 +02:00
Susis Strolch f82040d2ef ignore power-on reset value (85.0 °C) 2018-04-14 12:31:17 +02:00
Susis Strolch 56f2cf3121 system variables %sysheap%, %syssec_d
- %sysheap%: free heap memory
- %syssec_d%: seconds since midnight
2018-04-14 12:03:23 +02:00
Susis Strolch 6349f07d1a add missing USES_XXX to _C*.ino, _N*.ino 2018-04-14 10:44:25 +02:00
GrovkillenandGitHub 1b44559d3e Merge pull request #2 from letscontrolit/mega
Update source from MAIN
2018-04-14 08:57:26 +02:00
ESPEasy release bot a151e60755 automaticly updated release notes for mega-20180414 2018-04-14 04:00:08 +02:00
Gijs NoorlanderandGitHub ce11c84e74 Merge pull request #1186 from linuxnico/mega
add ds1822 definition to ds_read_temp function
2018-04-14 00:13:39 +02:00
Gijs NoorlanderandGitHub 9808bf86c4 Merge pull request #1078 from GHolli/mega
Sensor MH-Z19: Fixing offsets for the detection range setting command
2018-04-14 00:13:04 +02:00
Gijs NoorlanderandGitHub cfae636e55 Merge pull request #1240 from TD-er/feature/bssid_channel_variables
[issue #1239] %bssid% and %wi_ch% added as variables
2018-04-14 00:09:23 +02:00
Gijs NoorlanderandGitHub ebaaf50df6 Merge pull request #1230 from Grovkillen/Fix-nomenclature-for-delay/interval
Renamed delay to interval/time for better understanding
2018-04-14 00:09:09 +02:00
Gijs NoorlanderandGitHub 5c0be9e89f Merge pull request #1193 from clumsy-stefan/patch-1
_P015_TSL2561 added Broadband and IR Values
2018-04-14 00:07:32 +02:00
Gijs NoorlanderandGitHub 36468663f7 Merge pull request #1210 from giig1967g/mega
Fixes for #1208 and partial #1196
2018-04-14 00:05:36 +02:00
TD-er fba32608ee [issue #1239] %bssid% and %wi_ch% added as variables
See #1239
2018-04-13 23:47:08 +02:00
GrovkillenandGitHub 06848e50c3 Fixed main page!
Table was messed up... also update other tables
2018-04-13 23:46:45 +02:00
GrovkillenandGitHub 879d0d4916 Added better(?) format for tables
Fixed "normal" and "multirow" table css and made some column widths fixed.
2018-04-13 15:47:13 +02:00
ESPEasy release bot d083a58cd7 automaticly updated release notes for mega-20180413 2018-04-13 04:00:09 +02:00
Gijs NoorlanderandGitHub b1e9ff9fdc Merge pull request #1234 from TD-er/bugfix/Wifi_connection_issues
[wifi] Event based wifi, fix set AP and crash on start
2018-04-13 01:51:45 +02:00
TD-er 304280f415 [wifi] Event based wifi, fix set AP and crash on start
The settings had 2 new values which would be overwriten by the checksum and there was still some issue about when to save the settings.

Also added a check to only save changed settings.

Known issue: 
Sometimes after initial setup of wifi credentials, it is best to perform a reset.
2018-04-13 01:48:22 +02:00
GrovkillenandGitHub 2c8ca1421f Removed the serial print "done." 2018-04-12 09:55:11 +02:00
GrovkillenandGitHub 3ce0fb9f75 Merge branch 'mega' into Fix-nomenclature-for-delay/interval 2018-04-12 09:28:48 +02:00
ESPEasy release bot 8a71d2abd6 automaticly updated release notes for mega-20180412 2018-04-12 04:00:14 +02:00
Gijs NoorlanderandGitHub 1b174f4eac Merge pull request #1224 from flexiti/mega
ESP32 cpu speed and Id
2018-04-12 01:25:45 +02:00
Gijs NoorlanderandGitHub f1d18c7b41 Merge pull request #1220 from TD-er/bugfix/SoftAP_event_based_wifi
[issue #1215] Cannot login to accesspoint on new install
2018-04-12 01:22:46 +02:00
TD-er 204d4607ba Merge remote-tracking branch 'upstream/mega' into bugfix/SoftAP_event_based_wifi 2018-04-12 01:12:28 +02:00
TD-er 51f7ce0cb6 [wifi] Event based wifi, improve scan information. 2018-04-12 01:07:39 +02:00
Nuno Sousa 8f73deb133 Replace ultrasonic plugin with NewPing lib 2018-04-11 23:26:58 +01:00
Gijs NoorlanderandGitHub 1d4147309c [MQTT] Process MQTT loop on publish
As [discussed here](https://github.com/letscontrolit/ESPEasy/issues/1228#issuecomment-380420609).
2018-04-11 15:29:49 +02:00
mvdbro a68e4c1456 Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into mega 2018-04-11 14:57:22 +02:00
mvdbro 2ee51363dd Reboot/Reset pin, build 20101 patch 2018-04-11 14:57:12 +02:00
TD-er 172eb37b5b [wifi] Fix wifi AP setup mode for ESP32. 2018-04-11 01:24:34 +02:00
GrovkillenandGitHub 68e1d8ea69 Added RSSI, BSSID, Channel to WifiScan/Setup
And also delay is now renamed interval.
2018-04-10 15:47:59 +02:00
GrovkillenandGitHub ac8e8db0e7 Merge pull request #1 from letscontrolit/mega
Update
2018-04-10 14:24:17 +02:00
ESPEasy release bot d72bf9b76c automaticly updated release notes for mega-20180410 2018-04-10 04:00:21 +02:00
GeraldandGitHub 6d3f535d16 Merge pull request #3 from letscontrolit/mega
Downstream updates from head fork.
2018-04-09 21:39:15 +02:00
GrovkillenandGitHub 0709763f3a Update issue_template.md
`YOUR TEXT GOES HERE` added
2018-04-09 13:09:59 +02:00
GrovkillenandGitHub 538d843643 Update issue_template.md
Rearranged the topics...
2018-04-09 13:07:56 +02:00
GrovkillenandGitHub 2339ee928c Update issue_template.md
Added code format
2018-04-09 13:05:55 +02:00
GrovkillenandGitHub 9550b951d5 Update issue_template.md
Added a "Summarize" topic
2018-04-09 12:55:43 +02:00
GrovkillenandGitHub 0491af8a2f Added comments that will not show up on issues
Many users forget to "clean" the template from unnecessary text... these are now automatically hidden.
2018-04-09 12:53:05 +02:00
ESPEasy release bot 806a2757b2 automaticly updated release notes for mega-20180409 2018-04-09 04:00:13 +02:00
TD-er 3931b71d00 Merge branch 'mega' into bugfix/SoftAP_event_based_wifi 2018-04-09 00:17:48 +02:00
TD-er af0c3d5f62 [wifi] Make it work for ESP32 again 2018-04-08 23:50:07 +02:00
mvdbro c7a6ca4555 Both reset/factoryreset option 2018-04-08 17:05:59 +02:00
mvdbro 4a01e2eb49 Factory Reset (not enabled yet) 2018-04-08 08:27:25 +02:00
TD-er d6ff20b35d [WiFi] Event based wifi, now AP mode works
It appeared to be related to the core 2.3.0 version. The 2.4.0 does just work. Also changed a number of other things to improve stability.
2018-04-08 00:34:34 +02:00
ESPEasy release bot 0ada9aa105 automaticly updated release notes for mega-20180407 2018-04-07 04:00:12 +02:00
Holli 6b04539571 Disable detection range commands by default. 2018-04-06 18:40:08 +02:00
Plebs 9380ec13dc Added #I
#I: IN/OUT
2018-04-06 12:41:00 +02:00
GrovkillenandGitHub ae946c27c0 Fixed clickable link www.letscontrolit.com (#1192) 2018-04-06 10:02:36 +02:00
Plebs 86cf00759f added more formats
#X
#y
#Z
2018-04-06 08:38:26 +02:00
Plebs 0eb5f55d63 new #formats
Hi, here the new formats:
#O: ON/OFF
#C: Open/Close
#U: UP/Down
#Y: YES/NO
#D: converto to nearest integer
#F: convert to floor
#E: convert to ceiling
2018-04-05 23:39:54 +02:00
flexitiandGitHub f27d2aa7eb ESP CPU speed and ID 2018-04-05 15:09:24 +02:00
flexitiandGitHub 2d3285aaaf Merge pull request #1 from letscontrolit/mega
update
2018-04-05 15:05:25 +02:00
ESPEasy release bot 5bd2532853 automaticly updated release notes for mega-20180405 2018-04-05 04:00:10 +02:00
Plebs 765c56ccef modified float() call 2018-04-05 00:20:38 +02:00
mvdbro 4c755d83a6 ESP32 RTOS 10 per second
Run 10 per seconds call independent from main loop
2018-04-04 21:55:50 +02:00
mvdbro 1b9e1b92aa ESP32 RTOS config setting 2018-04-04 12:32:17 +02:00
Gijs NoorlanderandGitHub a4c73cc91e Merge pull request #1175 from Grovkillen/Fix-parsing-structure-for-JSON-+-upload-file-filter
Updated JSON path for sensor values and names
2018-04-04 10:06:17 +02:00
Gijs NoorlanderandGitHub 736fe2111a Merge pull request #1218 from soif/Fix/PioConfTypo
Unwanted lib_ignore now properly commented
2018-04-04 10:05:22 +02:00
Gijs NoorlanderandGitHub 767b0af733 Merge pull request #1217 from soif/Feat/JsonLoad
Shows CPU Load in JSON page
2018-04-04 10:04:59 +02:00
TD-er 02255180e9 [Wifi] Use statemachine to move between Wifi states
Still existing problems:
- Credentials are not being saved from web interface and thus connection doesn't work from setup page.
- First time connect to SoftAP takes a lot of attempts, when the wifi was searching for an existing accesspoint. This searching does prevent the SoftAP to form a stable connection to the client.

Maybe the entire wifi stack has to be reset before switching to SoftAP. Now it is near to impossible to recover from incorrect settings or a changes accesspoint.
Still under investigation.

It looks to be a problem with the
2018-04-04 03:19:03 +02:00
ESPEasy release bot c3bde94f7a automaticly updated release notes for mega-20180403 2018-04-03 04:00:14 +02:00
TD-er 886958d479 Merge remote-tracking branch 'origin/bugfix/SoftAP_event_based_wifi' into bugfix/SoftAP_event_based_wifi 2018-04-03 01:04:22 +02:00
TD-er 84cbc19f38 [issue #1215] Cannot login to accesspoint on new install
Since event based wifi, it became more apparent the ESP8266 has some issues with running AP and STA mode simultaneous.
It appears this can only work when the channel remains constant. But when trying to connect to an accesspoint that channel will change.
This means Soft AP and STA cannot be active at the same time when searching for an accesspoint to connect to. For example login to the Soft AP to correct some settings or replace an accesspoint would not be possible.

This fix deals with all of these issues and keeps the fast try/fail connection attempts offered by the event based wifi.
In short:
- 3x attempt to connect to AP1 (each attempt takes about 2.5 seconds when failing)
- 3x attempt to connect to AP2
- Enable accesspoint

When accesspoint is active, the connect attempts will be done at a slower pace and STA mode is disabled. STA mode is also disabled as soon as someone connects to the Soft AP.
When the settings are saved, a retry to connect like normal is started almost immediately. N.B. This will result in a disconnect of the connected users to the Soft AP.

So the connection time is:
- AP1 is valid: 4 - 10 seconds
- AP1 is not valid, AP2 is: 12 - 20 seconds
- AP1 and AP2 are not valid: +/- 18 seconds before activating Soft AP
2018-04-03 01:03:27 +02:00
TD-er 178ec9dfa9 [issue #1215] Cannot login to accesspoint on new install
Since event based wifi, it became more apparent the ESP8266 has some issues with running AP and STA mode simultaneous.
It appears this can only work when the channel remains constant. But when trying to connect to an accesspoint that channel will change.
This means Soft AP and STA cannot be active at the same time when searching for an accesspoint to connect to. For example login to the Soft AP to correct some settings or replace an accesspoint would not be possible.

This fix deals with all of these issues and keeps the fast try/fail connection attempts offered by the event based wifi.
In short:
- 3x attempt to connect to AP1 (each attempt takes about 2.5 seconds when failing)
- 3x attempt to connect to AP2
- Enable accesspoint

When accesspoint is active, the connect attempts will be done at a slower pace and STA mode is disabled. STA mode is also disabled as soon as someone connects to the Soft AP.
When the settings are saved, a retry to connect like normal is started almost immediately. N.B. This will result in a disconnect of the connected users to the Soft AP.

So the connection time is:
- AP1 is valid: 4 - 10 seconds
- AP1 is not valid, AP2 is: 12 - 20 seconds
- AP1 and AP2 are not valid: +/- 18 seconds before activating Soft AP
2018-04-03 00:47:06 +02:00
GrovkillenandGitHub 080be1ad0a Update _P029_Output.ino 2018-04-02 20:41:22 +02:00
GrovkillenandGitHub 232ca4f215 Update _P038_NeoPixel.ino 2018-04-02 20:40:08 +02:00
mvdbro bfa6eac538 ESP32 prep for RTOS multitasking 2018-04-02 15:59:01 +02:00
moi 0ca06782b9 unwanted lib_ignore now properly commented 2018-04-02 13:27:02 +02:00
moi 2079b0f28b Adds CPU Load LC in JSON page 2018-04-02 12:39:14 +02:00
moi 32bf45e817 Show CPU Load in JSON page 2018-04-02 12:38:30 +02:00
ESPEasy release bot 5d41bf9e73 automaticly updated release notes for mega-20180402 2018-04-02 04:00:10 +02:00
Gijs Noorlander dc5a2fd956 Revert "Merge pull request #1205 from s0170071/SerialSwap"
This reverts commit 46586e5355.
2018-04-01 10:47:50 +02:00
ESPEasy release bot b20f05305b automaticly updated release notes for mega-20180401 2018-04-01 04:00:08 +02:00
Gijs NoorlanderandGitHub 46586e5355 Merge pull request #1205 from s0170071/SerialSwap
Serial Swap function
2018-04-01 01:17:51 +02:00
Gijs NoorlanderandGitHub 7e8a751657 Merge pull request #1203 from TD-er/feature/mqtt_disconnect_event
[issue #1201] MQTT#Disconnected event and MQTT stability improvements
2018-04-01 01:14:55 +02:00
TD-er 7d61e55d34 [deepsleep] Allow for some minimum wifi connect time
In Deepsleep mode the wifi connect time is now minimum of 6 seconds.
Also the first loop after connect, the 'awake' timer will reset and start over. Without WiFi connection the set 'awake' timer starts at the moment the node boots.
2018-03-31 23:53:15 +02:00
GrovkillenandGitHub 2f663429a3 P0059 (rotary encoder) and P0063 (ttp229, keypad)
These two plugins are not in test but in normal.
2018-03-31 19:52:25 +02:00
ESPEasy release bot 492791a4ac automaticly updated release notes for mega-20180331 2018-03-31 04:00:09 +02:00
TD-er 52e75ade78 Merge remote-tracking branch 'origin/feature/mqtt_disconnect_event' into feature/mqtt_disconnect_event 2018-03-31 01:42:19 +02:00
TD-er 525a0ba0a1 [issue #1201] MQTT#Disconnected event and MQTT stability improvements
While looking for issues regarding DeepSleep + MQTT and issue #1195, I came across a number of other issues related to high CPU load and WiFi disconnects when a MQTT controller cannot reach the MQTT broker or is set to be no longer enabled.

These fixes improve CPU load and WiFi stability and also send the following events:
- `MQTT#Connected` 
- `MQTT#Disconnected`
- `MQTTimport#Connected` 
- `MQTTimport#Disconnected`

The MQTTimport plugin still has some major issues which have to be taken care of, so #1195 is not fixed yet.
2018-03-31 01:34:50 +02:00
Gijs NoorlanderandGitHub 52c7e5012e Merge pull request #1212 from TD-er/bugfix/build_issues_ESP32_ESP8266
[Build ESP32] Fix for build issues between ESP32 and ESP8266
2018-03-31 01:32:13 +02:00
TD-er 4dd733eb63 [ESP32] Build errors/warnings 2018-03-31 00:53:25 +02:00
TD-er 02a065d623 [Build ESP32] Fix for build issues between ESP32 and ESP8266
There is a problem with the PlatformIO builder since the last update of @mvdbro
It's an issue with the parsing of `#ifdef ESP32`.

It is very well explained here: [platformio/platformio-core#801 (comment)](https://github.com/platformio/platformio-core/issues/801#issuecomment-252447178)

In short, the event handling functions for the wifi have been moved to a separate .h file, since those files will be parsed properly by the Library Dependency Finder (LDF) in PlatformIO 3.x
2018-03-31 00:22:12 +02:00
Plebs e774ef5751 Fixes for #1208 and partial #1196
Fixed #1208
Added dìformat commands:
#C: 1/0 = Open/Close
#U: 1/0 = Up/Down
2018-03-30 21:05:33 +02:00
mvdbro 0afee4fafb ESP32: Fix Wifi Disconnect reason 2018-03-30 16:21:47 +02:00
s0170071 eba1fb3388 Serial Swap function
swaps Serial Pins *and* keeps track of it.
2018-03-30 08:47:55 +02:00
ESPEasy release bot b2c866edeb automaticly updated release notes for mega-20180330 2018-03-30 04:00:10 +02:00
TD-er 3583db3e22 [issue #1201] MQTT#Disconnected event and MQTT stability improvements
While looking for issues regarding DeepSleep + MQTT and issue #1195, I came across a number of other issues related to high CPU load and WiFi disconnects when a MQTT controller cannot reach the MQTT broker or is set to be no longer enabled.

These fixes improve CPU load and WiFi stability and also send the following events:
- `MQTT#Connected` 
- `MQTT#Disconnected`
- `MQTTimport#Connected` 
- `MQTTimport#Disconnected`

The MQTTimport plugin still has some major issues which have to be taken care of, so #1195 is not fixed yet.
2018-03-30 02:48:23 +02:00
GeraldandGitHub 5d3f8bf073 Update _P049_MHZ19.ino
Clarification of pin connections.
2018-03-29 21:28:25 +02:00
Gijs NoorlanderandGitHub 1a72444b0a Build issue with Arduino IDE
See https://github.com/letscontrolit/ESPEasy/issues/1188#issuecomment-377020065
2018-03-29 21:27:09 +02:00
GHolliandGitHub dd88db1913 Merge pull request #2 from letscontrolit/mega
Downstream updates
2018-03-29 20:10:05 +02:00
GHolliandGitHub aab00567fc Downstream updates (#1)
* Initial re-organisation of plugin sets (#1019)

* 12bit ADC values acceted up to 4095

MCP3221 is a 12bit ADC so accepted values should be up to 40195 not 1024

* automaticly updated release notes for v2.0-20180313

* - move all structs from ESPEasy.ino into header file
- add some fix for headers
- add const to rtttl notes array

* [issue #1066] Fix Webserver handle_control

There wasn't a proper start/end for the streaming webserver.
See discussion on issue #1066

* automaticly updated release notes for mega-20180314

* Custom controller GUI option

* Fixed #433

Not tested!

* #893, part 2 receiving

* Merge branch 'mega' of github.com:letscontrolit/ESPEasy into mega

# Conflicts:
#	src/ESPEasy.ino

* Rules fix

* #893 part1, send messages

* Custom controller GUI option

* #893, part 2 receiving

* Rules fix

* automaticly updated release notes for mega-20180315

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

# Conflicts:
#	src/ESPEasy.ino

* [v2.0 split globals] Base split on v2.0 version of ESPEasy.ino

*  MCP3221 allow values for calibration (#1073)

MCP3221 allow values for calibration

* [issue #1066] Fix Webserver handle_control (#1079)

[issue #1066] Fix Webserver handle_control

* Fixed multi instance problem on SHT3x #433 (#1081)

Fixed multi instance problem on SHT3x #433

* [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%`

* [issue #993] variable in MQTT subscribe topic

As [noted](https://github.com/letscontrolit/ESPEasy/issues/993#issuecomment-373140135) by @kluszcyn

* [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.

* [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%`

* [issue #993] variable in MQTT subscribe topic

As [noted](https://github.com/letscontrolit/ESPEasy/issues/993#issuecomment-373140135) by @kluszcyn

* [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.

* automaticly updated release notes for mega-20180316

* automaticly updated release notes for v2.0-20180316

* Add download button for current rule set

* - add encoder write #1086

* changed memory tracker to uint64_t for the ESP32

* Changed so that running all tasks immediately with deep sleep enabled only happens on first iteration after wake up

* Keep uint. Just change the init value.

* [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.

* - fix success setting

* - fix P073 success setting in PLUGIN_WRITE callback

* - initialize pointer in P073

* [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.

* [Travis error] Some #include test that wasn't meant to be included

... in the commit.

* [JSON] Add uint name (#1099) and WiFi information (PR #1113)

As suggested by @Grovkillen on PR #1113.

* [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

* #ifndef instead of #ifdef

* [issue #1007] Add other defines as suggested by @uzi18

* [Memory] parseTemplate did not check if markers were found

"Free Mem" reported this function to be using quite a lot of memory.
Maybe that was related to parsing texts without matching ']' or '#'
Just added some checks to see if they were found.

* [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.

* Add download button for current rule set (#1102)

Add download button for current rule set

* - add encoder write command #1086 (#1103)

- add encoder write command #1086

* 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

* Merge pull request #1112 from uzi18/fix-p073

Fix p073 - #1111

* Merge pull request #1114 from TD-er/feature/wifi_details_json

[JSON] Add uint name (#1099) and WiFi information (PR #1113)

* Merge pull request #1113 from TD-er/feature/reduce_impact_wifi_disconnect

[Relaxed WiFi] Perform WiFi initialization in steps

* Merge pull request #1116 from TD-er/feature/allow_own_defaults

[issue #1007] Allow user specific data in separate file

* Merge pull request #1118 from TD-er/bugfix/mqtt_publish_after_deep_sleep

[issue #1097] MQTT publish after deep sleep

* [merge] MIssing #endif due to merging.

* automaticly updated release notes for mega-20180319

* automaticly updated release notes for v2.0-20180319

* Fix wiring description for SN75176 transceiver

* Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"

This reverts commit 8ccbdcadf0.

* Fix wiring description for SN75176 transceiver

* Revert "Merge pull request #1116 from TD-er/feature/allow_own_defaults"

This reverts commit 8ccbdcadf0.

* [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.

* [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.

* automaticly updated release notes for mega-20180320

* automaticly updated release notes for v2.0-20180320

* [wifi] Setup with factory settings could not complete

* [wifi] Setup with factory settings could not complete

* [merge issue] Forgotten #endif in merge

* - P012 fix command interpretation

* - P023 fix command interpretation

* - P035 move strings to flash

* - P048 fetch params only when needed

* automaticly updated release notes for mega-20180321

* automaticly updated release notes for v2.0-20180321

* Serial WD crash

* [wifi] Make more robust checks and increase timeout

See #1145

* - P012 fix command interpretation

* - P023 fix command interpretation

* - P035 move strings to flash

* - P048 fetch params only when needed

* Serial WD crash

* [wifi] Make more robust checks and increase timeout

See #1145

* [Memory] parseTemplate did not check if markers were found

"Free Mem" reported this function to be using quite a lot of memory.
Maybe that was related to parsing texts without matching ']' or '#'
Just added some checks to see if they were found.

* [WiFi] Take much more time for initial WiFi connect during setup

Accesspoint is still active, so it may take a lot more time to make the initial connection

* [WiFi] Take much more time for initial WiFi connect during setup

Accesspoint is still active, so it may take a lot more time to make the initial connection

* automaticly updated release notes for mega-20180322

* ESP32 fix

* [Command] Parsing improvement for commands

Use more intelligent parsing of commands and switch statement to improve speed

* automaticly updated release notes for mega-20180323

* [WiFi] Reverted those temp String uses for ssid/pass

Was introduced due to misunderstanding of reported issues with WiFi.

* [issue #1131] Add %unixtime%

Show the current time as [Unix time](https://en.wikipedia.org/wiki/Unix_time) (numbers of seconds that have elapsed since midnight 1970-01-01, UTC)

* [issue #1097] Call MQTTclient.loop() during deepsleep

The `MQTTclient.loop()` function should be called quite often.
This does the actual MQTT handling.
In normal operations, this is called quite frequently, but it should also be called when deepsleep is active and right before deepsleep is activated again.

* [P1] Support for latest standard

* [wifi] Event based connect/reconnect

Now using the core WiFiEvents to act on:

- connect
- disconnect
- gotIP

This will make polling for a status no longer needed.
It also allows to get a better understanding in why diconnects happen, since the disconnect reason is given in the events.
This extra information is also present on the information panel on the webinterface and also in the JSON output.

The entire connect/disconnect/reconnect is now done completely asynchronous and thus takes much less resources from the ESP.
A disconnect will now also send an event: "WiFi#Disconnected"

For deepsleep this means there has to be a minimum awake time set and perhaps use rules to set the ESP into sleep again when done.
Typical connection times to an accesspoint are about 3 seconds + about 1 second for DHCP.

This also resolves the issues where services my try to connect while there is a WiFi connection, but not yet an IP address set.

I already noticed a lot of NTP servers from pool.ntp.org are non responsive the last few weeks, so that may still take some time, but that's another issue.

* automaticly updated release notes for mega-20180324

* [NTP] Speedup NTP again with async WiFi

Previously it would only start calling "now" when the WiFi was already setup.
And in calling `now()`, a call to an NTP server is being made. When this fails, retry again in a minute.
But now the WiFi initialization is asynchronous, so the first NTP query was already failing and thus the retry is already set to a minute.

This is fixed now and also the pool.ntp.org will pick a random one from 0...3 (.pool.ntp.org).
The DNS queries from this pool change about every minute, so if you want to retry because one of the servers is offline, you should try one from the other `N.pool.ntp.org` or else you have to wait for another minute.

* - fix for #1170 - uservar not setted on encwrite

* automaticly updated release notes for mega-20180326

* [issue #1174] Show degree sign via external writes to LCD

Fix suggested by [elmicha](https://github.com/letscontrolit/ESPEasy/issues/1174#issuecomment-376244766)

* [ESP32] Event driven WiFi for ESP32

Not tested, just got some inspiration by these files:

- https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino
- https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.cpp
- https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/esp32/esp_event.h

* automaticly updated release notes for mega-20180327

* Fix nesting level check

* [Build] Cleanup/split builds using defines

See PR #1034 and #1040 made by @soif

* [build] Disabled a few PlatformIO profiles for now.

There were way too many.
Just placed them in comments and Travis had already built them all to test first.

* automaticly updated release notes for mega-20180328

* [Arduino IDE] Revert changes in include paths

Were changed to be able to test the PlatformIO feature to compile only files that are actually used.
Apparently the Arduino IDE cannot find the files anymore because that IDE needs the parent directory to be named as the main project file, not "src"

* automaticly updated release notes for mega-20180329
2018-03-29 19:53:54 +02:00
clumsy-stefanandGitHub 21cb6135dd _P015_TSL2561 added Broadband and IR Values
Extended Plugin to also read Broadband and IR values from device.
2018-03-29 09:27:53 +02:00
ESPEasy release bot f613bb4572 automaticly updated release notes for mega-20180329 2018-03-29 04:00:11 +02:00
Gijs NoorlanderandGitHub 51059f0c18 Merge pull request #1189 from TD-er/bugfix/include_paths_ArduinoIDE
[issue #1188] Revert changes in include paths
2018-03-28 21:58:07 +02:00
TD-er dec6598f49 [Arduino IDE] Revert changes in include paths
Were changed to be able to test the PlatformIO feature to compile only files that are actually used.
Apparently the Arduino IDE cannot find the files anymore because that IDE needs the parent directory to be named as the main project file, not "src"
2018-03-28 21:40:09 +02:00
mvdbroandGitHub f8f6767bec Merge pull request #1180 from TD-er/bugfix/esp32_eventbased_wifi
[ESP32] Event driven WiFi for ESP32
2018-03-28 19:42:54 +02:00
linuxnico 07948c87aa add ds1822 definition to ds_read_temp function 2018-03-28 14:30:05 +02:00
ESPEasy release bot 5c475b98db automaticly updated release notes for mega-20180328 2018-03-28 04:00:09 +02:00
Gijs NoorlanderandGitHub 58fb8dc42b Merge pull request #1182 from TD-er/feature/pluginsets
[Build] Cleanup/split builds using defines
2018-03-27 22:37:45 +02:00
TD-er cb2b11a41a [build] Disabled a few PlatformIO profiles for now.
There were way too many.
Just placed them in comments and Travis had already built them all to test first.
2018-03-27 22:27:31 +02:00
TD-er ac4f3c4cd4 [Build] Cleanup/split builds using defines
See PR #1034 and #1040 made by @soif
2018-03-27 21:24:08 +02:00
mvdbro c651e29d2a Merge branch 'mega' of https://github.com/letscontrolit/ESPEasy into mega 2018-03-27 17:24:45 +02:00
mvdbro d7e886a841 Fix nesting level check 2018-03-27 17:23:56 +02:00
Gijs NoorlanderandGitHub eec7647782 Merge pull request #1025 from soif/Feat/PlugSets
Initial re-organisation of plugin sets (#1019)
2018-03-27 10:12:56 +02:00
ESPEasy release bot 6f9d120ff0 automaticly updated release notes for mega-20180327 2018-03-27 04:00:09 +02:00
TD-er 28ddc2d9c0 [ESP32] Event driven WiFi for ESP32
Not tested, just got some inspiration by these files:

- https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/examples/WiFiClientEvents/WiFiClientEvents.ino
- https://github.com/espressif/arduino-esp32/blob/master/libraries/WiFi/src/WiFiGeneric.cpp
- https://github.com/espressif/arduino-esp32/blob/master/tools/sdk/include/esp32/esp_event.h
2018-03-26 22:44:58 +02:00
Gijs NoorlanderandGitHub cc54354ac3 Merge pull request #1178 from TD-er/bugfix/degree_parse_LCD
[issue #1174] Show degree sign via external writes to LCD
2018-03-26 19:48:56 +02:00
TD-er 3929390629 [issue #1174] Show degree sign via external writes to LCD
Fix suggested by [elmicha](https://github.com/letscontrolit/ESPEasy/issues/1174#issuecomment-376244766)
2018-03-26 19:48:12 +02:00
GrovkillenandGitHub 5f4685337e Added value number as discussed. 2018-03-26 14:59:47 +02:00
GrovkillenandGitHub 08c158aa9c Moved to correct folder 2018-03-26 10:33:22 +02:00
GrovkillenandGitHub e9d71a8f35 Delete WebServer.ino
Same mistake as before, wrong folder upload
2018-03-26 10:32:58 +02:00
GrovkillenandGitHub 3e3173cbb0 Updated JSON path for sensor values and names
+file type filter on upload (not OTA since that is not part of ESP Easy core)
2018-03-26 10:31:27 +02:00
ESPEasy release bot 3a26ebf7b1 automaticly updated release notes for mega-20180326 2018-03-26 04:00:15 +02:00
Gijs NoorlanderandGitHub 1685bead52 Merge pull request #1173 from TD-er/merge/command_parsing
Merge "improve command parsing" & fix for #1170 - uservar not set on encwrite
2018-03-25 21:54:19 +02:00
Bartlomiej ZimonandTD-er 3a2fe35e5c - fix for #1170 - uservar not setted on encwrite 2018-03-25 21:04:34 +02:00
TD-er 29ce7f774f Merge branch 'bugfix/improve_command_parsing' into mega 2018-03-25 20:51:23 +02:00
Gijs NoorlanderandGitHub cc85327356 Merge pull request #1164 from BrianSetz/bugfix/plugin044
[P1 Wifi Gateway] Support for ESMR 5.0
2018-03-25 20:33:01 +02:00
Gijs NoorlanderandGitHub 0851bb655e Merge pull request #1165 from TD-er/feature/event_driven_wifi
[wifi] Event based connect/reconnect
2018-03-25 20:30:49 +02:00
TD-er d4bc10d8f1 [NTP] Speedup NTP again with async WiFi
Previously it would only start calling "now" when the WiFi was already setup.
And in calling `now()`, a call to an NTP server is being made. When this fails, retry again in a minute.
But now the WiFi initialization is asynchronous, so the first NTP query was already failing and thus the retry is already set to a minute.

This is fixed now and also the pool.ntp.org will pick a random one from 0...3 (.pool.ntp.org).
The DNS queries from this pool change about every minute, so if you want to retry because one of the servers is offline, you should try one from the other `N.pool.ntp.org` or else you have to wait for another minute.
2018-03-25 12:32:06 +02:00
ESPEasy release bot 0672f32f4b automaticly updated release notes for mega-20180324 2018-03-24 04:00:10 +01:00
TD-er a17f7b679c [wifi] Event based connect/reconnect
Now using the core WiFiEvents to act on:

- connect
- disconnect
- gotIP

This will make polling for a status no longer needed.
It also allows to get a better understanding in why diconnects happen, since the disconnect reason is given in the events.
This extra information is also present on the information panel on the webinterface and also in the JSON output.

The entire connect/disconnect/reconnect is now done completely asynchronous and thus takes much less resources from the ESP.
A disconnect will now also send an event: "WiFi#Disconnected"

For deepsleep this means there has to be a minimum awake time set and perhaps use rules to set the ESP into sleep again when done.
Typical connection times to an accesspoint are about 3 seconds + about 1 second for DHCP.

This also resolves the issues where services my try to connect while there is a WiFi connection, but not yet an IP address set.

I already noticed a lot of NTP servers from pool.ntp.org are non responsive the last few weeks, so that may still take some time, but that's another issue.
2018-03-24 01:19:32 +01:00
Brian Setz 425bd85c83 [P1] Support for latest standard 2018-03-23 22:13:03 +01:00
Gijs NoorlanderandGitHub 3be005e1ee Merge pull request #1161 from TD-er/bugfix/mqtt_deepsleep
[issue #1097] Call MQTTclient.loop() during deepsleep
2018-03-23 15:52:48 +01:00
TD-er 174f9e6e03 [issue #1097] Call MQTTclient.loop() during deepsleep
The `MQTTclient.loop()` function should be called quite often.
This does the actual MQTT handling.
In normal operations, this is called quite frequently, but it should also be called when deepsleep is active and right before deepsleep is activated again.
2018-03-23 15:19:10 +01:00
Gijs NoorlanderandGitHub 51a14a174f Merge pull request #1160 from TD-er/feature/epoch_time
[issue #1131] Add %unixtime%
2018-03-23 14:44:55 +01:00
Gijs NoorlanderandGitHub 7cb1f453d3 Merge pull request #1159 from TD-er/bugfix/wifi_issues
[WiFi] Reverted those temp String uses for ssid/pass
2018-03-23 14:44:41 +01:00
TD-er 23a6caab89 [issue #1131] Add %unixtime%
Show the current time as [Unix time](https://en.wikipedia.org/wiki/Unix_time) (numbers of seconds that have elapsed since midnight 1970-01-01, UTC)
2018-03-23 14:23:27 +01:00
TD-er 6b4300bd46 [WiFi] Reverted those temp String uses for ssid/pass
Was introduced due to misunderstanding of reported issues with WiFi.
2018-03-23 12:34:27 +01:00
ESPEasy release bot 04a9069db0 automaticly updated release notes for mega-20180323 2018-03-23 04:00:06 +01:00
TD-er dd636903c8 [Command] Parsing improvement for commands
Use more intelligent parsing of commands and switch statement to improve speed
2018-03-22 22:33:41 +01:00
GHolliandGitHub 4543a10739 Change comma to semicolon
Same functionality, but more common.
2018-03-22 20:12:28 +01:00
mvdbro 940b65e86a ESP32 fix 2018-03-22 14:08:47 +01:00
ESPEasy release bot 6344de0649 automaticly updated release notes for mega-20180322 2018-03-22 04:00:11 +01:00
TD-er 8ccd7c3e8d Merge branch 'v2.0' into mega 2018-03-22 01:06:27 +01:00
TD-er 22371649a4 [WiFi] Take much more time for initial WiFi connect during setup
Accesspoint is still active, so it may take a lot more time to make the initial connection
2018-03-22 01:05:56 +01:00
Gijs NoorlanderandGitHub 2a48d5033e Merge pull request #1149 from TD-er/bugfix/initialWiFiconnect
[WiFi] Take much more time for initial WiFi connect during setup
2018-03-22 01:04:48 +01:00
TD-er f064da797d [WiFi] Take much more time for initial WiFi connect during setup
Accesspoint is still active, so it may take a lot more time to make the initial connection
2018-03-22 01:04:19 +01:00
TD-er b0b8edf935 Merge branch 'v2.0' into mega 2018-03-22 00:27:38 +01:00
Gijs NoorlanderandGitHub 8cbd9a0822 Merge pull request #1148 from TD-er/merge/mega_to_v2.0_0321
Merge/mega to v2.0 0321
2018-03-22 00:24:59 +01:00
TD-er 93f9d11738 [Memory] parseTemplate did not check if markers were found
"Free Mem" reported this function to be using quite a lot of memory.
Maybe that was related to parsing texts without matching ']' or '#'
Just added some checks to see if they were found.
2018-03-22 00:24:17 +01:00
TD-er cf3e0a3f0a [wifi] Make more robust checks and increase timeout
See #1145
2018-03-22 00:12:04 +01:00
s0170071andTD-er ccfd14dbd3 Serial WD crash 2018-03-22 00:11:48 +01:00
Bartlomiej ZimonandTD-er 3034738ad4 - P048 fetch params only when needed 2018-03-22 00:11:30 +01:00
TD-er 178d1c46a2 - P035 move strings to flash 2018-03-22 00:11:21 +01:00
Bartlomiej ZimonandTD-er cdfd1d986e - P023 fix command interpretation 2018-03-22 00:10:55 +01:00
Bartlomiej ZimonandTD-er 4b7aa53692 - P012 fix command interpretation 2018-03-22 00:10:50 +01:00
Gijs NoorlanderandGitHub 7959a5133f Merge pull request #1117 from TD-er/bugfix/memoryusage_parsetemplate
[Memory] parseTemplate did not check if markers were found
2018-03-21 23:33:47 +01:00
Gijs NoorlanderandGitHub 941fb5c29c Merge pull request #1147 from TD-er/bugfix/check_wifi_cred
[wifi] Make more robust checks and increase timeout
2018-03-21 23:32:37 +01:00
TD-er c43c9ea2b3 [wifi] Make more robust checks and increase timeout
See #1145
2018-03-21 23:19:05 +01:00
Gijs NoorlanderandGitHub 967103bcad Merge pull request #1141 from uzi18/mega-plugins_check
some small fixes found during check for propper success setting
2018-03-21 21:36:52 +01:00
Gijs NoorlanderandGitHub efe637ec70 Merge pull request #1146 from s0170071/SerialWDCrash
Wifi connect fails if serial bytes are incoming
2018-03-21 21:24:43 +01:00
s0170071 00450eb260 Serial WD crash 2018-03-21 19:48:04 +01:00
ESPEasy release bot cc02fa4481 automaticly updated release notes for v2.0-20180321 2018-03-21 04:00:21 +01:00
Bartlomiej Zimon fccc31a7c6 - P048 fetch params only when needed 2018-03-21 02:43:04 +01:00
Bartlomiej Zimon b84d905a0b - P035 move strings to flash 2018-03-21 02:42:13 +01:00
Bartlomiej Zimon 94aa951cba - P023 fix command interpretation 2018-03-21 02:41:35 +01:00
Bartlomiej Zimon 2a23dcd011 - P012 fix command interpretation 2018-03-21 02:41:08 +01:00
Gijs NoorlanderandGitHub ab3a406706 [merge issue] Forgotten #endif in merge 2018-03-20 23:46:43 +01:00
Unknown f135c63d84 [Memory] parseTemplate did not check if markers were found
"Free Mem" reported this function to be using quite a lot of memory.
Maybe that was related to parsing texts without matching ']' or '#'
Just added some checks to see if they were found.
2018-03-18 23:57:42 +01:00
GHolliandGitHub daecf2017e Update _P049_MHZ19.ino 2018-03-13 21:41:17 +01:00
Holli 37122bc619 It seems the offsets [3]..[4] for the detection range setting (command byte 0x99) are wrong in the latest online data sheet: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf
According to the MH-Z19B data sheet version 1.2, valid from: 2017.03.22 (received 2018-03-07), the offset should be [6]..[7] instead.
Fixing the implementation accordingly.
2018-03-13 20:22:45 +01:00
soif 4bca2c6361 Initial re-organisation of plugin sets (#1019) 2018-03-06 09:53:17 +01:00
120 changed files with 5992 additions and 2195 deletions
+33 -9
View File
@@ -1,18 +1,42 @@
**NOTE: This is not a support forum! For questions and support go here: https://www.letscontrolit.com/forum/viewforum.php?f=1**
<!--- NOTE: This is not a support forum! For questions and support go here: --->
<!--- https://www.letscontrolit.com/forum/viewforum.php?f=1 --->
<!--- Remove topics that are not applicable to your feature request of issue --->
<!--- Remember to have a "to the point" TITLE --->
### Steps to reproduce
How can we trigger this problem?
Does the problem persists after powering off and on? (just resetting isn't enough sometimes)
### Summarize of the problem/feature request
<!--- Describe the problem or feature request --->
YOUR TEXT GOES HERE
### Expected behavior
Tell us what should happen?
<!--- Tell us what should happen? --->
YOUR TEXT GOES HERE
### Actual behavior
Tell us what happens instead?
<!--- Tell us what happens instead? --->
YOUR TEXT GOES HERE
### Steps to reproduce
<!--- How can we trigger this problem? --->
1.
2.
3.
<!--- Does the problem persists after powering off and on? (just resetting isn't enough sometimes) --->
<!--- Please document if you have restarted the unit and if the problem is then gone etc. etc. --->
### System configuration
<!--- Please add as much information and screenshots as possible --->
Hardware:
Software or git version:
<!--- You should also provide links to hardware pages etc where we can find more info --->
ESP Easy version:
<!--- In order to have a better readablity of your issue then you should place screenshots here --->
<!--- Simply drag and drop them onto this template, move the text string below the "ESP Easy settings/screenshots" topic --->
ESP Easy settings/screenshots:
### Rules or log data
<!--- place your code/rules between the two ``` rows --->
<!--- remove if not applicable! --->
```
```
+390
View File
@@ -1,3 +1,393 @@
-------------------------------------------------
Changes in release mega-20180417 (since mega-20180416)
-------------------------------------------------
Release date: Tue Apr 17 04:00:09 CEST 2018
Grovkillen (11):
Put borders around checkboxes
Re-arranged Rules page
Moved help button for sleep
Moved help button on hardware page
Made controller symbols a bit bigger (1)(2)(3)
Change enable "off" to a nicer X
Made input type password part of "wide"
Added number input to CSS (width 100px)
Made IDX column wider (device list)
Added max widths for inputs
"Ctr (IDX)" was accidentally removed, now added
TD-er (5):
[wifi] Fix wifi reconnects with static IP
[NTP] Add more information in the log when connecting to NTP server fail
[issue #1260] parentheses error on the json page
[P075] Nextion plugin (testing)
[wifi] Fix build error for ESP32
Unknown (1):
[Nextion] Initial support for Nextion displays
-------------------------------------------------
Changes in release mega-20180416 (since mega-20180415)
-------------------------------------------------
Release date: Mon Apr 16 04:00:09 CEST 2018
TD-er (4):
[wifi] Prevent starting AP+STA mode with correct settings
[Wifi] force STA mode at boot
[wifi] Proper log of static IP configuration
[info] Added FW information to help diagnose issues
-------------------------------------------------
Changes in release mega-20180415 (since mega-20180414)
-------------------------------------------------
Release date: Sun Apr 15 04:00:08 CEST 2018
Gijs Noorlander (1):
Added C013
Grovkillen (6):
Made checkmarks CSS
Fixed missed update.
Added column width for separator...
Updated some more stuff
Made addFormSeparator function a lot cleaner
Bumped delay timer for MQTT pub 10mSec
Nuno Sousa (1):
Replace ultrasonic plugin with NewPing lib
Susis Strolch (4):
add missing USES_XXX to _C*.ino, _N*.ino
system variables %sysheap%, %syssec_d
ignore power-on reset value (85.0 °C)
DS_readTemp: handle power-on reset value
TD-er (4):
[WebServer] Cleanup of all functions appending to a big string
[PR #1247 ] Merged PR into the refactoring of Webserver
[PR #1248] Fixed textarea sizes
[Merge] Easier to merge, rebased on Mega branch.
-------------------------------------------------
Changes in release mega-20180414 (since mega-20180413)
-------------------------------------------------
Release date: Sat Apr 14 04:00:08 CEST 2018
GHolli (3):
Update _P049_MHZ19.ino
Change comma to semicolon
Downstream updates (#1)
Gerald (1):
Update _P049_MHZ19.ino
Grovkillen (4):
Added RSSI, BSSID, Channel to WifiScan/Setup
Removed the serial print "done."
Added better(?) format for tables
Fixed main page!
Holli (2):
It seems the offsets [3]..[4] for the detection range setting (command byte 0x99) are wrong in the latest online data sheet: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf According to the MH-Z19B data sheet version 1.2, valid from: 2017.03.22 (received 2018-03-07), the offset should be [6]..[7] instead. Fixing the implementation accordingly.
Disable detection range commands by default.
Plebs (5):
Fixes for #1208 and partial #1196
modified float() call
new #formats
added more formats
Added #I
TD-er (1):
[issue #1239] %bssid% and %wi_ch% added as variables
clumsy-stefan (1):
_P015_TSL2561 added Broadband and IR Values
linuxnico (1):
add ds1822 definition to ds_read_temp function
-------------------------------------------------
Changes in release mega-20180413 (since mega-20180412)
-------------------------------------------------
Release date: Fri Apr 13 04:00:09 CEST 2018
TD-er (1):
[wifi] Event based wifi, fix set AP and crash on start
-------------------------------------------------
Changes in release mega-20180412 (since mega-20180410)
-------------------------------------------------
Release date: Thu Apr 12 04:00:14 CEST 2018
Gijs Noorlander (1):
[MQTT] Process MQTT loop on publish
TD-er (7):
[issue #1215] Cannot login to accesspoint on new install
[issue #1215] Cannot login to accesspoint on new install
[Wifi] Use statemachine to move between Wifi states
[WiFi] Event based wifi, now AP mode works
[wifi] Make it work for ESP32 again
[wifi] Fix wifi AP setup mode for ESP32.
[wifi] Event based wifi, improve scan information.
flexiti (1):
ESP CPU speed and ID
mvdbro (1):
Reboot/Reset pin, build 20101 patch
-------------------------------------------------
Changes in release mega-20180410 (since mega-20180409)
-------------------------------------------------
Release date: Tue Apr 10 04:00:21 CEST 2018
Grovkillen (5):
Added comments that will not show up on issues
Update issue_template.md
Update issue_template.md
Update issue_template.md
Update issue_template.md
-------------------------------------------------
Changes in release mega-20180409 (since mega-20180407)
-------------------------------------------------
Release date: Mon Apr 9 04:00:13 CEST 2018
mvdbro (2):
Factory Reset (not enabled yet)
Both reset/factoryreset option
-------------------------------------------------
Changes in release mega-20180407 (since mega-20180405)
-------------------------------------------------
Release date: Sat Apr 7 04:00:12 CEST 2018
Grovkillen (1):
Fixed clickable link www.letscontrolit.com (#1192)
-------------------------------------------------
Changes in release mega-20180405 (since mega-20180403)
-------------------------------------------------
Release date: Thu Apr 5 04:00:10 CEST 2018
Grovkillen (4):
Updated JSON path for sensor values and names
Delete WebServer.ino
Moved to correct folder
Added value number as discussed.
moi (3):
Show CPU Load in JSON page
Adds CPU Load LC in JSON page
unwanted lib_ignore now properly commented
mvdbro (2):
ESP32 RTOS config setting
ESP32 RTOS 10 per second
-------------------------------------------------
Changes in release mega-20180403 (since mega-20180402)
-------------------------------------------------
Release date: Tue Apr 3 04:00:14 CEST 2018
Grovkillen (2):
Update _P038_NeoPixel.ino
Update _P029_Output.ino
mvdbro (1):
ESP32 prep for RTOS multitasking
-------------------------------------------------
Changes in release mega-20180402 (since mega-20180401)
-------------------------------------------------
Release date: Mon Apr 2 04:00:10 CEST 2018
Gijs Noorlander (1):
Revert "Merge pull request #1205 from s0170071/SerialSwap"
-------------------------------------------------
Changes in release mega-20180401 (since mega-20180331)
-------------------------------------------------
Release date: Sun Apr 1 04:00:08 CEST 2018
Grovkillen (1):
P0059 (rotary encoder) and P0063 (ttp229, keypad)
TD-er (3):
[issue #1201] MQTT#Disconnected event and MQTT stability improvements
[issue #1201] MQTT#Disconnected event and MQTT stability improvements
[deepsleep] Allow for some minimum wifi connect time
s0170071 (1):
Serial Swap function
-------------------------------------------------
Changes in release mega-20180331 (since mega-20180330)
-------------------------------------------------
Release date: Sat Mar 31 04:00:09 CEST 2018
TD-er (2):
[Build ESP32] Fix for build issues between ESP32 and ESP8266
[ESP32] Build errors/warnings
mvdbro (1):
ESP32: Fix Wifi Disconnect reason
-------------------------------------------------
Changes in release mega-20180330 (since mega-20180329)
-------------------------------------------------
Release date: Fri Mar 30 04:00:10 CEST 2018
Gijs Noorlander (1):
Build issue with Arduino IDE
-------------------------------------------------
Changes in release mega-20180329 (since mega-20180328)
-------------------------------------------------
Release date: Thu Mar 29 04:00:11 CEST 2018
TD-er (2):
[ESP32] Event driven WiFi for ESP32
[Arduino IDE] Revert changes in include paths
-------------------------------------------------
Changes in release mega-20180328 (since mega-20180327)
-------------------------------------------------
Release date: Wed Mar 28 04:00:09 CEST 2018
TD-er (2):
[Build] Cleanup/split builds using defines
[build] Disabled a few PlatformIO profiles for now.
mvdbro (1):
Fix nesting level check
soif (1):
Initial re-organisation of plugin sets (#1019)
-------------------------------------------------
Changes in release mega-20180327 (since mega-20180326)
-------------------------------------------------
Release date: Tue Mar 27 04:00:09 CEST 2018
TD-er (1):
[issue #1174] Show degree sign via external writes to LCD
-------------------------------------------------
Changes in release mega-20180326 (since mega-20180324)
-------------------------------------------------
Release date: Mon Mar 26 04:00:14 CEST 2018
Bartlomiej Zimon (1):
- fix for #1170 - uservar not setted on encwrite
Brian Setz (1):
[P1] Support for latest standard
TD-er (3):
[Command] Parsing improvement for commands
[wifi] Event based connect/reconnect
[NTP] Speedup NTP again with async WiFi
-------------------------------------------------
Changes in release mega-20180324 (since mega-20180323)
-------------------------------------------------
Release date: Sat Mar 24 04:00:10 CET 2018
TD-er (3):
[WiFi] Reverted those temp String uses for ssid/pass
[issue #1131] Add %unixtime%
[issue #1097] Call MQTTclient.loop() during deepsleep
-------------------------------------------------
Changes in release mega-20180323 (since mega-20180322)
-------------------------------------------------
Release date: Fri Mar 23 04:00:06 CET 2018
mvdbro (1):
ESP32 fix
-------------------------------------------------
Changes in release mega-20180322 (since mega-20180321)
-------------------------------------------------
Release date: Thu Mar 22 04:00:11 CET 2018
Bartlomiej Zimon (7):
- P012 fix command interpretation
- P023 fix command interpretation
- P035 move strings to flash
- P048 fetch params only when needed
- P012 fix command interpretation
- P023 fix command interpretation
- P048 fetch params only when needed
ESPEasy release bot (1):
automaticly updated release notes for v2.0-20180321
Gijs Noorlander (1):
[merge issue] Forgotten #endif in merge
TD-er (6):
[wifi] Make more robust checks and increase timeout
- P035 move strings to flash
[wifi] Make more robust checks and increase timeout
[Memory] parseTemplate did not check if markers were found
[WiFi] Take much more time for initial WiFi connect during setup
[WiFi] Take much more time for initial WiFi connect during setup
Unknown (1):
[Memory] parseTemplate did not check if markers were found
s0170071 (2):
Serial WD crash
Serial WD crash
-------------------------------------------------
Changes in release mega-20180321 (since mega-20180320)
-------------------------------------------------
+1 -3
View File
@@ -1,4 +1,4 @@
# EspESPeasySoftwareSerial
# ESPeasySoftwareSerial
Implementation of the Arduino software serial library for the ESP8266
@@ -7,5 +7,3 @@ Speed up to 115200 baud is supported. The constructor also has an optional input
Please note that due to the fact that the ESP always have other activities ongoing, there will be some inexactness in interrupt
timings. This may lead to bit errors when having heavy data traffic in high baud rates.
+1 -1
View File
@@ -1,5 +1,5 @@
{
"name": "EspESPeasySoftwareSerial",
"name": "ESPeasySoftwareSerial",
"version": "3.3.1",
"keywords": [
"serial", "io", "softwareserial"
+362
View File
@@ -0,0 +1,362 @@
// ---------------------------------------------------------------------------
// Created by Tim Eckel - teckel@leethost.com
// Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl.html
//
// See "NewPing.h" for purpose, syntax, version history, links, and more.
// ---------------------------------------------------------------------------
#include "NewPing.h"
// ---------------------------------------------------------------------------
// NewPing constructor
// ---------------------------------------------------------------------------
NewPing::NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance) {
#if DO_BITWISE == true
_triggerBit = digitalPinToBitMask(trigger_pin); // Get the port register bitmask for the trigger pin.
_echoBit = digitalPinToBitMask(echo_pin); // Get the port register bitmask for the echo pin.
_triggerOutput = portOutputRegister(digitalPinToPort(trigger_pin)); // Get the output port register for the trigger pin.
_echoInput = portInputRegister(digitalPinToPort(echo_pin)); // Get the input port register for the echo pin.
_triggerMode = (uint8_t *) portModeRegister(digitalPinToPort(trigger_pin)); // Get the port mode register for the trigger pin.
#else
_triggerPin = trigger_pin;
_echoPin = echo_pin;
#endif
set_max_distance(max_cm_distance); // Call function to set the max sensor distance.
#if (defined (__arm__) && defined (TEENSYDUINO)) || DO_BITWISE != true
pinMode(echo_pin, INPUT); // Set echo pin to input (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode).
pinMode(trigger_pin, OUTPUT); // Set trigger pin to output (on Teensy 3.x (ARM), pins default to disabled, at least one pinMode() is needed for GPIO mode).
#endif
#if defined (ARDUINO_AVR_YUN)
pinMode(echo_pin, INPUT); // Set echo pin to input for the Arduino Yun, not sure why it doesn't default this way.
#endif
#if ONE_PIN_ENABLED != true && DO_BITWISE == true
*_triggerMode |= _triggerBit; // Set trigger pin to output.
#endif
}
// ---------------------------------------------------------------------------
// Standard ping methods
// ---------------------------------------------------------------------------
unsigned int NewPing::ping(unsigned int max_cm_distance) {
if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance.
if (!ping_trigger()) return NO_ECHO; // Trigger a ping, if it returns false, return NO_ECHO to the calling function.
#if URM37_ENABLED == true
#if DO_BITWISE == true
while (!(*_echoInput & _echoBit)) // Wait for the ping echo.
#else
while (!digitalRead(_echoPin)) // Wait for the ping echo.
#endif
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
#else
#if DO_BITWISE == true
while (*_echoInput & _echoBit) // Wait for the ping echo.
#else
while (digitalRead(_echoPin)) // Wait for the ping echo.
#endif
if (micros() > _max_time) return NO_ECHO; // Stop the loop and return NO_ECHO (false) if we're beyond the set maximum distance.
#endif
return (micros() - (_max_time - _maxEchoTime) - PING_OVERHEAD); // Calculate ping time, include overhead.
}
unsigned long NewPing::ping_cm(unsigned int max_cm_distance) {
unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS.
#if ROUNDING_ENABLED == false
return (echoTime / US_ROUNDTRIP_CM); // Call the ping method and returns the distance in centimeters (no rounding).
#else
return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
#endif
}
unsigned long NewPing::ping_in(unsigned int max_cm_distance) {
unsigned long echoTime = NewPing::ping(max_cm_distance); // Calls the ping method and returns with the ping echo distance in uS.
#if ROUNDING_ENABLED == false
return (echoTime / US_ROUNDTRIP_IN); // Call the ping method and returns the distance in inches (no rounding).
#else
return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
#endif
}
unsigned long NewPing::ping_median(uint8_t it, unsigned int max_cm_distance) {
unsigned int uS[it], last;
uint8_t j, i = 0;
unsigned long t;
uS[0] = NO_ECHO;
while (i < it) {
t = micros(); // Start ping timestamp.
last = ping(max_cm_distance); // Send ping.
if (last != NO_ECHO) { // Ping in range, include as part of median.
if (i > 0) { // Don't start sort till second ping.
for (j = i; j > 0 && uS[j - 1] < last; j--) // Insertion sort loop.
uS[j] = uS[j - 1]; // Shift ping array to correct position for sort insertion.
} else j = 0; // First ping is sort starting point.
uS[j] = last; // Add last ping to array in sorted position.
i++; // Move to next ping.
} else it--; // Ping out of range, skip and don't include as part of median.
if (i < it && micros() - t < PING_MEDIAN_DELAY)
delay((PING_MEDIAN_DELAY + t - micros()) / 1000); // Millisecond delay between pings.
}
return (uS[it >> 1]); // Return the ping distance median.
}
// ---------------------------------------------------------------------------
// Standard and timer interrupt ping method support functions (not called directly)
// ---------------------------------------------------------------------------
boolean NewPing::ping_trigger() {
#if DO_BITWISE == true
#if ONE_PIN_ENABLED == true
*_triggerMode |= _triggerBit; // Set trigger pin to output.
#endif
*_triggerOutput &= ~_triggerBit; // Set the trigger pin low, should already be low, but this will make sure it is.
delayMicroseconds(4); // Wait for pin to go low.
*_triggerOutput |= _triggerBit; // Set trigger pin high, this tells the sensor to send out a ping.
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
*_triggerOutput &= ~_triggerBit; // Set trigger pin back to low.
#if ONE_PIN_ENABLED == true
*_triggerMode &= ~_triggerBit; // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin).
#endif
#if URM37_ENABLED == true
if (!(*_echoInput & _echoBit)) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (*_echoInput & _echoBit) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
#else
if (*_echoInput & _echoBit) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (!(*_echoInput & _echoBit)) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
#endif
#else
#if ONE_PIN_ENABLED == true
pinMode(_triggerPin, OUTPUT); // Set trigger pin to output.
#endif
digitalWrite(_triggerPin, LOW); // Set the trigger pin low, should already be low, but this will make sure it is.
delayMicroseconds(4); // Wait for pin to go low.
digitalWrite(_triggerPin, HIGH); // Set trigger pin high, this tells the sensor to send out a ping.
delayMicroseconds(10); // Wait long enough for the sensor to realize the trigger pin is high. Sensor specs say to wait 10uS.
digitalWrite(_triggerPin, LOW); // Set trigger pin back to low.
#if ONE_PIN_ENABLED == true
pinMode(_triggerPin, INPUT); // Set trigger pin to input (when using one Arduino pin, this is technically setting the echo pin to input as both are tied to the same Arduino pin).
#endif
#if URM37_ENABLED == true
if (!digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (digitalRead(_echoPin)) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
#else
if (digitalRead(_echoPin)) return false; // Previous ping hasn't finished, abort.
_max_time = micros() + _maxEchoTime + MAX_SENSOR_DELAY; // Maximum time we'll wait for ping to start (most sensors are <450uS, the SRF06 can take up to 34,300uS!)
while (!digitalRead(_echoPin)) // Wait for ping to start.
if (micros() > _max_time) return false; // Took too long to start, abort.
#endif
#endif
_max_time = micros() + _maxEchoTime; // Ping started, set the time-out.
return true; // Ping started successfully.
}
void NewPing::set_max_distance(unsigned int max_cm_distance) {
#if ROUNDING_ENABLED == false
_maxEchoTime = min(max_cm_distance + 1, (unsigned int) MAX_SENSOR_DISTANCE + 1) * US_ROUNDTRIP_CM; // Calculate the maximum distance in uS (no rounding).
#else
_maxEchoTime = min(max_cm_distance, (unsigned int) MAX_SENSOR_DISTANCE) * US_ROUNDTRIP_CM + (US_ROUNDTRIP_CM / 2); // Calculate the maximum distance in uS.
#endif
}
#if TIMER_ENABLED == true && DO_BITWISE == true
// ---------------------------------------------------------------------------
// Timer interrupt ping methods (won't work with non-AVR, ATmega128 and all ATtiny microcontrollers)
// ---------------------------------------------------------------------------
void NewPing::ping_timer(void (*userFunc)(void), unsigned int max_cm_distance) {
if (max_cm_distance > 0) set_max_distance(max_cm_distance); // Call function to set a new max sensor distance.
if (!ping_trigger()) return; // Trigger a ping, if it returns false, return without starting the echo timer.
timer_us(ECHO_TIMER_FREQ, userFunc); // Set ping echo timer check every ECHO_TIMER_FREQ uS.
}
boolean NewPing::check_timer() {
if (micros() > _max_time) { // Outside the time-out limit.
timer_stop(); // Disable timer interrupt
return false; // Cancel ping timer.
}
#if URM37_ENABLED == false
if (!(*_echoInput & _echoBit)) { // Ping echo received.
#else
if (*_echoInput & _echoBit) { // Ping echo received.
#endif
timer_stop(); // Disable timer interrupt
ping_result = (micros() - (_max_time - _maxEchoTime) - PING_TIMER_OVERHEAD); // Calculate ping time including overhead.
return true; // Return ping echo true.
}
return false; // Return false because there's no ping echo yet.
}
// ---------------------------------------------------------------------------
// Timer2/Timer4 interrupt methods (can be used for non-ultrasonic needs)
// ---------------------------------------------------------------------------
// Variables used for timer functions
void (*intFunc)();
void (*intFunc2)();
unsigned long _ms_cnt_reset;
volatile unsigned long _ms_cnt;
#if defined(__arm__) && defined(TEENSYDUINO)
IntervalTimer itimer;
#endif
void NewPing::timer_us(unsigned int frequency, void (*userFunc)(void)) {
intFunc = userFunc; // User's function to call when there's a timer event.
timer_setup(); // Configure the timer interrupt.
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
OCR4C = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit.
TIMSK4 = (1<<TOIE4); // Enable Timer4 interrupt.
#elif defined (__arm__) && defined (TEENSYDUINO) // Timer for Teensy 3.x
itimer.begin(userFunc, frequency); // Really simple on the Teensy 3.x, calls userFunc every 'frequency' uS.
#else
OCR2A = min((frequency>>2) - 1, 255); // Every count is 4uS, so divide by 4 (bitwise shift right 2) subtract one, then make sure we don't go over 255 limit.
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 interrupt.
#endif
}
void NewPing::timer_ms(unsigned long frequency, void (*userFunc)(void)) {
intFunc = NewPing::timer_ms_cntdwn; // Timer events are sent here once every ms till user's frequency is reached.
intFunc2 = userFunc; // User's function to call when user's frequency is reached.
_ms_cnt = _ms_cnt_reset = frequency; // Current ms counter and reset value.
timer_setup(); // Configure the timer interrupt.
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
OCR4C = 249; // Every count is 4uS, so 1ms = 250 counts - 1.
TIMSK4 = (1<<TOIE4); // Enable Timer4 interrupt.
#elif defined (__arm__) && defined (TEENSYDUINO) // Timer for Teensy 3.x
itimer.begin(NewPing::timer_ms_cntdwn, 1000); // Set timer to 1ms (1000 uS).
#else
OCR2A = 249; // Every count is 4uS, so 1ms = 250 counts - 1.
TIMSK2 |= (1<<OCIE2A); // Enable Timer2 interrupt.
#endif
}
void NewPing::timer_stop() { // Disable timer interrupt.
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
TIMSK4 = 0;
#elif defined (__arm__) && defined (TEENSYDUINO) // Timer for Teensy 3.x
itimer.end();
#else
TIMSK2 &= ~(1<<OCIE2A);
#endif
}
// ---------------------------------------------------------------------------
// Timer2/Timer4 interrupt method support functions (not called directly)
// ---------------------------------------------------------------------------
void NewPing::timer_setup() {
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
timer_stop(); // Disable Timer4 interrupt.
TCCR4A = TCCR4C = TCCR4D = TCCR4E = 0;
TCCR4B = (1<<CS42) | (1<<CS41) | (1<<CS40) | (1<<PSR4); // Set Timer4 prescaler to 64 (4uS/count, 4uS-1020uS range).
TIFR4 = (1<<TOV4);
TCNT4 = 0; // Reset Timer4 counter.
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__) // Alternate timer commands for certain microcontrollers.
timer_stop(); // Disable Timer2 interrupt.
ASSR &= ~(1<<AS2); // Set clock, not pin.
TCCR2 = (1<<WGM21 | 1<<CS22); // Set Timer2 to CTC mode, prescaler to 64 (4uS/count, 4uS-1020uS range).
TCNT2 = 0; // Reset Timer2 counter.
#elif defined (__arm__) && defined (TEENSYDUINO)
timer_stop(); // Stop the timer.
#else
timer_stop(); // Disable Timer2 interrupt.
ASSR &= ~(1<<AS2); // Set clock, not pin.
TCCR2A = (1<<WGM21); // Set Timer2 to CTC mode.
TCCR2B = (1<<CS22); // Set Timer2 prescaler to 64 (4uS/count, 4uS-1020uS range).
TCNT2 = 0; // Reset Timer2 counter.
#endif
}
void NewPing::timer_ms_cntdwn() {
if (!_ms_cnt--) { // Count down till we reach zero.
intFunc2(); // Scheduled time reached, run the main timer event function.
_ms_cnt = _ms_cnt_reset; // Reset the ms timer.
}
}
#if defined (__AVR_ATmega32U4__) // Use Timer4 for ATmega32U4 (Teensy/Leonardo).
ISR(TIMER4_OVF_vect) {
intFunc(); // Call wrapped function.
}
#elif defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__) // Alternate timer commands for certain microcontrollers.
ISR(TIMER2_COMP_vect) {
intFunc(); // Call wrapped function.
}
#elif defined (__arm__)
// Do nothing...
#else
ISR(TIMER2_COMPA_vect) {
intFunc(); // Call wrapped function.
}
#endif
#endif
// ---------------------------------------------------------------------------
// Conversion methods (rounds result to nearest cm or inch).
// ---------------------------------------------------------------------------
unsigned int NewPing::convert_cm(unsigned int echoTime) {
#if ROUNDING_ENABLED == false
return (echoTime / US_ROUNDTRIP_CM); // Convert uS to centimeters (no rounding).
#else
return NewPingConvert(echoTime, US_ROUNDTRIP_CM); // Convert uS to centimeters.
#endif
}
unsigned int NewPing::convert_in(unsigned int echoTime) {
#if ROUNDING_ENABLED == false
return (echoTime / US_ROUNDTRIP_IN); // Convert uS to inches (no rounding).
#else
return NewPingConvert(echoTime, US_ROUNDTRIP_IN); // Convert uS to inches.
#endif
}
+245
View File
@@ -0,0 +1,245 @@
// ---------------------------------------------------------------------------
// NewPing Library - v1.8 - 07/30/2016
//
// AUTHOR/LICENSE:
// Created by Tim Eckel - teckel@leethost.com
// Copyright 2016 License: GNU GPL v3 http://www.gnu.org/licenses/gpl.html
//
// LINKS:
// Project home: https://bitbucket.org/teckel12/arduino-new-ping/wiki/Home
// Blog: http://arduino.cc/forum/index.php/topic,106043.0.html
//
// DISCLAIMER:
// This software is furnished "as is", without technical support, and with no
// warranty, express or implied, as to its usefulness for any purpose.
//
// BACKGROUND:
// When I first received an ultrasonic sensor I was not happy with how poorly
// it worked. Quickly I realized the problem wasn't the sensor, it was the
// available ping and ultrasonic libraries causing the problem. The NewPing
// library totally fixes these problems, adds many new features, and breaths
// new life into these very affordable distance sensors.
//
// FEATURES:
// * Works with many different ultrasonic sensors: SR04, SRF05, SRF06, DYP-ME007, URM37 & Parallax PING))).
// * Compatible with the entire Arduino line-up (and clones), Teensy family (including $19 96Mhz 32 bit Teensy 3.2) and non-AVR microcontrollers.
// * Interface with all but the SRF06 sensor using only one Arduino pin.
// * Doesn't lag for a full second if no ping/echo is received.
// * Ping sensors consistently and reliably at up to 30 times per second.
// * Timer interrupt method for event-driven sketches.
// * Built-in digital filter method ping_median() for easy error correction.
// * Uses port registers for a faster pin interface and smaller code size.
// * Allows you to set a maximum distance where pings beyond that distance are read as no ping "clear".
// * Ease of using multiple sensors (example sketch with 15 sensors).
// * More accurate distance calculation (cm, inches & uS).
// * Doesn't use pulseIn, which is slow and gives incorrect results with some ultrasonic sensor models.
// * Actively developed with features being added and bugs/issues addressed.
//
// CONSTRUCTOR:
// NewPing sonar(trigger_pin, echo_pin [, max_cm_distance])
// trigger_pin & echo_pin - Arduino pins connected to sensor trigger and echo.
// NOTE: To use the same Arduino pin for trigger and echo, specify the same pin for both values.
// max_cm_distance - [Optional] Maximum distance you wish to sense. Default=500cm.
//
// METHODS:
// sonar.ping([max_cm_distance]) - Send a ping and get the echo time (in microseconds) as a result. [max_cm_distance] allows you to optionally set a new max distance.
// sonar.ping_in([max_cm_distance]) - Send a ping and get the distance in whole inches. [max_cm_distance] allows you to optionally set a new max distance.
// sonar.ping_cm([max_cm_distance]) - Send a ping and get the distance in whole centimeters. [max_cm_distance] allows you to optionally set a new max distance.
// sonar.ping_median(iterations [, max_cm_distance]) - Do multiple pings (default=5), discard out of range pings and return median in microseconds. [max_cm_distance] allows you to optionally set a new max distance.
// NewPing::convert_in(echoTime) - Convert echoTime from microseconds to inches (rounds to nearest inch).
// NewPing::convert_cm(echoTime) - Convert echoTime from microseconds to centimeters (rounds to nearest cm).
// sonar.ping_timer(function [, max_cm_distance]) - Send a ping and call function to test if ping is complete. [max_cm_distance] allows you to optionally set a new max distance.
// sonar.check_timer() - Check if ping has returned within the set distance limit.
// NewPing::timer_us(frequency, function) - Call function every frequency microseconds.
// NewPing::timer_ms(frequency, function) - Call function every frequency milliseconds.
// NewPing::timer_stop() - Stop the timer.
//
// HISTORY:
// 07/30/2016 v1.8 - Added support for non-AVR microcontrollers. For non-AVR
// microcontrollers, advanced ping_timer() timer methods are disabled due to
// inconsistencies or no support at all between platforms. However, standard
// ping methods are all supported. Added new optional variable to ping(),
// ping_in(), ping_cm(), ping_median(), and ping_timer() methods which allows
// you to set a new maximum distance for each ping. Added support for the
// ATmega16, ATmega32 and ATmega8535 microcontrollers. Changed convert_cm()
// and convert_in() methods to static members. You can now call them without
// an object. For example: cm = NewPing::convert_cm(distance);
//
// 09/29/2015 v1.7 - Removed support for the Arduino Due and Zero because
// they're both 3.3 volt boards and are not 5 volt tolerant while the HC-SR04
// is a 5 volt sensor. Also, the Due and Zero don't support pin manipulation
// compatibility via port registers which can be done (see the Teensy 3.2).
//
// 06/17/2014 v1.6 - Corrected delay between pings when using ping_median()
// method. Added support for the URM37 sensor (must change URM37_ENABLED from
// false to true). Added support for Arduino microcontrollers like the $20
// 32 bit ARM Cortex-M4 based Teensy 3.2. Added automatic support for the
// Atmel ATtiny family of microcontrollers. Added timer support for the
// ATmega8 microcontroller. Rounding disabled by default, reduces compiled
// code size (can be turned on with ROUNDING_ENABLED switch). Added
// TIMER_ENABLED switch to get around compile-time "__vector_7" errors when
// using the Tone library, or you can use the toneAC, NewTone or
// TimerFreeTone libraries: https://bitbucket.org/teckel12/arduino-toneac/
// Other speed and compiled size optimizations.
//
// 08/15/2012 v1.5 - Added ping_median() method which does a user specified
// number of pings (default=5) and returns the median ping in microseconds
// (out of range pings ignored). This is a very effective digital filter.
// Optimized for smaller compiled size (even smaller than sketches that
// don't use a library).
//
// 07/14/2012 v1.4 - Added support for the Parallax PING))) sensor. Interface
// with all but the SRF06 sensor using only one Arduino pin. You can also
// interface with the SRF06 using one pin if you install a 0.1uf capacitor
// on the trigger and echo pins of the sensor then tie the trigger pin to
// the Arduino pin (doesn't work with Teensy). To use the same Arduino pin
// for trigger and echo, specify the same pin for both values. Various bug
// fixes.
//
// 06/08/2012 v1.3 - Big feature addition, event-driven ping! Uses Timer2
// interrupt, so be mindful of PWM or timing conflicts messing with Timer2
// may cause (namely PWM on pins 3 & 11 on Arduino, PWM on pins 9 and 10 on
// Mega, and Tone library). Simple to use timer interrupt functions you can
// use in your sketches totally unrelated to ultrasonic sensors (don't use if
// you're also using NewPing's ping_timer because both use Timer2 interrupts).
// Loop counting ping method deleted in favor of timing ping method after
// inconsistent results kept surfacing with the loop timing ping method.
// Conversion to cm and inches now rounds to the nearest cm or inch. Code
// optimized to save program space and fixed a couple minor bugs here and
// there. Many new comments added as well as line spacing to group code
// sections for better source readability.
//
// 05/25/2012 v1.2 - Lots of code clean-up thanks to Arduino Forum members.
// Rebuilt the ping timing code from scratch, ditched the pulseIn code as it
// doesn't give correct results (at least with ping sensors). The NewPing
// library is now VERY accurate and the code was simplified as a bonus.
// Smaller and faster code as well. Fixed some issues with very close ping
// results when converting to inches. All functions now return 0 only when
// there's no ping echo (out of range) and a positive value for a successful
// ping. This can effectively be used to detect if something is out of range
// or in-range and at what distance. Now compatible with Arduino 0023.
//
// 05/16/2012 v1.1 - Changed all I/O functions to use low-level port registers
// for ultra-fast and lean code (saves from 174 to 394 bytes). Tested on both
// the Arduino Uno and Teensy 2.0 but should work on all Arduino-based
// platforms because it calls standard functions to retrieve port registers
// and bit masks. Also made a couple minor fixes to defines.
//
// 05/15/2012 v1.0 - Initial release.
// ---------------------------------------------------------------------------
#ifndef NewPing_h
#define NewPing_h
#if defined (ARDUINO) && ARDUINO >= 100
#include <Arduino.h>
#else
#include <WProgram.h>
#include <pins_arduino.h>
#endif
#if defined (__AVR__)
#include <avr/io.h>
#include <avr/interrupt.h>
#endif
// Shouldn't need to change these values unless you have a specific need to do so.
#define MAX_SENSOR_DISTANCE 500 // Maximum sensor distance can be as high as 500cm, no reason to wait for ping longer than sound takes to travel this distance and back. Default=500
#define US_ROUNDTRIP_CM 57 // Microseconds (uS) it takes sound to travel round-trip 1cm (2cm total), uses integer to save compiled code space. Default=57
#define US_ROUNDTRIP_IN 146 // Microseconds (uS) it takes sound to travel round-trip 1 inch (2 inches total), uses integer to save compiled code space. Defalult=146
#define ONE_PIN_ENABLED true // Set to "false" to disable one pin mode which saves around 14-26 bytes of binary size. Default=true
#define ROUNDING_ENABLED false // Set to "true" to enable distance rounding which also adds 64 bytes to binary size. Default=false
#define URM37_ENABLED false // Set to "true" to enable support for the URM37 sensor in PWM mode. Default=false
#define TIMER_ENABLED true // Set to "false" to disable the timer ISR (if getting "__vector_7" compile errors set this to false). Default=true
// Probably shouldn't change these values unless you really know what you're doing.
#define NO_ECHO 0 // Value returned if there's no ping echo within the specified MAX_SENSOR_DISTANCE or max_cm_distance. Default=0
#define MAX_SENSOR_DELAY 5800 // Maximum uS it takes for sensor to start the ping. Default=5800
#define ECHO_TIMER_FREQ 24 // Frequency to check for a ping echo (every 24uS is about 0.4cm accuracy). Default=24
#define PING_MEDIAN_DELAY 29000 // Microsecond delay between pings in the ping_median method. Default=29000
#define PING_OVERHEAD 5 // Ping overhead in microseconds (uS). Default=5
#define PING_TIMER_OVERHEAD 13 // Ping timer overhead in microseconds (uS). Default=13
#if URM37_ENABLED == true
#undef US_ROUNDTRIP_CM
#undef US_ROUNDTRIP_IN
#define US_ROUNDTRIP_CM 50 // Every 50uS PWM signal is low indicates 1cm distance. Default=50
#define US_ROUNDTRIP_IN 127 // If 50uS is 1cm, 1 inch would be 127uS (50 x 2.54 = 127). Default=127
#endif
// Conversion from uS to distance (round result to nearest cm or inch).
#define NewPingConvert(echoTime, conversionFactor) (max(((unsigned int)echoTime + conversionFactor / 2) / conversionFactor, (echoTime ? 1 : 0)))
// Detect non-AVR microcontrollers (Teensy 3.x, Arduino DUE, etc.) and don't use port registers or timer interrupts as required.
#if (defined (__arm__) && defined (TEENSYDUINO))
#undef PING_OVERHEAD
#define PING_OVERHEAD 1
#undef PING_TIMER_OVERHEAD
#define PING_TIMER_OVERHEAD 1
#define DO_BITWISE true
#elif !defined (__AVR__)
#undef PING_OVERHEAD
#define PING_OVERHEAD 1
#undef PING_TIMER_OVERHEAD
#define PING_TIMER_OVERHEAD 1
#undef TIMER_ENABLED
#define TIMER_ENABLED false
#define DO_BITWISE false
#else
#define DO_BITWISE true
#endif
// Disable the timer interrupts when using ATmega128 and all ATtiny microcontrollers.
#if defined (__AVR_ATmega128__) || defined (__AVR_ATtiny24__) || defined (__AVR_ATtiny44__) || defined (__AVR_ATtiny84__) || defined (__AVR_ATtiny25__) || defined (__AVR_ATtiny45__) || defined (__AVR_ATtiny85__) || defined (__AVR_ATtiny261__) || defined (__AVR_ATtiny461__) || defined (__AVR_ATtiny861__) || defined (__AVR_ATtiny43U__)
#undef TIMER_ENABLED
#define TIMER_ENABLED false
#endif
// Define timers when using ATmega8, ATmega16, ATmega32 and ATmega8535 microcontrollers.
#if defined (__AVR_ATmega8__) || defined (__AVR_ATmega16__) || defined (__AVR_ATmega32__) || defined (__AVR_ATmega8535__)
#define OCR2A OCR2
#define TIMSK2 TIMSK
#define OCIE2A OCIE2
#endif
class NewPing {
public:
NewPing(uint8_t trigger_pin, uint8_t echo_pin, unsigned int max_cm_distance = MAX_SENSOR_DISTANCE);
unsigned int ping(unsigned int max_cm_distance = 0);
unsigned long ping_cm(unsigned int max_cm_distance = 0);
unsigned long ping_in(unsigned int max_cm_distance = 0);
unsigned long ping_median(uint8_t it = 5, unsigned int max_cm_distance = 0);
static unsigned int convert_cm(unsigned int echoTime);
static unsigned int convert_in(unsigned int echoTime);
#if TIMER_ENABLED == true
void ping_timer(void (*userFunc)(void), unsigned int max_cm_distance = 0);
boolean check_timer();
unsigned long ping_result;
static void timer_us(unsigned int frequency, void (*userFunc)(void));
static void timer_ms(unsigned long frequency, void (*userFunc)(void));
static void timer_stop();
#endif
private:
boolean ping_trigger();
void set_max_distance(unsigned int max_cm_distance);
#if TIMER_ENABLED == true
boolean ping_trigger_timer(unsigned int trigger_delay);
boolean ping_wait_timer();
static void timer_setup();
static void timer_ms_cntdwn();
#endif
#if DO_BITWISE == true
uint8_t _triggerBit;
uint8_t _echoBit;
volatile uint8_t *_triggerOutput;
volatile uint8_t *_echoInput;
volatile uint8_t *_triggerMode;
#else
uint8_t _triggerPin;
uint8_t _echoPin;
#endif
unsigned int _maxEchoTime;
unsigned long _max_time;
};
#endif
+75
View File
@@ -0,0 +1,75 @@
// ---------------------------------------------------------------------------
// This example code was used to successfully communicate with 15 ultrasonic sensors. You can adjust
// the number of sensors in your project by changing SONAR_NUM and the number of NewPing objects in the
// "sonar" array. You also need to change the pins for each sensor for the NewPing objects. Each sensor
// is pinged at 33ms intervals. So, one cycle of all sensors takes 495ms (33 * 15 = 495ms). The results
// are sent to the "oneSensorCycle" function which currently just displays the distance data. Your project
// would normally process the sensor results in this function (for example, decide if a robot needs to
// turn and call the turn function). Keep in mind this example is event-driven. Your complete sketch needs
// to be written so there's no "delay" commands and the loop() cycles at faster than a 33ms rate. If other
// processes take longer than 33ms, you'll need to increase PING_INTERVAL so it doesn't get behind.
// ---------------------------------------------------------------------------
#include <NewPing.h>
#define SONAR_NUM 15 // Number of sensors.
#define MAX_DISTANCE 200 // Maximum distance (in cm) to ping.
#define PING_INTERVAL 33 // Milliseconds between sensor pings (29ms is about the min to avoid cross-sensor echo).
unsigned long pingTimer[SONAR_NUM]; // Holds the times when the next ping should happen for each sensor.
unsigned int cm[SONAR_NUM]; // Where the ping distances are stored.
uint8_t currentSensor = 0; // Keeps track of which sensor is active.
NewPing sonar[SONAR_NUM] = { // Sensor object array.
NewPing(41, 42, MAX_DISTANCE), // Each sensor's trigger pin, echo pin, and max distance to ping.
NewPing(43, 44, MAX_DISTANCE),
NewPing(45, 20, MAX_DISTANCE),
NewPing(21, 22, MAX_DISTANCE),
NewPing(23, 24, MAX_DISTANCE),
NewPing(25, 26, MAX_DISTANCE),
NewPing(27, 28, MAX_DISTANCE),
NewPing(29, 30, MAX_DISTANCE),
NewPing(31, 32, MAX_DISTANCE),
NewPing(34, 33, MAX_DISTANCE),
NewPing(35, 36, MAX_DISTANCE),
NewPing(37, 38, MAX_DISTANCE),
NewPing(39, 40, MAX_DISTANCE),
NewPing(50, 51, MAX_DISTANCE),
NewPing(52, 53, MAX_DISTANCE)
};
void setup() {
Serial.begin(115200);
pingTimer[0] = millis() + 75; // First ping starts at 75ms, gives time for the Arduino to chill before starting.
for (uint8_t i = 1; i < SONAR_NUM; i++) // Set the starting time for each sensor.
pingTimer[i] = pingTimer[i - 1] + PING_INTERVAL;
}
void loop() {
for (uint8_t i = 0; i < SONAR_NUM; i++) { // Loop through all the sensors.
if (millis() >= pingTimer[i]) { // Is it this sensor's time to ping?
pingTimer[i] += PING_INTERVAL * SONAR_NUM; // Set next time this sensor will be pinged.
if (i == 0 && currentSensor == SONAR_NUM - 1) oneSensorCycle(); // Sensor ping cycle complete, do something with the results.
sonar[currentSensor].timer_stop(); // Make sure previous timer is canceled before starting a new ping (insurance).
currentSensor = i; // Sensor being accessed.
cm[currentSensor] = 0; // Make distance zero in case there's no ping echo for this sensor.
sonar[currentSensor].ping_timer(echoCheck); // Do the ping (processing continues, interrupt will call echoCheck to look for echo).
}
}
// Other code that *DOESN'T* analyze ping results can go here.
}
void echoCheck() { // If ping received, set the sensor distance to array.
if (sonar[currentSensor].check_timer())
cm[currentSensor] = sonar[currentSensor].ping_result / US_ROUNDTRIP_CM;
}
void oneSensorCycle() { // Sensor ping cycle complete, do something with the results.
// The following code would be replaced with your code that does something with the ping results.
for (uint8_t i = 0; i < SONAR_NUM; i++) {
Serial.print(i);
Serial.print("=");
Serial.print(cm[i]);
Serial.print("cm ");
}
Serial.println();
}
@@ -0,0 +1,46 @@
// ---------------------------------------------------------------------------
// This example shows how to use NewPing's ping_timer method which uses the Timer2 interrupt to get the
// ping time. The advantage of using this method over the standard ping method is that it permits a more
// event-driven sketch which allows you to appear to do two things at once. An example would be to ping
// an ultrasonic sensor for a possible collision while at the same time navigating. This allows a
// properly developed sketch to multitask. Be aware that because the ping_timer method uses Timer2,
// other features or libraries that also use Timer2 would be effected. For example, the PWM function on
// pins 3 & 11 on Arduino Uno (pins 9 and 11 on Arduino Mega) and the Tone library. Note, only the PWM
// functionality of the pins is lost (as they use Timer2 to do PWM), the pins are still available to use.
// NOTE: For Teensy/Leonardo (ATmega32U4) the library uses Timer4 instead of Timer2.
// ---------------------------------------------------------------------------
#include <NewPing.h>
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on ping sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on ping sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
unsigned int pingSpeed = 50; // How frequently are we going to send out a ping (in milliseconds). 50ms would be 20 times a second.
unsigned long pingTimer; // Holds the next ping time.
void setup() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
pingTimer = millis(); // Start now.
}
void loop() {
// Notice how there's no delays in this sketch to allow you to do other processing in-line while doing distance pings.
if (millis() >= pingTimer) { // pingSpeed milliseconds since last ping, do another ping.
pingTimer += pingSpeed; // Set the next ping time.
sonar.ping_timer(echoCheck); // Send out the ping, calls "echoCheck" function every 24uS where you can check the ping status.
}
// Do other stuff here, really. Think of it as multi-tasking.
}
void echoCheck() { // Timer2 interrupt calls this function every 24uS where you can check the ping status.
// Don't do anything here!
if (sonar.check_timer()) { // This is how you check to see if the ping was received.
// Here's where you can add code.
Serial.print("Ping: ");
Serial.print(sonar.ping_result / US_ROUNDTRIP_CM); // Ping returned, uS result in ping_result, convert to cm with US_ROUNDTRIP_CM.
Serial.println("cm");
}
// Don't do anything here!
}
+22
View File
@@ -0,0 +1,22 @@
// ---------------------------------------------------------------------------
// Example NewPing library sketch that does a ping about 20 times per second.
// ---------------------------------------------------------------------------
#include <NewPing.h>
#define TRIGGER_PIN 12 // Arduino pin tied to trigger pin on the ultrasonic sensor.
#define ECHO_PIN 11 // Arduino pin tied to echo pin on the ultrasonic sensor.
#define MAX_DISTANCE 200 // Maximum distance we want to ping for (in centimeters). Maximum sensor distance is rated at 400-500cm.
NewPing sonar(TRIGGER_PIN, ECHO_PIN, MAX_DISTANCE); // NewPing setup of pins and maximum distance.
void setup() {
Serial.begin(115200); // Open serial monitor at 115200 baud to see ping results.
}
void loop() {
delay(50); // Wait 50ms between pings (about 20 pings/sec). 29ms should be the shortest delay between pings.
Serial.print("Ping: ");
Serial.print(sonar.ping_cm()); // Send ping, get distance in cm and print result (0 = outside set distance range)
Serial.println("cm");
}
+25
View File
@@ -0,0 +1,25 @@
// ---------------------------------------------------------------------------
// While the NewPing library's primary goal is to interface with ultrasonic sensors, interfacing with
// the Timer2 interrupt was a result of creating an interrupt-based ping method. Since these Timer2
// interrupt methods were built, the library may as well provide the functionality to use these methods
// in your sketches. This shows how simple it is (no ultrasonic sensor required). Keep in mind that
// these methods use Timer2, as does NewPing's ping_timer method for using ultrasonic sensors. You
// can't use ping_timer at the same time you're using timer_ms or timer_us as all use the same timer.
// ---------------------------------------------------------------------------
#include <NewPing.h>
#define LED_PIN 13 // Pin with LED attached.
void setup() {
pinMode(LED_PIN, OUTPUT);
NewPing::timer_ms(500, toggleLED); // Create a Timer2 interrupt that calls toggleLED in your sketch once every 500 milliseconds.
}
void loop() {
// Do anything here, the Timer2 interrupt will take care of the flashing LED without your intervention.
}
void toggleLED() {
digitalWrite(LED_PIN, !digitalRead(LED_PIN)); // Toggle the LED.
}
+29
View File
@@ -0,0 +1,29 @@
###################################
# Syntax Coloring Map For NewPing
###################################
###################################
# Datatypes (KEYWORD1)
###################################
NewPing KEYWORD1
###################################
# Methods and Functions (KEYWORD2)
###################################
ping KEYWORD2
ping_in KEYWORD2
ping_cm KEYWORD2
ping_median KEYWORD2
ping_timer KEYWORD2
check_timer KEYWORD2
timer_us KEYWORD2
timer_ms KEYWORD2
timer_stop KEYWORD2
convert_in KEYWORD2
convert_cm KEYWORD2
###################################
# Constants (LITERAL1)
###################################
+1
View File
@@ -31,6 +31,7 @@
#include "SensorSerialBuffer.h"
#include "ESPeasySoftwareSerial.h"
class CjkSDS011
{
public:
+488 -128
View File
@@ -7,11 +7,11 @@
#minimal version for esps with 512K or less flash (only has minimal plugin set)
; [env:mini_512]
; platform = espressif8266@1.5.0
; framework = arduino
; platform = ${common.platform}
; framework = ${common.framework}
; board = esp01
; upload_speed=460800
; build_flags = !echo -Wl,-Tesp8266.flash.512k64.ld -D BUILD_GIT=\'\"$(git describe)\"\'
; upload_speed = ${common.upload_speed}
; build_flags = !echo -Wl,-Tesp8266.flash.512k64.ld -D BUILD_GIT=\'\"$(git describe)\"\'
; # upload_port = /dev/ttyUSB0
# add these:
@@ -19,150 +19,510 @@
# -Wmissing-include-dirs -Wnoexcept -Wold-style-cast -Woverloaded-virtual -Wredundant-decls -Wshadow -Wsign-promo -Wstrict-null-sentinel
# -Wstrict-overflow=5 -Wundef -Wno-unused -Wno-variadic-macros -Wno-parentheses -fdiagnostics-show-option
# thanks @chouffe103
[compiler_warnings]
build_flags =
-Wall -Wno-parentheses -fdiagnostics-show-option
##########################################################################################
###### Definition cheat sheet:
# board_flash_mode in terms of performance: QIO > QOUT > DIO > DOUT
# for lib_ldf_mode, see http://docs.platformio.org/en/latest/librarymanager/ldf.html#ldf
###### Frequently used build flags:
# Use custom.h file to override default settings for ESPeasy: -D USE_CUSTOM_H
# Set VCC mode to measure Vcc of ESP chip : -D FEATURE_ADC_VCC=true
[core_2_3_0]
platform = espressif8266@1.5.0
[core_2_4_0]
platform = espressif8266@1.6.0
[core_staged]
platform = https://github.com/platformio/platform-espressif8266.git#feature/stage
[core_esp32]
#platform = espressif32@0.12.0
platform = https://github.com/platformio/platform-espressif32.git#feature/stage
build_flags = -D BUILD_GIT='"${env.TRAVIS_TAG}"'
lib_ignore = ESPeasySoftwareSerial, EspESPeasySoftwareSerial, AS_BH1750, ESP8266WiFi, ESP8266Ping, ESP8266WebServer, ESP8266HTTPUpdateServer, ESP8266mDNS, IRremoteESP8266, ESPEasy_ESP8266Ping, SerialSensors
lib_deps = ESP32WebServer
[common]
build_flags = -D BUILD_GIT='"${env.TRAVIS_TAG}"'
lib_deps = ""
build_flags = -D BUILD_GIT='"${env.TRAVIS_TAG}"' ; ${compiler_warnings.build_flags}
lib_deps = ""
lib_ignore = ESP32_ping, ESP32WebServer
lib_ldf_mode = chain
upload_speed = 460800
framework = arduino
board = esp12e
platform = ${core_2_4_0.platform}
[normal]
platform = ${common.platform}
[testing]
platform = ${core_2_4_0.platform}
[dev]
platform = ${core_2_4_0.platform}
#normal version with stable plugins, 1024k version
[esp8266_1M]
board_flash_mode = dout
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
[esp8285_1M]
board = esp8285
board_flash_mode = ${esp8266_1M.board_flash_mode}
build_flags = ${esp8266_1M.build_flags} -DESP8285
[Sonoff]
board = esp01_1m
board_flash_mode = ${esp8266_1M.board_flash_mode}
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
[espWroom2M]
board_flash_mode = dout
board = esp_wroom_02
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.2m.ld
[esp8266_4M]
board_flash_mode = dio
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld
### ESP32 pre-alpha test build ###########################################################
# Very limited build for ESP32, to start testing regular building for ESP32. #
# Will probably not work, not tested and guaranteed to take a few hours time of some #
# still trying to build the version without reading this warning. #
##########################################################################################
[env:esp32dev]
platform = ${core_esp32.platform}
board = esp32dev
build_flags = ${core_esp32.build_flags} -DPLUGIN_SET_GENERIC_ESP32
lib_deps = ${core_esp32.lib_deps}
lib_ignore = ${core_esp32.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
### NORMAL (STABLE) ######################################################################
# normal version with stable plugins #
##########################################################################################
# NORMAL: 1024k version --------------------------
[env:normal_ESP8266_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
# upload_port = /dev/ttyUSB0
platform = ${common.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board = ${common.board}
board_flash_mode = ${esp8266_1M.board_flash_mode}
build_flags = ${esp8266_1M.build_flags}
[env:normal_ESP8266_1024_DOUT]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld
# upload_port = /dev/ttyUSB0
#normal version with stable plugins, 4096k version
[env:normal_ESP8266_4096]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld
# upload_port = /dev/ttyUSB0
#normal version with stable plugins, 4096k version for esp8285
# NORMAL: 1024k for esp8285 ----------------------
[env:normal_ESP8285_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp8285
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -DESP8285
# upload_port = /dev/ttyUSB0
platform = ${common.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board = ${esp8285_1M.board}
board_flash_mode = ${esp8285_1M.board_flash_mode}
build_flags = ${esp8285_1M.build_flags}
# NORMAL: 2048k version --------------------------
[env:normal_WROOM02_2048]
platform = ${common.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board = ${espWroom2M.board}
board_flash_mode = ${espWroom2M.board_flash_mode}
build_flags = ${espWroom2M.build_flags}
# NORMAL: 4096k version --------------------------
[env:normal_ESP8266_4096]
platform = ${common.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board = ${common.board}
board_flash_mode = ${esp8266_4M.board_flash_mode}
build_flags = ${esp8266_4M.build_flags}
#version with additional plugins (and dependend code) that are in test-stadium 1024k
### TESTING ##############################################################################
# additional plugins (and dependend code) that are in test-stadium #
##########################################################################################
# TEST: 1024k version ----------------------------
[env:test_ESP8266_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING
platform = ${testing.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board = ${common.board}
board_flash_mode = ${esp8266_1M.board_flash_mode}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_TESTING
#version with additional plugins (and dependend code) that are in test-stadium 4096k
[env:test_ESP8266_4096]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING
[env:test_ESP8266_4096_VCC]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING -D FEATURE_ADC_VCC=true
#version with additional plugins (and dependend code) that are in test-stadium 4096k for esp8285
# TEST: 1024k for esp8285 ------------------------
[env:test_ESP8285_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp8285
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -DESP8285
platform = ${testing.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8285_1M.board_flash_mode}
board = ${esp8285_1M.board}
build_flags = ${esp8285_1M.build_flags} -D PLUGIN_BUILD_TESTING
# TEST: 2048k version ----------------------------
[env:test_WROOM02_2048]
platform = ${testing.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board_flash_mode = ${espWroom2M.board_flash_mode}
board = ${espWroom2M.board}
build_flags = ${espWroom2M.build_flags} -D PLUGIN_BUILD_TESTING
# TEST: 4096k version ----------------------------
[env:test_ESP8266_4096]
platform = ${testing.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
board = ${common.board}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8266_4M.board_flash_mode}
build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_TESTING
# TEST: 4096k version + FEATURE_ADC_VCC ----------
[env:test_ESP8266_4096_VCC]
platform = ${testing.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
board = ${common.board}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8266_4M.board_flash_mode}
build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_TESTING -D FEATURE_ADC_VCC=true
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 1024k
### DEV ##################################################################################
# additional plugins (and dependend code) that is in development (probably broken or incomplete)
##########################################################################################
# DEV : 1024k version ----------------------------
[env:dev_ESP8266_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV
platform = ${dev.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8266_1M.board_flash_mode}
board = ${common.board}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 4096k
[env:dev_ESP8266_4096]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 4096k
# Use latest ESP8266 core 2.4.0
[env:dev_ESP8266_4096_core2_4_0]
platform = espressif8266
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.4m1m.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV
#version with additional plugins (and dependend code) that is in development (probably broken or incomplete) 4096k for esp8285
# DEV: 1024k for esp8285 -------------------------
[env:dev_ESP8285_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp8285
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV -DESP8285
platform = ${dev.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8285_1M.board_flash_mode}
board = ${esp8285_1M.board}
build_flags = ${esp8285_1M.build_flags} -D PLUGIN_BUILD_DEV
# DEV: 2048k version -----------------------------
[env:dev_WROOM02_2048]
platform = ${dev.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
upload_speed = ${common.upload_speed}
board_flash_mode = ${espWroom2M.board_flash_mode}
board = ${espWroom2M.board}
build_flags = ${espWroom2M.build_flags} -D PLUGIN_BUILD_DEV
# DEV : 4096k version ----------------------------
[env:dev_ESP8266_4096]
platform = ${dev.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
board = ${common.board}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8266_4M.board_flash_mode}
build_flags = ${esp8266_4M.build_flags} -D PLUGIN_BUILD_DEV
#special patched version for PUYA flash chips, see https://github.com/letscontrolit/ESPEasy/issues/650
### DEV + PUYA ###########################################################################
# special patched version for PUYA flash chips, see issue #650 at Github #
##########################################################################################
# DEV+PUYA : 1024k version -----------------------
[env:dev_ESP8266PUYA_1024]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1
platform = ${dev.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
board = ${common.board}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8266_1M.board_flash_mode}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1
#special patched version for PUYA flash chips, see https://github.com/letscontrolit/ESPEasy/issues/650
# DEV+PUYA : 1024k version + FEATURE_ADC_VCC -----
[env:dev_ESP8266PUYA_1024_VCC]
platform = espressif8266@1.5.0
lib_deps = ${common.lib_deps}
board_flash_mode = dout
framework = arduino
board = esp12e
upload_speed=460800
build_flags = ${common.build_flags} -Wl,-Tesp8266.flash.1m128.ld -D PLUGIN_BUILD_TESTING -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1 -D FEATURE_ADC_VCC=true
platform = ${dev.platform}
lib_deps = ${common.lib_deps}
lib_ignore = ${common.lib_ignore}
lib_ldf_mode = ${common.lib_ldf_mode}
framework = ${common.framework}
board = ${common.board}
upload_speed = ${common.upload_speed}
board_flash_mode = ${esp8266_1M.board_flash_mode}
build_flags = ${esp8266_1M.build_flags} -D PLUGIN_BUILD_DEV -D FLASH_QUIRK_WRITE_0_TO_1 -D FEATURE_ADC_VCC=true
### HARDWARE SPECIFIC VERSIONS ###########################################################
# versions specially designed to fit, and contents only needed plugins for each hardware #
##########################################################################################
# ITEAD Products ################################
# ITEAD / SONOFF BASIC version ------------------
#[env:hard_SONOFF_BASIC]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_BASIC
# ITEAD / SONOFF TH10 version -------------------
#[env:hard_SONOFF_TH10]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_TH10
# ITEAD / SONOFF TH16 version -------------------
#[env:hard_SONOFF_TH16]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_TH16
# ITEAD / SONOFF POW version --------------------
#[env:hard_SONOFF_POW]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_POW
# ITEAD / SONOFF S20 version --------------------
#[env:hard_SONOFF_S20]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_S20
# ITEAD / SONOFF 4CH version --------------------
#[env:hard_SONOFF_4CH]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_4CH
# ITEAD / SONOFF TOUCH version ------------------
#[env:hard_SONOFF_TOUCH]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${Sonoff.board_flash_mode}
#board = ${Sonoff.board}
#build_flags = ${Sonoff.build_flags} -D PLUGIN_SET_SONOFF_TOUCH
# LED Strips #####################################
# Huacanxing / H801 ------------------------------
#[env:hard_HUACANXING_H801]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_H801
# MagicHome / Led Controller ---------------------
#[env:hard_MAGICHOME]
#upload_speed = ${common.upload_speed}
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_MAGICHOME
# MagicHome / Led Controller with IR -------------
#[env:hard_MAGICHOME_IR]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_MAGICHOME_IR
### EASY VERSIONS ########################################################################
# versions specially designed to be small and cover a specific usage #
##########################################################################################
# Easy Temperature Sensor ------------------------
#[env:easy_TEMP]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_EASY_TEMP
# Easy Carbon Sensor -----------------------------
#[env:easy_CARBON]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_EASY_CARBON
## Easy Nextion ----------------------------------
##PLUGIN_SET_EASY_NEXTION
# Easy OLED Display v1 ---------------------------
#[env:easy_OLED_V1]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_EASY_OLED1
# Easy OLED Display v2 ---------------------------
#[env:easy_OLED_V2]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_EASY_OLED2
# Easy Relay Switch ------------------------------
#[env:easy_OLED_V2]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_EASY_RELAY
# Easy Generic (1M) device ----------------------
#[env:easy_GENERIC_1M]
#upload_speed = ${common.upload_speed}
#framework = ${common.framework}
#platform = ${common.platform}
#lib_deps = ${common.lib_deps}
#lib_ignore = ${common.lib_ignore}
#lib_ldf_mode = ${common.lib_ldf_mode}
#board_flash_mode = ${esp8266_1M.board_flash_mode}
#board = esp01_1m
#build_flags = ${esp8266_1M.build_flags} -D PLUGIN_SET_GENERIC_1M
+306 -128
View File
@@ -38,31 +38,146 @@ bool safeReadStringUntil(Stream &input, String &str, char terminator, unsigned i
}
#define INPUT_COMMAND_SIZE 80
Command commandStringToEnum(const char * cmd) {
String tmpcmd;
tmpcmd = cmd;
tmpcmd.toLowerCase();
char cmd_lc[INPUT_COMMAND_SIZE];
tmpcmd.toCharArray(cmd_lc, tmpcmd.length() + 1);
switch (cmd_lc[0]) {
case 'a': {
if (strcmp_P(cmd_lc, PSTR("accessinfo") ) == 0) return cmd_accessinfo;
break;
}
case 'b': {
if (strcmp_P(cmd_lc, PSTR("background") ) == 0) return cmd_background;
else if (strcmp_P(cmd_lc, PSTR("blynkget") ) == 0) return cmd_BlynkGet;
else if (strcmp_P(cmd_lc, PSTR("build") ) == 0) return cmd_build;
break;
}
case 'c': {
if (strcmp_P(cmd_lc, PSTR("clearaccessblock") ) == 0) return cmd_clearaccessblock;
else if (strcmp_P(cmd_lc, PSTR("clearrtcram") ) == 0) return cmd_clearRTCRAM;
else if (strcmp_P(cmd_lc, PSTR("config") ) == 0) return cmd_config;
break;
}
case 'd': {
if (strcmp_P(cmd_lc, PSTR("debug") ) == 0) return cmd_Debug;
else if (strcmp_P(cmd_lc, PSTR("delay") ) == 0) return cmd_Delay;
else if (strcmp_P(cmd_lc, PSTR("deepsleep") ) == 0) return cmd_deepSleep;
break;
}
case 'e': {
if (strcmp_P(cmd_lc, PSTR("erase") ) == 0) return cmd_Erase;
else if (strcmp_P(cmd_lc, PSTR("event") ) == 0) return cmd_Event;
else if (strcmp_P(cmd_lc, PSTR("executerules") ) == 0) return cmd_executeRules;
break;
}
case 'i': {
if (strcmp_P(cmd_lc, PSTR("i2cscanner") ) == 0) return cmd_i2cscanner;
else if (strcmp_P(cmd_lc, PSTR("ip") ) == 0) return cmd_IP;
break;
}
case 'l': {
if (strcmp_P(cmd_lc, PSTR("load") ) == 0) return cmd_Load;
else if (strcmp_P(cmd_lc, PSTR("lowmem") ) == 0) return cmd_lowmem;
break;
}
case 'm': {
if (strcmp_P(cmd_lc, PSTR("malloc") ) == 0) return cmd_malloc;
else if (strcmp_P(cmd_lc, PSTR("meminfo") ) == 0) return cmd_meminfo;
break;
}
case 'n': {
if (strcmp_P(cmd_lc, PSTR("name") ) == 0) return cmd_Name;
else if (strcmp_P(cmd_lc, PSTR("notify") ) == 0) return cmd_notify;
else if (strcmp_P(cmd_lc, PSTR("nosleep") ) == 0) return cmd_NoSleep;
break;
}
case 'p': {
if (strcmp_P(cmd_lc, PSTR("password") ) == 0) return cmd_Password;
else if (strcmp_P(cmd_lc, PSTR("publish") ) == 0) return cmd_Publish;
break;
}
case 'r': {
if (strcmp_P(cmd_lc, PSTR("reboot") ) == 0) return cmd_Reboot;
else if (strcmp_P(cmd_lc, PSTR("reset") ) == 0) return cmd_Reset;
else if (strcmp_P(cmd_lc, PSTR("restart") ) == 0) return cmd_Restart;
else if (strcmp_P(cmd_lc, PSTR("resetflashwritecounter")) == 0) return cmd_resetFlashWriteCounter;
else if (strcmp_P(cmd_lc, PSTR("rules") ) == 0) return cmd_Rules;
break;
}
case 's': {
if (strcmp_P(cmd_lc, PSTR("sdcard") ) == 0) return cmd_sdcard;
else if (strcmp_P(cmd_lc, PSTR("sdremove") ) == 0) return cmd_sdremove;
else if (strcmp_P(cmd_lc, PSTR("sysload") ) == 0) return cmd_sysload;
else if (strcmp_P(cmd_lc, PSTR("save") ) == 0) return cmd_Save;
else if (strcmp_P(cmd_lc, PSTR("sendto") ) == 0) return cmd_SendTo;
else if (strcmp_P(cmd_lc, PSTR("sendtohttp") ) == 0) return cmd_SendToHTTP;
else if (strcmp_P(cmd_lc, PSTR("sendtoudp") ) == 0) return cmd_SendToUDP;
else if (strcmp_P(cmd_lc, PSTR("serialfloat") ) == 0) return cmd_SerialFloat;
else if (strcmp_P(cmd_lc, PSTR("settings") ) == 0) return cmd_Settings;
break;
}
case 't': {
if (strcmp_P(cmd_lc, PSTR("taskclear") ) == 0) return cmd_TaskClear;
else if (strcmp_P(cmd_lc, PSTR("taskclearall") ) == 0) return cmd_TaskClearAll;
else if (strcmp_P(cmd_lc, PSTR("taskrun") ) == 0) return cmd_TaskRun;
else if (strcmp_P(cmd_lc, PSTR("taskvalueset") ) == 0) return cmd_TaskValueSet;
else if (strcmp_P(cmd_lc, PSTR("timerset") ) == 0) return cmd_TimerSet;
break;
}
case 'u': {
if (strcmp_P(cmd_lc, PSTR("udptest") ) == 0) return cmd_udptest;
else if (strcmp_P(cmd_lc, PSTR("unit") ) == 0) return cmd_Unit;
break;
}
case 'w': {
if (strcmp_P(cmd_lc, PSTR("wdconfig") ) == 0) return cmd_wdconfig;
else if (strcmp_P(cmd_lc, PSTR("wdread") ) == 0) return cmd_wdread;
else if (strcmp_P(cmd_lc, PSTR("wifiapmode") ) == 0) return cmd_WifiAPMode;
else if (strcmp_P(cmd_lc, PSTR("wificonnect") ) == 0) return cmd_WifiConnect;
else if (strcmp_P(cmd_lc, PSTR("wifidisconnect") ) == 0) return cmd_WifiDisconnect;
else if (strcmp_P(cmd_lc, PSTR("wifikey2") ) == 0) return cmd_WifiKey2;
else if (strcmp_P(cmd_lc, PSTR("wifikey") ) == 0) return cmd_WifiKey;
else if (strcmp_P(cmd_lc, PSTR("wifissid2") ) == 0) return cmd_WifiSSID2;
else if (strcmp_P(cmd_lc, PSTR("wifissid") ) == 0) return cmd_WifiSSID;
else if (strcmp_P(cmd_lc, PSTR("wifiscan") ) == 0) return cmd_WifiScan;
break;
}
default:
return cmd_Unknown;
}
return cmd_Unknown;
}
void ExecuteCommand(byte source, const char *Line)
{
checkRAM(F("ExecuteCommand"));
String status = "";
boolean success = false;
char TmpStr1[80];
char TmpStr1[INPUT_COMMAND_SIZE];
TmpStr1[0] = 0;
char Command[80];
Command[0] = 0;
char cmd[INPUT_COMMAND_SIZE];
cmd[0] = 0;
int Par1 = 0;
int Par2 = 0;
int Par3 = 0;
GetArgv(Line, Command, 1);
GetArgv(Line, cmd, 1);
if (GetArgv(Line, TmpStr1, 2)) Par1 = str2int(TmpStr1);
if (GetArgv(Line, TmpStr1, 3)) Par2 = str2int(TmpStr1);
if (GetArgv(Line, TmpStr1, 4)) Par3 = str2int(TmpStr1);
const Command cmd_enum = commandStringToEnum(cmd);
switch (cmd_enum) {
// ****************************************
// commands for debugging
// ****************************************
if (strcasecmp_P(Command, PSTR("background")) == 0)
case cmd_background:
{
success = true;
unsigned long timer = millis() + Par1;
@@ -70,9 +185,10 @@ void ExecuteCommand(byte source, const char *Line)
while (!timeOutReached(timer))
backgroundtasks();
Serial.println("end");
break;
}
if (strcasecmp_P(Command, PSTR("executeRules")) == 0)
case cmd_executeRules:
{
success = true;
if (GetArgv(Line, TmpStr1, 2))
@@ -81,15 +197,17 @@ void ExecuteCommand(byte source, const char *Line)
String event = "";
rulesProcessingFile(fileName, event);
}
break;
}
if (strcasecmp_P(Command, PSTR("clearRTCRAM")) == 0)
case cmd_clearRTCRAM:
{
success = true;
initRTC();
break;
}
if (strcasecmp_P(Command, PSTR("notify")) == 0)
case cmd_notify:
{
success = true;
String message = "";
@@ -110,15 +228,17 @@ void ExecuteCommand(byte source, const char *Line)
}
}
}
break;
}
if (strcasecmp_P(Command, PSTR("resetFlashWriteCounter")) == 0)
case cmd_resetFlashWriteCounter:
{
success = true;
RTC.flashDayCounter = 0;
break;
}
if (strcasecmp_P(Command, PSTR("udptest")) == 0)
case cmd_udptest:
{
success = true;
for (byte x = 0; x < Par2; x++)
@@ -127,18 +247,20 @@ void ExecuteCommand(byte source, const char *Line)
event += x;
SendUDPCommand(Par1, (char*)event.c_str(), event.length());
}
break;
}
#ifdef FEATURE_SD
if (strcasecmp_P(Command, PSTR("sdcard")) == 0)
case cmd_sdcard:
{
success = true;
File root = SD.open("/");
root.rewindDirectory();
printDirectory(root, 0);
root.close();
break;
}
if (strcasecmp_P(Command, PSTR("sdremove")) == 0)
case cmd_sdremove:
{
success = true;
String fname = Line;
@@ -146,56 +268,63 @@ void ExecuteCommand(byte source, const char *Line)
Serial.print(F("Removing:"));
Serial.println(fname.c_str());
SD.remove((char*)fname.c_str());
break;
}
#endif
if (strcasecmp_P(Command, PSTR("lowmem")) == 0)
case cmd_lowmem:
{
Serial.print(lowestRAM);
Serial.print(F(" : "));
Serial.println(lowestRAMfunction);
success = true;
break;
}
if (strcasecmp_P(Command, PSTR("malloc")) == 0)
case cmd_malloc:
{
ramtest = (char *)malloc(Par1);
success = true;
break;
}
if (strcasecmp_P(Command, PSTR("sysload")) == 0)
case cmd_sysload:
{
success = true;
Serial.print(100 - (100 * loopCounterLast / loopCounterMax));
Serial.print(F("% (LC="));
Serial.print(int(loopCounterLast / 30));
Serial.println(F(")"));
break;
}
if (strcasecmp_P(Command, PSTR("SerialFloat")) == 0)
case cmd_SerialFloat:
{
success = true;
pinMode(1, INPUT);
pinMode(3, INPUT);
delay(60000);
break;
}
if (strcasecmp_P(Command, PSTR("accessinfo")) == 0)
case cmd_accessinfo:
{
success = true;
Serial.print(F("Allowed IP range : "));
Serial.println(describeAllowedIPrange());
break;
}
if (strcasecmp_P(Command, PSTR("clearaccessblock")) == 0)
case cmd_clearaccessblock:
{
success = true;
clearAccessBlock();
Serial.print(F("Allowed IP range : "));
Serial.println(describeAllowedIPrange());
break;
}
if (strcasecmp_P(Command, PSTR("meminfo")) == 0)
case cmd_meminfo:
{
success = true;
Serial.print(F("SecurityStruct : "));
@@ -206,32 +335,36 @@ void ExecuteCommand(byte source, const char *Line)
Serial.println(sizeof(ExtraTaskSettings));
Serial.print(F("DeviceStruct: "));
Serial.println(sizeof(Device));
break;
}
if (strcasecmp_P(Command, PSTR("TaskClear")) == 0)
case cmd_TaskClear:
{
success = true;
taskClear(Par1 - 1, true);
break;
}
//quickly clear all tasks, without saving (used by test suite)
if (strcasecmp_P(Command, PSTR("TaskClearAll")) == 0)
case cmd_TaskClearAll:
{
success = true;
for (byte t=0; t<TASKS_MAX; t++)
taskClear(t, false);
break;
}
if (strcasecmp_P(Command, PSTR("wdconfig")) == 0)
case cmd_wdconfig:
{
success = true;
Wire.beginTransmission(Par1); // address
Wire.write(Par2); // command
Wire.write(Par3); // data
Wire.endTransmission();
break;
}
if (strcasecmp_P(Command, PSTR("wdread")) == 0)
case cmd_wdread:
{
success = true;
Wire.beginTransmission(Par1); // address
@@ -245,22 +378,25 @@ void ExecuteCommand(byte source, const char *Line)
status = F("Reg value: ");
status += value;
}
break;
}
if (strcasecmp_P(Command, PSTR("build")) == 0)
case cmd_build:
{
success = true;
Settings.Build = Par1;
SaveSettings();
break;
}
if (strcasecmp_P(Command, PSTR("NoSleep")) == 0)
case cmd_NoSleep:
{
success = true;
Settings.deepSleep = 0;
break;
}
if (strcasecmp_P(Command, PSTR("i2cscanner")) == 0)
case cmd_i2cscanner:
{
success = true;
@@ -280,28 +416,31 @@ void ExecuteCommand(byte source, const char *Line)
Serial.println(String(address, HEX));
}
}
break;
}
// ****************************************
// commands for rules
// ****************************************
if (strcasecmp_P(Command, PSTR("config")) == 0)
case cmd_config:
{
success = true;
struct EventStruct TempEvent;
String request = Line;
remoteConfig(&TempEvent, request);
break;
}
if (strcasecmp_P(Command, PSTR("deepSleep")) == 0)
case cmd_deepSleep:
{
success = true;
if (Par1 > 0)
deepSleepStart(Par1); // call the second part of the function to avoid check and enable one-shot operation
break;
}
if (strcasecmp_P(Command, PSTR("TaskValueSet")) == 0)
case cmd_TaskValueSet:
{
success = true;
if (GetArgv(Line, TmpStr1, 4))
@@ -310,15 +449,17 @@ void ExecuteCommand(byte source, const char *Line)
Calculate(TmpStr1, &result);
UserVar[(VARS_PER_TASK * (Par1 - 1)) + Par2 - 1] = result;
}
break;
}
if (strcasecmp_P(Command, PSTR("TaskRun")) == 0)
case cmd_TaskRun:
{
success = true;
SensorSendTask(Par1 - 1);
break;
}
if (strcasecmp_P(Command, PSTR("TimerSet")) == 0)
case cmd_TimerSet:
{
if (Par1>=1 && Par1<=RULES_TIMER_MAX)
{
@@ -334,24 +475,27 @@ void ExecuteCommand(byte source, const char *Line)
{
addLog(LOG_LEVEL_ERROR, F("TIMER: invalid timer number"));
}
break;
}
if (strcasecmp_P(Command, PSTR("Delay")) == 0)
case cmd_Delay:
{
success = true;
delayBackground(Par1);
break;
}
if (strcasecmp_P(Command, PSTR("Rules")) == 0)
case cmd_Rules:
{
success = true;
if (Par1 == 1)
Settings.UseRules = true;
else
Settings.UseRules = false;
break;
}
if (strcasecmp_P(Command, PSTR("Event")) == 0)
case cmd_Event:
{
success = true;
String event = Line;
@@ -359,9 +503,10 @@ void ExecuteCommand(byte source, const char *Line)
event.replace("$", "#");
if (Settings.UseRules)
rulesProcessing(event);
break;
}
if (strcasecmp_P(Command, PSTR("SendTo")) == 0)
case cmd_SendTo:
{
success = true;
String event = Line;
@@ -372,78 +517,88 @@ void ExecuteCommand(byte source, const char *Line)
event = event.substring(index + 1);
SendUDPCommand(Par1, (char*)event.c_str(), event.length());
}
break;
}
if (strcasecmp_P(Command, PSTR("Publish")) == 0 && WiFi.status() == WL_CONNECTED)
case cmd_Publish:
{
// ToDo TD-er: Not sure about this function, but at least it sends to an existing MQTTclient
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
// ToDo TD-er: Not sure about this function, but at least it sends to an existing MQTTclient
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
success = true;
String event = Line;
event = event.substring(8);
int index = event.indexOf(',');
if (index > 0)
{
String topic = event.substring(0, index);
String value = event.substring(index + 1);
MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), Settings.MQTTRetainFlag);
}
}
}
break;
}
case cmd_SendToUDP:
{
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
success = true;
String event = Line;
event = event.substring(8);
int index = event.indexOf(',');
if (index > 0)
String strLine = Line;
String ip = parseString(strLine, 2);
String port = parseString(strLine, 3);
int msgpos = getParamStartPos(strLine, 4);
String message = strLine.substring(msgpos);
IPAddress UDP_IP;
if(UDP_IP.fromString(ip)) {
portUDP.beginPacket(UDP_IP, port.toInt());
#if defined(ESP8266)
portUDP.write(message.c_str(), message.length());
#endif
#if defined(ESP32)
portUDP.write((uint8_t*)message.c_str(), message.length());
#endif
portUDP.endPacket();
}
}
break;
}
case cmd_SendToHTTP:
{
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
success = true;
String strLine = Line;
String host = parseString(strLine, 2);
String port = parseString(strLine, 3);
int pathpos = getParamStartPos(strLine, 4);
String path = strLine.substring(pathpos);
WiFiClient client;
if (client.connect(host.c_str(), port.toInt()))
{
String topic = event.substring(0, index);
String value = event.substring(index + 1);
MQTTpublish(enabledMqttController, topic.c_str(), value.c_str(), Settings.MQTTRetainFlag);
client.print(String("GET ") + path + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timer = millis() + 200;
while (!client.available() && !timeOutReached(timer))
delay(1);
while (client.available()) {
// String line = client.readStringUntil('\n');
String line;
safeReadStringUntil(client, line, '\n');
if (line.substring(0, 15) == F("HTTP/1.1 200 OK"))
addLog(LOG_LEVEL_DEBUG, line);
delay(1);
}
client.flush();
client.stop();
}
}
}
if (strcasecmp_P(Command, PSTR("SendToUDP")) == 0 && WiFi.status() == WL_CONNECTED)
{
success = true;
String strLine = Line;
String ip = parseString(strLine, 2);
String port = parseString(strLine, 3);
int msgpos = getParamStartPos(strLine, 4);
String message = strLine.substring(msgpos);
IPAddress UDP_IP;
if(UDP_IP.fromString(ip)) {
portUDP.beginPacket(UDP_IP, port.toInt());
#if defined(ESP8266)
portUDP.write(message.c_str(), message.length());
#endif
#if defined(ESP32)
portUDP.write((uint8_t*)message.c_str(), message.length());
#endif
portUDP.endPacket();
}
}
if (strcasecmp_P(Command, PSTR("SendToHTTP")) == 0 && WiFi.status() == WL_CONNECTED)
{
success = true;
String strLine = Line;
String host = parseString(strLine, 2);
String port = parseString(strLine, 3);
int pathpos = getParamStartPos(strLine, 4);
String path = strLine.substring(pathpos);
WiFiClient client;
if (client.connect(host.c_str(), port.toInt()))
{
client.print(String("GET ") + path + " HTTP/1.1\r\n" +
"Host: " + host + "\r\n" +
"Connection: close\r\n\r\n");
unsigned long timer = millis() + 200;
while (!client.available() && !timeOutReached(timer))
delay(1);
while (client.available()) {
// String line = client.readStringUntil('\n');
String line;
safeReadStringUntil(client, line, '\n');
if (line.substring(0, 15) == F("HTTP/1.1 200 OK"))
addLog(LOG_LEVEL_DEBUG, line);
delay(1);
}
client.flush();
client.stop();
}
break;
}
// ****************************************
@@ -452,7 +607,7 @@ void ExecuteCommand(byte source, const char *Line)
#ifdef CPLUGIN_012
//FIXME: this should go to PLUGIN_WRITE in _C012.ino
if (strcasecmp_P(Command, PSTR("BlynkGet")) == 0)
case cmd_BlynkGet:
{
byte first_enabled_blynk_controller = firstEnabledBlynkController();
if (first_enabled_blynk_controller == -1) {
@@ -481,80 +636,91 @@ void ExecuteCommand(byte source, const char *Line)
}
}
}
break;
}
#endif
// ****************************************
// configure settings commands
// ****************************************
if (strcasecmp_P(Command, PSTR("WifiSSID")) == 0)
case cmd_WifiSSID:
{
success = true;
strcpy(SecuritySettings.WifiSSID, Line + 9);
break;
}
if (strcasecmp_P(Command, PSTR("WifiKey")) == 0)
case cmd_WifiKey:
{
success = true;
strcpy(SecuritySettings.WifiKey, Line + 8);
break;
}
if (strcasecmp_P(Command, PSTR("WifiSSID2")) == 0)
case cmd_WifiSSID2:
{
success = true;
strcpy(SecuritySettings.WifiSSID2, Line + 10);
break;
}
if (strcasecmp_P(Command, PSTR("WifiKey2")) == 0)
case cmd_WifiKey2:
{
success = true;
strcpy(SecuritySettings.WifiKey2, Line + 9);
break;
}
if (strcasecmp_P(Command, PSTR("WifiScan")) == 0)
case cmd_WifiScan:
{
success = true;
WifiScan();
break;
}
if (strcasecmp_P(Command, PSTR("WifiConnect")) == 0)
case cmd_WifiConnect:
{
success = true;
WifiConnect(1);
setWifiState(WifiTryConnect);
break;
}
if (strcasecmp_P(Command, PSTR("WifiDisconnect")) == 0)
case cmd_WifiDisconnect:
{
success = true;
WifiDisconnect();
break;
}
if (strcasecmp_P(Command, PSTR("WifiAPMode")) == 0)
case cmd_WifiAPMode:
{
WifiAPMode(true);
setWifiState(WifiEnableAP);
success = true;
break;
}
if (strcasecmp_P(Command, PSTR("Unit")) == 0)
case cmd_Unit:
{
success = true;
Settings.Unit=Par1;
break;
}
if (strcasecmp_P(Command, PSTR("Name")) == 0)
case cmd_Name:
{
success = true;
strcpy(Settings.Name, Line + 5);
break;
}
if (strcasecmp_P(Command, PSTR("Password")) == 0)
case cmd_Password:
{
success = true;
strcpy(SecuritySettings.Password, Line + 9);
break;
}
if (strcasecmp_P(Command, PSTR("Reboot")) == 0)
case cmd_Reboot:
{
success = true;
pinMode(0, INPUT);
@@ -566,22 +732,26 @@ void ExecuteCommand(byte source, const char *Line)
#if defined(ESP32)
ESP.restart();
#endif
break;
}
if (strcasecmp_P(Command, PSTR("Restart")) == 0)
case cmd_Restart:
{
success = true;
ESP.restart();
break;
}
if (strcasecmp_P(Command, PSTR("Erase")) == 0)
case cmd_Erase:
{
success = true;
WiFi.persistent(true); // use SDK storage of SSID/WPA parameters
WiFi.disconnect(); // this will store empty ssid/wpa into sdk storage
WifiDisconnect(); // this will store empty ssid/wpa into sdk storage
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
break;
}
if (strcasecmp_P(Command, PSTR("Reset")) == 0)
case cmd_Reset:
{
success = true;
ResetFactory();
@@ -591,37 +761,41 @@ void ExecuteCommand(byte source, const char *Line)
#if defined(ESP32)
ESP.restart();
#endif
break;
}
if (strcasecmp_P(Command, PSTR("Save")) == 0)
case cmd_Save:
{
success = true;
SaveSettings();
break;
}
if (strcasecmp_P(Command, PSTR("Load")) == 0)
case cmd_Load:
{
success = true;
LoadSettings();
break;
}
if (strcasecmp_P(Command, PSTR("Debug")) == 0)
case cmd_Debug:
{
success = true;
Settings.SerialLogLevel = Par1;
break;
}
if (strcasecmp_P(Command, PSTR("IP")) == 0)
case cmd_IP:
{
success = true;
if (GetArgv(Line, TmpStr1, 2)) {
if (!str2ip(TmpStr1, Settings.IP))
Serial.println("?");
}
break;
}
if (strcasecmp_P(Command, PSTR("Settings")) == 0)
case cmd_Settings:
{
success = true;
char str[20];
@@ -639,6 +813,10 @@ void ExecuteCommand(byte source, const char *Line)
Serial.print(F(" WifiSSID2 : ")); Serial.println(SecuritySettings.WifiSSID2);
Serial.print(F(" WifiKey2 : ")); Serial.println(SecuritySettings.WifiKey2);
Serial.print(F(" Free mem : ")); Serial.println(FreeMem());
break;
}
default:
success = false;
}
yield();
+13 -11
View File
@@ -92,11 +92,11 @@ void callback(char* c_topic, byte* b_payload, unsigned int length) {
String log;
log=F("MQTT : Topic: ");
log+=c_topic;
addLog(LOG_LEVEL_DEBUG, log);
addLog(LOG_LEVEL_DEBUG_MORE, log);
log=F("MQTT : Payload: ");
log+=c_payload;
addLog(LOG_LEVEL_DEBUG, log);
addLog(LOG_LEVEL_DEBUG_MORE, log);
// sprintf_P(log, PSTR("%s%s"), "MQTT : Topic: ", c_topic);
// addLog(LOG_LEVEL_DEBUG, log);
@@ -120,8 +120,10 @@ bool MQTTConnect(int controller_idx)
LoadControllerSettings(controller_idx, (byte*)&ControllerSettings, sizeof(ControllerSettings));
if (!ControllerSettings.checkHostReachable(true))
return false;
if (MQTTclient.connected())
if (MQTTclient.connected()) {
MQTTclient.disconnect();
updateMQTTclient_connected();
}
if (ControllerSettings.UseDNS) {
MQTTclient.setServer(ControllerSettings.getHost().c_str(), ControllerSettings.Port);
} else {
@@ -166,11 +168,7 @@ bool MQTTConnect(int controller_idx)
addLog(LOG_LEVEL_INFO, log);
if (MQTTclient.publish(LWTTopic.c_str(), "Connected", 1)) {
if (Settings.UseRules)
{
String event = F("MQTT#Connected");
rulesProcessing(event);
}
updateMQTTclient_connected();
statusLED(true);
return true; // end loop if succesfull
}
@@ -183,15 +181,17 @@ bool MQTTConnect(int controller_idx)
\*********************************************************************************************/
bool MQTTCheck(int controller_idx)
{
if (!WiFiConnected(10)) {
return false;
}
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[controller_idx]);
if (Protocol[ProtocolIndex].usesMQTT)
{
if (MQTTclient_should_reconnect || !WiFiConnected(10) || !MQTTclient.connected())
if (MQTTclient_should_reconnect || !MQTTclient.connected())
{
if (MQTTclient_should_reconnect) {
addLog(LOG_LEVEL_ERROR, F("MQTT : Intentional reconnect"));
} else {
addLog(LOG_LEVEL_ERROR, F("MQTT : Connection lost"));
connectionFailures += 2;
}
return MQTTConnect(controller_idx);
@@ -227,8 +227,10 @@ void SendStatus(byte source, String status)
boolean MQTTpublish(int controller_idx, const char* topic, const char* payload, boolean retained)
{
if (MQTTclient.publish(topic, payload, retained))
if (MQTTclient.publish(topic, payload, retained)) {
timermqtt = millis() + 10; // Make sure the MQTT is being processed as soon as possible.
return true;
}
addLog(LOG_LEVEL_DEBUG, F("MQTT : publish failed"));
return false;
}
+35 -1
View File
@@ -84,6 +84,14 @@ String minutesToDayHour(int minutes) {
return TimeString;
}
String minutesToHourMinute(int minutes) {
int hours = (minutes % 1440) / 60;
int mins = (minutes % 1440) % 60;
char TimeString[20];
sprintf_P(TimeString, PSTR("%d%c%02d%c"), hours, 'h', mins, 'm');
return TimeString;
}
String minutesToDayHourMinute(int minutes) {
int days = minutes / 1440;
int hours = (minutes % 1440) / 60;
@@ -104,7 +112,33 @@ String secondsToDayHourMinuteSecond(int seconds) {
return TimeString;
}
String format_msec_duration(long duration) {
String result;
if (duration < 0) {
result = "-";
duration = -1 * duration;
}
if (duration < 10000) {
result += duration;
result += F(" ms");
return result;
}
duration /= 1000;
if (duration < 3600) {
int sec = duration % 60;
int minutes = duration / 60;
if (minutes > 0) {
result += minutes;
result += F(" m ");
}
result += sec;
result += F(" s");
return result;
}
duration /= 60;
if (duration < 1440) return minutesToHourMinute(duration);
return minutesToDayHourMinute(duration);
}
/********************************************************************************************\
+183 -7
View File
@@ -16,7 +16,8 @@
#define DEFAULT_DELAY 60 // Sleep Delay in seconds
// --- Wifi AP Mode (when your Wifi Network is not reachable) ----------------------------------------
#define DEFAULT_AP_IP 192,168,4,1 // Enter IP address (comma separated) for AP (config) mode
#define DEFAULT_AP_IP 192,168,4,1 // Enter IP address (comma separated) for AP (config) mode
#define DEFAULT_AP_SUBNET 255,255,255,0 // Enter IP address (comma separated) for AP (config) mode
#define DEFAULT_AP_KEY "configesp" // Enter network WPA key for AP (config) mode
// --- Wifi Client Mode -----------------------------------------------------------------------------
@@ -32,6 +33,8 @@
#define DEFAULT_IPRANGE_HIGH "255.255.255.255" // Allowed IP range to access webserver
#define DEFAULT_IP_BLOCK_LEVEL 1 // 0: ALL_ALLOWED 1: LOCAL_SUBNET_ALLOWED 2: ONLY_IP_RANGE_ALLOWED
#define DEFAULT_WIFI_CONNECTION_TIMEOUT 10000 // minimum timeout in ms for WiFi to be connected.
// --- Default Controller ------------------------------------------------------------------------------
#define DEFAULT_CONTROLLER false // true or false enabled or disabled, set 1st controller defaults
// using a default template, you also need to set a DEFAULT PROTOCOL to a suitable MQTT protocol !
@@ -53,6 +56,10 @@
// --- Advanced Settings ---------------------------------------------------------------------------------
#if defined(ESP32)
#define USE_RTOS_MULTITASKING
#endif
#define DEFAULT_USE_RULES false // (true|false) Enable Rules?
#define DEFAULT_MQTT_RETAIN false // (true|false) Retain MQTT messages?
@@ -147,7 +154,7 @@
#define VERSION 3 // Change in config.dat mapping needs a full reset
#endif
#define BUILD 20100 // git version 2.1.0
#define BUILD 20101 // git version 2.1.01
#if defined(ESP8266)
#define BUILD_NOTES " - Mega"
#endif
@@ -233,9 +240,9 @@
#define CMD_WIFI_DISCONNECT 135
#if defined(PLUGIN_BUILD_TESTING) || defined(PLUGIN_BUILD_DEV)
#define DEVICES_MAX 72
#define DEVICES_MAX 75
#else
#define DEVICES_MAX 64
#define DEVICES_MAX 50
#endif
#if defined(ESP8266)
@@ -432,11 +439,26 @@ using namespace fs;
ADC_MODE(ADC_VCC);
#endif
#define ESPEASY_WIFI_DISCONNECTED 0
#define ESPEASY_WIFI_CONNECTED 1
#define ESPEASY_WIFI_GOT_IP 2
#define ESPEASY_WIFI_SERVICES_INITIALIZED 3
#if defined(ESP32)
void WiFiEvent(system_event_id_t event, system_event_info_t info);
#else
WiFiEventHandler stationConnectedHandler;
WiFiEventHandler stationDisconnectedHandler;
WiFiEventHandler stationGotIpHandler;
WiFiEventHandler APModeStationConnectedHandler;
WiFiEventHandler APModeStationDisconnectedHandler;
#endif
// Setup DNS, only used if the ESP has no valid WiFi config
const byte DNS_PORT = 53;
IPAddress apIP(DEFAULT_AP_IP);
DNSServer dnsServer;
bool dnsServerActive = false;
#ifdef FEATURE_MDNS
MDNSResponder mdns;
#endif
@@ -445,6 +467,7 @@ MDNSResponder mdns;
WiFiClient mqtt;
PubSubClient MQTTclient(mqtt);
bool MQTTclient_should_reconnect = true;
bool MQTTclient_connected = false;
// udp protocol stuff (syslog, global sync, node info list, ntp time)
WiFiUDP portUDP;
@@ -459,7 +482,68 @@ struct CRCStruct{
uint32_t numberOfCRCBytes=0;
}CRCValues;
enum Command {
cmd_Unknown,
cmd_accessinfo,
cmd_background,
cmd_BlynkGet,
cmd_build,
cmd_clearaccessblock,
cmd_clearRTCRAM,
cmd_config,
cmd_Debug,
cmd_Delay,
cmd_deepSleep,
cmd_Erase,
cmd_Event,
cmd_executeRules,
cmd_i2cscanner,
cmd_IP,
cmd_Load,
cmd_lowmem,
cmd_malloc,
cmd_meminfo,
cmd_Name,
cmd_notify,
cmd_NoSleep,
cmd_Password,
cmd_Publish,
cmd_Reboot,
cmd_Reset,
cmd_Restart,
cmd_resetFlashWriteCounter,
cmd_Rules,
cmd_sdcard,
cmd_sdremove,
cmd_sysload,
cmd_Save,
cmd_SendTo,
cmd_SendToHTTP,
cmd_SendToUDP,
cmd_SerialFloat,
cmd_Settings,
cmd_TaskClear,
cmd_TaskClearAll,
cmd_TaskRun,
cmd_TaskValueSet,
cmd_TimerSet,
cmd_udptest,
cmd_Unit,
cmd_wdconfig,
cmd_wdread,
cmd_WifiAPMode,
cmd_WifiConnect,
cmd_WifiDisconnect,
cmd_WifiKey2,
cmd_WifiKey,
cmd_WifiSSID2,
cmd_WifiSSID,
cmd_WifiScan
};
// Forward declarations.
Command commandStringToEnum(const char * cmd);
bool WiFiConnected(uint32_t timeout_ms);
bool hostReachable(const IPAddress& ip);
bool hostReachable(const String& hostname);
@@ -491,6 +575,7 @@ struct SecurityStruct
byte AllowedIPrangeLow[4]; // TD-er: Use these
byte AllowedIPrangeHigh[4];
byte IPblockLevel;
//its safe to extend this struct, up to 4096 bytes, default values in config are 0. Make sure crc is last
uint8_t ProgmemMd5[16]; // crc of the binary that last saved the struct to file.
uint8_t md5[16];
@@ -612,6 +697,9 @@ struct SettingsStruct
boolean ArduinoOTAEnable;
uint16_t DST_Start;
uint16_t DST_End;
boolean UseRTOSMultitasking;
int8_t Pin_Reset;
//its safe to extend this struct, up to several bytes, default values in config are 0
//look in misc.ino how config.dat is used because also other stuff is stored in it at different offsets.
@@ -814,7 +902,11 @@ struct EventStruct
};
#define LOG_STRUCT_MESSAGE_SIZE 128
#define LOG_STRUCT_MESSAGE_LINES 20
#if defined(PLUGIN_BUILD_TESTING) || defined(PLUGIN_BUILD_DEV)
#define LOG_STRUCT_MESSAGE_LINES 10
#else
#define LOG_STRUCT_MESSAGE_LINES 15
#endif
struct LogStruct {
LogStruct() : write_idx(0), read_idx(0) {
@@ -1043,15 +1135,92 @@ String dummyString = "";
byte lastBootCause = BOOT_CAUSE_MANUAL_REBOOT;
#if defined(ESP32)
enum WiFiDisconnectReason
{
WIFI_DISCONNECT_REASON_UNSPECIFIED = 1,
WIFI_DISCONNECT_REASON_AUTH_EXPIRE = 2,
WIFI_DISCONNECT_REASON_AUTH_LEAVE = 3,
WIFI_DISCONNECT_REASON_ASSOC_EXPIRE = 4,
WIFI_DISCONNECT_REASON_ASSOC_TOOMANY = 5,
WIFI_DISCONNECT_REASON_NOT_AUTHED = 6,
WIFI_DISCONNECT_REASON_NOT_ASSOCED = 7,
WIFI_DISCONNECT_REASON_ASSOC_LEAVE = 8,
WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED = 9,
WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD = 10, /* 11h */
WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD = 11, /* 11h */
WIFI_DISCONNECT_REASON_IE_INVALID = 13, /* 11i */
WIFI_DISCONNECT_REASON_MIC_FAILURE = 14, /* 11i */
WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT = 15, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT = 16, /* 11i */
WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS = 17, /* 11i */
WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID = 18, /* 11i */
WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID = 19, /* 11i */
WIFI_DISCONNECT_REASON_AKMP_INVALID = 20, /* 11i */
WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION = 21, /* 11i */
WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP = 22, /* 11i */
WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED = 23, /* 11i */
WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED = 24, /* 11i */
WIFI_DISCONNECT_REASON_BEACON_TIMEOUT = 200,
WIFI_DISCONNECT_REASON_NO_AP_FOUND = 201,
WIFI_DISCONNECT_REASON_AUTH_FAIL = 202,
WIFI_DISCONNECT_REASON_ASSOC_FAIL = 203,
WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT = 204
};
#endif
enum WifiState {
WifiOff,
WifiStart,
WifiTryConnect,
WifiConnectionFailed,
WifiClientConnectAP,
WifiClientDisconnectAP,
WifiCredentialsChanged,
WifiConnectSuccess,
WifiDisableAP,
WifiEnableAP,
WifiStartScan,
};
WifiState currentWifiState = WifiStart;
void setWifiState(WifiState state);
bool useStaticIP();
// WiFi related data
boolean wifiSetup = false;
boolean wifiSetupConnect = false;
uint8_t lastBSSID[6] = {0};
boolean wifiConnected = false;
unsigned long wifi_connect_timer = 0;
uint8_t wifiStatus = ESPEASY_WIFI_DISCONNECTED;
unsigned long last_wifi_connect_attempt_moment = 0;
unsigned int wifi_connect_attempt = 0;
uint8_t lastWiFiSettings = 0;
String last_ssid;
bool bssid_changed = false;
uint8_t last_channel = 0;
WiFiDisconnectReason lastDisconnectReason = WIFI_DISCONNECT_REASON_UNSPECIFIED;
unsigned long lastConnectMoment = 0;
unsigned long lastDisconnectMoment = 0;
unsigned long lastGetIPmoment = 0;
unsigned long lastGetScanMoment = 0;
unsigned long lastConnectedDuration = 0;
bool intent_to_reboot = false;
uint8_t lastMacConnectedAPmode[6] = {0};
uint8_t lastMacDisconnectedAPmode[6] = {0};
//uint32_t scan_done_status = 0;
uint8_t scan_done_number = 0;
//uint8_t scan_done_scan_id = 0;
// Semaphore like booleans for processing data gathered from WiFi events.
bool processedConnect = true;
bool processedDisconnect = true;
bool processedGetIP = true;
bool processedConnectAPmode = true;
bool processedDisconnectAPmode = true;
bool processedScanDone = true;
unsigned long start = 0;
unsigned long elapsed = 0;
@@ -1071,4 +1240,11 @@ bool firstLoop=true;
boolean activeRuleSets[RULESETS_MAX];
boolean UseRTOSMultitasking;
// These wifi event functions must be in a .h-file because otherwise the preprocessor
// may not filter the ifdef checks properly.
// Also the functions use a lot of global defined variables, so include at the end of this file.
#include "ESPEasyWiFiEvent.h"
#endif /* ESPEASY_GLOBALS_H_ */
+189 -74
View File
@@ -1,3 +1,4 @@
#ifdef CONTINUOUS_INTEGRATION
#pragma GCC diagnostic error "-Wall"
#else
@@ -71,7 +72,9 @@
// SHT1X temperature/humidity sensors
// Ser2Net server
// Define globals before plugin sets to allow a personal override of the selected plugins
#include "ESPEasy-Globals.h"
#include "define_plugin_sets.h"
// Blynk_get prototype
boolean Blynk_get(const String& command, byte controllerIndex,float *data = NULL );
@@ -93,7 +96,8 @@ int firstEnabledBlynkController() {
\*********************************************************************************************/
void setup()
{
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
WiFi.setAutoReconnect(false);
checkRAM(F("setup"));
#if defined(ESP32)
@@ -107,7 +111,18 @@ void setup()
// Serial.print("\n\n\nBOOOTTT\n\n\n");
initLog();
setWifiMode(WIFI_STA);
#if defined(ESP32)
WiFi.onEvent((WiFiEventFullCb)WiFiEvent);
#else
// WiFi event handlers
stationConnectedHandler = WiFi.onStationModeConnected(onConnected);
stationDisconnectedHandler = WiFi.onStationModeDisconnected(onDisconnect);
stationGotIpHandler = WiFi.onStationModeGotIP(onGotIP);
APModeStationConnectedHandler = WiFi.onSoftAPModeStationConnected(onConnectedAPmode);
APModeStationDisconnectedHandler = WiFi.onSoftAPModeStationDisconnected(onDisonnectedAPmode);
#endif
if (SpiffsSectors() < 32)
{
@@ -120,6 +135,11 @@ void setup()
String log = F("\n\n\rINIT : Booting version: ");
log += BUILD_GIT;
#if defined(ESP8266)
log += F(" (core ");
log += ESP.getCoreVersion();
log += F(")");
#endif
addLog(LOG_LEVEL_INFO, log);
@@ -160,8 +180,6 @@ void setup()
progMemMD5check();
LoadSettings();
checkRuleSets();
if (strcasecmp(SecuritySettings.WifiSSID, "ssid") == 0)
wifiSetup = true;
ExtraTaskSettings.TaskIndex = 255; // make sure this is an unused nr to prevent cache load on boot
@@ -184,6 +202,7 @@ void setup()
//make sure previous serial buffers are flushed before resetting baudrate
Serial.flush();
Serial.begin(Settings.BaudRate);
// Serial.setDebugOutput(true);
}
if (Settings.Build != BUILD)
@@ -210,36 +229,53 @@ void setup()
timer100ms = 0; // timer for periodic actions 10 x per/sec
timer1s = 0; // timer for periodic actions once per/sec
timerwd = 0; // timer for watchdog once per 30 sec
timermqtt = 0; // Timer for the MQTT keep alive loop.
timermqtt = 10000; // Timer for the MQTT keep alive loop, initial value can be high, since it will be set as soon as IP is set.
timermqtt_interval = 250; // Interval for checking MQTT
timerAwakeFromDeepSleep = millis();
PluginInit();
CPluginInit();
NPluginInit();
log = F("INFO : Plugins: ");
log += deviceCount + 1;
#ifdef PLUGIN_BUILD_NORMAL
log += F(" [Normal]");
#endif
#ifdef PLUGIN_BUILD_TESTING
log += F(" [Testing]");
#endif
#ifdef PLUGIN_BUILD_DEV
log += F(" [Development]");
#endif
#if defined(ESP8266)
log += F(" (core ");
log += ESP.getCoreVersion();
log += F(")");
#endif
addLog(LOG_LEVEL_INFO, log);
if (deviceCount + 1 >= PLUGIN_MAX) {
addLog(LOG_LEVEL_ERROR, F("Programming error! - Increase PLUGIN_MAX"));
}
if (Settings.UseRules)
{
String event = F("System#Wake");
rulesProcessing(event);
}
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
WifiAPconfig();
if (Settings.deepSleep)
{
//only one attempt in deepsleep, to conserve battery
if (!WifiConnect(1))
{
if (Settings.deepSleepOnFail)
{
addLog(LOG_LEVEL_ERROR, F("SLEEP: Connection failed, going back to sleep."));
deepSleep(Settings.Delay);
}
}
if (!selectValidWiFiSettings()) {
wifiSetup = true;
}
else
WiFiConnectRelaxed();
/*
// FIXME TD-er:
// Async scanning for wifi doesn't work yet like it should.
// So no selection of strongest network yet.
if (selectValidWiFiSettings()) {
WifiScanAsync();
}
*/
setWifiState(WifiTryConnect);
#ifdef FEATURE_REPORTING
ReportStatus();
@@ -264,12 +300,6 @@ void setup()
vcc = ESP.getVcc() / 1000.0;
#endif
// Start DNS, only used if the ESP has no valid WiFi config
// It will reply with it's own address on all DNS requests
// (captive portal concept)
if (wifiSetup)
dnsServer.start(DNS_PORT, "*", apIP);
if (Settings.UseRules)
{
String event = F("System#Boot");
@@ -278,8 +308,49 @@ void setup()
writeDefaultCSS();
UseRTOSMultitasking = Settings.UseRTOSMultitasking;
#ifdef USE_RTOS_MULTITASKING
if(UseRTOSMultitasking){
log = F("RTOS : Launching tasks");
addLog(LOG_LEVEL_INFO, log);
xTaskCreatePinnedToCore(RTOS_TaskServers, "RTOS_TaskServers", 8192, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(RTOS_TaskSerial, "RTOS_TaskSerial", 8192, NULL, 1, NULL, 1);
xTaskCreatePinnedToCore(RTOS_Task10ps, "RTOS_Task10ps", 8192, NULL, 1, NULL, 1);
}
#endif
}
#ifdef USE_RTOS_MULTITASKING
void RTOS_TaskServers( void * parameter )
{
while (true){
delay(100);
WebServer.handleClient();
checkUDP();
}
}
void RTOS_TaskSerial( void * parameter )
{
while (true){
delay(100);
if (Settings.UseSerial)
if (Serial.available())
if (!PluginCall(PLUGIN_SERIAL_IN, 0, dummyString))
serial();
}
}
void RTOS_Task10ps( void * parameter )
{
while (true){
delay(100);
run10TimesPerSecond();
}
}
#endif
int firstEnabledMQTTController() {
for (byte i = 0; i < CONTROLLER_MAX; ++i) {
byte ProtocolIndex = getProtocolIndex(Settings.Protocol[i]);
@@ -307,20 +378,33 @@ void loop()
if (wifiSetupConnect)
{
// try to connect for setup wizard
WifiConnect(1);
setWifiState(WifiCredentialsChanged);
wifiSetupConnect = false;
}
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
if (wifiStatus >= ESPEASY_WIFI_CONNECTED) processConnect();
if (wifiStatus >= ESPEASY_WIFI_GOT_IP) processGotIP();
if (wifiStatus == ESPEASY_WIFI_DISCONNECTED) processDisconnect();
} else if (WiFi.status() != WL_CONNECTED) {
// Somehow the WiFi has entered a limbo state.
// FIXME TD-er: This may happen on WiFi config with AP_STA mode active.
// addLog(LOG_LEVEL_ERROR, F("Wifi status out sync"));
// resetWiFi();
}
if (!processedConnectAPmode) processConnectAPmode();
if (!processedDisconnectAPmode) processDisconnectAPmode();
if (!processedScanDone) processScanDone();
// Deep sleep mode, just run all tasks one time and go back to sleep as fast as possible
if (firstLoop && isDeepSleepEnabled())
bool firstLoopWiFiConnected = wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED && firstLoop;
if (firstLoopWiFiConnected) {
firstLoop = false;
timerAwakeFromDeepSleep = millis(); // Allow to run for "awake" number of seconds, now we have wifi.
}
// Deep sleep mode, just run all tasks one (more) time and go back to sleep as fast as possible
if ((firstLoopWiFiConnected || readyForSleep()) && isDeepSleepEnabled())
{
// Setup MQTT Client
// Controller index is forced to the first enabled MQTT controller.
// This is normally done via frequent checks, but there's no time for in deepsleep.
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
MQTTConnect(enabledMqttController);
}
runPeriodicalMQTT();
// Now run all frequent tasks
run50TimesPerSecond();
run10TimesPerSecond();
@@ -335,7 +419,8 @@ void loop()
run50TimesPerSecond();
if (timeOutReached(timer100ms))
run10TimesPerSecond();
if(!UseRTOSMultitasking)
run10TimesPerSecond();
if (timeOutReached(timerwd))
runEach30Seconds();
@@ -344,21 +429,7 @@ void loop()
runOncePerSecond();
if (timeOutReached(timermqtt)) {
// MQTT_KEEPALIVE = 15 seconds.
timermqtt = millis() + timermqtt_interval;
//dont do this in backgroundtasks(), otherwise causes crashes. (https://github.com/letscontrolit/ESPEasy/issues/683)
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
if (!MQTTclient.loop()) {
if (!MQTTCheck(enabledMqttController)) {
// Check failed, no need to retry it immediately.
if (timermqtt_interval < 2000)
timermqtt_interval += 250;
} else {
timermqtt_interval = 250;
}
}
}
runPeriodicalMQTT();
}
}
@@ -370,14 +441,58 @@ void loop()
String event = F("System#Sleep");
rulesProcessing(event);
}
// Flush outstanding MQTT messages
runPeriodicalMQTT();
deepSleep(Settings.Delay);
//deepsleep will never return, its a special kind of reboot
}
firstLoop = false;
}
void runPeriodicalMQTT() {
// MQTT_KEEPALIVE = 15 seconds.
if (!WiFiConnected(10)) {
updateMQTTclient_connected();
return;
}
//dont do this in backgroundtasks(), otherwise causes crashes. (https://github.com/letscontrolit/ESPEasy/issues/683)
int enabledMqttController = firstEnabledMQTTController();
if (enabledMqttController >= 0) {
if (!MQTTclient.loop()) {
updateMQTTclient_connected();
if (MQTTCheck(enabledMqttController)) {
updateMQTTclient_connected();
}
}
} else {
if (MQTTclient.connected()) {
MQTTclient.disconnect();
updateMQTTclient_connected();
}
}
}
void updateMQTTclient_connected() {
if (MQTTclient_connected != MQTTclient.connected()) {
MQTTclient_connected = !MQTTclient_connected;
if (!MQTTclient_connected)
addLog(LOG_LEVEL_ERROR, F("MQTT : Connection lost"));
if (Settings.UseRules) {
String event = MQTTclient_connected ? F("MQTT#Connected") : F("MQTT#Disconnected");
rulesProcessing(event);
}
}
if (!MQTTclient_connected) {
if (timermqtt_interval < 2000) {
timermqtt_interval += 250;
}
} else {
timermqtt_interval = 250;
}
timermqtt = millis() + timermqtt_interval;
}
/*********************************************************************************************\
* Tasks that run 50 times per second
\*********************************************************************************************/
@@ -405,7 +520,9 @@ void run10TimesPerSecond()
eventBuffer = "";
}
elapsed = micros() - start;
WebServer.handleClient();
#ifndef USE_RTOS_MULTITASKING
WebServer.handleClient();
#endif
}
@@ -493,12 +610,7 @@ void runOncePerSecond()
Serial.print(F(" uS 1 ps:"));
Serial.println(timer);
}
if (timerAPoff != 0 && timeOutReached(timerAPoff))
{
timerAPoff = 0;
WifiAPMode(false);
}
checkResetFactoryPin();
}
/*********************************************************************************************\
@@ -510,11 +622,14 @@ void runEach30Seconds()
checkRAMtoLog();
wdcounter++;
timerwd = millis() + 30000;
char str[60];
str[0] = 0;
sprintf_P(str, PSTR("Uptime %u ConnectFailures %u FreeMem %u"), wdcounter / 2, connectionFailures, FreeMem());
String log = F("WD : ");
log += str;
String log;
log.reserve(60);
log = F("WD : Uptime ");
log += wdcounter / 2;
log += F(" ConnectFailures ");
log += connectionFailures;
log += F(" FreeMem ");
log += FreeMem();
addLog(LOG_LEVEL_INFO, log);
sendSysInfoUDP(1);
refreshNodeList();
@@ -741,19 +856,19 @@ void backgroundtasks()
tcpCleanup();
#endif
if (Settings.UseSerial)
if (Serial.available())
if (!PluginCall(PLUGIN_SERIAL_IN, 0, dummyString))
serial();
if(!UseRTOSMultitasking){
if (Settings.UseSerial)
if (Serial.available())
if (!PluginCall(PLUGIN_SERIAL_IN, 0, dummyString))
serial();
WebServer.handleClient();
checkUDP();
}
// process DNS, only used if the ESP has no valid WiFi config
if (wifiSetup)
if (dnsServerActive)
dnsServer.processNextRequest();
WebServer.handleClient();
checkUDP();
#ifdef FEATURE_ARDUINO_OTA
if(Settings.ArduinoOTAEnable)
ArduinoOTA.handle();
+1
View File
@@ -64,6 +64,7 @@ void setTimeZone(const TimeChangeRule& dstStart, const TimeChangeRule& stdStart,
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);
long timeDiff(unsigned long prev, unsigned long next);
#endif /* ESPEASY_TIMETYPES_H_ */
+113
View File
@@ -0,0 +1,113 @@
void markGotIP() {
lastGetIPmoment = millis();
wifiStatus = ESPEASY_WIFI_GOT_IP;
processedGetIP = false;
}
//********************************************************************************
// Functions called on events.
// Make sure not to call anything in these functions that result in delay() or yield()
//********************************************************************************
#ifdef ESP32
void WiFiEvent(system_event_id_t event, system_event_info_t info) {
switch(event) {
case SYSTEM_EVENT_STA_CONNECTED:
lastConnectMoment = millis();
processedConnect = false;
wifiStatus = ESPEASY_WIFI_CONNECTED;
break;
case SYSTEM_EVENT_STA_DISCONNECTED:
lastDisconnectMoment = millis();
if (timeDiff(lastConnectMoment, last_wifi_connect_attempt_moment) > 0) {
// There was an unsuccessful connection attempt
lastConnectedDuration = timeDiff(last_wifi_connect_attempt_moment, lastDisconnectMoment);
} else {
lastConnectedDuration = timeDiff(lastConnectMoment, lastDisconnectMoment);
}
processedDisconnect = false;
lastDisconnectReason = static_cast<WiFiDisconnectReason>(info.disconnected.reason);
wifiStatus = ESPEASY_WIFI_DISCONNECTED;
break;
case SYSTEM_EVENT_STA_GOT_IP:
markGotIP();
break;
case SYSTEM_EVENT_AP_STACONNECTED:
for (byte i = 0; i < 6; ++i) {
lastMacConnectedAPmode[i] = info.sta_connected.mac[i];
}
processedConnectAPmode = false;
break;
case SYSTEM_EVENT_AP_STADISCONNECTED:
for (byte i = 0; i < 6; ++i) {
lastMacConnectedAPmode[i] = info.sta_disconnected.mac[i];
}
processedDisconnectAPmode = false;
break;
case SYSTEM_EVENT_SCAN_DONE:
lastGetScanMoment = millis();
// scan_done_status = info.scan_done.status;
scan_done_number = info.scan_done.number;
// scan_done_scan_id = info.scan_done.scan_id;
processedScanDone = false;
break;
default:
break;
}
}
#else
void onConnected(const WiFiEventStationModeConnected& event){
lastConnectMoment = millis();
processedConnect = false;
wifiStatus = ESPEASY_WIFI_CONNECTED;
last_channel = event.channel;
last_ssid = event.ssid;
bssid_changed = false;
for (byte i=0; i < 6; ++i) {
if (lastBSSID[i] != event.bssid[i]) {
bssid_changed = true;
lastBSSID[i] = event.bssid[i];
}
}
if (useStaticIP()) {
markGotIP();
}
}
void onDisconnect(const WiFiEventStationModeDisconnected& event){
lastDisconnectMoment = millis();
if (timeDiff(lastConnectMoment, last_wifi_connect_attempt_moment) > 0) {
// There was an unsuccessful connection attempt
lastConnectedDuration = timeDiff(last_wifi_connect_attempt_moment, lastDisconnectMoment);
} else
lastConnectedDuration = timeDiff(lastConnectMoment, lastDisconnectMoment);
lastDisconnectReason = event.reason;
wifiStatus = ESPEASY_WIFI_DISCONNECTED;
processedDisconnect = false;
}
void onGotIP(const WiFiEventStationModeGotIP& event){
markGotIP();
}
void onConnectedAPmode(const WiFiEventSoftAPModeStationConnected& event) {
for (byte i = 0; i < 6; ++i) {
lastMacConnectedAPmode[i] = event.mac[i];
}
processedConnectAPmode = false;
}
void onDisonnectedAPmode(const WiFiEventSoftAPModeStationDisconnected& event) {
for (byte i = 0; i < 6; ++i) {
lastMacDisconnectedAPmode[i] = event.mac[i];
}
processedDisconnectAPmode = false;
}
void onScanFinished(int networksFound) {
lastGetScanMoment = millis();
scan_done_number = networksFound;
processedScanDone = false;
}
#endif
+814
View File
@@ -0,0 +1,814 @@
#define WIFI_AP_OFF_TIMER_DURATION 60000 // in milliSeconds
//********************************************************************************
// Functions to process the data gathered from the events.
// These functions are called from Setup() or Loop() and thus may call delay() or yield()
//********************************************************************************
void processConnect() {
if (processedConnect) return;
processedConnect = true;
if (wifiStatus < ESPEASY_WIFI_CONNECTED) return;
const long connect_duration = timeDiff(last_wifi_connect_attempt_moment, lastConnectMoment);
String log = F("WIFI : Connected! AP: ");
log += WiFi.SSID();
log += F(" (");
log += WiFi.BSSIDstr();
log += F(") Ch: ");
log += last_channel;
if (connect_duration > 0 && connect_duration < 30000) {
// Just log times when they make sense.
log += F(" Duration: ");
log += connect_duration;
log += F(" ms");
}
addLog(LOG_LEVEL_INFO, log);
if (useStaticIP())
{
const IPAddress ip = Settings.IP;
const IPAddress gw = Settings.Gateway;
const IPAddress subnet = Settings.Subnet;
const IPAddress dns = Settings.DNS;
log = F("IP : Static IP : ");
log += formatIP(ip);
log += F(" GW: ");
log += formatIP(gw);
log += F(" SN: ");
log += formatIP(subnet);
log += F(" DNS: ");
log += formatIP(dns);
addLog(LOG_LEVEL_INFO, log);
WiFi.config(ip, gw, subnet, dns);
}
if (Settings.UseRules && bssid_changed) {
String event = F("WiFi#ChangedAccesspoint");
rulesProcessing(event);
}
setWifiState(WifiConnectSuccess);
}
void processDisconnect() {
if (processedDisconnect) return;
processedDisconnect = true;
if (Settings.UseRules) {
String event = F("WiFi#Disconnected");
rulesProcessing(event);
}
String log = F("WIFI : Disconnected! Reason: '");
log += getLastDisconnectReason();
log += F("'");
if (lastConnectedDuration > 0) {
log += F(" Connected for ");
log += format_msec_duration(lastConnectedDuration);
}
addLog(LOG_LEVEL_INFO, log);
if (wifi_connect_attempt > 5) {
setWifiState(WifiConnectionFailed);
} else {
switch (lastDisconnectReason) {
case WIFI_DISCONNECT_REASON_NO_AP_FOUND:
case WIFI_DISCONNECT_REASON_AUTH_FAIL:
case WIFI_DISCONNECT_REASON_ASSOC_FAIL:
case WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT:
// Disconnect without chance for success on next attempt
if (selectNextWiFiSettings()) {
if (!intent_to_reboot)
setWifiState(WifiTryConnect);
return;
} else {
if (Settings.deepSleep && Settings.deepSleepOnFail) {
//only one attempt in deepsleep, to conserve battery
addLog(LOG_LEVEL_ERROR, F("SLEEP: Connection failed, going back to sleep."));
deepSleep(Settings.Delay);
}
setWifiState(WifiConnectionFailed);
return;
}
break;
default:
setWifiState(WifiStart);
if (!intent_to_reboot)
setWifiState(WifiTryConnect);
return;
}
}
}
void processGotIP() {
if (processedGetIP)
return;
processedGetIP = true;
if (wifiStatus < ESPEASY_WIFI_GOT_IP)
return;
IPAddress ip = WiFi.localIP();
if (ip[0] == 0 && ip[1] == 0 && ip[2] == 0 && ip[3] == 0)
return;
const IPAddress gw = WiFi.gatewayIP();
const IPAddress subnet = WiFi.subnetMask();
String log = F("WIFI : ");
if (useStaticIP()) {
log += F("Static IP: ");
} else {
log += F("DHCP IP: ");
}
log += formatIP(ip);
log += F(" (");
log += WifiGetHostname();
log += F(") GW: ");
log += formatIP(gw);
log += F(" SN: ");
log += formatIP(subnet);
const long dhcp_duration = timeDiff(lastConnectMoment, lastGetIPmoment);
if (dhcp_duration > 0 && dhcp_duration < 30000) {
// Just log times when they make sense.
log += F(" duration: ");
log += dhcp_duration;
log += F(" ms");
}
addLog(LOG_LEVEL_INFO, log);
// fix octet?
if (Settings.IP_Octet != 0 && Settings.IP_Octet != 255)
{
ip[3] = Settings.IP_Octet;
log = F("IP : Fixed IP octet:");
log += formatIP(ip);
addLog(LOG_LEVEL_INFO, log);
WiFi.config(ip, gw, subnet);
}
#ifdef FEATURE_MDNS
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();
}
timermqtt_interval = 100;
timermqtt = millis() + timermqtt_interval;
if (Settings.UseRules)
{
String event = F("WiFi#Connected");
rulesProcessing(event);
}
statusLED(true);
// WiFi.scanDelete();
wifiStatus = ESPEASY_WIFI_SERVICES_INITIALIZED;
if (wifiSetup) {
// Wifi setup was active, Apparently these settings work.
wifiSetup = false;
SaveSettings();
}
}
void processConnectAPmode() {
if (processedConnectAPmode) return;
processedConnectAPmode = true;
String log = F("AP Mode: Client connected: ");
log += formatMAC(lastMacConnectedAPmode);
log += F(" Connected devices: ");
log += WiFi.softAPgetStationNum();
addLog(LOG_LEVEL_INFO, log);
setWifiState(WifiClientConnectAP);
}
void processDisconnectAPmode() {
if (processedDisconnectAPmode) return;
processedDisconnectAPmode = true;
const int nrStationsConnected = WiFi.softAPgetStationNum();
String log = F("AP Mode: Client disconnected: ");
log += formatMAC(lastMacDisconnectedAPmode);
log += F(" Connected devices: ");
log += nrStationsConnected;
addLog(LOG_LEVEL_INFO, log);
if (nrStationsConnected == 0) {
setWifiState(WifiClientDisconnectAP);
}
}
void processScanDone() {
if (processedScanDone) return;
processedScanDone = true;
String log = F("WIFI : Scan finished, found: ");
log += scan_done_number;
addLog(LOG_LEVEL_INFO, log);
int bestScanID = -1;
int32_t bestRssi = -1000;
uint8_t bestWiFiSettings = lastWiFiSettings;
if (selectValidWiFiSettings()) {
bool done = false;
String lastWiFiSettingsSSID = getLastWiFiSettingsSSID();
for (int settingNr = 0; !done && settingNr < 2; ++settingNr) {
for (int i = 0; i < scan_done_number; ++i) {
if (WiFi.SSID(i) == lastWiFiSettingsSSID) {
int32_t rssi = WiFi.RSSI(i);
if (bestRssi < rssi) {
bestRssi = rssi;
bestScanID = i;
bestWiFiSettings = lastWiFiSettings;
}
}
}
if (!selectNextWiFiSettings()) done = true;
}
if (bestScanID >= 0) {
log = F("WIFI : Selected: ");
log += formatScanResult(bestScanID, " ");
addLog(LOG_LEVEL_INFO, log);
lastWiFiSettings = bestWiFiSettings;
uint8_t * scanbssid = WiFi.BSSID(bestScanID);
if (scanbssid) {
for (int i = 0; i < 6 ; ++i) {
lastBSSID[i] = *(scanbssid + i);
}
}
}
setWifiState(WifiTryConnect);
}
}
void resetWiFi() {
addLog(LOG_LEVEL_INFO, F("Reset WiFi."));
setWifiState(WifiOff);
setWifiState(WifiStart);
lastDisconnectMoment = millis();
processedDisconnect = false;
wifiStatus = ESPEASY_WIFI_DISCONNECTED;
}
void WifiScanAsync() {
setWifiState(WifiStartScan);
addLog(LOG_LEVEL_INFO, F("WIFI : Start network scan"));
#ifdef ESP32
bool async = true;
bool show_hidden = false;
bool passive = false;
uint32_t max_ms_per_chan = 300;
WiFi.scanNetworks(async, show_hidden, passive, max_ms_per_chan);
#else
// 2.4.x only and it doesn't work like expected.
// WiFi.scanNetworksAsync(onScanFinished);
#endif
}
//********************************************************************************
// WiFi state
//********************************************************************************
// 0 Wifi off
// 1 Start => STA
// 2 Try connect => STA => successful, goto 7
// 3 Connection fails => AP => no client in N seconds, goto 1
// 4 Client connects => AP
// 5 Credentials changed => STA_AP => goto 2
// 6 Connect successful (AP on) => STA_AP => disable AP after N seconds, goto 8
// 7 Connect successful => STA
// 8 Disable AP after N seconds => STA
//********************************************************************************
bool WifiIsAP(WiFiMode_t wifimode)
{
#if defined(ESP32)
return (wifimode == WIFI_MODE_AP) || (wifimode == WIFI_MODE_APSTA);
#else
return (wifimode == WIFI_AP) || (wifimode == WIFI_AP_STA);
#endif
}
bool WifiIsSTA(WiFiMode_t wifimode)
{
#if defined(ESP32)
return ((wifimode & WIFI_MODE_STA) != 0);
#else
return ((wifimode & WIFI_STA) != 0);
#endif
}
void setWifiState(WifiState state) {
currentWifiState = state;
switch (state) {
case WifiOff:
WifiDisconnect();
changeWifiMode(WIFI_OFF);
break;
case WifiStart:
changeWifiMode(WIFI_STA);
break;
case WifiConnectionFailed:
addLog(LOG_LEVEL_INFO, F("WIFI : Connection Failed"));
if (WIFI_AP != WiFi.getMode()) {
changeWifiMode(WIFI_AP);
wifiSetup = true;
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
}
break;
case WifiClientConnectAP:
timerAPoff = 0; // Disable timer to switch AP off.
changeWifiMode(WIFI_AP);
break;
case WifiClientDisconnectAP:
if (WifiIsAP(WiFi.getMode())) {
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
}
break;
case WifiCredentialsChanged:
lastWiFiSettings = 0; // Force to load the first settings.
wifi_connect_attempt = 0;
// fall through
case WifiTryConnect:
if (WifiIsAP(WiFi.getMode())) {
timerAPoff = 0; // Disable timer to switch AP off.
changeWifiMode(WIFI_AP_STA);
} else {
changeWifiMode(WIFI_STA);
}
if (prepareWiFi()) {
tryConnectWiFi();
} else {
setWifiState(WifiConnectionFailed);
}
break;
case WifiConnectSuccess:
if (WifiIsAP(WiFi.getMode())) {
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
} else {
timerAPoff = 0; // Disable timer to switch AP off.
changeWifiMode(WIFI_STA);
}
wifi_connect_attempt = 0;
break;
case WifiDisableAP:
if (WifiIsAP(WiFi.getMode())) {
timerAPoff = 0; // Disable timer to switch AP off.
changeWifiMode(WIFI_STA);
}
break;
case WifiEnableAP:
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
changeWifiMode(WIFI_AP_STA);
} else {
changeWifiMode(WIFI_AP);
}
timerAPoff = millis() + WIFI_AP_OFF_TIMER_DURATION;
break;
case WifiStartScan:
if (WifiIsAP(WiFi.getMode())) {
changeWifiMode(WIFI_AP_STA);
} else changeWifiMode(WIFI_STA);
break;
}
}
//********************************************************************************
// Set Wifi AP Mode
//********************************************************************************
void setWifiMode(WiFiMode_t wifimode) {
switch (wifimode) {
case WIFI_OFF:
addLog(LOG_LEVEL_INFO, F("WIFI : Switch off WiFi"));
break;
case WIFI_STA:
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to STA"));
break;
case WIFI_AP:
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to AP"));
break;
case WIFI_AP_STA:
addLog(LOG_LEVEL_INFO, F("WIFI : Set WiFi to AP+STA"));
break;
default:
break;
}
WiFi.mode(wifimode);
}
void changeWifiMode(WiFiMode_t wifimode)
{
if (wifimode == WiFi.getMode()) return;
if (WiFi.getMode() == WIFI_OFF) {
// Any mode can be selected, starting from off mode.
addLog(LOG_LEVEL_INFO, F("WIFI : Switch on WiFi"));
setWifiMode(wifimode);
return;
}
switch (wifimode) {
case WIFI_OFF:
WifiDisconnect();
setWifiMode(WIFI_OFF);
return;
case WIFI_STA:
if (WifiIsAP(WiFi.getMode())) {
// Change from AP mode to STA mode, must disconnect clients.
dnsServerActive = false;
dnsServer.stop();
if (WiFi.softAPdisconnect(true)) {
String log("WIFI : AP Mode Disabled for SSID: ");
log += WifiGetAPssid();
addLog(LOG_LEVEL_INFO, log);
} else {
String log("WIFI : Error while disabling AP Mode with SSID: ");
log += WifiGetAPssid();
addLog(LOG_LEVEL_ERROR, log);
}
}
setWifiMode(wifimode);
WiFi.reconnect();
break;
case WIFI_AP_STA:
case WIFI_AP:
{
if (WifiIsSTA(WiFi.getMode())) {
// Should disable WiFi first and then restart in AP mode.
WifiDisconnect();
if (wifimode == WIFI_AP_STA) {
WiFi.reconnect();
}
// setWifiMode(WIFI_OFF);
delay(100);
}
// create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password!
// setup ssid for AP Mode when needed
setWifiMode(wifimode);
WiFi.setAutoConnect(false);
String softAPSSID=WifiGetAPssid();
String pwd = SecuritySettings.WifiAPKey;
IPAddress subnet(DEFAULT_AP_SUBNET);
if (!WiFi.softAPConfig(apIP, apIP, subnet)) {
addLog(LOG_LEVEL_ERROR, "WIFI : [AP] softAPConfig failed!");
}
if (WiFi.softAP(softAPSSID.c_str(),pwd.c_str())) {
String log("WIFI : AP Mode ssid will be ");
log += softAPSSID;
log += F(" with address ");
log += WiFi.softAPIP().toString();
addLog(LOG_LEVEL_INFO, log);
} else {
String log("WIFI : Error while starting AP Mode with SSID: ");
log += softAPSSID;
log += F(" IP: ");
log += apIP.toString();
addLog(LOG_LEVEL_ERROR, log);
}
#ifdef ESP32
#else
if(wifi_softap_dhcps_status() != DHCP_STARTED) {
if(!wifi_softap_dhcps_start()) {
addLog(LOG_LEVEL_ERROR, "WIFI : [AP] wifi_softap_dhcps_start failed!");
}
}
#endif
// Start DNS, only used if the ESP has no valid WiFi config
// It will reply with it's own address on all DNS requests
// (captive portal concept)
dnsServerActive = true;
dnsServer.start(DNS_PORT, "*", apIP);
break;
}
default:
break;
}
}
//********************************************************************************
// Determine Wifi AP name to set. (also used for mDNS)
//********************************************************************************
String WifiGetAPssid()
{
String ssid(Settings.Name);
ssid+=F("_");
ssid+=Settings.Unit;
return (ssid);
}
//********************************************************************************
// Determine hostname: basically WifiGetAPssid with spaces changed to -
//********************************************************************************
String WifiGetHostname()
{
String hostname(WifiGetAPssid());
hostname.replace(F(" "), F("-"));
hostname.replace(F("_"), F("-")); // See RFC952
return (hostname);
}
bool useStaticIP() {
return (Settings.IP[0] != 0 && Settings.IP[0] != 255);
}
//********************************************************************************
// Set Wifi config
//********************************************************************************
bool prepareWiFi() {
if (!selectValidWiFiSettings()) {
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid wifi settings"));
return false;
}
String log = "";
char hostname[40];
strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname));
#if defined(ESP8266)
wifi_station_set_hostname(hostname);
#endif
#if defined(ESP32)
WiFi.setHostname(hostname);
#endif
return 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 selectNextWiFiSettings() {
uint8_t tmp = lastWiFiSettings;
lastWiFiSettings = (lastWiFiSettings + 1) % 2;
if (!wifiSettingsValid(getLastWiFiSettingsSSID(), getLastWiFiSettingsPassphrase())) {
// other settings are not correct, switch back.
lastWiFiSettings = tmp;
return false; // Nothing changed.
}
return true;
}
bool selectValidWiFiSettings() {
if (wifiSettingsValid(getLastWiFiSettingsSSID(), getLastWiFiSettingsPassphrase()))
return true;
return selectNextWiFiSettings();
}
bool wifiSettingsValid(const char* ssid, const char* pass) {
if (ssid[0] == 0 || (strcasecmp(ssid, "ssid") == 0)) {
return false;
}
// if (pass[0] == 0) return false; // Allow for empty pass
if (strlen(ssid) > 32) return false;
if (strlen(pass) > 64) return false;
return true;
}
bool wifiConnectTimeoutReached() {
if (wifi_connect_attempt == 0) return true;
if (timeDiff(last_wifi_connect_attempt_moment, lastDisconnectMoment) >0 ) {
// Connection attempt was already ended.
return true;
}
if (WifiIsAP(WiFi.getMode())) {
// Initial setup of WiFi, may take much longer since accesspoint is still active.
return timeOutReached(last_wifi_connect_attempt_moment + 20000);
}
// wait until it connects + add some device specific random offset to prevent
// all nodes overloading the accesspoint when turning on at the same time.
#if defined(ESP8266)
const unsigned int randomOffset_in_sec = wifi_connect_attempt == 1 ? 0 : 1000 * ((ESP.getChipId() & 0xF));
#endif
#if defined(ESP32)
const unsigned int randomOffset_in_sec = wifi_connect_attempt == 1 ? 0 : 1000 * ((ESP.getEfuseMac() & 0xF));
#endif
return timeOutReached(last_wifi_connect_attempt_moment + DEFAULT_WIFI_CONNECTION_TIMEOUT + randomOffset_in_sec);
}
//********************************************************************************
// Simply start the WiFi connection sequence
//********************************************************************************
bool tryConnectWiFi() {
// if (wifiSetup && !wifiSetupConnect)
// return false;
if (wifiStatus != ESPEASY_WIFI_DISCONNECTED) {
if (!WifiIsAP(WiFi.getMode())) {
// Only when not in AP mode.
return(true); //already connected, need to disconnect first
}
}
if (!wifiConnectTimeoutReached())
return true; // timeout not reached yet, thus no need to retry again.
if (!selectValidWiFiSettings()) {
addLog(LOG_LEVEL_ERROR, F("WIFI : No valid WiFi settings!"));
return false;
}
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);
last_wifi_connect_attempt_moment = 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;
}
default:
break;
}
return true; // Sent
}
//********************************************************************************
// Disconnect from Wifi AP
//********************************************************************************
void WifiDisconnect()
{
#if defined(ESP32)
WiFi.disconnect();
#else
ETS_UART_INTR_DISABLE();
wifi_station_disconnect();
ETS_UART_INTR_ENABLE();
#endif
}
//********************************************************************************
// Scan all Wifi Access Points
//********************************************************************************
void WifiScan()
{
// Direct Serial is allowed here, since this function will only be called from serial input.
Serial.println(F("WIFI : SSID Scan start"));
int n = WiFi.scanNetworks();
if (n == 0)
Serial.println(F("WIFI : No networks found"));
else
{
Serial.print(F("WIFI : "));
Serial.print(n);
Serial.println(F(" networks found"));
for (int i = 0; i < n; ++i)
{
// Print SSID and RSSI for each network found
Serial.print(F("WIFI : "));
Serial.print(i + 1);
Serial.print(": ");
Serial.println(formatScanResult(i, " "));
delay(10);
}
}
Serial.println("");
}
String formatScanResult(int i, const String& separator) {
String result = WiFi.SSID(i);
result += separator;
result += WiFi.BSSIDstr(i);
result += separator;
result += F("Ch:");
result += WiFi.channel(i);
result += F(" (");
result += WiFi.RSSI(i);
result += F("dBm) ");
switch (WiFi.encryptionType(i)) {
#ifdef ESP32
case WIFI_AUTH_OPEN: result += F("open"); break;
case WIFI_AUTH_WEP: result += F("WEP"); break;
case WIFI_AUTH_WPA_PSK: result += F("WPA/PSK"); break;
case WIFI_AUTH_WPA2_PSK: result += F("WPA2/PSK"); break;
case WIFI_AUTH_WPA_WPA2_PSK: result += F("WPA/WPA2/PSK"); break;
case WIFI_AUTH_WPA2_ENTERPRISE: result += F("WPA2 Enterprise"); break;
#else
case ENC_TYPE_WEP: result += F("WEP"); break;
case ENC_TYPE_TKIP: result += F("WPA/PSK"); break;
case ENC_TYPE_CCMP: result += F("WPA2/PSK"); break;
case ENC_TYPE_NONE: result += F("open"); break;
case ENC_TYPE_AUTO: result += F("WPA/WPA2/PSK"); break;
#endif
default:
break;
}
return result;
}
//********************************************************************************
// Check if we are still connected to a Wifi AP
//********************************************************************************
void WifiCheck()
{
if(wifiSetup)
return;
if (WifiIsAP(WiFi.getMode())) {
// disable AP after timeout.
if (timerAPoff && timeOutReached(timerAPoff)) {
setWifiState(WifiDisableAP);
}
}
if (wifiStatus == ESPEASY_WIFI_DISCONNECTED)
{
NC_Count++;
if (!WifiIsAP(WiFi.getMode()))
setWifiState(WifiTryConnect);
}
//connected
else if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED)
{
C_Count++;
NC_Count = 0;
}
}
//********************************************************************************
// Return subnet range of WiFi.
//********************************************************************************
bool getSubnetRange(IPAddress& low, IPAddress& high)
{
if (WifiIsAP(WiFi.getMode())) {
// WiFi is active as accesspoint, do not check.
return false;
}
if (wifiStatus < ESPEASY_WIFI_GOT_IP) {
return false;
}
const IPAddress ip = WiFi.localIP();
const IPAddress subnet = WiFi.subnetMask();
low = ip;
high = ip;
// Compute subnet range.
for (byte i=0; i < 4; ++i) {
if (subnet[i] != 255) {
low[i] = low[i] & subnet[i];
high[i] = high[i] | ~subnet[i];
}
}
return true;
}
String getLastDisconnectReason() {
switch (lastDisconnectReason) {
case WIFI_DISCONNECT_REASON_UNSPECIFIED: return F("Unspecified");
case WIFI_DISCONNECT_REASON_AUTH_EXPIRE: return F("Auth expire");
case WIFI_DISCONNECT_REASON_AUTH_LEAVE: return F("Auth leave");
case WIFI_DISCONNECT_REASON_ASSOC_EXPIRE: return F("Assoc expire");
case WIFI_DISCONNECT_REASON_ASSOC_TOOMANY: return F("Assoc toomany");
case WIFI_DISCONNECT_REASON_NOT_AUTHED: return F("Not authed");
case WIFI_DISCONNECT_REASON_NOT_ASSOCED: return F("Not assoced");
case WIFI_DISCONNECT_REASON_ASSOC_LEAVE: return F("Assoc leave");
case WIFI_DISCONNECT_REASON_ASSOC_NOT_AUTHED: return F("Assoc not authed");
case WIFI_DISCONNECT_REASON_DISASSOC_PWRCAP_BAD: return F("Disassoc pwrcap bad");
case WIFI_DISCONNECT_REASON_DISASSOC_SUPCHAN_BAD: return F("Disassoc supchan bad");
case WIFI_DISCONNECT_REASON_IE_INVALID: return F("IE invalid");
case WIFI_DISCONNECT_REASON_MIC_FAILURE: return F("Mic failure");
case WIFI_DISCONNECT_REASON_4WAY_HANDSHAKE_TIMEOUT: return F("4way handshake timeout");
case WIFI_DISCONNECT_REASON_GROUP_KEY_UPDATE_TIMEOUT: return F("Group key update timeout");
case WIFI_DISCONNECT_REASON_IE_IN_4WAY_DIFFERS: return F("IE in 4way differs");
case WIFI_DISCONNECT_REASON_GROUP_CIPHER_INVALID: return F("Group cipher invalid");
case WIFI_DISCONNECT_REASON_PAIRWISE_CIPHER_INVALID: return F("Pairwise cipher invalid");
case WIFI_DISCONNECT_REASON_AKMP_INVALID: return F("AKMP invalid");
case WIFI_DISCONNECT_REASON_UNSUPP_RSN_IE_VERSION: return F("Unsupp RSN IE version");
case WIFI_DISCONNECT_REASON_INVALID_RSN_IE_CAP: return F("Invalid RSN IE cap");
case WIFI_DISCONNECT_REASON_802_1X_AUTH_FAILED: return F("802 1X auth failed");
case WIFI_DISCONNECT_REASON_CIPHER_SUITE_REJECTED: return F("Cipher suite rejected");
case WIFI_DISCONNECT_REASON_BEACON_TIMEOUT: return F("Beacon timeout");
case WIFI_DISCONNECT_REASON_NO_AP_FOUND: return F("No AP found");
case WIFI_DISCONNECT_REASON_AUTH_FAIL: return F("Auth fail");
case WIFI_DISCONNECT_REASON_ASSOC_FAIL: return F("Assoc fail");
case WIFI_DISCONNECT_REASON_HANDSHAKE_TIMEOUT: return F("Handshake timeout");
}
return F("Unknown");
}
+27
View File
@@ -26,6 +26,9 @@ void hardwareInit()
break;
}
if (Settings.Pin_Reset != -1)
pinMode(Settings.Pin_Reset,INPUT_PULLUP);
// configure hardware pins according to eeprom settings.
if (Settings.Pin_i2c_sda != -1)
{
@@ -97,3 +100,27 @@ void hardwareInit()
}
void checkResetFactoryPin(){
static byte factoryResetCounter=0;
if (Settings.Pin_Reset == -1)
return;
if (digitalRead(Settings.Pin_Reset) == 0){ // active low reset pin
factoryResetCounter++; // just count every second
}
else
{ // reset pin released
if (factoryResetCounter > 9) // factory reset and reboot
ResetFactory();
if (factoryResetCounter > 3) // normal reboot
#if defined(ESP8266)
ESP.reset();
#endif
#if defined(ESP32)
ESP.restart();
#endif
factoryResetCounter = 0; // count was < 3, reset counter
}
}
+147 -110
View File
@@ -44,6 +44,10 @@ bool readyForSleep()
{
if (!isDeepSleepEnabled())
return false;
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
// Allow 6 seconds to connect to WiFi
return timeOutReached(timerAwakeFromDeepSleep + 6000);
}
return timeOutReached(timerAwakeFromDeepSleep + 1000 * Settings.deepSleep);
}
@@ -317,7 +321,7 @@ void statusLED(boolean traffic)
else
{
if (WiFi.status() == WL_CONNECTED)
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED)
{
long int delta = timePassedSince(gnLastUpdate);
if (delta>0 || delta<0 )
@@ -328,7 +332,7 @@ void statusLED(boolean traffic)
}
}
//AP mode is active
else if (WifiIsAP())
else if (WifiIsAP(WiFi.getMode()))
{
nStatusValue = ((millis()>>1) & PWMRANGE) - (PWMRANGE>>2); //ramp up for 2 sec, 3/4 luminosity
}
@@ -478,6 +482,13 @@ String BuildFixes()
f.close();
}
}
if (Settings.Build < 20101)
{
Serial.println(F("Fix reset Pin"));
Settings.Pin_Reset = -1;
}
Settings.Build = BUILD;
return(SaveSettings());
}
@@ -690,25 +701,36 @@ String SaveSettings(void)
{
checkRAM(F("SaveSettings"));
MD5Builder md5;
uint8_t tmp_md5[16] = {0};
memcpy( Settings.ProgmemMd5, CRCValues.runTimeMD5, 16);
md5.begin();
md5.add((uint8_t *)&Settings, sizeof(Settings)-16);
md5.calculate();
md5.getBytes(Settings.md5);
md5.getBytes(tmp_md5);
String err;
err=SaveToFile((char*)FILE_CONFIG, 0, (byte*)&Settings, sizeof(struct SettingsStruct));
if (err.length())
return(err);
if (memcmp(tmp_md5, Settings.md5, 16) != 0) {
// Settings have changed, save to file.
memcpy(Settings.md5, tmp_md5, 16);
err=SaveToFile((char*)FILE_CONFIG, 0, (byte*)&Settings, sizeof(struct SettingsStruct));
if (err.length())
return(err);
}
memcpy( SecuritySettings.ProgmemMd5, CRCValues.runTimeMD5, 16);
md5.begin();
md5.add((uint8_t *)&SecuritySettings, sizeof(SecuritySettings)-16);
md5.calculate();
md5.getBytes(SecuritySettings.md5);
err=SaveToFile((char*)FILE_SECURITY, 0, (byte*)&SecuritySettings, sizeof(struct SecurityStruct));
return (err);
md5.getBytes(tmp_md5);
if (memcmp(tmp_md5, SecuritySettings.md5, 16) != 0) {
// Settings have changed, save to file.
memcpy(SecuritySettings.md5, tmp_md5, 16);
err=SaveToFile((char*)FILE_SECURITY, 0, (byte*)&SecuritySettings, sizeof(struct SecurityStruct));
if (WifiIsAP(WiFi.getMode())) {
// Security settings are saved, may be update of WiFi settings or hostname.
wifiSetupConnect = true;
}
}
return (err);
}
/********************************************************************************************\
@@ -1091,6 +1113,7 @@ void ResetFactory(void)
Settings.Pin_status_led = -1;
Settings.Pin_status_led_Inversed = true;
Settings.Pin_sd_cs = -1;
Settings.Pin_Reset = -1;
Settings.Protocol[0] = DEFAULT_PROTOCOL;
strcpy_P(Settings.Name, PSTR(DEFAULT_NAME));
Settings.deepSleep = false;
@@ -1163,7 +1186,8 @@ void ResetFactory(void)
//NOTE: this is a known ESP8266 bug, not our fault. :)
delay(1000);
WiFi.persistent(true); // use SDK storage of SSID/WPA parameters
WiFi.disconnect(); // this will store empty ssid/wpa into sdk storage
intent_to_reboot = true;
WifiDisconnect(); // this will store empty ssid/wpa into sdk storage
WiFi.persistent(false); // Do not use SDK storage of SSID/WPA parameters
#if defined(ESP8266)
ESP.reset();
@@ -1308,6 +1332,8 @@ boolean loglevelActiveFor(byte destination, byte logLevel) {
case LOG_TO_SERIAL: {
if (!SerialAvailableForWrite()) return false;
logLevelSettings = Settings.SerialLogLevel;
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED)
logLevelSettings = 2;
break;
}
case LOG_TO_SYSLOG: {
@@ -1336,6 +1362,8 @@ boolean loglevelActive(byte logLevel, byte logLevelSettings) {
void addLog(byte logLevel, const char *line)
{
if (loglevelActiveFor(LOG_TO_SERIAL, logLevel)) {
Serial.print(millis());
Serial.print(F(" : "));
Serial.println(line);
}
if (loglevelActiveFor(LOG_TO_SYSLOG, logLevel)) {
@@ -1383,7 +1411,9 @@ void delayedReboot(int rebootDelay)
\*********************************************************************************************/
boolean saveToRTC()
{
#if defined(ESP8266)
#if defined(ESP32)
return false;
#else
if (!system_rtc_mem_write(RTC_BASE_STRUCT, (byte*)&RTC, sizeof(RTC)) || !readFromRTC())
{
addLog(LOG_LEVEL_ERROR, F("RTC : Error while writing to RTC"));
@@ -1394,9 +1424,6 @@ boolean saveToRTC()
return(true);
}
#endif
#if defined(ESP32)
boolean ret = false;
#endif
}
@@ -1419,17 +1446,12 @@ void initRTC()
\*********************************************************************************************/
boolean readFromRTC()
{
#if defined(ESP8266)
#if defined(ESP32)
return false;
#else
if (!system_rtc_mem_read(RTC_BASE_STRUCT, (byte*)&RTC, sizeof(RTC)))
return(false);
if (RTC.ID1 == 0xAA && RTC.ID2 == 0x55)
return true;
else
return false;
#endif
#if defined(ESP32)
boolean ret = false;
return (RTC.ID1 == 0xAA && RTC.ID2 == 0x55);
#endif
}
@@ -1439,18 +1461,17 @@ boolean readFromRTC()
\*********************************************************************************************/
boolean saveUserVarToRTC()
{
#if defined(ESP8266)
#if defined(ESP32)
return false;
#else
//addLog(LOG_LEVEL_DEBUG, F("RTCMEM: saveUserVarToRTC"));
byte* buffer = (byte*)&UserVar;
size_t size = sizeof(UserVar);
uint32_t sum = getChecksum(buffer, size);
boolean ret = system_rtc_mem_write(RTC_BASE_USERVAR, buffer, size);
ret &= system_rtc_mem_write(RTC_BASE_USERVAR+(size>>2), (byte*)&sum, 4);
return ret;
#endif
#if defined(ESP32)
boolean ret = false;
#endif
return ret;
}
@@ -1459,7 +1480,9 @@ boolean saveUserVarToRTC()
\*********************************************************************************************/
boolean readUserVarFromRTC()
{
#if defined(ESP8266)
#if defined(ESP32)
return false;
#else
//addLog(LOG_LEVEL_DEBUG, F("RTCMEM: readUserVarFromRTC"));
byte* buffer = (byte*)&UserVar;
size_t size = sizeof(UserVar);
@@ -1472,11 +1495,8 @@ boolean readUserVarFromRTC()
addLog(LOG_LEVEL_ERROR, F("RTC : Checksum error on reading RTC user var"));
memset(buffer, 0, size);
}
return ret;
#endif
#if defined(ESP32)
boolean ret = false;
#endif
return ret;
}
@@ -1513,87 +1533,104 @@ String parseTemplate(String &tmpString, byte lineSize)
newString += tmpString.substring(0, leftBracketIndex);
tmpString = tmpString.substring(leftBracketIndex + 1);
int rightBracketIndex = tmpString.indexOf(']');
if (rightBracketIndex)
if (rightBracketIndex >= 0)
{
tmpStringMid = tmpString.substring(0, rightBracketIndex);
tmpString = tmpString.substring(rightBracketIndex + 1);
int hashtagIndex = tmpStringMid.indexOf('#');
String deviceName = tmpStringMid.substring(0, hashtagIndex);
String valueName = tmpStringMid.substring(hashtagIndex + 1);
String valueFormat = "";
hashtagIndex = valueName.indexOf('#');
if (hashtagIndex >= 0)
{
valueFormat = valueName.substring(hashtagIndex + 1);
valueName = valueName.substring(0, hashtagIndex);
}
if (deviceName.equalsIgnoreCase("Plugin"))
{
String tmpString = tmpStringMid.substring(7);
tmpString.replace("#", ",");
if (PluginCall(PLUGIN_REQUEST, 0, tmpString))
newString += tmpString;
}
else
for (byte y = 0; y < TASKS_MAX; y++)
if (hashtagIndex >= 0) {
String deviceName = tmpStringMid.substring(0, hashtagIndex);
String valueName = tmpStringMid.substring(hashtagIndex + 1);
String valueFormat = "";
hashtagIndex = valueName.indexOf('#');
if (hashtagIndex >= 0)
{
if (Settings.TaskDeviceEnabled[y])
valueFormat = valueName.substring(hashtagIndex + 1);
valueName = valueName.substring(0, hashtagIndex);
}
if (deviceName.equalsIgnoreCase("Plugin"))
{
String tmpString = tmpStringMid.substring(7);
tmpString.replace("#", ",");
if (PluginCall(PLUGIN_REQUEST, 0, tmpString))
newString += tmpString;
}
else
for (byte y = 0; y < TASKS_MAX; y++)
{
LoadTaskSettings(y);
if (ExtraTaskSettings.TaskDeviceName[0] != 0)
if (Settings.TaskDeviceEnabled[y])
{
if (deviceName.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceName))
LoadTaskSettings(y);
if (ExtraTaskSettings.TaskDeviceName[0] != 0)
{
boolean match = false;
for (byte z = 0; z < VARS_PER_TASK; z++)
if (valueName.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceValueNames[z]))
{
// here we know the task and value, so find the uservar
match = true;
String value = "";
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[y]);
if (Device[DeviceIndex].VType == SENSOR_TYPE_LONG)
value = (unsigned long)UserVar[y * VARS_PER_TASK + z] + ((unsigned long)UserVar[y * VARS_PER_TASK + z + 1] << 16);
else
value = toString(UserVar[y * VARS_PER_TASK + z], ExtraTaskSettings.TaskDeviceValueDecimals[z]);
int oidx;
if ((oidx = valueFormat.indexOf('O')) >= 0) // Output
{
valueFormat.remove(oidx);
oidx = valueFormat.indexOf('!'); // inverted or active low
float val = value.toFloat();
if (oidx >= 0) {
valueFormat.remove(oidx);
value = val == 0 ? " ON" : "OFF";
} else {
value = val == 0 ? "OFF" : " ON";
}
}
if (valueFormat == "R")
{
int filler = lineSize - newString.length() - value.length() - tmpString.length() ;
for (byte f = 0; f < filler; f++)
newString += " ";
}
newString += String(value);
break;
}
if (!match) // try if this is a get config request
if (deviceName.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceName))
{
struct EventStruct TempEvent;
TempEvent.TaskIndex = y;
String tmpName = valueName;
if (PluginCall(PLUGIN_GET_CONFIG, &TempEvent, tmpName))
newString += tmpName;
boolean match = false;
for (byte z = 0; z < VARS_PER_TASK; z++)
if (valueName.equalsIgnoreCase(ExtraTaskSettings.TaskDeviceValueNames[z]))
{
// here we know the task and value, so find the uservar
match = true;
String value = "";
byte DeviceIndex = getDeviceIndex(Settings.TaskDeviceNumber[y]);
if (Device[DeviceIndex].VType == SENSOR_TYPE_LONG)
value = (unsigned long)UserVar[y * VARS_PER_TASK + z] + ((unsigned long)UserVar[y * VARS_PER_TASK + z + 1] << 16);
else
value = toString(UserVar[y * VARS_PER_TASK + z], ExtraTaskSettings.TaskDeviceValueDecimals[z]);
if (valueFormat.length() > 0) //do the checks only if a Format is defined to optimize loop
{
const int val = value == "0" ? 0 : 1; //to be used for GPIO status (0 or 1)
const float valFloat = value.toFloat();
const int inverted = valueFormat.indexOf('!') >= 0 ? 1 : 0;
if (valueFormat.indexOf('O') >= 0)
value = val == inverted ? "OFF" : " ON"; //(equivalent to XOR operator)
else if (valueFormat.indexOf('C') >= 0)
value = val == inverted ? "CLOSE" : " OPEN";
else if (valueFormat.indexOf('U') >= 0)
value = val == inverted ? "DOWN" : " UP";
else if (valueFormat.indexOf('Y') >= 0)
value = val == inverted ? " NO" : "YES";
else if (valueFormat.indexOf('y') >= 0)
value = val == inverted ? "N" : "Y";
else if (valueFormat.indexOf('X') >= 0)
value = val == inverted ? "O" : "X";
else if (valueFormat.indexOf('I') >= 0)
value = val == inverted ? "OUT" : " IN";
else if (valueFormat.indexOf('Z') >= 0) // return "0" or "1"
value = val == inverted ? "0" : "1";
else if (valueFormat.indexOf('D') >= 0) // round to the nearest integer
value = (int)roundf(valFloat);
else if (valueFormat.indexOf('F') >= 0) // FLOOR (round down)
value = (int)floorf(valFloat);
else if (valueFormat.indexOf('E') >= 0) // CEILING (round up)
value = (int)ceilf(valFloat);
if (valueFormat.indexOf('R') >= 0) {
int filler = lineSize - newString.length() - value.length() - tmpString.length() ;
for (byte f = 0; f < filler; f++)
newString += " ";
}
}
newString += String(value);
break;
}
if (!match) // try if this is a get config request
{
struct EventStruct TempEvent;
TempEvent.TaskIndex = y;
String tmpName = valueName;
if (PluginCall(PLUGIN_GET_CONFIG, &TempEvent, tmpName))
newString += tmpName;
}
break;
}
break;
}
}
}
}
}
}
leftBracketIndex = tmpString.indexOf('[');
count++;
@@ -1615,7 +1652,6 @@ String parseTemplate(String &tmpString, byte lineSize)
return newString;
}
/********************************************************************************************\
Calculate function for simple expressions
\*********************************************************************************************/
@@ -1959,8 +1995,6 @@ String rulesProcessingFile(String fileName, String& event)
Serial.println(fileName);
Serial.println(F(" flags CMI parse output:"));
}
fs::File f = SPIFFS.open(fileName, "r+");
SPIFFS_CHECK(f, fileName.c_str());
static byte nestingLevel = 0;
int data = 0;
@@ -1975,6 +2009,9 @@ String rulesProcessingFile(String fileName, String& event)
return (log);
}
fs::File f = SPIFFS.open(fileName, "r+");
SPIFFS_CHECK(f, fileName.c_str());
String line = "";
boolean match = false;
boolean codeBlock = false;
@@ -2013,7 +2050,7 @@ String rulesProcessingFile(String fileName, String& event)
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
@@ -2060,9 +2097,9 @@ String rulesProcessingFile(String fileName, String& event)
{
isCommand = false;
codeBlock = false;
match = false;
match = false;
}
if (Settings.SerialLogLevel == LOG_LEVEL_DEBUG_DEV){
Serial.print(F("RuleDebug: "));
Serial.print(codeBlock);
@@ -2071,7 +2108,7 @@ String rulesProcessingFile(String fileName, String& event)
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
+6 -8
View File
@@ -12,7 +12,7 @@
\*********************************************************************************************/
void syslog(const char *message)
{
if (Settings.Syslog_IP[0] != 0 && WiFi.status() == WL_CONNECTED)
if (Settings.Syslog_IP[0] != 0 && wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED)
{
IPAddress broadcastIP(Settings.Syslog_IP[0], Settings.Syslog_IP[1], Settings.Syslog_IP[2], Settings.Syslog_IP[3]);
portUDP.beginPacket(broadcastIP, 514);
@@ -596,12 +596,10 @@ 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) {
// Apparently something needs network, perform check to see if it is ready now.
// if (!tryConnectWiFi())
// return false;
while (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
if (timeOutReached(timer)) {
return false;
}
@@ -624,7 +622,7 @@ bool hostReachable(const IPAddress& ip) {
--retry;
}
String log = F("Host unreachable: ");
log += ip;
log += formatIP(ip);
addLog(LOG_LEVEL_ERROR, log);
return false;
}
+13 -2
View File
@@ -54,6 +54,12 @@ void formatMAC(const uint8_t* mac, char (&strMAC)[20]) {
sprintf_P(strMAC, PSTR("%02X:%02X:%02X:%02X:%02X:%02X"), mac[0], mac[1], mac[2], mac[3], mac[4], mac[5]);
}
String formatMAC(const uint8_t* mac) {
char str[20];
formatMAC(mac, str);
return String(str);
}
/*********************************************************************************************\
Workaround for removing trailing white space when String() converts a float with 0 decimals
\*********************************************************************************************/
@@ -278,8 +284,10 @@ void parseSystemVariables(String& s, boolean useURLencode)
repl(F("%CR%"), F("\r"), s, useURLencode);
repl(F("%LF%"), F("\n"), s, useURLencode);
SMART_REPL(F("%ip%"),WiFi.localIP().toString())
SMART_REPL(F("%rssi%"), String((WiFi.status() == WL_CONNECTED) ? WiFi.RSSI() : 0))
SMART_REPL(F("%ssid%"), (WiFi.status() == WL_CONNECTED) ? WiFi.SSID() : F("--"))
SMART_REPL(F("%rssi%"), String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? 0 : WiFi.RSSI()))
SMART_REPL(F("%ssid%"), (wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? F("--") : WiFi.SSID())
SMART_REPL(F("%bssid%"), (wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? F("00:00:00:00:00:00") : WiFi.BSSIDstr())
SMART_REPL(F("%wi_ch%"), String((wifiStatus == ESPEASY_WIFI_DISCONNECTED) ? 0 : WiFi.channel()))
SMART_REPL(F("%unit%"), String(Settings.Unit))
SMART_REPL(F("%mac%"), String(WiFi.macAddress()))
#if defined(ESP8266)
@@ -288,6 +296,7 @@ void parseSystemVariables(String& s, boolean useURLencode)
if (s.indexOf(F("%sys")) != -1) {
SMART_REPL(F("%sysload%"), String(100 - (100 * loopCounterLast / loopCounterMax)))
SMART_REPL(F("%sysheap%"), String(ESP.getFreeHeap()));
SMART_REPL(F("%systm_hm%"), getTimeString(':', false))
SMART_REPL(F("%systm_hm_am%"), getTimeString_ampm(':', false))
SMART_REPL(F("%systime%"), getTimeString(':'))
@@ -300,6 +309,7 @@ void parseSystemVariables(String& s, boolean useURLencode)
SMART_REPL_TIME(F("%syshour%"), PSTR("%02d"), hour())
SMART_REPL_TIME(F("%sysmin%"), PSTR("%02d"), minute())
SMART_REPL_TIME(F("%syssec%"),PSTR("%02d"), second())
SMART_REPL_TIME(F("%syssec_d%"),PSTR("%d"), ((hour()*60) + minute())*60 + second());
SMART_REPL_TIME(F("%sysday%"), PSTR("%02d"), day())
SMART_REPL_TIME(F("%sysmonth%"),PSTR("%02d"), month())
SMART_REPL_TIME(F("%sysyear%"), PSTR("%04d"), year())
@@ -311,6 +321,7 @@ void parseSystemVariables(String& s, boolean useURLencode)
SMART_REPL(F("%lcltime%"), getDateTimeString('-',':',' '))
SMART_REPL(F("%lcltime_am%"), getDateTimeString_ampm('-',':',' '))
SMART_REPL(F("%uptime%"), String(wdcounter / 2))
SMART_REPL(F("%unixtime%"), String(getUnixTime()))
repl(F("%tskname%"), ExtraTaskSettings.TaskDeviceName, s, useURLencode);
if (s.indexOf("%vname") != -1) {
+31 -13
View File
@@ -72,6 +72,7 @@ void breakTime(unsigned long timeInput, struct timeStruct &tm) {
void setTime(unsigned long t) {
sysTime = (uint32_t)t;
applyTimeZone(t);
nextSyncTime = (uint32_t)t + syncInterval;
prevMillis = millis(); // restart counting from now (thanks to Korman for this fix)
if (Settings.UseRules)
@@ -83,6 +84,10 @@ void setTime(unsigned long t) {
}
}
uint32_t getUnixTime() {
return sysTime;
}
unsigned long now() {
// calculate number of seconds passed since last call to now()
const long msec_passed = timePassedSince(prevMillis);
@@ -94,10 +99,6 @@ unsigned long now() {
unsigned long t = getNtpTime();
if (t != 0) {
setTime(t);
applyTimeZone(t);
} else {
// Unable to sync, retry again in a minute
nextSyncTime = sysTime + 60;
}
}
uint32_t localSystime = toLocal(sysTime);
@@ -197,19 +198,36 @@ void checkTime()
unsigned long getNtpTime()
{
if (!Settings.UseNTP || !WiFiConnected(100)) {
if (!Settings.UseNTP || !WiFiConnected(10)) {
return 0;
}
IPAddress timeServerIP;
const char* ntpServerName = "pool.ntp.org";
// Have to do a lookup eacht time, since the NTP pool always returns another IP
if (Settings.NTPHost[0] != 0)
String log = F("NTP : NTP host ");
if (Settings.NTPHost[0] != 0) {
WiFi.hostByName(Settings.NTPHost, timeServerIP);
else
WiFi.hostByName(ntpServerName, timeServerIP);
log += Settings.NTPHost;
// When single set host fails, retry again in a minute
nextSyncTime = sysTime + 20;
}
else {
// Have to do a lookup eacht time, since the NTP pool always returns another IP
String ntpServerName = String(random(0, 3));
ntpServerName += F(".pool.ntp.org");
WiFi.hostByName(ntpServerName.c_str(), timeServerIP);
log += ntpServerName;
// When pool host fails, retry can be much sooner
nextSyncTime = sysTime + 5;
}
if (!hostReachable(timeServerIP))
log += F(" (");
log += timeServerIP.toString();
log += F(")");
if (!hostReachable(timeServerIP)) {
log += F(" unreachable");
addLog(LOG_LEVEL_INFO, log);
return 0;
}
WiFiUDP udp;
udp.begin(123);
@@ -217,8 +235,7 @@ unsigned long getNtpTime()
const int NTP_PACKET_SIZE = 48; // NTP time is in the first 48 bytes of message
byte packetBuffer[NTP_PACKET_SIZE]; //buffer to hold incoming & outgoing packets
String log = F("NTP : NTP send to ");
log += timeServerIP.toString();
log += F(" queried");
addLog(LOG_LEVEL_DEBUG_MORE, log);
while (udp.parsePacket() > 0) ; // discard any previously received packets
@@ -253,6 +270,7 @@ unsigned long getNtpTime()
addLog(LOG_LEVEL_DEBUG_MORE, log);
return secsSince1900 - 2208988800UL;
}
delay(10);
}
log = F("NTP : No reply");
addLog(LOG_LEVEL_DEBUG_MORE, log);
+837 -761
View File
File diff suppressed because it is too large Load Diff
-475
View File
@@ -1,475 +0,0 @@
//********************************************************************************
// Determine Wifi AP name to set. (also used for mDNS)
//********************************************************************************
String WifiGetAPssid()
{
String ssid(Settings.Name);
ssid+=F("_");
ssid+=Settings.Unit;
return (ssid);
}
//********************************************************************************
// Determine hostname: basically WifiGetAPssid with spaces changed to -
//********************************************************************************
String WifiGetHostname()
{
String hostname(WifiGetAPssid());
hostname.replace(F(" "), F("-"));
return (hostname);
}
//********************************************************************************
// Set Wifi AP Mode config
//********************************************************************************
void WifiAPconfig()
{
// create and store unique AP SSID/PW to prevent ESP from starting AP mode with default SSID and No password!
// setup ssid for AP Mode when needed
WiFi.softAP(WifiGetAPssid().c_str(), SecuritySettings.WifiAPKey);
// We start in STA mode
WifiAPMode(false);
String log("WIFI : AP Mode ssid will be ");
log=log+WifiGetAPssid();
log=log+F(" with address ");
log=log+apIP.toString();
addLog(LOG_LEVEL_INFO, log);
}
bool WifiIsAP()
{
#if defined(ESP8266)
byte wifimode = wifi_get_opmode();
#endif
#if defined(ESP32)
byte wifimode = WiFi.getMode();
#endif
return(wifimode == 2 || wifimode == 3); //apmode is enabled
}
//********************************************************************************
// Set Wifi AP Mode
//********************************************************************************
void WifiAPMode(boolean state)
{
if (WifiIsAP())
{
//want to disable?
if (!state)
{
WiFi.mode(WIFI_STA);
addLog(LOG_LEVEL_INFO, F("WIFI : AP Mode disabled"));
}
}
else
{
//want to enable?
if (state)
{
WiFi.mode(WIFI_AP_STA);
addLog(LOG_LEVEL_INFO, F("WIFI : AP Mode enabled"));
}
}
}
//********************************************************************************
// Set Wifi config
//********************************************************************************
void prepareWiFi() {
String log = "";
char hostname[40];
strncpy(hostname, WifiGetHostname().c_str(), sizeof(hostname));
#if defined(ESP8266)
wifi_station_set_hostname(hostname);
#endif
#if defined(ESP32)
WiFi.setHostname(hostname);
#endif
//use static ip?
if (Settings.IP[0] != 0 && Settings.IP[0] != 255)
{
const IPAddress ip = Settings.IP;
log = F("IP : Static IP :");
log += ip;
addLog(LOG_LEVEL_INFO, log);
const IPAddress gw = Settings.Gateway;
const IPAddress subnet = Settings.Subnet;
const IPAddress dns = Settings.DNS;
WiFi.config(ip, gw, subnet, dns);
}
}
//********************************************************************************
// 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);
}
}
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 WifiConnectAndWait(byte connectAttempts)
{
String log;
wifiConnected = false;
wifi_connect_attempt = 0;
for (byte tryConnect = 0; tryConnect < connectAttempts; tryConnect++)
{
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
//********************************************************************************
void WifiDisconnect()
{
WiFi.disconnect();
wifiConnected = false;
}
//********************************************************************************
// Scan all Wifi Access Points
//********************************************************************************
void WifiScan()
{
// Direct Serial is allowed here, since this function will only be called from serial input.
Serial.println(F("WIFI : SSID Scan start"));
int n = WiFi.scanNetworks();
if (n == 0)
Serial.println(F("WIFI : No networks found"));
else
{
Serial.print(F("WIFI : "));
Serial.print(n);
Serial.println(F(" networks found"));
for (int i = 0; i < n; ++i)
{
// Print SSID and RSSI for each network found
Serial.print(F("WIFI : "));
Serial.print(i + 1);
Serial.print(": ");
Serial.print(WiFi.SSID(i));
Serial.print(" (");
Serial.print(WiFi.RSSI(i));
Serial.print(")");
Serial.println("");
delay(10);
}
}
Serial.println("");
}
//********************************************************************************
// Check if we are still connected to a Wifi AP
//********************************************************************************
void WifiCheck()
{
if(wifiSetup)
return;
if (WiFi.status() != WL_CONNECTED)
{
NC_Count++;
//give it time to automatically reconnect
if (NC_Count > 2)
{
if (wifiConnected) {
wifi_connect_attempt = 0;
wifiConnected = false;
WiFiConnectRelaxed();
}
C_Count=0;
NC_Count = 0;
}
}
//connected
else
{
C_Count++;
NC_Count = 0;
if (C_Count > 2) // disable AP after timeout if a Wifi connection is established...
{
WifiAPMode(false);
}
}
if (!wifiConnected) {
if (tryConnectWiFi())
checkWifiJustConnected();
}
}
//********************************************************************************
// Return subnet range of WiFi.
//********************************************************************************
bool getSubnetRange(IPAddress& low, IPAddress& high)
{
if (WifiIsAP()) {
// WiFi is active as accesspoint, do not check.
return false;
}
if (WiFi.status() != WL_CONNECTED) {
return false;
}
const IPAddress ip = WiFi.localIP();
const IPAddress subnet = WiFi.subnetMask();
low = ip;
high = ip;
// Compute subnet range.
for (byte i=0; i < 4; ++i) {
if (subnet[i] != 255) {
low[i] = low[i] & subnet[i];
high[i] = high[i] | ~subnet[i];
}
}
return true;
}
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C001
//#######################################################################################################
//########################### Controller Plugin 001: Domoticz HTTP ######################################
//#######################################################################################################
@@ -165,3 +166,4 @@ boolean CPlugin_001(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C002
//#######################################################################################################
//########################### Controller Plugin 002: Domoticz MQTT ######################################
//#######################################################################################################
@@ -209,3 +210,4 @@ boolean CPlugin_002(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C003
//#######################################################################################################
//########################### Controller Plugin 003: Nodo Telnet #######################################
//#######################################################################################################
@@ -107,3 +108,4 @@ boolean CPlugin_003(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C004
//#######################################################################################################
//########################### Controller Plugin 004: ThingSpeak #########################################
//#######################################################################################################
@@ -127,3 +128,4 @@ boolean CPlugin_004(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C005
//#######################################################################################################
//########################### Controller Plugin 005: OpenHAB MQTT #######################################
//#######################################################################################################
@@ -122,3 +123,4 @@ boolean CPlugin_005(byte function, struct EventStruct *event, String& string)
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C006
//#######################################################################################################
//########################### Controller Plugin 006: PiDome MQTT ########################################
//#######################################################################################################
@@ -109,3 +110,4 @@ boolean CPlugin_006(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C007
//#######################################################################################################
//########################### Controller Plugin 007: Emoncms ############################################
//#######################################################################################################
@@ -122,3 +123,4 @@ boolean CPlugin_007(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C008
//#######################################################################################################
//########################### Controller Plugin 008: Generic HTTP #######################################
//#######################################################################################################
@@ -151,3 +152,4 @@ boolean HTTPSend(struct EventStruct *event, byte varIndex, float value, unsigned
return(true);
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_C009
//#######################################################################################################
//########################### Controller Plugin 009: FHEM HTTP ##########################################
//#######################################################################################################
@@ -197,3 +198,4 @@ void FHEMHTTPsend(String & url, String & buffer, byte index)
client.flush();
client.stop();
}
#endif
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_C010
//#######################################################################################################
//########################### Controller Plugin 010: Generic UDP ########################################
//#######################################################################################################
@@ -87,7 +88,7 @@ void C010_Send(struct EventStruct *event, byte varIndex, float value, unsigned l
else
msg.replace(F("%value%"), toString(value, ExtraTaskSettings.TaskDeviceValueDecimals[varIndex]));
if (WiFi.status() == WL_CONNECTED) {
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
ControllerSettings.beginPacket(portUDP);
portUDP.write((uint8_t*)msg.c_str(),msg.length());
portUDP.endPacket();
@@ -97,3 +98,4 @@ void C010_Send(struct EventStruct *event, byte varIndex, float value, unsigned l
addLog(LOG_LEVEL_DEBUG_MORE, log);
}
#endif
+3 -1
View File
@@ -1,8 +1,9 @@
#ifdef USES_C011
//#######################################################################################################
//########################### Controller Plugin 011: Generic HTTP #######################################
//#######################################################################################################
#ifdef PLUGIN_BUILD_TESTING
// #ifdef PLUGIN_BUILD_TESTING
#define CPLUGIN_011
#define CPLUGIN_ID_011 11
@@ -283,3 +284,4 @@ void ReplaceTokenByValue(String& s, struct EventStruct *event)
}
#endif
+4 -3
View File
@@ -1,8 +1,9 @@
#ifdef USES_C012
//#######################################################################################################
//########################### Controller Plugin 012: Blynk #############################################
//#######################################################################################################
#ifdef PLUGIN_BUILD_TESTING
// #ifdef PLUGIN_BUILD_TESTING
#define CPLUGIN_012
#define CPLUGIN_ID_012 12
@@ -33,7 +34,7 @@ boolean CPlugin_012(byte function, struct EventStruct *event, String& string)
case CPLUGIN_PROTOCOL_SEND:
{
if (WiFi.status() != WL_CONNECTED) {
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
success = false;
break;
}
@@ -63,7 +64,7 @@ boolean CPlugin_012_send(struct EventStruct *event, int nrValues) {
boolean Blynk_get(const String& command, byte controllerIndex, float *data )
{
if (WiFi.status() != WL_CONNECTED) {
if (wifiStatus != ESPEASY_WIFI_SERVICES_INITIALIZED) {
return false;
}
+2 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_C013
//#######################################################################################################
//########################### Controller Plugin 013: ESPEasy P2P network ################################
//#######################################################################################################
@@ -262,4 +263,4 @@ void C013_Receive(struct EventStruct *event) {
}
}
}
#endif
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_N001
//#######################################################################################################
//########################### Notification Plugin 001: Email ############################################
//#######################################################################################################
@@ -174,3 +175,4 @@ boolean NPlugin_001_MTA(WiFiClient& client, String aStr, const String &aWaitForP
return false;
}
#endif
+5
View File
@@ -1,3 +1,4 @@
#ifdef USES_N002
//#######################################################################################################
//########################### Notification Plugin 002: Buzzer ###########################################
//#######################################################################################################
@@ -46,10 +47,14 @@ boolean NPlugin_002(byte function, struct EventStruct *event, String& string)
NotificationSettingsStruct NotificationSettings;
LoadNotificationSettings(event->NotificationIndex, (byte*)&NotificationSettings, sizeof(NotificationSettings));
//this reserves IRAM and uninitialized RAM
#ifndef ESP32
// Buzzer not compatible with ESP32 due to lack of tone command.
tone(NotificationSettings.Pin1, 500, 500);
#endif
success = true;
}
}
return success;
}
#endif
+7 -5
View File
@@ -1,3 +1,4 @@
#ifdef USES_P001
//#######################################################################################################
//#################################### Plugin 001: Input Switch #########################################
//#######################################################################################################
@@ -68,13 +69,13 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
options[1] = F("Dimmer");
int optionValues[2] = { PLUGIN_001_TYPE_SWITCH, PLUGIN_001_TYPE_DIMMER };
const byte switchtype = P001_getSwitchType(event);
addFormSelector(string, F("Switch Type"), F("plugin_001_type"), 2, options, optionValues, switchtype);
addFormSelector(F("Switch Type"), F("plugin_001_type"), 2, options, optionValues, switchtype);
if (switchtype == PLUGIN_001_TYPE_DIMMER)
{
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Dim value:<TD><input type='text' name='plugin_001_dimvalue' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
string += tmpString;
addHtml(tmpString);
}
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
@@ -83,9 +84,9 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
buttonOptions[1] = F("Push Button Active Low");
buttonOptions[2] = F("Push Button Active High");
int buttonOptionValues[3] = {PLUGIN_001_BUTTON_TYPE_NORMAL_SWITCH, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_LOW, PLUGIN_001_BUTTON_TYPE_PUSH_ACTIVE_HIGH};
addFormSelector(string, F("Switch Button Type"), F("plugin_001_button"), 3, buttonOptions, buttonOptionValues, choice);
addFormSelector(F("Switch Button Type"), F("plugin_001_button"), 3, buttonOptions, buttonOptionValues, choice);
addFormCheckBox(string, F("Send Boot state"),F("plugin_001_boot"),
addFormCheckBox(F("Send Boot state"),F("plugin_001_boot"),
Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
success = true;
@@ -148,7 +149,7 @@ boolean Plugin_001(byte function, struct EventStruct *event, String& string)
}
break;
}
case PLUGIN_UNCONDITIONAL_POLL:
{
// port monitoring, on request by rule command
@@ -480,3 +481,4 @@ byte P001_getSwitchType(struct EventStruct *event) {
}
return choice;
}
#endif // USES_P001
+14 -12
View File
@@ -1,3 +1,4 @@
#ifdef USES_P002
//#######################################################################################################
//#################################### Plugin 002: Analog ###############################################
//#######################################################################################################
@@ -48,23 +49,23 @@ boolean Plugin_002(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
#if defined(ESP32)
string += F("<TR><TD>Analog Pin:<TD>");
addPinSelect(false, string, "taskdevicepin1", Settings.TaskDevicePin1[event->TaskIndex]);
addHtml(F("<TR><TD>Analog Pin:<TD>"));
addPinSelect(false, "taskdevicepin1", Settings.TaskDevicePin1[event->TaskIndex]);
#endif
addFormCheckBox(string, F("Oversampling"), F("plugin_002_oversampling"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormSubHeader(string, F("Two Point Calibration"));
addFormCheckBox(F("Oversampling"), F("plugin_002_oversampling"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_002_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addFormSubHeader(F("Two Point Calibration"));
addFormNumericBox(string, F("Point 1"), F("plugin_002_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 1023);
string += F(" &#8793; ");
addTextBox(string, F("plugin_002_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
addFormCheckBox(F("Calibration Enabled"), F("plugin_002_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addFormNumericBox(string, F("Point 2"), F("plugin_002_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 1023);
string += F(" &#8793; ");
addTextBox(string, F("plugin_002_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
addFormNumericBox(F("Point 1"), F("plugin_002_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], 0, 1023);
addHtml(F(" &#8793; "));
addTextBox(F("plugin_002_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
addFormNumericBox(F("Point 2"), F("plugin_002_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], 0, 1023);
addHtml(F(" &#8793; "));
addTextBox(F("plugin_002_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
success = true;
break;
@@ -150,3 +151,4 @@ boolean Plugin_002(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P002
+6 -4
View File
@@ -1,3 +1,4 @@
#ifdef USES_P003
//#######################################################################################################
//#################################### Plugin 003: Pulse ###############################################
//#######################################################################################################
@@ -64,16 +65,16 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(string, F("Debounce Time (mSec)"), F("plugin_003")
addFormNumericBox(F("Debounce Time (mSec)"), F("plugin_003")
, Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
String options[4] = { F("Delta"), F("Delta/Total/Time"), F("Total"), F("Delta/Total") };
addFormSelector(string, F("Counter Type"), F("plugin_003_countertype"), 4, options, NULL, choice );
addFormSelector(F("Counter Type"), F("plugin_003_countertype"), 4, options, NULL, choice );
if (choice !=0)
string += F("<span style=\"color:red\">Total count is not persistent!</span>");
addHtml(F("<span style=\"color:red\">Total count is not persistent!</span>"));
String modeRaise[4];
modeRaise[0] = F("LOW");
@@ -86,7 +87,7 @@ boolean Plugin_003(byte function, struct EventStruct *event, String& string)
modeValues[2] = RISING;
modeValues[3] = FALLING;
addFormSelector(string, F("Mode Type"), F("plugin_003_raisetype"), 4, modeRaise, modeValues, choice2 );
addFormSelector(F("Mode Type"), F("plugin_003_raisetype"), 4, modeRaise, modeValues, choice2 );
success = true;
break;
@@ -267,3 +268,4 @@ bool Plugin_003_pulseinit(byte Par1, byte Index, byte Mode)
return(true);
}
#endif // USES_P003
+14 -8
View File
@@ -1,3 +1,4 @@
#ifdef USES_P004
// #######################################################################################################
// #################################### Plugin 004: TempSensor Dallas DS18B20 ###########################
// #######################################################################################################
@@ -63,9 +64,9 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
savedAddress[i] = ExtraTaskSettings.TaskDevicePluginConfigLong[i];
// find all suitable devices
addRowLabel(string, F("Device Address"));
addSelector_Head(string, F("plugin_004_dev"), false);
addSelector_Item(string, "", -1, false, false, F(""));
addRowLabel(F("Device Address"));
addSelector_Head(F("plugin_004_dev"), false);
addSelector_Item("", -1, false, false, F(""));
uint8_t tmpAddress[8];
byte count = 0;
Plugin_004_DS_reset();
@@ -79,10 +80,10 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
if (j < 7) option += F("-");
}
bool selected = (memcmp(tmpAddress, savedAddress, 8) == 0) ? true : false;
addSelector_Item(string, option, count, selected, false, F(""));
addSelector_Item(option, count, selected, false, F(""));
count ++;
}
addSelector_Foot(string);
addSelector_Foot();
// Device Resolution select
if (ExtraTaskSettings.TaskDevicePluginConfigLong[0] != 0)
@@ -91,8 +92,8 @@ boolean Plugin_004(byte function, struct EventStruct * event, String& string)
resolutionChoice = 9;
String resultsOptions[4] = { "9", "10", "11", "12" };
int resultsOptionValues[4] = { 9, 10, 11, 12 };
addFormSelector(string, F("Device Resolution"), F("plugin_004_res"), 4, resultsOptions, resultsOptionValues, resolutionChoice);
string += F(" Bit");
addFormSelector(F("Device Resolution"), F("plugin_004_res"), 4, resultsOptions, resultsOptionValues, resolutionChoice);
addHtml(F(" Bit"));
}
success = true;
break;
@@ -250,13 +251,17 @@ boolean Plugin_004_DS_readTemp(uint8_t ROM[8], float * value)
return false;
}
if ((ROM[0] == 0x28 ) || (ROM[0] == 0x3b)) // DS18B20 or DS1825
if ((ROM[0] == 0x28 ) || (ROM[0] == 0x3b) || (ROM[0] == 0x22)) // DS18B20 or DS1825 or DS1822
{
DSTemp = (ScratchPad[1] << 8) + ScratchPad[0];
if (DSTemp == 0x550) // power-on reset value
return false;
*value = (float(DSTemp) * 0.0625);
}
else if (ROM[0] == 0x10) // DS1820 DS18S20
{
if (ScratchPad[0] == 0xaa) // power-on reset value
return false;
DSTemp = (ScratchPad[1] << 11) | ScratchPad[0] << 3;
DSTemp = ((DSTemp & 0xfff0) << 3) - 16 +
(((ScratchPad[7] - ScratchPad[6]) << 7) / ScratchPad[7]);
@@ -653,3 +658,4 @@ boolean Plugin_004_DS_crc8(uint8_t * addr)
}
return crc == *addr; // addr 8
}
#endif // USES_P004
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P005
//#######################################################################################################
//######################## Plugin 005: Temperature and Humidity sensor DHT 11/22 ########################
//#######################################################################################################
@@ -50,7 +51,7 @@ boolean Plugin_005(byte function, struct EventStruct *event, String& string)
const String options[] = { F("DHT 11"), F("DHT 22"), F("DHT 12"), F("Sonoff am2301"), F("Sonoff si7021") };
int indices[] = { 11, 22, 12, 23, 70 };
addFormSelector(string, F("DHT Type"), F("plugin_005_dhttype"), 5, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][0] );
addFormSelector(F("DHT Type"), F("plugin_005_dhttype"), 5, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][0] );
success = true;
break;
@@ -219,3 +220,4 @@ int Plugin_005_read_dht_dat(void)
}
return result;
}
#endif // USES_P005
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P006
//#######################################################################################################
//######################## Plugin 006 BMP0685 I2C Barometric Pressure Sensor ###########################
//#######################################################################################################
@@ -49,7 +50,7 @@ boolean Plugin_006(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(string, F("Altitude [m]"), F("_p006_bmp085_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormNumericBox(F("Altitude [m]"), F("_p006_bmp085_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
success = true;
break;
}
@@ -287,3 +288,4 @@ float Plugin_006_pressureElevation(float atmospheric, int altitude) {
/*********************************************************************/
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
#endif // USES_P006
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P007
//#######################################################################################################
//#################################### Plugin 007: ExtWiredAnalog #######################################
//#######################################################################################################
@@ -69,3 +70,4 @@ boolean Plugin_007(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P007
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P008
//#######################################################################################################
//################################# Plugin 008: Wiegand RFID Tag Reader #################################
//#######################################################################################################
@@ -176,3 +177,4 @@ void Plugin_008_interrupt2()
Plugin_008_keyBuffer = Plugin_008_keyBuffer << 1; // Left shift the number (effectively multiplying by 2)
Plugin_008_bitCount++; // Increment the bit count
}
#endif // USES_P008
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P009
//#######################################################################################################
//#################################### Plugin 009: MCP23017 input #######################################
//#######################################################################################################
@@ -46,7 +47,7 @@ boolean Plugin_009(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormCheckBox(string, F("Send Boot state") ,F("plugin_009_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormCheckBox(F("Send Boot state") ,F("plugin_009_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
success = true;
break;
@@ -306,3 +307,4 @@ void Plugin_009_Config(byte Par1, byte Par2)
Wire.endTransmission();
}
}
#endif // USES_P009
+6 -4
View File
@@ -1,3 +1,4 @@
#ifdef USES_P010
//#######################################################################################################
//#################################### Plugin-010: LuxRead ############################################
//#######################################################################################################
@@ -56,8 +57,8 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
int optionValues[2];
optionValues[0] = BH1750_DEFAULT_I2CADDR;
optionValues[1] = BH1750_SECOND_I2CADDR;
addFormSelectorI2C(string, F("plugin_010"), 2, optionValues, choice);
addFormNote(string, F("ADDR Low=0x23, High=0x5c"));
addFormSelectorI2C(F("plugin_010"), 2, optionValues, choice);
addFormNote(F("ADDR Low=0x23, High=0x5c"));
byte choiceMode = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String optionsMode[4];
@@ -70,9 +71,9 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
optionValuesMode[1] = RESOLUTION_NORMAL;
optionValuesMode[2] = RESOLUTION_HIGH;
optionValuesMode[3] = RESOLUTION_AUTO_HIGH;
addFormSelector(string, F("Measurement mode"), F("plugin_010_mode"), 4, optionsMode, optionValuesMode, choiceMode);
addFormSelector(F("Measurement mode"), F("plugin_010_mode"), 4, optionsMode, optionValuesMode, choiceMode);
addFormCheckBox(string, F("Send sensor to sleep"), F("plugin_010_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addFormCheckBox(F("Send sensor to sleep"), F("plugin_010_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
success = true;
break;
@@ -124,3 +125,4 @@ boolean Plugin_010(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P010
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P011
//#######################################################################################################
//#################################### Plugin 011: Pro Mini Extender ####################################
//#######################################################################################################
@@ -47,7 +48,7 @@ boolean Plugin_011(byte function, struct EventStruct *event, String& string)
{
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2] = { F("Digital"), F("Analog") };
addFormSelector(string, F("Port Type"), F("plugin_011"), 2, options, NULL, choice);
addFormSelector(F("Port Type"), F("plugin_011"), 2, options, NULL, choice);
success = true;
break;
@@ -211,3 +212,4 @@ void Plugin_011_Write(byte Par1, byte Par2)
Wire.write((Par2 >> 8));
Wire.endTransmission();
}
#endif // USES_P011
+32 -31
View File
@@ -1,3 +1,4 @@
#ifdef USES_P012
//#######################################################################################################
//#################################### Plugin 012: LCD ##################################################
//#######################################################################################################
@@ -8,7 +9,6 @@
// Lux:[Lux#Lux#R]
// Baro:[Baro#Pressure#R]
// Pump:[Pump#on#O] -> ON/OFF
#include <LiquidCrystal_I2C.h>
LiquidCrystal_I2C *lcd=NULL;
@@ -67,7 +67,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
//options[x] = F("0x");
//options[x] += String(optionValues[x], HEX);
}
addFormSelectorI2C(string, F("plugin_012_adr"), 16, optionValues, choice);
addFormSelectorI2C(F("plugin_012_adr"), 16, optionValues, choice);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
@@ -75,30 +75,30 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
options2[0] = F("2 x 16");
options2[1] = F("4 x 20");
int optionValues2[2] = { 1, 2 };
addFormSelector(string, F("Display Size"), F("plugin_012_size"), 2, options2, optionValues2, choice2);
addFormSelector(F("Display Size"), F("plugin_012_size"), 2, options2, optionValues2, choice2);
char deviceTemplate[4][80];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
for (byte varNr = 0; varNr < 4; varNr++)
{
string += F("<TR><TD>Line ");
string += varNr + 1;
string += F(":<TD><input type='text' size='80' maxlength='80' name='Plugin_012_template");
string += varNr + 1;
string += F("' value='");
string += deviceTemplate[varNr];
string += F("'>");
addHtml(F("<TR><TD>Line "));
addHtml(String(varNr + 1));
addHtml(F(":<TD><input type='text' size='80' maxlength='80' name='Plugin_012_template"));
addHtml(String(varNr + 1));
addHtml(F("' value='"));
addHtml(deviceTemplate[varNr]);
addHtml(F("'>"));
}
addRowLabel(string, "Display button");
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
addRowLabel("Display button");
addPinSelect(false, "taskdevicepin3", Settings.TaskDevicePin3[event->TaskIndex]);
char tmpString[128];
sprintf_P(tmpString, PSTR("<TR><TD>Display Timeout:<TD><input type='text' name='plugin_12_timer' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
string += tmpString;
addHtml(tmpString);
String options3[3];
@@ -106,7 +106,7 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
options3[1] = F("Truncate exceeding message");
options3[2] = F("Clear then truncate exceeding message");
int optionValues3[3] = { 0,1,2 };
addFormSelector(string, F("LCD command Mode"), F("plugin_012_mode"), 3, options3, optionValues3, Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addFormSelector(F("LCD command Mode"), F("plugin_012_mode"), 3, options3, optionValues3, Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
success = true;
break;
@@ -226,11 +226,27 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
if (argIndex)
tmpString = tmpString.substring(0, argIndex);
if (lcd && tmpString.equalsIgnoreCase(F("LCD")))
if (lcd && tmpString.equalsIgnoreCase(F("LCDCMD")))
{
success = true;
argIndex = string.lastIndexOf(',');
tmpString = string.substring(argIndex + 1);
if (tmpString.equalsIgnoreCase(F("Off"))){
lcd->noBacklight();
}
else if (tmpString.equalsIgnoreCase(F("On"))){
lcd->backlight();
}
else if (tmpString.equalsIgnoreCase(F("Clear"))){
lcd->clear();
}
}
else if (lcd && tmpString.equalsIgnoreCase(F("LCD")))
{
success = true;
tmpString = P012_parseTemplate(string, cols);
argIndex = tmpString.lastIndexOf(',');
tmpString = tmpString.substring(argIndex + 1);
int colPos = event->Par2 - 1;
int rowPos = event->Par1 - 1;
@@ -281,22 +297,6 @@ boolean Plugin_012(byte function, struct EventStruct *event, String& string)
}
}
if (lcd && tmpString.equalsIgnoreCase(F("LCDCMD")))
{
success = true;
argIndex = string.lastIndexOf(',');
tmpString = string.substring(argIndex + 1);
if (tmpString.equalsIgnoreCase(F("Off"))){
lcd->noBacklight();
}
else if (tmpString.equalsIgnoreCase(F("On"))){
lcd->backlight();
}
else if (tmpString.equalsIgnoreCase(F("Clear"))){
lcd->clear();
}
}
break;
}
@@ -313,3 +313,4 @@ String P012_parseTemplate(String &tmpString, byte lineSize) {
result.replace(degree, degree_lcd);
return result;
}
#endif // USES_P012
+35 -45
View File
@@ -1,19 +1,19 @@
#ifdef USES_P013
//#######################################################################################################
//#################################### Plugin 013: HC-SR04 ##############################################
//############################### Plugin 013: HC-SR04, RCW-0001, etc. ###################################
//#######################################################################################################
#define PLUGIN_013
#define PLUGIN_ID_013 13
#define PLUGIN_NAME_013 "Distance - HC-SR04"
#define PLUGIN_NAME_013 "Distance - HC-SR04, RCW-0001, etc."
#define PLUGIN_VALUENAME1_013 "Distance"
void Plugin_013_interrupt() ICACHE_RAM_ATTR;
#include <NewPing.h>
boolean Plugin_013_init = false;
volatile unsigned long Plugin_013_timer = 0;
volatile unsigned long Plugin_013_state = 0;
byte Plugin_013_TRIG_Pin = 0;
byte Plugin_013_IRQ_Pin = 0;
NewPing *sonar = NULL;
boolean Plugin_013(byte function, struct EventStruct *event, String& string)
{
@@ -58,11 +58,11 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
options[0] = F("Value");
options[1] = F("State");
int optionValues[2] = { 1, 2 };
addFormSelector(string, F("Mode"), F("plugin_013_mode"), 2, options, optionValues, choice);
addFormSelector(F("Mode"), F("plugin_013_mode"), 2, options, optionValues, choice);
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 2)
{
addFormNumericBox(string, F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormNumericBox(F("Threshold"), F("plugin_013_threshold"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
}
success = true;
break;
@@ -82,21 +82,38 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
case PLUGIN_INIT:
{
Plugin_013_init = true;
pinMode(Settings.TaskDevicePin1[event->TaskIndex], OUTPUT);
pinMode(Settings.TaskDevicePin2[event->TaskIndex], INPUT_PULLUP);
Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
Plugin_013_IRQ_Pin = Settings.TaskDevicePin2[event->TaskIndex];
attachInterrupt(Settings.TaskDevicePin2[event->TaskIndex], Plugin_013_interrupt, CHANGE);
if (sonar)
{
delete sonar;
sonar=NULL;
}
sonar = new NewPing(Plugin_013_TRIG_Pin, Plugin_013_IRQ_Pin);
success = true;
break;
}
case PLUGIN_EXIT:
{
if (sonar)
{
delete sonar;
sonar=NULL;
}
break;
}
case PLUGIN_READ: // If we select value mode, read and send the value based on global timer
{
if (Settings.TaskDevicePluginConfig[event->TaskIndex][0] == 1)
{
Plugin_013_TRIG_Pin = Settings.TaskDevicePin1[event->TaskIndex];
float value = Plugin_013_read();
String log = F("SR04 : Distance: ");
String log = F("ULTRASONIC : Distance: ");
if (value > 0)
{
UserVar[event->BaseVarIndex] = value;
@@ -124,7 +141,7 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
state = 1;
if (state != switchstate[event->TaskIndex])
{
String log = F("SR04 : State ");
String log = F("ULTRASONIC : State ");
log += state;
addLog(LOG_LEVEL_INFO,log);
switchstate[event->TaskIndex] = state;
@@ -145,38 +162,11 @@ boolean Plugin_013(byte function, struct EventStruct *event, String& string)
float Plugin_013_read()
/*********************************************************************/
{
float value = -1;
Plugin_013_timer = 0;
Plugin_013_state = 0;
noInterrupts();
digitalWrite(Plugin_013_TRIG_Pin, LOW);
delayMicroseconds(2);
digitalWrite(Plugin_013_TRIG_Pin, HIGH);
delayMicroseconds(10);
digitalWrite(Plugin_013_TRIG_Pin, LOW);
interrupts();
if (!sonar)
{
return 0;
}
delay(25); // wait for measurement to finish (max 400 cm * 58 uSec = 23uSec)
if (Plugin_013_state == 2)
{
value = (float)Plugin_013_timer / 58;
}
return value;
}
/*********************************************************************/
void Plugin_013_interrupt()
/*********************************************************************/
{
byte pinState = digitalRead(Plugin_013_IRQ_Pin);
if (pinState == 1) // Start of pulse
{
Plugin_013_state = 1;
Plugin_013_timer = micros();
}
else // End of pulse, calculate timelapse between start & end
{
Plugin_013_state = 2;
Plugin_013_timer = micros() - Plugin_013_timer;
}
return sonar->ping_cm();
}
#endif // USES_P013
+4 -2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P014
//#######################################################################################################
//######################## Plugin 014 SI7021 I2C Temperature Humidity Sensor ###########################
//#######################################################################################################
@@ -85,8 +86,8 @@ boolean Plugin_014(byte function, struct EventStruct *event, String& string)
options[2] = F("Temp 12 bits / RH 8 bits");
optionValues[3] = SI7021_RESOLUTION_11T_11RH;
options[3] = F("Temp 11 bits / RH 11 bits");
addFormSelector(string, F("Resolution"), F("plugin_014_res"), SI7021_RESOLUTION_OPTION, options, optionValues, choice);
//addUnit(string, F("bits"));
addFormSelector(F("Resolution"), F("plugin_014_res"), SI7021_RESOLUTION_OPTION, options, optionValues, choice);
//addUnit(F("bits"));
success = true;
break;
@@ -393,3 +394,4 @@ int8_t Plugin_014_si7021_setResolution(uint8_t res)
return error;
}
#endif // USES_P014
+28 -9
View File
@@ -1,3 +1,4 @@
#ifdef USES_P015
//#######################################################################################################
//######################## Plugin 015 TSL2561 I2C Lux Sensor ############################################
//#######################################################################################################
@@ -11,6 +12,8 @@
#define PLUGIN_ID_015 15
#define PLUGIN_NAME_015 "Light/Lux - TSL2561"
#define PLUGIN_VALUENAME1_015 "Lux"
#define PLUGIN_VALUENAME2_015 "Infrared"
#define PLUGIN_VALUENAME3_015 "Broadband"
boolean Plugin_015_init = false;
@@ -218,7 +221,7 @@ boolean plugin_015_getData(unsigned int &data0, unsigned int &data1)
}
boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0, unsigned int CH1, double &lux)
boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0, unsigned int CH1, double &lux, double &infrared, double &broadband)
// Convert raw data to lux
// gain: 0 (1X) or 1 (16X), see setTiming()
// ms: integration time in ms, from setTiming() or from manual integration
@@ -245,6 +248,10 @@ boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0,
// We will need the ratio for subsequent calculations
ratio = d1 / d0;
// save original values
infrared = d1;
broadband = d0;
// Normalize for integration time
d0 *= (402.0/ms);
d1 *= (402.0/ms);
@@ -289,7 +296,6 @@ boolean plugin_015_getLux(unsigned char gain, unsigned int ms, unsigned int CH0,
}
boolean Plugin_015(byte function, struct EventStruct *event, String& string)
{
boolean success = false;
@@ -300,12 +306,12 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
{
Device[++deviceCount].Number = PLUGIN_ID_015;
Device[deviceCount].Type = DEVICE_TYPE_I2C;
Device[deviceCount].VType = SENSOR_TYPE_SINGLE;
Device[deviceCount].VType = SENSOR_TYPE_TRIPLE;
Device[deviceCount].Ports = 0;
Device[deviceCount].PullUpOption = false;
Device[deviceCount].InverseLogicOption = false;
Device[deviceCount].FormulaOption = true;
Device[deviceCount].ValueCount = 1;
Device[deviceCount].ValueCount = 3;
Device[deviceCount].SendDataOption = true;
Device[deviceCount].TimerOption = true;
Device[deviceCount].GlobalSyncOption = true;
@@ -321,6 +327,9 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
case PLUGIN_GET_DEVICEVALUENAMES:
{
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[0], PSTR(PLUGIN_VALUENAME1_015));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[1], PSTR(PLUGIN_VALUENAME2_015));
strcpy_P(ExtraTaskSettings.TaskDeviceValueNames[2], PSTR(PLUGIN_VALUENAME3_015));
break;
}
@@ -337,7 +346,7 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
optionValues1[0] = TSL2561_ADDR;
optionValues1[1] = TSL2561_ADDR_1;
optionValues1[2] = TSL2561_ADDR_0;
addFormSelectorI2C(string, F("plugin_015_tsl2561_i2c"), 3, optionValues1, choice1);
addFormSelectorI2C(F("plugin_015_tsl2561_i2c"), 3, optionValues1, choice1);
#define TSL2561_INTEGRATION_OPTION 3
@@ -350,12 +359,12 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
options2[1] = F("101 ms");
optionValues2[2] = 0x02;
options2[2] = F("402 ms");
addFormSelector(string, F("Integration time"), F("plugin_015_integration"), TSL2561_INTEGRATION_OPTION, options2, optionValues2, choice2);
addFormSelector(F("Integration time"), F("plugin_015_integration"), TSL2561_INTEGRATION_OPTION, options2, optionValues2, choice2);
addFormCheckBox(string, F("Send sensor to sleep:"), F("plugin_015_sleep"),
addFormCheckBox(F("Send sensor to sleep:"), F("plugin_015_sleep"),
Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addFormCheckBox(string, F("Enable 16x Gain:"), F("plugin_015_gain"),
addFormCheckBox(F("Enable 16x Gain:"), F("plugin_015_gain"),
Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
success = true;
@@ -402,12 +411,17 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
{
double lux; // Resulting lux value
double infrared; // Resulting infrared value
double broadband; // Resulting broadband value
boolean good; // True if neither sensor is saturated
// Perform lux calculation:
good = plugin_015_getLux(gain,ms,data0,data1,lux);
good = plugin_015_getLux(gain,ms,data0,data1,lux, infrared, broadband);
UserVar[event->BaseVarIndex] = lux;
UserVar[event->BaseVarIndex + 1] = infrared;
UserVar[event->BaseVarIndex + 2] = broadband;
if (!good)
{
addLog(LOG_LEVEL_INFO,F("TSL2561: Sensor saturated! > 65535 Lux"));
@@ -422,6 +436,10 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
log += String(gain,HEX);
log += F(": Lux: ");
log += UserVar[event->BaseVarIndex];
log += F(": Infrared: ");
log += UserVar[event->BaseVarIndex + 1];
log += F(": Broadband: ");
log += UserVar[event->BaseVarIndex + 2];
addLog(LOG_LEVEL_INFO,log);
}
else
@@ -441,3 +459,4 @@ boolean Plugin_015(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P015
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P016
//#######################################################################################################
//#################################### Plugin 016: Input IR #############################################
//#######################################################################################################
@@ -93,3 +94,4 @@ boolean Plugin_016(byte function, struct EventStruct *event, String& string)
}
#endif
#endif // USES_P016
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P017
//#######################################################################################################
//#################################### Plugin-017: PN532 RFID reader ####################################
//#######################################################################################################
@@ -66,7 +67,7 @@ boolean Plugin_017(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormPinSelect(string, F("Reset Pin"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
addFormPinSelect(F("Reset Pin"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
success = true;
break;
}
@@ -401,3 +402,4 @@ int8_t Plugin_017_readAckFrame()
return 0;
}
#endif // USES_P017
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P018
//#######################################################################################################
//#################################### Plugin 018: GP2Y10 ###############################################
//#######################################################################################################
@@ -82,3 +83,4 @@ boolean Plugin_018(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P018
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P019
//#######################################################################################################
//#################################### Plugin 019: PCF8574 ##############################################
//#######################################################################################################
@@ -46,7 +47,7 @@ boolean Plugin_019(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormCheckBox(string, F("Send Boot state"), F("plugin_019_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormCheckBox(F("Send Boot state"), F("plugin_019_boot"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
success = true;
break;
@@ -238,3 +239,4 @@ boolean Plugin_019_Write(byte Par1, byte Par2)
return true;
}
#endif // USES_P019
+10 -8
View File
@@ -1,3 +1,4 @@
#ifdef USES_P020
//#######################################################################################################
//#################################### Plugin 020: Ser2Net ##############################################
//#######################################################################################################
@@ -45,9 +46,9 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(string, F("TCP Port"), F("plugin_020_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
addFormNumericBox(string, F("Baud Rate"), F("plugin_020_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
addFormNumericBox(string, F("Data bits"), F("plugin_020_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
addFormNumericBox(F("TCP Port"), F("plugin_020_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
addFormNumericBox(F("Baud Rate"), F("plugin_020_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
addFormNumericBox(F("Data bits"), F("plugin_020_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
byte choice = ExtraTaskSettings.TaskDevicePluginConfigLong[3];
String options[3];
@@ -58,13 +59,13 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
optionValues[0] = 0;
optionValues[1] = 2;
optionValues[2] = 3;
addFormSelector(string, F("Parity"), F("plugin_020_parity"), 3, options, optionValues, choice);
addFormSelector(F("Parity"), F("plugin_020_parity"), 3, options, optionValues, choice);
addFormNumericBox(string, F("Stop bits"), F("plugin_020_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
addFormNumericBox(F("Stop bits"), F("plugin_020_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
addFormPinSelect(string, F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
addFormNumericBox(string, F("RX Receive Timeout (mSec)"), F("plugin_020_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormNumericBox(F("RX Receive Timeout (mSec)"), F("plugin_020_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
@@ -72,7 +73,7 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
options2[0] = F("None");
options2[1] = F("Generic");
options2[2] = F("RFLink");
addFormSelector(string, F("Event processing"), F("plugin_020_events"), 3, options2, NULL, choice2);
addFormSelector(F("Event processing"), F("plugin_020_events"), 3, options2, NULL, choice2);
success = true;
break;
@@ -292,3 +293,4 @@ boolean Plugin_020(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P020
+8 -6
View File
@@ -1,3 +1,4 @@
#ifdef USES_P021
//#######################################################################################################
//#################################### Plugin 021: Level Control ########################################
//#######################################################################################################
@@ -46,16 +47,16 @@ boolean Plugin_021(byte function, struct EventStruct *event, String& string)
{
// char tmpString[128];
string += F("<TR><TD>Check Task:<TD>");
addTaskSelect(string, "plugin_021_task", Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addHtml(F("<TR><TD>Check Task:<TD>"));
addTaskSelect("plugin_021_task", Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
LoadTaskSettings(Settings.TaskDevicePluginConfig[event->TaskIndex][0]); // we need to load the values from another task for selection!
string += F("<TR><TD>Check Value:<TD>");
addTaskValueSelect(string, "plugin_021_value", Settings.TaskDevicePluginConfig[event->TaskIndex][1], Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addHtml(F("<TR><TD>Check Value:<TD>"));
addTaskValueSelect("plugin_021_value", Settings.TaskDevicePluginConfig[event->TaskIndex][1], Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormTextBox(string, F("Set Level"), F("plugin_021_setvalue"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0]), 8);
addFormTextBox(F("Set Level"), F("plugin_021_setvalue"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0]), 8);
addFormTextBox(string, F("Hysteresis"), F("plugin_021_hyst"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]), 8);
addFormTextBox(F("Hysteresis"), F("plugin_021_hyst"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1]), 8);
LoadTaskSettings(event->TaskIndex); // we need to restore our original taskvalues!
success = true;
@@ -137,3 +138,4 @@ boolean Plugin_021(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P021
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P022
//#######################################################################################################
//#################################### Plugin 022: PCA9685 ##############################################
//#######################################################################################################
@@ -152,3 +153,4 @@ void Plugin_022_initialize()
Plugin_022_writeRegister(PCA9685_MODE2, (byte)0x10); // set to output
Plugin_022_init = true;
}
#endif // USES_P022
+26 -25
View File
@@ -1,3 +1,4 @@
#ifdef USES_P023
//#######################################################################################################
//#################################### Plugin 023: OLED SSD1306 display #################################
//#######################################################################################################
@@ -70,33 +71,33 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*String options[2] = { F("3C"), F("3D") };*/
int optionValues[2] = { 0x3C, 0x3D };
addFormSelectorI2C(string, F("plugin_023_adr"), 2, optionValues, choice);
addFormSelectorI2C(F("plugin_023_adr"), 2, optionValues, choice);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options2[2] = { F("Normal"), F("Rotated") };
int optionValues2[2] = { 1, 2 };
addFormSelector(string, F("Rotation"), F("plugin_023_rotate"), 2, options2, optionValues2, choice2);
addFormSelector(F("Rotation"), F("plugin_023_rotate"), 2, options2, optionValues2, choice2);
byte choice3 = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
String options3[3] = { F("128x64"), F("128x32"), F("64x48") };
int optionValues3[3] = { 1, 3, 2 };
addFormSelector(string, F("Display Size"), F("plugin_023_size"), 3, options3, optionValues3, choice3);
addFormSelector(F("Display Size"), F("plugin_023_size"), 3, options3, optionValues3, choice3);
byte choice4 = Settings.TaskDevicePluginConfig[event->TaskIndex][4];
String options4[2] = { F("Normal"), F("Optimized") };
int optionValues4[2] = { 1, 2 };
addFormSelector(string, F("Font Width"), F("plugin_023_font_width"), 2, options4, optionValues4, choice4);
addFormSelector(F("Font Width"), F("plugin_023_font_width"), 2, options4, optionValues4, choice4);
char deviceTemplate[8][64];
LoadCustomTaskSettings(event->TaskIndex, (byte*)&deviceTemplate, sizeof(deviceTemplate));
for (byte varNr = 0; varNr < 8; varNr++)
{
addFormTextBox(string, String(F("Line ")) + (varNr + 1), String(F("Plugin_023_template")) + (varNr + 1), deviceTemplate[varNr], 64);
addFormTextBox(String(F("Line ")) + (varNr + 1), String(F("Plugin_023_template")) + (varNr + 1), deviceTemplate[varNr], 64);
}
addFormPinSelect(string, F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
addFormPinSelect(F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
addFormNumericBox(string, F("Display Timeout"), F("plugin_23_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addFormNumericBox(F("Display Timeout"), F("plugin_23_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
success = true;
break;
@@ -208,14 +209,6 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
int argIndex = tmpString.indexOf(',');
if (argIndex)
tmpString = tmpString.substring(0, argIndex);
if (tmpString.equalsIgnoreCase(F("OLED")))
{
success = true;
argIndex = string.lastIndexOf(',');
tmpString = string.substring(argIndex + 1);
String newString = P023_parseTemplate(tmpString, 16);
Plugin_023_sendStrXY(newString.c_str(), event->Par1 - 1, event->Par2 - 1);
}
if (tmpString.equalsIgnoreCase(F("OLEDCMD")))
{
success = true;
@@ -228,9 +221,16 @@ boolean Plugin_023(byte function, struct EventStruct *event, String& string)
else if (tmpString.equalsIgnoreCase(F("Clear")))
Plugin_023_clear_display();
}
else if (tmpString.equalsIgnoreCase(F("OLED")))
{
success = true;
argIndex = string.lastIndexOf(',');
tmpString = string.substring(argIndex + 1);
String newString = P023_parseTemplate(tmpString, 16);
Plugin_023_sendStrXY(newString.c_str(), event->Par1 - 1, event->Par2 - 1);
}
break;
}
}
return success;
}
@@ -444,7 +444,7 @@ const char Plugin_023_myFont[][8] PROGMEM = {
{0x00, 0x02, 0x05, 0x05, 0x02, 0x00, 0x00, 0x00} // DEL
};
static void Plugin_023_reset_display(void)
void Plugin_023_reset_display(void)
{
Plugin_023_displayOff();
Plugin_023_clear_display();
@@ -475,7 +475,7 @@ void Plugin_023_displayOff(void)
}
static void Plugin_023_clear_display(void)
void Plugin_023_clear_display(void)
{
unsigned char i, k;
for (k = 0; k < 8; k++)
@@ -492,7 +492,7 @@ static void Plugin_023_clear_display(void)
// Actually this sends a byte, not a char to draw in the display.
static void Plugin_023_SendChar(unsigned char data)
void Plugin_023_SendChar(unsigned char data)
{
Wire.beginTransmission(Plugin_023_OLED_address); // begin transmitting
Wire.write(0x40); //data mode
@@ -503,7 +503,7 @@ static void Plugin_023_SendChar(unsigned char data)
// Prints a display char (not just a byte) in coordinates X Y,
//currently unused:
// static void Plugin_023_sendCharXY(unsigned char data, int X, int Y)
// void Plugin_023_sendCharXY(unsigned char data, int X, int Y)
// {
// //if (interrupt && !doing_menu) return; // Stop printing only if interrupt is call but not in button functions
// Plugin_023_setXY(X, Y);
@@ -517,7 +517,7 @@ static void Plugin_023_SendChar(unsigned char data)
// }
static void Plugin_023_sendcommand(unsigned char com)
void Plugin_023_sendcommand(unsigned char com)
{
Wire.beginTransmission(Plugin_023_OLED_address); //begin transmitting
Wire.write(0x80); //command mode
@@ -528,7 +528,7 @@ static void Plugin_023_sendcommand(unsigned char com)
// Set the cursor position in a 16 COL * 8 ROW map (128x64 pixels)
// or 8 COL * 5 ROW map (64x48 pixels)
static void Plugin_023_setXY(unsigned char row, unsigned char col)
void Plugin_023_setXY(unsigned char row, unsigned char col)
{
switch (Plugin_023_OLED_type)
{
@@ -548,7 +548,7 @@ static void Plugin_023_setXY(unsigned char row, unsigned char col)
// Prints a string regardless the cursor position.
// unused:
// static void Plugin_023_sendStr(unsigned char *string)
// void Plugin_023_sendStr(unsigned char *string)
// {
// unsigned char i = 0;
// while (*string)
@@ -564,7 +564,7 @@ static void Plugin_023_setXY(unsigned char row, unsigned char col)
// Prints a string in coordinates X Y, being multiples of 8.
// This means we have 16 COLS (0-15) and 8 ROWS (0-7).
static void Plugin_023_sendStrXY(const char *string, int X, int Y)
void Plugin_023_sendStrXY(const char *string, int X, int Y)
{
Plugin_023_setXY(X, Y);
unsigned char i = 0;
@@ -590,7 +590,7 @@ static void Plugin_023_sendStrXY(const char *string, int X, int Y)
}
static void Plugin_023_init_OLED(void)
void Plugin_023_init_OLED(void)
{
unsigned char multiplex;
unsigned char compins;
@@ -636,3 +636,4 @@ static void Plugin_023_init_OLED(void)
Plugin_023_sendcommand(0x00); //Set Memory Addressing Mode ab Horizontal addressing mode
}
#endif // USES_P023
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P024
//#######################################################################################################
//#################################### Plugin 024: MLX90614 IR temperature I2C 0x5A) ###############################################
//#######################################################################################################
@@ -77,7 +78,7 @@ boolean Plugin_024(byte function, struct EventStruct *event, String& string)
options[0] = F("IR object temperature");
optionValues[1] = (0x06);
options[1] = F("Ambient temperature");
addFormSelector(string, F("Option"), F("plugin_024_option"), MLX90614_OPTION, options, optionValues, choice);
addFormSelector(F("Option"), F("plugin_024_option"), MLX90614_OPTION, options, optionValues, choice);
success = true;
break;
@@ -122,3 +123,4 @@ boolean Plugin_024(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P024
+15 -13
View File
@@ -1,3 +1,4 @@
#ifdef USES_P025
//#######################################################################################################
//#################################### Plugin 025: ADS1115 I2C 0x48) ###############################################
//#######################################################################################################
@@ -9,7 +10,7 @@
boolean Plugin_025_init = false;
static uint16_t readRegister025(uint8_t i2cAddress, uint8_t reg) {
uint16_t readRegister025(uint8_t i2cAddress, uint8_t reg) {
Wire.beginTransmission(i2cAddress);
Wire.write((0x00));
Wire.endTransmission();
@@ -66,9 +67,9 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
#define ADS1115_I2C_OPTION 4
byte addr = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
int optionValues[ADS1115_I2C_OPTION] = { 0x48, 0x49, 0x4A, 0x4B };
addFormSelectorI2C(string, F("plugin_025_i2c"), ADS1115_I2C_OPTION, optionValues, addr);
addFormSelectorI2C(F("plugin_025_i2c"), ADS1115_I2C_OPTION, optionValues, addr);
addFormSubHeader(string, F("Input"));
addFormSubHeader(F("Input"));
#define ADS1115_PGA_OPTION 6
byte pga = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
@@ -80,7 +81,7 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
F("8x gain (FS=0.512V)"),
F("16x gain (FS=0.256V)")
};
addFormSelector(string, F("Gain"), F("plugin_025_gain"), ADS1115_PGA_OPTION, pgaOptions, NULL, pga);
addFormSelector(F("Gain"), F("plugin_025_gain"), ADS1115_PGA_OPTION, pgaOptions, NULL, pga);
#define ADS1115_MUX_OPTION 8
byte mux = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
@@ -94,19 +95,19 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
F("AIN2 - GND (Single-Ended)"),
F("AIN3 - GND (Single-Ended)"),
};
addFormSelector(string, F("Input Multiplexer"), F("plugin_025_mode"), ADS1115_MUX_OPTION, muxOptions, NULL, mux);
addFormSelector(F("Input Multiplexer"), F("plugin_025_mode"), ADS1115_MUX_OPTION, muxOptions, NULL, mux);
addFormSubHeader(string, F("Two Point Calibration"));
addFormSubHeader(F("Two Point Calibration"));
addFormCheckBox(string, F("Calibration Enabled"), F("plugin_025_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addFormCheckBox(F("Calibration Enabled"), F("plugin_025_cal"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addFormNumericBox(string, F("Point 1"), F("plugin_025_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], -32768, 32767);
string += F(" &#8793; ");
addTextBox(string, F("plugin_025_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
addFormNumericBox(F("Point 1"), F("plugin_025_adc1"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][0], -32768, 32767);
addHtml(F(" &#8793; "));
addTextBox(F("plugin_025_out1"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][0], 3), 10);
addFormNumericBox(string, F("Point 2"), F("plugin_025_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], -32768, 32767);
string += F(" &#8793; ");
addTextBox(string, F("plugin_025_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
addFormNumericBox(F("Point 2"), F("plugin_025_adc2"), Settings.TaskDevicePluginConfigLong[event->TaskIndex][1], -32768, 32767);
addHtml(F(" &#8793; "));
addTextBox(F("plugin_025_out2"), String(Settings.TaskDevicePluginConfigFloat[event->TaskIndex][1], 3), 10);
success = true;
break;
@@ -202,3 +203,4 @@ boolean Plugin_025(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P025
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P026
//#######################################################################################################
//#################################### Plugin 026: System Info ##########################################
//#######################################################################################################
@@ -51,7 +52,7 @@ boolean Plugin_026(byte function, struct EventStruct *event, String& string)
options[7] = F("IP 3.Octet");
options[8] = F("IP 4.Octet");
options[9] = F("Web activity");
addFormSelector(string, F("Indicator"), F("plugin_026"), 10, options, NULL, choice);
addFormSelector(F("Indicator"), F("plugin_026"), 10, options, NULL, choice);
success = true;
break;
@@ -134,3 +135,4 @@ boolean Plugin_026(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P026
+5 -3
View File
@@ -1,3 +1,4 @@
#ifdef USES_P027
//#######################################################################################################
//######################### Plugin 027: INA219 DC Voltage/Current sensor ################################
//#######################################################################################################
@@ -137,13 +138,13 @@ boolean Plugin_027(byte function, struct EventStruct *event, String& string)
optionValuesMode[0] = 0;
optionValuesMode[1] = 1;
optionValuesMode[2] = 2;
addFormSelector(string, F("Measure range"), F("plugin_027_range"), 3, optionsMode, optionValuesMode, choiceMode);
addFormSelector(F("Measure range"), F("plugin_027_range"), 3, optionsMode, optionValuesMode, choiceMode);
addFormSelectorI2C(string, F("plugin_027_i2c"), 4, Plugin_27_i2c_addresses, Plugin_027_i2c_addr(event));
addFormSelectorI2C(F("plugin_027_i2c"), 4, Plugin_27_i2c_addresses, Plugin_027_i2c_addr(event));
byte choiceMeasureType = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
String options[4] = { F("Voltage"), F("Current"), F("Power"), F("Voltage/Current/Power") };
addFormSelector(string, F("Measurement Type"), F("plugin_027_measuretype"), 4, options, NULL, choiceMeasureType );
addFormSelector(F("Measurement Type"), F("plugin_027_measuretype"), 4, options, NULL, choiceMeasureType );
success = true;
break;
@@ -426,3 +427,4 @@ float Plugin_027_getCurrent_mA(uint8_t i2caddr) {
valueDec /= _ina219_data[idx].currentDivider_mA;
return valueDec;
}
#endif // USES_P027
+10 -8
View File
@@ -1,3 +1,4 @@
#ifdef USES_P028
//#######################################################################################################
//#################### Plugin 028 BME280 I2C Temp/Hum/Barometric Pressure Sensor #######################
//#######################################################################################################
@@ -212,25 +213,25 @@ boolean Plugin_028(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
const uint8_t i2cAddress = Plugin_028_i2c_addr(event);
addFormSelectorI2C(string, F("plugin_028_bme280_i2c"), 2, Plugin_28_i2c_addresses, i2cAddress);
addFormSelectorI2C(F("plugin_028_bme280_i2c"), 2, Plugin_28_i2c_addresses, i2cAddress);
const uint8_t idx = Plugin_028_device_index(i2cAddress);
if (_sensorID[idx] != Unknown_DEVICE) {
String detectedString = F("Detected: ");
detectedString += Plugin_028_getFullDeviceName();
addUnit(string, detectedString);
addUnit(detectedString);
}
addFormNote(string, F("SDO Low=0x76, High=0x77"));
addFormNote(F("SDO Low=0x76, High=0x77"));
addFormNumericBox(string, F("Altitude"), F("plugin_028_bme280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(string, F("m"));
addFormNumericBox(F("Altitude"), F("plugin_028_bme280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(F("m"));
addFormNumericBox(string, F("Temperature offset"), F("plugin_028_bme280_tempoffset"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addUnit(string, F("x 0.1C"));
addFormNumericBox(F("Temperature offset"), F("plugin_028_bme280_tempoffset"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addUnit(F("x 0.1C"));
String offsetNote = F("Offset in units of 0.1 degree Celcius");
if (Plugin_028_hasHumidity()) {
offsetNote += F(" (also correct humidity)");
}
addFormNote(string, offsetNote);
addFormNote(offsetNote);
success = true;
break;
@@ -667,3 +668,4 @@ float Plugin_028_readAltitude(float seaLevel)
float Plugin_028_pressureElevation(float atmospheric, int altitude) {
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
#endif // USES_P028
+5 -3
View File
@@ -1,10 +1,11 @@
#ifdef USES_P029
//#######################################################################################################
//#################################### Plugin 029: Output ###############################################
//#######################################################################################################
#define PLUGIN_029
#define PLUGIN_ID_029 29
#define PLUGIN_NAME_029 "Output - (Domoticz MQTT helper)"
#define PLUGIN_NAME_029 "Output - Domoticz MQTT Helper"
#define PLUGIN_VALUENAME1_029 "Output"
boolean Plugin_029(byte function, struct EventStruct *event, String& string)
{
@@ -49,10 +50,10 @@ boolean Plugin_029(byte function, struct EventStruct *event, String& string)
if (Settings.Protocol[i] == 2) { controllerNr = i; }
}
string += F("<TR><TD>IDX:<TD>");
addHtml(F("<TR><TD>IDX:<TD>"));
String id = F("TDID"); //="taskdeviceid"
id += controllerNr + 1;
addNumericBox(string, id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, 9999);
addNumericBox(id, Settings.TaskDeviceID[controllerNr][event->TaskIndex], 0, 9999);
success = true;
break;
}
@@ -65,3 +66,4 @@ boolean Plugin_029(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P029
+6 -4
View File
@@ -1,3 +1,4 @@
#ifdef USES_P030
//#######################################################################################################
//#################### Plugin 030 BMP280 I2C Temp/Barometric Pressure Sensor #######################
//#######################################################################################################
@@ -105,11 +106,11 @@ boolean Plugin_030(byte function, struct EventStruct *event, String& string)
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*String options[2] = { F("0x76 - default settings (SDO Low)"), F("0x77 - alternate settings (SDO HIGH)") };*/
int optionValues[2] = { 0x76, 0x77 };
addFormSelectorI2C(string, F("plugin_030_bmp280_i2c"), 2, optionValues, choice);
addFormNote(string, F("SDO Low=0x76, High=0x77"));
addFormSelectorI2C(F("plugin_030_bmp280_i2c"), 2, optionValues, choice);
addFormNote(F("SDO Low=0x76, High=0x77"));
addFormNumericBox(string, F("Altitude"), F("plugin_030_bmp280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(string, F("m"));
addFormNumericBox(F("Altitude"), F("plugin_030_bmp280_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(F("m"));
success = true;
break;
@@ -394,3 +395,4 @@ float Plugin_030_readAltitude(float seaLevel)
float Plugin_030_pressureElevation(float atmospheric, int altitude) {
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
#endif // USES_P030
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P031
//#######################################################################################################
//#################### Plugin 031: SHT10/SHT11/SHT15 Temp/Humidity Sensor ###############################
//#######################################################################################################
@@ -242,3 +243,4 @@ int Plugin_031_readData(const int bits)
return val;
}
#endif // USES_P031
+4 -2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P032
//#######################################################################################################
//################ Plugin 032 MS5611 (GY-63) I2C Temp/Barometric Pressure Sensor #######################
//#######################################################################################################
@@ -72,9 +73,9 @@ boolean Plugin_032(byte function, struct EventStruct *event, String& string)
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*String options[2] = { F("0x77 - default I2C address"), F("0x76 - alternate I2C address") };*/
int optionValues[2] = { 0x77, 0x76 };
addFormSelectorI2C(string, F("plugin_032_ms5611_i2c"), 2, optionValues, choice);
addFormSelectorI2C(F("plugin_032_ms5611_i2c"), 2, optionValues, choice);
addFormNumericBox(string, F("Altitude [m]"), F("plugin_032_ms5611_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormNumericBox(F("Altitude [m]"), F("plugin_032_ms5611_elev"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
success = true;
break;
@@ -252,3 +253,4 @@ void Plugin_032_readout() {
double Plugin_032_pressureElevation(double atmospheric, int altitude) {
return atmospheric / pow(1.0 - (altitude/44330.0), 5.255);
}
#endif // USES_P032
+3 -1
View File
@@ -1,3 +1,4 @@
#ifdef USES_P033
//#######################################################################################################
//#################################### Plugin 033: Dummy ################################################
//#######################################################################################################
@@ -70,7 +71,7 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string)
optionValues[9] = SENSOR_TYPE_LONG;
optionValues[10] = SENSOR_TYPE_WIND;
addFormSelector(string, F("Simulate Data Type"), F("plugin_033_sensortype"), 11, options, optionValues, choice );
addFormSelector(F("Simulate Data Type"), F("plugin_033_sensortype"), 11, options, optionValues, choice );
success = true;
break;
@@ -100,3 +101,4 @@ boolean Plugin_033(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P033
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P034
//#######################################################################################################
//######################## Plugin 034: Temperature and Humidity sensor DHT 12 (I2C) #####################
//#######################################################################################################
@@ -110,3 +111,4 @@ boolean Plugin_034(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P034
+10 -8
View File
@@ -1,3 +1,4 @@
#ifdef USES_P035
//#######################################################################################################
//#################################### Plugin 035: Output IR ############################################
//#######################################################################################################
@@ -204,14 +205,14 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
if (GetArgv(command, TmpStr1, 5)) IrRepeat = str2int(TmpStr1);
if (GetArgv(command, TmpStr1, 6)) IrSecondCode = strtoul(TmpStr1, NULL, 16);
if (IrType.equalsIgnoreCase("NEC")) Plugin_035_irSender->sendNEC(IrCode, IrBits);
if (IrType.equalsIgnoreCase("JVC")) Plugin_035_irSender->sendJVC(IrCode, IrBits, 2);
if (IrType.equalsIgnoreCase("RC5")) Plugin_035_irSender->sendRC5(IrCode, IrBits);
if (IrType.equalsIgnoreCase("RC6")) Plugin_035_irSender->sendRC6(IrCode, IrBits);
if (IrType.equalsIgnoreCase("SAMSUNG")) Plugin_035_irSender->sendSAMSUNG(IrCode, IrBits);
if (IrType.equalsIgnoreCase("SONY")) Plugin_035_irSender->sendSony(IrCode, IrBits);
if (IrType.equalsIgnoreCase("PANASONIC")) Plugin_035_irSender->sendPanasonic(IrBits, IrCode);
if (IrType.equalsIgnoreCase("PIONEER")) Plugin_035_irSender->sendPioneer(IrCode, IrBits, IrRepeat, IrSecondCode);
if (IrType.equalsIgnoreCase(F("NEC"))) Plugin_035_irSender->sendNEC(IrCode, IrBits);
if (IrType.equalsIgnoreCase(F("JVC"))) Plugin_035_irSender->sendJVC(IrCode, IrBits, 2);
if (IrType.equalsIgnoreCase(F("RC5"))) Plugin_035_irSender->sendRC5(IrCode, IrBits);
if (IrType.equalsIgnoreCase(F("RC6"))) Plugin_035_irSender->sendRC6(IrCode, IrBits);
if (IrType.equalsIgnoreCase(F("SAMSUNG"))) Plugin_035_irSender->sendSAMSUNG(IrCode, IrBits);
if (IrType.equalsIgnoreCase(F("SONY"))) Plugin_035_irSender->sendSony(IrCode, IrBits);
if (IrType.equalsIgnoreCase(F("PANASONIC"))) Plugin_035_irSender->sendPanasonic(IrBits, IrCode);
if (IrType.equalsIgnoreCase(F("PIONEER"))) Plugin_035_irSender->sendPioneer(IrCode, IrBits, IrRepeat, IrSecondCode);
}
addLog(LOG_LEVEL_INFO, F("IRTX :IR Code Sent"));
@@ -233,3 +234,4 @@ boolean Plugin_035(byte function, struct EventStruct *event, String& string)
}
#endif
#endif // USES_P035
+15 -12
View File
@@ -1,3 +1,4 @@
#ifdef USES_P036
//#######################################################################################################
//#################################### Plugin 036: OLED SSD1306 display #################################
//
@@ -24,6 +25,7 @@
#define P36_CONTRAST_MED 0xCF
#define P36_CONTRAST_HIGH 0xFF
#include "SSD1306.h"
#include "SH1106Wire.h"
#include "OLED_SSD1306_SH1106_images.h"
@@ -92,7 +94,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
options5[0] = F("SSD1306");
options5[1] = F("SH1106");
int optionValues5[2] = { 1, 2 };
addFormSelector(string, F("Controler"), F("plugin_036_controler"), 2, options5, optionValues5, choice5);
addFormSelector(F("Controler"), F("plugin_036_controler"), 2, options5, optionValues5, choice5);
byte choice0 = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
/*
@@ -103,14 +105,14 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
int optionValues0[2];
optionValues0[0] = 0x3C;
optionValues0[1] = 0x3D;
addFormSelectorI2C(string, F("plugin_036_adr"), 2, optionValues0, choice0);
addFormSelectorI2C(F("plugin_036_adr"), 2, optionValues0, choice0);
byte choice1 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options1[2];
options1[0] = F("Normal");
options1[1] = F("Rotated");
int optionValues1[2] = { 1, 2 };
addFormSelector(string, F("Rotation"), F("plugin_036_rotate"), 2, options1, optionValues1, choice1);
addFormSelector(F("Rotation"), F("plugin_036_rotate"), 2, options1, optionValues1, choice1);
byte choice2 = Settings.TaskDevicePluginConfig[event->TaskIndex][2];
String options2[4];
@@ -119,7 +121,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
options2[2] = F("3");
options2[3] = F("4");
int optionValues2[4] = { 1, 2, 3, 4 };
addFormSelector(string, F("Lines per Frame"), F("plugin_036_nlines"), 4, options2, optionValues2, choice2);
addFormSelector(F("Lines per Frame"), F("plugin_036_nlines"), 4, options2, optionValues2, choice2);
byte choice3 = Settings.TaskDevicePluginConfig[event->TaskIndex][3];
String options3[5];
@@ -134,18 +136,18 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
optionValues3[2] = 4;
optionValues3[3] = 8;
optionValues3[4] = 32;
addFormSelector(string, F("Scroll"), F("plugin_036_scroll"), 5, options3, optionValues3, choice3);
addFormSelector(F("Scroll"), F("plugin_036_scroll"), 5, options3, optionValues3, choice3);
LoadCustomTaskSettings(event->TaskIndex, (byte*)&P036_deviceTemplate, sizeof(P036_deviceTemplate));
for (byte varNr = 0; varNr < P36_Nlines; varNr++)
{
addFormTextBox(string, String(F("Line ")) + (varNr + 1), String(F("Plugin_036_template")) + (varNr + 1), P036_deviceTemplate[varNr], P36_Nchars);
addFormTextBox(String(F("Line ")) + (varNr + 1), String(F("Plugin_036_template")) + (varNr + 1), P036_deviceTemplate[varNr], P36_Nchars);
}
addFormPinSelect(string, F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
addFormPinSelect(F("Display button"), F("taskdevicepin3"), Settings.TaskDevicePin3[event->TaskIndex]);
addFormNumericBox(string, F("Display Timeout"), F("plugin_036_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
addFormNumericBox(F("Display Timeout"), F("plugin_036_timer"), Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
byte choice6 = Settings.TaskDevicePluginConfig[event->TaskIndex][6];
if (choice6 == 0) choice6 = P36_CONTRAST_HIGH;
@@ -157,7 +159,7 @@ boolean Plugin_036(byte function, struct EventStruct *event, String& string)
optionValues6[0] = P36_CONTRAST_LOW;
optionValues6[1] = P36_CONTRAST_MED;
optionValues6[2] = P36_CONTRAST_HIGH;
addFormSelector(string, F("Contrast"), F("plugin_036_contrast"), 3, options6, optionValues6, choice6);
addFormSelector(F("Contrast"), F("plugin_036_contrast"), 3, options6, optionValues6, choice6);
success = true;
break;
@@ -466,7 +468,7 @@ String P36_parseTemplate(String &tmpString, byte lineSize) {
void display_header() {
static boolean showWiFiName = true;
if (showWiFiName && (WiFi.status() == WL_CONNECTED) ) {
if (showWiFiName && (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) ) {
String newString = WiFi.SSID();
newString.trim();
display_title(newString);
@@ -629,7 +631,7 @@ void display_scroll(String outString[], String inString[], int nlines, int scrol
//Draw Signal Strength Bars, return true when there was an update.
bool display_wifibars() {
const bool connected = WiFi.status() == WL_CONNECTED;
const bool connected = wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED;
const int nbars_filled = (WiFi.RSSI() + 100) / 8;
const int newState = connected ? nbars_filled : P36_WIFI_STATE_UNSET;
if (newState == lastWiFiState)
@@ -651,7 +653,7 @@ bool display_wifibars() {
display->setColor(BLACK);
display->fillRect(x , y, size_x, size_y);
display->setColor(WHITE);
if (WiFi.status() == WL_CONNECTED) {
if (wifiStatus == ESPEASY_WIFI_SERVICES_INITIALIZED) {
for (byte ibar = 0; ibar < nbars; ibar++) {
int16_t height = size_y * (ibar + 1) / nbars;
int16_t xpos = x + ibar * width;
@@ -670,3 +672,4 @@ bool display_wifibars() {
}
return true;
}
#endif // USES_P036
+30 -9
View File
@@ -1,3 +1,4 @@
#ifdef USES_P037
//#######################################################################################################
//#################################### Plugin 037: MQTT Import ##########################################
//#######################################################################################################
@@ -19,8 +20,26 @@
// Declare a Wifi client for this plugin only
// TODO TD-er: These must be kept in some vector to allow multiple instances of MQTT import.
WiFiClient espclient_037;
PubSubClient *MQTTclient_037;
PubSubClient *MQTTclient_037 = NULL;
bool MQTTclient_037_connected = false;
void Plugin_037_update_connect_status() {
bool connected = false;
if (MQTTclient_037 != NULL) {
connected = MQTTclient_037->connected();
}
if (MQTTclient_037_connected != connected) {
MQTTclient_037_connected = !MQTTclient_037_connected;
if (Settings.UseRules) {
String event = connected ? F("MQTTimport#Connected") : F("MQTTimport#Disconnected");
rulesProcessing(event);
}
if (!connected)
addLog(LOG_LEVEL_ERROR, F("IMPT : MQTT 037 Connection lost"));
}
}
boolean Plugin_037(byte function, struct EventStruct *event, String& string)
{
@@ -73,7 +92,7 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
for (byte varNr = 0; varNr < 4; varNr++)
{
addFormTextBox(string, String(F("MQTT Topic ")) + (varNr + 1), String(F("Plugin_037_template")) +
addFormTextBox(String(F("MQTT Topic ")) + (varNr + 1), String(F("Plugin_037_template")) +
(varNr + 1), deviceTemplate[varNr], 40);
}
success = true;
@@ -121,7 +140,9 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
case PLUGIN_TEN_PER_SECOND:
{
MQTTclient_037->loop(); // Listen out for callbacks
if (!MQTTclient_037->loop()) { // Listen out for callbacks
Plugin_037_update_connect_status();
}
success = true;
break;
}
@@ -133,13 +154,11 @@ boolean Plugin_037(byte function, struct EventStruct *event, String& string)
if (!MQTTclient_037->connected() || MQTTclient_should_reconnect) {
if (MQTTclient_should_reconnect) {
addLog(LOG_LEVEL_ERROR, F("IMPT : MQTT 037 Intentional reconnect"));
} else {
addLog(LOG_LEVEL_ERROR, F("IMPT : MQTT 037 Connection lost"));
}
MQTTclient_037->disconnect();
delay(1000);
Plugin_037_update_connect_status();
delay(250);
if (! MQTTConnect_037(ClientName)) {
success = false;
@@ -338,7 +357,8 @@ boolean MQTTConnect_037(String clientid)
if (MQTTclient_037->connected()) return true;
// define stuff for the client - this could also be done in the intial declaration of MQTTclient_037
if (!WiFiConnected(1000)) {
if (!WiFiConnected(100)) {
Plugin_037_update_connect_status();
return false; // Not connected, so no use in wasting time to connect to a host.
}
ControllerSettingsStruct ControllerSettings;
@@ -379,7 +399,7 @@ boolean MQTTConnect_037(String clientid)
delay(500);
}
Plugin_037_update_connect_status();
return MQTTclient_037->connected();
}
@@ -448,3 +468,4 @@ boolean MQTTCheckSubscription_037(String Topic, String Subscription) {
}
return false;
}
#endif // USES_P037
+7 -4
View File
@@ -1,3 +1,4 @@
#ifdef USES_P038
//#######################################################################################################
//#################################### Plugin 038: NeoPixel Basic #######################################
//#######################################################################################################
@@ -21,11 +22,12 @@
// The NeoPixelLine command does not work for RGBW, cause espeasy currently only allows max. 5 parameters
#include <Adafruit_NeoPixel.h>
Adafruit_NeoPixel *Plugin_038_pixels;
#define PLUGIN_038
#define PLUGIN_ID_038 38
#define PLUGIN_NAME_038 "Output - NeoPixel (basic)"
#define PLUGIN_NAME_038 "Output - NeoPixel (Basic)"
#define PLUGIN_VALUENAME1_038 ""
int MaxPixels = 0;
@@ -63,9 +65,9 @@ boolean Plugin_038(byte function, struct EventStruct *event, String& string)
const String options[] = { F("GRB"), F("GRBW") };
int indices[] = { 1, 2 };
addFormNumericBox(string, F("Led Count"), F("plugin_038_leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][0],1,999);
addFormPinSelect(string, F("GPIO"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
addFormSelector(string, F("Strip Type"), F("plugin_038_strip"), 2, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][1] );
addFormNumericBox(F("Led Count"), F("plugin_038_leds"), Settings.TaskDevicePluginConfig[event->TaskIndex][0],1,999);
addFormPinSelect(F("GPIO"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
addFormSelector(F("Strip Type"), F("plugin_038_strip"), 2, options, indices, Settings.TaskDevicePluginConfig[event->TaskIndex][1] );
success = true;
break;
@@ -159,3 +161,4 @@ boolean Plugin_038(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P038
+5 -3
View File
@@ -1,3 +1,4 @@
#ifdef USES_P039
//#######################################################################################################
//######################## Plugin 039: Thermocouple (MAX6675 / MAX31855) ################################
//#######################################################################################################
@@ -103,8 +104,8 @@ boolean Plugin_039(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormNote(string, F("<b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)"));
//string += F("<TR><TD>Info GPIO:<TD><b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)");
addFormNote(F("<b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)"));
//addHtml(F("<TR><TD>Info GPIO:<TD><b>1st GPIO</b> = CS (Usable GPIOs : 0, 2, 4, 5, 15)"));
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2];
@@ -112,7 +113,7 @@ boolean Plugin_039(byte function, struct EventStruct *event, String& string)
options[1] = F("MAX 31855");
//options[2] = F("MAX 31865");
int optionValues[2] = { 1, 2 };
addFormSelector(string, F("Adapter IC"), F("plugin_039_maxtype"), 2, options, optionValues, choice);
addFormSelector(F("Adapter IC"), F("plugin_039_maxtype"), 2, options, optionValues, choice);
success = true;
break;
@@ -289,3 +290,4 @@ int Plugin_039_convert_two_complement(uint32_t value, int nr_bits) {
}
return nativeInt;
}
#endif // USES_P039
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P040
//#######################################################################################################
//#################################### Plugin 040: Serial RFID ID-12 ####################################
//#######################################################################################################
@@ -133,3 +134,4 @@ boolean Plugin_040(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P040
+5 -3
View File
@@ -1,3 +1,4 @@
#ifdef USES_P041
//#######################################################################################################
//#################################### Plugin 041: NeoPixel clock #######################################
//#######################################################################################################
@@ -50,9 +51,9 @@ boolean Plugin_041(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(string, F("Red"), F("plugin_041_red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
addFormNumericBox(string, F("Green"), F("plugin_041_green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
addFormNumericBox(string, F("Blue"), F("plugin_041_blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
addFormNumericBox(F("Red"), F("plugin_041_red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
addFormNumericBox(F("Green"), F("plugin_041_green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
addFormNumericBox(F("Blue"), F("plugin_041_blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
success = true;
break;
}
@@ -429,3 +430,4 @@ void pushHOURE() {
pushToStrip(103);
pushToStrip(104);
}
#endif // USES_P041
+36 -34
View File
@@ -1,3 +1,4 @@
#ifdef USES_P042
//#######################################################################################################
//######################################## Plugin 042: NeoPixel Candle ##################################
//#######################################################################################################
@@ -134,7 +135,7 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
string += F("<script src=\"jscolor.min.js\"></script>\n");
addHtml(F("<script src=\"jscolor.min.js\"></script>\n"));
char tmpString[128];
String options[8];
@@ -156,25 +157,25 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
}
// Candle Type Selection
addFormSelector(string, F("Flame Type"), F("web_Candle_Type"), 8, options, NULL, choice);
addFormSelector(F("Flame Type"), F("web_Candle_Type"), 8, options, NULL, choice);
// Advanced Color options
Candle_color = (ColorType)Settings.TaskDevicePluginConfig[event->TaskIndex][5];
string += F("<TR><TD>Color Handling:<TD>"); // checked
string += F("<input type='radio' id='web_Color_Default' name='web_Color_Type' value='0'");
addHtml(F("<TR><TD>Color Handling:<TD>")); // checked
addHtml(F("<input type='radio' id='web_Color_Default' name='web_Color_Type' value='0'"));
if (Candle_color == ColorDefault) {
string += F(" checked>");
addHtml(F(" checked>"));
} else {
string += F(">");
addHtml(F(">"));
}
string += F("<label for='web_Color_Default'> Use default color</label><br>");
string += F("<input type='radio' id='web_Color_Selected' name='web_Color_Type' value='1'");
addHtml(F("<label for='web_Color_Default'> Use default color</label><br>"));
addHtml(F("<input type='radio' id='web_Color_Selected' name='web_Color_Type' value='1'"));
if (Candle_color == ColorSelected) {
string += F(" checked>");
addHtml(F(" checked>"));
} else {
string += F(">");
addHtml(F(">"));
}
string += F("<label for='web_Color_Selected'> Use selected color</label><br>");
addHtml(F("<label for='web_Color_Selected'> Use selected color</label><br>"));
// Color Selection
char hexvalue[7] = {0};
@@ -184,36 +185,36 @@ boolean Plugin_042(byte function, struct EventStruct *event, String& string)
Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
// http://jscolor.com/examples/
string += F("<TR><TD>Color:<TD><input class=\"jscolor {onFineChange:'update(this)'}\" value='");
string += hexvalue;
string += F("'>");
addFormNumericBox(string, F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
addNumericBox(string, F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
addNumericBox(string, F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
addHtml(F("<TR><TD>Color:<TD><input class=\"jscolor {onFineChange:'update(this)'}\" value='"));
addHtml(hexvalue);
addHtml(F("'>"));
addFormNumericBox(F("RGB Color"), F("web_RGB_Red"), Settings.TaskDevicePluginConfig[event->TaskIndex][0], 0, 255);
addNumericBox(F("web_RGB_Green"), Settings.TaskDevicePluginConfig[event->TaskIndex][1], 0, 255);
addNumericBox(F("web_RGB_Blue"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 255);
// Brightness Selection
string += F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='");
string += Settings.TaskDevicePluginConfig[event->TaskIndex][3];
string += F("'> max");
addHtml(F("<TR><TD>Brightness:<TD>min<input type='range' id='web_Bright_Slide' min='0' max='255' value='"));
addHtml(String(Settings.TaskDevicePluginConfig[event->TaskIndex][3]));
addHtml(F("'> max"));
sprintf_P(tmpString, PSTR("<TR><TD>Brightness Value:<TD><input type='text' name='web_Bright_Text' id='web_Bright_Text' size='3' value='%u'>"), Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
string += tmpString;
addHtml(tmpString);
// Some Javascript we need to update the items
string += F("<script script type='text/javascript'>");
string += F("function update(picker) {");
string += F(" document.getElementById('web_RGB_Red').value = Math.round(picker.rgb[0]);");
string += F(" document.getElementById('web_RGB_Green').value = Math.round(picker.rgb[1]);");
string += F(" document.getElementById('web_RGB_Blue').value = Math.round(picker.rgb[2]);");
string += F("}");
string += F("</script>");
addHtml(F("<script script type='text/javascript'>"));
addHtml(F("function update(picker) {"));
addHtml(F(" document.getElementById('web_RGB_Red').value = Math.round(picker.rgb[0]);"));
addHtml(F(" document.getElementById('web_RGB_Green').value = Math.round(picker.rgb[1]);"));
addHtml(F(" document.getElementById('web_RGB_Blue').value = Math.round(picker.rgb[2]);"));
addHtml(F("}"));
addHtml(F("</script>"));
string += F("<script type='text/javascript'>window.addEventListener('load', function(){");
string += F("var slider = document.getElementById('web_Bright_Slide');");
string += F("slider.addEventListener('change', function(){");
string += F("document.getElementById('web_Bright_Text').value = this.value;");
string += F("});");
string += F("});</script>");
addHtml(F("<script type='text/javascript'>window.addEventListener('load', function(){"));
addHtml(F("var slider = document.getElementById('web_Bright_Slide');"));
addHtml(F("slider.addEventListener('change', function(){"));
addHtml(F("document.getElementById('web_Bright_Text').value = this.value;"));
addHtml(F("});"));
addHtml(F("});</script>"));
success = true;
break;
@@ -718,3 +719,4 @@ void RGBtoHSV(byte r, byte g, byte b, double hsv[3]) {
hsv[1] = s * 255;
hsv[2] = v * 255;
}
#endif // USES_P042
+12 -10
View File
@@ -1,3 +1,4 @@
#ifdef USES_P043
//#######################################################################################################
//#################################### Plugin 043: Clock Output #########################################
//#######################################################################################################
@@ -49,18 +50,18 @@ boolean Plugin_043(byte function, struct EventStruct *event, String& string)
for (byte x = 0; x < PLUGIN_043_MAX_SETTINGS; x++)
{
addFormTextBox(string, String(F("Day,Time ")) + (x + 1), String(F("plugin_043_clock")) + (x), timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]), 32);
// string += F("<TR><TD>Day,Time ");
// string += x+1;
// string += F(":<TD><input type='text' name='plugin_043_clock");
// string += x;
// string += F("' value='");
// string += timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]);
// string += F("'>");
addFormTextBox(String(F("Day,Time ")) + (x + 1), String(F("plugin_043_clock")) + (x), timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]), 32);
// addHtml(F("<TR><TD>Day,Time "));
// addHtml(x+1);
// addHtml(F(":<TD><input type='text' name='plugin_043_clock"));
// addHtml(x);
// addHtml(F("' value='"));
// addHtml(timeLong2String(ExtraTaskSettings.TaskDevicePluginConfigLong[x]));
// addHtml(F("'>"));
string += F(" ");
addHtml(F(" "));
byte choice = ExtraTaskSettings.TaskDevicePluginConfig[x];
addSelector(string, String(F("plugin_043_state")) + (x), 3, options, NULL, NULL, choice, false);
addSelector(String(F("plugin_043_state")) + (x), 3, options, NULL, NULL, choice, false);
}
success = true;
break;
@@ -119,3 +120,4 @@ boolean Plugin_043(byte function, struct EventStruct *event, String& string)
}
return success;
}
#endif // USES_P043
+11 -9
View File
@@ -1,3 +1,4 @@
#ifdef USES_P044
//#################################### Plugin 044: P1WifiGateway ########################################
//
// based on P020 Ser2Net, extended by Ronald Leenes romix/-at-/macuser.nl
@@ -65,9 +66,9 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormNumericBox(string, F("TCP Port"), F("plugin_044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
addFormNumericBox(string, F("Baud Rate"), F("plugin_044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
addFormNumericBox(string, F("Data bits"), F("plugin_044_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
addFormNumericBox(F("TCP Port"), F("plugin_044_port"), ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
addFormNumericBox(F("Baud Rate"), F("plugin_044_baud"), ExtraTaskSettings.TaskDevicePluginConfigLong[1]);
addFormNumericBox(F("Data bits"), F("plugin_044_data"), ExtraTaskSettings.TaskDevicePluginConfigLong[2]);
byte choice = ExtraTaskSettings.TaskDevicePluginConfigLong[3];
String options[3];
@@ -75,13 +76,13 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
options[1] = F("Even");
options[2] = F("Odd");
int optionValues[3] = { 0, 2, 3 };
addFormSelector(string, F("Parity"), F("plugin_044_parity"), 3, options, optionValues, choice);
addFormSelector(F("Parity"), F("plugin_044_parity"), 3, options, optionValues, choice);
addFormNumericBox(string, F("Stop bits"), F("plugin_044_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
addFormNumericBox(F("Stop bits"), F("plugin_044_stop"), ExtraTaskSettings.TaskDevicePluginConfigLong[4]);
addFormPinSelect(string, F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
addFormPinSelect(F("Reset target after boot"), F("taskdevicepin1"), Settings.TaskDevicePin1[event->TaskIndex]);
addFormNumericBox(string, F("RX Receive Timeout (mSec)"), F("plugin_044_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addFormNumericBox(F("RX Receive Timeout (mSec)"), F("plugin_044_rxwait"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
success = true;
break;
@@ -123,7 +124,7 @@ boolean Plugin_044(byte function, struct EventStruct *event, String& string)
#endif
#if defined(ESP32)
Serial.begin(ExtraTaskSettings.TaskDevicePluginConfigLong[1], serialconfig);
#endif
#endif
if (P1GatewayServer) P1GatewayServer->close();
P1GatewayServer = new WiFiServer(ExtraTaskSettings.TaskDevicePluginConfigLong[0]);
P1GatewayServer->begin();
@@ -347,7 +348,7 @@ void blinkLED() {
checks whether the incoming character is a valid one for a P1 datagram. Returns false if not, which signals corrupt datagram
*/
bool validP1char(char ch) {
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '.') || (ch == '!') || (ch == 92) || (ch == 13) || (ch == '\n') || (ch == '(') || (ch == ')') || (ch == '-') || (ch == '*') || (ch == ':') )
if ((ch >= '0' && ch <= '9') || (ch >= 'a' && ch <= 'z') || (ch >= 'A' && ch <= 'Z') || (ch == '.') || (ch == '!') || (ch == ' ') || (ch == 92) || (ch == 13) || (ch == '\n') || (ch == '(') || (ch == ')') || (ch == '-') || (ch == '*') || (ch == ':') )
{
return true;
} else {
@@ -436,3 +437,4 @@ bool checkDatagram(int len) {
}
return validCRCFound;
}
#endif // USES_P044
+19 -17
View File
@@ -1,3 +1,4 @@
#ifdef USES_P045
//#######################################################################################################
//#################################### Plugin 045: MPU6050 [Testing] ####################################
//#######################################################################################################
@@ -122,8 +123,8 @@ boolean Plugin_045(byte function, struct EventStruct *event, String& string)
int optionValues[2];
optionValues[0] = 0x68;
optionValues[1] = 0x69;
addFormSelectorI2C(string, F("plugin_045_address"), 2, optionValues, choice);
addFormNote(string, F("ADDR Low=0x68, High=0x69"));
addFormSelectorI2C(F("plugin_045_address"), 2, optionValues, choice);
addFormNote(F("ADDR Low=0x68, High=0x69"));
choice = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String options[10];
@@ -137,28 +138,28 @@ boolean Plugin_045(byte function, struct EventStruct *event, String& string)
options[7] = F("G-force X");
options[8] = F("G-force Y");
options[9] = F("G-force Z");
addFormSelector(string, F("Function"), F("plugin_045_function"), 10, options, NULL, choice);
addFormSelector(F("Function"), F("plugin_045_function"), 10, options, NULL, choice);
if (choice == 0) {
// If this is instance function 0, setup webform for additional vars
// Show some user information about the webform and what the vars mean.
string += F("<TR><TD><TD>The thresholdvalues (0-65535) can be used to set a threshold for one or more<br>");
string += F("axis. The axis will trigger when the range for that axis exceeds the threshold<br>");
string += F("value. A value of 0 disables movement detection for that axis.");
addHtml(F("<TR><TD><TD>The thresholdvalues (0-65535) can be used to set a threshold for one or more<br>"));
addHtml(F("axis. The axis will trigger when the range for that axis exceeds the threshold<br>"));
addHtml(F("value. A value of 0 disables movement detection for that axis."));
addFormNumericBox(string, F("Detection threshold X"), F("plugin_045_threshold_x"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 65535);
addFormNumericBox(string, F("Detection threshold Y"), F("plugin_045_threshold_y"), Settings.TaskDevicePluginConfig[event->TaskIndex][3], 0, 65535);
addFormNumericBox(string, F("Detection threshold Z"), F("plugin_045_threshold_z"), Settings.TaskDevicePluginConfig[event->TaskIndex][4], 0, 65535);
addFormNumericBox(F("Detection threshold X"), F("plugin_045_threshold_x"), Settings.TaskDevicePluginConfig[event->TaskIndex][2], 0, 65535);
addFormNumericBox(F("Detection threshold Y"), F("plugin_045_threshold_y"), Settings.TaskDevicePluginConfig[event->TaskIndex][3], 0, 65535);
addFormNumericBox(F("Detection threshold Z"), F("plugin_045_threshold_z"), Settings.TaskDevicePluginConfig[event->TaskIndex][4], 0, 65535);
string += F("<TR><TD><TD>Each 30 seconds a counter for the detection window is increased plus all axis<br>");
string += F("are checked and if they *all* exceeded the threshold values, a counter is increased.<br>");
string += F("Each period, defined by the [detection window], the counter is checked against<br>");
string += F("the [min. detection count] and if found equal or larger, movement is detected.<br>");
string += F("If in the next window the [min. detection count] value is not met, movement has stopped.");
string += F("The [detection window] cannot be smaller than the [min. detection count].");
addHtml(F("<TR><TD><TD>Each 30 seconds a counter for the detection window is increased plus all axis<br>"));
addHtml(F("are checked and if they *all* exceeded the threshold values, a counter is increased.<br>"));
addHtml(F("Each period, defined by the [detection window], the counter is checked against<br>"));
addHtml(F("the [min. detection count] and if found equal or larger, movement is detected.<br>"));
addHtml(F("If in the next window the [min. detection count] value is not met, movement has stopped."));
addHtml(F("The [detection window] cannot be smaller than the [min. detection count]."));
addFormNumericBox(string, F("Min. detection count"), F("plugin_045_threshold_counter"), Settings.TaskDevicePluginConfig[event->TaskIndex][5], 0, 999999);
addFormNumericBox(string, F("Detection window"), F("plugin_045_threshold_window"), Settings.TaskDevicePluginConfig[event->TaskIndex][6], 0, 999999);
addFormNumericBox(F("Min. detection count"), F("plugin_045_threshold_counter"), Settings.TaskDevicePluginConfig[event->TaskIndex][5], 0, 999999);
addFormNumericBox(F("Detection window"), F("plugin_045_threshold_window"), Settings.TaskDevicePluginConfig[event->TaskIndex][6], 0, 999999);
}
success = true;
@@ -401,3 +402,4 @@ void _P045_writeBits(uint8_t devAddr, uint8_t regAddr, uint8_t bitStart, uint8_t
}
}
#endif
#endif // USES_P045
+30 -28
View File
@@ -1,3 +1,4 @@
#ifdef USES_P046
//#######################################################################################################
//#################################### Plugin 046: Ventus W266 [Testing] ################################
//#######################################################################################################
@@ -154,74 +155,74 @@ boolean Plugin_046(byte function, struct EventStruct *event, String& string)
options[7] = F("Unknown 2, byte 16");
options[8] = F("Unknown 3, byte 19");
addFormSelector(string, F("Plugin function"), F("plugin_046"), nrchoices, options, NULL, choice);
addFormSelector(F("Plugin function"), F("plugin_046"), nrchoices, options, NULL, choice);
if (choice==0) {
string += F("<TR><TD>1st GPIO (5-MOSI):<TD>");
addPinSelect(false, string, "taskdevicepin1", Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
string += F("<TR><TD>2nd GPIO (6-SCLK):<TD>");
addPinSelect(false, string, "taskdevicepin2", Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
string += F("<TR><TD>3rd GPIO (7-nSEL):<TD>");
addPinSelect(false, string, "taskdevicepin3", Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
string += F("<TR><TD>4th GPIO (8-MISO):<TD>");
addPinSelect(false, string, "taskdeviceport", Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
addHtml(F("<TR><TD>1st GPIO (5-MOSI):<TD>"));
addPinSelect(false, "taskdevicepin1", Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addHtml(F("<TR><TD>2nd GPIO (6-SCLK):<TD>"));
addPinSelect(false, "taskdevicepin2", Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addHtml(F("<TR><TD>3rd GPIO (7-nSEL):<TD>"));
addPinSelect(false, "taskdevicepin3", Settings.TaskDevicePluginConfig[event->TaskIndex][3]);
addHtml(F("<TR><TD>4th GPIO (8-MISO):<TD>"));
addPinSelect(false, "taskdeviceport", Settings.TaskDevicePluginConfig[event->TaskIndex][4]);
}
switch (choice)
{
case (0):
{
string += F("<TR><TD><B>Be sure you only have 1 main plugin!</B></TD>");
string += F("<TR><TD>Value 1: Temperature, 1 decimal<BR>Value 2: Humidity, 0 decimals");
string += F("<BR>Value 3: not used</TD>");
addHtml(F("<TR><TD><B>Be sure you only have 1 main plugin!</B></TD>"));
addHtml(F("<TR><TD>Value 1: Temperature, 1 decimal<BR>Value 2: Humidity, 0 decimals"));
addHtml(F("<BR>Value 3: not used</TD>"));
break;
}
case (1):
{
string += F("<TR><TD>Value 1: Direction, 0 decimals<BR>");
string += F("Value 2: Average, 1 decimal<Br>Value 3: Gust, 1 decimal</TD>");
addHtml(F("<TR><TD>Value 1: Direction, 0 decimals<BR>"));
addHtml(F("Value 2: Average, 1 decimal<Br>Value 3: Gust, 1 decimal</TD>"));
break;
}
case (2):
{
string += F("<TR><TD>Value 1: Rain in mm per hour<BR>Value 2: Total rain in mm");
string += F("<BR>Value 3: not used</TD>");
addHtml(F("<TR><TD>Value 1: Rain in mm per hour<BR>Value 2: Total rain in mm"));
addHtml(F("<BR>Value 3: not used</TD>"));
break;
}
case (3):
{
string += F("<TR><TD>Value 1: UV, 1 decimal");
string += F("<BR>Values 2, 3</TD>");
addHtml(F("<TR><TD>Value 1: UV, 1 decimal"));
addHtml(F("<BR>Values 2, 3</TD>"));
break;
}
case (4):
{
string += F("<TR><TD>Value 1: Strikes this hour, 0 decimals");
string += F("<BR>Values 2, 3: not used</TD>");
addHtml(F("<TR><TD>Value 1: Strikes this hour, 0 decimals"));
addHtml(F("<BR>Values 2, 3: not used</TD>"));
break;
}
case (5):
{
string += F("<TR><TD>Value 1: Distance in km, 0 decimals");
string += F("<BR>Values 2, 3: not used</TD>");
addHtml(F("<TR><TD>Value 1: Distance in km, 0 decimals"));
addHtml(F("<BR>Values 2, 3: not used</TD>"));
break;
}
case (6):
{
string += F("<TR><TD>Value 1: Batterybyte, 0 decimals");
string += F("<BR>Values 2, 3: not used</TD>");
addHtml(F("<TR><TD>Value 1: Batterybyte, 0 decimals"));
addHtml(F("<BR>Values 2, 3: not used</TD>"));
break;
}
case (7):
{
string += F("<TR><TD>Value 1: Last rainbyte, 0 decimals");
string += F("<BR>Values 2, 3: not used</TD>");
addHtml(F("<TR><TD>Value 1: Last rainbyte, 0 decimals"));
addHtml(F("<BR>Values 2, 3: not used</TD>"));
break;
}
case (8):
{
string += F("<TR><TD>Value 1: Last lightningbyte, 0 decimals");
string += F("<BR>Values 2, 3: not used</TD>");
addHtml(F("<TR><TD>Value 1: Last lightningbyte, 0 decimals"));
addHtml(F("<BR>Values 2, 3: not used</TD>"));
break;
}
}
@@ -499,3 +500,4 @@ void Plugin_046_ISR_SCLK() // Interrupt on
}
}
#endif
#endif // USES_P046
+9 -7
View File
@@ -1,3 +1,4 @@
#ifdef USES_P047
//#######################################################################################################
//#################### Plugin 047 Moisture & Temperature & Light I2C Soil moisture sensor ##############
//#######################################################################################################
@@ -75,20 +76,20 @@ boolean Plugin_047(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
addFormTextBox(string, F("I2C Address (Hex)"), F("plugin_047_i2cSoilMoisture_i2cAddress"), String(F("0x")) +
addFormTextBox(F("I2C Address (Hex)"), F("plugin_047_i2cSoilMoisture_i2cAddress"), String(F("0x")) +
String(Settings.TaskDevicePluginConfig[event->TaskIndex][0],HEX), 4);
addFormCheckBox(string, F("Send sensor to sleep"), F("plugin_047_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormCheckBox(F("Send sensor to sleep"), F("plugin_047_sleep"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormCheckBox(string, F("Check sensor version") ,F("plugin_047_version"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addFormCheckBox(F("Check sensor version") ,F("plugin_047_version"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
addFormSeparator(string);
addFormSeparator(2);
addFormCheckBox(string, F("Change Sensor address"),F("plugin_047_changeAddr"), false);
addFormTextBox(string, F("Change I2C Addr. to (Hex)"), F("plugin_047_i2cSoilMoisture_changeAddr"), String(F("0x")) +
addFormCheckBox(F("Change Sensor address"),F("plugin_047_changeAddr"), false);
addFormTextBox(F("Change I2C Addr. to (Hex)"), F("plugin_047_i2cSoilMoisture_changeAddr"), String(F("0x")) +
String(Settings.TaskDevicePluginConfig[event->TaskIndex][0],HEX), 4);
addFormSeparator(string);
addFormSeparator(2);
success = true;
break;
@@ -302,3 +303,4 @@ bool Plugin_047_setAddress(int addr) {
#endif
#endif // USES_P047
+10 -9
View File
@@ -1,3 +1,4 @@
#ifdef USES_P048
//#######################################################################################################
//#################################### Plugin 048: Adafruit Motorshield v2 ##############################
//#######################################################################################################
@@ -58,13 +59,13 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
case PLUGIN_WEBFORM_LOAD: {
addFormTextBox(string, F("I2C Address (Hex)"), F("plugin_048_adr"), String(F("0x")) +
addFormTextBox(F("I2C Address (Hex)"), F("plugin_048_adr"), String(F("0x")) +
String(Settings.TaskDevicePluginConfig[event->TaskIndex][0],HEX), 4);
addFormNumericBox(string, F("Stepper: steps per revolution"), F("plugin_048_MotorStepsPerRevolution")
addFormNumericBox(F("Stepper: steps per revolution"), F("plugin_048_MotorStepsPerRevolution")
, Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addFormNumericBox(string, F("Stepper speed (rpm)"), F("plugin_048_StepperSpeed")
addFormNumericBox(F("Stepper speed (rpm)"), F("plugin_048_StepperSpeed")
, Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
success = true;
@@ -102,18 +103,17 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
String tmpString = string;
String cmd = parseString(tmpString, 1);
String param1 = parseString(tmpString, 2);
String param2 = parseString(tmpString, 3);
String param3 = parseString(tmpString, 4);
String param4 = parseString(tmpString, 5);
String param5 = parseString(tmpString, 6);
// Commands:
// MotorShieldCMD,<DCMotor>,<Motornumber>,<Forward/Backward/Release>,<Speed>
if (cmd.equalsIgnoreCase(F("MotorShieldCMD")))
{
String param1 = parseString(tmpString, 2);
String param2 = parseString(tmpString, 3);
String param3 = parseString(tmpString, 4);
String param4 = parseString(tmpString, 5);
String param5 = parseString(tmpString, 6);
// Create the motor shield object with the default I2C address
AFMS = Adafruit_MotorShield(Plugin_048_MotorShield_address);
@@ -277,3 +277,4 @@ boolean Plugin_048(byte function, struct EventStruct *event, String& string) {
#endif
#endif // USES_P048
+59 -12
View File
@@ -1,3 +1,4 @@
#ifdef USES_P049
/*
This plug in is written by Dmitry (rel22 ___ inbox.ru)
@@ -5,10 +6,25 @@
Additional features based on https://geektimes.ru/post/285572/ by Gerben (infernix__AT__gmail.com)
This plugin reads the CO2 value from MH-Z19 NDIR Sensor
DevicePin1 - is RX for ESP
DevicePin2 - is TX for ESP
Pin-out:
Hd o
SR o o PWM
Tx o o AOT
Rx o o GND
Vo o o Vin
(bottom view)
Skipping pin numbers due to inconsistancies in individual data sheet revisions.
MHZ19: Connection:
VCC 5 V
GND GND
Tx ESP8266 1st GPIO specified in Device-settings
Rx ESP8266 2nd GPIO specified in Device-settings
*/
// Uncomment the following define to enable the detection range commands:
//#define ENABLE_DETECTION_RANGE_COMMANDS
#define PLUGIN_049
#define PLUGIN_ID_049 49
#define PLUGIN_NAME_049 "Gases - CO2 MH-Z19"
@@ -36,31 +52,56 @@ enum mhzCommands : byte { mhzCmdReadPPM,
mhzCmdABCEnable,
mhzCmdABCDisable,
mhzCmdReset,
#ifdef ENABLE_DETECTION_RANGE_COMMANDS
mhzCmdMeasurementRange1000,
mhzCmdMeasurementRange2000,
mhzCmdMeasurementRange3000,
mhzCmdMeasurementRange5000 };
mhzCmdMeasurementRange5000
#endif
};
// 9 byte commands:
// mhzCmdReadPPM[] = {0xFF,0x01,0x86,0x00,0x00,0x00,0x00,0x00,0x79};
// mhzCmdCalibrateZero[] = {0xFF,0x01,0x87,0x00,0x00,0x00,0x00,0x00,0x78};
// mhzCmdABCEnable[] = {0xFF,0x01,0x79,0xA0,0x00,0x00,0x00,0x00,0xE6};
// mhzCmdABCDisable[] = {0xFF,0x01,0x79,0x00,0x00,0x00,0x00,0x00,0x86};
// mhzCmdReset[] = {0xFF,0x01,0x8d,0x00,0x00,0x00,0x00,0x00,0x72};
// mhzCmdMeasurementRange1000[] = {0xFF,0x01,0x99,0x03,0xE8,0x00,0x00,0x00,0x7B};
// mhzCmdMeasurementRange2000[] = {0xFF,0x01,0x99,0x07,0xD0,0x00,0x00,0x00,0x8F};
// mhzCmdMeasurementRange3000[] = {0xFF,0x01,0x99,0x0B,0xB8,0x00,0x00,0x00,0xA3};
// mhzCmdMeasurementRange5000[] = {0xFF,0x01,0x99,0x13,0x88,0x00,0x00,0x00,0xCB};
// Removing redundant data, just keeping offsets [2]..[4]:
/* It seems the offsets [3]..[4] for the detection range setting (command byte 0x99) are wrong in the latest
* online data sheet: http://www.winsen-sensor.com/d/files/infrared-gas-sensor/mh-z19b-co2-ver1_0.pdf
* According to the MH-Z19B datasheet version 1.2, valid from: 2017.03.22 (received 2018-03-07)
* the offset should be [6]..[7] instead.
* 0x99 - Detection range setting, send command:
* /---------+---------+---------+---------+---------+---------+---------+---------+---------\
* | Byte 0 | Byte 1 | Byte 2 | Byte 3 | Byte 4 | Byte 5 | Byte 6 | Byte 7 | Byte 8 |
* |---------+---------+---------+---------+---------+---------+---------+---------+---------|
* | Start | Reserved| Command | Reserved|Detection|Detection|Detection|Detection| Checksum|
* | Byte | | | |range |range |range |range | |
* | | | | |24~32 bit|16~23 bit|8~15 bit |0~7 bit | |
* |---------+---------+---------+---------+---------+---------+---------+---------+---------|
* | 0xFF | 0x01 | 0x99 | 0x00 | Data 1 | Data 2 | Data 3 | Data 4 | Checksum|
* \---------+---------+---------+---------+---------+---------+---------+---------+---------/
* Note: Detection range should be 0~2000, 0~5000, 0~10000 ppm.
* For example: set 0~2000 ppm detection range, send command: FF 01 99 00 00 00 07 D0 8F
* set 0~10000 ppm detection range, send command: FF 01 99 00 00 00 27 10 8F
* The latter, updated version above is implemented here.
*/
// mhzCmdMeasurementRange1000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x03,0xE8,0x7B};
// mhzCmdMeasurementRange2000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x07,0xD0,0x8F};
// mhzCmdMeasurementRange3000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x0B,0xB8,0xA3};
// mhzCmdMeasurementRange5000[] = {0xFF,0x01,0x99,0x00,0x00,0x00,0x13,0x88,0xCB};
// Removing redundant data, just keeping offsets [2], [6]..[7]:
const PROGMEM byte mhzCmdData[][3] = {
{0x86,0x00,0x00},
{0x87,0x00,0x00},
{0x79,0xA0,0x00},
{0x79,0x00,0x00},
{0x8d,0x00,0x00},
#ifdef ENABLE_DETECTION_RANGE_COMMANDS
{0x99,0x03,0xE8},
{0x99,0x07,0xD0},
{0x99,0x0B,0xB8},
{0x99,0x13,0x88}};
{0x99,0x13,0x88}
#endif
};
byte mhzResp[9]; // 9 byte response buffer
@@ -162,7 +203,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
byte choice = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String options[2] = { F("Normal"), F("ABC disabled") };
int optionValues[2] = { ABC_enabled, ABC_disabled };
addFormSelector(string, F("Auto Base Calibration"), F("plugin_049_abcdisable"), 2, options, optionValues, choice);
addFormSelector(F("Auto Base Calibration"), F("plugin_049_abcdisable"), 2, options, optionValues, choice);
byte choiceFilter = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String filteroptions[5] = { F("Skip Unstable"), F("Use Unstable"), F("Fast Response"), F("Medium Response"), F("Slow Response") };
int filteroptionValues[5] = {
@@ -171,7 +212,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
PLUGIN_049_FILTER_FAST,
PLUGIN_049_FILTER_MEDIUM,
PLUGIN_049_FILTER_SLOW };
addFormSelector(string, F("Filter"), F("plugin_049_filter"), 5, filteroptions, filteroptionValues, choiceFilter);
addFormSelector(F("Filter"), F("plugin_049_filter"), 5, filteroptions, filteroptionValues, choiceFilter);
success = true;
break;
@@ -245,6 +286,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
success = true;
}
#ifdef ENABLE_DETECTION_RANGE_COMMANDS
if (command == F("mhzmeasurementrange1000"))
{
_P049_send_mhzCmd(mhzCmdMeasurementRange1000);
@@ -272,6 +314,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
addLog(LOG_LEVEL_INFO, F("MHZ19: Sent measurement range 0-5000PPM!"));
success = true;
}
#endif
break;
}
@@ -412,6 +455,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
addLog(LOG_LEVEL_INFO, log);
break;
//#ifdef ENABLE_DETECTION_RANGE_COMMANDS
// Sensor responds with 0x99 whenever we send it a measurement range adjustment
} else if (mhzResp[0] == 0xFF && mhzResp[1] == 0x99 && mhzResp[8] == checksum) {
@@ -419,6 +463,7 @@ boolean Plugin_049(byte function, struct EventStruct *event, String& string)
addLog(LOG_LEVEL_INFO, F("Expecting sensor reset..."));
success = false;
break;
//#endif
// log verbosely anything else that the sensor reports
} else {
@@ -456,8 +501,10 @@ size_t _P049_send_mhzCmd(byte CommandId)
mhzResp[0] = 0xFF; // Start byte, fixed
mhzResp[1] = 0x01; // Sensor number, 0x01 by default
memcpy_P(&mhzResp[2], mhzCmdData[CommandId], sizeof(mhzCmdData[0]));
mhzResp[5] = mhzResp[6] = mhzResp[7] = 0x00;
mhzResp[6] = mhzResp[3]; mhzResp[7] = mhzResp[4];
mhzResp[3] = mhzResp[4] = mhzResp[5] = 0x00;
mhzResp[8] = _P049_calculateChecksum(mhzResp);
return Plugin_049_SoftSerial->write(mhzResp, sizeof(mhzResp));
}
#endif // USES_P049
+4 -2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P050
//#######################################################################################################
//#################### Plugin 050 I2C TCS34725 RGB Color Sensor with IR filter and White LED ############
//#######################################################################################################
@@ -78,7 +79,7 @@ boolean Plugin_050(byte function, struct EventStruct *event, String& string)
optionValuesMode[3] = TCS34725_INTEGRATIONTIME_101MS;
optionValuesMode[4] = TCS34725_INTEGRATIONTIME_154MS;
optionValuesMode[5] = TCS34725_INTEGRATIONTIME_700MS;
addFormSelector(string, F("Integration Time"), F("plugin_050_integrationTime"), 6, optionsMode, optionValuesMode, choiceMode);
addFormSelector(F("Integration Time"), F("plugin_050_integrationTime"), 6, optionsMode, optionValuesMode, choiceMode);
byte choiceMode2 = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String optionsMode2[4];
@@ -91,7 +92,7 @@ boolean Plugin_050(byte function, struct EventStruct *event, String& string)
optionValuesMode2[1] = TCS34725_GAIN_4X;
optionValuesMode2[2] = TCS34725_GAIN_16X;
optionValuesMode2[3] = TCS34725_GAIN_60X;
addFormSelector(string, F("Gain"), F("plugin_050_gain"), 4, optionsMode2, optionValuesMode2, choiceMode2);
addFormSelector(F("Gain"), F("plugin_050_gain"), 4, optionsMode2, optionValuesMode2, choiceMode2);
success = true;
break;
@@ -176,3 +177,4 @@ boolean Plugin_050(byte function, struct EventStruct *event, String& string)
#endif
#endif // USES_P050
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P051
//#######################################################################################################
//#################### Plugin 051 Temperature and Humidity Sensor AM2320 ##############
//#######################################################################################################
@@ -102,3 +103,4 @@ boolean Plugin_051(byte function, struct EventStruct *event, String& string)
#endif
#endif // USES_P051
+4 -2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P052
//#######################################################################################################
//############################# Plugin 052: Senseair CO2 Sensors ########################################
//#######################################################################################################
@@ -100,14 +101,14 @@ boolean Plugin_052(byte function, struct EventStruct *event, String& string)
byte choiceSensor = Settings.TaskDevicePluginConfig[event->TaskIndex][0];
String optionsSensor[7] = { F("Error Status"), F("Carbon Dioxide"), F("Temperature"), F("Humidity"), F("Relay Status"), F("Temperature Adjustment"), F("ABC period") };
addFormSelector(string, F("Sensor"), F("plugin_052_sensor"), 7, optionsSensor, NULL, choiceSensor);
addFormSelector(F("Sensor"), F("plugin_052_sensor"), 7, optionsSensor, NULL, choiceSensor);
/*
// ABC functionality disabled for now, due to a bug in the firmware.
// See https://github.com/letscontrolit/ESPEasy/issues/759
byte choiceABCperiod = Settings.TaskDevicePluginConfig[event->TaskIndex][1];
String optionsABCperiod[9] = { F("disable"), F("1 h"), F("12 h"), F("1 day"), F("2 days"), F("4 days"), F("7 days"), F("14 days"), F("30 days") };
addFormSelector(string, F("ABC period"), F("plugin_052_ABC_period"), 9, optionsABCperiod, NULL, choiceABCperiod);
addFormSelector(F("ABC period"), F("plugin_052_ABC_period"), 9, optionsABCperiod, NULL, choiceABCperiod);
*/
success = true;
@@ -416,3 +417,4 @@ int getBitOfInt(int reg, int pos)
return result;
}
#endif // USES_P052
+2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P053
//#######################################################################################################
//#################################### Plugin 053: Plantower PMSx003 ####################################
//#######################################################################################################
@@ -301,3 +302,4 @@ boolean Plugin_053(byte function, struct EventStruct *event, String& string)
return success;
}
#endif // PLUGIN_BUILD_TESTING
#endif // USES_P053
+4 -2
View File
@@ -1,3 +1,4 @@
#ifdef USES_P054
//#######################################################################################################
//######################################## Plugin 054: DMX512 TX ########################################
//#######################################################################################################
@@ -100,8 +101,8 @@ boolean Plugin_054(byte function, struct EventStruct *event, String& string)
{
Settings.TaskDevicePin1[event->TaskIndex] = 2;
Settings.TaskDevicePluginConfig[event->TaskIndex][0] = Plugin_054_DMXSize;
addFormNote(string, F("Only GPIO-2 (D4) can be used as TX1!"));
addFormNumericBox(string, F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512);
addFormNote(F("Only GPIO-2 (D4) can be used as TX1!"));
addFormNumericBox(F("Channels"), F("channels"), Plugin_054_DMXSize, 1, 512);
success = true;
break;
}
@@ -256,3 +257,4 @@ boolean Plugin_054(byte function, struct EventStruct *event, String& string)
}
#endif //PLUGIN_BUILD_TESTING
#endif // USES_P054
+14 -13
View File
@@ -1,3 +1,4 @@
#ifdef USES_P055
//#######################################################################################################
//#################################### Plugin 055: Chiming Mechanism ####################################
//#######################################################################################################
@@ -135,29 +136,28 @@ boolean Plugin_055(byte function, struct EventStruct *event, String& string)
if (Settings.TaskDevicePluginConfig[event->TaskIndex][1] <= 0) //Plugin_055_millisPauseTime
Settings.TaskDevicePluginConfig[event->TaskIndex][1] = 400;
addFormPinSelect(string, F("GPIO &rarr; Driver#8"), F("TDP4"), (int)(Settings.TaskDevicePin[3][event->TaskIndex]));
addFormPinSelect(F("GPIO &rarr; Driver#8"), F("TDP4"), (int)(Settings.TaskDevicePin[3][event->TaskIndex]));
addFormSubHeader(string, F("Timing"));
addFormSubHeader(F("Timing"));
addFormNumericBox(string, F("Chiming/Strike Time (ct)"), F("chimetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addUnit(string, F("ms"));
addFormNumericBox(F("Chiming/Strike Time (ct)"), F("chimetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][0]);
addUnit(F("ms"));
addFormNumericBox(string, F("Normal Pause Time (t)"), F("pausetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(string, F("ms"));
addFormNumericBox(F("Normal Pause Time (t)"), F("pausetime"), Settings.TaskDevicePluginConfig[event->TaskIndex][1]);
addUnit(F("ms"));
addFormNote(string, F("'1=1'&rArr;3t, '1-1' or '11'&rArr;1t, '1.1'&rArr;&#8531;t, '1|1'&rArr;&frac12;ct"));
addFormNote(F("'1=1'&rArr;3t, '1-1' or '11'&rArr;1t, '1.1'&rArr;&#8531;t, '1|1'&rArr;&frac12;ct"));
addFormSubHeader(string, F("Chiming Clock"));
addFormSubHeader(F("Chiming Clock"));
addFormCheckBox(string, F("Hourly Chiming Clock Strike"), F("chimeclock"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
//string += F("<TR><TD><TD>");
string += F(" ");
addButton(string, F("'control?cmd=chimeplay,hours'"), F("Test 1&hellip;12"));
addFormCheckBox(F("Hourly Chiming Clock Strike"), F("chimeclock"), Settings.TaskDevicePluginConfig[event->TaskIndex][2]);
//addHtml(F("<TR><TD><TD>"));
addButton(F("'control?cmd=chimeplay,hours'"), F("Test 1&hellip;12"));
if (Settings.TaskDevicePluginConfig[event->TaskIndex][2] && !Settings.UseNTP)
addFormNote(string, F("Enable and configure NTP!"));
addFormNote(F("Enable and configure NTP!"));
success = true;
break;
@@ -501,3 +501,4 @@ byte Plugin_055_ReadChime(const String& name, String& tokens)
}
#endif
#endif // USES_P055
+5 -3
View File
@@ -1,3 +1,4 @@
#ifdef USES_P056
//#######################################################################################################
//#################################### Plugin 056: Dust Sensor SDS011 / SDS018 ##########################
//#######################################################################################################
@@ -62,11 +63,11 @@ boolean Plugin_056(byte function, struct EventStruct *event, String& string)
case PLUGIN_WEBFORM_LOAD:
{
if (Plugin_056_hasTxPin(event)) {
addFormNumericBox(string, F("Sleep time"), F("plugin_056_sleeptime"),
addFormNumericBox(F("Sleep time"), F("plugin_056_sleeptime"),
Settings.TaskDevicePluginConfig[event->TaskIndex][0],
0, 30);
addUnit(string, F("Minutes"));
addFormNote(string, F("0 = continous, 1..30 = Work 30 seconds and sleep n*60-30 seconds"));
addUnit(F("Minutes"));
addFormNote(F("0 = continous, 1..30 = Work 30 seconds and sleep n*60-30 seconds"));
}
break;
}
@@ -204,3 +205,4 @@ void Plugin_056_setWorkingPeriod(int minutes) {
}
#endif //PLUGIN_BUILD_TESTING
#endif // USES_P056
+12 -10
View File
@@ -1,3 +1,4 @@
#ifdef USES_P057
//#######################################################################################################
//#################################### Plugin 057: HT16K33 LED ##########################################
//#######################################################################################################
@@ -93,23 +94,23 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
byte addr = CONFIG(0);
int optionValues[8] = { 0x70, 0x71, 0x72, 0x73, 0x74, 0x75, 0x76, 0x77 };
addFormSelectorI2C(string, F("i2c_addr"), 8, optionValues, addr);
addFormSelectorI2C(F("i2c_addr"), 8, optionValues, addr);
addFormSubHeader(string, F("7-Seg. Clock"));
addFormSubHeader(F("7-Seg. Clock"));
int16_t choice = CONFIG(1);
String options[2] = { F("none"), F("7-Seg. HH:MM") };
addFormSelector(string, F("Clock Type"), F("clocktype"), 2, options, NULL, choice);
addFormSelector(F("Clock Type"), F("clocktype"), 2, options, NULL, choice);
addFormNumericBox(string, F("Seg. for <b>X</b>x:xx"), F("clocksegh10"), CONFIG(2), 0, 7);
addFormNumericBox(string, F("Seg. for x<b>X</b>:xx"), F("clocksegh1"), CONFIG(3), 0, 7);
addFormNumericBox(string, F("Seg. for xx:<b>X</b>x"), F("clocksegm10"), CONFIG(4), 0, 7);
addFormNumericBox(string, F("Seg. for xx:x<b>X</b>"), F("clocksegm1"), CONFIG(5), 0, 7);
addFormNumericBox(F("Seg. for <b>X</b>x:xx"), F("clocksegh10"), CONFIG(2), 0, 7);
addFormNumericBox(F("Seg. for x<b>X</b>:xx"), F("clocksegh1"), CONFIG(3), 0, 7);
addFormNumericBox(F("Seg. for xx:<b>X</b>x"), F("clocksegm10"), CONFIG(4), 0, 7);
addFormNumericBox(F("Seg. for xx:x<b>X</b>"), F("clocksegm1"), CONFIG(5), 0, 7);
addFormNumericBox(string, F("Seg. for Colon"), F("clocksegcol"), CONFIG(6), -1, 7);
string += F(" Value ");
addNumericBox(string, F("clocksegcolval"), CONFIG(7), 0, 255);
addFormNumericBox(F("Seg. for Colon"), F("clocksegcol"), CONFIG(6), -1, 7);
addHtml(F(" Value "));
addNumericBox(F("clocksegcolval"), CONFIG(7), 0, 255);
success = true;
break;
@@ -324,3 +325,4 @@ boolean Plugin_057(byte function, struct EventStruct *event, String& string)
}
#endif
#endif // USES_P057

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