├── Bundles
├── AbacusCountingMachine.zip
├── AbacusTimeTraveler.zip
├── AtHomeSimulator.zip
├── AveragingPlus.zip
├── BIControl.zip
├── ChromecastHelper.zip
├── DeviceCheckPlus.zip
├── DeviceTransformer.zip
├── DeviceWatchdog.zip
├── ErrorMonitor.zip
├── EventEngine.zip
├── FollowMe.zip
├── HomeTracker.zip
├── HubWatchdog.zip
├── Life360Tracker.zip
├── Life360withStates.zip
├── LifeEventCalendar.zip
├── MLBGameDayLive.zip
├── MyRadar.zip
├── NHLGameDayLive.zip
├── NormalStuffLibrary.zip
├── OneataTime.zip
├── OwnTracker.zip
├── PackageExplorer.zip
├── PatternsPlus.zip
├── PeriodicExpressions.zip
├── PresencePlus.zip
├── README.md
├── RemoteWellnessCheck.zip
├── RingKeypadSync.zip
├── SceneControl.zip
├── SendIP2IR.zip
├── SimpleDeviceTimer.zip
├── SimpleIrrigation.zip
├── SimpleKitchenTimer.zip
├── SimpleMultiTile.zip
├── Snapshot.zip
├── TheFlasher.zip
├── TileMaster.zip
├── aDeviceTest.zip
├── masterBundles.json
└── myBundles.json
├── Docs
├── Adding a Tile to Dashboard.md
├── BPTWorld Apps and Data Collection.md
├── CODE_OF_CONDUCT.md
├── CONTRIBUTING.md
├── How to Install a Custom App or Driver.md
├── LICENSE
├── README.md
├── Things to Remember.md
└── packageManifest - What is it.md
├── Drivers
├── Asthma Forecaster
│ ├── AF-driver.groovy
│ └── README.md
├── Inovelli_VZM36_Zigbee_Canopy
│ ├── VZM36-Canopy-Driver.groovy
│ ├── VZM36-Fan-Driver.groovy
│ ├── VZM36-Light-Driver.groovy
│ └── packageManifest.json
├── Marine Weather
│ ├── MW-driver.groovy
│ └── README.md
├── Pollen Forecaster
│ ├── PF-driver.groovy
│ └── README.md
├── Send to Hub with CATT
│ ├── README.md
│ └── STHWC-driver.groovy
└── gCalendar
│ ├── README.md
│ ├── gc-driver.groovy
│ └── packageManifest.json
├── LICENSE
├── README.md
├── _config.yml
├── apps
├── FlowEngine
│ ├── drawflow-css.min.css
│ ├── drawflow-extra.css
│ ├── drawflow-js.min.js
│ ├── favicon.ico
│ ├── flowengine-child.groovy
│ ├── flowengine-parent.groovy
│ ├── flowengineeditor.html
│ ├── flowvars.js
│ ├── packageManifest.json
│ ├── pickr.es5.min.js
│ └── pickr.min.css
├── TheFlasher
│ ├── packageManifest.json
│ ├── theflasher-child.groovy
│ └── theflasher-parent.groovy
├── devicewatchdog
│ ├── dw-child.groovy
│ ├── dw-parent.groovy
│ ├── dw-tiledriver.groovy
│ └── packageManifest.json
└── simplepush
│ ├── simplepush-Barebones.groovy
│ ├── simplepushNotifications-app.groovy
│ └── simplepushNotifications-driver.groovy
├── info.json
├── old-repo.json
├── repositories.json
└── resources
├── README.md
├── images
├── L360-URL.png
├── L360-URL2a.png
├── L360-XMLError2.png
├── blank.png
├── button-green.png
├── button-power-green.png
├── button-power-red.png
├── button-red.png
├── checkMarkGreen2.png
├── cogWithWrench.png
├── door-closed.png
├── door-open.png
├── image-Bryan.png
├── instructions.png
├── logo.png
├── options-green.png
├── options-red.png
├── pp.png
├── pp2.jpg
├── question-mark-icon-2.jpg
├── question-mark-icon.png
├── readme.txt
├── reports.jpg
├── shield-checkmark.png
└── shield-lock.png
└── media
├── doorclose1.mp3
├── dooropen1.mp3
├── fastpops1.mp3
├── pup1.mp3
└── readme.txt
/Bundles/AbacusCountingMachine.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/AbacusCountingMachine.zip
--------------------------------------------------------------------------------
/Bundles/AbacusTimeTraveler.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/AbacusTimeTraveler.zip
--------------------------------------------------------------------------------
/Bundles/AtHomeSimulator.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/AtHomeSimulator.zip
--------------------------------------------------------------------------------
/Bundles/AveragingPlus.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/AveragingPlus.zip
--------------------------------------------------------------------------------
/Bundles/BIControl.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/BIControl.zip
--------------------------------------------------------------------------------
/Bundles/ChromecastHelper.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/ChromecastHelper.zip
--------------------------------------------------------------------------------
/Bundles/DeviceCheckPlus.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/DeviceCheckPlus.zip
--------------------------------------------------------------------------------
/Bundles/DeviceTransformer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/DeviceTransformer.zip
--------------------------------------------------------------------------------
/Bundles/DeviceWatchdog.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/DeviceWatchdog.zip
--------------------------------------------------------------------------------
/Bundles/ErrorMonitor.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/ErrorMonitor.zip
--------------------------------------------------------------------------------
/Bundles/EventEngine.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/EventEngine.zip
--------------------------------------------------------------------------------
/Bundles/FollowMe.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/FollowMe.zip
--------------------------------------------------------------------------------
/Bundles/HomeTracker.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/HomeTracker.zip
--------------------------------------------------------------------------------
/Bundles/HubWatchdog.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/HubWatchdog.zip
--------------------------------------------------------------------------------
/Bundles/Life360Tracker.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/Life360Tracker.zip
--------------------------------------------------------------------------------
/Bundles/Life360withStates.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/Life360withStates.zip
--------------------------------------------------------------------------------
/Bundles/LifeEventCalendar.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/LifeEventCalendar.zip
--------------------------------------------------------------------------------
/Bundles/MLBGameDayLive.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/MLBGameDayLive.zip
--------------------------------------------------------------------------------
/Bundles/MyRadar.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/MyRadar.zip
--------------------------------------------------------------------------------
/Bundles/NHLGameDayLive.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/NHLGameDayLive.zip
--------------------------------------------------------------------------------
/Bundles/NormalStuffLibrary.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/NormalStuffLibrary.zip
--------------------------------------------------------------------------------
/Bundles/OneataTime.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/OneataTime.zip
--------------------------------------------------------------------------------
/Bundles/OwnTracker.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/OwnTracker.zip
--------------------------------------------------------------------------------
/Bundles/PackageExplorer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/PackageExplorer.zip
--------------------------------------------------------------------------------
/Bundles/PatternsPlus.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/PatternsPlus.zip
--------------------------------------------------------------------------------
/Bundles/PeriodicExpressions.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/PeriodicExpressions.zip
--------------------------------------------------------------------------------
/Bundles/PresencePlus.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/PresencePlus.zip
--------------------------------------------------------------------------------
/Bundles/README.md:
--------------------------------------------------------------------------------
1 | To Install a Bundle:
2 |
3 | In Github:
4 | - Click on the Bundle you want to install (Hubitat/Bundles/xxxx.zip)
5 | - Right-Click on the 'Raw' button and select 'Copy Link Address'
6 |
7 | Back in Hubitat:
8 | - Select 'Bundles' from the left-hand menu
9 | - Click 'Import Zip'
10 | - Select 'Import from URL'
11 | - Paste in the URL (copied from Github) and then click 'Import'
12 |
13 | REMEMBER - All bundles require 'NormalStuffLibrary.zip' to be installed first.
14 |
15 | Also remember, the files here are no longer supported or maintained by BPTWorld.
16 |
--------------------------------------------------------------------------------
/Bundles/RemoteWellnessCheck.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/RemoteWellnessCheck.zip
--------------------------------------------------------------------------------
/Bundles/RingKeypadSync.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/RingKeypadSync.zip
--------------------------------------------------------------------------------
/Bundles/SceneControl.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/SceneControl.zip
--------------------------------------------------------------------------------
/Bundles/SendIP2IR.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/SendIP2IR.zip
--------------------------------------------------------------------------------
/Bundles/SimpleDeviceTimer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/SimpleDeviceTimer.zip
--------------------------------------------------------------------------------
/Bundles/SimpleIrrigation.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/SimpleIrrigation.zip
--------------------------------------------------------------------------------
/Bundles/SimpleKitchenTimer.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/SimpleKitchenTimer.zip
--------------------------------------------------------------------------------
/Bundles/SimpleMultiTile.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/SimpleMultiTile.zip
--------------------------------------------------------------------------------
/Bundles/Snapshot.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/Snapshot.zip
--------------------------------------------------------------------------------
/Bundles/TheFlasher.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/TheFlasher.zip
--------------------------------------------------------------------------------
/Bundles/TileMaster.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/TileMaster.zip
--------------------------------------------------------------------------------
/Bundles/aDeviceTest.zip:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/Bundles/aDeviceTest.zip
--------------------------------------------------------------------------------
/Bundles/masterBundles.json:
--------------------------------------------------------------------------------
1 | {
2 | "masterBundles": [{
3 | "hubitatName": "BPTWorld",
4 | "location": "https://raw.githubusercontent.com/bptworld/Hubitat/master/Bundles/myBundles.json"
5 | }
6 | ]
7 | }
8 |
--------------------------------------------------------------------------------
/Docs/Adding a Tile to Dashboard.md:
--------------------------------------------------------------------------------
1 | # Adding a Tile to Dashboard
2 |
3 | Couple of things to check before trying to display data on a Tile:
4 | - Be sure to have the App setup and collecting data
5 | - Be sure to go into the Device and visually CHECK to make sure the Attribute actually contains the data you want to display on the tile
6 | - CLOSE all Dashboards at this point! This is a very important step.
7 |
8 | Adding The Tile to the Dashboard using Custom Attributes
9 | - Open up the Dashboard (Remember, they should have been Closed up to this point)
10 | - On the Dashboard you want to add the Custom Tile, click '+' in the upper right hand corner (Add A Tile)
11 | - Under 'Pick a Device', select the Device that contains the Custom Attribute you want to display
12 | - Under 'Pick a Template', select 'Attribute'
13 | - Under 'Pick an Attribute', Use the dropdown menu and select the Custom Attribute you want to display.
14 | 1. Remember, you can see the Custom Attributes in the Device you checked before starting to add the tile to the dashboard.
15 | 2. If you are not seeing any Custom Attributes, go back to the 'Couple of things to check' section and start again!
16 |
17 | That's it!
18 | You should now have an amazing new Custom Tile displayed on your Dashboard.
19 |
20 | Thanks,
21 | Bryan
22 | @BPTWorld
23 |
--------------------------------------------------------------------------------
/Docs/BPTWorld Apps and Data Collection.md:
--------------------------------------------------------------------------------
1 | # BPTWorld Apps and Data Collection
2 |
3 |
4 | My apps do NOT collect any data of any kind from any users.
5 |
6 | Each app does reach out to GitHub to retrieve the Header and Footer messages. The file, info.json, is located in the main directory. This file is openly available to anyone who would want to see what's in it. Simply click on it to view its contents.
7 |
8 | I do not collect any IP addresses, download statistics, app usage or any other information - I ca not tell you how many people use or download any of my apps/drivers or even access the json file. ABSOLUTELY NOTHING.
9 |
10 | Remember - Your data is your data and what you do with it is your business and nobody else's.
11 |
12 |
13 | Thanks,
14 | Bryan
15 | @BPTWorld
16 |
--------------------------------------------------------------------------------
/Docs/CODE_OF_CONDUCT.md:
--------------------------------------------------------------------------------
1 | # Contributor Covenant Code of Conduct
2 |
3 | ## Our Pledge
4 |
5 | In the interest of fostering an open and welcoming environment, we as
6 | contributors and maintainers pledge to making participation in our project and
7 | our community a harassment-free experience for everyone, regardless of age, body
8 | size, disability, ethnicity, sex characteristics, gender identity and expression,
9 | level of experience, education, socio-economic status, nationality, personal
10 | appearance, race, religion, or sexual identity and orientation.
11 |
12 | ## Our Standards
13 |
14 | Examples of behavior that contributes to creating a positive environment
15 | include:
16 |
17 | * Using welcoming and inclusive language
18 | * Being respectful of differing viewpoints and experiences
19 | * Gracefully accepting constructive criticism
20 | * Focusing on what is best for the community
21 | * Showing empathy towards other community members
22 |
23 | Examples of unacceptable behavior by participants include:
24 |
25 | * The use of sexualized language or imagery and unwelcome sexual attention or
26 | advances
27 | * Trolling, insulting/derogatory comments, and personal or political attacks
28 | * Public or private harassment
29 | * Publishing others' private information, such as a physical or electronic
30 | address, without explicit permission
31 | * Other conduct which could reasonably be considered inappropriate in a
32 | professional setting
33 |
34 | ## Our Responsibilities
35 |
36 | Project maintainers are responsible for clarifying the standards of acceptable
37 | behavior and are expected to take appropriate and fair corrective action in
38 | response to any instances of unacceptable behavior.
39 |
40 | Project maintainers have the right and responsibility to remove, edit, or
41 | reject comments, commits, code, wiki edits, issues, and other contributions
42 | that are not aligned to this Code of Conduct, or to ban temporarily or
43 | permanently any contributor for other behaviors that they deem inappropriate,
44 | threatening, offensive, or harmful.
45 |
46 | ## Scope
47 |
48 | This Code of Conduct applies both within project spaces and in public spaces
49 | when an individual is representing the project or its community. Examples of
50 | representing a project or community include using an official project e-mail
51 | address, posting via an official social media account, or acting as an appointed
52 | representative at an online or offline event. Representation of a project may be
53 | further defined and clarified by project maintainers.
54 |
55 | ## Enforcement
56 |
57 | Instances of abusive, harassing, or otherwise unacceptable behavior may be
58 | reported by contacting the project team at . All
59 | complaints will be reviewed and investigated and will result in a response that
60 | is deemed necessary and appropriate to the circumstances. The project team is
61 | obligated to maintain confidentiality with regard to the reporter of an incident.
62 | Further details of specific enforcement policies may be posted separately.
63 |
64 | Project maintainers who do not follow or enforce the Code of Conduct in good
65 | faith may face temporary or permanent repercussions as determined by other
66 | members of the project's leadership.
67 |
68 | ## Attribution
69 |
70 | This Code of Conduct is adapted from the [Contributor Covenant][homepage], version 1.4,
71 | available at https://www.contributor-covenant.org/version/1/4/code-of-conduct.html
72 |
73 | [homepage]: https://www.contributor-covenant.org
74 |
75 | For answers to common questions about this code of conduct, see
76 | https://www.contributor-covenant.org/faq
77 |
--------------------------------------------------------------------------------
/Docs/CONTRIBUTING.md:
--------------------------------------------------------------------------------
1 | # Pull Requests
2 | I encourage all to help make each app/driver better. But please remember that this is my code and if I don't understand what you are trying to add/change, it may not get added. After all, I am the one that will have to edit the code if someone has an issue.
3 |
--------------------------------------------------------------------------------
/Docs/How to Install a Custom App or Driver.md:
--------------------------------------------------------------------------------
1 | # How to Install an App or Driver from BPTWorld
2 | Design Usage:
3 | Basic instructions on installing a custom app or driver from GitHub.
4 |
5 | New Install: Copying the Code from GitHub
6 | * Locate the code that you want to install on GitHub
7 | * Copy the Parent code from GitHub using 1 of 2 methods
8 | 1. Click the 'Raw' button, then use 'ctrl + a' to select all of the code and then 'ctrl + c' to copy it
9 | 2. Click the 'Raw button, then copy the URL by double clicking the URL and then using 'ctrl + c' to copy it
10 | * In Hubitat, select ‘Apps Code’, ‘New App’ and paste in the new code, again there are two ways
11 | 1. Be sure your cursor is active on line 1 in the code, use 'ctrl + v' to paste in the raw code
12 | 2. Click the 'Import' button and paste in the URL copied in the previous step, then click 'Ok' on the warning message
13 | * Be sure to click 'Save' each time you add or replace the code
14 |
15 | If the App contains a Child App:
16 | * Follow the same procedure as above to create each child app available
17 |
18 | If the App also contains a Custom Driver:
19 | * Follow the same instructions as above to copy the code
20 | * In Hubitat, select ‘Drivers Code’, ‘New Driver’ and paste in the new code, using one of the methods previously described
21 | * Be sure to click 'Save' each time you add or replace the code
22 | * Do this for each Driver available on GitHub
23 |
24 | New Install: Loading the App in Hubitat
25 | * In Hubitat, go to 'Apps'
26 | * Click ‘Add User Apps’
27 | * Select ‘(the app you just created)’ ie. 'Follow Me'
28 | * Click 'Done', this will install the App and bring you back to the 'Apps' list
29 | * Now just scroll to the new App and click on it to open it
30 |
31 | That's it!
32 | Don't worry, it gets easier each time you do it!
33 |
--------------------------------------------------------------------------------
/Docs/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/Docs/README.md:
--------------------------------------------------------------------------------
1 | # Welcome to BPTWorld Apps and Drivers
2 |
3 | Hopefully the information found here will make your installs a little easier!
4 |
5 | Click on each file above to view the contents.
6 |
7 | Thanks,
8 | Bryan
9 | @BPTWorld
10 |
--------------------------------------------------------------------------------
/Docs/Things to Remember.md:
--------------------------------------------------------------------------------
1 | # A few things to Remember
2 | Just a few things to keep in mind when using BPTWorld Apps and Drivers
3 |
4 | - I am not a professional programmer, everything I do takes a lot of time and research (then MORE research)! Donations are never necessary but always appreciated. Donations to support development efforts are accepted via: Paypal at: https://paypal.me/bptworld
5 | - When asking for support, please post a log (NOT ONE LINE). I need to see what led up to the error. To post a log, screenshots work best but if you do copy and paste, please do not format the text! This makes it not readable and you will not get the help you need.
6 |
7 | Thank you.
8 |
--------------------------------------------------------------------------------
/Docs/packageManifest - What is it.md:
--------------------------------------------------------------------------------
1 | # packageManifest - What is it?
2 | Design Usage:
3 | For use with Hubitat Package Manager
4 |
5 | - Each app/driver will have a packageManifest.json which tells the Hubitat Package Manager all about the app.
6 | - Makes installs a breeze and most importantly, when there are updates!
7 | - There is no need for you to do anything with this file.
8 |
9 | Thanks
10 |
--------------------------------------------------------------------------------
/Drivers/Asthma Forecaster/AF-driver.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Asthma Forecaster
3 | *
4 | * Design Usage:
5 | * Retrieve data from asthmaforecast.com. For use with Hubitat dashboards.
6 | *
7 | * Copyright 2019 Bryan Turcotte (@bptworld)
8 | *
9 | * This App is free. If you like and use this app, please be sure to give a shout out on the Hubitat forums to let
10 | * people know that it exists! Thanks.
11 | *
12 | * Remember...I am not a programmer, everything I do takes a lot of time and research (then MORE research)!
13 | * Donations are never necessary but always appreciated. Donations to support development efforts are accepted via:
14 | *
15 | * Paypal at: https://paypal.me/bptworld
16 | *
17 | * Unless noted in the code, ALL code contained within this app is mine. You are free to change, ripout, copy, modify or
18 | * otherwise use the code in anyway you want. This is a hobby, I'm more than happy to share what I have learned and help
19 | * the community grow. Have FUN with it!
20 | *
21 | * ------------------------------------------------------------------------------------------------------------------------------
22 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23 | * in compliance with the License. You may obtain a copy of the License at:
24 | *
25 | * http://www.apache.org/licenses/LICENSE-2.0
26 | *
27 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
28 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
29 | * for the specific language governing permissions and limitations under the License.
30 | *
31 | * ------------------------------------------------------------------------------------------------------------------------------
32 | *
33 | * If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! - @BPTWorld
34 | *
35 | * App and Driver updates can be found at https://github.com/bptworld/Hubitat
36 | *
37 | * ------------------------------------------------------------------------------------------------------------------------------
38 | *
39 | * Changes:
40 | *
41 | * v2.0.4 - 01/03/2020 - Adjustment for AW2
42 | * v2.0.3 - 08/29/2019 - App Watchdog compatible
43 | * v2.0.2 - 05/12/2019 - Added Yesterday data by request
44 | * v2.0.1 - 04/16/2019 - Code cleanup, added importUrl
45 | * v2.0.0 - 04/10/2019 - Code cleanup. Added 'Tomorrow forecast', Updated display for Hubitat dashboard tile (@bptworld)
46 | * Based on ST 'Pollen Virtual Sensor' - Author: jschlackman (james@schlackman.org)
47 | *
48 | */
49 |
50 | def setVersion(){
51 | appName = "AsthmaForecasterDriver"
52 | version = "v2.0.4"
53 | dwInfo = "${appName}:${version}"
54 | sendEvent(name: "dwDriverInfo", value: dwInfo, displayed: true)
55 | }
56 |
57 | def updateVersion() {
58 | log.info "In updateVersion"
59 | setVersion()
60 | }
61 |
62 | metadata {
63 | definition (name: "Asthma Forecaster Driver", namespace: "BPTWorld", author: "Bryan Turcotte", importUrl: "https://raw.githubusercontent.com/bptworld/Hubitat/master/Drivers/Asthma%20Forecaster/AF-driver.groovy") {
64 | capability "Actuator"
65 | capability "Sensor"
66 | capability "Polling"
67 |
68 | attribute "indexToday", "number"
69 | attribute "categoryToday", "string"
70 | attribute "triggersToday", "string"
71 | attribute "indexTomorrow", "number"
72 | attribute "categoryTomorrow", "string"
73 | attribute "triggersTomorrow", "string"
74 | attribute "location", "string"
75 |
76 | attribute "yesterdayTile", "string"
77 | attribute "todayTile", "string"
78 | attribute "tomorrowTile", "string"
79 |
80 | attribute "dwDriverInfo", "string"
81 | command "updateVersion"
82 | }
83 |
84 | preferences {
85 | input name: "about", type: "paragraph", element: "paragraph", title: "Asthma Forecaster", description: "Retrieve data from asthmaforecast.com. For use with Hubitat dashboards."
86 | input name: "zipCode", type: "text", title: "Zip Code", required: true, defaultValue: "${location.zipCode}"
87 | input "fontSizeIndex", "text", title: "Font Size-Index", required: true, defaultValue: "70"
88 | input "fontSizeTriggers", "text", title: "Font Size-Triggers", required: true, defaultValue: "60"
89 | input "logEnable", "bool", title: "Enable logging", required: true, defaultValue: false
90 | }
91 | }
92 |
93 | def installed() {
94 | runEvery1Hour(poll)
95 | poll()
96 | }
97 |
98 | def updated() {
99 | poll()
100 | }
101 |
102 | def uninstalled() {
103 | unschedule()
104 | }
105 |
106 | def poll() {
107 | if(logEnable) log.debug "In poll..."
108 | def asthmaZip = null
109 |
110 | // Use hub zipcode if user has not defined their own
111 | if(zipCode) {
112 | asthmaZip = zipCode
113 | } else {
114 | asthmaZip = location.zipCode
115 | }
116 |
117 | if(logEnable) log.debug "Getting asthma data for ZIP: ${asthmaZip}"
118 |
119 | def params = [
120 | uri: 'https://www.asthmaforecast.com/api/forecast/current/asthma/',
121 | path: asthmaZip,
122 | headers: [Referer:'https://www.asthmaforecast.com']
123 | ]
124 |
125 | try {
126 | httpGet(params) {resp ->
127 | resp.data.Location.periods.each {period ->
128 | if(period.Type == 'Yesterday') {
129 | def catName = ""
130 | def indexNum = period.Index.toFloat()
131 |
132 | // Set the category according to index thresholds
133 | if (indexNum < 2.5) {catName = "Low"}
134 | else if (indexNum < 4.9) {catName = "Low-Medium"}
135 | else if (indexNum < 7.3) {catName = "Medium"}
136 | else if (indexNum < 9.7) {catName = "Medium-High"}
137 | else if (indexNum < 12) {catName = "High"}
138 | else {catName = "Unknown"}
139 |
140 | // Build the list of allergen triggers
141 | def triggersList = period.Triggers.inject([]) { result, entry ->
142 | result << "${entry.Name}"
143 | }.join(", ")
144 | state.indexYesterday = period.Index
145 | state.categoryYesterday = catName
146 | state.triggersYesterday = triggersList
147 |
148 | sendEvent(name: "indexYesterday", value: state.indexYesterday, displayed: true)
149 | sendEvent(name: "categoryYesterday", value: state.categoryYesterday, displayed: true)
150 | sendEvent(name: "triggersYesterday", value: state.triggersYesterday, displayed: true)
151 | }
152 |
153 | if(period.Type == 'Today') {
154 | def catName = ""
155 | def indexNum = period.Index.toFloat()
156 |
157 | // Set the category according to index thresholds
158 | if (indexNum < 2.5) {catName = "Low"}
159 | else if (indexNum < 4.9) {catName = "Low-Medium"}
160 | else if (indexNum < 7.3) {catName = "Medium"}
161 | else if (indexNum < 9.7) {catName = "Medium-High"}
162 | else if (indexNum < 12) {catName = "High"}
163 | else {catName = "Unknown"}
164 |
165 | // Build the list of allergen triggers
166 | def triggersList = period.Triggers.inject([]) { result, entry ->
167 | result << "${entry.Name}"
168 | }.join(", ")
169 | state.indexToday = period.Index
170 | state.categoryToday = catName
171 | state.triggersToday = triggersList
172 |
173 | sendEvent(name: "indexToday", value: state.indexToday, displayed: true)
174 | sendEvent(name: "categoryToday", value: state.categoryToday, displayed: true)
175 | sendEvent(name: "triggersToday", value: state.triggersToday, displayed: true)
176 | }
177 |
178 | if(period.Type == 'Tomorrow') {
179 | def catName = ""
180 | def indexNum = period.Index.toFloat()
181 |
182 | // Set the category according to index thresholds
183 | if (indexNum < 2.5) {catName = "Low"}
184 | else if (indexNum < 4.9) {catName = "Low-Medium"}
185 | else if (indexNum < 7.3) {catName = "Medium"}
186 | else if (indexNum < 9.7) {catName = "Medium-High"}
187 | else if (indexNum < 12) {catName = "High"}
188 | else {catName = "Unknown"}
189 |
190 | // Build the list of allergen triggers
191 | def triggersList = period.Triggers.inject([]) { result, entry ->
192 | result << "${entry.Name}"
193 | }.join(", ")
194 | state.indexTomorrow = period.Index
195 | state.categoryTomorrow = catName
196 | state.triggersTomorrow = triggersList
197 |
198 | sendEvent(name: "indexTomorrow", value: state.indexTomorrow, displayed: true)
199 | sendEvent(name: "categoryTomorrow", value: state.categoryTomorrow, displayed: true)
200 | sendEvent(name: "triggersTomorrow", value: state.triggersTomorrow, displayed: true)
201 | }
202 | state.location = resp.data.Location.DisplayLocation
203 | sendEvent(name: "location", value: state.location, displayed: true)
204 | }
205 | }
206 | }
207 | catch (SocketTimeoutException e) {
208 | if(logEnable) log.debug "Connection to asthmaforecast.com API timed out."
209 | sendEvent(name: "location", value: "Connection timed out while retrieving data from API", displayed: true)
210 | }
211 | catch (e) {
212 | if(logEnable) log.debug "Could not retrieve asthma data: $e"
213 | sendEvent(name: "location", value: "Could not retrieve data from API", displayed: true)
214 | }
215 | yesterdayTileMap()
216 | todayTileMap()
217 | tomorrowTileMap()
218 | }
219 |
220 | def configure() {
221 | poll()
222 | }
223 |
224 | def yesterdayTileMap() {
225 | if(logEnable) log.debug "In yesterdayTileMap..."
226 | state.appDataYesterday = "
"
292 | sendEvent(name: "tomorrowTile", value: state.appDataTomorrow, displayed: true)
293 | }
294 |
--------------------------------------------------------------------------------
/Drivers/Pollen Forecaster/README.md:
--------------------------------------------------------------------------------
1 | # Pollen Forecaster
2 | Design Usage:
3 | Retrieve data from pollen.com. For use with Hubitat dashboards.
4 | Please vist my Docs section for Install and other information!
5 |
6 | Thanks,
7 | Bryan
8 | @BPTWorld
9 |
--------------------------------------------------------------------------------
/Drivers/Send to Hub with CATT/README.md:
--------------------------------------------------------------------------------
1 | # Send to Hub with CATT Driver
2 | Design Usage:
3 | This driver is designed to send the HE dashboard (and MORE) to a Nest Hub using CATT.
4 | Please vist my Docs section for Install and other information!
5 |
6 | Thanks,
7 | Bryan
8 | @BPTWorld
9 |
--------------------------------------------------------------------------------
/Drivers/Send to Hub with CATT/STHWC-driver.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * **************** Send to Hub with CATT Driver ****************
3 | *
4 | * Design Usage:
5 | * This driver is designed to send the HE dashboard (and MORE) to a Nest Hub using CATT.
6 | *
7 | * Copyright 2019 Bryan Turcotte (@bptworld)
8 | *
9 | * This App is free. If you like and use this app, please be sure to give a shout out on the Hubitat forums to let
10 | * people know that it exists! Thanks.
11 | *
12 | * Remember...I am not a programmer, everything I do takes a lot of time and research (then MORE research)!
13 | * Donations are never necessary but always appreciated. Donations to support development efforts are accepted via:
14 | *
15 | * Paypal at: https://paypal.me/bptworld
16 | *
17 | * Unless noted in the code, ALL code contained within this app is mine. You are free to change, ripout, copy, modify or
18 | * otherwise use the code in anyway you want. This is a hobby, I'm more than happy to share what I have learned and help
19 | * the community grow. Have FUN with it!
20 | *
21 | ------------------------------------------------------------------------------------------------------------------------------
22 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
23 | * in compliance with the License. You may obtain a copy of the License at:
24 | *
25 | * http://www.apache.org/licenses/LICENSE-2.0
26 | *
27 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
28 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
29 | * for the specific language governing permissions and limitations under the License.
30 | *
31 | * ------------------------------------------------------------------------------------------------------------------------------
32 | *
33 | * If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! - @BPTWorld
34 | *
35 | * App and Driver updates can be found at https://github.com/bptworld/Hubitat
36 | *
37 | * ------------------------------------------------------------------------------------------------------------------------------
38 | *
39 | * Changes:
40 | *
41 | * v1.0.4 - 01/03/20 - Adjustment for AW2
42 | * V1.0.3 - 08/29/19 - App Watchdog compatible
43 | * V1.0.2 - 08/17/19 - Added more commands, fixed typo in volume
44 | * V1.0.1 - 08/16/19 - Name changed to 'Send to Hub with CATT', added a ton more commands, added some suggestions from @Ryan780, Thank you!
45 | * V1.0.0 - 08/15/19 - Initial release
46 | */
47 |
48 | def setVersion(){
49 | appName = "SendtoHubwithCATTDriver"
50 | version = "v1.0.4"
51 | dwInfo = "${appName}:${version}"
52 | sendEvent(name: "dwDriverInfo", value: dwInfo, displayed: true)
53 | }
54 |
55 | def updateVersion() {
56 | log.info "In updateVersion"
57 | setVersion()
58 | }
59 |
60 | metadata {
61 | definition (name: "Send to Hub with CATT Driver", namespace: "BPTWorld", author: "Bryan Turcotte", importUrl: "https://raw.githubusercontent.com/bptworld/Hubitat/master/Drivers/Send%20to%20Hub%20with%20CATT/STHWC-driver.groovy") {
62 | capability "Actuator"
63 | capability "Initialize"
64 | capability "Telnet"
65 | capability "Switch"
66 | capability "Speech Synthesis"
67 |
68 | attribute "telnet", "string"
69 | attribute "switch", "string"
70 |
71 | command "add", ["URI"]
72 | command "cast", ["URI"]
73 | command "castDashboard", ["URI"]
74 | command "clear"
75 | command "ffwd", ["Number"]
76 | command "info"
77 | command "pause"
78 | command "play"
79 | command "remove", ["URI"]
80 | command "restore"
81 | command "rewind", ["Number"]
82 | command "save"
83 | command "skip"
84 | command "status"
85 | command "stop"
86 | command "volume", ["Number"]
87 | command "volumedown"
88 | command "volumeup"
89 | command "write_config", ["Text"]
90 |
91 | attribute "dwDriverInfo", "string"
92 | command "updateVersion"
93 | }
94 |
95 | preferences() {
96 | section(){
97 | input "ipaddress", "text", required: true, title: "Catt Server IP Address", defaultValue: "0.0.0.0"
98 | input "userName", "text", required: true, title: "Catt Server Username"
99 | input "userPass", "password", required: true, title: "Catt Server Password"
100 | input "gDevice", "text", required: true, title: "Exact name of the Nest Hub to use"
101 | input "castWebsite", "text", required: true, title: "Default Website - Enter the exact webite URL including http://"
102 | input "logEnable", "bool", title: "Enable logging", required: true, defaultValue: false
103 | }
104 | }
105 | }
106 |
107 | def sendCommand(theCommand){
108 | state.lastmsg = theCommand
109 | if(logEnable) log.debug "Sending msg: ${theCommand}"
110 | return new hubitat.device.HubAction("${theCommand}\n", hubitat.device.Protocol.TELNET)
111 | }
112 |
113 | def resend(){
114 | if(logEnable) log.debug "RESEND!"
115 | sendCommand(state.lastmsg)
116 | }
117 |
118 | def initialize(){
119 | try {
120 | if(logEnable) log.debug "Opening telnet connection"
121 | sendEvent([name: "telnet", value: "Opening"])
122 | telnetConnect([terminalType: 'VT100'], "${ipaddress}", 23, "${userName}", "${userPass}")
123 | //give it a chance to start
124 | pauseExecution(1000)
125 | if(logEnable) log.debug "Telnet connection established"
126 | } catch(e) {
127 | if(logEnable) log.debug "Initialize Error: ${e.message}"
128 | }
129 | }
130 |
131 | def installed() {
132 | initialize()
133 | }
134 |
135 | def updated() {
136 | initialize()
137 | }
138 |
139 | def parse(String msg) {
140 | if(logEnable) log.debug "parse ${msg}"
141 | sendEvent([name: "telnet", value: "Connected"])
142 | if (msg == "busyIR,1:1,1"){
143 | return new hubitat.device.HubAction("${state.lastmsg}\n", hubitat.device.Protocol.TELNET)
144 | }
145 | }
146 |
147 | def telnetStatus(String status) {
148 | if(logEnable) log.debug "telnetStatus: ${status}"
149 | if (status == "receive error: Stream is closed" || status == "send error: Broken pipe (Write failed)") {
150 | log.error("Telnet connection dropped...PLEASE OPEN THIS DEVICE IN HE AND PRESS THE 'INITIALIZE' BUTTON")
151 | sendEvent([name: "telnet", value: "Disconnected"])
152 | telnetClose()
153 | runIn(60, initialize)
154 | }
155 | }
156 |
157 | def on(msg) {
158 | if(msg){
159 | theMsg = msg
160 | } else {
161 | theMsg = castWebsite
162 | }
163 | def msgAction = "catt -d '${gDevice}' cast_site '${theMsg}'"
164 | sendEvent(name: "switch", value: "on")
165 | sendCommand(msgAction)
166 | }
167 |
168 | def castDashboard(dashBoard){
169 | def msgAction = "catt -d '${gDevice}' cast_site '$dashBoard'"
170 | sendEvent(name: "switch", value: "on")
171 | sendCommand(msgAction)
172 | }
173 |
174 | def off() {
175 | def msgAction = "catt -d '${gDevice}' stop"
176 | sendEvent(name: "switch", value: "off")
177 | sendCommand(msgAction)
178 | }
179 |
180 | def add(msg) {
181 | def msgAction = "catt -d '${gDevice}' add '${msg}'"
182 | sendCommand(msgAction)
183 | }
184 |
185 | def cast(msg) {
186 | def msgAction = "catt -d '${gDevice}' cast '${msg}'"
187 | sendEvent(name: "switch", value: "on")
188 | sendCommand(msgAction)
189 | }
190 |
191 | def ffwd(msg) {
192 | def msgAction = "catt -d '${gDevice}' ffwd '${msg}'"
193 | sendCommand(msgAction)
194 | }
195 |
196 | def info() {
197 | def msgAction = "catt -d '${gDevice}' info"
198 | sendCommand(msgAction)
199 | }
200 |
201 | def pause() {
202 | def msgAction = "catt -d '${gDevice}' pause"
203 | sendCommand(msgAction)
204 | }
205 |
206 | def play() {
207 | def msgAction = "catt -d '${gDevice}' play"
208 | sendCommand(msgAction)
209 | }
210 |
211 | def clear() {
212 | def msgAction = "catt -d '${gDevice}' clear"
213 | sendCommand(msgAction)
214 | }
215 |
216 | def remove(msg) {
217 | def msgAction = "catt -d '${gDevice}' remove '${msg}'"
218 | sendCommand(msgAction)
219 | }
220 |
221 | def restore() {
222 | def msgAction = "catt -d '${gDevice}' restore"
223 | sendCommand(msgAction)
224 | }
225 |
226 | def rewind(msg) {
227 | def msgAction = "catt -d '${gDevice}' rewind '${msg}'"
228 | sendCommand(msgAction)
229 | }
230 |
231 | def save() {
232 | def msgAction = "catt -d '${gDevice}' save"
233 | sendCommand(msgAction)
234 | }
235 |
236 | def skip(msg) {
237 | def msgAction = "catt -d '${gDevice}' skip"
238 | sendCommand(msgAction)
239 | }
240 |
241 | def status() {
242 | def msgAction = "catt -d '${gDevice}' status"
243 | sendCommand(msgAction)
244 | }
245 |
246 | def stop() {
247 | def msgAction = "catt -d '${gDevice}' stop"
248 | sendCommand(msgAction)
249 | }
250 |
251 | def volume(msgVolume) {
252 | def msgAction = "catt -d '${gDevice}' volume ${msgVolume}"
253 | sendCommand(msgAction)
254 | }
255 |
256 | def volumeDown() {
257 | def msgAction = "catt -d '${gDevice}' volumedown 10"
258 | sendCommand(msgAction)
259 | }
260 |
261 | def volumeUp() {
262 | def msgAction = "catt -d '${gDevice}' volumeup 10"
263 | sendCommand(msgAction)
264 | }
265 |
266 | def write_config(setDevice) {
267 | def msgAction = "catt write_config ${setDevice}"
268 | sendCommand(msgAction)
269 | }
270 |
--------------------------------------------------------------------------------
/Drivers/gCalendar/README.md:
--------------------------------------------------------------------------------
1 | # gCalendar Driver
2 | Design Usage:
3 | Retrieves a Google Calendar to be used with HE Dashboards.
4 | Please vist my Docs section for Install and other information!
5 |
6 | Thanks,
7 | Bryan
8 | @BPTWorld
9 |
--------------------------------------------------------------------------------
/Drivers/gCalendar/gc-driver.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * **************** gCalendar Driver ****************
3 | *
4 | * Design Usage:
5 | * Retrieves a Google Calendar to be used with HE Dashboards.
6 | *
7 | * Copyright 2021 Bryan Turcotte (@bptworld)
8 | *
9 | * This App is free. If you like and use this app, please be sure to mention it on the Hubitat forums! Thanks.
10 | *
11 | * Remember...I am not a professional programmer, everything I do takes a lot of time and research (then MORE research)!
12 | * Donations are never necessary but always appreciated. Donations to support development efforts are accepted via:
13 | *
14 | * Paypal at: https://paypal.me/bptworld
15 | *
16 | * Unless noted in the code, ALL code contained within this app is mine. You are free to change, ripout, copy, modify or
17 | * otherwise use the code in anyway you want. This is a hobby, I'm more than happy to share what I have learned and help
18 | * the community grow. Have FUN with it!
19 | *
20 | * ------------------------------------------------------------------------------------------------------------------------------
21 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
22 | * in compliance with the License. You may obtain a copy of the License at:
23 | *
24 | * http://www.apache.org/licenses/LICENSE-2.0
25 | *
26 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
27 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
28 | * for the specific language governing permissions and limitations under the License.
29 | *
30 | * ------------------------------------------------------------------------------------------------------------------------------
31 | *
32 | * If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! - @BPTWorld
33 | *
34 | * App and Driver updates can be found at https://github.com/bptworld/Hubitat
35 | *
36 | * ------------------------------------------------------------------------------------------------------------------------------
37 | *
38 | * Original concept by @TechMedX
39 | *
40 | * Changes:
41 | *
42 | * 1.0.2 - 09/05/21 - Added urlSize Attribute, added additional language for 255 character limit.
43 | * 1.0.1 - 03/01/21 - Fixed a typo
44 | * 1.0.0 - 02/28/21 - Initial release
45 | */
46 |
47 | metadata {
48 | definition (name: "gCalendar Driver", namespace: "BPTWorld", author: "Bryan Turcotte", importUrl: "") {
49 | capability "Actuator"
50 | attribute "bpt-gCal", "text"
51 | attribute "lastUpdated", "text"
52 | attribute "urlSize", "text"
53 | command "refresh"
54 | }
55 | }
56 |
57 | preferences {
58 | input title:"Google Calendar Tile", description:"Note: Calendar will be updated once every hour or when 'Refresh' button is pushed.
Setup: 1) Go to your Google Calendar 2) For the calendar you want to display, click Settings 3) Scroll down until you see the Embed Code 4) Copy that code and paste it into URL field here 5) Press 'Save Preferences'", type:"paragraph", element:"paragraph"
59 | input "gCal", "text", title: "Google Calendar URL (URL must be less than 256 characters or it won't work. See urlSize in Attributes.)", required:true, submitOnChange:true
60 | if(gCal) {
61 | theCount = gCal.size()
62 | sendEvent(name: "urlSize", value: theCount)
63 | }
64 | input "logEnable", "bool", title: "Enable logging", required: true, defaultValue: false, submitOnChange: true
65 | input "logOffTime", "enum", title: "Logs Off Time", required:false, multiple:false, options: ["1 Hour", "2 Hours", "3 Hours", "4 Hours", "5 Hours", "Keep On"], defaultValue: "1 Hour"
66 | }
67 |
68 | def refresh() {
69 | if(logEnable) log.debug "In refresh"
70 | if(gCal) {
71 | if(gCal.contains("", "")
72 | if(logEnable) log.debug "In refresh - gCal URl: ${gCal}"
73 | lu = new Date()
74 | theCal = ""
75 | sendEvent(name: "bpt-gCal", value: theCal)
76 | sendEvent(name: "lastUpdated", value: lu)
77 | } else {
78 | log.info "gCalendar Driver - Be sure to fill in the Google Calendar URL and click Save Preferences"
79 | }
80 | }
81 |
82 | def updated() {
83 | installed()
84 | }
85 |
86 | def installed() {
87 | unschedule()
88 | if(logEnable && logOffTime == "1 Hour") runIn(3600, logsOff, [overwrite:false])
89 | if(logEnable && logOffTime == "2 Hours") runIn(7200, logsOff, [overwrite:false])
90 | if(logEnable && logOffTime == "3 Hours") runIn(10800, logsOff, [overwrite:false])
91 | if(logEnable && logOffTime == "4 Hours") runIn(14400, logsOff, [overwrite:false])
92 | if(logEnable && logOffTime == "5 Hours") runIn(18000, logsOff, [overwrite:false])
93 | if(logEnagle && logOffTime == "Keep On") unschedule(logsOff)
94 | refresh()
95 | schedule("0 0 * ? * * *", refresh)
96 | }
97 |
98 | def logsOff() {
99 | log.info "${app.label} - Debug logging auto disabled"
100 | app.updateSetting("logEnable",[value:"false",type:"bool"])
101 | }
102 |
--------------------------------------------------------------------------------
/Drivers/gCalendar/packageManifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageName": "gCalendar Driver",
3 | "minimumHEVersion": "2.1.9",
4 | "author": "BPTWorld",
5 | "dateReleased": "2021-02-28",
6 | "documentationLink": "https://github.com/bptworld/Hubitat",
7 | "communityLink": "",
8 | "releaseNotes": "All release notes can be found within the Community Link and within the App/Driver code.",
9 | "apps" : [
10 | ],
11 | "drivers" : [
12 | {
13 | "id": "faf9cf98-d7d3-46fc-ba8a-55756ee7e1d1",
14 | "name": "gCalendar Driver",
15 | "namespace": "BPTWorld",
16 | "location": "https://raw.githubusercontent.com/bptworld/Hubitat/master/Drivers/gCalendar/gc-driver.groovy",
17 | "required": true,
18 | "version": "1.0.2"
19 | }
20 | ]
21 | }
22 |
--------------------------------------------------------------------------------
/LICENSE:
--------------------------------------------------------------------------------
1 | Apache License
2 | Version 2.0, January 2004
3 | http://www.apache.org/licenses/
4 |
5 | TERMS AND CONDITIONS FOR USE, REPRODUCTION, AND DISTRIBUTION
6 |
7 | 1. Definitions.
8 |
9 | "License" shall mean the terms and conditions for use, reproduction,
10 | and distribution as defined by Sections 1 through 9 of this document.
11 |
12 | "Licensor" shall mean the copyright owner or entity authorized by
13 | the copyright owner that is granting the License.
14 |
15 | "Legal Entity" shall mean the union of the acting entity and all
16 | other entities that control, are controlled by, or are under common
17 | control with that entity. For the purposes of this definition,
18 | "control" means (i) the power, direct or indirect, to cause the
19 | direction or management of such entity, whether by contract or
20 | otherwise, or (ii) ownership of fifty percent (50%) or more of the
21 | outstanding shares, or (iii) beneficial ownership of such entity.
22 |
23 | "You" (or "Your") shall mean an individual or Legal Entity
24 | exercising permissions granted by this License.
25 |
26 | "Source" form shall mean the preferred form for making modifications,
27 | including but not limited to software source code, documentation
28 | source, and configuration files.
29 |
30 | "Object" form shall mean any form resulting from mechanical
31 | transformation or translation of a Source form, including but
32 | not limited to compiled object code, generated documentation,
33 | and conversions to other media types.
34 |
35 | "Work" shall mean the work of authorship, whether in Source or
36 | Object form, made available under the License, as indicated by a
37 | copyright notice that is included in or attached to the work
38 | (an example is provided in the Appendix below).
39 |
40 | "Derivative Works" shall mean any work, whether in Source or Object
41 | form, that is based on (or derived from) the Work and for which the
42 | editorial revisions, annotations, elaborations, or other modifications
43 | represent, as a whole, an original work of authorship. For the purposes
44 | of this License, Derivative Works shall not include works that remain
45 | separable from, or merely link (or bind by name) to the interfaces of,
46 | the Work and Derivative Works thereof.
47 |
48 | "Contribution" shall mean any work of authorship, including
49 | the original version of the Work and any modifications or additions
50 | to that Work or Derivative Works thereof, that is intentionally
51 | submitted to Licensor for inclusion in the Work by the copyright owner
52 | or by an individual or Legal Entity authorized to submit on behalf of
53 | the copyright owner. For the purposes of this definition, "submitted"
54 | means any form of electronic, verbal, or written communication sent
55 | to the Licensor or its representatives, including but not limited to
56 | communication on electronic mailing lists, source code control systems,
57 | and issue tracking systems that are managed by, or on behalf of, the
58 | Licensor for the purpose of discussing and improving the Work, but
59 | excluding communication that is conspicuously marked or otherwise
60 | designated in writing by the copyright owner as "Not a Contribution."
61 |
62 | "Contributor" shall mean Licensor and any individual or Legal Entity
63 | on behalf of whom a Contribution has been received by Licensor and
64 | subsequently incorporated within the Work.
65 |
66 | 2. Grant of Copyright License. Subject to the terms and conditions of
67 | this License, each Contributor hereby grants to You a perpetual,
68 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
69 | copyright license to reproduce, prepare Derivative Works of,
70 | publicly display, publicly perform, sublicense, and distribute the
71 | Work and such Derivative Works in Source or Object form.
72 |
73 | 3. Grant of Patent License. Subject to the terms and conditions of
74 | this License, each Contributor hereby grants to You a perpetual,
75 | worldwide, non-exclusive, no-charge, royalty-free, irrevocable
76 | (except as stated in this section) patent license to make, have made,
77 | use, offer to sell, sell, import, and otherwise transfer the Work,
78 | where such license applies only to those patent claims licensable
79 | by such Contributor that are necessarily infringed by their
80 | Contribution(s) alone or by combination of their Contribution(s)
81 | with the Work to which such Contribution(s) was submitted. If You
82 | institute patent litigation against any entity (including a
83 | cross-claim or counterclaim in a lawsuit) alleging that the Work
84 | or a Contribution incorporated within the Work constitutes direct
85 | or contributory patent infringement, then any patent licenses
86 | granted to You under this License for that Work shall terminate
87 | as of the date such litigation is filed.
88 |
89 | 4. Redistribution. You may reproduce and distribute copies of the
90 | Work or Derivative Works thereof in any medium, with or without
91 | modifications, and in Source or Object form, provided that You
92 | meet the following conditions:
93 |
94 | (a) You must give any other recipients of the Work or
95 | Derivative Works a copy of this License; and
96 |
97 | (b) You must cause any modified files to carry prominent notices
98 | stating that You changed the files; and
99 |
100 | (c) You must retain, in the Source form of any Derivative Works
101 | that You distribute, all copyright, patent, trademark, and
102 | attribution notices from the Source form of the Work,
103 | excluding those notices that do not pertain to any part of
104 | the Derivative Works; and
105 |
106 | (d) If the Work includes a "NOTICE" text file as part of its
107 | distribution, then any Derivative Works that You distribute must
108 | include a readable copy of the attribution notices contained
109 | within such NOTICE file, excluding those notices that do not
110 | pertain to any part of the Derivative Works, in at least one
111 | of the following places: within a NOTICE text file distributed
112 | as part of the Derivative Works; within the Source form or
113 | documentation, if provided along with the Derivative Works; or,
114 | within a display generated by the Derivative Works, if and
115 | wherever such third-party notices normally appear. The contents
116 | of the NOTICE file are for informational purposes only and
117 | do not modify the License. You may add Your own attribution
118 | notices within Derivative Works that You distribute, alongside
119 | or as an addendum to the NOTICE text from the Work, provided
120 | that such additional attribution notices cannot be construed
121 | as modifying the License.
122 |
123 | You may add Your own copyright statement to Your modifications and
124 | may provide additional or different license terms and conditions
125 | for use, reproduction, or distribution of Your modifications, or
126 | for any such Derivative Works as a whole, provided Your use,
127 | reproduction, and distribution of the Work otherwise complies with
128 | the conditions stated in this License.
129 |
130 | 5. Submission of Contributions. Unless You explicitly state otherwise,
131 | any Contribution intentionally submitted for inclusion in the Work
132 | by You to the Licensor shall be under the terms and conditions of
133 | this License, without any additional terms or conditions.
134 | Notwithstanding the above, nothing herein shall supersede or modify
135 | the terms of any separate license agreement you may have executed
136 | with Licensor regarding such Contributions.
137 |
138 | 6. Trademarks. This License does not grant permission to use the trade
139 | names, trademarks, service marks, or product names of the Licensor,
140 | except as required for reasonable and customary use in describing the
141 | origin of the Work and reproducing the content of the NOTICE file.
142 |
143 | 7. Disclaimer of Warranty. Unless required by applicable law or
144 | agreed to in writing, Licensor provides the Work (and each
145 | Contributor provides its Contributions) on an "AS IS" BASIS,
146 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or
147 | implied, including, without limitation, any warranties or conditions
148 | of TITLE, NON-INFRINGEMENT, MERCHANTABILITY, or FITNESS FOR A
149 | PARTICULAR PURPOSE. You are solely responsible for determining the
150 | appropriateness of using or redistributing the Work and assume any
151 | risks associated with Your exercise of permissions under this License.
152 |
153 | 8. Limitation of Liability. In no event and under no legal theory,
154 | whether in tort (including negligence), contract, or otherwise,
155 | unless required by applicable law (such as deliberate and grossly
156 | negligent acts) or agreed to in writing, shall any Contributor be
157 | liable to You for damages, including any direct, indirect, special,
158 | incidental, or consequential damages of any character arising as a
159 | result of this License or out of the use or inability to use the
160 | Work (including but not limited to damages for loss of goodwill,
161 | work stoppage, computer failure or malfunction, or any and all
162 | other commercial damages or losses), even if such Contributor
163 | has been advised of the possibility of such damages.
164 |
165 | 9. Accepting Warranty or Additional Liability. While redistributing
166 | the Work or Derivative Works thereof, You may choose to offer,
167 | and charge a fee for, acceptance of support, warranty, indemnity,
168 | or other liability obligations and/or rights consistent with this
169 | License. However, in accepting such obligations, You may act only
170 | on Your own behalf and on Your sole responsibility, not on behalf
171 | of any other Contributor, and only if You agree to indemnify,
172 | defend, and hold each Contributor harmless for any liability
173 | incurred by, or claims asserted against, such Contributor by reason
174 | of your accepting any such warranty or additional liability.
175 |
176 | END OF TERMS AND CONDITIONS
177 |
178 | APPENDIX: How to apply the Apache License to your work.
179 |
180 | To apply the Apache License to your work, attach the following
181 | boilerplate notice, with the fields enclosed by brackets "[]"
182 | replaced with your own identifying information. (Don't include
183 | the brackets!) The text should be enclosed in the appropriate
184 | comment syntax for the file format. We also recommend that a
185 | file or class name and description of purpose be included on the
186 | same "printed page" as the copyright notice for easier
187 | identification within third-party archives.
188 |
189 | Copyright [yyyy] [name of copyright owner]
190 |
191 | Licensed under the Apache License, Version 2.0 (the "License");
192 | you may not use this file except in compliance with the License.
193 | You may obtain a copy of the License at
194 |
195 | http://www.apache.org/licenses/LICENSE-2.0
196 |
197 | Unless required by applicable law or agreed to in writing, software
198 | distributed under the License is distributed on an "AS IS" BASIS,
199 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
200 | See the License for the specific language governing permissions and
201 | limitations under the License.
202 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 | *** BPTWorld apps are no longer being developed or maintained. Thanks ***
2 |
3 | # Apps/Drivers for Hubitat Elevation
4 | Apps for use with the Hubitat Elevation Hub.
5 | Offiical Website: www.hubitat.com
6 | Official Forum: https://community.hubitat.com/
7 |
8 | Donations to support development efforts are accepted via:
9 | Paypal: https://paypal.me/bptworld Venmo: Bryan-Turcotte-MA (8477) Remember...I am not a professional programmer, everything I do takes a lot of time and research! Donations for this time and effort are always greatly appreciated. I 'Thank You' for your support. Be sure to include your forum username if you would like a personal thank you, which is always nice!
10 |
11 | * Note: Acceptance of donation in no way guarentees support or updates. All apps/drivers are provided 'as is'. While I do my best to maintain/update each app/driver, priorities do change and any app/driver could be depreciated at any time. Thank you for your understanding.
12 |
13 |
--------------------------------------------------------------------------------
/_config.yml:
--------------------------------------------------------------------------------
1 | theme: jekyll-theme-slate
--------------------------------------------------------------------------------
/apps/FlowEngine/drawflow-css.min.css:
--------------------------------------------------------------------------------
1 | .drawflow,.drawflow .parent-node{position:relative}.parent-drawflow{display:flex;overflow:hidden;touch-action:none;outline:0}.drawflow{width:100%;height:100%;user-select:none}.drawflow .drawflow-node{display:flex;align-items:center;position:absolute;background:#0ff;width:160px;min-height:40px;border-radius:4px;border:2px solid #000;color:#000;z-index:2;padding:15px}.drawflow .drawflow-node.selected{background:red}.drawflow .drawflow-node:hover{cursor:move}.drawflow .drawflow-node .inputs,.drawflow .drawflow-node .outputs{width:0}.drawflow .drawflow-node .drawflow_content_node{width:100%;display:block}.drawflow .drawflow-node .input,.drawflow .drawflow-node .output{position:relative;width:20px;height:20px;background:#fff;border-radius:50%;border:2px solid #000;cursor:crosshair;z-index:1;margin-bottom:5px}.drawflow .drawflow-node .input{left:-27px;top:2px;background:#ff0}.drawflow .drawflow-node .output{right:-3px;top:2px}.drawflow svg{z-index:0;position:absolute;overflow:visible!important}.drawflow .connection{position:absolute;pointer-events:none}.drawflow .connection .main-path{fill:none;stroke-width:5px;stroke:#4682b4;pointer-events:all}.drawflow .connection .main-path:hover{stroke:#1266ab;cursor:pointer}.drawflow .connection .main-path.selected{stroke:#43b993}.drawflow .connection .point{cursor:move;stroke:#000;stroke-width:2;fill:#fff;pointer-events:all}.drawflow .connection .point.selected,.drawflow .connection .point:hover{fill:#1266ab}.drawflow .main-path{fill:none;stroke-width:5px;stroke:#4682b4}.drawflow-delete{position:absolute;display:block;width:30px;height:30px;background:#000;color:#fff;z-index:4;border:2px solid #fff;line-height:30px;font-weight:700;text-align:center;border-radius:50%;font-family:monospace;cursor:pointer}.drawflow>.drawflow-delete{margin-left:-15px;margin-top:15px}.parent-node .drawflow-delete{right:-15px;top:-15px}
--------------------------------------------------------------------------------
/apps/FlowEngine/drawflow-extra.css:
--------------------------------------------------------------------------------
1 | button { background: #b3e6b3; border: 1px solid #5cb85c; margin:4px; }
2 | button:active { background: #2d862d; color: white; }
3 | html, body { margin:0; padding:0; height:100%; font-family:sans-serif; }
4 | #controls { padding:10px; background:#eee; display:flex; flex-wrap:wrap; gap:10px; }
5 | #main { display:flex; height:calc(100vh - 100px); }
6 | #drawflow {
7 | width:70%;
8 | background-color: #f4f4f4;
9 | background-image:
10 | linear-gradient(to right, #ddd 1px, transparent 1px),
11 | linear-gradient(to bottom, #ddd 1px, transparent 1px);
12 | background-size: 24px 24px;
13 | }
14 | #editor { width:30%; padding:10px; background:#fff; overflow:auto; border-left:1px solid #ccc; }
15 | #nodeEditor { display:flex; flex-direction:column; gap:10px; }
16 | input, button, select { padding:6px; font-size:14px; border-radius:4px; border:1px solid #ccc; }
17 | .log-info { color: #2d862d; }
18 | .log-error { color: #c0392b; }
19 | .drawflow-node .outputs .output { width: 14px; height: 14px; }
20 | .drawflow-node .outputs .output[data-name="false"] { background: #e67e22; }
21 | .drawflow-node .outputs .output[data-name="true"] { background: #27ae60; }
22 | #wsLogBox {
23 | resize: vertical;
24 | min-height: 50px;
25 | max-height: 300px;
26 | height: 120px;
27 | }
28 |
--------------------------------------------------------------------------------
/apps/FlowEngine/favicon.ico:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/bptworld/Hubitat/0ef6af971b7260ea936eb4dca21ac131efc82e46/apps/FlowEngine/favicon.ico
--------------------------------------------------------------------------------
/apps/FlowEngine/flowengine-parent.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * **************** Flow Engine Parent ****************
3 | * Design Usage:
4 | * Feel the Flow
5 | *
6 | * Copyright 2025 Bryan Turcotte (@bptworld)
7 | *
8 | * This App is free. If you like and use this app, please be sure to mention it on the Hubitat forums! Thanks.
9 | *
10 | * Remember...I am not a professional programmer, everything I do takes a lot of time and research!
11 | * Donations are never necessary but always appreciated. Donations to support development efforts are accepted via:
12 | *
13 | * Paypal at: https://paypal.me/bptworld
14 | *-------------------------------------------------------------------------------------------------------------------
15 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
16 | * in compliance with the License. You may obtain a copy of the License at:
17 | *
18 | * http://www.apache.org/licenses/LICENSE-2.0
19 | *
20 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
21 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
22 | * for the specific language governing permissions and limitations under the License.
23 | * ------------------------------------------------------------------------------------------------------------------------------
24 | * If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! - @BPTWorld
25 | * App and Driver updates can be found at https://github.com/bptworld/Hubitat
26 | * ------------------------------------------------------------------------------------------------------------------------------
27 | * Changes are listed in child app
28 | */
29 |
30 | import groovy.json.JsonOutput
31 | import groovy.json.JsonSlurper
32 | import groovy.transform.Field
33 |
34 | definition(
35 | name:"Flow Engine",
36 | namespace: "BPTWorld",
37 | author: "Bryan Turcotte",
38 | description: "Feel the Flow",
39 | category: "Convenience",
40 | iconUrl: "",
41 | iconX2Url: "",
42 | iconX3Url: "",
43 | importUrl: "",
44 | oauth: true
45 | )
46 |
47 | preferences {
48 | page name: "mainPage", title: "", install: true, uninstall: true
49 | }
50 |
51 | def mainPage() {
52 | dynamicPage(name: "mainPage") {
53 | installCheck()
54 | if(state.appInstalled == 'COMPLETE'){
55 | display()
56 |
57 | section(getFormat("header-green", " Child Apps")) {
58 | app(name: "anyOpenApp", appName: "Flow Engine Child", namespace: "BPTWorld", title: "Add a new 'Flow Engine' child", multiple: true)
59 | }
60 |
61 | section(getFormat("header-green", " Flow Engine Editor Infomation")) {
62 | paragraph "This app is used to receive flow data from your Flow Engine Editor."
63 | paragraph "Copy and paste this info into the Flow Engine Editor - appId: ${state.appId} - token: ${state.token}"
64 | paragraph ""
65 | paragraph "
webhook request: $request", status: 200)
107 | }
108 |
109 | def sendAsynchttpPost() {
110 | def extUri = fullApiServerUrl().replaceAll("null","webhook?access_token=${state.accessToken}")
111 | def postParams = [
112 | uri: "https://simplepu.sh",
113 | requestContentType: 'application/json',
114 | contentType: 'application/json',
115 | body : ["key": simpleKey, "title": "Hubitat Notification", "msg": simpleMsg, "event": eventType, "attachments": attach, "actions": [["name": "yes", "url": "${extUri}&action=yes"],["name": "no", "url": "${extUri}&action=no"]]]
116 | ]
117 | if(logEnable) log.debug "In sendAsynchttpPost - ${postParams}"
118 | asynchttpPost('myCallbackMethod', postParams, [dataitem1: "datavalue1"])
119 | }
120 |
121 | def myCallbackMethod(response, data) {
122 | if(data["dataitem1"] == "datavalue1")
123 | if(logEnable) log.debug "Data was passed successfully"
124 | if(logEnable) log.debug "status of post call is: ${response.status}"
125 | }
126 |
127 | def appButtonHandler(buttonPressed) {
128 | if(logEnable) log.debug "In appButtonHandler (${state.version}) - Button Pressed: ${buttonPressed}"
129 | if(buttonPressed == "sendMsg") {
130 | if(logEnable) log.debug "In appButtonHandler - Working on: ${buttonPressed}"
131 | sendAsynchttpPost()}
132 | }
133 |
--------------------------------------------------------------------------------
/apps/simplepush/simplepushNotifications-driver.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * **************** Simplepush Notification Driver ****************
3 | *
4 | * Design Usage:
5 | * This driver works with the Simplepush Notification app.
6 | *
7 | * Copyright 2024 Bryan Turcotte (@bptworld)
8 | *
9 | * This App is free. If you like and use this app, please be sure to mention it on the Hubitat forums! Thanks.
10 | *
11 | * Remember...I am not a programmer, everything I do takes a lot of time and research (then MORE research)!
12 | * Donations are never necessary but always appreciated. Donations to support development efforts are accepted via:
13 | *
14 | * Paypal at: https://paypal.me/bptworld
15 | *
16 | * Unless noted in the code, ALL code contained within this app is mine. You are free to change, ripout, copy, modify or
17 | * otherwise use the code in anyway you want. This is a hobby, I'm more than happy to share what I have learned and help
18 | * the community grow. Have FUN with it!
19 | *
20 | * ------------------------------------------------------------------------------------------------------------------------------
21 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
22 | * in compliance with the License. You may obtain a copy of the License at:
23 | *
24 | * http://www.apache.org/licenses/LICENSE-2.0
25 | *
26 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
27 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
28 | * for the specific language governing permissions and limitations under the License.
29 | *
30 | * ------------------------------------------------------------------------------------------------------------------------------
31 | *
32 | * If modifying this project, please keep the above header intact and add your comments/credits below - Thank you! - @BPTWorld
33 | * App and Driver updates can be found at https://github.com/bptworld/Hubitat
34 | *
35 | * ------------------------------------------------------------------------------------------------------------------------------
36 | *
37 | * Changes:
38 | * Changes are listed in the app.
39 | */
40 |
41 | metadata {
42 | definition (name: "Simplepush Notification Driver", namespace: "BPTWorld", author: "Bryan Turcotte", importUrl: "") {
43 | capability "Notification"
44 | capability "Actuator"
45 | capability "Switch"
46 |
47 | command "sendSimplepush", [[name:"title", type:"STRING", description: "Optional Title"],
48 | [name:"theMessage", type:"STRING", description:"Message to send"],
49 | [name:"actions", type:"STRING", description: "Optional - 'option1-option2' - Seperated by a -"],
50 | [name:"theEvent", type:"STRING", description: "Optional Event"]]
51 |
52 | command "sendSimplepushwebCore",[[name:"title", type:"STRING", description: "Optional Title"],
53 | [name:"theMessage", type:"STRING", description:"Message to send"],
54 | [name:"WebCoreURL", type:"STRING", description:"WebCoRE External URL"],
55 | [name:"theEvent", type:"STRING", description: "Optional Event"]]
56 |
57 | attribute "lastMessage", "string"
58 | attribute "lastAction", "string"
59 | attribute "sentAt", "string"
60 | attribute "switch", "string"
61 | }
62 | preferences() {
63 | section(){
64 | input name: "about", type: "paragraph", element: "paragraph", title: "Simplepush Notification", description: "This device was created by Simplepush Notification
Actions: option1-option2 ie. on-off, off-on, yes-no, light-dark, whatever you want!
Selecting Option1 will turn this device ON, Option2 with turn this device OFF."
65 |
66 | input name: "about", type: "paragraph", element: "paragraph", title: "Use with RM", description: "In the Message box use syntax 'Title:Message:Actions:Event'.
ie. 'My Title:This is a Test:yes-no:silent'.
If a field isn't needed use 'na', do not leave a field blank or missing."
67 |
68 | input name: "simpleKey", type: "text", title: "Simplepush Key", description: "Each 'User/Phone' will have one Key that can be used across as many virtual devices as you need."
69 | input name: "simpleTitle", type: "text", title: "Push Title", description: "Default Title to be used if no custom title is specified."
70 |
71 | input("logEnable", "bool", title: "Enable logging", required: false, defaultValue: false)
72 | }
73 | }
74 | }
75 |
76 | def sendSimplepush(title=null, theMessage, actions=null, theEvent=null) {
77 | if(simpleKey) {
78 | if(logEnable) log.info "In sendSimplepush - ${title} - ${theMessage} - Actions: ${actions} - Event: ${theEvent}"
79 | def data = new Date()
80 | sendEvent(name: "sentAt", value: data, displayed: true)
81 | sendEvent(name: "lastMessage", value: theMessage, displayed: true)
82 | if(title == "na" || title == null) title = simpleTitle ?: ""
83 | theDevice = device.id
84 | parent.sendAsynchttpPost(theDevice, simpleKey, title, theMessage, actions, theEvent)
85 | } else {
86 | log.warn "Simplepush Driver - Be sure to enter your Simplepush Key in to the driver."
87 | }
88 | }
89 |
90 | def sendSimplepushwebCore(title=null, theMessage, webCoreURL=null,theEvent=null) {
91 | if(simpleKey) {
92 | if(webCoreURL){
93 | if(logEnable) log.info "In sendSimplepushwebCore - ${title} - ${theMessage} - Event: ${theEvent} - WebCoRE ${webCoreURL}"
94 | def data = new Date()
95 | sendEvent(name: "sentAt", value: data, displayed: true)
96 | sendEvent(name: "lastMessage", value: theMessage, displayed: true)
97 | if(title == "na" || title == null) title = simpleTitle ?: ""
98 | theDevice = device.id
99 | parent.sendAsynchttpPostwebCore(theDevice, simpleKey, title, theMessage, webCoreURL, theEvent)
100 | }
101 | else{
102 | log.warn "Simplepush Driver - Be sure to enter your WebCoRE External Piston URL when using the Send SimplePush WebCore Command."
103 | }
104 | }
105 | else {
106 | log.warn "Simplepush Driver - Be sure to enter your Simplepush Key in to the driver."
107 | }
108 | }
109 |
110 | def actionHandler(theAction) {
111 | if(logEnable) log.info "In actionHandler - ${theAction}"
112 | if(theAction == "act0") { on() }
113 | if(theAction == "act1") { off() }
114 | if(theAction == "act2") { }
115 | if(theAction == "act3") { }
116 | if(theAction == "act4") { }
117 |
118 | sendEvent(name: "lastAction", value: theAction, displayed: true)
119 | }
120 |
121 | def on() {
122 | sendEvent(name: "switch", value: "on", displayed: true)
123 | }
124 |
125 | def off() {
126 | sendEvent(name: "switch", value: "off", displayed: true)
127 | }
128 |
129 | def deviceNotification(data) {
130 | try{
131 | if(logEnable) log.info "In deviceNotification - ${data}"
132 | theData = data.split(":")
133 | sendSimplepush(theData[0], theData[1], theData[2], theData[3])
134 | } catch(e) {
135 | log.info "Simplepush - Please check your notification syntax. Must be 'Title:Your Message:Actions:Event'"
136 | log.error(getExceptionMessageWithLine(e))
137 | }
138 | }
139 |
--------------------------------------------------------------------------------
/info.json:
--------------------------------------------------------------------------------
1 | {
2 | "headerMessage": "