├── .gitignore
├── images
├── NewDriverButton.png
├── InstalledAppsList.png
├── NewDriverExample.png
├── RokuTVDeviceInfo.png
├── RokuTVPreferences.png
├── RokuTVCurrentState.png
├── RokuTVStateVariables.png
├── AddVirtualDeviceButton.png
└── HubitatMenuDriversCode.png
├── .groovylintrc.json
├── APACHE-LICENSE.md
├── tesla
├── LICENSE.md
├── README.md
├── device
│ └── tesla.groovy
└── app
│ └── tesla-connect.groovy
├── devices
├── packageManifest.json
└── timer-device.groovy
├── LICENSE.md
├── MIT-LICENSE.md
├── hue
├── LICENSE.md
├── device
│ ├── advanced-hue-light-sensor.groovy
│ ├── advanced-hue-temperature-sensor.groovy
│ ├── advanced-hue-tap-sensor.groovy
│ ├── advanced-hue-motion-sensor.groovy
│ ├── advanced-hue-dimmer-sensor.groovy
│ ├── advanced-hue-runlesswires-sensor.groovy
│ └── advanced-hue-group.groovy
├── README.md
├── packageManifest.json
└── libs
│ └── HueFunctions.groovy
├── roku
├── LICENSE.md
├── packageManifest.json
├── README.md
└── app
│ └── roku-connect.groovy
├── revproxy
├── LICENSE.md
├── packageManifest.json
├── app
│ ├── simple-reverse-proxy-service.groovy
│ └── simple-proxy-provider.groovy
└── README.md
├── iopool
├── packageManifest.json
├── README.md
├── app
│ └── iopool-connect.groovy
└── device
│ └── eco-sensor
├── repository.json
└── README.md
/.gitignore:
--------------------------------------------------------------------------------
1 |
2 | hue/rest/hueTest.rest
3 | *.rest
4 |
--------------------------------------------------------------------------------
/images/NewDriverButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/NewDriverButton.png
--------------------------------------------------------------------------------
/images/InstalledAppsList.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/InstalledAppsList.png
--------------------------------------------------------------------------------
/images/NewDriverExample.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/NewDriverExample.png
--------------------------------------------------------------------------------
/images/RokuTVDeviceInfo.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/RokuTVDeviceInfo.png
--------------------------------------------------------------------------------
/images/RokuTVPreferences.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/RokuTVPreferences.png
--------------------------------------------------------------------------------
/images/RokuTVCurrentState.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/RokuTVCurrentState.png
--------------------------------------------------------------------------------
/images/RokuTVStateVariables.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/RokuTVStateVariables.png
--------------------------------------------------------------------------------
/images/AddVirtualDeviceButton.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/AddVirtualDeviceButton.png
--------------------------------------------------------------------------------
/images/HubitatMenuDriversCode.png:
--------------------------------------------------------------------------------
https://raw.githubusercontent.com/apwelsh/hubitat/HEAD/images/HubitatMenuDriversCode.png
--------------------------------------------------------------------------------
/.groovylintrc.json:
--------------------------------------------------------------------------------
1 | {
2 | "extends": "recommended",
3 | "rules": {
4 | "BlockStartsWithBlankLine": {
5 | "enabled": false
6 | },
7 | "LineLength": {
8 | "enabled": false
9 | }
10 | }
11 | }
--------------------------------------------------------------------------------
/APACHE-LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2020 Armand Welsh
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/tesla/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2020 Armand Welsh
2 |
3 | Licensed under the Apache License, Version 2.0 (the "License");
4 | you may not use this file except in compliance with the License.
5 | You may obtain a copy of the License at
6 |
7 | http://www.apache.org/licenses/LICENSE-2.0
8 |
9 | Unless required by applicable law or agreed to in writing, software
10 | distributed under the License is distributed on an "AS IS" BASIS,
11 | WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
12 | See the License for the specific language governing permissions and
13 | limitations under the License.
--------------------------------------------------------------------------------
/devices/packageManifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageName": "Countdown Timer",
3 | "author": "Armand Welsh",
4 | "minimumHEVersion": "0.0",
5 | "licenseFile": "https://raw.githubusercontent.com/apwelsh/hubitat/master/APACHE-LICENSE.md",
6 | "dateReleased": "2020-05-10",
7 | "drivers": [
8 | {
9 | "id": "622d6f64-7c1d-4d7f-9de0-e4038628438a",
10 | "name": "Timer Device",
11 | "namespace": "apwelsh",
12 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/devices/timer-device.groovy",
13 | "required": true,
14 | "version": "1.10"
15 | }
16 | ],
17 | "releaseNotes": "Version 1.10 Update fixes timeremaining overflow for very large numbers, and add display support for days"
18 | }
--------------------------------------------------------------------------------
/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2020 Armand Peter Welsh
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/MIT-LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2019 Armand Peter Welsh
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/hue/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2020 Armand Peter Welsh
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/roku/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2020 Armand Peter Welsh
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/revproxy/LICENSE.md:
--------------------------------------------------------------------------------
1 | Copyright 2020 Armand Peter Welsh
2 |
3 | Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated documentation files (the "Software"), to deal in the Software without restriction, including without limitation the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
4 |
5 | The above copyright notice and this permission notice shall be included in all copies or substantial portions of the Software.
6 |
7 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
--------------------------------------------------------------------------------
/iopool/packageManifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageName": "iopool EcO Pool/Spa Monitor",
3 | "author": "Armand Welsh",
4 | "minimumHEVersion": "2.2.6",
5 | "licenseFile": "https://raw.githubusercontent.com/apwelsh/hubitat/master/LICENSE.md",
6 | "documentationLink": "https://raw.githubusercontent.com/apwelsh/hubitat/master/iopool/README.md",
7 | "communityLink": "",
8 | "dateReleased": "2022-07-03",
9 | "apps": [
10 | {
11 | "id": "5e6e32c5-0b47-4b04-a230-c3f2ce73c07d",
12 | "name": "iopool Connect",
13 | "namespace": "apwelsh",
14 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/iopool/app/iopool-connect.groovy",
15 | "required": true,
16 | "oauth": false,
17 | "primary": true,
18 | "version": "1.0.1"
19 | }
20 | ],
21 | "drivers": [
22 | {
23 | "id": "a9654937-91ff-4a1d-817b-0f70faec38a0",
24 | "name": "EcO Water Quality Sensor",
25 | "namespace": "apwelsh",
26 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/iopool/device/eco-sensor",
27 | "required": true,
28 | "version": "1.0.0"
29 | }
30 | ],
31 | "version": "1.0.1",
32 | "releaseNotes": "1.0.1 - Fixed NullPointerException in app code \n1.0.0 - Initial release"
33 | }
--------------------------------------------------------------------------------
/iopool/README.md:
--------------------------------------------------------------------------------
1 | # iopool EcO Pool & Spa Monitor Integration for Hubitat [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
2 |
3 | The iopool EcO Pool & Spa Monitor Integration for Hubitat brings leverages the iopool public API (cloud based) to link your Hubitat hub with the iopool connected devices.
4 |
5 | To use the iopool public API, you will need to obtain an API key from iopool. This can be done by emailing iopool support, or leveraging the iopool app.
6 |
7 | The application works best with the iopool gateway
8 |
9 | To install this integration, it is highly recommended to use the Hubitat Package Manager, however a manual install is supported as well. Please follow Hubitat's guides on install custom applications and drivers. This integrations requires both the eco-sensor.groovy and the iopool-connect.groovy to function.
10 |
11 | ## Support the Author
12 | Please consider donating. This app took a lot of work to make.
13 | Any donations received will be used to fund additional Hue based development.
14 |
15 | [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
16 |
17 | ## License
18 |
19 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
20 |
--------------------------------------------------------------------------------
/revproxy/packageManifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageName": "Simple Reverse Proxy Service",
3 | "author": "Armand Welsh",
4 | "minimumHEVersion": "2.4.0",
5 | "licenseFile": "https://raw.githubusercontent.com/apwelsh/hubitat/master/revproxy/LICENSE.md",
6 | "documentationLink": "https://github.com/apwelsh/hubitat/tree/master/revproxy",
7 | "dateReleased": "2025-02-25",
8 | "apps": [
9 | {
10 | "id": "3667c53f-55e9-4008-b56c-6ff91c9f666b",
11 | "name": "Simple Reverse Proxy Service",
12 | "namespace": "apwelsh",
13 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/revproxy/app/simple-reverse-proxy-service.groovy",
14 | "required": true,
15 | "oauth": false,
16 | "primary": true,
17 | "version": "1.0.0"
18 | },
19 | {
20 | "id": "6c229ee3-593d-4389-8bdd-0972b44ca83c",
21 | "name": "Simple Proxy Provider",
22 | "namespace": "apwelsh",
23 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/revproxy/app/simple-proxy-provider.groovy",
24 | "required": true,
25 | "oauth": true,
26 | "primary": false,
27 | "version": "1.0.0"
28 | }
29 | ],
30 | "version": "1.0.0",
31 | "releaseNotes": "v1.0.0\nEnabling the reverse proxy service may expose your Hubitat hub and connected network to significant security risks if proper precautions are not taken. Before enabling remote access, ensure that you have configured adequate network security measures (such as firewalls, VPNs, or strict access controls). By using this service, you assume full responsibility for any unauthorized access or security breaches that may occur. Use this feature only on trusted networks and at your own risk."
32 | }
--------------------------------------------------------------------------------
/tesla/README.md:
--------------------------------------------------------------------------------
1 | # Tesla Connect
2 |
3 | This is my implementation of the **Tesla Connect App and Tesla Device** adapted and enhanced for Hubitat and to meet my needs.
4 |
5 | NOTICE: This driver is a very early implementation
6 |
7 | ## Getting Started
8 |
9 | To use this software, you must download two files:
10 | - [tesla.groovy](device/tesla.groovy)
11 | - [tesla-connect.groovy](device/tesla-connect.groovy)
12 |
13 | ## Installation
14 | Sign into your Hubitat device, and add the devices and apps included in this project. To do so, from the menu select the **"Drivers Code"** menu option.
15 |
16 | 
17 |
18 | Next, click the **"(+) New Driver"** button
19 |
20 | 
21 |
22 | ### Tesla Device
23 | Select the import button, and put in the URL to the [tesla.groovy](device/tesla.groovy), Click the import button, and the new driver is ready.
24 | Click **Save**.
25 |
26 |
27 | ### Tesla Connect App
28 | Next, navigate to **"Apps Code"**
29 | and repeat the process for the [tesla-connect.groovy](/app/tesla-connect.groovy) app.
30 |
31 | ## Configuration
32 |
33 | The configuration is quite simple, and tries to be as automatic as possible. Once everything is installed, go to Apps, and select **"Add User Apps"** then select the **Tesla Connect** app.
34 |
35 | Once the app is installed, open the Tesla Connect app (this normally happens automatically after install) and enter you Tesla Connect credentials. Once signed in, you will receive a list of all your connected vehivles. Select the vehicle(s) to install, and click next. This will install the Tesla device for each selected vehicle. Now you are ready to configure and manage each vehicle.
36 |
37 | ### Prerequisite
38 | For smart home automation to work reliably, it is highly recommended that each installed vehicle be configured to join your wifi network, and to always be assigned the same IP Address (check your router documentation of how to configure DHCP reservations). This is not required, but it will help to ensure the best results for consistency.
39 |
40 | **Not yet implemented**
41 | Presence based on distance from home
42 | Custom attribute for geofenced home range
43 |
44 | ### Status Updates
45 | January 20, 2020
46 | - Initial implementation with minor changes from the original SmartThings implementation to adapt this solution to my needs
47 |
48 | ## License
49 |
50 | This project is licensed under the Apache 2.0 License - see the [LICENSE.md](LICENSE.md) file for details. Portions of this code are licensed from Trent Foley (https://github.com/trentfoley)
51 |
52 | ## Acknowledgments
53 | This software would not be possible without the efforts and free sharing of information provided by the original author of the [SmartThings Tesla-Connect App](https://github.com/trentfoley/SmartThingsPublic/tree/master/smartapps/trentfoley/tesla-connect.src) and [SmartThings Tesa Device](https://github.com/trentfoley/SmartThingsPublic/tree/master/devicetypes/trentfoley/tesla.src) created by [Trent Foley](https://github.com/trentfoley).
54 |
--------------------------------------------------------------------------------
/revproxy/app/simple-reverse-proxy-service.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Simple Reverse Proxy Service
3 | *
4 | * Parent app that manages multiple Simple Proxy Provider child apps.
5 | *
6 | * SUMMARY:
7 | * This service manages multiple Simple Proxy Provider child apps that act as reverse proxies.
8 | * Each child proxy forwards incoming web requests to a specified target URL and returns the upstream
9 | * response. This allows you to expose content from your private network to trusted external hosts without
10 | * directly exposing your network.
11 | *
12 | * BENEFITS:
13 | * Using a reverse proxy enables selective exposure of internal resources, adding a layer of abstraction
14 | * and security. Trusted external services (e.g., sharptools.io) can securely access specific data on your
15 | * hub's network while the proxy handles requests in a controlled manner. This helps maintain security
16 | * while providing remote access to designated content.
17 | *
18 | * DISCLAIMER:
19 | * Enabling the reverse proxy service may expose your Hubitat hub to significant security risks if proper
20 | * precautions are not taken. Before enabling remote access, ensure that you have configured adequate network
21 | * security measures (such as firewalls, VPNs, or strict access controls). By using this service, you assume
22 | * full responsibility for any unauthorized access or security breaches that may occur. Use this feature only on
23 | * trusted networks and at your own risk.
24 | */
25 | definition(
26 | name: "Simple Reverse Proxy Service",
27 | namespace: "apwelsh",
28 | author: "Armand Welsh",
29 | description: "Parent app to manage multiple Simple Proxy Provider child apps. Use with caution!",
30 | category: "Utility",
31 | iconUrl: "",
32 | iconX2Url: "",
33 | singleInstance: true
34 | )
35 |
36 | preferences {
37 | page(name: "mainPage")
38 | }
39 |
40 | def mainPage() {
41 | dynamicPage(name: "mainPage", title: "Simple Reverse Proxy Service", install: true, uninstall: true) {
42 | section("Overview") {
43 | paragraph "This service manages multiple Simple Proxy Provider child apps that act as reverse proxies. Each child proxy forwards incoming web requests to a specified target URL and returns the upstream response. This allows you to expose content from your private network to trusted external hosts without directly exposing your network."
44 | paragraph "Using a reverse proxy enables selective exposure of internal resources, adding a layer of abstraction and security. Trusted external services (e.g., sharptools.io) can securely access specific data on your hub's network while the proxy handles requests in a controlled manner. This helps maintain security while providing remote access to designated content."
45 | }
46 | section("Child Apps") {
47 | app(name: "childApps", appName: "Simple Proxy Provider", namespace: "apwelsh", title: "Add New Simple Proxy Provider", multiple: true)
48 | }
49 | section("
") {
50 | paragraph "WARNING: Enabling the reverse proxy service may expose your Hubitat hub to significant security risks if proper precautions are not taken. Before enabling remote access, ensure that you have configured adequate network security measures (such as firewalls, VPNs, or strict access controls). By using this service, you assume full responsibility for any unauthorized access or security breaches that may occur. Use this feature only on trusted networks and at your own risk."
51 | }
52 | }
53 | }
54 |
--------------------------------------------------------------------------------
/repository.json:
--------------------------------------------------------------------------------
1 | {
2 | "author": "Armand Welsh",
3 | "gitHubUrl": "https://github.com/apwelsh/hubitat",
4 | "payPalUrl": "https://www.paypal.me/apwelsh",
5 | "packages": [
6 | {
7 | "name": "Countdown Timer",
8 | "category": "Utility",
9 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/devices/packageManifest.json",
10 | "description": "A simple countdown timer device that is designed to integrate well with SharpTools",
11 | "id": "7ca01f5b-02b5-4ce4-a77c-0067661eb91a",
12 | "tags": [
13 | "Timers"
14 | ]
15 | },
16 | {
17 | "name": "Roku TV Integration",
18 | "category": "Integrations",
19 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/roku/packageManifest.json",
20 | "description": "Manage all your Roku TVs and Roku Media players through Hubitat with full support for activating applications as switches, and creating any remote command as a momentary switch. Use this device to control your Roku system, or to make a smart home that responds to Roku actions.",
21 | "id": "6442a8c3-22c2-4cbd-af81-61bc84e1690a",
22 | "tags": [
23 | "Multimedia",
24 | "LAN"
25 | ]
26 | },
27 | {
28 | "name": "Advanced Hue Hub Integration",
29 | "category": "Integrations",
30 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/packageManifest.json",
31 | "description": "Add support to Hubitat for Hue Groups, Bulbs, and Scenes. This integration differs from the built-in Hue integration, because this one allows you to import Hue scenes which can be added to any Hubitat scene/group to be turned on. This was created specifically to satisfy a need the Hubitat could not. With this driver, it is possible to smoothly transition hue scenes for any Hue group. I plan to add management of Hue scenes at a later time, as well as a capture state, similar to Hubitat's scene manager.",
32 | "id": "236c1937-ef40-4afb-a571-3cb54bce5723",
33 | "tags": [
34 | "Lights & Switches",
35 | "LAN"
36 | ]
37 | },
38 | {
39 | "id": "1fb918e8-21aa-419c-a98d-828673b174dc",
40 | "name": "iopool EcO Pool/Spa Monitor",
41 | "category": "Integrations",
42 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/iopool/packageManifest.json",
43 | "description": "Add support to Hubitat for iopool's EcO pool / spa water quality monitor. iopool can also be used breath new life into the no-longer support pHin pool monitor. The iopool EcO is used to track water pH, Oxidation-reduction potential (ora), and temperature.",
44 | "tags": [
45 | "Cloud",
46 | "LAN",
47 | "Monitoring",
48 | "Multi Sensors",
49 | "Pools & Spas",
50 | "Water"
51 | ]
52 | },
53 | {
54 | "id": "e34b1f40-315c-49f2-8ac7-68566d4dfd2a",
55 | "name": "Simple Reverse Proxy Service",
56 | "category": "Integrations",
57 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/revproxy/packageManifest.json",
58 | "description": "A simple reverse proxy service. This service is designed to allow you to access http resources on your Hubitat hub's network from outside your network. This is not a full-featured reverse proxy, but it is a simple one that can be used to access specific web based endpoints without the need for complex VPNs, and without opening up your firewall directly to the internal resource. This is useful for accessing webhooks, or other web-based services that are not directly accessible from the internet.",
59 | "tags": [
60 | "Security",
61 | "LAN",
62 | "Remote Access"
63 | ]
64 | }
65 | ]
66 | }
--------------------------------------------------------------------------------
/revproxy/README.md:
--------------------------------------------------------------------------------
1 | # Simple Reverse Proxy Service for Hubitat [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
2 |
3 | ## SUMMARY
4 | This application provides a service that manages multiple Simple Proxy Provider child apps that act as reverse mico-proxies. Each child proxy forwards incoming web requests to a specified target URL and returns the upstream response. This allows you to expose content from your private network to trusted external hosts without directly exposing your network, and without the need for complex VPNs.
5 |
6 | ## BENEFITS
7 | Using a reverse proxy enables selective exposure of internal resources, adding a layer of abstraction and security. Trusted external services (e.g., sharptools.io) can securely access specific data on your hub's network while the proxy handles requests in a controlled manner. This helps maintain security while providing remote access to designated content.
8 |
9 | ## SECURITY DISCLAIMER
10 | Enabling the reverse proxy service may expose your Hubitat hub and connected network to significant security risks if proper precautions are not taken. Before enabling remote access, ensure that you have configured adequate network security measures (such as firewalls, VPNs, or strict access controls). By using this service, you assume full responsibility for any unauthorized access or security breaches that may occur. Use this feature only on trusted networks and at your own risk.
11 |
12 |
13 | ## Features
14 |
15 | - [Simple Reverse Proxy Service](app/simple-reverse-proxy-service.groovy)
16 | - This is the main app for managing the various reverse micro-proxy endpoints.
17 | - Each endpoint can expose only one specific URL to the consumer of the service.
18 | - This is not just for exposing private network resources to the internet, it can also be used to enable access between IoT networks and home networks, when the Hubitat Elevation hub has visibility to both networks.
19 | - [Simple Proxy Provider](app/simple-proxy-provider.groovy)
20 | - Each reverse micro-proxy can be provided a unique name
21 | - Each reverse micro-proxy must define a fully quialified target URL
22 | - Optional switch to turn on/off support to forward query parameters
23 | - Optional switch to turn on/off support to forward http request headers
24 | - The micro-proxy will not work until the OAuth has been enabled for this driver in the Dev / Apps Code section of hubitat for this driver
25 | - The micro-proxy also requires the activation of the remote endpoint to function properly
26 |
27 | ## Vision / Future Enhancements
28 | The goal of this project is to leverage the Hubitat Hub as a means of accessing select internal resources. As this project matures, additional features will be added to further provide protection from bad actors. At this time, the features is very simple, but it is in all accounts a real proxy. At no time does the consumer of this server talk directly to the back-end web endpoint. All data is downloaded from the back-end (upstream) endpoint before it is sent to the consumer. This is not intended to work as an application reverse proxy, as it is not a simple URL redirector.
29 |
30 | This project was created with the assistance of AI, but every bit of this code it original code.
31 |
32 | ## Support the Author
33 | Please consider donating. This app took a lot of work to make.
34 | Any donations received will be used to fund additional Hue based development.
35 |
36 | [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
37 |
38 | ## License
39 |
40 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
41 |
--------------------------------------------------------------------------------
/README.md:
--------------------------------------------------------------------------------
1 |
2 | # Hubitat Drivers [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
3 |
4 |
5 | Welcome to my Hubitat Github repo. All drivers and applications in this repo are free for use. If you like them, please share, and consider a modest donation. If you have recommendations for updates, or observed bugs, please open an issue and communiate it. If you have a bug-fix, or enhancement you think I might like, or others might like, please submit a pull request to merge your changes.
6 |
7 |
8 | ## Current Projects
9 |
10 | - [Roku TV and Media Players](roku/README.md)
11 | - An application and device driver for managing Roku TVs and Media Players. This solution can be used to create rules that respond to Roku events, such as:
12 | - [X] Turn off theater lights, and dim the entry light with Plex loads
13 | - [X] Turn on living room lights when show is paused, and restore prior state with show is playing
14 | - [X] Change the TV LED light strips to Red when Netflix is, Green for Hulu, Blue for Amazon Prime, etc...
15 | - [X] Turn on the living room lights for 5 minutes when the TV is powered off, and the Mode is Night
16 | - Or use the Basic Rules to automate your TV, such as:
17 | - [X] If mode transitions to day, then hallway motion is detected, turn on the kitchen TV, and play a random episode of Dora the Explorer
18 | - [X] If Goodnight Scene is actived, then hallway motion is detected, then bedroom motion is detected, turn off living room TV and turn on Hulu on bedroom TV
19 | - [Timer Device](Timer.md)
20 | - This is a simple count-down timer tile. Use this device when you want a timer that shows you the amount of time remaining and that is SharpTools.io HERO tile friendly. The timer supports start/stop/pause/cancel events. Cancel is basically the same as stop, except the sessionStatus will report canceled, rather than stopped. The device is rather straight forward. To use the timer in applications, the timer attribute sessionStatus will report the timer status as text, and the switch state will be set to on while the timer is running and off when it is stopped. To detect that the timer ended, the timer implemented the PushableButton and will send a button 1 pushed event upon timer completion.
21 | - [Advanced Hue Hub Integration](hue/README.md)
22 | - This project's goal is to bridge the gap that currently exists between Hubitat and Hue Bridge. The hubitat native support should be used whenever possible -- however, there are some things in the native hue integration that create an unpleasent user experience. Hue Scenes are not supported in hubitat. This *experimental*, and **in development** project's goal is to bring Hue scenes to hubitat as child devices of the hue groups.
23 | - This project has been expanded to also support real-time updates for hue device changes, and adds support for hue sensors, and dimmer controllers.
24 | - [iopool EcO Pool/Spa Monitor](iopool/README.md)
25 | - This projects integrates the iopool EcO pool monitor with Hubitat. iopool is pool monitoring solution that can monitor pH, temperature, and sanitization level of your pool or spa water.
26 | - [Tesla Connect](tesla/README.md) **Project is dead**
27 | - This project's goal is to convert the SmartThings Tesla-Connect solution for Hubitat, and enhance it to provide features not available with the current SmartThings solution. This *experimental*, and **in development** project's goal is to bring Tesla Presence based logic to Hubit and provide an alternative to Tesla HomeLink. _** Update **_ Tesla Motors has changed how their service works, and this app no longer works.
28 |
29 |
30 | ## License
31 |
32 | Portions of this repository are licensed under the MIT License - see the [MIT LICENSE](MIT-LICENSE.md)
33 |
34 | Portions of this repository are licensed under the Apache 2.0 License - see the [Apache LICENSE](APACHE-LICENSE.md)
35 |
--------------------------------------------------------------------------------
/hue/device/advanced-hue-light-sensor.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Advanced Hue Light Sensor
3 | * Version 1.0.6
4 | * Download: https://github.com/apwelsh/hubitat
5 | * Description:
6 | * This is a child device handler for the Advance Hue Bridge Integration App. This device reports light level
7 | * and battery level from a Hue connected sensor. Although this can work in poll mode, it is highly recommended to
8 | * use the event stream based push notifications
9 | *-------------------------------------------------------------------------------------------------------------------
10 | * Copyright 2020 Armand Peter Welsh
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13 | * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16 | *
17 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18 | * the Software.
19 | *
20 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21 | * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | * IN THE SOFTWARE.
25 | *-------------------------------------------------------------------------------------------------------------------
26 | **/
27 |
28 | import groovy.transform.Field
29 |
30 | @Field static final Boolean DEFAULT_LOG_ENABLE = true
31 | @Field static final Boolean DEFAULT_DBG_ENABLE = false
32 |
33 | @Field static final String SETTING_LOG_ENABLE = 'logEnable'
34 | @Field static final String SETTING_DBG_ENABLE = 'debug'
35 |
36 | metadata {
37 | definition (
38 | name: 'AdvancedHueLightSensor',
39 | namespace: 'apwelsh',
40 | author: 'Armand Welsh',
41 | importUrl: 'https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-light-sensor.groovy') {
42 |
43 | capability 'Battery'
44 | capability 'IlluminanceMeasurement'
45 | capability 'Refresh'
46 | capability 'Sensor'
47 |
48 | attribute 'status', 'string' // expect enabled/disabled
49 | attribute 'health', 'string' // reachable/unreachable
50 | }
51 | }
52 |
53 | preferences {
54 |
55 | input name: SETTING_LOG_ENABLE,
56 | type: 'bool',
57 | defaultValue: DEFAULT_LOG_ENABLE,
58 | title: 'Enable informational logging'
59 |
60 | input name: SETTING_DBG_ENABLE,
61 | type: 'bool',
62 | defaultValue: DEFAULT_DBG_ENABLE,
63 | title: 'Enable debug logging'
64 |
65 | }
66 |
67 | void updateSetting(String name, Object value) {
68 | device.updateSetting(name, value)
69 | this[name] = value
70 | }
71 |
72 | /**
73 | * Hubitat DTH Lifecycle Functions
74 | **/
75 | def installed() {
76 | updated()
77 | refresh()
78 | }
79 |
80 | def updated() {
81 | if (this[SETTING_LOG_ENABLE] == null) { updateSetting(SETTING_LOG_ENABLE, DEFAULT_LOG_ENABLE) }
82 | if (this[SETTING_DBG_ENABLE] == null) { updateSetting(SETTING_DBG_ENABLE, DEFAULT_DBG_ENABLE) }
83 | if (this[SETTING_LOG_ENABLE]) { log.debug 'Preferences updated' }
84 | }
85 |
86 |
87 | /*
88 | * Device Capability Interface Functions
89 | */
90 |
91 |
92 | void refresh() {
93 | if (this[SETTING_DBG_ENABLE]) { log.debug "Sensor (${this}) refreshing" }
94 | parent.getDeviceState(this)
95 | }
96 |
97 | void setHueProperty(Map args) {
98 | }
99 |
--------------------------------------------------------------------------------
/hue/device/advanced-hue-temperature-sensor.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Advanced Hue Temperature Sensor
3 | * Version 1.0.7
4 | * Download: https://github.com/apwelsh/hubitat
5 | * Description:
6 | * This is a child device handler for the Advance Hue Bridge Integration App. This device reports light level
7 | * and battery level from a Hue connected sensor. Although this can work in poll mode, it is highly recommended to
8 | * use the event stream based push notifications
9 | *-------------------------------------------------------------------------------------------------------------------
10 | * Copyright 2020 Armand Peter Welsh
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13 | * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16 | *
17 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18 | * the Software.
19 | *
20 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21 | * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | * IN THE SOFTWARE.
25 | *-------------------------------------------------------------------------------------------------------------------
26 | **/
27 |
28 | import groovy.transform.Field
29 |
30 | @Field static final Boolean DEFAULT_LOG_ENABLE = true
31 | @Field static final Boolean DEFAULT_DBG_ENABLE = false
32 |
33 | @Field static final String SETTING_LOG_ENABLE = 'logEnable'
34 | @Field static final String SETTING_DBG_ENABLE = 'debug'
35 |
36 | metadata {
37 | definition (
38 | name: 'AdvancedHueTemperatureSensor',
39 | namespace: 'apwelsh',
40 | author: 'Armand Welsh',
41 | importUrl: 'https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-temperature-sensor.groovy') {
42 |
43 | capability 'Battery'
44 | capability 'TemperatureMeasurement'
45 | capability 'Refresh'
46 | capability 'Sensor'
47 |
48 | attribute 'status', 'string' // expect enabled/disabled
49 | attribute 'health', 'string' // reachable/unreachable
50 | }
51 | }
52 |
53 | preferences {
54 |
55 | input name: SETTING_LOG_ENABLE,
56 | type: 'bool',
57 | defaultValue: DEFAULT_LOG_ENABLE,
58 | title: 'Enable informational logging'
59 |
60 | input name: SETTING_DBG_ENABLE,
61 | type: 'bool',
62 | defaultValue: DEFAULT_DBG_ENABLE,
63 | title: 'Enable debug logging'
64 |
65 | }
66 |
67 | void updateSetting(String name, Object value) {
68 | device.updateSetting(name, value)
69 | this[name] = value
70 | }
71 |
72 | /**
73 | * Hubitat DTH Lifecycle Functions
74 | **/
75 | def installed() {
76 | updated()
77 | refresh()
78 | }
79 |
80 | def updated() {
81 | if (this[SETTING_LOG_ENABLE] == null) { updateSetting(SETTING_LOG_ENABLE, DEFAULT_LOG_ENABLE) }
82 | if (this[SETTING_DBG_ENABLE] == null) { updateSetting(SETTING_DBG_ENABLE, DEFAULT_DBG_ENABLE) }
83 | if (this[SETTING_LOG_ENABLE]) { log.debug 'Preferences updated' }
84 | }
85 |
86 |
87 | /*
88 | * Device Capability Interface Functions
89 | */
90 |
91 |
92 | void refresh() {
93 | if (this[SETTING_DBG_ENABLE]) { log.debug "Sensor (${this}) refreshing" }
94 | parent.getDeviceState(this)
95 | }
96 |
97 | void setHueProperty(Map args) {
98 | }
99 |
--------------------------------------------------------------------------------
/roku/packageManifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageName": "Roku TV Integration",
3 | "author": "Armand Welsh",
4 | "minimumHEVersion": "2.2.6",
5 | "licenseFile": "https://raw.githubusercontent.com/apwelsh/hubitat/master/roku/LICENSE.md",
6 | "documentationLink": "https://raw.githubusercontent.com/apwelsh/hubitat/master/roku/README.md",
7 | "communityLink": "https://community.hubitat.com/t/new-roku-tv-device-handler/12038",
8 | "dateReleased": "2020-06-11",
9 | "apps": [
10 | {
11 | "id": "cbf5b247-9c87-4926-83db-69c1dd70e211",
12 | "name": "Roku Connect",
13 | "namespace": "apwelsh",
14 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/roku/app/roku-connect.groovy",
15 | "required": false,
16 | "oauth": false,
17 | "primary": true,
18 | "version": "1.3.0"
19 | }
20 | ],
21 | "drivers": [
22 | {
23 | "id": "516bab57-6e80-4364-be6b-c4ef7c1361f5",
24 | "name": "Roku TV",
25 | "namespace": "apwelsh",
26 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/roku/device/roku-tv.groovy",
27 | "required": true,
28 | "version": "2.8.4"
29 | }
30 | ],
31 | "version": "1.4.4",
32 | "releaseNotes": "1.4.4 - Removed quiter command (unused, and typo - was supposed to be quieter)\n1.4.3 - Fixed setChannel. Roku changed the live TV app, and with that change, they changed how to send a channel slightly.\n1.4.2 - Initial fix for 5 Series Roku TVs that report Home instead of Roku when the Home app is active.\n1.4.1 - Added volumeUp10 and volumeDown10. Reworked the setChannel to be more accurate by sending key presses synchronously, instead of asynchronously.\n1.4.0 - Added setChannel command to RokuTV driver \n1.3.23 - Fixed bug that prevented the turning on of application child devices. \n1.3.22 - Fixed bug the turns off scheduled refreshes when a app initiated keypress event is issued. Fixed bug that prevents matching of TV input to installed child device, when the TV inuput name has been modified on the TV. Added iconPath to child Input devices. Added ability to manage Input devices from Roku Connect app. \n1.3.21 - Fixed code error that broke the media status updates. Thanks to @mike385 for reporting it. \n1.3.20 - Cnverted most web calls back to async to more accurately represent system load, so idle wait times are not counted as busy time in runtime statistics. \n1.3.19 - Added support to use ping when a TV is powered off, to detect when it is powered back on. Due to performance concerns, the refresh interval is never more frequent than every 20 seconds. Enable Experimental Features to use. \n1.3.18 - Removed trace log from debugging in exception handler \n1.3.17 - Added donate link to app \n1.3.16 - Implement Initialize capability to refresh device state on hub startup. \n1.3.15 - Fixed Null Point Exception parsing active application. Added new Debug Verbose Logging setting. \n1.3.14 - Added logic to skip device info query on non-TV Roku device, since they do not report power state. \n1.3.13 - Corrected annoying bug when adding new devices. \n1.3.12 - Minor update to improve performance on updating values. \n1.3.11 - Implement logic changes to reduce CPU load and network traffic. Suppress redundant events. \n1.3.110 - Fix logic fro updating mediaInputSource, and improved quality of transport status detection. \n1.3.8 - Added a critical bug fix and some more minor fixes for handling power state. \n1.3.7- Enabled support for disabling refresh with refresh interval of 0. \n1.3.6 - Added support for MediaInputSource to support standard input source selection, and removed refresh attribute. This update limits event logging considerably to improve overall performance. \n1.3.5 - Fixed reported bugs in Roku Connect preventing the addition of new channels on newly added Roku devices. \n1.3.4 - Updated refresh logic so that when the TV turns off, the transportStatus changes to stopped, and application changes to Roku. \n1.3.3 - Added support for MediaTransport capability, which emulates the play/pause/stop commands of media players. \n1.3.2 - Added ability to turn off the ssdp auto-discovery. Added ability to choose power on/off command mode"
33 | }
34 |
--------------------------------------------------------------------------------
/hue/device/advanced-hue-tap-sensor.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Advanced Hue Tap Sensor
3 | * Version 1.0.3
4 | * Download: https://github.com/apwelsh/hubitat
5 | * Description:
6 | * This is a child device handler for the Advance Hue Bridge Integration App. This device reports light level
7 | * and battery level from a Hue connected sensor. Although this can work in poll mode, it is highly recommended to
8 | * use the event stream based push notifications
9 | *-------------------------------------------------------------------------------------------------------------------
10 | * Copyright 2020 Armand Peter Welsh
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13 | * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16 | *
17 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18 | * the Software.
19 | *
20 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21 | * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | * IN THE SOFTWARE.
25 | *-------------------------------------------------------------------------------------------------------------------
26 | **/
27 |
28 | import groovy.transform.Field
29 | import java.util.concurrent.ConcurrentHashMap
30 |
31 |
32 | @Field static final Boolean DEFAULT_LOG_ENABLE = true
33 | @Field static final Boolean DEFAULT_DBG_ENABLE = false
34 |
35 | @Field static final String SETTING_LOG_ENABLE = 'logEnable'
36 | @Field static final String SETTING_DBG_ENABLE = 'debug'
37 |
38 | metadata {
39 | definition (
40 | name: 'AdvancedHueTapSensor',
41 | namespace: 'apwelsh',
42 | author: 'Armand Welsh',
43 | importUrl: 'https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-tap-sensor.groovy') {
44 |
45 | capability 'Battery'
46 | capability 'PushableButton'
47 | capability 'Refresh'
48 | capability 'Initialize'
49 |
50 | attribute 'status', 'string' // expect enabled/disabled
51 | attribute 'health', 'string' // reachable/unreachable
52 | }
53 | }
54 |
55 | preferences {
56 |
57 | input name: SETTING_LOG_ENABLE,
58 | type: 'bool',
59 | defaultValue: DEFAULT_LOG_ENABLE,
60 | title: 'Enable informational logging'
61 |
62 | input name: SETTING_DBG_ENABLE,
63 | type: 'bool',
64 | defaultValue: DEFAULT_DBG_ENABLE,
65 | title: 'Enable debug logging'
66 |
67 | }
68 |
69 | void updateSetting(String name, Object value) {
70 | device.updateSetting(name, value)
71 | this[name] = value
72 | }
73 |
74 | /**
75 | * Hubitat DTH Lifecycle Functions
76 | **/
77 | def installed() {
78 | updated()
79 | initialize()
80 | refresh()
81 |
82 | mapButtons()
83 |
84 | }
85 |
86 | def initialize() {
87 | String id = parent.deviceIdNode(device.deviceNetworkId)
88 | Long buttons = parent.state.sensors[id]?.capabilities?.inputs?.size()?:0
89 | parent.sendChildEvent(this, [name: 'numberOfButtons', value: buttons])
90 | }
91 |
92 | def updated() {
93 | if (this[SETTING_LOG_ENABLE] == null) { updateSetting(SETTING_LOG_ENABLE, DEFAULT_LOG_ENABLE) }
94 | if (this[SETTING_DBG_ENABLE] == null) { updateSetting(SETTING_DBG_ENABLE, DEFAULT_DBG_ENABLE) }
95 | if (this[SETTING_LOG_ENABLE]) { log.debug 'Preferences updated' }
96 | }
97 |
98 | void mapButtons() {
99 | String id = parent.deviceIdNode(device.deviceNetworkId)
100 |
101 | state.buttonMap = parent.enumerateResourcesV2().findAll { resource ->
102 | resource.type == 'button' && resource.id_v1 == "/sensors/${id}"
103 | }.collectEntries { button ->
104 | [(button.id): button.metadata.control_id]
105 | }
106 | }
107 |
108 | /*
109 | * Device Capability Interface Functions
110 | */
111 |
112 |
113 | void refresh() {
114 | if (this[SETTING_DBG_ENABLE]) { log.debug "Sensor (${this}) refreshing" }
115 | parent.getDeviceState(this)
116 | }
117 |
118 | void setHueProperty(Map args) {
119 | if (args.last_event && args.id) {
120 | Number btn = state.buttonMap?.(args.id) ?: 0
121 | if (args.last_event == 'initial_press') { push(btn) }
122 | }
123 | }
124 |
125 | void push(Number buttonNumber) {
126 | sendEvent([name: 'pushed', value: buttonNumber, isStateChange:true])
127 | }
128 |
--------------------------------------------------------------------------------
/hue/device/advanced-hue-motion-sensor.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Advanced Hue Motion Sensor
3 | * Version 1.0.7
4 | * Download: https://github.com/apwelsh/hubitat
5 | * Description:
6 | * This is a child device handler for the Advance Hue Bridge Integration App. This device reports light level
7 | * and battery level from a Hue connected sensor. Although this can work in poll mode, it is highly recommended to
8 | * use the event stream based push notifications
9 | *-------------------------------------------------------------------------------------------------------------------
10 | * Copyright 2020 Armand Peter Welsh
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13 | * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16 | *
17 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18 | * the Software.
19 | *
20 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21 | * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | * IN THE SOFTWARE.
25 | *-------------------------------------------------------------------------------------------------------------------
26 | **/
27 |
28 | import groovy.transform.Field
29 |
30 | @Field static final Boolean DEFAULT_LOG_ENABLE = true
31 | @Field static final Boolean DEFAULT_DBG_ENABLE = false
32 |
33 | @Field static final String SETTING_LOG_ENABLE = 'logEnable'
34 | @Field static final String SETTING_DBG_ENABLE = 'debug'
35 | @Field static final String SETTING_SENSITIVITY = 'sensitivity'
36 |
37 | metadata {
38 | definition (
39 | name: 'AdvancedHueMotionSensor',
40 | namespace: 'apwelsh',
41 | author: 'Armand Welsh',
42 | importUrl: 'https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-motion-sensor.groovy') {
43 |
44 | capability 'MotionSensor'
45 | capability 'Battery'
46 | capability 'Refresh'
47 | capability 'Sensor'
48 |
49 | attribute 'status', 'string' // expect enabled/disabled
50 | attribute 'health', 'string' // reachable/unreachable
51 | }
52 | }
53 |
54 | preferences {
55 |
56 | input name: SETTING_LOG_ENABLE,
57 | type: 'bool',
58 | defaultValue: DEFAULT_LOG_ENABLE,
59 | title: 'Enable informational logging'
60 |
61 | input name: SETTING_DBG_ENABLE,
62 | type: 'bool',
63 | defaultValue: DEFAULT_DBG_ENABLE,
64 | title: 'Enable debug logging'
65 |
66 | def sensitivitymax = 1
67 | try {
68 | Map config = parent.stateForNetworkId(deviceInstance.deviceNetworkId)?.config
69 | sensitivitymax = config?.sensitivitymax?:1
70 | int s = config?.sensitivity == null ? sensitivitymax : config.sensitivity
71 | if (this[SETTING_SENSITIVITY] != s) {
72 | updateSetting(SETTING_SENSITIVITY, s)
73 | }
74 | } catch (ex) {
75 | log.error "${ex}"
76 | }
77 |
78 | input name: SETTING_SENSITIVITY,
79 | type: 'number',
80 | defaultValue: sensitivitymax,
81 | range: 0..sensitivitymax,
82 | title: 'Motion Sensitivity',
83 | description: "Enter a value from 0 to ${sensitivitymax}"
84 |
85 | }
86 |
87 | private getDeviceInstance() {
88 | parent.getChildDeviceById(device.deviceId)
89 | }
90 |
91 | void updateSetting(String name, Object value) {
92 | device.updateSetting(name, value)
93 | this[name] = value
94 | }
95 |
96 | /**
97 | * Hubitat DTH Lifecycle Functions
98 | **/
99 | def installed() {
100 | updated()
101 | refresh()
102 | }
103 |
104 | def updated() {
105 | if (this[SETTING_LOG_ENABLE] == null) { updateSetting(SETTING_LOG_ENABLE, DEFAULT_LOG_ENABLE) }
106 | if (this[SETTING_DBG_ENABLE] == null) { updateSetting(SETTING_DBG_ENABLE, DEFAULT_DBG_ENABLE) }
107 | if (this[SETTING_LOG_ENABLE]) { log.debug 'Preferences updated' }
108 |
109 | Map configs = [:]
110 | Map devcfg = parent.stateForNetworkId(device.deviceNetworkId)?.config
111 |
112 | if (this[SETTING_SENSITIVITY] != devcfg[SETTING_SENSITIVITY]) { configs[SETTING_SENSITIVITY] = this[SETTING_SENSITIVITY] }
113 |
114 | parent.setDeviceConfig(this, configs)
115 | }
116 |
117 | /*
118 | * Device Capability Interface Functions
119 | */
120 |
121 |
122 | void refresh() {
123 | if (this[SETTING_DBG_ENABLE]) { log.debug "Sensor (${this}) refreshing" }
124 | parent.getDeviceState(this)
125 | }
126 |
127 | void setHueProperty(Map args) {
128 | }
129 |
130 |
--------------------------------------------------------------------------------
/hue/README.md:
--------------------------------------------------------------------------------
1 | # Advanced Hue Bridge Integration for Hubitat [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
2 |
3 | The Advanced Hue Bridge Integration for Hubitat brings support the Hue scenes, groups, and lights. It minimizes hubitat complexity by leveraging the built-in Hubitat component drivers whereever possible. Additionally, this system will pick the best fit generic component driver for each light, to ensure the devices are correctly represented in dashboards.
4 |
5 | This application and associated drivers are now ready for general use. A beta branch will be created for those that wish to use the newest features as they are being added and tested.
6 |
7 | Hue Play systems, like the Hue Sync are not yet supported, as I do not own one to test with.
8 |
9 | The functionality is mostly complete at this time. I believe this system already provides more features and better performance than the built-in Hue integration, but that is an opion, not a measured fact.
10 |
11 | This integration fully supports hue push notifaction events, so that sensors can be leveraged in near-realtime, and lights are updated in near-realtime with no need to require a scheduled refresh of the Hue system.
12 |
13 |
14 | ## Features
15 |
16 | - [Advanced Hue Bridge Integration App](app/hue-bridge-integration.groovy)
17 | - This is the main component. Like the native application, this is the app that you will use to link the Hue bridge to your HE system. All drivers in this project are 100% dependent upon this app.
18 | - Used to add Lights, Groups, and Scenes
19 | - [Advanced Hue Bridge Device](device/advanced-hue-bridge.groovy)
20 | - The main app will install an instance of this device after the app successfully pairs the hue bridge.
21 | - Used to schedule the hub refresh event.
22 | - Supports `Switch` capability to turn on/off all Hue lights.
23 | - Can be configured to automatically turn on if Any light is on, or if All ligts are on.
24 | - [Advanced Hue Group Device](device/advanced-hue-group.groovy)
25 | - All imported Hue Groups will use this device to manage the group. This device depends on the parent app to operate. The initial version of this device supports all color light control capabilities, and the ability to activate any hue scene by scene ID or scene name (as identified in the hue bridge).
26 | - Can define a default scene to activate when the group is turned on.
27 | - Hue Lights Device `Generic Hubitat Device`
28 | - All imported Hue Ligts will use one of the matching Hubitat component drivers. Hue lights are installed as individual lights, now as child devices or another device.
29 | - Use `Generic Component Dimmer` for dimmable lights
30 | - Use `Generic Component CT` for color temperature adjustable lights
31 | - Use `Generic Component RGBW` for extended color lights
32 | - Use `Generic Component RGB` for all other lights
33 | - Hue Scenes Device `Generic Hubitat Device`
34 | - One of the key features of this integration, is the ability to use and manage Hue scenes. This device is the a switch devices used to active a hue scene.
35 | - Use `Generic Component Switch` for switching on hue scenes.
36 | - Can be configured as a momentary (trigger) switch, or as a toggle switch.
37 | - Trigger (momentary) mode. When turned on, scene will be activated and will automatically turn off the switch after 400 milliseconds.
38 | - Switch mode. Turning on a scene will result in the scene switch staying on, until *any* attribute of the group or bublbs within the group are changed, or until another scene is activated. Turning off the active scene will turn off the parent Hue group.
39 | - [Advanced Hue Motion Sensor Device](device/advanced-hue-motion-sensor.groovy)
40 | - Support for Motion Sensor
41 | - Support for Battery level
42 | - Support for Refresh
43 | - [Advanced Hue Light Sensor Device](device/advanced-hue-light-sensor.groovy)
44 | - Support for IlluminanceMeasurement
45 | - Support for Battery level
46 | - Support for Refresh
47 | - [Advanced Hue Temperature Sensor Device](device/advanced-hue-temperature-sensor.groovy)
48 | - Support for TemperatureMeasurement
49 | - Support for Battery level
50 | - Support for Refresh
51 |
52 |
53 |
54 | ## Vision / Future Enhancements
55 | The goal of this project is to more tightly integrate the hue system with Hubitat.
56 | - Hue Integrated Group Manager -- Hubitat has support for groups, but adding hue lights to groups results in slow automation, as the bridge controls the light individually. With this project, I will enable the ability to create and manage custom groups on Hue that can include Hue and HE devices. This will enable making changes to the hue group with a single API call to hue.
57 | - Hue Integrated Scene Manager -- Hubitat has support for scenes, but adding hue lights to scenes results in slow and out of sync transitions. With this project, I will enable the ability to create and manage scenes on Hue that can include Hue and HE devices. This will make it possible to syncronize the hue devices with the HE devices as they transition. To what extent I will be able to sync with HE and achieve the zigbee optiminizations of non-hue is not yet known.
58 |
59 | ## Support the Author
60 | Please consider donating. This app took a lot of work to make.
61 | Any donations received will be used to fund additional Hue based development.
62 |
63 | [](https://www.paypal.com/donate?hosted_button_id=XZXSPZWAABU8J)
64 |
65 | ## License
66 |
67 | This project is licensed under the MIT License - see the [LICENSE.md](LICENSE.md) file for details.
68 |
--------------------------------------------------------------------------------
/hue/device/advanced-hue-dimmer-sensor.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Advanced Hue Dimmer Sensor
3 | * Version 1.0.3
4 | * Download: https://github.com/apwelsh/hubitat
5 | * Description:
6 | * This is a child device handler for the Advance Hue Bridge Integration App. This device reports light level
7 | * and battery level from a Hue connected sensor. Although this can work in poll mode, it is highly recommended to
8 | * use the event stream based push notifications
9 | *-------------------------------------------------------------------------------------------------------------------
10 | * Copyright 2020 Armand Peter Welsh
11 | *
12 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
13 | * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
14 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
15 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
16 | *
17 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
18 | * the Software.
19 | *
20 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
21 | * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
22 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
23 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
24 | * IN THE SOFTWARE.
25 | *-------------------------------------------------------------------------------------------------------------------
26 | **/
27 |
28 | import groovy.transform.Field
29 | import java.util.concurrent.ConcurrentHashMap
30 |
31 |
32 | @Field static final Boolean DEFAULT_LOG_ENABLE = true
33 | @Field static final Boolean DEFAULT_DBG_ENABLE = false
34 |
35 | @Field static final String SETTING_LOG_ENABLE = 'logEnable'
36 | @Field static final String SETTING_DBG_ENABLE = 'debug'
37 |
38 | metadata {
39 | definition (
40 | name: 'AdvancedHueDimmerSensor',
41 | namespace: 'apwelsh',
42 | author: 'Armand Welsh',
43 | importUrl: 'https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-dimmer-sensor.groovy') {
44 |
45 | capability 'Battery'
46 | capability 'PushableButton'
47 | capability 'HoldableButton'
48 | capability 'ReleasableButton'
49 | capability 'Refresh'
50 | capability 'Initialize'
51 |
52 | attribute 'status', 'string' // expect enabled/disabled
53 | attribute 'health', 'string' // reachable/unreachable
54 | }
55 | }
56 |
57 | preferences {
58 |
59 | input name: SETTING_LOG_ENABLE,
60 | type: 'bool',
61 | defaultValue: DEFAULT_LOG_ENABLE,
62 | title: 'Enable informational logging'
63 |
64 | input name: SETTING_DBG_ENABLE,
65 | type: 'bool',
66 | defaultValue: DEFAULT_DBG_ENABLE,
67 | title: 'Enable debug logging'
68 |
69 | }
70 |
71 | void updateSetting(String name, Object value) {
72 | device.updateSetting(name, value)
73 | this[name] = value
74 | }
75 |
76 | /**
77 | * Hubitat DTH Lifecycle Functions
78 | **/
79 | def installed() {
80 | updated()
81 | initialize()
82 | refresh()
83 |
84 | mapButtons()
85 |
86 | }
87 |
88 | def initialize() {
89 | String id = parent.deviceIdNode(device.deviceNetworkId)
90 | Long buttons = parent.state.sensors[id]?.capabilities?.inputs?.size()?:0
91 | parent.sendChildEvent(this, [name: 'numberOfButtons', value: buttons])
92 | }
93 |
94 | def updated() {
95 | if (this[SETTING_LOG_ENABLE] == null) { updateSetting(SETTING_LOG_ENABLE, DEFAULT_LOG_ENABLE) }
96 | if (this[SETTING_DBG_ENABLE] == null) { updateSetting(SETTING_DBG_ENABLE, DEFAULT_DBG_ENABLE) }
97 | if (this[SETTING_LOG_ENABLE]) { log.debug 'Preferences updated' }
98 | }
99 |
100 | void mapButtons() {
101 | String id = parent.deviceIdNode(device.deviceNetworkId)
102 |
103 | state.buttonMap = parent.enumerateResourcesV2().findAll { resource ->
104 | resource.type == 'button' && resource.id_v1 == "/sensors/${id}"
105 | }.collectEntries { button ->
106 | [(button.id): button.metadata.control_id]
107 | }
108 | }
109 |
110 | /*
111 | * Device Capability Interface Functions
112 | */
113 |
114 |
115 | void refresh() {
116 | if (this[SETTING_DBG_ENABLE]) { log.debug "Sensor (${this}) refreshing" }
117 | parent.getDeviceState(this)
118 | }
119 |
120 | void setHueProperty(Map args) {
121 | if (args.last_event && args.id) {
122 | Number btn = state.buttonMap?.(args.id) ?: 0
123 | switch(args.last_event) {
124 | case 'initial_press':
125 | break;
126 | case 'repeat':
127 | hold(btn)
128 | break;
129 | case 'short_release':
130 | push(btn)
131 | break;
132 | case 'long_release':
133 | release(btn)
134 | break;
135 | }
136 |
137 | }
138 | }
139 |
140 | void push(Number buttonNumber) {
141 | sendEvent([name: 'pushed', value: buttonNumber, isStateChange: true])
142 | }
143 |
144 | void hold(Number buttonNumber) {
145 | sendEvent([name: 'held', value: buttonNumber, isStateChange: true])
146 | }
147 |
148 | void release(Number buttonNumber) {
149 | sendEvent([name: 'released', value: buttonNumber, isStateChange: true])
150 | }
--------------------------------------------------------------------------------
/tesla/device/tesla.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * Tesla
3 | *
4 | * Copyright 2020 Armand Welsh
5 | *
6 | * Licensed under the Apache License, Version 2.0 (the "License"); you may not use this file except
7 | * in compliance with the License. You may obtain a copy of the License at:
8 | *
9 | * http://www.apache.org/licenses/LICENSE-2.0
10 | *
11 | * Unless required by applicable law or agreed to in writing, software distributed under the License is distributed
12 | * on an "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the License
13 | * for the specific language governing permissions and limitations under the License.
14 | *
15 | */
16 | preferences {
17 | input name: "homelink", type: "bool", title: "Use HomeLink presence", defaultValue: false
18 | if (homelink)
19 | input name: "geofence", type: "number", title: "Meters from home for presence", defaultValue: 50
20 | input name: "logEnable", type: "bool", title: "Enable logging", defaultValue: false
21 | }
22 |
23 | metadata {
24 | definition (name: "Tesla", namespace: "apwelsh", author: "Armand Welsh") {
25 | capability "Actuator"
26 | capability "Battery"
27 | capability "Lock"
28 | capability "MotionSensor"
29 | capability "PresenceSensor"
30 | capability "Refresh"
31 | capability "TemperatureMeasurement"
32 | capability "ThermostatMode"
33 | capability "ThermostatSetpoint"
34 |
35 | attribute "state", "string"
36 | attribute "vin", "string"
37 | attribute "odometer", "number"
38 | attribute "batteryRange", "number"
39 | attribute "chargingState", "string"
40 |
41 | attribute "latitude", "number"
42 | attribute "longitude", "number"
43 | attribute "method", "string"
44 | attribute "heading", "number"
45 | attribute "lastUpdateTime", "date"
46 | attribute "distanceAway", "number"
47 |
48 | command "wake"
49 | command "setThermostatSetpoint"
50 | command "startCharge"
51 | command "stopCharge"
52 | command "openFrontTrunk"
53 | command "openRearTrunk"
54 | }
55 |
56 | }
57 |
58 | def initialize() {
59 | if (logEnable) log.debug "Executing 'initialize'"
60 |
61 | sendEvent(name: "supportedThermostatModes", value: ["auto", "off"])
62 |
63 | runEvery15Minutes(refresh)
64 | }
65 |
66 | // parse events into attributes
67 | def parse(String description) {
68 | if (logEnable) log.debug "Parsing '${description}'"
69 | }
70 |
71 | private processData(data) {
72 | if(data) {
73 | if (logEnable) log.debug "processData: ${data}"
74 |
75 | sendEvent(name: "state", value: data.state)
76 | sendEvent(name: "motion", value: data.motion)
77 | sendEvent(name: "speed", value: data.speed, unit: "mph")
78 | sendEvent(name: "vin", value: data.vin)
79 | sendEvent(name: "thermostatMode", value: data.thermostatMode)
80 |
81 | if (data.chargeState) {
82 | sendEvent(name: "battery", value: data.chargeState.battery)
83 | sendEvent(name: "batteryRange", value: data.chargeState.batteryRange)
84 | sendEvent(name: "chargingState", value: data.chargeState.chargingState)
85 | }
86 |
87 | if (data.driveState) {
88 | sendEvent(name: "latitude", value: data.driveState.latitude)
89 | sendEvent(name: "longitude", value: data.driveState.longitude)
90 | sendEvent(name: "method", value: data.driveState.method)
91 | sendEvent(name: "heading", value: data.driveState.heading)
92 | sendEvent(name: "lastUpdateTime", value: data.driveState.lastUpdateTime)
93 | def dist = distance(location.latitude, location.longitude, data.driveState.latitude, data.driveState.longitude)
94 | if (logEnable) log.debug "distance: ${dist}"
95 | sendEvent(name: "distanceAway", value: dist)
96 | if (!homelink) {
97 | sendEvent(name: "presence", value: (dist <= (geofence?:50) ? "present" : "not present")
98 | }
99 | }
100 |
101 | if (data.vehicleState) {
102 | sendEvent(name: "presence", value: data.vehicleState.presence)
103 | sendEvent(name: "lock", value: data.vehicleState.lock)
104 | sendEvent(name: "odometer", value: data.vehicleState.odometer)
105 | }
106 |
107 | if (data.climateState) {
108 | sendEvent(name: "temperature", value: data.climateState.temperature)
109 | sendEvent(name: "thermostatSetpoint", value: data.climateState.thermostatSetpoint)
110 | }
111 | } else {
112 | if (logEnable) log.error "No data found for ${device.deviceNetworkId}"
113 | }
114 | }
115 |
116 | def refresh() {
117 | if (logEnable) log.debug "Executing 'refresh'"
118 | def data = parent.refresh(this)
119 | processData(data)
120 | }
121 |
122 | def wake() {
123 | if (logEnable) log.debug "Executing 'wake'"
124 | def data = parent.wake(this)
125 | processData(data)
126 | runIn(30, refresh)
127 | }
128 |
129 | def lock() {
130 | if (logEnable) log.debug "Executing 'lock'"
131 | def result = parent.lock(this)
132 | if (result) { refresh() }
133 | }
134 |
135 | def unlock() {
136 | if (logEnable) log.debug "Executing 'unlock'"
137 | def result = parent.unlock(this)
138 | if (result) { refresh() }
139 | }
140 |
141 | def auto() {
142 | if (logEnable) log.debug "Executing 'auto'"
143 | def result = parent.climateAuto(this)
144 | if (result) { refresh() }
145 | }
146 |
147 | def off() {
148 | if (logEnable) log.debug "Executing 'off'"
149 | def result = parent.climateOff(this)
150 | if (result) { refresh() }
151 | }
152 |
153 | def heat() {
154 | if (logEnable) log.debug "Executing 'heat'"
155 | // Not supported
156 | }
157 |
158 | def emergencyHeat() {
159 | if (logEnable) log.debug "Executing 'emergencyHeat'"
160 | // Not supported
161 | }
162 |
163 | def cool() {
164 | if (logEnable) log.debug "Executing 'cool'"
165 | // Not supported
166 | }
167 |
168 | def setThermostatMode(mode) {
169 | if (logEnable) log.debug "Executing 'setThermostatMode'"
170 | switch (mode) {
171 | case "auto":
172 | auto()
173 | break
174 | case "off":
175 | off()
176 | break
177 | default:
178 | if (logEnable) log.error "setThermostatMode: Only thermostat modes Auto and Off are supported"
179 | }
180 | }
181 |
182 | def setThermostatSetpoint(setpoint) {
183 | if (logEnable) log.debug "Executing 'setThermostatSetpoint'"
184 | def result = parent.setThermostatSetpoint(this, setpoint)
185 | if (result) { refresh() }
186 | }
187 |
188 | def startCharge() {
189 | if (logEnable) log.debug "Executing 'startCharge'"
190 | def result = parent.startCharge(this)
191 | if (result) { refresh() }
192 | }
193 |
194 | def stopCharge() {
195 | if (logEnable) log.debug "Executing 'stopCharge'"
196 | def result = parent.stopCharge(this)
197 | if (result) { refresh() }
198 | }
199 |
200 | def openFrontTrunk() {
201 | if (logEnable) log.debug "Executing 'openFrontTrunk'"
202 | def result = parent.openTrunk(this, "front")
203 | // if (result) { refresh() }
204 | }
205 |
206 | def openRearTrunk() {
207 | if (logEnable) log.debug "Executing 'openRearTrunk'"
208 | def result = parent.openTrunk(this, "rear")
209 | // if (result) { refresh() }
210 | }
211 |
212 | def distance(lat1, lon1, lat2, lon2) {
213 | // compute horizontal distance bteween two points at sea-level, in meters
214 |
215 | final int R = 6371; // Radius of the earth (equator 6378, at poles 6357, median radius 6371)
216 |
217 | def latDistance = Math.toRadians(lat2 - lat1)
218 | def lonDistance = Math.toRadians(lon2 - lon1)
219 | def sinLat = Math.sin(latDistance/2)
220 | def sinLon = Math.sin(lonDistance/2)
221 | def a = sinLat * sinLat + Math.cos(Math.toRadians(lat1)) * Math.cos(Math.toRadians(lat2)) * sinLon * sinLon
222 | def c = 2 * Math.atan2(Math.sqrt(a), Math.sqrt(1 - a))
223 | def distance = R * c * 1000; // convert to meters
224 |
225 | return distance
226 | }
227 |
228 |
--------------------------------------------------------------------------------
/hue/packageManifest.json:
--------------------------------------------------------------------------------
1 | {
2 | "packageName": "Advanced Hue Hub Integration",
3 | "author": "Armand Welsh",
4 | "minimumHEVersion": "2.2.9",
5 | "licenseFile": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/LICENSE.md",
6 | "documentationLink": "https://github.com/apwelsh/hubitat/tree/master/hue",
7 | "communityLink": "https://community.hubitat.com/t/release-advanced-hue-bridge-integration/51420",
8 | "dateReleased": "2020-01-20",
9 | "apps": [
10 | {
11 | "id": "4ca23ce9-4e0f-4d0d-9fd2-9034376dc134",
12 | "name": "Advanced Hue Bridge Integration",
13 | "namespace": "apwelsh",
14 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/app/hue-bridge-integration.groovy",
15 | "required": true,
16 | "oauth": false,
17 | "primary": true,
18 | "version": "1.6.8"
19 | }
20 | ],
21 | "drivers": [
22 | {
23 | "id": "1d0f66d0-afed-4fe6-a2c8-39619f5b8eaa",
24 | "name": "AdvancedHueBridge",
25 | "namespace": "apwelsh",
26 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-bridge.groovy",
27 | "required": true,
28 | "version": "1.5.0"
29 | },
30 | {
31 | "id": "11de790f-60db-48f4-bda3-72fa1d3c61b9",
32 | "name": "AdvancedHueGroup",
33 | "namespace": "apwelsh",
34 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-group.groovy",
35 | "required": true,
36 | "version": "1.6.1"
37 | },
38 | {
39 | "id": "4e877c99-7537-47d9-9849-9022e75fc355",
40 | "name": "AdvancedHueLightSensor",
41 | "namespace": "apwelsh",
42 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-light-sensor.groovy",
43 | "required": false,
44 | "version": "1.0.6"
45 | },
46 | {
47 | "id": "428ff30b-152a-4e21-8daf-fa58935a018a",
48 | "name": "AdvancedHueMotionSensor",
49 | "namespace": "apwelsh",
50 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-motion-sensor.groovy",
51 | "required": false,
52 | "version": "1.0.7"
53 | },
54 | {
55 | "id": "bbf68d11-1581-40a1-9218-561899546174",
56 | "name": "AdvancedHueTemperatureSensor",
57 | "namespace": "apwelsh",
58 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-temperature-sensor.groovy",
59 | "required": false,
60 | "version": "1.0.7"
61 | },
62 | {
63 | "id": "99bc549d-ffa2-4b97-bbb3-1b18fb576a37",
64 | "name": "AdvancedHueDimmerSensor",
65 | "namespace": "apwelsh",
66 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-dimmer-sensor.groovy",
67 | "required": false,
68 | "version": "1.0.3"
69 | },
70 | {
71 | "id": "0fdebe44-6a4b-48ca-859d-480252ac8ec4",
72 | "name": "AdvancedHueTapSensor",
73 | "namespace": "apwelsh",
74 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-tap-sensor.groovy",
75 | "required": false,
76 | "version": "1.0.3"
77 | },
78 | {
79 | "id": "c7ac5c30-d728-4370-8362-ee541a92ffc5",
80 | "name": "Advanced Hue RunLessWires Sensor",
81 | "namespace": "apwelsh",
82 | "location": "https://raw.githubusercontent.com/apwelsh/hubitat/master/hue/device/advanced-hue-runlesswires-sensor.groovy",
83 | "required": false,
84 | "version": "1.0.0"
85 | }
86 | ],
87 | "version": "1.10.24",
88 | "releaseNotes": "1.10.x revision:\n1.10.24 - Fix infinite :443 appending in host URL bug.\n1.10.23 - Possible fix for host address translation logic. Possible fix for NPE when metadata is not fully updated.\n1.10.22 - added sensor capability to all non-button sendor types.\n1.10.19 - Fixed another bug in hub linking for new installs, and relinking processes. Also added additional code to hue bridge driver to better pause the hub activity when hub is unlinked.\n1.10.18 - Add additional controls to try hub unlinking in attempt to silence hub activity while in an unlinked state.\n1.10.17 - Additional bug fixes to further improve relinking hubs.\n1.10.16 - Improved support for hub discovery, and fixed a bug in hub discovery code that prevented the app from finding the hub on the network.\n1.10.15 - Added support to auto-detect when IP Address of Hub changes, and update it. This change is best implemented with a hub reboot however, it can be update pro-actively by unlinking and re-linking the hub. This change was overlaid with a V2 API update, so that the app can now convert hue XY colors to a best match to HSV. The change in color spaces is a bit wonky, due to proprietary mapping data not shared by Philips Hue, but it does currently get really close to the correct HSV values for Type C hue bulbs. \n1.10.14 - fix for lights turning off when level from Hue < 1\n1.10.13 - Simplified hub referesh and watchdog logic to improve stability.\n1.10.12 - Modified startLevelChange to turn on/off lights based on current level.\n1.10.11 - Added another enhancement to fix tracking of subscribed/unsubscribed state to further improve the watchdog timer behavior, and help the system keep the EventStream online.\n1.10.10 - Added a watchdog setting to force aggressive monitoring of dropped connections, and reworked the workflow that handles connecting/disconnecting processes to better handle the watchdog processing.\n1.10.9 - Fixed unlik hub to completely remove the hub linking details, and improved the ssdpSubscription handler\n1.10.8 - Fix ssdpDiscover scheduling causing event spamming in the events log.\n1.10.7 - fixed typo in last fix.\n1.10.6 - Fix to discovery of IP Address changes; now, unlink and relink will re-bind the hub if a new IP Address is assigned.\n1.10.5 - Fix bug from last change. \n1.10.4 - Added connection watchdog to hub device to attempt to auto-reconnect hub if disconnected.\n1.10.3 - fixed index out of bounds in log when full refresh runs.\n1.10.2 - Added support to set sensitivity on motion sensors and general support for maintaining device configs.\n1.10.1 - Fixed auto-refresh on groups. Added forced device refresh on detected light/group updates from hue event stream. Still researching soltuion for slow to update states from Hue.\n1.10.0 - removed all hub refresh calls, and rely only on the event stream to update device states. It is required that you have an updated Hue bridge to work properly, as this version relies on the new v2 API for all device updates. It is also recommended to turn on auto-refresh at the hub level only, with a very conservative refresh schedule, so as to not overload the HE hub with unnecessary hub processing.\n\n1.9.x revisions:\n1.9.8 - Skip color name computation if hub version is not version 2.3.2 or newer.\n1.9.7 - Fixed log spamming when eventStream messages do not have a Version 1 ID from Hue.\n1.9.6 - Fix type cast conversion error on line 1610.\n1.9.5 - Fix Null pointer when updating some groups lighting values.\n1.9.4 - Change minimum level reported to HE to 1, if hue device is on\n1.9.3 - Fixed scene bug to turn off active scene when group is turned off.\n1.9.2 - Fixed Hue Group handling of color / saturation changes not working on hue hub. Added support for colorName reporting. Removed redundant device info from group logging.\n1.9.1 - Fixed bug resulting in wrong temperatures reported on temp sensors.\n1.9.0 - Added RunLessWires Friends of Hue switch. (Thanks to @pocketgeek)\n1.8.x revisions:\n1.8.6 - Removed colormode state assignment, which has been removed from the Hue API, and no longer works. With this change in Hue, some non-hue lighs will no longer work in groups correctly. I do not have a fix for this Hue change.\n1.8.5 - Modified the main app to support devices w/o label defined.\n1.8.4 - Fixed errors reported in log when adding a new hue group.\n1.8.3 - Fix for default scene of group that prevents the group from turning on when scened default scene is defined. This appears to be a change in Hue hub behavior, possibly related to v2 API updates. \n1.8.2 - Update dimmer and tap devices to allow pressing the same button multiple times, without losing the press event. \n1.8.1 - Correct the Hue Tap device name so the applicaiton can correctly associate the Tap button device to the device driver."
89 | }
--------------------------------------------------------------------------------
/iopool/app/iopool-connect.groovy:
--------------------------------------------------------------------------------
1 | /**
2 | * iopool Connect
3 | * Version 1.0.1
4 | * Download: https://github.com/apwelsh/hubitat
5 | * Description:
6 | * This is an integration app for Hubitat designed to locate, and install any/all attached iopool managed devices.
7 | * The iopool application works with the iopool EcO and the pHin pool monitor. iopool support the pHin mointor for
8 | * users that bought the pHin pool monitor, and were stuck with a monitor and not support. I do not have a pHin to test
9 | * with. If you have a pHin, the data should be available via the iopool public API for use by this app. Send me a note
10 | * if you would like to use a pHin device. Huibitat does not have a bluetooth receiver. All communications in this application
11 | * use the iopool public API in the cloud. To use this app, you will need the iopool app, and possibly the gateway too.
12 | * To use this application, follow the instruction on GitHub to obtain an API key, and enter it into this application.
13 | *-------------------------------------------------------------------------------------------------------------------
14 | * Copyright 2020 Armand Peter Welsh
15 | *
16 | * Permission is hereby granted, free of charge, to any person obtaining a copy of this software and associated
17 | * documentation files (the 'Software'), to deal in the Software without restriction, including without limitation
18 | * the rights to use, copy, modify, merge, publish, distribute, sublicense, and/or sell copies of the Software,
19 | * and to permit persons to whom the Software is furnished to do so, subject to the following conditions:
20 | *
21 | * The above copyright notice and this permission notice shall be included in all copies or substantial portions of
22 | * the Software.
23 | *
24 | * THE SOFTWARE IS PROVIDED 'AS IS', WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO
25 | * THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
26 | * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF
27 | * CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
28 | * IN THE SOFTWARE.
29 | *-------------------------------------------------------------------------------------------------------------------
30 | **/
31 |
32 | definition(
33 | name: 'iopool Connect',
34 | namespace: 'apwelsh',
35 | author: 'Armand Welsh (apwelsh)',
36 | description: 'iopool Connect Integration',
37 | category: 'Convenience',
38 | //importUrl: 'https://raw.githubusercontent.com/apwelsh/hubitat/master/iopool/app/iopool-connect.groovy',
39 | iconUrl: '',
40 | iconX2Url: '',
41 | iconX3Url: ''
42 | )
43 |
44 | preferences {
45 | page(name: 'mainPage')
46 | page(name: 'addSelectedDevices')
47 | }
48 |
49 | /*
50 | * Life Cycle Functions
51 | */
52 |
53 | def installed() {
54 | initialize()
55 | }
56 |
57 | def uninstalled() {
58 | unschedule()
59 | getChildDevices().each {
60 | deleteChildDevice(it.deviceNetworkId)
61 | }
62 | }
63 |
64 | def updated() {
65 | unschedule()
66 | initialize()
67 | }
68 |
69 | def initialize() {
70 | scheduleRefresh()
71 | }
72 |
73 | /*
74 | * Application Screens
75 | */
76 |
77 | def mainPage() {
78 |
79 | if (!state && !apiKey) {
80 | return dynamicPage(name: 'mainPage', title: 'iopool Connect', uninstall: true, install: true) {
81 | section('Login') {
82 | input name: 'apiKey', type: 'string', title: 'Public API Key', description: 'Once the iopool mobile app is configure, request an API key from the company, and enter it here.'
83 | }
84 | section {
85 | paragraph 'Hit Done to to install the iopool Connect Integration.\nRe-open to setup.'
86 | }
87 | }
88 | }
89 |
90 | Map pools = findPools()
91 | Map availablePools = pools.collectEntries { it } // clone the list to create a copy
92 | List installedPools = childDevices
93 | installedPools.each { child -> availablePools.remove(child.device.deviceNetworkId) }
94 |
95 | if (selectedPools) {
96 | selectedPools?.each { dni ->
97 | log.debug "${dni} selected from [${pools}]"
98 | if (pools[dni]) {
99 | log.debug "installing child device"
100 | installedPools << addChildDevice('apwelsh', 'EcO Water Quality Sensor', "${dni}", [name: pools[dni]])
101 | availablePools.remove(dni)
102 | }
103 | }
104 | selectedPools = selectedPools?.collectMany { dni -> return availablePools[dni] ? it : [] } ?: []
105 | app.updateSetting('selectedPools', selectedPools )
106 | }
107 |
108 | return dynamicPage(name: 'mainPage', title: '', uninstall: (!installedPools), install: true) {
109 |
110 | section(getFormat('title', 'iopool Connect')) {
111 | paragraph getFormat('line')
112 | }
113 |
114 | if (availablePools) {
115 | section('Available Monitors') {
116 | input 'selectedPools', 'enum', title: 'Select Pool/Spa monitors to install', required: false, multiple: true, options: availablePools, submitOnChange: true
117 | }
118 | }
119 |
120 | if (installedPools) {
121 | section('Installed Devices') {
122 | installedPools.sort({ a, b -> a.label <=> b.label }).each { child ->
123 | def desc = child.label != child.name ? child.name : ''
124 | Boolean ena = pools[child.device.deviceNetworkId]
125 | paragraph """"""
128 |
129 | }
130 | }
131 | }
132 |
133 | section('Options') {
134 | input name: 'refreshInterval', type: 'number', defaultValue: 5, title: 'Refresh interval (minutes)'
135 | input name: 'logEnable', type: 'bool', defaultValue: true, title: 'Enable logging'
136 | }
137 |
138 | section {
139 | paragraph getFormat('line')
140 | paragraph "
iopool Connect
Please consider donating. This app took a lot of work to make. If you find it valuable, I'd certainly appreciate it!