[amazonechocontrol] fix SmartHomeDevice channels (#9644)

* [amazonechocontrol] add channel-types to schema
* [amazonechocontrol] use mergedApplianceIds to query state

Signed-off-by: Miguel <miguelwork92@gmail.com>
This commit is contained in:
GiviMAD 2021-01-03 09:00:55 +01:00 committed by GitHub
parent a02be787ee
commit d9caa46031
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 149 additions and 20 deletions

View File

@ -1053,15 +1053,30 @@ public class Connection {
return json;
}
public Map<String, JsonArray> getSmartHomeDeviceStatesJson(Set<String> applianceIds)
public Map<String, JsonArray> getSmartHomeDeviceStatesJson(Set<SmartHomeBaseDevice> devices)
throws IOException, URISyntaxException, InterruptedException {
JsonObject requestObject = new JsonObject();
JsonArray stateRequests = new JsonArray();
for (String applianceId : applianceIds) {
JsonObject stateRequest = new JsonObject();
stateRequest.addProperty("entityId", applianceId);
stateRequest.addProperty("entityType", "APPLIANCE");
stateRequests.add(stateRequest);
Map<String, String> mergedApplianceMap = new HashMap<>();
for (SmartHomeBaseDevice device : devices) {
String applianceId = device.findId();
if (applianceId != null) {
JsonObject stateRequest;
if (device instanceof SmartHomeDevice && !((SmartHomeDevice) device).mergedApplianceIds.isEmpty()) {
for (String idToMerge : ((SmartHomeDevice) device).mergedApplianceIds) {
mergedApplianceMap.put(idToMerge, applianceId);
stateRequest = new JsonObject();
stateRequest.addProperty("entityId", idToMerge);
stateRequest.addProperty("entityType", "APPLIANCE");
stateRequests.add(stateRequest);
}
} else {
stateRequest = new JsonObject();
stateRequest.addProperty("entityId", applianceId);
stateRequest.addProperty("entityType", "APPLIANCE");
stateRequests.add(stateRequest);
}
}
}
requestObject.add("stateRequests", stateRequests);
String requestBody = requestObject.toString();
@ -1074,10 +1089,21 @@ public class Connection {
for (JsonElement deviceState : deviceStates) {
JsonObject deviceStateObject = deviceState.getAsJsonObject();
JsonObject entity = deviceStateObject.get("entity").getAsJsonObject();
String applicanceId = entity.get("entityId").getAsString();
String applianceId = entity.get("entityId").getAsString();
JsonElement capabilityState = deviceStateObject.get("capabilityStates");
if (capabilityState != null && capabilityState.isJsonArray()) {
result.put(applicanceId, capabilityState.getAsJsonArray());
String realApplianceId = mergedApplianceMap.get(applianceId);
if (realApplianceId != null) {
var capabilityArray = result.get(realApplianceId);
if (capabilityArray != null) {
capabilityArray.addAll(capabilityState.getAsJsonArray());
result.put(realApplianceId, capabilityArray);
} else {
result.put(realApplianceId, capabilityState.getAsJsonArray());
}
} else {
result.put(applianceId, capabilityState.getAsJsonArray());
}
}
}
return result;

View File

@ -220,7 +220,6 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
public void addEchoHandler(EchoHandler echoHandler) {
if (echoHandlers.add(echoHandler)) {
forceCheckData();
}
}
@ -909,9 +908,10 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
return;
}
List<SmartHomeBaseDevice> allDevices = getLastKnownSmartHomeDevices();
Set<String> applianceIds = new HashSet<>();
Set<SmartHomeBaseDevice> targetDevices = new HashSet<>();
if (deviceFilterId != null) {
applianceIds.add(deviceFilterId);
allDevices.stream().filter(d -> deviceFilterId.equals(d.findId())).findFirst()
.ifPresent(targetDevices::add);
} else {
SmartHomeDeviceStateGroupUpdateCalculator smartHomeDeviceStateGroupUpdateCalculator = this.smartHomeDeviceStateGroupUpdateCalculator;
if (smartHomeDeviceStateGroupUpdateCalculator == null) {
@ -928,18 +928,13 @@ public class AccountHandler extends BaseBridgeHandler implements IWebSocketComma
.forEach(devicesToUpdate::add);
}
smartHomeDeviceStateGroupUpdateCalculator.removeDevicesWithNoUpdate(devicesToUpdate);
devicesToUpdate.stream().map(shd -> shd.applianceId).forEach(applianceId -> {
if (applianceId != null) {
applianceIds.add(applianceId);
}
});
if (applianceIds.isEmpty()) {
devicesToUpdate.stream().filter(Objects::nonNull).forEach(targetDevices::add);
if (targetDevices.isEmpty()) {
return;
}
}
Map<String, JsonArray> applianceIdToCapabilityStates = connection
.getSmartHomeDeviceStatesJson(applianceIds);
.getSmartHomeDeviceStatesJson(targetDevices);
for (SmartHomeDeviceHandler smartHomeDeviceHandler : smartHomeDeviceHandlers) {
String id = smartHomeDeviceHandler.getId();

View File

@ -13,6 +13,7 @@
package org.openhab.binding.amazonechocontrol.internal.jsons;
import java.util.Arrays;
import java.util.List;
import org.eclipse.jdt.annotation.NonNullByDefault;
import org.eclipse.jdt.annotation.Nullable;
@ -53,6 +54,7 @@ public class JsonSmartHomeDevices {
public @Nullable SmartHomeDevice @Nullable [] groupDevices;
public @Nullable String connectedVia;
public @Nullable DriverIdentity driverIdentity;
public List<String> mergedApplianceIds = List.of();
@Override
public String toString() {
@ -64,7 +66,7 @@ public class JsonSmartHomeDevices {
+ Arrays.toString(capabilities) + ", tags=" + tags + ", applianceTypes="
+ Arrays.toString(applianceTypes) + ", aliases=" + Arrays.toString(aliases) + ", groupDevices="
+ Arrays.toString(groupDevices) + ", connectedVia='" + connectedVia + '\'' + ", driverIdentity="
+ driverIdentity + '}';
+ driverIdentity + ", mergedApplianceIds=" + mergedApplianceIds + '}';
}
}

View File

@ -535,4 +535,110 @@
<description>Next timer</description>
<state readOnly="true"/>
</channel-type>
<!-- dynamic smart home device channels -->
<!-- Alexa.AcousticEventSensor -->
<channel-type id="glassBreakDetectionState">
<item-type>Contact</item-type>
<label>Glass Break Detection State</label>
<description>Glass Break Detection State</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="smokeAlarmDetectionState">
<item-type>Contact</item-type>
<label>Smoke Alarm Detection State</label>
<description>Smoke Alarm Detection State</description>
<state readOnly="true"/>
</channel-type>
<!-- Alexa.BrightnessController -->
<channel-type id="brightness">
<item-type>Dimmer</item-type>
<label>Brightness</label>
<description>Brightness</description>
<state min="0" max="100" step="1"/>
</channel-type>
<!-- Alexa.ColorController -->
<channel-type id="color">
<item-type>Color</item-type>
<label>Color</label>
<description>Color</description>
</channel-type>
<channel-type id="colorName">
<item-type>String</item-type>
<label>Color Name</label>
<description>Color Name</description>
</channel-type>
<!-- Alexa.ColorTemperatureController -->
<channel-type id="colorTemperatureName">
<item-type>String</item-type>
<label>Color Temperature Name</label>
<description>Color Temperature Name</description>
</channel-type>
<channel-type id="colorTemperatureInKelvin">
<item-type>Number</item-type>
<label>Color Temperature In Kelvin</label>
<description>Color Temperature In Kelvin</description>
</channel-type>
<!-- Alexa.PercentageController -->
<channel-type id="percentage">
<item-type>Dimmer</item-type>
<label>Percentage</label>
<description>Percentage</description>
</channel-type>
<!-- Alexa.PowerController -->
<channel-type id="powerState">
<item-type>Switch</item-type>
<label>Power State</label>
<description>Power State</description>
</channel-type>
<!-- Alexa.PowerLevelController -->
<channel-type id="powerLevel">
<item-type>Dimmer</item-type>
<label>Power Level</label>
<description>Power Level</description>
<state min="0" max="100" step="1"/>
</channel-type>
<!-- Alexa.SecurityPanelController -->
<channel-type id="armState">
<item-type>String</item-type>
<label>ARM State</label>
<description>ARM State</description>
</channel-type>
<channel-type id="burglaryAlarm">
<item-type>Contact</item-type>
<label>Burglary Alarm</label>
<description>Burglary Alarm</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="carbonMonoxideAlarm">
<item-type>Contact</item-type>
<label>Carbon Monoxide Alarm</label>
<description>Carbon Monoxide Alarm</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="fireAlarm">
<item-type>Contact</item-type>
<label>Fire Alarm</label>
<description>Fire Alarm</description>
<state readOnly="true"/>
</channel-type>
<channel-type id="waterAlarm">
<item-type>Contact</item-type>
<label>Water Alarm</label>
<description>Water Alarm</description>
<state readOnly="true"/>
</channel-type>
<!-- Alexa.TemperatureSensor -->
<channel-type id="temperature">
<item-type>Number:Temperature</item-type>
<label>Temperature</label>
<description>Temperature</description>
<state readOnly="true" pattern="%.1f %unit%"/>
</channel-type>
<!-- Alexa.ThermostatController -->
<channel-type id="targetSetpoint">
<item-type>Number:Temperature</item-type>
<label>Target Setpoint</label>
<description>Target Setpoint</description>
<state pattern="%.1f %unit%"/>
</channel-type>
</thing:thing-descriptions>