mirror of
https://github.com/bwssytems/ha-bridge.git
synced 2025-12-16 18:24:36 +00:00
Fixed sizing of scrollable table to be dynamic. Added Appliances,
Theater and Custom devices to HAL interface. Added Select ALL feature for bulk add screens.
This commit is contained in:
16
README.md
16
README.md
@@ -21,7 +21,7 @@ Then locate the jar and start the server with:
|
|||||||
ATTENTION: This requires JDK 1.8 to run
|
ATTENTION: This requires JDK 1.8 to run
|
||||||
|
|
||||||
```
|
```
|
||||||
java -jar ha-bridge-2.0.6.jar
|
java -jar ha-bridge-2.5.0.jar
|
||||||
```
|
```
|
||||||
### Automation on Linux systems
|
### 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
|
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
|
||||||
@@ -35,7 +35,7 @@ After=network.target
|
|||||||
|
|
||||||
[Service]
|
[Service]
|
||||||
Type=simple
|
Type=simple
|
||||||
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/amazon-echo/data/habridge.config /home/pi/amazon-echo/ha-bridge-2.0.6.jar
|
ExecStart=/usr/bin/java -jar -Dconfig.file=/home/pi/amazon-echo/data/habridge.config /home/pi/amazon-echo/ha-bridge-2.5.0.jar
|
||||||
|
|
||||||
[Install]
|
[Install]
|
||||||
WantedBy=multi-user.target
|
WantedBy=multi-user.target
|
||||||
@@ -43,11 +43,11 @@ WantedBy=multi-user.target
|
|||||||
|
|
||||||
Basic script setup to run the bridge on a pi.
|
Basic script setup to run the bridge on a pi.
|
||||||
|
|
||||||
Create the directory and make sure that ha-bridge-2.0.6.jar is in your /home/pi/habridge directory.
|
Create the directory and make sure that ha-bridge-2.5.0.jar is in your /home/pi/habridge directory.
|
||||||
```
|
```
|
||||||
pi@raspberrypi:~ $ mkdir habridge
|
pi@raspberrypi:~ $ mkdir habridge
|
||||||
pi@raspberrypi:~ $ cd habridge
|
pi@raspberrypi:~ $ cd habridge
|
||||||
pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v2.0.6/ha-bridge-2.0.6.jar
|
pi@raspberrypi:~/habridge $ wget https://github.com/bwssytems/ha-bridge/releases/download/v2.0.6/ha-bridge-2.5.0.jar
|
||||||
```
|
```
|
||||||
Edit the shell script for starting:
|
Edit the shell script for starting:
|
||||||
```
|
```
|
||||||
@@ -57,7 +57,7 @@ Then cut and past this, modify any locations that are not correct
|
|||||||
```
|
```
|
||||||
cd /home/pi/habridge
|
cd /home/pi/habridge
|
||||||
rm /home/pi/habridge/habridge-log.txt
|
rm /home/pi/habridge/habridge-log.txt
|
||||||
nohup java -jar /home/pi/habridge/ha-bridge-2.0.6.jar > /home/pi/habridge/habridge-log.txt 2>&1 &
|
nohup java -jar /home/pi/habridge/ha-bridge-2.5.0.jar > /home/pi/habridge/habridge-log.txt 2>&1 &
|
||||||
chmod 777 /home/pi/habridge/habridge-log.txt
|
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:
|
Exit and save the file with ctrl-X and follow the prompts and then execute on the command line:
|
||||||
@@ -109,7 +109,7 @@ The server defaults to running on port 8080. To override what the default is, sp
|
|||||||
#### UPNP Response Port
|
#### UPNP Response Port
|
||||||
The upnp response port that will be used. The default is 50000.
|
The upnp response port that will be used. The default is 50000.
|
||||||
#### Vera Names and IP Addresses
|
#### Vera Names and IP Addresses
|
||||||
Provide IP Addresses of your Veras that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the devices or scenes by the call it receives and send it to the target Vera and devce/scene you configure.
|
Provide IP Addresses of your Veras that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the devices or scenes by the call it receives and send it to the target Vera and device/scene you configure.
|
||||||
#### Harmony Names and IP Addresses
|
#### Harmony Names and IP Addresses
|
||||||
Provide IP Addresses of your Harmony Hubs that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the activity or buttons by the call it receives and send it to the target Harmony Hub and activity/button you configure.
|
Provide IP Addresses of your Harmony Hubs that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the activity or buttons by the call it receives and send it to the target Harmony Hub and activity/button you configure.
|
||||||
#### Harmony Username
|
#### Harmony Username
|
||||||
@@ -120,6 +120,10 @@ The password for the user name of the MyHarmony.com account for the Harmony Hub.
|
|||||||
Provide IP Addresses of your Hue Bridges that you want to proxy through the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will passthru the call it receives to the target Hue and device you configure.
|
Provide IP Addresses of your Hue Bridges that you want to proxy through the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will passthru the call it receives to the target Hue and device you configure.
|
||||||
|
|
||||||
Don't forget - You will need to push the link button when you got to the Hue Tab the first time ater the process comes up. (The user name is not persistent when the process comes up.)
|
Don't forget - You will need to push the link button when you got to the Hue Tab the first time ater the process comes up. (The user name is not persistent when the process comes up.)
|
||||||
|
#### HAL Names and IP Addresses
|
||||||
|
Provide IP Addresses of your HAL Systems that you want to utilize with the bridge. Also, give a meaningful name to each one so it is easy to decipher in the helper tab. When these names and IP's are given, the bridge will be able to control the devices or scenes by the call it receives and send it to the target HAL and device/scene you configure.
|
||||||
|
#### HAL Token
|
||||||
|
The token you generate or give to a HAL and must be the same for all HAL's you have identified. This needs to be given if you are using the HAL features.
|
||||||
#### Nest Username
|
#### Nest Username
|
||||||
The user name of the home.nest.com account for the Nest user. This needs to be given if you are using the Nest features. There is no need to give any ip address or host information as this contacts your cloud account.
|
The user name of the home.nest.com account for the Nest user. This needs to be given if you are using the Nest features. There is no need to give any ip address or host information as this contacts your cloud account.
|
||||||
#### Nest Password
|
#### Nest Password
|
||||||
|
|||||||
2
pom.xml
2
pom.xml
@@ -5,7 +5,7 @@
|
|||||||
|
|
||||||
<groupId>com.bwssystems.HABridge</groupId>
|
<groupId>com.bwssystems.HABridge</groupId>
|
||||||
<artifactId>ha-bridge</artifactId>
|
<artifactId>ha-bridge</artifactId>
|
||||||
<version>2.0.7-hal-a</version>
|
<version>2.0.7-hal-b</version>
|
||||||
<packaging>jar</packaging>
|
<packaging>jar</packaging>
|
||||||
|
|
||||||
<name>HA Bridge</name>
|
<name>HA Bridge</name>
|
||||||
|
|||||||
@@ -35,26 +35,46 @@ public class HalHome {
|
|||||||
|
|
||||||
public List<HalDevice> getDevices() {
|
public List<HalDevice> getDevices() {
|
||||||
log.debug("consolidating devices for hues");
|
log.debug("consolidating devices for hues");
|
||||||
|
List<HalDevice> theResponse = null;
|
||||||
Iterator<String> keys = hals.keySet().iterator();
|
Iterator<String> keys = hals.keySet().iterator();
|
||||||
List<HalDevice> deviceList = new ArrayList<HalDevice>();
|
List<HalDevice> deviceList = new ArrayList<HalDevice>();
|
||||||
while(keys.hasNext()) {
|
while(keys.hasNext()) {
|
||||||
String key = keys.next();
|
String key = keys.next();
|
||||||
List<HalDevice> theResponse = hals.get(key).getLights();
|
theResponse = hals.get(key).getLights();
|
||||||
if(theResponse != null) {
|
if(theResponse != null)
|
||||||
Iterator<HalDevice> devices = theResponse.iterator();
|
addHalDevices(deviceList, theResponse, key);
|
||||||
while(devices.hasNext()) {
|
|
||||||
HalDevice theDevice = devices.next();
|
|
||||||
HalDevice aNewHalDevice = new HalDevice();
|
|
||||||
aNewHalDevice.setHaldevicetype(theDevice.getHaldevicetype());
|
|
||||||
aNewHalDevice.setHaldevicename(theDevice.getHaldevicename());
|
|
||||||
aNewHalDevice.setHaladdress(hals.get(key).getHalAddress().getIp());
|
|
||||||
aNewHalDevice.setHalname(key);
|
|
||||||
deviceList.add(aNewHalDevice);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else
|
else
|
||||||
log.warn("Cannot get lights for Hal with name: " + key);
|
log.warn("Cannot get lights for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getAppliances();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get appliances for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getTheatre();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get theatre for Hal with name: " + key);
|
||||||
|
theResponse = hals.get(key).getCustom();
|
||||||
|
if(theResponse != null)
|
||||||
|
addHalDevices(deviceList, theResponse, key);
|
||||||
|
else
|
||||||
|
log.warn("Cannot get custom for Hal with name: " + key);
|
||||||
}
|
}
|
||||||
return deviceList;
|
return deviceList;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private Boolean addHalDevices(List<HalDevice> theDeviceList, List<HalDevice> theSourceList, String theKey) {
|
||||||
|
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.setHaladdress(hals.get(theKey).getHalAddress().getIp());
|
||||||
|
aNewHalDevice.setHalname(theKey);
|
||||||
|
theDeviceList.add(aNewHalDevice);
|
||||||
|
}
|
||||||
|
return true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,7 +19,13 @@ import com.google.gson.Gson;
|
|||||||
|
|
||||||
public class HalInfo {
|
public class HalInfo {
|
||||||
private static final Logger log = LoggerFactory.getLogger(HalInfo.class);
|
private static final Logger log = LoggerFactory.getLogger(HalInfo.class);
|
||||||
private static final String LIGHTS_REQUEST = "/DeviceData!DeviceCmd=GetNames!DeviceType=Light?Token=";
|
private static final String DEVICE_REQUEST = "/DeviceData!DeviceCmd=GetNames!DeviceType=";
|
||||||
|
private static final String TOKEN_REQUEST = "?Token=";
|
||||||
|
private static final String LIGHT_REQUEST = "Light";
|
||||||
|
private static final String APPL_REQUEST = "Appl";
|
||||||
|
private static final String VIDEO_REQUEST = "Video";
|
||||||
|
private static final String THEATRE_REQUEST = "Theatre";
|
||||||
|
private static final String CUSTOM_REQUEST = "Custom";
|
||||||
private HttpClient httpClient;
|
private HttpClient httpClient;
|
||||||
private NamedIP halAddress;
|
private NamedIP halAddress;
|
||||||
private String theToken;
|
private String theToken;
|
||||||
@@ -32,30 +38,56 @@ public class HalInfo {
|
|||||||
}
|
}
|
||||||
|
|
||||||
public List<HalDevice> getLights() {
|
public List<HalDevice> getLights() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + LIGHT_REQUEST + TOKEN_REQUEST, LIGHT_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getAppliances() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + APPL_REQUEST + TOKEN_REQUEST, APPL_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getTheatre() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + THEATRE_REQUEST + TOKEN_REQUEST, THEATRE_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<HalDevice> getCustom() {
|
||||||
|
return getHalDevices(DEVICE_REQUEST + CUSTOM_REQUEST + TOKEN_REQUEST, CUSTOM_REQUEST);
|
||||||
|
}
|
||||||
|
|
||||||
|
private List<HalDevice> getHalDevices(String apiType, String deviceType) {
|
||||||
DeviceElements theHalApiResponse = null;
|
DeviceElements theHalApiResponse = null;
|
||||||
List<HalDevice> deviceList = null;
|
List<HalDevice> deviceList = null;
|
||||||
|
|
||||||
String theUrl = null;
|
String theUrl = null;
|
||||||
String theData;
|
String theData;
|
||||||
theUrl = "http://" + halAddress.getIp() + LIGHTS_REQUEST + theToken;
|
theUrl = "http://" + halAddress.getIp() + apiType + theToken;
|
||||||
theData = doHttpGETRequest(theUrl);
|
theData = doHttpGETRequest(theUrl);
|
||||||
if(theData != null) {
|
if(theData != null) {
|
||||||
log.debug("GET HalApiResponse - data: " + theData);
|
log.debug("GET HalApiResponse - data: " + theData);
|
||||||
theHalApiResponse = new Gson().fromJson(theData, DeviceElements.class);
|
theHalApiResponse = new Gson().fromJson(theData, DeviceElements.class);
|
||||||
|
if(theHalApiResponse.getDeviceElements() == null) {
|
||||||
|
StatusDescription theStatus = new Gson().fromJson(theData, StatusDescription.class);
|
||||||
|
if(theStatus.getStatus() == null) {
|
||||||
|
log.warn("Cannot get an devices for type " + deviceType + " for hal " + halAddress.getName() + " as response is not parsable.");
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
log.warn("Cannot get an devices for type " + deviceType + " for hal " + halAddress.getName() + ". Status: " + theStatus.getStatus() + ", with description: " + theStatus.getDescription());
|
||||||
|
}
|
||||||
|
return deviceList;
|
||||||
|
}
|
||||||
deviceList = new ArrayList<HalDevice>();
|
deviceList = new ArrayList<HalDevice>();
|
||||||
|
|
||||||
Iterator<DeviceName> theDeviceNames = theHalApiResponse.getDeviceElements().iterator();
|
Iterator<DeviceName> theDeviceNames = theHalApiResponse.getDeviceElements().iterator();
|
||||||
while(theDeviceNames.hasNext()) {
|
while(theDeviceNames.hasNext()) {
|
||||||
DeviceName theDevice = theDeviceNames.next();
|
DeviceName theDevice = theDeviceNames.next();
|
||||||
HalDevice aNewHalDevice = new HalDevice();
|
HalDevice aNewHalDevice = new HalDevice();
|
||||||
aNewHalDevice.setHaldevicetype("lights");
|
aNewHalDevice.setHaldevicetype(deviceType);
|
||||||
aNewHalDevice.setHaldevicename(theDevice.getDeviceName());
|
aNewHalDevice.setHaldevicename(theDevice.getDeviceName());
|
||||||
deviceList.add(aNewHalDevice);
|
deviceList.add(aNewHalDevice);
|
||||||
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
log.warn("GET HalApiResponse for " + halAddress.getName() + " - returned null, no data.");
|
log.warn("Get Hal device types " + deviceType + " for " + halAddress.getName() + " - returned null, no data.");
|
||||||
}
|
}
|
||||||
return deviceList;
|
return deviceList;
|
||||||
}
|
}
|
||||||
|
|||||||
18
src/main/java/com/bwssystems/hal/StatusDescription.java
Normal file
18
src/main/java/com/bwssystems/hal/StatusDescription.java
Normal file
@@ -0,0 +1,18 @@
|
|||||||
|
package com.bwssystems.hal;
|
||||||
|
|
||||||
|
public class StatusDescription {
|
||||||
|
private String Status;
|
||||||
|
private String Description;
|
||||||
|
public String getStatus() {
|
||||||
|
return Status;
|
||||||
|
}
|
||||||
|
public void setStatus(String status) {
|
||||||
|
Status = status;
|
||||||
|
}
|
||||||
|
public String getDescription() {
|
||||||
|
return Description;
|
||||||
|
}
|
||||||
|
public void setDescription(String description) {
|
||||||
|
Description = description;
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -1,5 +1,5 @@
|
|||||||
.scrollableContainer {
|
.scrollableContainer {
|
||||||
height: 600px;
|
max-height: 436px; /* sets max-height value for all standards-compliant browsers */
|
||||||
position: relative;
|
position: relative;
|
||||||
padding-top: 35px;
|
padding-top: 35px;
|
||||||
overflow: hidden;
|
overflow: hidden;
|
||||||
@@ -28,7 +28,8 @@
|
|||||||
}
|
}
|
||||||
|
|
||||||
.scrollArea {
|
.scrollArea {
|
||||||
height: 100%;
|
_height: expression( this.scrollHeight > 599 ? "600px" : "auto" ); /* sets max-height for IE6 */
|
||||||
|
max-height: 400px; /* sets max-height value for all standards-compliant browsers */
|
||||||
overflow-x: auto;
|
overflow-x: auto;
|
||||||
overflow-y: auto;
|
overflow-y: auto;
|
||||||
border: 1px solid #d5d5d5;
|
border: 1px solid #d5d5d5;
|
||||||
|
|||||||
@@ -864,12 +864,20 @@ app.controller('DeleteMapandIdDialogCtrl', function ($scope, bridgeService, ngDi
|
|||||||
ngDialog.close('ngdialog1');
|
ngDialog.close('ngdialog1');
|
||||||
bridgeService.deleteDeviceByMapId(mapandid.id, mapandid.mapType);
|
bridgeService.deleteDeviceByMapId(mapandid.id, mapandid.mapType);
|
||||||
bridgeService.viewDevices();
|
bridgeService.viewDevices();
|
||||||
bridgeService.viewVeraDevices();
|
if(mapandid.mapType == "veraDevice")
|
||||||
bridgeService.viewVeraScenes();
|
bridgeService.viewVeraDevices();
|
||||||
bridgeService.viewHarmonyActivities();
|
if(mapandid.mapType == "veraScene")
|
||||||
bridgeService.viewHarmonyDevices();
|
bridgeService.viewVeraScenes();
|
||||||
bridgeService.viewNestItems();
|
if(mapandid.mapType == "harmonyActivity")
|
||||||
bridgeService.viewHueDevices();
|
bridgeService.viewHarmonyActivities();
|
||||||
|
if(mapandid.mapType == "harmonyButton")
|
||||||
|
bridgeService.viewHarmonyDevices();
|
||||||
|
if(mapandid.mapType == "nestThermoSet" || mapandid.mapType == "nestHomeAway")
|
||||||
|
bridgeService.viewNestItems();
|
||||||
|
if(mapandid.mapType == "hueDevice")
|
||||||
|
bridgeService.viewHueDevices();
|
||||||
|
if(mapandid.mapType == "halDevice")
|
||||||
|
bridgeService.viewHalDevices();
|
||||||
$scope.bridge.mapandid = null;
|
$scope.bridge.mapandid = null;
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@@ -879,6 +887,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
$scope.device = $scope.bridge.device;
|
$scope.device = $scope.bridge.device;
|
||||||
$scope.device_dim_control = "";
|
$scope.device_dim_control = "";
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
var veraList = angular.fromJson($scope.bridge.settings.veraaddress);
|
var veraList = angular.fromJson($scope.bridge.settings.veraaddress);
|
||||||
if(veraList != null)
|
if(veraList != null)
|
||||||
$scope.vera = {base: "http://" + veraList.devices[0].ip, port: "3480", id: ""};
|
$scope.vera = {base: "http://" + veraList.devices[0].ip, port: "3480", id: ""};
|
||||||
@@ -985,6 +994,7 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleSelection = function toggleSelection(deviceId) {
|
$scope.toggleSelection = function toggleSelection(deviceId) {
|
||||||
@@ -993,11 +1003,28 @@ app.controller('VeraController', function ($scope, $location, $http, bridgeServi
|
|||||||
// is currently selected
|
// is currently selected
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
$scope.bulk.devices.splice(idx, 1);
|
$scope.bulk.devices.splice(idx, 1);
|
||||||
|
if($scope.bulk.devices.length == 0 && $scope.selectAll)
|
||||||
|
$scope.selectAll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is newly selected
|
// is newly selected
|
||||||
else {
|
else {
|
||||||
$scope.bulk.devices.push(deviceId);
|
$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.veradevices.length; x++) {
|
||||||
|
if($scope.bulk.devices.indexOf(bridgeService.state.veradevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.veradevices[x].id, bridgeService.state.veradevices[x].veraname, "veraDevice"))
|
||||||
|
$scope.bulk.devices.push(bridgeService.state.veradevices[x].id);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1226,6 +1253,7 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
|
|||||||
$scope.bridge = bridgeService.state;
|
$scope.bridge = bridgeService.state;
|
||||||
$scope.device = $scope.bridge.device;
|
$scope.device = $scope.bridge.device;
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
bridgeService.viewHueDevices();
|
bridgeService.viewHueDevices();
|
||||||
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
$scope.buttonsVisible = false;
|
$scope.buttonsVisible = false;
|
||||||
@@ -1298,6 +1326,7 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
|
|||||||
);
|
);
|
||||||
|
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleSelection = function toggleSelection(deviceId) {
|
$scope.toggleSelection = function toggleSelection(deviceId) {
|
||||||
@@ -1306,11 +1335,28 @@ app.controller('HueController', function ($scope, $location, $http, bridgeServic
|
|||||||
// is currently selected
|
// is currently selected
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
$scope.bulk.devices.splice(idx, 1);
|
$scope.bulk.devices.splice(idx, 1);
|
||||||
|
if($scope.bulk.devices.length == 0 && $scope.selectAll)
|
||||||
|
$scope.selectAll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is newly selected
|
// is newly selected
|
||||||
else {
|
else {
|
||||||
$scope.bulk.devices.push(deviceId);
|
$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.huedevices.length; x++) {
|
||||||
|
if($scope.bulk.devices.indexOf(bridgeService.state.huedevices[x]) < 0 && !bridgeService.findDeviceByMapId(bridgeService.state.huedevices[x].device.uniqueid, bridgeService.state.huedevices[x].huename, "hueDevice"))
|
||||||
|
$scope.bulk.devices.push(bridgeService.state.huedevices[x].device.uniqueid);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
@@ -1338,6 +1384,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
|
|||||||
$scope.device = $scope.bridge.device;
|
$scope.device = $scope.bridge.device;
|
||||||
$scope.device_dim_control = "";
|
$scope.device_dim_control = "";
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
bridgeService.viewHalDevices();
|
bridgeService.viewHalDevices();
|
||||||
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
$scope.imgButtonsUrl = "glyphicon glyphicon-plus";
|
||||||
$scope.buttonsVisible = false;
|
$scope.buttonsVisible = false;
|
||||||
@@ -1432,6 +1479,7 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
|
|||||||
}
|
}
|
||||||
);
|
);
|
||||||
$scope.bulk = { devices: [] };
|
$scope.bulk = { devices: [] };
|
||||||
|
$scope.selectAll = false;
|
||||||
};
|
};
|
||||||
|
|
||||||
$scope.toggleSelection = function toggleSelection(deviceId) {
|
$scope.toggleSelection = function toggleSelection(deviceId) {
|
||||||
@@ -1440,11 +1488,28 @@ app.controller('HalController', function ($scope, $location, $http, bridgeServic
|
|||||||
// is currently selected
|
// is currently selected
|
||||||
if (idx > -1) {
|
if (idx > -1) {
|
||||||
$scope.bulk.devices.splice(idx, 1);
|
$scope.bulk.devices.splice(idx, 1);
|
||||||
|
if($scope.bulk.devices.length == 0 && $scope.selectAll)
|
||||||
|
$scope.selectAll = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
// is newly selected
|
// is newly selected
|
||||||
else {
|
else {
|
||||||
$scope.bulk.devices.push(deviceId);
|
$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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|||||||
@@ -61,7 +61,7 @@
|
|||||||
</table>
|
</table>
|
||||||
</scrollable-table>
|
</scrollable-table>
|
||||||
</div>
|
</div>
|
||||||
<div class="panel panel-default backup">
|
<div class="panel panel-default">
|
||||||
<div class="panel-heading">
|
<div class="panel-heading">
|
||||||
<h1 class="panel-title">
|
<h1 class="panel-title">
|
||||||
Bridge Device DB Backup <a ng-click="toggleBk()"><span
|
Bridge Device DB Backup <a ng-click="toggleBk()"><span
|
||||||
@@ -69,6 +69,7 @@
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="visibleBk" class="animate-if" class="panel-body">
|
<div ng-if="visibleBk" class="animate-if" class="panel-body">
|
||||||
|
<p>Control your backups from this area. Use the default name by hitting backup or specify your own.</p>
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup
|
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup
|
||||||
|
|||||||
@@ -96,6 +96,7 @@
|
|||||||
<option value="nestHomeAway">Nest Home Status</option>
|
<option value="nestHomeAway">Nest Home Status</option>
|
||||||
<option value="nestThermoSet">Nest Thermostat</option>
|
<option value="nestThermoSet">Nest Thermostat</option>
|
||||||
<option value="hueDevice">Hue Device</option>
|
<option value="hueDevice">Hue Device</option>
|
||||||
|
<option value="halDevice">HAL Device</option>
|
||||||
</select>
|
</select>
|
||||||
</div>
|
</div>
|
||||||
<button class="btn btn-danger" ng-click="clearDevice()">
|
<button class="btn btn-danger" ng-click="clearDevice()">
|
||||||
|
|||||||
@@ -50,7 +50,11 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Row</th>
|
<th>Row</th>
|
||||||
<th sortable-header col="name">Name</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="category">Category</th>
|
<th sortable-header col="category">Category</th>
|
||||||
<th sortable-header col="halname">HAL</th>
|
<th sortable-header col="halname">HAL</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
|
|||||||
@@ -40,7 +40,10 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Row</th>
|
<th>Row</th>
|
||||||
<th sortable-header col="name">Name</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="id">Id</th>
|
<th sortable-header col="id">Id</th>
|
||||||
<th sortable-header col="huename">Hue</th>
|
<th sortable-header col="huename">Hue</th>
|
||||||
<th>Actions</th>
|
<th>Actions</th>
|
||||||
|
|||||||
@@ -284,6 +284,7 @@
|
|||||||
</h1>
|
</h1>
|
||||||
</div>
|
</div>
|
||||||
<div ng-if="visible" class="animate-if" class="panel-body">
|
<div ng-if="visible" class="animate-if" class="panel-body">
|
||||||
|
<p>Control your backups from this area. Use the default name by hitting backup or specify your own.</p>
|
||||||
<form class="form-horizontal">
|
<form class="form-horizontal">
|
||||||
<div class="form-group">
|
<div class="form-group">
|
||||||
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup
|
<label class="col-xs-12 col-sm-2 control-label" for="backup-name">Backup
|
||||||
|
|||||||
@@ -49,7 +49,10 @@
|
|||||||
<thead>
|
<thead>
|
||||||
<tr>
|
<tr>
|
||||||
<th>Row</th>
|
<th>Row</th>
|
||||||
<th sortable-header col="name">Name</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="id">Id</th>
|
<th sortable-header col="id">Id</th>
|
||||||
<th sortable-header col="category">Category</th>
|
<th sortable-header col="category">Category</th>
|
||||||
<th sortable-header col="room">Room</th>
|
<th sortable-header col="room">Room</th>
|
||||||
|
|||||||
Reference in New Issue
Block a user