Skip to content

Commit

Permalink
Improve discovery request performance
Browse files Browse the repository at this point in the history
* removed state field from getting pulled in discovery request
* added UoM default value logic based on dimension and regional settings
* streamlined rest request options now accepting gzip compressed data

Signed-off-by: jsetton <jeremy.setton@gmail.com>
  • Loading branch information
jsetton committed Aug 28, 2019
1 parent 1913d14 commit 1193716
Show file tree
Hide file tree
Showing 7 changed files with 148 additions and 120 deletions.
15 changes: 9 additions & 6 deletions USAGE.md
Expand Up @@ -241,7 +241,7 @@ Number:Temperature Temperature2 "Temperature" {alexa="TemperatureSenso
* Rollershutter
* Default category: OTHER
* `ThermostatController.targetSetpoint`
* Items that represent a target setpoint for a thermostat. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) unit of measurement unit if Number:Temperature item type; (4) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (5) defaults to Celsius. By default, the temperature range is limited to predefined setpoint values based on the scale parameter. If necessary, the temperature range can be customized using parameter `setpointRange="60:90"`.
* Items that represent a target setpoint for a thermostat. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (4) defaults to Celsius. By default, the temperature range is limited to predefined setpoint values based on the scale parameter. If necessary, the temperature range can be customized using parameter `setpointRange="60:90"`.
* Supported item type:
* Number(:Temperature)
* Supported metadata parameters:
Expand All @@ -252,7 +252,7 @@ Number:Temperature Temperature2 "Temperature" {alexa="TemperatureSenso
* defaults to defined scale range listed above if omitted
* Default category: THERMOSTAT
* `ThermostatController.upperSetpoint`
* Items that represent a upper or HEAT setpoint for a thermostat. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) unit of measurement unit if Number:Temperature item type; (4) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (5) defaults to Celsius. By default, the temperature range is limited to predefined setpoint values based on the scale parameter. If necessary, the temperature range can be customized using parameter `setpointRange="60:90"`.
* Items that represent a upper or HEAT setpoint for a thermostat. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (4) defaults to Celsius. By default, the temperature range is limited to predefined setpoint values based on the scale parameter. If necessary, the temperature range can be customized using parameter `setpointRange="60:90"`.
* Supported item type:
* Number(:Temperature)
* Supported metadata parameters:
Expand All @@ -265,7 +265,7 @@ Number:Temperature Temperature2 "Temperature" {alexa="TemperatureSenso
* defaults to defined scale range listed above if omitted
* Default category: THERMOSTAT
* `ThermostatController.lowerSetpoint`
* Items that represent a lower or COOL setpoint for a thermostat. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) unit of measurement unit if Number:Temperature item type; (4) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (5) defaults to Celsius. By default, the temperature range is limited to predefined setpoint values based on the scale parameter. If necessary, the temperature range can be customized using parameter `setpointRange="60:90"`.
* Items that represent a lower or COOL setpoint for a thermostat. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (4) defaults to Celsius. By default, the temperature range is limited to predefined setpoint values based on the scale parameter. If necessary, the temperature range can be customized using parameter `setpointRange="60:90"`.
* Supported item type:
* Number(:Temperature)
* Supported metadata parameters:
Expand Down Expand Up @@ -302,7 +302,7 @@ Number:Temperature Temperature2 "Temperature" {alexa="TemperatureSenso
* defaults to, depending on the parameters provided, either user-based, preset-based or default item type-based mapping.
* Default category: THERMOSTAT
* `TemperatureSensor.temperature`
* Items that represent the current temperature. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) unit of measurement unit if Number:Temperature item type; (4) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (5) defaults to Celsius.
* Items that represent the current temperature. The scale is determined based on: (1) value set in parameter `scale="Fahrenheit"`; (2) unit of item state presentation (`°F`=Fahrenheit; `°C`=Celsius); (3) your openHAB server regional measurement system or region settings (US=Fahrenheit; SI=Celsius); (4) defaults to Celsius.
* Supported item type:
* Number(:Temperature)
* Supported metadata parameters:
Expand Down Expand Up @@ -519,7 +519,7 @@ Number:Temperature Temperature2 "Temperature" {alexa="TemperatureSenso
* defaults to false
* Default category: OTHER
* `RangeController.rangeValue`
* Items that represent components of a device that are characterized by numbers within a minimum and maximum range. Multiple instances can be configured in a group endpoint. By default, to ask for a specific range, the item label will be used as the friendly name. To configure it, use `friendlyNames` parameter and provide a comma delimited list of different labels (Keep in mind that some names are [not allowed](#friendly-names-not-allowed)). Additionally, pre-defined [asset ids](#asset-catalog) can be used to label a mode as well prefixing with an @ sign (e.g. `friendlyNames="@Setting.FanSpeed,Speed"`). To set the supported range, provide a column delimited list including minimum, maximum and precision values. The latter value will be use as default increment when requesting adjusted range values. Optionally, to name specific presets, like fan speeds low [1] & high value [10], can be added in `presets` parameter and provide a comma delimited list of preset mappings composed of range value and the associated names/asset ids they should be called, delimited by equal and column signs (e.g. `presets="1=@Value.Minimum:@Value.Low:Lowest,10=@Value.Maximum:@Value.High:Highest"`). Another optional settings is `unitOfMeasure` parameter which gives a unit of measure to the range values. By default if omitted, it is based on the unit of measurement number item type that have a supported unit, otherwise, a [unit id](#unit-of-measurement-catalog) can be used. (e.g. `unitOfMeasure=Angle.Degrees`)
* Items that represent components of a device that are characterized by numbers within a minimum and maximum range. Multiple instances can be configured in a group endpoint. By default, to ask for a specific range, the item label will be used as the friendly name. To configure it, use `friendlyNames` parameter and provide a comma delimited list of different labels (Keep in mind that some names are [not allowed](#friendly-names-not-allowed)). Additionally, pre-defined [asset ids](#asset-catalog) can be used to label a mode as well prefixing with an @ sign (e.g. `friendlyNames="@Setting.FanSpeed,Speed"`). To set the supported range, provide a column delimited list including minimum, maximum and precision values. The latter value will be use as default increment when requesting adjusted range values. Optionally, to name specific presets, like fan speeds low [1] & high value [10], can be added in `presets` parameter and provide a comma delimited list of preset mappings composed of range value and the associated names/asset ids they should be called, delimited by equal and column signs (e.g. `presets="1=@Value.Minimum:@Value.Low:Lowest,10=@Value.Maximum:@Value.High:Highest"`). Another optional settings is `unitOfMeasure` parameter which gives a unit of measure to the range values. It is determined based on: (1) [unit id](#unit-of-measurement-catalog) set in parameter `unitOfMeasure=Angle.Degrees`; (2) supported unit of item state presentation; (3) default unit of measurement for item type with dimension based on your openHAB server regional settings; (4) defaults to empty.
* Supported item type:
* Dimmer
* Number
Expand All @@ -539,7 +539,10 @@ Number:Temperature Temperature2 "Temperature" {alexa="TemperatureSenso
* presets=`<presets>` (optional)
* each preset formatted as `<presetValue>=<@assetIdOrName1>:<@assetIdOrName2>:...`
* unitOfMeasure=`<unitId>` (optional)
* defaults to item state unit of measurement symbol for Number:* item types
* defaults to unit of item state presentation or default unit of measurement for the Number:* item types listed below:
* Number:Angle [`Angle.Degrees`]
* Number:Length [`Distance.Meters` (SI); `Distance.Inches` (US)]
* Number:Temperature [`Temperature.Celsius` (SI); `Temperature.Fahrenheit` (US)]
* Default category: OTHER
* `ToggleController.toggleState`
* Items that represent components of a device that can be turned on or off. Multiple instances can be configured in a group endpoint. By default, to ask for a specific range, the item label will be used as the friendly name. To configure it, use `friendlyNames` parameter and provide a comma delimited list of different labels (Keep in mind that some names are [not allowed](#friendly-names-not-allowed)). Additionally, pre-defined [asset ids](#asset-catalog) can be used to label a mode as well with an @ sign prefix (e.g. `friendlyNames="@Setting.Oscillate,Rotate"`).
Expand Down
34 changes: 33 additions & 1 deletion lambda/smarthome/alexa/capabilities.js
Expand Up @@ -14,7 +14,7 @@
/**
* Amazon Smart Home Skill Capabilities for API V3
*/
const { CAPABILITIES, PROPERTY_SCHEMAS, ASSET_IDENTIFIERS, DISPLAY_CATEGORIES } = require('./config.js');
const { CAPABILITIES, PROPERTY_SCHEMAS, ASSET_IDENTIFIERS, DISPLAY_CATEGORIES, UNIT_OF_MEASUREMENT } = require('./config.js');

/**
* Returns alexa capability display category for a given interface
Expand Down Expand Up @@ -317,6 +317,37 @@ function getPropertyStateMap(property) {
return Object.keys(userMap).length > 0 ? userMap : customMap || defaultMap;
}

/**
* Returns unit of measurement based on given query
* @param {Object} query
* @return {*}
*/
function getUnitOfMeasure(query) {
let result;
// Find unit of measurement matching query
Object.keys(UNIT_OF_MEASUREMENT).some(dimension => {
if (!query.dimension || query.dimension === dimension) {
const values = UNIT_OF_MEASUREMENT[dimension].filter(measurement =>
query.id && measurement.id === query.id ||
query.symbol && measurement.symbol === query.symbol ||
query.unit && measurement.unit === query.unit
);
// Search based on query system fallback to first value
result = values.find(measurement => measurement.system === query.system) || values.shift();
return result;
}
});
// Find unit of measurement default value if result empty and query dimension defined
if (!result && UNIT_OF_MEASUREMENT[query.dimension]) {
const values = UNIT_OF_MEASUREMENT[query.dimension].filter(measurement => measurement.default);
// Search based on query system fallback to international system (SI)
result = values.find(measurement => measurement.system === query.system) ||
values.find(measurement => measurement.system === 'SI');
}
// Return result property if defined, otherwise whole object
return result && query.property ? result[query.property] : result;
}

/**
* Determines if light endpoint is in color mode
* @param {Object} colorItem
Expand Down Expand Up @@ -357,6 +388,7 @@ module.exports = {
getPropertySchema: getPropertySchema,
getPropertySettings: getPropertySettings,
getPropertyStateMap: getPropertyStateMap,
getUnitOfMeasure: getUnitOfMeasure,
isInColorMode: isInColorMode,
isSupportedDisplayCategory: isSupportedDisplayCategory
};
63 changes: 32 additions & 31 deletions lambda/smarthome/alexa/config.js
Expand Up @@ -543,15 +543,16 @@ module.exports = Object.freeze({
* Defines alexa supported unit of measurement
* https://developer.amazon.com/docs/device-apis/alexa-rangecontroller.html#supported-values-for-unitofmeasure
* https://developer.amazon.com/docs/device-apis/alexa-property-schemas.html (Alexa units)
* https://www.openhab.org/docs/concepts/units-of-measurement.html#list-of-units (OH symbols)
* https://www.openhab.org/docs/concepts/units-of-measurement.html#list-of-units (OH symbols + defaults)
*
* {
* '<ohItemTypeNumberDimension>': [
* {
* 'id': <alexaUnitOfMesureId>, (Alexa unitOfMeasure id used by RangeController interface)
* 'unit': <alexaUnit>, (Alexa unit properties naming convention)
* 'symbol': <ohUnitOfMeasureSymbol>, (OH unit of measurement item state symbol)
* 'system': <measurementSystem> (Measurement sytem)
* 'id': <alexaUnitOfMesureId>, (Alexa unitOfMeasure id used by RangeController interface)
* 'unit': <alexaUnit>, (Alexa unit properties naming convention)
* 'symbol': <ohUnitOfMeasureSymbol>, (OH unit of measurement item state symbol)
* 'system': <measurementSystem>, (Measurement sytem)
* 'default': <ohUnitOfMesureDefault>, (OH unit of measurement default boolean)
* },
* ...
* ],
Expand All @@ -562,42 +563,42 @@ module.exports = Object.freeze({
*/
UNIT_OF_MEASUREMENT: {
'Angle': [
{'id': 'Angle.Degrees', 'unit': undefined, 'symbol': '°', 'system': 'SI'},
{'id': 'Angle.Radians', 'unit': undefined, 'symbol': 'rad', 'system': 'SI'},
{'id': 'Angle.Degrees', 'unit': undefined, 'symbol': '°', 'system': 'SI', 'default': true },
{'id': 'Angle.Radians', 'unit': undefined, 'symbol': 'rad', 'system': 'SI', 'default': false},
],
'Dimensionless': [
{'id': 'Percent', 'unit': undefined, 'symbol': '%', 'system': 'SI'},
{'id': 'Percent', 'unit': undefined, 'symbol': '%', 'system': 'SI', 'default': false},
],
'Length': [
{'id': 'Distance.Yards', 'unit': undefined, 'symbol': 'yd', 'system': 'US'},
{'id': 'Distance.Inches', 'unit': undefined, 'symbol': 'in', 'system': 'US'},
{'id': 'Distance.Meters', 'unit': undefined, 'symbol': 'm', 'system': 'SI'},
{'id': 'Distance.Feet', 'unit': undefined, 'symbol': 'ft', 'system': 'US'},
{'id': 'Distance.Miles', 'unit': undefined, 'symbol': 'mi', 'system': 'US'},
{'id': 'Distance.Kilometers', 'unit': undefined, 'symbol': 'km', 'system': 'SI'},
{'id': 'Distance.Yards', 'unit': undefined, 'symbol': 'yd', 'system': 'US', 'default': false},
{'id': 'Distance.Inches', 'unit': undefined, 'symbol': 'in', 'system': 'US', 'default': true },
{'id': 'Distance.Meters', 'unit': undefined, 'symbol': 'm', 'system': 'SI', 'default': true },
{'id': 'Distance.Feet', 'unit': undefined, 'symbol': 'ft', 'system': 'US', 'default': false},
{'id': 'Distance.Miles', 'unit': undefined, 'symbol': 'mi', 'system': 'US', 'default': false},
{'id': 'Distance.Kilometers', 'unit': undefined, 'symbol': 'km', 'system': 'SI', 'default': false},
],
'Mass': [
{'id': 'Mass.Kilograms', 'unit': 'KILOGRAM', 'symbol': 'kg', 'system': 'SI'},
{'id': 'Mass.Grams', 'unit': 'GRAM', 'symbol': 'g', 'system': 'SI'},
{'id': 'Weight.Pounds', 'unit': 'POUND', 'symbol': 'lb', 'system': 'US'},
{'id': 'Weight.Ounces', 'unit': 'OUNCE', 'symbol': 'oz', 'system': 'US'},
{'id': 'Mass.Kilograms', 'unit': 'KILOGRAM', 'symbol': 'kg', 'system': 'SI', 'default': false},
{'id': 'Mass.Grams', 'unit': 'GRAM', 'symbol': 'g', 'system': 'SI', 'default': false},
{'id': 'Weight.Pounds', 'unit': 'POUND', 'symbol': 'lb', 'system': 'US', 'default': false},
{'id': 'Weight.Ounces', 'unit': 'OUNCE', 'symbol': 'oz', 'system': 'US', 'default': false},
],
'Temperature': [
{'id': 'Temperature.Degrees', 'unit': undefined, 'symbol': '°', 'system': 'SI'},
{'id': 'Temperature.Celsius', 'unit': 'CELSIUS', 'symbol': '°C', 'system': 'SI'},
{'id': 'Temperature.Fahrenheit', 'unit': 'FAHRENHEIT', 'symbol': '°F', 'system': 'US'},
{'id': 'Temperature.Kelvin', 'unit': 'KELVIN', 'symbol': 'K', 'system': 'SI'},
{'id': 'Temperature.Degrees', 'unit': undefined, 'symbol': '°', 'system': 'SI', 'default': false},
{'id': 'Temperature.Celsius', 'unit': 'CELSIUS', 'symbol': '°C', 'system': 'SI', 'default': true },
{'id': 'Temperature.Fahrenheit', 'unit': 'FAHRENHEIT', 'symbol': '°F', 'system': 'US', 'default': true },
{'id': 'Temperature.Kelvin', 'unit': 'KELVIN', 'symbol': 'K', 'system': 'SI', 'default': false},
],
'Volume': [
{'id': 'Volume.Gallons', 'unit': 'UK_GALLON', 'symbol': 'gal', 'system': 'UK'},
{'id': 'Volume.Gallons', 'unit': 'US_FLUID_GALLON', 'symbol': 'gal', 'system': 'US'},
{'id': 'Volume.Pints', 'unit': 'UK_PINT', 'symbol': 'pt', 'system': 'UK'},
{'id': 'Volume.Pints', 'unit': 'US_FLUID_PINT', 'symbol': 'pt', 'system': 'US'},
{'id': 'Volume.Quarts', 'unit': 'UK_QUART', 'symbol': 'qt', 'system': 'UK'},
{'id': 'Volume.Quarts', 'unit': 'US_FLUID_QUART', 'symbol': 'qt', 'system': 'US'},
{'id': 'Volume.Liters', 'unit': 'LITER', 'symbol': 'l', 'system': 'SI'},
{'id': 'Volume.CubicMeters', 'unit': 'CUBIC_METER', 'symbol': 'm3', 'system': 'SI'},
{'id': 'Volume.CubicFeet', 'unit': 'CUBIC_FOOT', 'symbol': 'ft3', 'system': 'US'},
{'id': 'Volume.Gallons', 'unit': 'UK_GALLON', 'symbol': 'gal', 'system': 'UK', 'default': false},
{'id': 'Volume.Gallons', 'unit': 'US_FLUID_GALLON', 'symbol': 'gal', 'system': 'US', 'default': false},
{'id': 'Volume.Pints', 'unit': 'UK_PINT', 'symbol': 'pt', 'system': 'UK', 'default': false},
{'id': 'Volume.Pints', 'unit': 'US_FLUID_PINT', 'symbol': 'pt', 'system': 'US', 'default': false},
{'id': 'Volume.Quarts', 'unit': 'UK_QUART', 'symbol': 'qt', 'system': 'UK', 'default': false},
{'id': 'Volume.Quarts', 'unit': 'US_FLUID_QUART', 'symbol': 'qt', 'system': 'US', 'default': false},
{'id': 'Volume.Liters', 'unit': 'LITER', 'symbol': 'l', 'system': 'SI', 'default': false},
{'id': 'Volume.CubicMeters', 'unit': 'CUBIC_METER', 'symbol': 'm3', 'system': 'SI', 'default': false},
{'id': 'Volume.CubicFeet', 'unit': 'CUBIC_FOOT', 'symbol': 'ft3', 'system': 'US', 'default': false},
]
},

Expand Down

0 comments on commit 1193716

Please sign in to comment.