mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-19 00:20:26 +00:00
Compare commits
12 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a091262b80 | ||
|
|
0bcc1628c8 | ||
|
|
ffd95aad87 | ||
|
|
b5e6e3ad60 | ||
|
|
611cc7be4a | ||
|
|
4b7ba0fabe | ||
|
|
6abe1b082c | ||
|
|
a9f48e1f9c | ||
|
|
8b9fd355b4 | ||
|
|
b4da321368 | ||
|
|
d118dd8523 | ||
|
|
104d341864 |
216
README.md
216
README.md
@@ -33,16 +33,23 @@ ATTENTION: This requires JDK 1.8 to run
|
||||
ATTENTION: Due to port 80 being the default, Linux restricts this to super user. Use the instructions below.
|
||||
|
||||
```
|
||||
java -jar ha-bridge-4.0.3.jar
|
||||
java -jar ha-bridge-4.1.0.jar
|
||||
```
|
||||
### Automation on Linux systems
|
||||
To have this configured and running automatically there are a few resources to use. One is using Docker and a docker container has been built for this and can be gotten here: https://github.com/aptalca/docker-ha-bridge
|
||||
|
||||
Create the directory and make sure that ha-bridge-4.0.3.jar is in your /home/pi/habridge directory.
|
||||
Create the directory and make sure that ha-bridge-4.1.0.jar is in your /home/pi/habridge directory.
|
||||
```
|
||||
pi@raspberrypi:~ $ mkdir habridge
|
||||
pi@raspberrypi:~ $ cd habridge
|
||||
pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.0.3/ha-bridge-4.0.3.jar
|
||||
|
||||
pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.1.0/ha-bridge-4.1.0.jar
|
||||
|
||||
Create the directory and make sure that ha-bridge-4.1.0.jar is in your /home/pi/habridge directory.
|
||||
```
|
||||
pi@raspberrypi:~ $ mkdir habridge
|
||||
pi@raspberrypi:~ $ cd habridge
|
||||
pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v4.1.0/ha-bridge-4.1.0.jar
|
||||
```
|
||||
#### System Control Setup on a pi (preferred)
|
||||
For next gen Linux systems (this includes the Raspberry Pi), here is a systemctl unit file that you can install. Here is a link on how to do this: https://www.digitalocean.com/community/tutorials/how-to-use-systemctl-to-manage-systemd-services-and-units
|
||||
@@ -61,7 +68,8 @@ After=network.target
|
||||
|
||||
[Service]
|
||||
Type=simple
|
||||
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.3.jar
|
||||
|
||||
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.1.0.jar
|
||||
|
||||
[Install]
|
||||
WantedBy=multi-user.target
|
||||
@@ -96,7 +104,8 @@ Then cut and past this, modify any locations that are not correct
|
||||
```
|
||||
cd /home/pi/habridge
|
||||
rm /home/pi/habridge/habridge-log.txt
|
||||
nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.0.3.jar > /home/pi/habridge/habridge-log.txt 2>&1 &
|
||||
nohup java -jar -Dconfig.file=/home/pi/habridge/data/habridge.config /home/pi/habridge/ha-bridge-4.1.0.jar > /home/pi/habridge/habridge-log.txt 2>&1 &
|
||||
|
||||
chmod 777 /home/pi/habridge/habridge-log.txt
|
||||
```
|
||||
Exit and save the file with ctrl-X and follow the prompts and then execute on the command line:
|
||||
@@ -140,6 +149,54 @@ Added the following lines to my Apache config file “000-default”
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
service apache2 restart
|
||||
### lighthttpd Example
|
||||
```
|
||||
server.modules += ( "mod_proxy" )
|
||||
proxy.server = (
|
||||
"/api" =>
|
||||
(
|
||||
( "host" => "127.0.0.1",
|
||||
"port" => "8080"
|
||||
)
|
||||
)
|
||||
)
|
||||
```
|
||||
### nginx Example
|
||||
```
|
||||
location /api/ {
|
||||
proxy_pass http://127.0.0.1:8080/api;
|
||||
}
|
||||
```
|
||||
## Run ha-bridge alongside web server already on port 80
|
||||
These examples will help you proxy your current webserver requests to the ha-bridge running on a different port, such as 8080.
|
||||
### Apache Example
|
||||
Reverse proxy with Apache on Ubuntu linux:
|
||||
|
||||
a2enmod proxy
|
||||
a2enmod proxy_http
|
||||
a2enmod headers
|
||||
|
||||
Added the following lines to my Apache config file “000-default”
|
||||
|
||||
```
|
||||
<VirtualHost *:80>
|
||||
ProxyPass /api http://localhost:8080/api nocanon
|
||||
ProxyPassReverse /api http://localhost:8080/api
|
||||
ProxyRequests Off
|
||||
AllowEncodedSlashes NoDecode
|
||||
|
||||
# Local reverse proxy authorization override
|
||||
# Most unix distribution deny proxy by default (ie /etc/apache2/mods-enabled/proxy.conf in Ubuntu)
|
||||
<Proxy http://localhost:8080/api*>
|
||||
Order deny,allow
|
||||
Allow from all
|
||||
</Proxy>
|
||||
|
||||
….. (the rest of the VirtualHost config section) …..
|
||||
</VirtualHost>
|
||||
```
|
||||
|
||||
service apache2 restart
|
||||
### lighthttpd Example
|
||||
```
|
||||
@@ -252,7 +309,40 @@ The helper tabs will also show you what you have already configured for that tar
|
||||
#### The Add/Edit Tab
|
||||
Another way to add a device is through the Manual Add Tab. This allows you to manually enter the name, the on and off URLs and select if there are custom handling with the type of call that can be made. This allows for control of anything that has a distinct request that can be executed so you are not limited to the Vera, Harmony, Nest or other Hue.
|
||||
|
||||
The format of these can be the default HTTP request which executes the URLs formatted as `http://<your stuff here>` as a GET. Other options to this are to select the HTTP Verb and add the data type and add a body that is passed with the request. Secure https is supported as well, just use `https://<your secure call here>`. When using POST and PUT, you have the ability to specify the body that will be sent with the request as well as the application type for the http call.
|
||||
There is a new format for the on/dim/off URL areas. The new editor handles the intricasies of the components, but is broken down here for explanation.
|
||||
|
||||
Here are the fields that can be put into the call item:
|
||||
Json Type | field name | What | Use
|
||||
----------|------------|------|-----
|
||||
String or JsonElement | item| This is the payload that will be called for devices | Required
|
||||
Integer | count | This is how many times this items will be executed | Optional
|
||||
Integer | delay | This is how long we will wait until the next call after | Optional
|
||||
String | type | This is the type of device we are executing | Required
|
||||
String | filterIPs | This is used filter on the IPs given in the list | Optional
|
||||
String | httpVerb | This is the http command if given, default is GET | Optional
|
||||
String | httpBody | Send this Body with a PUT or POST | Optional
|
||||
String | httpHeaders | Send these headers with the http call | Optional
|
||||
String | contentType | Define the type of content in the body | Optional
|
||||
|
||||
Example:
|
||||
```
|
||||
[{"item":<a String that is quoted or another JSON object>,"type":"<atype>"."count":X."delay":X."filterIPs":"<comma separated list of IP addresses that are valid>"."httpVerb":"<GET,PUT,POST>","httpBody":"<body info>","httpHeaders":[{"name":"header name","value":"header value"},{"name":"another header","value":"another value"}],"contentType":"<http content type i.e application/json>"},{"item":<another item>,"type":"<aType>"}]
|
||||
```
|
||||
|
||||
The format of the item can be the default HTTP request which executes the URLs formatted as `http://<your stuff here>` as a GET. Other options to this are to select the HTTP Verb and add the data type and add a body that is passed with the request. Secure https is supported as well, just use `https://<your secure call here>`. When using POST and PUT, you have the ability to specify the body that will be sent with the request as well as the application type for the http call.
|
||||
|
||||
The valid device types are: "custom", "veraDevice", "veraScene", "harmonyActivity", "harmonyButton", "nestHomeAway", "nestThermoSet", "hueDevice", "halDevice",
|
||||
"halButton", "halHome", "halThermoSet", "mqttMessage", "cmdDevice", "hassDevice", "tcpDevice", "udpDevice", "httpDevice", "domoticzDevice"
|
||||
|
||||
Filter Ip example:
|
||||
```
|
||||
Turn on Lights in Bedroom 1 (http://api.call.here/1) - Restricted to Echo 1 (10.1.1.1)
|
||||
Turn on Lights in Bedroom 2 (http://api.call.here/2) - Restricted to Echo 2 (10.2.2.2)
|
||||
Turn on Lights in Bedroom 3 (http://api.call.here/3) - Restricted to Echo 3 (10.3.3.3)
|
||||
|
||||
Device: "Lights"
|
||||
On URL: [{"item":"http://api.call.here/1", "httpVerb":"POST", "httpBody":"value1=1&value2=2","type":"httpDevice","filterIPs":"10.1.1.1"},{"item":"http://api.call.here/2", "httpVerb":"POST", "httpBody":"value1=1&value2=2","type":"httpDevice","filterIPs":"10.2.2.2"},{"item":"http://api.call.here/3", "httpVerb":"POST", "httpBody":"value1=1&value2=2","type":"httpDevice","filterIPs":"10.3.3.3"}]
|
||||
```
|
||||
|
||||
Headers can be added as well using a Json construct [{"name":"header type name","value":"the header value"}] with the format example:
|
||||
```
|
||||
@@ -262,44 +352,43 @@ Headers can be added as well using a Json construct [{"name":"header type name",
|
||||
|
||||
Another option that is detected by the bridge is to use UDP or TCP direct calls such as `udp://<ip_address>:<port>/<your stuff here>` to send a UDP request. TCP calls are handled the same way as `tcp://<ip_address>:<port>/<your stuff here>`. If your data for the UDP or TCP request is formatted as "0x00F009B9" lexical hex format, the bridge will convert the data into a binary stream to send.
|
||||
|
||||
You can also use the value replacement constructs within these statements. Such as using the expressions ${intensity.percent} for 0-100 or ${intensity.byte} for 0-255 for straight pass through of the value or items that require special calculated values using ${intensity.math()} i.e. "${intensity.math(X/4)}".
|
||||
You can also use the value replacement constructs within these statements. Such as using the expressions "${time.format(Java time format string)}" for inserting a date/time stamp, ${intensity.percent} for 0-100 or ${intensity.byte} for 0-255 for straight pass through of the value or items that require special calculated values using ${intensity.math()} i.e. "${intensity.math(X/4)}". See Value Passing Controls Below.
|
||||
Examples:
|
||||
```
|
||||
GET
|
||||
http://192.168.1.1:8180/set/this/value/${intensity.percent}
|
||||
|
||||
PUT
|
||||
http://192.168.1.1:8280/set/this
|
||||
ContentBody: {"someValue":"${intensity.byte}"}
|
||||
[{"item":"http://192.168.1.1:8180/set/this/value/${intensity.percent}","type":"httpDevice","httpVerb":"GET"}]
|
||||
|
||||
udp://192.168.1.1:5000/0x45${intensity.percent}55
|
||||
|
||||
udp://192.168.2.2:6000/fireoffthismessage\n
|
||||
[{"item":"http://192.168.1.1:8280/set/this","type":"httpDevice","httpVerb":"PUT","httpBody":{"someValue":"${intensity.byte}"}}]
|
||||
|
||||
tcp://192.168.3.3:9000/sendthismessage
|
||||
[{"item":"udp://192.168.1.1:5000/0x45${intensity.percent}55","type":"udpDevice"}]
|
||||
|
||||
tcp://192.168.4.4:10000/0x435f12dd${intensity.math((X -4)*50)}438c
|
||||
[{"item":"udp://192.168.2.2:6000/fireoffthismessage\n","type":"udpDevice"}]
|
||||
|
||||
tcp://192.168.5.5:110000/0x
|
||||
[{"item":"tcp://192.168.3.3:9000/sendthismessage","type":"tcpDevice"}]
|
||||
|
||||
[{"item":"tcp://192.168.4.4:10000/0x435f12dd${intensity.math((X -4)*50)}438c","type":"tcpDevice"}]
|
||||
|
||||
[{"item":"tcp://192.168.5.5:110000/0x","type":"tcpDevice"}]
|
||||
```
|
||||
|
||||
#### Multiple Call Construct
|
||||
Also available is the ability to specify multiple commands in the On URL, Dim URL and Off URL areas by adding Json constructs listed here. This is only for the types of tcp, udp, http, https or a new exec type. Also within the item format you can specify delay in milliseconds and count per item. These new paramters work on device buttons for the Harmony as well.
|
||||
Format Example in the URL areas:
|
||||
```
|
||||
[{"item":"http://192.168.1.1:8180/do/this/thing"},
|
||||
{"item":"http://192.168.1.1:8180/do/the/next/thing","delay":1000,"count":2},
|
||||
{"item":"http://192.168.1.1:8180/do/another/thing"}]
|
||||
[{"item":"http://192.168.1.1:8180/do/this/thing","type":"httpDevice"},
|
||||
{"item":"http://192.168.1.1:8180/do/the/next/thing","delay":1000,"count":2,"type":"httpDevice"},
|
||||
{"item":"http://192.168.1.1:8180/do/another/thing","type":"httpDevice"}]
|
||||
|
||||
|
||||
[{"item":"udp://192.168.1.1:5000/0x450555"},
|
||||
{"item":"udp://192.168.1.1:5000/0x45${intensity.percent}55"}]
|
||||
[{"item":"udp://192.168.1.1:5000/0x450555","type":"udpDevice"},
|
||||
{"item":"udp://192.168.1.1:5000/0x45${intensity.percent}55","type":"udpDevice"}]
|
||||
|
||||
[{"item":"udp://192.168.1.1:5000/0x450555"},
|
||||
{"item":"http://192.168.1.1:8180/do/this/thing"},
|
||||
{"item":"tcp://192.168.2.1/sendthisdata"},
|
||||
{"item":"https://192.168.12.1/do/this/secure/thing"},
|
||||
{"item":"exec://notepad.exe"}]
|
||||
[{"item":"udp://192.168.1.1:5000/0x450555","type":"udpDevice"},
|
||||
{"item":"http://192.168.1.1:8180/do/this/thing","type":"httpDevice"},
|
||||
{"item":"tcp://192.168.2.1/sendthisdata","type":"tcpDevice"},
|
||||
{"item":"https://192.168.12.1/do/this/secure/thing","type":"httpDevice"},
|
||||
{"item":"exec://notepad.exe","type":"cmdDevice"}]
|
||||
```
|
||||
#### Script or Command Execution
|
||||
The release as of v2.0.0 will now support the execution of a local script or program. This will blindly fire off a process to run and is bound by the privileges of the java process.
|
||||
@@ -308,20 +397,27 @@ To configure this type of manual add, you will need to select the Device type of
|
||||
|
||||
In the URL areas, the format of the execution is just providing what command line you would like to run, or using the multiple call item construct described above.
|
||||
```
|
||||
notepad.exe
|
||||
[{"item":"C:\\Users\\John\\Documents\\Applications\\putty.exe 192.168.1.1","type":"cmdDevice"},
|
||||
{"item":"notepad.exe","type":"cmdDevice"}]
|
||||
|
||||
OR
|
||||
|
||||
[{"item":"C:\\Users\\John\\Documents\\Applications\\putty.exe 192.168.1.1"},
|
||||
{"item":"notepad.exe"}]
|
||||
[{"item":"exec://notepad.exe","type":"cmdDevice"}]
|
||||
|
||||
OR
|
||||
```
|
||||
#### Value Passing Controls
|
||||
There are multiple replacement constructs available to be put into any of the calls except Harmony items, Net Items and HAL items. These constructs are: "${time.format(Java time format string)}", "${intensity.percent}", "${intensity.byte}" and "${intensity.math(using X in your calc)}".
|
||||
You can control items that require special calculated values using ${intensity.math(<your expression using "X" as the value to operate on>)} i.e. "${intensity.math(X/4)}".
|
||||
For the items that want to have a date time put into the message, utilize ${time.format(yyyy-MM-ddTHH:mm:ssXXX)} where "yyyy-MM-ddTHH:mm:ssXXX" can be any format from the Java SimpleDateFormat documented here: https://docs.oracle.com/javase/8/docs/api/java/text/SimpleDateFormat.html
|
||||
e.g.
|
||||
```
|
||||
[{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=10&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.math(X/4)}","type":"httpDevice"}]
|
||||
|
||||
/home/me/startsomething.sh
|
||||
[{"item":"udp://192.168.1.1:5000/0x45${intensity.percent}55","type":"udpDevice"}]
|
||||
|
||||
OR
|
||||
[{"item":"tcp://192.168.1.1:5000/This is the intensity real value ${intensity.byte}","type":"tcpDevice"}]
|
||||
|
||||
[{"item":"exec://notepad.exe"}]
|
||||
[{"item":{"clientId":"TestClient","topic":"Yep","message":"This is the time ${time.format(yyyy-MM-ddTHH:mm:ssXXX)}"},"type":"mqttDevice"}]
|
||||
|
||||
```
|
||||
|
||||
@@ -415,8 +511,8 @@ contentBodyOff | string | This is the content body that you would like to send w
|
||||
{
|
||||
"name" : "bedroom light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
#### Dimming Control Example
|
||||
@@ -426,8 +522,8 @@ e.g.
|
||||
{
|
||||
"name": "entry light",
|
||||
"deviceType": "switch",
|
||||
"offUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=31",
|
||||
"onUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=31&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.percent}"
|
||||
"offUrl": [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=31","type":"veraDevice"}],
|
||||
"onUrl": [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=31&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.percent}","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
See the echo's documentation for the dimming phrase.
|
||||
@@ -439,8 +535,8 @@ e.g.
|
||||
{
|
||||
"name": "Thermostat,
|
||||
"deviceType": "custom",
|
||||
"offUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=10",
|
||||
"onUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=10&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.math(X/4)}"
|
||||
"offUrl": [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=10","type":"veraDevice"}],
|
||||
"onUrl": [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=10&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.math(X/4)}","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
See the echo's documentation for the dimming phrase.
|
||||
@@ -452,12 +548,8 @@ e.g:
|
||||
{
|
||||
"name": "test device",
|
||||
"deviceType": "custom",
|
||||
"offUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=31",
|
||||
"onUrl": "http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=31&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.percent}",
|
||||
"httpVerb":"POST",
|
||||
"contentType" : "application/json",
|
||||
"contentBody" : "{\"fooBar\":\"baz_on\"}"
|
||||
"contentBodyOff" : "{\"fooBar\":\"baz_off\"}"
|
||||
"offUrl": [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=31","httpVerb":"POST","contentType" : "application/json","httpBody" : "{\"fooBar\":\"baz_off\"}],
|
||||
"onUrl": [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&DeviceNum=31&serviceId=urn:upnp-org:serviceId:Dimming1&action=SetLoadLevelTarget&newLoadlevelTarget=${intensity.percent}","type":"httpDevice","httpVerb":"POST","contentType" : "application/json","httpBody" : "{\"fooBar\":\"baz_on\"}]
|
||||
}
|
||||
```
|
||||
#### Custom Usage URLs Example
|
||||
@@ -466,8 +558,8 @@ Anything that takes an action as a result of an HTTP request will probably work
|
||||
{
|
||||
"name": "night mode",
|
||||
"deviceType": ""custom",
|
||||
"offUrl": "http://192.168.1.201:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=SetHouseMode&Mode=1",
|
||||
"onUrl": "http://192.168.1.201:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=SetHouseMode&Mode=3"
|
||||
"offUrl": [{"item":"http://192.168.1.201:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=SetHouseMode&Mode=1","type":"httpDevice"}],
|
||||
"onUrl": [{"item":"http://192.168.1.201:3480/data_request?id=lu_action&serviceId=urn:micasaverde-com:serviceId:HomeAutomationGateway1&action=SetHouseMode&Mode=3","type":"httpDevice"}]
|
||||
}
|
||||
```
|
||||
Here is a UDP example that can send binary data.
|
||||
@@ -475,8 +567,8 @@ Here is a UDP example that can send binary data.
|
||||
{
|
||||
"name": "UDPPacket",
|
||||
"deviceType": "custom",
|
||||
"offUrl": "udp://192.168.1.1:8899/0x460055",
|
||||
"onUrl": "udp://192.168.1.1:8899/0x450055"
|
||||
"offUrl": [{"item":"udp://192.168.1.1:8899/0x460055","type":"udpDevice"}],
|
||||
"onUrl": [{"item":"udp://192.168.1.1:8899/0x450055","type":"udpDevice"}]
|
||||
}
|
||||
```
|
||||
#### Response
|
||||
@@ -501,8 +593,8 @@ contentBodyOff | string | This is the content body that you would like to send w
|
||||
"id" : "12345",
|
||||
"name" : "bedroom light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
### Update a Device
|
||||
@@ -535,8 +627,8 @@ contentBodyOff | string | This is the content body that you would like to send w
|
||||
"id" : "6789",
|
||||
"name" : "table light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
#### Response
|
||||
@@ -545,8 +637,8 @@ contentBodyOff | string | This is the content body that you would like to send w
|
||||
"id" : "6789",
|
||||
"name" : "table light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
### Get All Devices
|
||||
@@ -561,15 +653,15 @@ Individual entries are the same as a single device but in json list format.
|
||||
"id" : "12345",
|
||||
"name" : "bedroom light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}
|
||||
{
|
||||
"id" : "6789",
|
||||
"name" : "table light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}]
|
||||
```
|
||||
### Get a Specific Device
|
||||
@@ -584,8 +676,8 @@ The response is the same layout as defined in the add device response.
|
||||
"id" : "6789",
|
||||
"name" : "table light",
|
||||
"deviceType" : "switch",
|
||||
"onUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41",
|
||||
"offUrl" : "http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41"
|
||||
"onUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=1&DeviceNum=41","type":"veraDevice"}],
|
||||
"offUrl" : [{"item":"http://192.168.1.201:3480/data_request?id=action&output_format=json&serviceId=urn:upnp-org:serviceId:SwitchPower1&action=SetTarget&newTargetValue=0&DeviceNum=41","type":"veraDevice"}]
|
||||
}
|
||||
```
|
||||
### Delete a Specific Device
|
||||
|
||||
4
pom.xml
4
pom.xml
@@ -5,7 +5,7 @@
|
||||
|
||||
<groupId>com.bwssystems.HABridge</groupId>
|
||||
<artifactId>ha-bridge</artifactId>
|
||||
<version>4.0.3</version>
|
||||
<version>4.1.0</version>
|
||||
<packaging>jar</packaging>
|
||||
|
||||
<name>HA Bridge</name>
|
||||
@@ -217,4 +217,4 @@
|
||||
</plugin>
|
||||
</plugins>
|
||||
</build>
|
||||
</project>
|
||||
</project>
|
||||
@@ -134,16 +134,10 @@ public class BridgeSettings extends BackupHandler {
|
||||
if(theBridgeSettings.getUpnpDeviceDb() == null)
|
||||
theBridgeSettings.setUpnpDeviceDb(Configuration.DEVICE_DB_DIRECTORY);
|
||||
|
||||
if(theBridgeSettings.getNumberoflogmessages() == null)
|
||||
if(theBridgeSettings.getNumberoflogmessages() == null || theBridgeSettings.getNumberoflogmessages() <= 0)
|
||||
theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES));
|
||||
|
||||
if(theBridgeSettings.getNumberoflogmessages() <= 0)
|
||||
theBridgeSettings.setNumberoflogmessages(new Integer(Configuration.NUMBER_OF_LOG_MESSAGES));
|
||||
|
||||
if(theBridgeSettings.getButtonsleep() == null)
|
||||
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
|
||||
|
||||
if(theBridgeSettings.getButtonsleep() < 0)
|
||||
if(theBridgeSettings.getButtonsleep() == null || theBridgeSettings.getButtonsleep() < 0)
|
||||
theBridgeSettings.setButtonsleep(Integer.parseInt(Configuration.DEFAULT_BUTTON_SLEEP));
|
||||
|
||||
theBridgeSettings.setVeraconfigured(theBridgeSettings.isValidVera());
|
||||
@@ -153,7 +147,8 @@ public class BridgeSettings extends BackupHandler {
|
||||
theBridgeSettings.setHalconfigured(theBridgeSettings.isValidHal());
|
||||
theBridgeSettings.setMqttconfigured(theBridgeSettings.isValidMQTT());
|
||||
theBridgeSettings.setHassconfigured(theBridgeSettings.isValidHass());
|
||||
if(serverPortOverride != null)
|
||||
theBridgeSettings.setDomoticzconfigured(theBridgeSettings.isValidDomoticz());
|
||||
if(serverPortOverride != null)
|
||||
theBridgeSettings.setServerPort(serverPortOverride);
|
||||
if(serverIpOverride != null)
|
||||
theBridgeSettings.setWebaddress(serverIpOverride);
|
||||
|
||||
@@ -38,6 +38,8 @@ public class BridgeSettingsDescriptor {
|
||||
private IpList hassaddress;
|
||||
private boolean hassconfigured;
|
||||
private String hubversion;
|
||||
private IpList domoticzaddress;
|
||||
private boolean domoticzconfigured;
|
||||
|
||||
public BridgeSettingsDescriptor() {
|
||||
super();
|
||||
@@ -249,6 +251,18 @@ public class BridgeSettingsDescriptor {
|
||||
public void setHubversion(String hubversion) {
|
||||
this.hubversion = hubversion;
|
||||
}
|
||||
public IpList getDomoticzaddress() {
|
||||
return domoticzaddress;
|
||||
}
|
||||
public void setDomoticzaddress(IpList domoticzaddress) {
|
||||
this.domoticzaddress = domoticzaddress;
|
||||
}
|
||||
public boolean isDomoticzconfigured() {
|
||||
return domoticzconfigured;
|
||||
}
|
||||
public void setDomoticzconfigured(boolean domoticzconfigured) {
|
||||
this.domoticzconfigured = domoticzconfigured;
|
||||
}
|
||||
public Boolean isValidVera() {
|
||||
if(this.getVeraAddress() == null || this.getVeraAddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
@@ -306,4 +320,12 @@ public class BridgeSettingsDescriptor {
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
public Boolean isValidDomoticz() {
|
||||
if(this.getDomoticzaddress() == null || this.getDomoticzaddress().getDevices().size() <= 0)
|
||||
return false;
|
||||
List<NamedIP> devicesList = this.getDomoticzaddress().getDevices();
|
||||
if(devicesList.get(0).getIp().contains(Configuration.DEFAULT_ADDRESS))
|
||||
return false;
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -25,6 +25,7 @@ public class DeviceMapTypes {
|
||||
public final static String[] UDP_DEVICE = { "udpDevice", "UDP Device"};
|
||||
public final static String[] UDP_DEVICE_COMPAT = { "UDP", "UDP Device"};
|
||||
public final static String[] HTTP_DEVICE = { "httpDevice", "HTTP Device"};
|
||||
public final static String[] DOMOTICZ_DEVICE = { "domoticzDevice", "Domoticz Device"};
|
||||
|
||||
public final static int typeIndex = 0;
|
||||
public final static int displayIndex = 1;
|
||||
@@ -35,10 +36,13 @@ public class DeviceMapTypes {
|
||||
super();
|
||||
deviceMapTypes = new ArrayList<String[]>();
|
||||
deviceMapTypes.add(CMD_DEVICE);
|
||||
deviceMapTypes.add(DOMOTICZ_DEVICE);
|
||||
deviceMapTypes.add(HAL_DEVICE);
|
||||
deviceMapTypes.add(HAL_HOME);
|
||||
deviceMapTypes.add(HAL_THERMO_SET);
|
||||
deviceMapTypes.add(HAL_BUTTON);
|
||||
deviceMapTypes.add(HARMONY_ACTIVITY);
|
||||
deviceMapTypes.add(HARMONY_BUTTON);
|
||||
deviceMapTypes.add(HASS_DEVICE);
|
||||
deviceMapTypes.add(HTTP_DEVICE);
|
||||
deviceMapTypes.add(HUE_DEVICE);
|
||||
@@ -49,8 +53,6 @@ public class DeviceMapTypes {
|
||||
deviceMapTypes.add(UDP_DEVICE);
|
||||
deviceMapTypes.add(VERA_DEVICE);
|
||||
deviceMapTypes.add(VERA_SCENE);
|
||||
deviceMapTypes.add(HARMONY_ACTIVITY);
|
||||
deviceMapTypes.add(HARMONY_BUTTON);
|
||||
}
|
||||
public static int getTypeIndex() {
|
||||
return typeIndex;
|
||||
|
||||
@@ -5,6 +5,7 @@ import java.util.Map;
|
||||
|
||||
import com.bwssystems.HABridge.devicemanagmeent.ResourceHandler;
|
||||
import com.bwssystems.HABridge.plugins.NestBridge.NestHome;
|
||||
import com.bwssystems.HABridge.plugins.domoticz.DomoticzHome;
|
||||
import com.bwssystems.HABridge.plugins.exec.CommandHome;
|
||||
import com.bwssystems.HABridge.plugins.hal.HalHome;
|
||||
import com.bwssystems.HABridge.plugins.harmony.HarmonyHome;
|
||||
@@ -69,6 +70,7 @@ public class HomeManager {
|
||||
homeList.put(DeviceMapTypes.CUSTOM_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome);
|
||||
homeList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the tcp handler Home
|
||||
aHome = new TCPHome(bridgeSettings);
|
||||
homeList.put(DeviceMapTypes.TCP_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
@@ -81,6 +83,9 @@ public class HomeManager {
|
||||
aHome = new VeraHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.VERA_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
resourceList.put(DeviceMapTypes.VERA_SCENE[DeviceMapTypes.typeIndex], aHome);
|
||||
//setup the HomeAssistant configuration if available
|
||||
aHome = new DomoticzHome(bridgeSettings);
|
||||
resourceList.put(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex], aHome);
|
||||
}
|
||||
|
||||
public Home findHome(String type) {
|
||||
|
||||
@@ -3,11 +3,20 @@ package com.bwssystems.HABridge.api.hue;
|
||||
import java.util.List;
|
||||
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class GroupResponse {
|
||||
@SerializedName("action")
|
||||
private DeviceState action;
|
||||
@SerializedName("lights")
|
||||
private String[] lights;
|
||||
@SerializedName("name")
|
||||
private String name;
|
||||
@SerializedName("type")
|
||||
private String type;
|
||||
@SerializedName("class")
|
||||
String class_name;
|
||||
|
||||
public DeviceState getAction() {
|
||||
return action;
|
||||
}
|
||||
@@ -27,7 +36,19 @@ public class GroupResponse {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public static GroupResponse createGroupResponse(List<DeviceDescriptor> deviceList) {
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
public String getClass_name() {
|
||||
return class_name;
|
||||
}
|
||||
public void setClass_name(String class_name) {
|
||||
this.class_name = class_name;
|
||||
}
|
||||
public static GroupResponse createDefaultGroupResponse(List<DeviceDescriptor> deviceList) {
|
||||
String[] theList = new String[deviceList.size()];
|
||||
int i = 0;
|
||||
for (DeviceDescriptor device : deviceList) {
|
||||
@@ -38,6 +59,23 @@ public class GroupResponse {
|
||||
theResponse.setAction(DeviceState.createDeviceState());
|
||||
theResponse.setName("Lightset 0");
|
||||
theResponse.setLights(theList);
|
||||
theResponse.setType("LightGroup");
|
||||
return theResponse;
|
||||
}
|
||||
public static GroupResponse createOtherGroupResponse(List<DeviceDescriptor> deviceList) {
|
||||
String[] theList = new String[deviceList.size()];
|
||||
int i = 0;
|
||||
for (DeviceDescriptor device : deviceList) {
|
||||
theList[i] = device.getId();
|
||||
i++;
|
||||
}
|
||||
GroupResponse theResponse = new GroupResponse();
|
||||
theResponse.setAction(DeviceState.createDeviceState());
|
||||
theResponse.setName("AGroup");
|
||||
theResponse.setLights(theList);
|
||||
theResponse.setType("Room");
|
||||
theResponse.setClass_name("Other");
|
||||
|
||||
return theResponse;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,7 +12,7 @@ import com.google.gson.JsonObject;
|
||||
public class HueApiResponse {
|
||||
private Map<String, DeviceResponse> lights;
|
||||
private Map<String, JsonObject> scenes;
|
||||
private Map<String, JsonObject> groups;
|
||||
private Map<String, GroupResponse> groups;
|
||||
private Map<String, JsonObject> schedules;
|
||||
private Map<String, JsonObject> sensors;
|
||||
private Map<String, JsonObject> rules;
|
||||
@@ -44,11 +44,11 @@ public class HueApiResponse {
|
||||
this.scenes = scenes;
|
||||
}
|
||||
|
||||
public Map<String, JsonObject> getGroups() {
|
||||
public Map<String, GroupResponse> getGroups() {
|
||||
return groups;
|
||||
}
|
||||
|
||||
public void setGroups(Map<String, JsonObject> groups) {
|
||||
public void setGroups(Map<String, GroupResponse> groups) {
|
||||
this.groups = groups;
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
package com.bwssystems.HABridge.api.hue;
|
||||
|
||||
public class HueConstants {
|
||||
public final static String HUB_VERSION = "01036562";
|
||||
public final static String HUB_VERSION = "01036659";
|
||||
public final static String API_VERSION = "1.15.0";
|
||||
public final static String MODEL_ID = "BSB002";
|
||||
public final static String UUID_PREFIX = "2f402f80-da50-11e1-9b23-";
|
||||
|
||||
@@ -56,6 +56,12 @@ public class DeviceDescriptor{
|
||||
@SerializedName("contentBodyDim")
|
||||
@Expose
|
||||
private String contentBodyDim;
|
||||
@SerializedName("inactive")
|
||||
@Expose
|
||||
private boolean inactive;
|
||||
@SerializedName("noState")
|
||||
@Expose
|
||||
private boolean noState;
|
||||
|
||||
private DeviceState deviceState;
|
||||
|
||||
@@ -197,4 +203,38 @@ public class DeviceDescriptor{
|
||||
this.deviceState = deviceState;
|
||||
}
|
||||
|
||||
}
|
||||
public boolean isInactive() {
|
||||
return inactive;
|
||||
}
|
||||
|
||||
public void setInactive(boolean inactive) {
|
||||
this.inactive = inactive;
|
||||
}
|
||||
|
||||
public boolean isNoState() {
|
||||
return noState;
|
||||
}
|
||||
|
||||
public void setNoState(boolean noState) {
|
||||
this.noState = noState;
|
||||
}
|
||||
|
||||
public boolean containsType(String aType) {
|
||||
if(this.mapType.contains(aType))
|
||||
return true;
|
||||
|
||||
if(this.deviceType.contains(aType))
|
||||
return true;
|
||||
|
||||
if(this.onUrl.contains(aType))
|
||||
return true;
|
||||
|
||||
if(this.dimUrl.contains(aType))
|
||||
return true;
|
||||
|
||||
if(this.offUrl.contains(aType))
|
||||
return true;
|
||||
|
||||
return false;
|
||||
}
|
||||
}
|
||||
@@ -74,6 +74,15 @@ public class DeviceRepository extends BackupHandler {
|
||||
return list;
|
||||
}
|
||||
|
||||
public List<DeviceDescriptor> findActive() {
|
||||
List<DeviceDescriptor> list = new ArrayList<DeviceDescriptor>();
|
||||
for(DeviceDescriptor aDevice : new ArrayList<DeviceDescriptor>(devices.values())) {
|
||||
if(!aDevice.isInactive())
|
||||
list.add(aDevice);
|
||||
}
|
||||
return list;
|
||||
}
|
||||
|
||||
public DeviceDescriptor findOne(String id) {
|
||||
return devices.get(id);
|
||||
}
|
||||
|
||||
@@ -213,6 +213,12 @@ public class DeviceResource {
|
||||
return homeManager.findResource(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.HASS_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/domoticz/devices", "application/json", (request, response) -> {
|
||||
log.debug("Get Domoticz Clients");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return homeManager.findResource(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex]).getItems(DeviceMapTypes.DOMOTICZ_DEVICE[DeviceMapTypes.typeIndex]);
|
||||
}, new JsonTransformer());
|
||||
|
||||
get (API_CONTEXT + "/map/types", "application/json", (request, response) -> {
|
||||
log.debug("Get map types");
|
||||
return new DeviceMapTypes().getDeviceMapTypes();
|
||||
|
||||
@@ -9,6 +9,7 @@ import com.bwssystems.HABridge.api.hue.DeviceResponse;
|
||||
import com.bwssystems.HABridge.api.hue.DeviceState;
|
||||
import com.bwssystems.HABridge.api.hue.GroupResponse;
|
||||
import com.bwssystems.HABridge.api.hue.HueApiResponse;
|
||||
import com.bwssystems.HABridge.api.hue.HueConfig;
|
||||
import com.bwssystems.HABridge.api.hue.HueError;
|
||||
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.api.hue.HuePublicConfig;
|
||||
@@ -73,16 +74,34 @@ public class HueMulator {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return basicListHandler("groups", request.params(":userid"), request.ip());
|
||||
});
|
||||
return groupsListHandler(request.params(":userid"), request.ip());
|
||||
} , new JsonTransformer());
|
||||
// http://ip_address:port/api/{userId}/groups/{groupId} returns json
|
||||
// object for specified group. Only 0 is supported
|
||||
get(HUE_CONTEXT + "/:userid/groups/:groupid", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return groupsListHandler(request.params(":groupid"), request.params(":userid"), request.ip());
|
||||
return groupsIdHandler(request.params(":groupid"), request.params(":userid"), request.ip());
|
||||
} , new JsonTransformer());
|
||||
// http://ip_address:port/:userid/groups CORS request
|
||||
options(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/groups
|
||||
// dummy handler
|
||||
post(HUE_CONTEXT + "/:userid/groups", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("group add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||
});
|
||||
// http://ip_address:port/api/{userId}/scenes returns json objects of
|
||||
// all scenes configured
|
||||
get(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
|
||||
@@ -91,6 +110,24 @@ public class HueMulator {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return basicListHandler("scenes", request.params(":userid"), request.ip());
|
||||
});
|
||||
// http://ip_address:port/:userid/scenes CORS request
|
||||
options(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/scenes
|
||||
// dummy handler
|
||||
post(HUE_CONTEXT + "/:userid/scenes", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("scene add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||
});
|
||||
// http://ip_address:port/api/{userId}/schedules returns json objects of
|
||||
// all schedules configured
|
||||
get(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
|
||||
@@ -99,6 +136,24 @@ public class HueMulator {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return basicListHandler("schedules", request.params(":userid"), request.ip());
|
||||
});
|
||||
// http://ip_address:port/:userid/schedules CORS request
|
||||
options(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/schedules
|
||||
// dummy handler
|
||||
post(HUE_CONTEXT + "/:userid/schedules", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("schedules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||
});
|
||||
// http://ip_address:port/api/{userId}/sensors returns json objects of
|
||||
// all sensors configured
|
||||
get(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
|
||||
@@ -107,6 +162,24 @@ public class HueMulator {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return basicListHandler("sensors", request.params(":userid"), request.ip());
|
||||
});
|
||||
// http://ip_address:port/:userid/sensors CORS request
|
||||
options(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/sensors
|
||||
// dummy handler
|
||||
post(HUE_CONTEXT + "/:userid/sensors", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("sensors add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||
});
|
||||
// http://ip_address:port/api/{userId}/rules returns json objects of all
|
||||
// rules configured
|
||||
get(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
|
||||
@@ -115,6 +188,24 @@ public class HueMulator {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return basicListHandler("rules", request.params(":userid"), request.ip());
|
||||
});
|
||||
// http://ip_address:port/:userid/rules CORS request
|
||||
options(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/rules
|
||||
// dummy handler
|
||||
post(HUE_CONTEXT + "/:userid/rules", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("rules add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||
});
|
||||
// http://ip_address:port/api/{userId}/resourcelinks returns json
|
||||
// objects of all resourcelinks configured
|
||||
get(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
|
||||
@@ -123,6 +214,24 @@ public class HueMulator {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return basicListHandler("resourcelinks", request.params(":userid"), request.ip());
|
||||
});
|
||||
// http://ip_address:port/:userid/resourcelinks CORS request
|
||||
options(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/resourcelinks
|
||||
// dummy handler
|
||||
post(HUE_CONTEXT + "/:userid/resourcelinks", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("resourcelinks add requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
return "[{\"success\":{\"id\":\"1\"}}]";
|
||||
});
|
||||
// http://ip_address:port/api/{userId}/lights returns json objects of
|
||||
// all lights configured
|
||||
get(HUE_CONTEXT + "/:userid/lights", "application/json", (request, response) -> {
|
||||
@@ -194,6 +303,28 @@ public class HueMulator {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
return getConfig(request.params(":userid"), request.ip());
|
||||
} , new JsonTransformer());
|
||||
// http://ip_address:port/:userid/config CORS request
|
||||
options(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> {
|
||||
response.status(HttpStatus.SC_OK);
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.header("Access-Control-Allow-Methods", "GET, POST, PUT");
|
||||
response.header("Access-Control-Allow-Headers", request.headers("Access-Control-Request-Headers"));
|
||||
response.header("Content-Type", "text/html");
|
||||
return "";
|
||||
});
|
||||
// http://ip_address:port/:userid/config uses json
|
||||
// object to set the config. this is to handle swupdates
|
||||
put(HUE_CONTEXT + "/:userid/config", "application/json", (request, response) -> {
|
||||
response.header("Access-Control-Allow-Origin", request.headers("Origin"));
|
||||
response.type("application/json");
|
||||
response.status(HttpStatus.SC_OK);
|
||||
log.debug("Config change requested from " + request.ip() + " user " + request.params(":userid") + " with body " + request.body());
|
||||
HueConfig aConfig = aGsonHandler.fromJson(request.body(), HueConfig.class);
|
||||
if(aConfig.getPortalservices() != null) {
|
||||
return "[{\"success\":{\"/config/portalservices\":true}}]";
|
||||
}
|
||||
return "[{\"success\":{\"/config/name\":\"My bridge\"}}]";
|
||||
});
|
||||
|
||||
// http://ip_address:port/api/{userId} returns json objects for the full
|
||||
// state
|
||||
@@ -463,7 +594,7 @@ public class HueMulator {
|
||||
}
|
||||
|
||||
if (!found) {
|
||||
log.debug("Valudate user, No User supplied");
|
||||
log.debug("Validate user, No User supplied");
|
||||
return HueErrorResponse.createResponse("1", "/api/" + aUser, "unauthorized user", null, null, null).getTheErrors();
|
||||
}
|
||||
|
||||
@@ -496,14 +627,32 @@ public class HueMulator {
|
||||
|
||||
return "{}";
|
||||
}
|
||||
private Object groupsListHandler(String userId, String requestIp) {
|
||||
log.debug("hue group list requested: " + userId + " from " + requestIp);
|
||||
HueError[] theErrors = null;
|
||||
Map<String, GroupResponse> groupResponseMap = null;
|
||||
theErrors = validateWhitelistUser(userId, false);
|
||||
if (theErrors == null) {
|
||||
groupResponseMap = new HashMap<String, GroupResponse>();
|
||||
groupResponseMap.put("1", (GroupResponse) this.groupsIdHandler("1", userId, requestIp));
|
||||
return groupResponseMap;
|
||||
}
|
||||
|
||||
private Object groupsListHandler(String groupId, String userId, String requestIp) {
|
||||
log.debug("hue group 0 list requested: " + userId + " from " + requestIp);
|
||||
return theErrors;
|
||||
}
|
||||
|
||||
|
||||
private Object groupsIdHandler(String groupId, String userId, String requestIp) {
|
||||
log.debug("hue group id: <" + groupId + "> requested: " + userId + " from " + requestIp);
|
||||
HueError[] theErrors = null;
|
||||
theErrors = validateWhitelistUser(userId, false);
|
||||
if (theErrors == null) {
|
||||
if (groupId.equalsIgnoreCase("0")) {
|
||||
GroupResponse theResponse = GroupResponse.createGroupResponse(repository.findAll());
|
||||
GroupResponse theResponse = GroupResponse.createDefaultGroupResponse(repository.findActive());
|
||||
return theResponse;
|
||||
}
|
||||
if (!groupId.equalsIgnoreCase("0")) {
|
||||
GroupResponse theResponse = GroupResponse.createOtherGroupResponse(repository.findActive());
|
||||
return theResponse;
|
||||
}
|
||||
theErrors = HueErrorResponse.createResponse("3", userId + "/groups/" + groupId, "Object not found", null, null, null).getTheErrors();
|
||||
@@ -520,7 +669,7 @@ public class HueMulator {
|
||||
log.debug("hue lights list requested: " + userId + " from " + requestIp);
|
||||
theErrors = validateWhitelistUser(userId, false);
|
||||
if (theErrors == null) {
|
||||
List<DeviceDescriptor> deviceList = repository.findAll();
|
||||
List<DeviceDescriptor> deviceList = repository.findActive();
|
||||
deviceResponseMap = new HashMap<String, DeviceResponse>();
|
||||
for (DeviceDescriptor device : deviceList) {
|
||||
DeviceResponse deviceResponse = null;
|
||||
@@ -552,7 +701,13 @@ public class HueMulator {
|
||||
log.debug("hue api user create requested: " + body + " from " + ipAddress);
|
||||
|
||||
if (body != null && !body.isEmpty()) {
|
||||
aNewUser = aGsonHandler.fromJson(body, UserCreateRequest.class);
|
||||
try {
|
||||
aNewUser = aGsonHandler.fromJson(body, UserCreateRequest.class);
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not add user. Request garbled: " + body);
|
||||
return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/",
|
||||
"Could not add user.", null, null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
newUser = aNewUser.getUsername();
|
||||
aDeviceType = aNewUser.getDevicetype();
|
||||
}
|
||||
@@ -576,7 +731,7 @@ public class HueMulator {
|
||||
log.info("Traceupnp: hue api/:userid/config config requested: " + userId + " from " + ipAddress);
|
||||
log.debug("hue api config requested: " + userId + " from " + ipAddress);
|
||||
if (validateWhitelistUser(userId, true) != null) {
|
||||
log.debug("Valudate user, No User supplied, returning public config");
|
||||
log.debug("hue api config requested, No User supplied, returning public config");
|
||||
HuePublicConfig apiResponse = HuePublicConfig.createConfig("Philips hue",
|
||||
bridgeSettings.getUpnpConfigAddress(), bridgeSettings.getHubversion());
|
||||
return apiResponse;
|
||||
@@ -597,15 +752,8 @@ public class HueMulator {
|
||||
|
||||
HueApiResponse apiResponse = new HueApiResponse("Philips hue", bridgeSettings.getUpnpConfigAddress(),
|
||||
bridgeSettings.getWhitelist(), bridgeSettings.getHubversion());
|
||||
Object aReturn = this.lightsListHandler(userId, ipAddress);
|
||||
Map<String, DeviceResponse> deviceList = new HashMap<String, DeviceResponse>();
|
||||
if(aReturn.getClass() == deviceList.getClass()) {
|
||||
deviceList = (Map<String, DeviceResponse>) aReturn;
|
||||
apiResponse.setLights(deviceList);
|
||||
}
|
||||
else {
|
||||
return aReturn;
|
||||
}
|
||||
apiResponse.setLights((Map<String, DeviceResponse>) this.lightsListHandler(userId, ipAddress));
|
||||
apiResponse.setGroups((Map<String, GroupResponse>) this.groupsListHandler(userId, ipAddress));
|
||||
|
||||
return apiResponse;
|
||||
}
|
||||
@@ -644,7 +792,11 @@ public class HueMulator {
|
||||
HueError[] theErrors = validateWhitelistUser(userId, false);
|
||||
if (theErrors != null)
|
||||
return aGsonHandler.toJson(theErrors);
|
||||
theStateChanges = aGsonHandler.fromJson(body, StateChangeBody.class);
|
||||
try {
|
||||
theStateChanges = aGsonHandler.fromJson(body, StateChangeBody.class);
|
||||
} catch (Exception e) {
|
||||
theStateChanges = null;
|
||||
}
|
||||
if (theStateChanges == null) {
|
||||
log.warn("Could not parse state change body. Light state not changed.");
|
||||
return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/lights/" + lightId,
|
||||
@@ -690,8 +842,11 @@ public class HueMulator {
|
||||
HueError[] theErrors = validateWhitelistUser(userId, false);
|
||||
if (theErrors != null)
|
||||
return aGsonHandler.toJson(theErrors);
|
||||
|
||||
theStateChanges = aGsonHandler.fromJson(body, StateChangeBody.class);
|
||||
try {
|
||||
theStateChanges = aGsonHandler.fromJson(body, StateChangeBody.class);
|
||||
} catch (Exception e) {
|
||||
theStateChanges = null;
|
||||
}
|
||||
if (theStateChanges == null) {
|
||||
log.warn("Could not parse state change body. Light state not changed.");
|
||||
return aGsonHandler.toJson(HueErrorResponse.createResponse("2", "/lights/" + lightId,
|
||||
@@ -714,8 +869,10 @@ public class HueMulator {
|
||||
}
|
||||
|
||||
state = device.getDeviceState();
|
||||
if (state == null)
|
||||
if (state == null) {
|
||||
state = DeviceState.createDeviceState();
|
||||
device.setDeviceState(state);
|
||||
}
|
||||
|
||||
if (targetBri != null || targetBriInc != null) {
|
||||
url = device.getDimUrl();
|
||||
@@ -803,8 +960,13 @@ public class HueMulator {
|
||||
}
|
||||
|
||||
if (responseString == null || !responseString.contains("[{\"error\":")) {
|
||||
responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc);
|
||||
device.setDeviceState(state);
|
||||
if(!device.isNoState()) {
|
||||
responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, state, targetBri, targetBriInc);
|
||||
device.setDeviceState(state);
|
||||
} else {
|
||||
DeviceState dummyState = DeviceState.createDeviceState();
|
||||
responseString = this.formatSuccessHueResponse(theStateChanges, body, lightId, dummyState, targetBri, targetBriInc);
|
||||
}
|
||||
}
|
||||
return responseString;
|
||||
|
||||
|
||||
38
src/main/java/com/bwssystems/HABridge/hue/TimeDecode.java
Normal file
38
src/main/java/com/bwssystems/HABridge/hue/TimeDecode.java
Normal file
@@ -0,0 +1,38 @@
|
||||
package com.bwssystems.HABridge.hue;
|
||||
|
||||
import java.text.SimpleDateFormat;
|
||||
import java.util.Date;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
public class TimeDecode {
|
||||
private static final Logger log = LoggerFactory.getLogger(TimeDecode.class);
|
||||
private static final String TIME_FORMAT = "${time.format(";
|
||||
private static final String TIME_FORMAT_CLOSE = ")}";
|
||||
|
||||
/*
|
||||
* light weight templating here, was going to use free marker but it was a
|
||||
* bit too heavy for what we were trying to do.
|
||||
*
|
||||
* currently provides: time format using Java DateTimeFormatter options
|
||||
*/
|
||||
public static String replaceTimeValue(String request) {
|
||||
if (request == null) {
|
||||
return null;
|
||||
}
|
||||
if (request.contains(TIME_FORMAT)) {
|
||||
String timeFormatDescriptor = request.substring(request.indexOf(TIME_FORMAT) + TIME_FORMAT.length(),
|
||||
request.indexOf(TIME_FORMAT_CLOSE));
|
||||
|
||||
try {
|
||||
log.debug("Time eval is: " + timeFormatDescriptor);
|
||||
SimpleDateFormat dateFormat = new SimpleDateFormat(timeFormatDescriptor);
|
||||
request = request.replace(TIME_FORMAT + timeFormatDescriptor + TIME_FORMAT_CLOSE, dateFormat.format(new Date()));
|
||||
} catch (Exception e) {
|
||||
log.warn("Could not format current time: " + timeFormatDescriptor, e);
|
||||
}
|
||||
}
|
||||
return request;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,529 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.domoticz;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class DeviceResult {
|
||||
|
||||
@SerializedName("AddjMulti")
|
||||
@Expose
|
||||
private Integer addjMulti;
|
||||
@SerializedName("AddjMulti2")
|
||||
@Expose
|
||||
private Integer addjMulti2;
|
||||
@SerializedName("AddjValue")
|
||||
@Expose
|
||||
private Integer addjValue;
|
||||
@SerializedName("AddjValue2")
|
||||
@Expose
|
||||
private Integer addjValue2;
|
||||
@SerializedName("BatteryLevel")
|
||||
@Expose
|
||||
private Integer batteryLevel;
|
||||
@SerializedName("CustomImage")
|
||||
@Expose
|
||||
private Integer customImage;
|
||||
@SerializedName("Data")
|
||||
@Expose
|
||||
private String data;
|
||||
@SerializedName("Description")
|
||||
@Expose
|
||||
private String description;
|
||||
@SerializedName("Favorite")
|
||||
@Expose
|
||||
private Integer favorite;
|
||||
@SerializedName("HardwareID")
|
||||
@Expose
|
||||
private Integer hardwareID;
|
||||
@SerializedName("HardwareName")
|
||||
@Expose
|
||||
private String hardwareName;
|
||||
@SerializedName("HardwareType")
|
||||
@Expose
|
||||
private String hardwareType;
|
||||
@SerializedName("HardwareTypeVal")
|
||||
@Expose
|
||||
private Integer hardwareTypeVal;
|
||||
@SerializedName("HaveDimmer")
|
||||
@Expose
|
||||
private Boolean haveDimmer;
|
||||
@SerializedName("HaveGroupCmd")
|
||||
@Expose
|
||||
private Boolean haveGroupCmd;
|
||||
@SerializedName("HaveTimeout")
|
||||
@Expose
|
||||
private Boolean haveTimeout;
|
||||
@SerializedName("ID")
|
||||
@Expose
|
||||
private String iD;
|
||||
@SerializedName("Image")
|
||||
@Expose
|
||||
private String image;
|
||||
@SerializedName("IsSubDevice")
|
||||
@Expose
|
||||
private Boolean isSubDevice;
|
||||
@SerializedName("LastUpdate")
|
||||
@Expose
|
||||
private String lastUpdate;
|
||||
@SerializedName("Level")
|
||||
@Expose
|
||||
private Integer level;
|
||||
@SerializedName("LevelInt")
|
||||
@Expose
|
||||
private Integer levelInt;
|
||||
@SerializedName("MaxDimLevel")
|
||||
@Expose
|
||||
private Integer maxDimLevel;
|
||||
@SerializedName("Name")
|
||||
@Expose
|
||||
private String name;
|
||||
@SerializedName("Notifications")
|
||||
@Expose
|
||||
private String notifications;
|
||||
@SerializedName("OffAction")
|
||||
@Expose
|
||||
private String offAction;
|
||||
@SerializedName("OnAction")
|
||||
@Expose
|
||||
private String onAction;
|
||||
@SerializedName("PlanID")
|
||||
@Expose
|
||||
private String planID;
|
||||
@SerializedName("PlanIDs")
|
||||
@Expose
|
||||
private List<Integer> planIDs = null;
|
||||
@SerializedName("Protected")
|
||||
@Expose
|
||||
private Boolean _protected;
|
||||
@SerializedName("ShowNotifications")
|
||||
@Expose
|
||||
private Boolean showNotifications;
|
||||
@SerializedName("SignalLevel")
|
||||
@Expose
|
||||
private String signalLevel;
|
||||
@SerializedName("Status")
|
||||
@Expose
|
||||
private String status;
|
||||
@SerializedName("StrParam1")
|
||||
@Expose
|
||||
private String strParam1;
|
||||
@SerializedName("StrParam2")
|
||||
@Expose
|
||||
private String strParam2;
|
||||
@SerializedName("SubType")
|
||||
@Expose
|
||||
private String subType;
|
||||
@SerializedName("SwitchType")
|
||||
@Expose
|
||||
private String switchType;
|
||||
@SerializedName("SwitchTypeVal")
|
||||
@Expose
|
||||
private Integer switchTypeVal;
|
||||
@SerializedName("Timers")
|
||||
@Expose
|
||||
private String timers;
|
||||
@SerializedName("Type")
|
||||
@Expose
|
||||
private String type;
|
||||
@SerializedName("TypeImg")
|
||||
@Expose
|
||||
private String typeImg;
|
||||
@SerializedName("Unit")
|
||||
@Expose
|
||||
private Integer unit;
|
||||
@SerializedName("Used")
|
||||
@Expose
|
||||
private Integer used;
|
||||
@SerializedName("UsedByCamera")
|
||||
@Expose
|
||||
private Boolean usedByCamera;
|
||||
@SerializedName("XOffset")
|
||||
@Expose
|
||||
private String xOffset;
|
||||
@SerializedName("YOffset")
|
||||
@Expose
|
||||
private String yOffset;
|
||||
@SerializedName("idx")
|
||||
@Expose
|
||||
private String idx;
|
||||
|
||||
public Integer getAddjMulti() {
|
||||
return addjMulti;
|
||||
}
|
||||
|
||||
public void setAddjMulti(Integer addjMulti) {
|
||||
this.addjMulti = addjMulti;
|
||||
}
|
||||
|
||||
public Integer getAddjMulti2() {
|
||||
return addjMulti2;
|
||||
}
|
||||
|
||||
public void setAddjMulti2(Integer addjMulti2) {
|
||||
this.addjMulti2 = addjMulti2;
|
||||
}
|
||||
|
||||
public Integer getAddjValue() {
|
||||
return addjValue;
|
||||
}
|
||||
|
||||
public void setAddjValue(Integer addjValue) {
|
||||
this.addjValue = addjValue;
|
||||
}
|
||||
|
||||
public Integer getAddjValue2() {
|
||||
return addjValue2;
|
||||
}
|
||||
|
||||
public void setAddjValue2(Integer addjValue2) {
|
||||
this.addjValue2 = addjValue2;
|
||||
}
|
||||
|
||||
public Integer getBatteryLevel() {
|
||||
return batteryLevel;
|
||||
}
|
||||
|
||||
public void setBatteryLevel(Integer batteryLevel) {
|
||||
this.batteryLevel = batteryLevel;
|
||||
}
|
||||
|
||||
public Integer getCustomImage() {
|
||||
return customImage;
|
||||
}
|
||||
|
||||
public void setCustomImage(Integer customImage) {
|
||||
this.customImage = customImage;
|
||||
}
|
||||
|
||||
public String getData() {
|
||||
return data;
|
||||
}
|
||||
|
||||
public void setData(String data) {
|
||||
this.data = data;
|
||||
}
|
||||
|
||||
public String getDescription() {
|
||||
return description;
|
||||
}
|
||||
|
||||
public void setDescription(String description) {
|
||||
this.description = description;
|
||||
}
|
||||
|
||||
public Integer getFavorite() {
|
||||
return favorite;
|
||||
}
|
||||
|
||||
public void setFavorite(Integer favorite) {
|
||||
this.favorite = favorite;
|
||||
}
|
||||
|
||||
public Integer getHardwareID() {
|
||||
return hardwareID;
|
||||
}
|
||||
|
||||
public void setHardwareID(Integer hardwareID) {
|
||||
this.hardwareID = hardwareID;
|
||||
}
|
||||
|
||||
public String getHardwareName() {
|
||||
return hardwareName;
|
||||
}
|
||||
|
||||
public void setHardwareName(String hardwareName) {
|
||||
this.hardwareName = hardwareName;
|
||||
}
|
||||
|
||||
public String getHardwareType() {
|
||||
return hardwareType;
|
||||
}
|
||||
|
||||
public void setHardwareType(String hardwareType) {
|
||||
this.hardwareType = hardwareType;
|
||||
}
|
||||
|
||||
public Integer getHardwareTypeVal() {
|
||||
return hardwareTypeVal;
|
||||
}
|
||||
|
||||
public void setHardwareTypeVal(Integer hardwareTypeVal) {
|
||||
this.hardwareTypeVal = hardwareTypeVal;
|
||||
}
|
||||
|
||||
public Boolean getHaveDimmer() {
|
||||
return haveDimmer;
|
||||
}
|
||||
|
||||
public void setHaveDimmer(Boolean haveDimmer) {
|
||||
this.haveDimmer = haveDimmer;
|
||||
}
|
||||
|
||||
public Boolean getHaveGroupCmd() {
|
||||
return haveGroupCmd;
|
||||
}
|
||||
|
||||
public void setHaveGroupCmd(Boolean haveGroupCmd) {
|
||||
this.haveGroupCmd = haveGroupCmd;
|
||||
}
|
||||
|
||||
public Boolean getHaveTimeout() {
|
||||
return haveTimeout;
|
||||
}
|
||||
|
||||
public void setHaveTimeout(Boolean haveTimeout) {
|
||||
this.haveTimeout = haveTimeout;
|
||||
}
|
||||
|
||||
public String getID() {
|
||||
return iD;
|
||||
}
|
||||
|
||||
public void setID(String iD) {
|
||||
this.iD = iD;
|
||||
}
|
||||
|
||||
public String getImage() {
|
||||
return image;
|
||||
}
|
||||
|
||||
public void setImage(String image) {
|
||||
this.image = image;
|
||||
}
|
||||
|
||||
public Boolean getIsSubDevice() {
|
||||
return isSubDevice;
|
||||
}
|
||||
|
||||
public void setIsSubDevice(Boolean isSubDevice) {
|
||||
this.isSubDevice = isSubDevice;
|
||||
}
|
||||
|
||||
public String getLastUpdate() {
|
||||
return lastUpdate;
|
||||
}
|
||||
|
||||
public void setLastUpdate(String lastUpdate) {
|
||||
this.lastUpdate = lastUpdate;
|
||||
}
|
||||
|
||||
public Integer getLevel() {
|
||||
return level;
|
||||
}
|
||||
|
||||
public void setLevel(Integer level) {
|
||||
this.level = level;
|
||||
}
|
||||
|
||||
public Integer getLevelInt() {
|
||||
return levelInt;
|
||||
}
|
||||
|
||||
public void setLevelInt(Integer levelInt) {
|
||||
this.levelInt = levelInt;
|
||||
}
|
||||
|
||||
public Integer getMaxDimLevel() {
|
||||
return maxDimLevel;
|
||||
}
|
||||
|
||||
public void setMaxDimLevel(Integer maxDimLevel) {
|
||||
this.maxDimLevel = maxDimLevel;
|
||||
}
|
||||
|
||||
public String getName() {
|
||||
return name;
|
||||
}
|
||||
|
||||
public void setName(String name) {
|
||||
this.name = name;
|
||||
}
|
||||
|
||||
public String getNotifications() {
|
||||
return notifications;
|
||||
}
|
||||
|
||||
public void setNotifications(String notifications) {
|
||||
this.notifications = notifications;
|
||||
}
|
||||
|
||||
|
||||
public String getOffAction() {
|
||||
return offAction;
|
||||
}
|
||||
|
||||
public void setOffAction(String offAction) {
|
||||
this.offAction = offAction;
|
||||
}
|
||||
|
||||
public String getOnAction() {
|
||||
return onAction;
|
||||
}
|
||||
|
||||
public void setOnAction(String onAction) {
|
||||
this.onAction = onAction;
|
||||
}
|
||||
|
||||
public String getPlanID() {
|
||||
return planID;
|
||||
}
|
||||
|
||||
public void setPlanID(String planID) {
|
||||
this.planID = planID;
|
||||
}
|
||||
|
||||
public List<Integer> getPlanIDs() {
|
||||
return planIDs;
|
||||
}
|
||||
|
||||
public void setPlanIDs(List<Integer> planIDs) {
|
||||
this.planIDs = planIDs;
|
||||
}
|
||||
|
||||
public Boolean getProtected() {
|
||||
return _protected;
|
||||
}
|
||||
|
||||
public void setProtected(Boolean _protected) {
|
||||
this._protected = _protected;
|
||||
}
|
||||
|
||||
public Boolean getShowNotifications() {
|
||||
return showNotifications;
|
||||
}
|
||||
|
||||
public void setShowNotifications(Boolean showNotifications) {
|
||||
this.showNotifications = showNotifications;
|
||||
}
|
||||
|
||||
public String getSignalLevel() {
|
||||
return signalLevel;
|
||||
}
|
||||
|
||||
public void setSignalLevel(String signalLevel) {
|
||||
this.signalLevel = signalLevel;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getStrParam1() {
|
||||
return strParam1;
|
||||
}
|
||||
|
||||
public void setStrParam1(String strParam1) {
|
||||
this.strParam1 = strParam1;
|
||||
}
|
||||
|
||||
public String getStrParam2() {
|
||||
return strParam2;
|
||||
}
|
||||
|
||||
public void setStrParam2(String strParam2) {
|
||||
this.strParam2 = strParam2;
|
||||
}
|
||||
|
||||
public String getSubType() {
|
||||
return subType;
|
||||
}
|
||||
|
||||
public void setSubType(String subType) {
|
||||
this.subType = subType;
|
||||
}
|
||||
|
||||
public String getSwitchType() {
|
||||
return switchType;
|
||||
}
|
||||
|
||||
public void setSwitchType(String switchType) {
|
||||
this.switchType = switchType;
|
||||
}
|
||||
|
||||
public Integer getSwitchTypeVal() {
|
||||
return switchTypeVal;
|
||||
}
|
||||
|
||||
public void setSwitchTypeVal(Integer switchTypeVal) {
|
||||
this.switchTypeVal = switchTypeVal;
|
||||
}
|
||||
|
||||
public String getTimers() {
|
||||
return timers;
|
||||
}
|
||||
|
||||
public void setTimers(String timers) {
|
||||
this.timers = timers;
|
||||
}
|
||||
|
||||
public String getType() {
|
||||
return type;
|
||||
}
|
||||
|
||||
public void setType(String type) {
|
||||
this.type = type;
|
||||
}
|
||||
|
||||
public String getTypeImg() {
|
||||
return typeImg;
|
||||
}
|
||||
|
||||
public void setTypeImg(String typeImg) {
|
||||
this.typeImg = typeImg;
|
||||
}
|
||||
|
||||
public Integer getUnit() {
|
||||
return unit;
|
||||
}
|
||||
|
||||
public void setUnit(Integer unit) {
|
||||
this.unit = unit;
|
||||
}
|
||||
|
||||
public Integer getUsed() {
|
||||
return used;
|
||||
}
|
||||
|
||||
public void setUsed(Integer used) {
|
||||
this.used = used;
|
||||
}
|
||||
|
||||
public Boolean getUsedByCamera() {
|
||||
return usedByCamera;
|
||||
}
|
||||
|
||||
public void setUsedByCamera(Boolean usedByCamera) {
|
||||
this.usedByCamera = usedByCamera;
|
||||
}
|
||||
|
||||
public String getXOffset() {
|
||||
return xOffset;
|
||||
}
|
||||
|
||||
public void setXOffset(String xOffset) {
|
||||
this.xOffset = xOffset;
|
||||
}
|
||||
|
||||
public String getYOffset() {
|
||||
return yOffset;
|
||||
}
|
||||
|
||||
public void setYOffset(String yOffset) {
|
||||
this.yOffset = yOffset;
|
||||
}
|
||||
|
||||
public String getIdx() {
|
||||
return idx;
|
||||
}
|
||||
|
||||
public void setIdx(String idx) {
|
||||
this.idx = idx;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,99 @@
|
||||
|
||||
package com.bwssystems.HABridge.plugins.domoticz;
|
||||
|
||||
import java.util.List;
|
||||
import com.google.gson.annotations.Expose;
|
||||
import com.google.gson.annotations.SerializedName;
|
||||
|
||||
public class Devices {
|
||||
|
||||
@SerializedName("ActTime")
|
||||
@Expose
|
||||
private Integer actTime;
|
||||
@SerializedName("AllowWidgetOrdering")
|
||||
@Expose
|
||||
private Boolean allowWidgetOrdering;
|
||||
@SerializedName("ServerTime")
|
||||
@Expose
|
||||
private String serverTime;
|
||||
@SerializedName("Sunrise")
|
||||
@Expose
|
||||
private String sunrise;
|
||||
@SerializedName("Sunset")
|
||||
@Expose
|
||||
private String sunset;
|
||||
@SerializedName("result")
|
||||
@Expose
|
||||
private List<DeviceResult> result = null;
|
||||
@SerializedName("status")
|
||||
@Expose
|
||||
private String status;
|
||||
@SerializedName("title")
|
||||
@Expose
|
||||
private String title;
|
||||
|
||||
public Integer getActTime() {
|
||||
return actTime;
|
||||
}
|
||||
|
||||
public void setActTime(Integer actTime) {
|
||||
this.actTime = actTime;
|
||||
}
|
||||
|
||||
public Boolean getAllowWidgetOrdering() {
|
||||
return allowWidgetOrdering;
|
||||
}
|
||||
|
||||
public void setAllowWidgetOrdering(Boolean allowWidgetOrdering) {
|
||||
this.allowWidgetOrdering = allowWidgetOrdering;
|
||||
}
|
||||
|
||||
public String getServerTime() {
|
||||
return serverTime;
|
||||
}
|
||||
|
||||
public void setServerTime(String serverTime) {
|
||||
this.serverTime = serverTime;
|
||||
}
|
||||
|
||||
public String getSunrise() {
|
||||
return sunrise;
|
||||
}
|
||||
|
||||
public void setSunrise(String sunrise) {
|
||||
this.sunrise = sunrise;
|
||||
}
|
||||
|
||||
public String getSunset() {
|
||||
return sunset;
|
||||
}
|
||||
|
||||
public void setSunset(String sunset) {
|
||||
this.sunset = sunset;
|
||||
}
|
||||
|
||||
public List<DeviceResult> getResult() {
|
||||
return result;
|
||||
}
|
||||
|
||||
public void setResult(List<DeviceResult> result) {
|
||||
this.result = result;
|
||||
}
|
||||
|
||||
public String getStatus() {
|
||||
return status;
|
||||
}
|
||||
|
||||
public void setStatus(String status) {
|
||||
this.status = status;
|
||||
}
|
||||
|
||||
public String getTitle() {
|
||||
return title;
|
||||
}
|
||||
|
||||
public void setTitle(String title) {
|
||||
this.title = title;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,39 @@
|
||||
package com.bwssystems.HABridge.plugins.domoticz;
|
||||
|
||||
public class DomoticzDevice {
|
||||
private String devicetype;
|
||||
private String devicename;
|
||||
private String idx;
|
||||
private String domoticzaddress;
|
||||
private String domoticzname;
|
||||
public String getDevicetype() {
|
||||
return devicetype;
|
||||
}
|
||||
public void setDevicetype(String devicetype) {
|
||||
this.devicetype = devicetype;
|
||||
}
|
||||
public String getDevicename() {
|
||||
return devicename;
|
||||
}
|
||||
public void setDevicename(String devicename) {
|
||||
this.devicename = devicename;
|
||||
}
|
||||
public String getIdx() {
|
||||
return idx;
|
||||
}
|
||||
public void setIdx(String idx) {
|
||||
this.idx = idx;
|
||||
}
|
||||
public String getDomoticzaddress() {
|
||||
return domoticzaddress;
|
||||
}
|
||||
public void setDomoticzaddress(String domoticzaddress) {
|
||||
this.domoticzaddress = domoticzaddress;
|
||||
}
|
||||
public String getDomoticzname() {
|
||||
return domoticzname;
|
||||
}
|
||||
public void setDomoticzname(String domoticzname) {
|
||||
this.domoticzname = domoticzname;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,81 @@
|
||||
package com.bwssystems.HABridge.plugins.domoticz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class DomoticzHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(DomoticzHandler.class);
|
||||
private static final String GET_REQUEST = "/json.htm?type=";
|
||||
private static final String DEVICES_TYPE = "devices";
|
||||
private static final String SCENES_TYPE = "scenes";
|
||||
private static final String FILTER_USED = "&used=";
|
||||
private HTTPHandler httpClient;
|
||||
private NamedIP domoticzAddress;
|
||||
|
||||
public DomoticzHandler(NamedIP addressName) {
|
||||
super();
|
||||
httpClient = new HTTPHandler();
|
||||
domoticzAddress = addressName;
|
||||
}
|
||||
|
||||
public List<DomoticzDevice> getDevices() {
|
||||
return getDomoticzDevices(GET_REQUEST, DEVICES_TYPE, FILTER_USED);
|
||||
}
|
||||
|
||||
public List<DomoticzDevice> getScenes() {
|
||||
return getDomoticzDevices(GET_REQUEST, SCENES_TYPE, null);
|
||||
}
|
||||
|
||||
private List<DomoticzDevice> getDomoticzDevices(String rootRequest, String type, String postpend) {
|
||||
Devices theDomoticzApiResponse = null;
|
||||
List<DomoticzDevice> deviceList = null;
|
||||
|
||||
String theUrl = null;
|
||||
String theData;
|
||||
theUrl = "http://" + domoticzAddress.getIp() + ":" + domoticzAddress.getPort() + rootRequest + type;
|
||||
theData = httpClient.doHttpRequest(theUrl, null, null, null, null);
|
||||
if(theData != null) {
|
||||
log.debug("GET " + type + " DomoticzApiResponse - data: " + theData);
|
||||
theDomoticzApiResponse = new Gson().fromJson(theData, Devices.class);
|
||||
if(theDomoticzApiResponse.getResult() == null) {
|
||||
log.warn("Cannot get any devices for type " + type + " for Domoticz " + domoticzAddress.getName() + " as response is not parsable.");
|
||||
return deviceList;
|
||||
}
|
||||
deviceList = new ArrayList<DomoticzDevice>();
|
||||
|
||||
Iterator<DeviceResult> theDeviceNames = theDomoticzApiResponse.getResult().iterator();
|
||||
while(theDeviceNames.hasNext()) {
|
||||
DeviceResult theDevice = theDeviceNames.next();
|
||||
DomoticzDevice aNewDomoticzDevice = new DomoticzDevice();
|
||||
aNewDomoticzDevice.setDevicetype(theDevice.getType());
|
||||
aNewDomoticzDevice.setDevicename(theDevice.getName());
|
||||
aNewDomoticzDevice.setIdx(theDevice.getIdx());
|
||||
aNewDomoticzDevice.setDomoticzaddress(domoticzAddress.getIp() + ":" + domoticzAddress.getPort());
|
||||
aNewDomoticzDevice.setDomoticzname(domoticzAddress.getName());
|
||||
deviceList.add(aNewDomoticzDevice);
|
||||
|
||||
}
|
||||
}
|
||||
else {
|
||||
log.warn("Get Domoticz device types " + type + " for " + domoticzAddress.getName() + " - returned null, no data.");
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
public NamedIP getDomoticzAddress() {
|
||||
return domoticzAddress;
|
||||
}
|
||||
|
||||
public void setDomoticzAddress(NamedIP DomoticzAddress) {
|
||||
this.domoticzAddress = DomoticzAddress;
|
||||
}
|
||||
|
||||
}
|
||||
@@ -0,0 +1,98 @@
|
||||
package com.bwssystems.HABridge.plugins.domoticz;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashMap;
|
||||
import java.util.Iterator;
|
||||
import java.util.List;
|
||||
import java.util.Map;
|
||||
|
||||
import org.slf4j.Logger;
|
||||
import org.slf4j.LoggerFactory;
|
||||
|
||||
import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
|
||||
public class DomoticzHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(DomoticzHome.class);
|
||||
private Map<String, DomoticzHandler> domoticzs;
|
||||
private Boolean validDomoticz;
|
||||
|
||||
public DomoticzHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||
super();
|
||||
createHome(bridgeSettings);
|
||||
}
|
||||
|
||||
@Override
|
||||
public Object getItems(String type) {
|
||||
if(!validDomoticz)
|
||||
return null;
|
||||
log.debug("consolidating devices for hues");
|
||||
List<DomoticzDevice> theResponse = null;
|
||||
Iterator<String> keys = domoticzs.keySet().iterator();
|
||||
List<DomoticzDevice> deviceList = new ArrayList<DomoticzDevice>();
|
||||
while(keys.hasNext()) {
|
||||
String key = keys.next();
|
||||
theResponse = domoticzs.get(key).getDevices();
|
||||
if(theResponse != null)
|
||||
addDomoticzDevices(deviceList, theResponse, key);
|
||||
else {
|
||||
log.warn("Cannot get lights for Domoticz with name: " + key + ", skipping this Domoticz.");
|
||||
continue;
|
||||
}
|
||||
theResponse = domoticzs.get(key).getScenes();
|
||||
if(theResponse != null)
|
||||
addDomoticzDevices(deviceList, theResponse, key);
|
||||
else
|
||||
log.warn("Cannot get Scenes for Domoticz with name: " + key);
|
||||
}
|
||||
return deviceList;
|
||||
}
|
||||
|
||||
private Boolean addDomoticzDevices(List<DomoticzDevice> theDeviceList, List<DomoticzDevice> theSourceList, String theKey) {
|
||||
if(!validDomoticz)
|
||||
return null;
|
||||
Iterator<DomoticzDevice> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
DomoticzDevice theDevice = devices.next();
|
||||
theDeviceList.add(theDevice);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) {
|
||||
// Not a device handler
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
public Home createHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||
validDomoticz = bridgeSettings.isValidDomoticz();
|
||||
log.info("Domoticz Home created." + (validDomoticz ? "" : " No Domoticz devices configured."));
|
||||
if(!validDomoticz)
|
||||
return null;
|
||||
domoticzs = new HashMap<String, DomoticzHandler>();
|
||||
Iterator<NamedIP> theList = bridgeSettings.getDomoticzaddress().getDevices().iterator();
|
||||
while(theList.hasNext()) {
|
||||
NamedIP aDomoticz = theList.next();
|
||||
try {
|
||||
domoticzs.put(aDomoticz.getName(), new DomoticzHandler(aDomoticz));
|
||||
} catch (Exception e) {
|
||||
log.error("Cannot get Domoticz client (" + aDomoticz.getName() + ") setup, Exiting with message: " + e.getMessage(), e);
|
||||
return null;
|
||||
}
|
||||
}
|
||||
return this;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void closeHome() {
|
||||
// noop
|
||||
|
||||
}
|
||||
}
|
||||
@@ -11,6 +11,7 @@ import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
|
||||
public class CommandHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(CommandHome.class);
|
||||
@@ -29,20 +30,21 @@ public class CommandHome implements Home {
|
||||
intermediate = anItem.getItem().getAsString().substring(anItem.getItem().getAsString().indexOf("://") + 3);
|
||||
else
|
||||
intermediate = anItem.getItem().getAsString();
|
||||
String anError = doExecRequest(intermediate,
|
||||
BrightnessDecode.calculateIntensity(itensity, targetBri, targetBriInc), lightId);
|
||||
intermediate = BrightnessDecode.calculateReplaceIntensityValue(intermediate, itensity, targetBri, targetBriInc, false);
|
||||
intermediate = TimeDecode.replaceTimeValue(intermediate);
|
||||
String anError = doExecRequest(intermediate, lightId);
|
||||
if (anError != null) {
|
||||
responseString = anError;
|
||||
}
|
||||
return responseString;
|
||||
}
|
||||
|
||||
private String doExecRequest(String anItem, int intensity, String lightId) {
|
||||
private String doExecRequest(String anItem, String lightId) {
|
||||
log.debug("Executing request: " + anItem);
|
||||
String responseString = null;
|
||||
if (anItem != null && !anItem.equalsIgnoreCase("")) {
|
||||
try {
|
||||
Process p = Runtime.getRuntime().exec(BrightnessDecode.replaceIntensityValue(anItem, intensity, false));
|
||||
Process p = Runtime.getRuntime().exec(anItem);
|
||||
log.debug("Process running: " + p.isAlive());
|
||||
} catch (IOException e) {
|
||||
log.warn("Could not execute request: " + anItem, e);
|
||||
|
||||
@@ -13,20 +13,13 @@ import com.bwssystems.HABridge.BridgeSettingsDescriptor;
|
||||
import com.bwssystems.HABridge.Home;
|
||||
import com.bwssystems.HABridge.NamedIP;
|
||||
import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.api.NameValue;
|
||||
import com.bwssystems.HABridge.api.hue.HueError;
|
||||
import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.plugins.http.HTTPHandler;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class HalHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(HalHome.class);
|
||||
private Map<String, HalInfo> hals;
|
||||
private Boolean validHal;
|
||||
private HTTPHandler anHttpHandler;
|
||||
|
||||
public HalHome(BridgeSettingsDescriptor bridgeSettings) {
|
||||
super();
|
||||
@@ -105,39 +98,16 @@ public class HalHome implements Home {
|
||||
Iterator<HalDevice> devices = theSourceList.iterator();
|
||||
while(devices.hasNext()) {
|
||||
HalDevice theDevice = devices.next();
|
||||
HalDevice aNewHalDevice = new HalDevice();
|
||||
aNewHalDevice.setHaldevicetype(theDevice.getHaldevicetype());
|
||||
aNewHalDevice.setHaldevicename(theDevice.getHaldevicename());
|
||||
aNewHalDevice.setButtons(theDevice.getButtons());
|
||||
aNewHalDevice.setHaladdress(hals.get(theKey).getHalAddress().getIp());
|
||||
aNewHalDevice.setHalname(theKey);
|
||||
theDeviceList.add(aNewHalDevice);
|
||||
theDeviceList.add(theDevice);
|
||||
}
|
||||
anHttpHandler = new HTTPHandler();
|
||||
return true;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String deviceHandler(CallItem anItem, MultiCommandUtil aMultiUtil, String lightId, int intensity,
|
||||
Integer targetBri,Integer targetBriInc, DeviceDescriptor device, String body) {
|
||||
log.debug("executing HUE api request to HAL Http " + anItem.getItem().getAsString());
|
||||
String responseString = null;
|
||||
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
String aBody = null;
|
||||
if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty())
|
||||
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
// make call
|
||||
if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody,
|
||||
new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) {
|
||||
log.warn("Error on calling url to change device state: " + anUrl);
|
||||
responseString = new Gson().toJson(HueErrorResponse.createResponse("6", "/lights/" + lightId,
|
||||
"Error on calling url to change device state", "/lights/"
|
||||
+ lightId + "state", null, null).getTheErrors(), HueError[].class);
|
||||
}
|
||||
return responseString;
|
||||
// Not a device handler
|
||||
return null;
|
||||
}
|
||||
|
||||
@Override
|
||||
|
||||
@@ -121,6 +121,8 @@ public class HalInfo {
|
||||
HalDevice aNewHalDevice = new HalDevice();
|
||||
aNewHalDevice.setHaldevicetype(deviceType);
|
||||
aNewHalDevice.setHaldevicename(theDevice.getDeviceName());
|
||||
aNewHalDevice.setHaladdress(halAddress.getIp());
|
||||
aNewHalDevice.setHalname(halAddress.getName());
|
||||
deviceList.add(aNewHalDevice);
|
||||
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ public class HassDevice {
|
||||
private State deviceState;
|
||||
private String deviceName;
|
||||
private String domain;
|
||||
private Boolean secure;
|
||||
private String hassaddress;
|
||||
private String hassname;
|
||||
public State getDeviceState() {
|
||||
@@ -24,6 +25,12 @@ public class HassDevice {
|
||||
public void setDomain(String domain) {
|
||||
this.domain = domain;
|
||||
}
|
||||
public Boolean getSecure() {
|
||||
return secure;
|
||||
}
|
||||
public void setSecure(Boolean secure) {
|
||||
this.secure = secure;
|
||||
}
|
||||
public String getHassaddress() {
|
||||
return hassaddress;
|
||||
}
|
||||
|
||||
@@ -36,7 +36,12 @@ public class HomeAssistant {
|
||||
public Boolean callCommand(HassCommand aCommand) {
|
||||
log.debug("calling HomeAssistant: " + aCommand.getHassName() + " - "
|
||||
+ aCommand.getEntityId() + " - " + aCommand.getState() + " - " + aCommand.getBri());
|
||||
String aUrl = "http://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/services/" + aCommand.getEntityId().substring(0, aCommand.getEntityId().indexOf("."));
|
||||
String aUrl = null;
|
||||
if(hassAddress.getSecure() != null && hassAddress.getSecure())
|
||||
aUrl = "https";
|
||||
else
|
||||
aUrl = "http";
|
||||
aUrl = aUrl + "://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/services/" + aCommand.getEntityId().substring(0, aCommand.getEntityId().indexOf("."));
|
||||
String aBody = "{\"entity_id\":\"" + aCommand.getEntityId() + "\"";
|
||||
NameValue[] headers = null;
|
||||
if(hassAddress.getPassword() != null && !hassAddress.getPassword().isEmpty()) {
|
||||
@@ -75,7 +80,11 @@ public class HomeAssistant {
|
||||
headers = new NameValue[1];
|
||||
headers[0] = password;
|
||||
}
|
||||
theUrl = "http://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/states";
|
||||
if(hassAddress.getSecure() != null && hassAddress.getSecure())
|
||||
theUrl = "https";
|
||||
else
|
||||
theUrl = "http";
|
||||
theUrl = theUrl + "://" + hassAddress.getIp() + ":" + hassAddress.getPort() + "/api/states";
|
||||
theData = anHttpHandler.doHttpRequest(theUrl, HttpGet.METHOD_NAME, "application/json", null, headers);
|
||||
if(theData != null) {
|
||||
log.debug("GET Hass States - data: " + theData);
|
||||
|
||||
@@ -4,8 +4,12 @@ import java.io.IOException;
|
||||
import java.net.URI;
|
||||
import java.net.URISyntaxException;
|
||||
import java.nio.charset.Charset;
|
||||
import java.security.KeyManagementException;
|
||||
import java.security.NoSuchAlgorithmException;
|
||||
|
||||
import javax.net.ssl.SSLContext;
|
||||
import javax.net.ssl.SSLSocket;
|
||||
import javax.net.ssl.SSLSocketFactory;
|
||||
|
||||
import org.apache.http.HttpResponse;
|
||||
import org.apache.http.client.HttpClient;
|
||||
@@ -30,21 +34,22 @@ import com.bwssystems.HABridge.api.NameValue;
|
||||
public class HTTPHandler {
|
||||
private static final Logger log = LoggerFactory.getLogger(HTTPHandler.class);
|
||||
private HttpClient httpClient;
|
||||
private CloseableHttpClient httpclientSSL;
|
||||
private SSLContext sslcontext;
|
||||
private SSLConnectionSocketFactory sslsf;
|
||||
private RequestConfig globalConfig;
|
||||
// private CloseableHttpClient httpclientSSL;
|
||||
// private SSLContext sslcontext;
|
||||
// private SSLConnectionSocketFactory sslsf;
|
||||
// private RequestConfig globalConfig;
|
||||
|
||||
|
||||
public HTTPHandler() {
|
||||
httpClient = HttpClients.createDefault();
|
||||
// Removed Specific SSL as Apache HttpClient automatically uses SSL if the URI starts with https://
|
||||
// Trust own CA and all self-signed certs
|
||||
sslcontext = SSLContexts.createDefault();
|
||||
// sslcontext = SSLContexts.createDefault();
|
||||
// Allow TLSv1 protocol only
|
||||
sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLSv1,TLSv1.1,TLSv1.2" }, null,
|
||||
SSLConnectionSocketFactory.getDefaultHostnameVerifier());
|
||||
globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
|
||||
httpclientSSL = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build();
|
||||
// sslsf = new SSLConnectionSocketFactory(sslcontext, new String[] { "TLS" }, null,
|
||||
// SSLConnectionSocketFactory.getDefaultHostnameVerifier());
|
||||
// globalConfig = RequestConfig.custom().setCookieSpec(CookieSpecs.STANDARD).build();
|
||||
// httpclientSSL = HttpClients.custom().setSSLSocketFactory(sslsf).setDefaultRequestConfig(globalConfig).build();
|
||||
}
|
||||
|
||||
|
||||
@@ -96,9 +101,10 @@ public class HTTPHandler {
|
||||
}
|
||||
try {
|
||||
HttpResponse response;
|
||||
if (url.startsWith("https"))
|
||||
response = httpclientSSL.execute(request);
|
||||
else
|
||||
// Removed Specific SSL as Apache HttpClient automatically uses SSL if the URI starts with https://
|
||||
// if (url.startsWith("xyzhttps"))
|
||||
// response = httpclientSSL.execute(request);
|
||||
// else
|
||||
response = httpClient.execute(request);
|
||||
log.debug((httpVerb == null ? "GET" : httpVerb) + " execute on URL responded: "
|
||||
+ response.getStatusLine().getStatusCode());
|
||||
@@ -132,18 +138,18 @@ public class HTTPHandler {
|
||||
}
|
||||
|
||||
|
||||
public CloseableHttpClient getHttpclientSSL() {
|
||||
return httpclientSSL;
|
||||
}
|
||||
// public CloseableHttpClient getHttpclientSSL() {
|
||||
// return httpclientSSL;
|
||||
// }
|
||||
|
||||
|
||||
public void closeHandler() {
|
||||
httpClient = null;
|
||||
try {
|
||||
httpclientSSL.close();
|
||||
} catch (IOException e) {
|
||||
// noop
|
||||
}
|
||||
httpclientSSL = null;
|
||||
// try {
|
||||
// httpclientSSL.close();
|
||||
// } catch (IOException e) {
|
||||
// // noop
|
||||
// }
|
||||
// httpclientSSL = null;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -12,6 +12,7 @@ import com.bwssystems.HABridge.api.hue.HueErrorResponse;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.google.gson.Gson;
|
||||
|
||||
public class HTTPHome implements Home {
|
||||
@@ -46,10 +47,14 @@ public class HTTPHome implements Home {
|
||||
|
||||
String anUrl = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
|
||||
anUrl = TimeDecode.replaceTimeValue(anUrl);
|
||||
String aBody = null;
|
||||
if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty())
|
||||
if(anItem.getHttpBody()!= null && !anItem.getHttpBody().isEmpty()) {
|
||||
aBody = BrightnessDecode.calculateReplaceIntensityValue(anItem.getHttpBody(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
aBody = TimeDecode.replaceTimeValue(aBody);
|
||||
}
|
||||
// make call
|
||||
if (anHttpHandler.doHttpRequest(anUrl, anItem.getHttpVerb(), anItem.getContentType(), aBody,
|
||||
new Gson().fromJson(anItem.getHttpHeaders(), NameValue[].class)) == null) {
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
@@ -81,13 +82,13 @@ public class MQTTHome implements Home {
|
||||
if (validMqtt) {
|
||||
String mqttObject = null;
|
||||
if(anItem.getItem().isJsonObject() || anItem.getItem().isJsonArray()) {
|
||||
String theItem = aGsonHandler.toJson(anItem.getItem());
|
||||
mqttObject = BrightnessDecode.calculateReplaceIntensityValue(theItem,
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
mqttObject = aGsonHandler.toJson(anItem.getItem());
|
||||
}
|
||||
else
|
||||
mqttObject = BrightnessDecode.calculateReplaceIntensityValue(anItem.getItem().getAsString(),
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
mqttObject =anItem.getItem().getAsString();
|
||||
mqttObject = BrightnessDecode.calculateReplaceIntensityValue(mqttObject,
|
||||
intensity, targetBri, targetBriInc, false);
|
||||
mqttObject = TimeDecode.replaceTimeValue(mqttObject);
|
||||
if (mqttObject.substring(0, 1).equalsIgnoreCase("{"))
|
||||
mqttObject = "[" + mqttObject + "]";
|
||||
MQTTMessage[] mqttMessages = aGsonHandler.fromJson(mqttObject, MQTTMessage[].class);
|
||||
@@ -96,18 +97,16 @@ public class MQTTHome implements Home {
|
||||
if(mqttMessages[z].getCount() != null && mqttMessages[z].getCount() > 0)
|
||||
theCount = mqttMessages[z].getCount();
|
||||
for(int y = 0; y < theCount; y++) {
|
||||
if( y > 0 || z > 0) {
|
||||
log.debug("publishing message: " + mqttMessages[y].getClientId() + " - "
|
||||
+ mqttMessages[y].getTopic() + " - " + mqttMessages[y].getMessage()
|
||||
+ " - count: " + String.valueOf(z));
|
||||
log.debug("publishing message: " + mqttMessages[y].getClientId() + " - "
|
||||
+ mqttMessages[y].getTopic() + " - " + mqttMessages[y].getMessage()
|
||||
+ " - count: " + String.valueOf(z));
|
||||
|
||||
MQTTHandler mqttHandler = getMQTTHandler(mqttMessages[y].getClientId());
|
||||
if (mqttHandler == null) {
|
||||
log.warn("Should not get here, no mqtt hanlder available");
|
||||
} else {
|
||||
mqttHandler.publishMessage(mqttMessages[y].getTopic(), mqttMessages[y].getMessage());
|
||||
}
|
||||
}
|
||||
MQTTHandler mqttHandler = getMQTTHandler(mqttMessages[y].getClientId());
|
||||
if (mqttHandler == null) {
|
||||
log.warn("Should not get here, no mqtt hanlder available");
|
||||
} else {
|
||||
mqttHandler.publishMessage(mqttMessages[y].getTopic(), mqttMessages[y].getMessage());
|
||||
}
|
||||
}
|
||||
}
|
||||
} else {
|
||||
|
||||
@@ -16,6 +16,7 @@ import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
|
||||
public class TCPHome implements Home {
|
||||
private static final Logger log = LoggerFactory.getLogger(TCPHome.class);
|
||||
@@ -48,11 +49,11 @@ public class TCPHome implements Home {
|
||||
// noop
|
||||
}
|
||||
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
|
||||
theUrlBody = TimeDecode.replaceTimeValue(theUrlBody);
|
||||
if (theUrlBody.startsWith("0x")) {
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
|
||||
sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
|
||||
} else {
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
|
||||
sendData = theUrlBody.getBytes();
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ import com.bwssystems.HABridge.api.CallItem;
|
||||
import com.bwssystems.HABridge.dao.DeviceDescriptor;
|
||||
import com.bwssystems.HABridge.hue.BrightnessDecode;
|
||||
import com.bwssystems.HABridge.hue.MultiCommandUtil;
|
||||
import com.bwssystems.HABridge.hue.TimeDecode;
|
||||
import com.bwssystems.HABridge.util.UDPDatagramSender;
|
||||
|
||||
public class UDPHome implements Home {
|
||||
@@ -46,22 +47,23 @@ public class UDPHome implements Home {
|
||||
try {
|
||||
IPAddress = InetAddress.getByName(hostAddr);
|
||||
} catch (UnknownHostException e) {
|
||||
// noop
|
||||
log.warn("Udp Call, unknown host, continuing...");
|
||||
return null;
|
||||
}
|
||||
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
|
||||
theUrlBody = TimeDecode.replaceTimeValue(theUrlBody);
|
||||
if (theUrlBody.startsWith("0x")) {
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, true);
|
||||
sendData = DatatypeConverter.parseHexBinary(theUrlBody.substring(2));
|
||||
} else {
|
||||
theUrlBody = BrightnessDecode.calculateReplaceIntensityValue(theUrlBody, intensity, targetBri, targetBriInc, false);
|
||||
sendData = theUrlBody.getBytes();
|
||||
}
|
||||
try {
|
||||
theUDPDatagramSender.sendUDPResponse(sendData, IPAddress, Integer.parseInt(port));
|
||||
} catch (NumberFormatException e) {
|
||||
// noop
|
||||
log.warn("Udp Call, Number format exception on port, continuing...");
|
||||
} catch (IOException e) {
|
||||
// noop
|
||||
log.warn("IO exception on udp call, continuing...");
|
||||
}
|
||||
return null;
|
||||
}
|
||||
|
||||
@@ -42,6 +42,9 @@ app.config (function ($locationProvider, $routeProvider) {
|
||||
}).when ('/hassdevices', {
|
||||
templateUrl: 'views/hassdevice.html',
|
||||
controller: 'HassController'
|
||||
}).when ('/domoticzdevices', {
|
||||
templateUrl: 'views/domoticzdevice.html',
|
||||
controller: 'DomoticzController'
|
||||
}).otherwise ({
|
||||
templateUrl: 'views/configuration.html',
|
||||
controller: 'ViewingController'
|
||||
@@ -68,7 +71,7 @@ String.prototype.replaceAll = function (search, replace)
|
||||
|
||||
app.service ('bridgeService', function ($http, $window, ngToast) {
|
||||
var self = this;
|
||||
this.state = {base: window.location.origin + "/api/devices", bridgelocation: window.location.origin, systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, habridgeversion: ""};
|
||||
this.state = {base: window.location.origin + "/api/devices", bridgelocation: window.location.origin, systemsbase: window.location.origin + "/system", huebase: window.location.origin + "/api", configs: [], backups: [], devices: [], device: {}, mapandid: [], type: "", settings: [], myToastMsg: [], logMsgs: [], loggerInfo: [], mapTypes: [], olddevicename: "", logShowAll: false, isInControl: false, showVera: false, showHarmony: false, showNest: false, showHue: false, showHal: false, showMqtt: false, showHass: false, showDomoticz: false, habridgeversion: ""};
|
||||
|
||||
this.displayWarn = function(errorTitle, error) {
|
||||
var toastContent = errorTitle;
|
||||
@@ -158,6 +161,25 @@ app.service ('bridgeService', function ($http, $window, ngToast) {
|
||||
return a.indexOf(b) >= 0;
|
||||
}
|
||||
|
||||
this.deviceContainsType = function (device, aType) {
|
||||
if(device.mapType !== undefined && device.mapType !== null && device.mapType.indexOf(aType) >= 0)
|
||||
return true;
|
||||
|
||||
if(device.deviceType !== undefined && device.deviceType !== null && device.deviceType.indexOf(aType) >= 0)
|
||||
return true;
|
||||
|
||||
if(device.onUrl !== undefined && device.onUrl !== null && device.onUrl.indexOf(aType) >= 0)
|
||||
return true;
|
||||
|
||||
if(device.dimUrl !== undefined && device.dimUrl !== null && device.dimUrl.indexOf(aType) >= 0)
|
||||
return true;
|
||||
|
||||
if(device.offUrl !== undefined && device.offUrl !== null && device.offUrl.indexOf(aType) >= 0)
|
||||
return true;
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
this.compareHarmonyNumber = function(r1, r2) {
|
||||
if (r1.device !== undefined) {
|
||||
if (r1.device.id === r2.device.id)
|
||||
@@ -230,6 +252,11 @@ app.service ('bridgeService', function ($http, $window, ngToast) {
|
||||
return;
|
||||
}
|
||||
|
||||
this.updateShowDomoticz = function () {
|
||||
this.state.showDomoticz = self.state.settings.domoticzconfigured;
|
||||
return;
|
||||
}
|
||||
|
||||
this.loadBridgeSettings = function () {
|
||||
return $http.get(this.state.systemsbase + "/settings").then(
|
||||
function (response) {
|
||||
@@ -241,6 +268,7 @@ app.service ('bridgeService', function ($http, $window, ngToast) {
|
||||
self.updateShowHal();
|
||||
self.updateShowMqtt();
|
||||
self.updateShowHass();
|
||||
self.updateShowDomoticz();
|
||||
},
|
||||
function (error) {
|
||||
self.displayWarn("Load Bridge Settings Error: ", error);
|
||||
@@ -409,6 +437,19 @@ app.service ('bridgeService', function ($http, $window, ngToast) {
|
||||
);
|
||||
};
|
||||
|
||||
this.viewDomoticzDevices = function () {
|
||||
if (!this.state.showDomoticz)
|
||||
return;
|
||||
return $http.get(this.state.base + "/domoticz/devices").then(
|
||||
function (response) {
|
||||
self.state.domoticzdevices = response.data;
|
||||
},
|
||||
function (error) {
|
||||
self.displayWarn("Get Domoticz Devices Error: ", error);
|
||||
}
|
||||
);
|
||||
};
|
||||
|
||||
this.formatCallItem = function (currentItem) {
|
||||
if(!currentItem.startsWith("{\"item") && !currentItem.startsWith("[{\"item")) {
|
||||
if (currentItem.startsWith("[") || currentItem.startsWith("{"))
|
||||
@@ -925,11 +966,11 @@ app.controller ('SystemController', function ($scope, $location, $http, $window,
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.addHasstoSettings = function (newhassname, newhassip, newhassport, newhasspassword) {
|
||||
$scope.addHasstoSettings = function (newhassname, newhassip, newhassport, newhasspassword, newhasssecure) {
|
||||
if($scope.bridge.settings.hassaddress === undefined || $scope.bridge.settings.hassaddress === null) {
|
||||
$scope.bridge.settings.hassaddress = { devices: [] };
|
||||
}
|
||||
var newhass = {name: newhassname, ip: newhassip, port: newhassport, password: newhasspassword }
|
||||
var newhass = {name: newhassname, ip: newhassip, port: newhassport, password: newhasspassword, secure: newhasssecure }
|
||||
$scope.bridge.settings.hassaddress.devices.push(newhass);
|
||||
$scope.newhassname = null;
|
||||
$scope.newhassip = null;
|
||||
@@ -943,6 +984,24 @@ app.controller ('SystemController', function ($scope, $location, $http, $window,
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.addDomoticztoSettings = function (newdomoticzname, newdomoticzip, newdomoticzport, newdomoticzusername, newdomoticzpassword) {
|
||||
if($scope.bridge.settings.domoticzaddress === undefined || $scope.bridge.settings.domoticzaddress === null) {
|
||||
$scope.bridge.settings.domoticzaddress = { devices: [] };
|
||||
}
|
||||
var newdomoticz = {name: newdomoticzname, ip: newdomoticzip, port: newdomoticzport, username: newdomoticzusername, password: newdomoticzpassword }
|
||||
$scope.bridge.settings.domoticzaddress.devices.push(newdomoticz);
|
||||
$scope.newdomoticzname = null;
|
||||
$scope.newdomoticzip = null;
|
||||
$scope.newdomoticzport = null;
|
||||
$scope.newdomoticzpassword = null;
|
||||
};
|
||||
$scope.removeDomoticztoSettings = function (domoticzname, domoticzip) {
|
||||
for(var i = $scope.bridge.settings.domoticzaddress.devices.length - 1; i >= 0; i--) {
|
||||
if($scope.bridge.settings.domoticzaddress.devices[i].name === domoticzname && $scope.bridge.settings.domoticzaddress.devices[i].ip === domoticzip) {
|
||||
$scope.bridge.settings.domoticzaddress.devices.splice(i, 1);
|
||||
}
|
||||
}
|
||||
};
|
||||
$scope.bridgeReinit = function () {
|
||||
bridgeService.reinit();
|
||||
};
|
||||
@@ -2085,6 +2144,157 @@ app.controller('HassController', function ($scope, $location, $http, bridgeServi
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('DomoticzController', function ($scope, $location, $http, bridgeService, ngDialog) {
|
||||
$scope.bridge = bridgeService.state;
|
||||
$scope.device = bridgeService.state.device;
|
||||
$scope.device_dim_control = "";
|
||||
$scope.bulk = { devices: [] };
|
||||
$scope.selectAll = false;
|
||||
bridgeService.viewDomoticzDevices();
|
||||
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||
$scope.buttonsVisible = false;
|
||||
|
||||
$scope.clearDevice = function () {
|
||||
bridgeService.clearDevice();
|
||||
$scope.device = bridgeService.state.device;
|
||||
};
|
||||
|
||||
$scope.buildDeviceUrls = function (domoticzdevice, dim_control) {
|
||||
var preCmd = "";
|
||||
var postOnCmd = "";
|
||||
var postDimCmd = "";
|
||||
var postOffCmd = "";
|
||||
var nameCmd = "";
|
||||
var aDeviceType;
|
||||
var postCmd = "";
|
||||
if(domoticzdevice.devicetype === "Scene") {
|
||||
aDeviceType = "scene";
|
||||
preCmd = "/json.htm?type=command¶m=switchscene&idx="
|
||||
postOnCmd = "&switchcmd=On";
|
||||
postOffCmd = "&switchcmd=Off";
|
||||
}
|
||||
else {
|
||||
aDeviceType = "switch";
|
||||
preCmd = "/json.htm?type=command¶m=switchlight&idx="
|
||||
postOnCmd = "&switchcmd=On";
|
||||
postDimCmd = "&switchcmd=Set%20Level&level=";
|
||||
postOffCmd = "&switchcmd=Off";
|
||||
}
|
||||
if((dim_control.indexOf("byte") >= 0 || dim_control.indexOf("percent") >= 0 || dim_control.indexOf("math") >= 0) && aDeviceType === "switch")
|
||||
dimpayload = "http://" + domoticzdevice.domoticzaddress
|
||||
+ preCmd
|
||||
+ domoticzdevice.idx
|
||||
+ postDimCmd
|
||||
+ dim_control;
|
||||
else
|
||||
dimpayload = null;
|
||||
onpayload = "http://" + domoticzdevice.domoticzaddress
|
||||
+ preCmd
|
||||
+ domoticzdevice.idx
|
||||
+ postOnCmd;
|
||||
offpayload = "http://" + domoticzdevice.domoticzaddress
|
||||
+ preCmd
|
||||
+ domoticzdevice.idx
|
||||
+ postOffCmd;
|
||||
bridgeService.buildUrls(onpayload, dimpayload, offpayload, false, domoticzdevice.devicename + "-" + domoticzdevice.domoticzname, domoticzdevice.devicename, domoticzdevice.domoticzname, aDeviceType, "domoticzDevice", null, null);
|
||||
$scope.device = bridgeService.state.device;
|
||||
bridgeService.editNewDevice($scope.device);
|
||||
$location.path('/editdevice');
|
||||
};
|
||||
|
||||
$scope.bulkAddDevices = function(dim_control) {
|
||||
var devicesList = [];
|
||||
for(var i = 0; i < $scope.bulk.devices.length; i++) {
|
||||
for(var x = 0; x < bridgeService.state.domoticzdevices.length; x++) {
|
||||
if(bridgeService.state.domoticzdevices[x].devicename === $scope.bulk.devices[i]) {
|
||||
$scope.buildDeviceUrls(bridgeService.state.domoticzdevices[x],dim_control);
|
||||
devicesList[i] = {
|
||||
name: $scope.device.name,
|
||||
mapId: $scope.device.mapId,
|
||||
mapType: $scope.device.mapType,
|
||||
deviceType: $scope.device.deviceType,
|
||||
targetDevice: $scope.device.targetDevice,
|
||||
onUrl: $scope.device.onUrl,
|
||||
dimUrl: $scope.device.dimUrl,
|
||||
offUrl: $scope.device.offUrl,
|
||||
headers: $scope.device.headers,
|
||||
httpVerb: $scope.device.httpVerb,
|
||||
contentType: $scope.device.contentType,
|
||||
contentBody: $scope.device.contentBody,
|
||||
contentBodyDim: $scope.device.contentBodyDim,
|
||||
contentBodyOff: $scope.device.contentBodyOff
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
bridgeService.bulkAddDevice(devicesList).then(
|
||||
function () {
|
||||
$scope.clearDevice();
|
||||
bridgeService.viewDevices();
|
||||
bridgeService.viewHalDevices();
|
||||
},
|
||||
function (error) {
|
||||
bridgeService.displayWarn("Error adding HAL devices in bulk.", error)
|
||||
}
|
||||
);
|
||||
$scope.bulk = { devices: [] };
|
||||
$scope.selectAll = false;
|
||||
};
|
||||
|
||||
$scope.toggleSelection = function toggleSelection(deviceId) {
|
||||
var idx = $scope.bulk.devices.indexOf(deviceId);
|
||||
|
||||
// is currently selected
|
||||
if (idx > -1) {
|
||||
$scope.bulk.devices.splice(idx, 1);
|
||||
if($scope.bulk.devices.length === 0 && $scope.selectAll)
|
||||
$scope.selectAll = false;
|
||||
}
|
||||
|
||||
// is newly selected
|
||||
else {
|
||||
$scope.bulk.devices.push(deviceId);
|
||||
$scope.selectAll = true;
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleSelectAll = function toggleSelectAll() {
|
||||
if($scope.selectAll) {
|
||||
$scope.selectAll = false;
|
||||
$scope.bulk = { devices: [] };
|
||||
}
|
||||
else {
|
||||
$scope.selectAll = true;
|
||||
for(var x = 0; x < bridgeService.state.haldevices.length; x++) {
|
||||
if($scope.bulk.devices.indexOf(bridgeService.state.haldevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.haldevices[x].haldevicename + "-" + bridgeService.state.haldevices[x].halname, bridgeService.state.haldevices[x].halname, "halDevice"))
|
||||
$scope.bulk.devices.push(bridgeService.state.haldevices[x].haldevicename);
|
||||
}
|
||||
}
|
||||
};
|
||||
|
||||
$scope.toggleButtons = function () {
|
||||
$scope.buttonsVisible = !$scope.buttonsVisible;
|
||||
if($scope.buttonsVisible)
|
||||
$scope.imgButtonsUrl = "glyphicon glyphicon-minus";
|
||||
else
|
||||
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||
};
|
||||
|
||||
$scope.deleteDevice = function (device) {
|
||||
$scope.bridge.device = device;
|
||||
ngDialog.open({
|
||||
template: 'deleteDialog',
|
||||
controller: 'DeleteDialogCtrl',
|
||||
className: 'ngdialog-theme-default'
|
||||
});
|
||||
};
|
||||
|
||||
$scope.editDevice = function (device) {
|
||||
bridgeService.editDevice(device);
|
||||
$location.path('/editdevice');
|
||||
};
|
||||
});
|
||||
|
||||
app.controller('EditController', function ($scope, $location, $http, bridgeService) {
|
||||
bridgeService.viewMapTypes();
|
||||
$scope.bridge = bridgeService.state;
|
||||
@@ -2147,8 +2357,10 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
|
||||
bridgeService.addDevice($scope.device).then(
|
||||
function () {
|
||||
$scope.clearDevice();
|
||||
$location.path('/');
|
||||
},
|
||||
function (error) {
|
||||
bridgeService.displayWarn("Error adding/updating device....", error);
|
||||
}
|
||||
);
|
||||
|
||||
@@ -2214,13 +2426,13 @@ app.controller('EditController', function ($scope, $location, $http, bridgeServi
|
||||
|
||||
});
|
||||
|
||||
app.filter('configuredVeraDevices', function () {
|
||||
app.filter('configuredVeraDevices', function (bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "veraDevice"){
|
||||
if(bridgeService.deviceContainsType(input[i], "veraDevice")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2228,13 +2440,13 @@ app.filter('configuredVeraDevices', function () {
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('configuredVeraScenes', function () {
|
||||
app.filter('configuredVeraScenes', function (bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "veraScene"){
|
||||
if(bridgeService.deviceContainsType(input[i], "veraScene")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2248,7 +2460,7 @@ app.filter('configuredNestItems', function (bridgeService) {
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "nest")){
|
||||
if(bridgeService.deviceContainsType(input[i], "nest")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2262,7 +2474,7 @@ app.filter('configuredHueItems', function (bridgeService) {
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hue")){
|
||||
if(bridgeService.deviceContainsType(input[i], "hue")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2276,7 +2488,7 @@ app.filter('configuredHalItems', function (bridgeService) {
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hal")){
|
||||
if(bridgeService.deviceContainsType(input[i], "hal")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2284,13 +2496,13 @@ app.filter('configuredHalItems', function (bridgeService) {
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('configuredHarmonyActivities', function () {
|
||||
app.filter('configuredHarmonyActivities', function (bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "harmonyActivity"){
|
||||
if(bridgeService.deviceContainsType(input[i], "harmonyActivity")){
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2298,13 +2510,13 @@ app.filter('configuredHarmonyActivities', function () {
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('configuredHarmonyButtons', function () {
|
||||
return function(input) {
|
||||
app.filter('configuredHarmonyButtons', function (bridgeService) {
|
||||
return function (input) {
|
||||
var out = [];
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "harmonyButtons"){
|
||||
if (bridgeService.deviceContainsType(input[i], "harmonyButton")) {
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2312,13 +2524,13 @@ app.filter('configuredHarmonyButtons', function () {
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('configuredMqttMsgs', function () {
|
||||
app.filter('configuredMqttMsgs', function (bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && input[i].mapType === "mqttMessage"){
|
||||
if (bridgeService.deviceContainsType(input[i], "mqtt")) {
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
@@ -2332,7 +2544,21 @@ app.filter('configuredHassItems', function (bridgeService) {
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if(input[i].mapType !== undefined && input[i].mapType !== null && bridgeService.aContainsB(input[i].mapType, "hass")){
|
||||
if (bridgeService.deviceContainsType(input[i], "hass")) {
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
return out;
|
||||
}
|
||||
});
|
||||
|
||||
app.filter('configuredDomoticzItems', function (bridgeService) {
|
||||
return function(input) {
|
||||
var out = [];
|
||||
if(input === undefined || input === null || input.length === undefined)
|
||||
return out;
|
||||
for (var i = 0; i < input.length; i++) {
|
||||
if (bridgeService.deviceContainsType(input[i], "domoticz")) {
|
||||
out.push(input[i]);
|
||||
}
|
||||
}
|
||||
|
||||
@@ -19,6 +19,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -41,6 +42,8 @@
|
||||
<th sortable-header col="name">Name</th>
|
||||
<th sortable-header col="deviceType">Type</th>
|
||||
<th sortable-header col="targetDevice">Target</th>
|
||||
<th sortable-header col="inactive">Inactive</th>
|
||||
<th sortable-header col="noState">No State</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -50,6 +53,8 @@
|
||||
<td>{{device.name}}</td>
|
||||
<td>{{device.deviceType}}</td>
|
||||
<td>{{device.targetDevice}}</td>
|
||||
<td>{{device.inactive}}</td>
|
||||
<td>{{device.noState}}</td>
|
||||
<td>
|
||||
<p>
|
||||
<button class="btn btn-info" type="submit"
|
||||
|
||||
140
src/main/resources/public/views/domoticzdevice.html
Normal file
140
src/main/resources/public/views/domoticzdevice.html
Normal file
@@ -0,0 +1,140 @@
|
||||
<ul class="nav nav-pills" role="tablist">
|
||||
<li role="presentation"><a href="#!/">Bridge Devices</a></li>
|
||||
<li role="presentation"><a href="#!/system">Bridge Control</a></li>
|
||||
<li role="presentation"><a href="#!/logs">Logs</a></li>
|
||||
<li ng-if="bridge.showVera" role="presentation"><a
|
||||
href="#!/veradevices">Vera Devices</a></li>
|
||||
<li ng-if="bridge.showVera" role="presentation"><a
|
||||
href="#!/verascenes">Vera Scenes</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||
href="#!/harmonyactivities">Harmony Activities</a></li>
|
||||
<li ng-if="bridge.showHarmony" role="presentation"><a
|
||||
href="#!/harmonydevices">Harmony Devices</a></li>
|
||||
<li ng-if="bridge.showNest" role="presentation"><a href="#!/nest">Nest</a></li>
|
||||
<li ng-if="bridge.showHue" role="presentation"><a
|
||||
href="#!/huedevices">Hue Devices</a></li>
|
||||
<li ng-if="bridge.showHal" role="presentation"><a href="#!/domoticzdevices">HAL
|
||||
Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">Domoticz Device List
|
||||
({{bridge.domoticzdevices.length}})</h2>
|
||||
</div>
|
||||
<div class="panel-body">
|
||||
<p class="text-muted">For any Domoticz Device, use the build action buttons
|
||||
to generate the item addition information into the ha-bridge device and this will put you into the edit screen. Then
|
||||
you can modify the name to anything you want that will be the keyword
|
||||
for the Echo or Google Home. Also, you can go back to any helper tab and click a build
|
||||
action button to add another item for a multi-command. After you are
|
||||
done in the edit tab, click the 'Add Bridge Device' to finish that selection
|
||||
setup. The 'Already Configured Domoticz Devices' list below will show what
|
||||
is already setup for your Domoticz.</p>
|
||||
<p>
|
||||
Also, use this select menu for which type of dim control you would
|
||||
like to be generated: <select name="device-dim-control"
|
||||
id="device-dim-control" ng-model="device_dim_control">
|
||||
<option value="">none</option>
|
||||
<option value="${intensity.byte}">Pass-thru Value</option>
|
||||
<option value="${intensity.percent}">Percentage</option>
|
||||
<option value="${intensity.math(X*1)}">Custom Math</option>
|
||||
</select>
|
||||
</p>
|
||||
<p>Use the check boxes by the names to use the bulk addition
|
||||
feature. Select your items and dim control type if wanted, then click
|
||||
bulk add below. Your items will be added with on and off or dim and
|
||||
off if selected with the name of the device from the Domoticz.</p>
|
||||
<scrollable-table watch="bridge.domoticzdevices">
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Row</th>
|
||||
<th sortable-header col="name">
|
||||
<span><input type="checkbox" name="selectAll"
|
||||
value="{{selectAll}}"
|
||||
ng-checked="selectAll"
|
||||
ng-click="toggleSelectAll()"> Name</span></th>
|
||||
<th sortable-header col="type">Type</th>
|
||||
<th sortable-header col="domoticzname">Domoticz</th>
|
||||
<th>Build Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="domoticzdevice in bridge.domoticzdevices">
|
||||
<td>{{$index+1}}</td>
|
||||
<td><input type="checkbox" name="bulk.devices[]"
|
||||
value="{{domoticzdevice.devicename}}"
|
||||
ng-checked="bulk.devices.indexOf(domoticzdevice.devicename) > -1"
|
||||
ng-click="toggleSelection(domoticzdevice.devicename)">
|
||||
{{domoticzdevice.devicename}}</td>
|
||||
<td>{{domoticzdevice.devicetype}}</td>
|
||||
<td>{{domoticzdevice.domoticzname}}</td>
|
||||
<td>
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="buildDeviceUrls(domoticzdevice, device_dim_control)">Build Item</button>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</scrollable-table>
|
||||
<div class="panel-footer">
|
||||
<button class="btn btn-success" type="submit"
|
||||
ng-click="bulkAddDevices(device_dim_control)">Bulk Add
|
||||
({{bulk.devices.length}})</button>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div class="panel panel-default">
|
||||
<div class="panel-heading">
|
||||
<h2 class="panel-title">
|
||||
Already Configured Domoticz Devices <a ng-click="toggleButtons()"><span
|
||||
class={{imgButtonsUrl}} aria-hidden="true"></span></a></a>
|
||||
</h2>
|
||||
</div>
|
||||
<div ng-if="buttonsVisible" class="panel-body">
|
||||
|
||||
<scrollable-table watch="bridge.domoticzdevices">
|
||||
<table class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Row</th>
|
||||
<th sortable-header col="name">Name</th>
|
||||
<th sortable-header col="category">Category</th>
|
||||
<th sortable-header col="domoticzname">Domoticz</th>
|
||||
<th>Map Id</th>
|
||||
<th>Actions</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr
|
||||
ng-repeat="device in bridge.devices | configuredDomoticzItems">
|
||||
<td>{{$index+1}}</td>
|
||||
<td>{{device.name}}</td>
|
||||
<td>{{device.deviceType}}</td>
|
||||
<td>{{device.targetDevice}}</td>
|
||||
<td>{{device.mapId}}</td>
|
||||
<td>
|
||||
<p>
|
||||
<button class="btn btn-warning" type="submit"
|
||||
ng-click="editDevice(device)">Edit</button>
|
||||
<button class="btn btn-danger" type="submit"
|
||||
ng-click="deleteDevice(device)">Delete</button>
|
||||
</p>
|
||||
</td>
|
||||
</tr>
|
||||
</table>
|
||||
</scrollable-table>
|
||||
</div>
|
||||
</div>
|
||||
<script type="text/ng-template" id="deleteMapandIdDialog">
|
||||
<div class="ngdialog-message">
|
||||
<h2>Device Map and Id?</h2>
|
||||
<p>{{mapandid.mapType}} with {{mapandid.id}}</p>
|
||||
<p>Are you Sure?</p>
|
||||
</div>
|
||||
<div class="ngdialog-buttons mt">
|
||||
<button type="button" class="ngdialog-button ngdialog-button-error" ng-click="deleteMapandId(mapandid)">Delete</button>
|
||||
</div>
|
||||
</script>
|
||||
@@ -19,6 +19,7 @@
|
||||
href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a
|
||||
href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -62,6 +63,18 @@
|
||||
<td><input type="text" class="form-control" id="device-name"
|
||||
ng-model="device.name" placeholder="Device Name"></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Inactive</td>
|
||||
<td><input type="checkbox"
|
||||
ng-model="device.inactive" ng-true-value=true
|
||||
ng-false-value=false> {{device.inactive}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>No State (Do not update state for device)</td>
|
||||
<td><input type="checkbox"
|
||||
ng-model="device.noState" ng-true-value=true
|
||||
ng-false-value=false> {{device.noState}}</td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><label>Target</label></td>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -16,8 +16,8 @@
|
||||
<li ng-if="bridge.showHal" role="presentation" class="active"><a href="#!/haldevices">HAL
|
||||
Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li role="presentation" class="active"><a href="#!/hassdevices">HomeAssistant
|
||||
Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -11,6 +11,7 @@
|
||||
<li ng-if="bridge.showHal" role="presentation"><a href="#!/haldevices">HAL Devices</a></li>
|
||||
<li role="presentation" class="active"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -18,6 +18,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
@@ -276,6 +277,7 @@
|
||||
<th>IP</th>
|
||||
<th>Port</th>
|
||||
<th>Password (opt)</th>
|
||||
<th>Use SSL</th>
|
||||
<th>Manage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
@@ -285,6 +287,7 @@
|
||||
<td>{{hass.port}}</td>
|
||||
<td ng-if="hass.password">*******</td>
|
||||
<td ng-if="!hass.password"> </td>
|
||||
<td>{{hass.secure}}</td>
|
||||
<td><button class="btn btn-danger" type="submit"
|
||||
ng-click="removeHasstoSettings(hass.name, hass.ip)">Del</button></td>
|
||||
</tr>
|
||||
@@ -301,8 +304,56 @@
|
||||
<td><input id="bridge-settings-next-hass-password"
|
||||
class="form-control" type="password" ng-model="newhasspassword"
|
||||
placeholder="Home Assistant password (opt)"></td>
|
||||
<td><input type="checkbox"
|
||||
ng-model="newhasssecure" ng-true-value=true
|
||||
ng-false-value=false></td>
|
||||
<td><button class="btn btn-success" type="submit"
|
||||
ng-click="addHasstoSettings(newhassname, newhassip, newhassport, newhasspassword)">Add</button></td>
|
||||
ng-click="addHasstoSettings(newhassname, newhassip, newhassport, newhasspassword, newhasssecure)">Add</button></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td>Domoticz Names and IP Addresses</td>
|
||||
<td><table
|
||||
class="table table-bordered table-striped table-hover">
|
||||
<thead>
|
||||
<tr>
|
||||
<th>Name</th>
|
||||
<th>IP</th>
|
||||
<th>Port</th>
|
||||
<th>Username (opt)</th>
|
||||
<th>Password (opt)</th>
|
||||
<th>Manage</th>
|
||||
</tr>
|
||||
</thead>
|
||||
<tr ng-repeat="domoticz in bridge.settings.domoticzaddress.devices">
|
||||
<td>{{domoticz.name}}</td>
|
||||
<td>{{domoticz.ip}}</td>
|
||||
<td>{{domoticz.port}}</td>
|
||||
<td>{{domoticz.username}}</td>
|
||||
<td ng-if="domoticz.password">*******</td>
|
||||
<td ng-if="!domoticz.password"> </td>
|
||||
<td><button class="btn btn-danger" type="submit"
|
||||
ng-click="removeDomoticztoSettings(domoticz.name, domoticz.ip)">Del</button></td>
|
||||
</tr>
|
||||
<tr>
|
||||
<td><input id="bridge-settings-next-domoticz-name"
|
||||
class="form-control" type="text" ng-model="newdomoticzname"
|
||||
placeholder="A Domoticz"></td>
|
||||
<td><input id="bridge-settings-next-domoticz-ip"
|
||||
class="form-control" type="text" ng-model="newdomoticzip"
|
||||
placeholder="192.168.1.3"></td>
|
||||
<td><input id="bridge-settings-next-domoticz-port"
|
||||
class="form-control" type="text" ng-model="newdomoticzport"
|
||||
placeholder="8080"></td>
|
||||
<td><input id="bridge-settings-next-domoticz-username"
|
||||
class="form-control" type="text" ng-model="newdomoticzusername"
|
||||
placeholder="Domoticz username"></td>
|
||||
<td><input id="bridge-settings-next-domoticz-password"
|
||||
class="form-control" type="password" ng-model="newdomoticzpassword"
|
||||
placeholder="Domoticz password (opt)"></td>
|
||||
<td><button class="btn btn-success" type="submit"
|
||||
ng-click="addDomoticztoSettings(newdomoticzname, newdomoticzip, newdomoticzport, newdomoticzusername, newdomoticzpassword)">Add</button></td>
|
||||
</tr>
|
||||
</table></td>
|
||||
</tr>
|
||||
@@ -369,7 +420,7 @@
|
||||
<div class="panel-heading">
|
||||
<h1 class="panel-title">
|
||||
Bridge Settings Backup <a ng-click="toggle()"><span
|
||||
class={{imgUrl}} aria-hidden="true"></a>
|
||||
class={{imgUrl}} aria-hidden="true"></span></a>
|
||||
</h1>
|
||||
</div>
|
||||
<div ng-if="visible" class="panel-body">
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -16,6 +16,7 @@
|
||||
href="#!/haldevices">HAL Devices</a></li>
|
||||
<li ng-if="bridge.showMqtt" role="presentation"><a href="#!/mqttmessages">MQTT Messages</a></li>
|
||||
<li ng-if="bridge.showHass" role="presentation"><a href="#!/hassdevices">HomeAssistant Devices</a></li>
|
||||
<li ng-if="bridge.showDomoticz" role="presentation"><a href="#!/domoticzdevices">Domoticz Devices</a></li>
|
||||
<li role="presentation"><a href="#!/editdevice">Add/Edit</a></li>
|
||||
</ul>
|
||||
|
||||
|
||||
@@ -0,0 +1,45 @@
|
||||
package com.bwssystems.hass.test;
|
||||
|
||||
import java.util.Iterator;
|
||||
|
||||
import com.bwssystems.HABridge.plugins.domoticz.DeviceResult;
|
||||
import com.bwssystems.HABridge.plugins.domoticz.Devices;
|
||||
import com.google.gson.Gson;
|
||||
import com.google.gson.GsonBuilder;
|
||||
|
||||
public class DomoticzDeviceConstructor {
|
||||
public final static String DevicesTestData = "{ \"ActTime\" : 1485295582, \"ServerTime\" : \"2017-01-24 16:06:22\", \"Sunrise\" : \"07:11\", \"Sunset\" : \"16:53\", \"result\" : [ { \"AddjMulti\" : 1.0, \"AddjMulti2\" : 1.0, \"AddjValue\" : 0.0, \"AddjValue2\" : 0.0, \"BatteryLevel\" : 255, \"CustomImage\" : 2, \"Data\" : \"On\", \"Description\" : \"\", \"Favorite\" : 1, \"HardwareID\" : 3, \"HardwareName\" : \"MyHue\", \"HardwareType\" : \"Philips Hue Bridge\", \"HardwareTypeVal\" : 38, \"HaveDimmer\" : true, \"HaveGroupCmd\" : false, \"HaveTimeout\" : false, \"ID\" : \"1\", \"Image\" : \"TV\", \"IsSubDevice\" : false, \"LastUpdate\" : \"2017-01-23 17:15:22\", \"Level\" : 0, \"LevelInt\" : 0, \"MaxDimLevel\" : 100, \"Name\" : \"TV\", \"Notifications\" : \"false\", \"PlanID\" : \"0\", \"PlanIDs\" : [ 0 ], \"Protected\" : false, \"ShowNotifications\" : true, \"SignalLevel\" : \"-\", \"Status\" : \"On\", \"StrParam1\" : \"\", \"StrParam2\" : \"\", \"SubType\" : \"RGBW\", \"SwitchType\" : \"On/Off\", \"SwitchTypeVal\" : 0, \"Timers\" : \"false\", \"Type\" : \"Lighting Limitless/Applamp\", \"TypeImg\" : \"lightbulb\", \"Unit\" : 1, \"Used\" : 1, \"UsedByCamera\" : false, \"XOffset\" : \"0\", \"YOffset\" : \"0\", \"idx\" : \"23\" }, { \"AddjMulti\" : 1.0, \"AddjMulti2\" : 1.0, \"AddjValue\" : 0.0, \"AddjValue2\" : 0.0, \"BatteryLevel\" : 255, \"CustomImage\" : 0, \"Data\" : \"On\", \"Description\" : \"\", \"Favorite\" : 1, \"HardwareID\" : 3, \"HardwareName\" : \"MyHue\", \"HardwareType\" : \"Philips Hue Bridge\", \"HardwareTypeVal\" : 38, \"HaveDimmer\" : true, \"HaveGroupCmd\" : false, \"HaveTimeout\" : false, \"ID\" : \"0000000B\", \"Image\" : \"Light\", \"IsSubDevice\" : false, \"LastUpdate\" : \"2017-01-23 16:15:31\", \"Level\" : 0, \"LevelInt\" : 0, \"MaxDimLevel\" : 100, \"Name\" : \"lights\", \"Notifications\" : \"false\", \"PlanID\" : \"0\", \"PlanIDs\" : [ 0 ], \"Protected\" : false, \"ShowNotifications\" : true, \"SignalLevel\" : \"-\", \"Status\" : \"On\", \"StrParam1\" : \"\", \"StrParam2\" : \"\", \"SubType\" : \"RGBW\", \"SwitchType\" : \"On/Off\", \"SwitchTypeVal\" : 0, \"Timers\" : \"false\", \"Type\" : \"Lighting Limitless/Applamp\", \"TypeImg\" : \"lightbulb\", \"Unit\" : 1, \"Used\" : 1, \"UsedByCamera\" : false, \"XOffset\" : \"0\", \"YOffset\" : \"0\", \"idx\" : \"25\" }, { \"AddjMulti\" : 1.0, \"AddjMulti2\" : 1.0, \"AddjValue\" : 0.0, \"AddjValue2\" : 0.0, \"BatteryLevel\" : 255, \"CustomImage\" : 0, \"Data\" : \"Off\", \"Description\" : \"\", \"Favorite\" : 1, \"HardwareID\" : 3, \"HardwareName\" : \"MyHue\", \"HardwareType\" : \"Philips Hue Bridge\", \"HardwareTypeVal\" : 38, \"HaveDimmer\" : true, \"HaveGroupCmd\" : false, \"HaveTimeout\" : false, \"ID\" : \"00000014\", \"Image\" : \"Light\", \"IsSubDevice\" : false, \"LastUpdate\" : \"2017-01-23 11:25:59\", \"Level\" : 0, \"LevelInt\" : 0, \"MaxDimLevel\" : 100, \"Name\" : \"testUDP\", \"Notifications\" : \"false\", \"PlanID\" : \"0\", \"PlanIDs\" : [ 0 ], \"Protected\" : false, \"ShowNotifications\" : true, \"SignalLevel\" : \"-\", \"Status\" : \"Off\", \"StrParam1\" : \"\", \"StrParam2\" : \"\", \"SubType\" : \"RGBW\", \"SwitchType\" : \"Dimmer\", \"SwitchTypeVal\" : 7, \"Timers\" : \"false\", \"Type\" : \"Lighting Limitless/Applamp\", \"TypeImg\" : \"dimmer\", \"Unit\" : 1, \"Used\" : 1, \"UsedByCamera\" : false, \"XOffset\" : \"0\", \"YOffset\" : \"0\", \"idx\" : \"35\" }, { \"AddjMulti\" : 1.0, \"AddjMulti2\" : 1.0, \"AddjValue\" : 0.0, \"AddjValue2\" : 0.0, \"BatteryLevel\" : 255, \"CustomImage\" : 0, \"Data\" : \"Off\", \"Description\" : \"\", \"Favorite\" : 1, \"HardwareID\" : 3, \"HardwareName\" : \"MyHue\", \"HardwareType\" : \"Philips Hue Bridge\", \"HardwareTypeVal\" : 38, \"HaveDimmer\" : true, \"HaveGroupCmd\" : false, \"HaveTimeout\" : false, \"ID\" : \"00000009\", \"Image\" : \"Light\", \"IsSubDevice\" : false, \"LastUpdate\" : \"2017-01-24 09:18:22\", \"Level\" : 94, \"LevelInt\" : 94, \"MaxDimLevel\" : 100, \"Name\" : \"Test Light on CM15 (PL) N1\", \"Notifications\" : \"false\", \"PlanID\" : \"0\", \"PlanIDs\" : [ 0 ], \"Protected\" : false, \"ShowNotifications\" : true, \"SignalLevel\" : \"-\", \"Status\" : \"Off\", \"StrParam1\" : \"\", \"StrParam2\" : \"\", \"SubType\" : \"RGBW\", \"SwitchType\" : \"Dimmer\", \"SwitchTypeVal\" : 7, \"Timers\" : \"false\", \"Type\" : \"Lighting Limitless/Applamp\", \"TypeImg\" : \"dimmer\", \"Unit\" : 1, \"Used\" : 1, \"UsedByCamera\" : false, \"XOffset\" : \"0\", \"YOffset\" : \"0\", \"idx\" : \"44\" } ], \"status\" : \"OK\", \"title\" : \"Devices\" }";
|
||||
public final static String ScenesTestData = "{ \"ActTime\" : 1485295431, \"AllowWidgetOrdering\" : true, \"ServerTime\" : \"2017-01-24 16:03:51\", \"Sunrise\" : \"07:11\", \"Sunset\" : \"16:53\", \"result\" : [ { \"Description\" : \"\", \"Favorite\" : 0, \"LastUpdate\" : \"2017-01-23 11:06:31\", \"Name\" : \"Watch TV\", \"OffAction\" : \"\", \"OnAction\" : \"\", \"Protected\" : false, \"Status\" : \"On\", \"Timers\" : \"false\", \"Type\" : \"Scene\", \"UsedByCamera\" : false, \"idx\" : \"1\" }, { \"Description\" : \"\", \"Favorite\" : 0, \"LastUpdate\" : \"2017-01-23 11:25:58\", \"Name\" : \"TestScene\", \"OffAction\" : \"\", \"OnAction\" : \"\", \"Protected\" : false, \"Status\" : \"Off\", \"Timers\" : \"false\", \"Type\" : \"Scene\", \"UsedByCamera\" : false, \"idx\" : \"2\" } ], \"status\" : \"OK\", \"title\" : \"Scenes\" }";
|
||||
public static void main(String[] args){
|
||||
DomoticzDeviceConstructor aTestService = new DomoticzDeviceConstructor();
|
||||
if(aTestService.validateStructure())
|
||||
System.out.println("Test Successful");
|
||||
}
|
||||
|
||||
public Boolean validateStructure() {
|
||||
Gson aGson;
|
||||
try {
|
||||
aGson = new GsonBuilder()
|
||||
// .registerTypeAdapter(Service.class, new ServiceDeserializer())
|
||||
// .registerTypeHierarchyAdapter(Field.class, new FieldDeserializer())
|
||||
.create();
|
||||
System.out.println("Decode Domoticz Devices Data");
|
||||
Devices aDeviceContainer = aGson.fromJson(DevicesTestData, Devices.class);
|
||||
Iterator<DeviceResult> aList = aDeviceContainer.getResult().iterator();
|
||||
while(aList.hasNext()) {
|
||||
DeviceResult theResult = aList.next();
|
||||
System.out.println(" " + theResult.getName() + " - " + theResult.getDescription() + " - " + theResult.getType());
|
||||
}
|
||||
System.out.println("Decode Domoticz Sceness Data");
|
||||
aDeviceContainer = aGson.fromJson(ScenesTestData, Devices.class);
|
||||
aList = aDeviceContainer.getResult().iterator();
|
||||
while(aList.hasNext()) {
|
||||
DeviceResult theResult = aList.next();
|
||||
System.out.println(" " + theResult.getName() + " - " + theResult.getDescription() + " - " + theResult.getType());
|
||||
}
|
||||
} catch (Exception e) {
|
||||
return false;
|
||||
}
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@@ -0,0 +1,14 @@
|
||||
package com.bwssystems.hass.test;
|
||||
|
||||
import org.junit.Assert;
|
||||
import org.junit.Test;
|
||||
|
||||
public class DomoticzStructureTestCase {
|
||||
|
||||
@Test
|
||||
public void testValidateStructure() {
|
||||
DomoticzDeviceConstructor aTestService = new DomoticzDeviceConstructor();
|
||||
Assert.assertEquals(aTestService.validateStructure(), true);
|
||||
}
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user