diff --git a/docs/USAGE.md b/docs/USAGE.md index 345e53e0..077fec6a 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -24,7 +24,7 @@ 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.8.0](https://github.com/openhab/openhab-google-assistant/releases/tag/v3.8.0) of [openHAB Google Assistant](https://github.com/openhab/openhab-google-assistant) published on 2023-11-03 +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 diff --git a/functions/devices/charger.js b/functions/devices/charger.js index 95c481d4..9db3480a 100644 --- a/functions/devices/charger.js +++ b/functions/devices/charger.js @@ -40,7 +40,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) { @@ -68,7 +68,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; diff --git a/functions/devices/climatesensor.js b/functions/devices/climatesensor.js index 314c7d82..81f6acef 100644 --- a/functions/devices/climatesensor.js +++ b/functions/devices/climatesensor.js @@ -71,7 +71,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; } diff --git a/functions/devices/dimmablelight.js b/functions/devices/dimmablelight.js index 6ef330e5..105bbb75 100644 --- a/functions/devices/dimmablelight.js +++ b/functions/devices/dimmablelight.js @@ -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 diff --git a/functions/devices/fan.js b/functions/devices/fan.js index f7da1385..6e6a4161 100644 --- a/functions/devices/fan.js +++ b/functions/devices/fan.js @@ -119,29 +119,30 @@ class Fan extends DefaultDevice { const config = this.getConfig(item); const itemType = item.groupType || item.type; if (itemType !== 'Group') { + const itemState = Math.round(parseFloat(item.state)); const state = { - currentFanSpeedPercent: Math.round(Number(item.state)), - on: Number(item.state) > 0 + currentFanSpeedPercent: itemState, + on: itemState > 0 }; if (config.fanSpeeds) { - state.currentFanSpeedSetting = item.state.toString(); + state.currentFanSpeedSetting = itemState.toString(); } return state; } else { const state = {}; const config = this.getConfig(item); const members = this.getMembers(item); - if ('fanPower' in members) { - state.on = members.fanPower.state === 'ON'; - } else if ('fanSpeed' in members) { - state.on = Number(members.fanSpeed.state) > 0; - } if ('fanSpeed' in members) { - state.currentFanSpeedPercent = Number(members.fanSpeed.state); + const itemState = Math.round(parseFloat(members.fanSpeed.state)); + state.on = itemState > 0; + state.currentFanSpeedPercent = itemState; if (config.fanSpeeds) { - state.currentFanSpeedSetting = members.fanSpeed.state.toString(); + state.currentFanSpeedSetting = itemState.toString(); } } + if ('fanPower' in members) { + state.on = members.fanPower.state === 'ON'; + } if ('fanMode' in members && config.fanModeName && config.fanModeSettings) { const modeNames = config.fanModeName.split(',').map((s) => s.trim()); state.currentModeSettings = { @@ -152,7 +153,7 @@ class Fan extends DefaultDevice { if ('fanFilterLifeTime' in members || 'fanPM25' in members) { state.currentSensorStateData = []; if ('fanFilterLifeTime' in members) { - const itemState = Number(members.fanFilterLifeTime.state); + const itemState = parseFloat(members.fanFilterLifeTime.state); state.currentSensorStateData.push({ name: 'FilterLifeTime', currentSensorState: this.translateFilterLifeTime(itemState), @@ -162,7 +163,7 @@ class Fan extends DefaultDevice { if ('fanPM25' in members) { state.currentSensorStateData.push({ name: 'PM2.5', - rawValue: Number(members.fanPM25.state) + rawValue: parseFloat(members.fanPM25.state) }); } } diff --git a/functions/devices/humiditysensor.js b/functions/devices/humiditysensor.js index 399e0035..b9df74b1 100644 --- a/functions/devices/humiditysensor.js +++ b/functions/devices/humiditysensor.js @@ -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 diff --git a/functions/devices/openclosedevice.js b/functions/devices/openclosedevice.js index c7f3c5cd..a92c64be 100644 --- a/functions/devices/openclosedevice.js +++ b/functions/devices/openclosedevice.js @@ -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; } diff --git a/functions/devices/sensor.js b/functions/devices/sensor.js index 77435f5d..fac8b6bc 100644 --- a/functions/devices/sensor.js +++ b/functions/devices/sensor.js @@ -36,15 +36,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) { @@ -53,7 +55,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; } } diff --git a/functions/devices/speaker.js b/functions/devices/speaker.js index 1688b6dd..b0b587ff 100644 --- a/functions/devices/speaker.js +++ b/functions/devices/speaker.js @@ -33,7 +33,7 @@ class Speaker extends DefaultDevice { static getState(item) { return { - currentVolume: Math.round(Number(item.state)) || 0 + currentVolume: Math.round(parseFloat(item.state)) || 0 }; } } diff --git a/functions/devices/specialcolorlight.js b/functions/devices/specialcolorlight.js index c8f5c6cf..17535201 100644 --- a/functions/devices/specialcolorlight.js +++ b/functions/devices/specialcolorlight.js @@ -72,7 +72,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; } @@ -101,15 +101,15 @@ 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 = Number(members[member].state); + let percent = parseFloat(members[member].state); if (this.getColorTemperatureInverted(item)) { percent = 100 - percent; } diff --git a/functions/devices/tv.js b/functions/devices/tv.js index 330921af..5bd112b6 100644 --- a/functions/devices/tv.js +++ b/functions/devices/tv.js @@ -118,7 +118,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; diff --git a/functions/package.json b/functions/package.json index 7b072d0a..b9bfddb2 100644 --- a/functions/package.json +++ b/functions/package.json @@ -1,6 +1,6 @@ { "name": "openhab.google-assistant-smarthome.cloud-function", - "version": "3.8.0", + "version": "3.8.1", "description": "A Google Assistant, Actions on Google based implementation for openHAB", "repository": { "type": "git", diff --git a/package.json b/package.json index d1f85e50..3da4d6f9 100644 --- a/package.json +++ b/package.json @@ -1,6 +1,6 @@ { "name": "openhab.google-assistant-smarthome", - "version": "3.8.0", + "version": "3.8.1", "description": "A Google Assistant, Actions on Google based implementation for openHAB", "main": "functions/index.js", "repository": { diff --git a/tests/devices/charger.test.js b/tests/devices/charger.test.js index a9536b5b..bbfeb1bb 100644 --- a/tests/devices/charger.test.js +++ b/tests/devices/charger.test.js @@ -335,7 +335,7 @@ describe('Charger Device', () => { }, { name: 'CapacityRemaining', - state: '4000.123', + state: '4000.123 wh', type: 'Number', metadata: { ga: { diff --git a/tests/devices/climatesensor.test.js b/tests/devices/climatesensor.test.js index f4243642..06d2e3b7 100644 --- a/tests/devices/climatesensor.test.js +++ b/tests/devices/climatesensor.test.js @@ -161,7 +161,7 @@ describe('ClimateSensor Device', () => { }, { name: 'Humidity', - state: '59.7', + state: '59.7 %', type: 'Number', metadata: { ga: { @@ -208,7 +208,7 @@ describe('ClimateSensor Device', () => { members: [ { name: 'Humidity', - state: '30.3', + state: '30.3 %', type: 'Number', metadata: { ga: { diff --git a/tests/devices/dimmablelight.test.js b/tests/devices/dimmablelight.test.js index 2bd34477..37ab65cf 100644 --- a/tests/devices/dimmablelight.test.js +++ b/tests/devices/dimmablelight.test.js @@ -21,7 +21,7 @@ describe('DimmableLight Device', () => { }); test('getState', () => { - expect(Device.getState({ state: '50' })).toStrictEqual({ + expect(Device.getState({ state: '50 %' })).toStrictEqual({ on: true, brightness: 50 }); diff --git a/tests/devices/fan.test.js b/tests/devices/fan.test.js index 2e556394..ef346112 100644 --- a/tests/devices/fan.test.js +++ b/tests/devices/fan.test.js @@ -377,7 +377,7 @@ describe('Fan Device', () => { value: 'fanSpeed' } }, - state: '50' + state: '50 %' } ] }; @@ -437,7 +437,7 @@ describe('Fan Device', () => { value: 'fanFilterLifeTime' } }, - state: '70' + state: '70 h' } ] }; @@ -469,7 +469,7 @@ describe('Fan Device', () => { value: 'fanPM25' } }, - state: '20' + state: '20 ppm' } ] }; diff --git a/tests/devices/humiditysensor.test.js b/tests/devices/humiditysensor.test.js index 8684faac..b6311f48 100644 --- a/tests/devices/humiditysensor.test.js +++ b/tests/devices/humiditysensor.test.js @@ -30,7 +30,7 @@ describe('HumiditySensor Device', () => { }); test('getState', () => { - expect(Device.getState({ state: '10.3' })).toStrictEqual({ + expect(Device.getState({ state: '9.6 %' })).toStrictEqual({ humidityAmbientPercent: 10, humiditySetpointPercent: 10 }); diff --git a/tests/devices/openclosedevice.test.js b/tests/devices/openclosedevice.test.js index 322b8143..ae5dbe43 100644 --- a/tests/devices/openclosedevice.test.js +++ b/tests/devices/openclosedevice.test.js @@ -84,7 +84,7 @@ describe('OpenCloseDevice Device', () => { test('getState Rollershutter', () => { const item = { type: 'Rollershutter', - state: '25' + state: '25 %' }; expect(Device.getState(item)).toStrictEqual({ openPercent: 75 diff --git a/tests/devices/sensor.test.js b/tests/devices/sensor.test.js index 68b8f633..2a7a17c3 100644 --- a/tests/devices/sensor.test.js +++ b/tests/devices/sensor.test.js @@ -97,7 +97,7 @@ describe('Sensor Device', () => { } } }, - state: '10' + state: '10 ppm' }; expect(Device.getState(item)).toStrictEqual({ currentSensorStateData: [ @@ -110,6 +110,29 @@ describe('Sensor Device', () => { }); }); + test('getState with string state', () => { + const item = { + metadata: { + ga: { + config: { + sensorName: 'Sensor', + valueUnit: 'AQI', + states: 'good=good,moderate=moderate,poor=poor' + } + } + }, + state: 'moderate' + }; + expect(Device.getState(item)).toStrictEqual({ + currentSensorStateData: [ + { + currentSensorState: 'moderate', + name: 'Sensor' + } + ] + }); + }); + test('getState no matching state', () => { const item = { metadata: { diff --git a/tests/devices/speaker.test.js b/tests/devices/speaker.test.js index 639e0649..f7535cb1 100644 --- a/tests/devices/speaker.test.js +++ b/tests/devices/speaker.test.js @@ -57,7 +57,7 @@ describe('Speaker Device', () => { }); test('getState', () => { - expect(Device.getState({ state: '10' })).toStrictEqual({ + expect(Device.getState({ state: '10 %' })).toStrictEqual({ currentVolume: 10 }); expect(Device.getState({ state: '90' })).toStrictEqual({ diff --git a/tests/devices/specialcolorlight.test.js b/tests/devices/specialcolorlight.test.js index 4afcb344..2fab6fde 100644 --- a/tests/devices/specialcolorlight.test.js +++ b/tests/devices/specialcolorlight.test.js @@ -505,7 +505,7 @@ describe('SpecialColorLight Device', () => { }, members: [ { - state: '0', + state: '0 %', type: 'Number', metadata: { ga: { @@ -514,7 +514,7 @@ describe('SpecialColorLight Device', () => { } }, { - state: '20', + state: '20 K', type: 'Number', metadata: { ga: { diff --git a/tests/devices/tv.test.js b/tests/devices/tv.test.js index 67c9318c..e51e8bf6 100644 --- a/tests/devices/tv.test.js +++ b/tests/devices/tv.test.js @@ -556,7 +556,7 @@ describe('TV Device', () => { } }, { - state: '50', + state: '50 %', type: 'Dimmer', metadata: { ga: {