Skip to content

Commit

Permalink
Merge branch 'main' into own-main
Browse files Browse the repository at this point in the history
  • Loading branch information
michikrug committed Nov 27, 2023
2 parents 01dbbbc + 65ac812 commit a09600c
Show file tree
Hide file tree
Showing 30 changed files with 244 additions and 165 deletions.
4 changes: 2 additions & 2 deletions .github/workflows/ci-cd.yml
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,7 @@ jobs:
uses: actions/checkout@v4

- name: Use Node.js 18.x
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18.x
cache: 'npm'
Expand Down Expand Up @@ -94,7 +94,7 @@ jobs:
uses: actions/checkout@v4

- name: Use Node.js 18.x
uses: actions/setup-node@v3
uses: actions/setup-node@v4
with:
node-version: 18.x
cache: 'npm'
Expand Down
21 changes: 19 additions & 2 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -24,9 +24,13 @@ If you have any issues, questions or an idea for additional features, please tak
## Latest Changes

::: tip State of this document
This documentation refers to release [v3.7.0](https://github.com/openhab/openhab-google-assistant/releases/tag/v3.7.0) of [openHAB Google Assistant](https://github.com/openhab/openhab-google-assistant) published on 2023-10-10
This documentation refers to release [v3.8.1](https://github.com/openhab/openhab-google-assistant/releases/tag/v3.8.1) of [openHAB Google Assistant](https://github.com/openhab/openhab-google-assistant) published on 2023-11-26
:::

### v3.8.0

- Added `colorTemperatureInverted=true` option to [`SpecialColorLight`](#light-as-group-with-separate-controls) allowing users to invert the percentage to Kelvin conversion for the `lightColorTemperature` item

### v3.7.0

- Adjusted [`Fan`](#fan-hood-airpurifier) to use `supportsFanSpeedPercent` option
Expand Down Expand Up @@ -99,7 +103,12 @@ Color { ga="Light" [ colorTemperatureRange="2000,9000" ] }
| **Device Type** | [Light](https://developers.home.google.com/cloud-to-cloud/guides/light) |
| **Supported Traits** | [OnOff](https://developers.home.google.com/cloud-to-cloud/traits/onoff), [ColorSetting](https://developers.home.google.com/cloud-to-cloud/traits/colorsetting), [Brightness](https://developers.home.google.com/cloud-to-cloud/traits/brightness) |
| **Supported Items** | Group as `SpecialColorLight` with the following members:<br>(optional) Number or Dimmer as `lightBrightness`<br>(optional) Number or Dimmer as `lightColorTemperature`<br>(optional) Color as `lightColor`<br>(optional) Switch as `lightPower` |
| **Configuration** | (optional) `colorUnit="percent/kelvin/mired"`<br>(optional) `checkState=true/false`<br>(optional) `colorTemperatureRange="minK,maxK"`<br>_Hint: if you want to use `lightColorTemperature`, you must either set `colorUnit` to `kelvin` or `mired` or define a `colorTemperatureRange`, because `colorUnit` defaults to `percent`_ |
| **Configuration** | (optional) `colorUnit="percent/kelvin/mired"`<br>(optional) `checkState=true/false`<br>(optional) `colorTemperatureRange="minK,maxK"`<br>(optional) `colorTemperatureInverted=true/false` |
**Important Hint:** If you want to use `lightColorTemperature`, you must either set `colorUnit` to `kelvin` or `mired` or define a `colorTemperatureRange`, because `colorUnit` defaults to `percent`.
If you use `colorUnit` as percentage values, the lowest color temperature (warm light) will be converted to 0%, and correspondingly the highest color temperature (cold light) will be converted to 100%.
If you need the inverted values for your device, you can set `colorTemperatureInverted=true`. This will convert low Kelvin values to high percentage values and vice versa.
```shell
Group lightGroup { ga="SpecialColorLight" [ colorUnit="kelvin", colorTemperatureRange="2000,9000" ] }
Expand All @@ -109,6 +118,14 @@ Color colorItem (lightGroup) { ga="lightColor" }
Number colorTemperatureItem (lightGroup) { ga="lightColorTemperature" }
```
Example of a light device where low Kelvin values (warm light) are represented by high percentage values in the color temperature item:
```shell
Group lightGroup { ga="SpecialColorLight" [ colorUnit="percent", colorTemperatureRange="2000,6500", colorTemperatureInverted=true ] }
Dimmer brightnessItem (lightGroup) { ga="lightBrightness" }
Dimmer colorTemperatureItem (lightGroup) { ga="lightColorTemperature" }
```
In case you want to control multiple lights using one device with Google Assistant, you can apply the following pattern:
```shell
Expand Down
6 changes: 5 additions & 1 deletion functions/commands/colorabsolutetemperature.js
Original file line number Diff line number Diff line change
Expand Up @@ -42,7 +42,11 @@ class ColorAbsoluteTemperature extends DefaultCommand {
return convertMired(params.color.temperature).toString();
}
const { temperatureMinK, temperatureMaxK } = SpecialColorLight.getAttributes(item).colorTemperatureRange;
return (((params.color.temperature - temperatureMinK) / (temperatureMaxK - temperatureMinK)) * 100).toString();
let percent = ((params.color.temperature - temperatureMinK) / (temperatureMaxK - temperatureMinK)) * 100;
if (SpecialColorLight.getColorTemperatureInverted(item)) {
percent = 100 - percent;
}
return percent.toString();
} catch (error) {
return '0';
}
Expand Down
8 changes: 4 additions & 4 deletions functions/commands/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -285,10 +285,10 @@ class DefaultCommand {
typeof error.errorCode === 'string'
? error.errorCode
: error.statusCode == 404
? 'deviceNotFound'
: error.statusCode == 400
? 'notSupported'
: 'deviceOffline'
? 'deviceNotFound'
: error.statusCode == 400
? 'notSupported'
: 'deviceOffline'
});
});
});
Expand Down
4 changes: 2 additions & 2 deletions functions/devices/charger.js
Original file line number Diff line number Diff line change
Expand Up @@ -36,7 +36,7 @@ class Charger extends DefaultDevice {
state.isPluggedIn = members[member].state === 'ON';
break;
case 'chargerCapacityRemaining': {
const capacity = Math.round(Number(members[member].state));
const capacity = Math.round(parseFloat(members[member].state));
if (!config.unit || config.unit === 'PERCENTAGE') {
let descCapacity = 'UNKNOWN';
if (capacity <= 10) {
Expand Down Expand Up @@ -64,7 +64,7 @@ class Charger extends DefaultDevice {
state.capacityUntilFull = [
{
unit: config.unit || 'PERCENTAGE',
rawValue: Math.round(Number(members[member].state))
rawValue: Math.round(parseFloat(members[member].state))
}
];
break;
Expand Down
2 changes: 1 addition & 1 deletion functions/devices/climatesensor.js
Original file line number Diff line number Diff line change
Expand Up @@ -56,7 +56,7 @@ class ClimateSensor extends DefaultDevice {
state.temperatureSetpointCelsius = temperature;
}
if ('humidityAmbient' in members) {
const humidity = Math.round(Number(members.humidityAmbient.state));
const humidity = Math.round(parseFloat(members.humidityAmbient.state));
state.humidityAmbientPercent = humidity;
state.humiditySetpointPercent = humidity;
}
Expand Down
6 changes: 3 additions & 3 deletions functions/devices/default.js
Original file line number Diff line number Diff line change
Expand Up @@ -93,13 +93,13 @@ class DefaultDevice {
itemType: itemType
}
};
if (config.inverted === true) {
if (!!config.inverted === true) {
metadata.customData.inverted = true;
}
if (config.checkState === true) {
if (!!config.checkState === true) {
metadata.customData.checkState = true;
}
if (config.ackNeeded === true || config.tfaAck === true) {
if (!!config.ackNeeded === true || !!config.tfaAck === true) {
metadata.customData.ackNeeded = true;
}
if (typeof config.pinNeeded === 'string' || typeof config.tfaPin === 'string') {
Expand Down
2 changes: 1 addition & 1 deletion functions/devices/dimmablelight.js
Original file line number Diff line number Diff line change
Expand Up @@ -14,7 +14,7 @@ class DimmableLight extends DefaultDevice {
}

static getState(item) {
const brightness = Math.round(Number(item.state)) || 0;
const brightness = Math.round(parseFloat(item.state)) || 0;
return {
on: brightness > 0,
brightness: brightness
Expand Down
7 changes: 4 additions & 3 deletions functions/devices/fan.js
Original file line number Diff line number Diff line change
Expand Up @@ -51,14 +51,15 @@ class Fan extends DefaultDevice {
}

static getState(item) {
const itemState = Math.round(parseFloat(item.state));
const state = {
on: Number(item.state) > 0
on: itemState > 0
};
const config = this.getConfig(item);
if (config && config.speeds) {
state.currentFanSpeedSetting = item.state.toString();
state.currentFanSpeedSetting = itemState.toString();
} else {
state.currentFanSpeedPercent = Math.round(Number(item.state));
state.currentFanSpeedPercent = itemState;
}
return state;
}
Expand Down
2 changes: 1 addition & 1 deletion functions/devices/humiditysensor.js
Original file line number Diff line number Diff line change
Expand Up @@ -24,7 +24,7 @@ class HumiditySensor extends DefaultDevice {
}

static getState(item) {
const state = Math.round(Number(item.state));
const state = Math.round(parseFloat(item.state));
return {
humidityAmbientPercent: state,
humiditySetpointPercent: state
Expand Down
2 changes: 1 addition & 1 deletion functions/devices/openclosedevice.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class OpenCloseDevice extends DefaultDevice {
let state = 0;
const itemType = item.groupType || item.type;
if (itemType === 'Rollershutter') {
state = Number(item.state);
state = Math.round(parseFloat(item.state));
} else {
state = item.state === 'ON' || item.state === 'OPEN' ? 0 : 100;
}
Expand Down
10 changes: 6 additions & 4 deletions functions/devices/sensor.js
Original file line number Diff line number Diff line change
Expand Up @@ -32,15 +32,17 @@ class Sensor extends DefaultDevice {

static getState(item) {
const config = this.getConfig(item);
return {
const state = {
currentSensorStateData: [
{
name: config.sensorName,
currentSensorState: this.translateStateToGoogle(item),
rawValue: Number(item.state) || 0
currentSensorState: this.translateStateToGoogle(item)
}
]
};
const rawValue = parseFloat(item.state);
if (!isNaN(rawValue)) state.currentSensorStateData[0].rawValue = rawValue;
return state;
}

static translateStateToGoogle(item) {
Expand All @@ -49,7 +51,7 @@ class Sensor extends DefaultDevice {
const states = config.states.split(',').map((s) => s.trim());
for (const state of states) {
const [key, value] = state.split('=').map((s) => s.trim());
if (value == item.state) {
if (value === item.state || value === parseFloat(item.state).toFixed(0)) {
return key;
}
}
Expand Down
2 changes: 1 addition & 1 deletion functions/devices/speaker.js
Original file line number Diff line number Diff line change
Expand Up @@ -30,7 +30,7 @@ class Speaker extends DefaultDevice {

static getState(item) {
return {
currentVolume: Math.round(Number(item.state)) || 0
currentVolume: Math.round(parseFloat(item.state)) || 0
};
}
}
Expand Down
18 changes: 12 additions & 6 deletions functions/devices/specialcolorlight.js
Original file line number Diff line number Diff line change
Expand Up @@ -54,7 +54,7 @@ class SpecialColorLight extends DefaultDevice {
state.on = members[member].state === 'ON';
break;
case 'lightBrightness':
state.brightness = Math.round(Number(members[member].state)) || 0;
state.brightness = Math.round(parseFloat(members[member].state)) || 0;
if (!('lightPower' in members)) {
state.on = state.brightness > 0;
}
Expand Down Expand Up @@ -83,18 +83,20 @@ class SpecialColorLight extends DefaultDevice {
const colorUnit = this.getColorUnit(item);
if (colorUnit === 'kelvin') {
state.color = {
temperatureK: Math.round(Number(members[member].state))
temperatureK: Math.round(parseFloat(members[member].state))
};
} else if (colorUnit === 'mired') {
state.color = {
temperatureK: convertMired(Math.round(Number(members[member].state)))
temperatureK: convertMired(Math.round(parseFloat(members[member].state)))
};
} else {
const { temperatureMinK, temperatureMaxK } = this.getAttributes(item).colorTemperatureRange;
let percent = parseFloat(members[member].state);
if (this.getColorTemperatureInverted(item)) {
percent = 100 - percent;
}
state.color = {
temperatureK:
temperatureMinK +
Math.round(((temperatureMaxK - temperatureMinK) / 100) * Number(members[member].state) || 0)
temperatureK: temperatureMinK + Math.round(((temperatureMaxK - temperatureMinK) / 100) * percent || 0)
};
}
} catch (error) {
Expand Down Expand Up @@ -126,6 +128,10 @@ class SpecialColorLight extends DefaultDevice {
const colorUnit = this.getConfig(item).colorUnit || 'percent';
return colorUnit.toLowerCase();
}

static getColorTemperatureInverted(item) {
return !!this.getConfig(item).colorTemperatureInverted === true;
}
}

module.exports = SpecialColorLight;
2 changes: 1 addition & 1 deletion functions/devices/tv.js
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ class TV extends DefaultDevice {
state.playbackState = members[member].state;
break;
case 'tvVolume':
state.currentVolume = Math.round(Number(members[member].state)) || 0;
state.currentVolume = Math.round(parseFloat(members[member].state)) || 0;
break;
case 'tvChannel':
state.channelNumber = members[member].state;
Expand Down
4 changes: 2 additions & 2 deletions functions/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

2 changes: 1 addition & 1 deletion functions/package.json
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
{
"name": "openhab.google-assistant-smarthome.cloud-function",
"version": "3.7.0",
"version": "3.8.1",
"description": "A Google Assistant, Actions on Google based implementation for openHAB",
"repository": {
"type": "git",
Expand Down
Loading

0 comments on commit a09600c

Please sign in to comment.