Skip to content

Commit

Permalink
Add unit of measure support for new item unit symbol property (#598)
Browse files Browse the repository at this point in the history
Signed-off-by: jsetton <[email protected]>
  • Loading branch information
jsetton authored Aug 7, 2023
1 parent 19b7adb commit eac8822
Show file tree
Hide file tree
Showing 10 changed files with 45 additions and 19 deletions.
5 changes: 3 additions & 2 deletions docs/USAGE.md
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
3 changes: 2 additions & 1 deletion lambda/alexa/smarthome/device/attributes/temperature.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down
3 changes: 1 addition & 2 deletions lambda/alexa/smarthome/properties/connectedDevice.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';

/**
Expand Down
3 changes: 1 addition & 2 deletions lambda/alexa/smarthome/properties/lowerSetpoint.js
Original file line number Diff line number Diff line change
Expand Up @@ -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';
Expand Down
4 changes: 2 additions & 2 deletions lambda/alexa/smarthome/properties/rangeValue.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down
3 changes: 2 additions & 1 deletion lambda/alexa/smarthome/properties/temperature.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
});
Expand Down
11 changes: 6 additions & 5 deletions lambda/alexa/smarthome/unitOfMeasure.js
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down Expand Up @@ -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)) ||
Expand Down
2 changes: 1 addition & 1 deletion lambda/openhab/index.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
}
};
Expand Down
28 changes: 26 additions & 2 deletions lambda/test/alexa/cases/discovery/temperatureSensor.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down Expand Up @@ -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'
}
}
};
2 changes: 1 addition & 1 deletion lambda/test/openhab.test.js
Original file line number Diff line number Diff line change
Expand Up @@ -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'
};

Expand Down

0 comments on commit eac8822

Please sign in to comment.