diff --git a/docs/USAGE.md b/docs/USAGE.md index c15e9a05..ce16a905 100644 --- a/docs/USAGE.md +++ b/docs/USAGE.md @@ -304,11 +304,12 @@ Contact Status "Status" (Lock) {alexa="CurrentLockState"} With the introduction of the [unit of measurement](https://www.openhab.org/docs/concepts/units-of-measurement.html) concept, the item unit can be automatically determined for thermostat and temperature using that feature, removing the need of having to set the metadata scale parameter for each of the relevant items or groups. -Below are two examples; the scale on the first will be set to Fahrenheit based on how it is defined in the item state presentation pattern and the second one will be set based on your openHAB system [regional settings](#regional-settings) (US=Fahrenheit; SI=Celsius). +Below are three examples; the scale on the first will be set to Fahrenheit based on how it is defined in the item state presentation pattern, the second one will be set to Fahrenheit based on the `unit` metadata (introduced in openHAB 4.0), and the last one will be set based on your openHAB system [regional settings](#regional-settings) (US=Fahrenheit; SI=Celsius). ```xtend Number:Temperature Temperature1 "Temperature [%.1f °F]" {alexa="CurrentTemperature"} -Number:Temperature Temperature2 "Temperature" {alexa="CurrentTemperature"} +Number:Temperature Temperature2 "Temperature" {alexa="CurrentTemperature", unit="°F"} +Number:Temperature Temperature3 "Temperature" {alexa="CurrentTemperature"} ``` ## Networking Capabilities diff --git a/lambda/alexa/smarthome/device/attributes/temperature.js b/lambda/alexa/smarthome/device/attributes/temperature.js index eb90e7d1..1ff52911 100644 --- a/lambda/alexa/smarthome/device/attributes/temperature.js +++ b/lambda/alexa/smarthome/device/attributes/temperature.js @@ -98,8 +98,9 @@ export default class Temperature extends DeviceAttribute { if (metadata.getConfigParameter(Parameter.SCALE)) { return metadata.getConfigParameter(Parameter.SCALE).toUpperCase(); } - // Return scale based on item state description and server regional settings otherwise + // Return scale based on item and regional server settings otherwise return AlexaUnitOfTemperature.valueOf({ + unitSymbol: item.unitSymbol, statePresentation: item.stateDescription?.pattern, system: settings.regional?.measurementSystem || settings.regional?.region }); diff --git a/lambda/alexa/smarthome/properties/connectedDevice.js b/lambda/alexa/smarthome/properties/connectedDevice.js index 63e2dd9d..0c38f8ae 100644 --- a/lambda/alexa/smarthome/properties/connectedDevice.js +++ b/lambda/alexa/smarthome/properties/connectedDevice.js @@ -13,9 +13,8 @@ import { isMACAddress } from '#root/utils.js'; import { ItemType } from '#openhab/constants.js'; -import { Capability } from '../constants.js'; +import { Capability, Parameter, ParameterType } from '../constants.js'; import AlexaDevice from '../device/index.js'; -import { Parameter, ParameterType } from '../constants.js'; import AlexaProperty from './property.js'; /** diff --git a/lambda/alexa/smarthome/properties/lowerSetpoint.js b/lambda/alexa/smarthome/properties/lowerSetpoint.js index c6a18d41..8ea1d198 100644 --- a/lambda/alexa/smarthome/properties/lowerSetpoint.js +++ b/lambda/alexa/smarthome/properties/lowerSetpoint.js @@ -11,8 +11,7 @@ * SPDX-License-Identifier: EPL-2.0 */ -import { Property } from '../constants.js'; -import { Parameter, ParameterType } from '../constants.js'; +import { Property, Parameter, ParameterType } from '../constants.js'; import { AlexaUnitOfTemperature } from '../unitOfMeasure.js'; import TargetSetpoint from './targetSetpoint.js'; import ThermostatMode from './thermostatMode.js'; diff --git a/lambda/alexa/smarthome/properties/rangeValue.js b/lambda/alexa/smarthome/properties/rangeValue.js index 40976a4e..44f4b334 100644 --- a/lambda/alexa/smarthome/properties/rangeValue.js +++ b/lambda/alexa/smarthome/properties/rangeValue.js @@ -217,12 +217,12 @@ export default class RangeValue extends Generic { // Define unit of measure as follow: // 1) using parameter value if defined - // 2) using alexa unit of measure id based on - // item type dimension, item state presentation and server regional settings + // 2) using alexa unit of measure id based on item and regional server settings const uom = parameters[Parameter.UNIT_OF_MEASURE] ? parameters[Parameter.UNIT_OF_MEASURE] : AlexaUnitOfMeasure.valueOf({ dimension: item.type.split(':')[1], + unitSymbol: item.unitSymbol, statePresentation: item.stateDescription?.pattern, system: settings.regional?.measurementSystem || settings.regional?.region }); diff --git a/lambda/alexa/smarthome/properties/temperature.js b/lambda/alexa/smarthome/properties/temperature.js index 19db57bc..fbf0df75 100644 --- a/lambda/alexa/smarthome/properties/temperature.js +++ b/lambda/alexa/smarthome/properties/temperature.js @@ -95,10 +95,11 @@ export default class Temperature extends AlexaProperty { // Define scale as follow: // 1) using parameter uppercased value if defined - // 2) using alexa unit name based on item state presentation and server regional settings + // 2) using alexa unit name based on item and regional server settings const scale = parameters[Parameter.SCALE] ? parameters[Parameter.SCALE].toUpperCase() : AlexaUnitOfTemperature.valueOf({ + unitSymbol: item.unitSymbol, statePresentation: item.stateDescription?.pattern, system: settings.regional?.measurementSystem || settings.regional?.region }); diff --git a/lambda/alexa/smarthome/unitOfMeasure.js b/lambda/alexa/smarthome/unitOfMeasure.js index 82bfdeb0..c720f28a 100644 --- a/lambda/alexa/smarthome/unitOfMeasure.js +++ b/lambda/alexa/smarthome/unitOfMeasure.js @@ -341,14 +341,14 @@ class UnitsOfMeasure { dimension: Dimension.LENGTH, symbol: UnitSymbol.INCH, system: UnitSystem.IMPERIAL_US, - default: false + default: true }, { name: AlexaUnitOfMeasure.DISTANCE_FEET, dimension: Dimension.LENGTH, symbol: UnitSymbol.FOOT, system: UnitSystem.IMPERIAL_US, - default: true + default: false }, { name: AlexaUnitOfMeasure.DISTANCE_MILES, @@ -486,13 +486,14 @@ class UnitsOfMeasure { /** * Returns unit of measure based on given parameters * @param {String} dimension + * @param {String} unitSymbol * @param {String} statePresentation * @param {String} system * @return {Object} */ - static getUnitOfMeasure({ dimension, statePresentation, system = UnitSystem.METRIC }) { - // Determine symbol using item state presentation - const symbol = this.getUnitSymbol(statePresentation); + static getUnitOfMeasure({ dimension, unitSymbol, statePresentation, system = UnitSystem.METRIC }) { + // Determine symbol using item unit symbol or item state presentation pattern + const symbol = unitSymbol ?? this.getUnitSymbol(statePresentation); // Return unit of measure using symbol/dimension or fallback to default value using dimension/system return ( this.#UOMS.find((uom) => uom.symbol === symbol && (!dimension || uom.dimension === dimension)) || diff --git a/lambda/openhab/index.js b/lambda/openhab/index.js index 1a2a3355..a2b5260d 100644 --- a/lambda/openhab/index.js +++ b/lambda/openhab/index.js @@ -116,7 +116,7 @@ export default class OpenHAB { method: 'GET', url: '/rest/items', params: { - fields: 'editable,groupNames,groupType,name,label,metadata,stateDescription,tags,type', + fields: 'editable,groupNames,groupType,name,label,metadata,stateDescription,tags,type,unitSymbol', metadata: 'alexa,autoupdate,channel,synonyms' } }; diff --git a/lambda/test/alexa/cases/discovery/temperatureSensor.test.js b/lambda/test/alexa/cases/discovery/temperatureSensor.test.js index 4af71e95..7deb6df1 100644 --- a/lambda/test/alexa/cases/discovery/temperatureSensor.test.js +++ b/lambda/test/alexa/cases/discovery/temperatureSensor.test.js @@ -64,9 +64,20 @@ export default { } }, { - type: 'Number', + type: 'Number:Temperature', name: 'temperature5', label: 'Temperature Sensor 5', + unitSymbol: '°F', + metadata: { + alexa: { + value: 'CurrentTemperature' + } + } + }, + { + type: 'Number', + name: 'temperature6', + label: 'Temperature Sensor 6', metadata: { alexa: { value: 'TemperatureSensor.temperature' // backward compatibility @@ -122,7 +133,20 @@ export default { temperature5: { capabilities: ['Alexa.TemperatureSensor.temperature', 'Alexa.EndpointHealth.connectivity', 'Alexa'], displayCategories: ['TEMPERATURE_SENSOR'], - friendlyName: 'Temperature Sensor 5' + friendlyName: 'Temperature Sensor 5', + cookie: [ + { + name: 'TemperatureSensor', + property: 'temperature', + parameters: { scale: 'FAHRENHEIT' }, + item: { name: 'temperature5', type: 'Number:Temperature' } + } + ] + }, + temperature6: { + capabilities: ['Alexa.TemperatureSensor.temperature', 'Alexa.EndpointHealth.connectivity', 'Alexa'], + displayCategories: ['TEMPERATURE_SENSOR'], + friendlyName: 'Temperature Sensor 6' } } }; diff --git a/lambda/test/openhab.test.js b/lambda/test/openhab.test.js index 09a0235b..07c0c8d1 100644 --- a/lambda/test/openhab.test.js +++ b/lambda/test/openhab.test.js @@ -198,7 +198,7 @@ describe('OpenHAB Tests', () => { describe('get all items', () => { // set default environment const qs = { - fields: 'editable,groupNames,groupType,name,label,metadata,stateDescription,tags,type', + fields: 'editable,groupNames,groupType,name,label,metadata,stateDescription,tags,type,unitSymbol', metadata: 'alexa,autoupdate,channel,synonyms' };