Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Prepared available configuration options #547

Merged
merged 2 commits into from
Jan 29, 2024
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
22 changes: 11 additions & 11 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -329,23 +329,23 @@ Player transportItem (tvGroup) { ga="tvTransport" }
| **Device Type** | [Fan](https://developers.home.google.com/cloud-to-cloud/guides/fan), [Hood](https://developers.home.google.com/cloud-to-cloud/guides/hood), [AirPurifier](https://developers.home.google.com/cloud-to-cloud/guides/airpurifier) |
| **Supported Traits** | [OnOff](https://developers.home.google.com/cloud-to-cloud/traits/OnOff), [FanSpeed](https://developers.home.google.com/cloud-to-cloud/traits/fanspeed) (depending on used item type) |
| **Supported Items** | Switch (no speed control), Dimmer |
| **Configuration** | (optional) `checkState=true/false`<br>(optional) `speeds="0=away:zero,50=default:standard:one,100=high:two"`<br>(optional) `lang="en"`<br>(optional) `ordered=true/false` |
| **Configuration** | (optional) `checkState=true/false`<br>(optional) `fanSpeeds="0=away:zero,50=default:standard:one,100=high:two"`<br>(optional) `lang="en"`<br>(optional) `ordered=true/false` |

Fans (and similar device types, like AirPurifier or Hood) support the `FanSpeed` trait.
If you do not specify the `speeds` option, Google will use and expect percentage values for the fan speed.
If you do not specify the `fanSpeeds` option, Google will use and expect percentage values for the fan speed.
Otherwise, you will be able to set up and use human speakable modes, e.g. "fast" for 100% or "slow" for 25%.

`speeds` will be a comma-separated list of modes, where the mode value corresponds to the speed value to be passed to the device. The mode or value is followed by an equal sign to list different aliases separated by a colon sign.
`fanSpeeds` will be a comma-separated list of modes, where the mode value corresponds to the speed value to be passed to the device. The mode or value is followed by an equal sign to list different aliases separated by a colon sign.
So in the example stated below both "high" and "two" would set the speed to 100%.
Some devices may expect a specific value instead of a percentage, like "1" or "2" as speed values. In this case, you can adjust the configuration and replace the percentage values with the values that the device expects. (e.g.: `speeds="0=away:zero,1=default:standard:one,2=high:two"`).
Some devices may expect a specific value instead of a percentage, like "1" or "2" as speed values. In this case, you can adjust the configuration and replace the percentage values with the values that the device expects. (e.g.: `fanSpeeds="0=away:zero,1=default:standard:one,2=high:two"`).
You are also able to define the language of those aliases.
The option `ordered` will tell the system that your list is ordered and you will then be able to also say "faster" or "slower" and Google will use the next or previous speed.

```shell
Dimmer { ga="Fan" [ speeds="0=away:zero,50=default:standard:one,100=high:two", lang="en", ordered=true ] } # Using specific percentage values for the speed
Dimmer { ga="Fan" [ fanSpeeds="0=away:zero,50=default:standard:one,100=high:two", lang="en", ordered=true ] } # Using specific percentage values for the speed
Switch { ga="Hood" } # No speed control - only on/off
Dimmer { ga="AirPurifier" } # Using percentage values for the speed
Dimmer { ga="AirPurifier" [ speeds="0=away:zero,1=low:one,2=medium:two,3=high:three,4=turbo:four", lang="en", ordered=true ] } # Using specific speed modes/values, which differ from percentage
Dimmer { ga="AirPurifier" [ fanSpeeds="0=away:zero,1=low:one,2=medium:two,3=high:three,4=turbo:four", lang="en", ordered=true ] } # Using specific speed modes/values, which differ from percentage
Switch { ga="AirPurifier" } # No speed control - only on/off
```

Expand Down Expand Up @@ -447,7 +447,7 @@ Number humidityItem (sensorGroup) { ga="humidityAmbient" }
| **Device Type** | [Thermostat](https://developers.home.google.com/cloud-to-cloud/guides/thermostat) |
| **Supported Traits** | [TemperatureSetting](https://developers.home.google.com/cloud-to-cloud/traits/temperaturesetting) |
| **Supported Items** | Group as `Thermostat` with the following members:<br>String or Number as `thermostatMode`<br>(optional) Number as `thermostatHumidityAmbient`<br>(optional) Number as `thermostatTemperatureAmbient`<br>(optional) Number as `thermostatTemperatureSetpoint`<br>(optional) Number as `thermostatTemperatureSetpointLow`<br>(optional) Number as `thermostatTemperatureSetpointHigh` |
| **Configuration** | (optional) `checkState=true/false`<br>(optional) `useFahrenheit=true/false`<br>(optional) `thermostatTemperatureRange="10,30"`<br>(optional) `modes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto"` |
| **Configuration** | (optional) `checkState=true/false`<br>(optional) `useFahrenheit=true/false`<br>(optional) `thermostatTemperatureRange="10,30"`<br>(optional) `thermostatModes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto"` |

Thermostat requires a group of items to be properly configured to be used with Google Assistant. The default temperature unit is Celsius.
To change the temperature unit to Fahrenheit, add the config option `useFahrenheit=true` to the thermostat group.
Expand All @@ -456,15 +456,15 @@ If your thermostat supports a range for the setpoint you can use both `thermosta

If your thermostat does not have a mode, you should create one and manually assign a value (e.g. heat, cool, on, etc.) to have proper functionality.

To map the [default thermostat modes of Google](https://developers.home.google.com/cloud-to-cloud/traits/temperaturesetting.html) (on, off, heat, cool, etc.) to custom ones for your specific setup, you can use the `modes` config option on the thermostat group.
E.g. `[ modes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto" ]` will enable the following five modes in Google Home `"off, heat, eco, on, auto"` that will be translated to `"OFF, COMFORT, ECO, ON, auto"`. You can specify alternative conversions using the colon sign, so that in the former example "BOOST" in openHAB would also be translated to "heat" in Google. For the translation of Google modes to openHAB always the first option after the equal sign is used.
By default the integration will provide `"off,heat,cool,on,heatcool,auto,eco"`.
To map the [default thermostat modes of Google](https://developers.home.google.com/cloud-to-cloud/traits/temperaturesetting.html) (on, off, heat, cool, etc.) to custom ones for your specific setup, you can use the `thermostatModes` config option on the thermostat group.
E.g. `[ thermostatModes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto" ]` will enable the following five modes in Google Home `"off, heat, eco, on, auto"` that will be translated to `"OFF, COMFORT, ECO, ON, auto"`. You can specify alternative conversions using the colon sign, so that in the former example "BOOST" in openHAB would also be translated to "heat" in Google. For the translation of Google modes to openHAB always the first option after the equal sign is used.
By default, the integration will provide `"off,heat,cool,on,heatcool,auto,eco"`.

You can also set up a Thermostat for using it as a temperature sensor. To do so, create a Thermostat group and only add one item member as "thermostatTemperatureAmbient".
However, it is recommended to prefer the `TemperatureSensor` type for simple temperature reports (but currently there is no UI support in Google Home).

```shell
Group thermostatGroup { ga="Thermostat" [ modes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto", thermostatTemperatureRange="10,30", useFahrenheit=false ] }
Group thermostatGroup { ga="Thermostat" [ thermostatModes="off=OFF:WINDOW_OPEN,heat=COMFORT:BOOST,eco=ECO,on=ON,auto", thermostatTemperatureRange="10,30", useFahrenheit=false ] }
Number temperatureItem (thermostatGroup) { ga="thermostatTemperatureAmbient" }
Number humidityItem (thermostatGroup) { ga="thermostatHumidityAmbient" }
Number setpointItem (thermostatGroup) { ga="thermostatTemperatureSetpoint" }
Expand Down
7 changes: 4 additions & 3 deletions functions/devices/fan.js
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ class Fan extends DefaultDevice {

static getAttributes(item) {
const config = this.getConfig(item);
if (!config || !config.speeds) {
if (!config || !(config.speeds || config.fanSpeeds)) {
return {
supportsFanSpeedPercent: true
};
Expand All @@ -23,7 +23,8 @@ class Fan extends DefaultDevice {
},
reversible: false
};
config.speeds.split(',').forEach((speedEntry) => {
const fanSpeeds = config.speeds || config.fanSpeeds;
fanSpeeds.split(',').forEach((speedEntry) => {
try {
const [speedName, speedSynonyms] = speedEntry
.trim()
Expand Down Expand Up @@ -56,7 +57,7 @@ class Fan extends DefaultDevice {
on: itemState > 0
};
const config = this.getConfig(item);
if (config && config.speeds) {
if (config && (config.speeds || config.fanSpeeds)) {
state.currentFanSpeedSetting = itemState.toString();
} else {
state.currentFanSpeedPercent = itemState;
Expand Down
2 changes: 2 additions & 0 deletions functions/devices/thermostat.js
Original file line number Diff line number Diff line change
Expand Up @@ -90,6 +90,8 @@ class Thermostat extends DefaultDevice {
let modes = ['off', 'heat', 'cool', 'on', 'heatcool', 'auto', 'eco'];
if ('modes' in config) {
modes = config.modes.split(',').map((s) => s.trim());
} else if ('thermostatModes' in config) {
modes = config.thermostatModes.split(',').map((s) => s.trim());
}
const modeMap = {};
modes.forEach((pair) => {
Expand Down
75 changes: 75 additions & 0 deletions tests/devices/fan.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -107,4 +107,79 @@ describe('Fan Device', () => {
on: true
});
});

describe('transition tests', () => {
test('getState', () => {
expect(Device.getState({ state: '50 %' })).toStrictEqual({
currentFanSpeedPercent: 50,
on: true
});
expect(
Device.getState({
state: '50 upm',
metadata: {
ga: {
config: {
ordered: true,
fanSpeeds: '0=null:off,50=slow,100=full:fast',
lang: 'en'
}
}
}
})
).toStrictEqual({
currentFanSpeedSetting: '50',
on: true
});
});

test('getAttributes speeds', () => {
const item = {
metadata: {
ga: {
config: {
ordered: true,
fanSpeeds: '0=null:off,50=slow,100=full:fast',
lang: 'en'
}
}
}
};
expect(Device.getAttributes(item)).toStrictEqual({
availableFanSpeeds: {
speeds: [
{
speed_name: '0',
speed_values: [
{
speed_synonym: ['null', 'off'],
lang: 'en'
}
]
},
{
speed_name: '50',
speed_values: [
{
speed_synonym: ['slow'],
lang: 'en'
}
]
},
{
speed_name: '100',
speed_values: [
{
speed_synonym: ['full', 'fast'],
lang: 'en'
}
]
}
],
ordered: true
},
reversible: false
});
});
});
});
34 changes: 34 additions & 0 deletions tests/devices/thermostat.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -394,4 +394,38 @@ describe('Thermostat Device', () => {
});
});
});

describe('transition tests', () => {
test('getModeMap', () => {
const item = {
metadata: {
ga: {
config: {
thermostatModes: 'on=ON:1,off=OFF:2,auto=3'
}
}
}
};
expect(Device.getModeMap(item)).toStrictEqual({
on: ['ON', '1'],
off: ['OFF', '2'],
auto: ['3']
});
});

test('translateModeToGoogle', () => {
const item = {
metadata: {
ga: {
config: {
thermostatModes: 'on=ON:1,off=OFF:2,auto=3'
}
}
}
};
expect(Device.translateModeToGoogle(item, 'OFF')).toBe('off');
expect(Device.translateModeToGoogle(item, '3')).toBe('auto');
expect(Device.translateModeToGoogle(item, 'invalid')).toBe('on');
});
});
});