Added Color and Brightness traits to Google Assistant

This commit is contained in:
Ziver Koc 2023-09-08 22:14:03 +02:00
parent a68980a6b3
commit a4745cdccd
7 changed files with 213 additions and 11 deletions

View file

@ -41,6 +41,7 @@ public class ColorEventData extends HalEventData {
public ColorEventData() { }
/**
* Create object based on sRGB.
*/

View file

@ -33,20 +33,34 @@ public class LevelEventData extends HalEventData {
public LevelEventData() { }
/**
* @param percent a percentage value (from 0.0 to 1.0).
* @param timestamp a timestamp value when this event was triggered.
*/
public LevelEventData(double percent, long timestamp) {
setData(percent);
this.setTimestamp(timestamp);
}
/**
* @return percentage in integer format (from 0 to 100)
*/
public int getPercent() {
return (int) Math.floor(percent * 100);
}
@Override
public String toString(){
return Math.floor(percent * 100) + "%";
return getPercent() + "%";
}
// ----------------------------------------
// Storage methods
// ----------------------------------------
/**
* @return a percentage value (from 0.0 to 1.0)
*/
@Override
public double getData() {
return percent;

View file

@ -0,0 +1,89 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.plugin.assistant.google.trait;
import com.google.actions.api.smarthome.ExecuteRequest;
import se.hal.EventControllerManager;
import se.hal.intf.HalAbstractDevice;
import se.hal.intf.HalDeviceConfig;
import se.hal.intf.HalDeviceData;
import se.hal.struct.Event;
import se.hal.struct.devicedata.ColorEventData;
import se.hal.struct.devicedata.LevelEventData;
import zutil.converter.Converter;
import java.util.HashMap;
/**
* https://developers.home.google.com/cloud-to-cloud/traits/brightness
*/
public class BrightnessSetting extends DeviceTrait {
@Override
String getId() {
return "action.devices.traits.Brightness";
}
@Override
public HashMap<String, Object> generateSyncResponse(HalDeviceConfig config) {
HashMap<String, Object> response = new HashMap<>();
response.put("commandOnlyBrightness", false);
return response;
}
@Override
public HashMap<String, Object> generateQueryResponse(HalDeviceData data) {
HashMap<String, Object> response = new HashMap<>();
if (data instanceof LevelEventData) {
response.put("brightness", ((LevelEventData) data).getData() * 100);
}
return response;
}
@Override
public void execute(HalAbstractDevice device, ExecuteRequest.Inputs.Payload.Commands.Execution execution) {
if ("action.devices.commands.BrightnessAbsolute".equals(execution.command)) {
LevelEventData eventData = new LevelEventData((int) execution.getParams().get("brightness"), System.currentTimeMillis());
EventControllerManager.getInstance().send((Event) device, eventData);
} else if ("action.devices.commands.BrightnessRelative".equals(execution.command) && device.getDeviceData() != null) {
LevelEventData currentLevel = (LevelEventData) device.getDeviceData();
int newPercentage = currentLevel.getPercent();
if (execution.getParams().containsKey("brightnessRelativePercent")) {
newPercentage += (int) execution.getParams().get("brightnessRelativePercent");
} else if (execution.getParams().containsKey("brightnessRelativeWeight")) {
newPercentage += 10 * (int) execution.getParams().get("brightnessRelativeWeight");
}
LevelEventData eventData = new LevelEventData(newPercentage, System.currentTimeMillis());
EventControllerManager.getInstance().send((Event) device, eventData);
}
}
}

View file

@ -0,0 +1,93 @@
/*
* The MIT License (MIT)
*
* Copyright (c) 2020 Ziver Koc
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*/
package se.hal.plugin.assistant.google.trait;
import com.google.actions.api.smarthome.ExecuteRequest;
import se.hal.EventControllerManager;
import se.hal.intf.HalAbstractDevice;
import se.hal.intf.HalDeviceConfig;
import se.hal.intf.HalDeviceData;
import se.hal.struct.Event;
import se.hal.struct.devicedata.ColorEventData;
import se.hal.struct.devicedata.OnOffEventData;
import zutil.converter.Converter;
import java.util.HashMap;
/**
* https://developers.home.google.com/cloud-to-cloud/traits/colorsetting
*/
public class ColorSetting extends DeviceTrait {
@Override
String getId() {
return "action.devices.traits.ColorSetting";
}
@Override
public HashMap<String, Object> generateSyncResponse(HalDeviceConfig config) {
HashMap<String, Object> response = new HashMap<>();
response.put("commandOnlyColorSetting", false);
response.put("colorModel", "rgb"); // rgb or hsv
//response.put("colorTemperatureRange", new HashMap<String, Object>() {{
// put("temperatureMinK", 2000);
// put("temperatureMaxK", 9000);
//}});
return response;
}
@Override
public HashMap<String, Object> generateQueryResponse(HalDeviceData data) {
HashMap<String, Object> colorState = new HashMap<>();
//colorState.put("temperatureK", data.getData());
if (data instanceof ColorEventData) {
colorState.put("spectrumRgb", ((ColorEventData) data).getData());
}
//colorState.put("spectrumHsv", new HashMap<String, Object>() {{
// put("hue", ((ColorEventData) data).getHex());
// put("saturation", ((ColorEventData) data).getSaturation());
// put("value", ((ColorEventData) data).getLightness());
//}});
HashMap<String, Object> response = new HashMap<>();
response.put("color", colorState);
return response;
}
@Override
public void execute(HalAbstractDevice device, ExecuteRequest.Inputs.Payload.Commands.Execution execution) {
if ("action.devices.commands.ColorAbsolute".equals(execution.command)) {
byte[] rgb = Converter.toBytes((int) execution.getParams().get("spectrumRGB"));
ColorEventData eventData = new ColorEventData(rgb[2], rgb[1], rgb[0], System.currentTimeMillis());
EventControllerManager.getInstance().send((Event) device, eventData);
}
}
}

View file

@ -51,6 +51,15 @@ public class DeviceTraitFactory {
return new DeviceTrait[0];
switch (device.getDeviceConfig().getDeviceDataClass().getName()) {
case "se.hal.struct.devicedata.LevelEventData":
return new DeviceTrait[]{new BrightnessSetting()};
case "se.hal.struct.devicedata.ColorEventData":
return new DeviceTrait[]{new ColorSetting()};
case "se.hal.struct.devicedata.HumiditySensorData":
return new DeviceTrait[]{new SensorStateTrait(), new HumiditySettingTrait()};
case "se.hal.struct.devicedata.DimmerEventData":
case "se.hal.struct.devicedata.OnOffEventData":
return new DeviceTrait[]{new OnOffTrait()};
@ -59,15 +68,10 @@ public class DeviceTraitFactory {
return new DeviceTrait[]{new OpenCloseTrait()};
case "se.hal.struct.devicedata.ParticulateMatterSensorData":
return new DeviceTrait[]{new SensorStateTrait()};
case "se.hal.struct.devicedata.PowerConsumptionSensorData":
case "se.hal.struct.devicedata.LightSensorData":
return new DeviceTrait[]{new SensorStateTrait()};
case "se.hal.struct.devicedata.HumiditySensorData":
return new DeviceTrait[]{new SensorStateTrait(), new HumiditySettingTrait()};
case "se.hal.struct.devicedata.TemperatureSensorData":
return new DeviceTrait[]{new SensorStateTrait(), new TemperatureControlTrait()};

View file

@ -45,7 +45,6 @@ public class SensorStateTrait extends DeviceTrait {
@Override
public HashMap<String, Object> generateSyncResponse(HalDeviceConfig config) {
HashMap<String, Object> response = new HashMap<>();
ArrayList<HashMap> sensorStatesSupported = new ArrayList<>();
sensorStatesSupported.add(new HashMap<String, Object>() {{
@ -57,13 +56,13 @@ public class SensorStateTrait extends DeviceTrait {
}
}});
HashMap<String, Object> response = new HashMap<>();
response.put("sensorStatesSupported", sensorStatesSupported);
return response;
}
@Override
public HashMap<String, Object> generateQueryResponse(HalDeviceData data) {
HashMap<String, Object> response = new HashMap<>();
ArrayList<HashMap> currentSensorStateData = new ArrayList<>();
currentSensorStateData.add(new HashMap<String, Object>() {{
@ -74,6 +73,7 @@ public class SensorStateTrait extends DeviceTrait {
}
}});
HashMap<String, Object> response = new HashMap<>();
response.put("currentSensorStateData", currentSensorStateData);
return response;
}

View file

@ -161,14 +161,15 @@ public enum DeviceType {
return null;
switch (device.getDeviceConfig().getDeviceDataClass().getName()) {
case "se.hal.struct.devicedata.DimmerEventData":
case "se.hal.struct.devicedata.ColorEventData":
case "se.hal.struct.devicedata.LevelEventData":
case "se.hal.struct.devicedata.OnOffEventData":
return LIGHT;
case "se.hal.struct.devicedata.HumiditySensorData":
case "se.hal.struct.devicedata.IlluminanceSensorData":
case "se.hal.struct.devicedata.PowerConsumptionSensorData":
case "se.hal.struct.devicedata.TemperatureSensorData":
case "se.hal.struct.devicedata.HumiditySensorData":
case "se.hal.struct.devicedata.LightSensorData":
return SENSOR;
default: