-
-
Notifications
You must be signed in to change notification settings - Fork 8
Adding a Device Type Capability
Following release of GHome API this section is due an overhaul. Alexa guidance is correct however Google Home/ Assistant guidance needs documenting.
- An example API/ Web Interface commit to add a new Alexa sensor capability can be viewed here.
- An example Node-RED contrib commit to add a new Alexa sensor capability can be viewed here.
Consider what state object the device will store, see devices.js model for information on current state elements, at time of writing this is as-is:
// attributes : {
// colorModel: String,
// colorTemperatureRange: {
// temperatureMinK: Number,
// temperatureMaxK: Number
// },
// contact: String,
// temperatureRange: {
// temperatureMin: Number,
// temperatureMax: Number,
// },
// temperatureScale: String,
// thermostatModes: [],
// availableModes: Schema.Types.Mixed,
// availableToggles: Schema.Types.Mixed,
// availableFanSpeeds: Schema.Types.Mixed,
// sceneReversible: Boolean,
// roomHint: String,
// require2FA: boolean,
// type2FA: String,
// pin: String
// }
Modify the **replaceCapability **function to return correct format discovery response for new capability:
// BrightnessController
if(capability == "BrightnessController") {
return {
"type": "AlexaInterface",
"interface": "Alexa.BrightnessController",
"version": "3",
"properties": {
"supported": [{
"name": "brightness"
}],
"proactivelyReported": reportState,
"retrievable": reportState
}
};
}
Add state handler to queryDeviceState function, for example:
case "BrightnessController":
// Return brightness percentage
if (deviceJSON.state.hasOwnProperty('brightness') && deviceJSON.state.hasOwnProperty('time')) {
properties.push({
"namespace": "Alexa.BrightnessController",
"name": "brightness",
"value": deviceJSON.state.brightness,
"timeOfSample": deviceJSON.state.time,
"uncertaintyInMilliseconds": 1000
});
}
break;
Add new Interface/ Capability option, for example:
<div class="form-check">
<input title="Brightness Control" type="checkbox" class="form-check-input" name="capabilities" id="BrightnessController" value="BrightnessController">
<label class="form-check-label" for="BrightnessController">
<a data-toggle="tooltip" data-placement="right" title="Set percentage, increase, decrease, dim">Brightness <img class="octicon octicon-question" src="octicons/question.svg"></img></a>
</label>
<br />
</div>
Modify existing device type or add a new one, with necessary validation to enable/ disable interface/ capability. Edit/ augment the checkCapability function, for example:
else if (type.id== "LIGHT" && type.checked && !$('#OTHER').prop('checked')) {
$('#simpleOptions').show();
$('#ReportState').prop('checked', true);
$('#stateReporting').show();
$("#PowerController").prop('checked',true);
//$('#validRangeOptions').show();
$('input[name=appType]').each(function(index){if ($(this).attr("id") != "LIGHT") {$('input[id^='+$(this).attr("id")+']').prop("checked", false)}});
$('input[name=capabilities]').each(function(index){
if ($(this).attr("id") != "PowerController" && $(this).attr("id") != "BrightnessController" && $(this).attr("id") != "ColorController" && $(this).attr("id") != "ColorTemperatureController"){
$('input[id^='+$(this).attr("id")+']').prop("checked", false);
$('input[id^='+$(this).attr("id")+']').attr("disabled", "disabled");
}
else {
if ($(this).attr("id") == "PowerController"){$('input[id^='+$(this).attr("id")+']').prop("checked", true)}
else {$('input[id^='+$(this).attr("id")+']').prop("checked", false)}
$('input[id^='+$(this).attr("id")+']').removeAttr("disabled");
}
});
}
You also need to consider whether further validation is required on this capability (i.e. are new modal elements used), workout the show/ hide logic and apply to:
- clearDevice function
- edit function
Modify generateState function to create dummy state on new device:
case "BrightnessController":
dummyState.brightness = 75;
break;
Modify generateState function to create dummy state on edit existing device:
case "BrightnessController":
if (deviceState.hasOwnProperty('brightness')) {
if (typeof deviceState.brightness == 'number' && (deviceState.brightness >= 0 || deviceState.brightness <= 100)) {
dummyState.brightness = deviceState.brightness;
}
}
else {dummyState.brightness = 75}
break;
Add handler new state objects, plus review whether there is any validation you need to do for a delta payload (range controller, thermostat and percentage use a delta payload for any "Adjust" command. For example:
if (payload.state.hasOwnProperty('brightness')) {dev.state.brightness = payload.state.brightness};
Extend command directive to include new namespace, look for:
// Device-specific directives
Create 60x40 icon, with the same name as capability checkbox id/ value.
Modify Command Node "command" function, specifically switch statements for directive names, look for:
// Command Node Command Function
Note that msg.payload should always contain the target state/ operation.
Update Config Node 'updateState' function to include new state payload element(s) as-per Amazon JSON specification, look for:
// Config Node Update State
Modify Set State Node function, look for:
// Set State Node On Input Function
You'll need to modify the Command Node payload assessment, look for:
// Handle AlexaHome output
Plus modify the general payload handler, look for:
// Set State Payload Handler
Modify replaceCapability function to include necessary discovery response, look for:
// Replace Capability function, replaces 'placeholders' stored under device.capabilities in mongoDB with Amazon JSON
Modify setstate function to include required state/ payload attribute assignment, look for:
// Set State Function, sets device "state" element in MongoDB based upon Node-RED MQTT 'state' message
Modify getstate API endpoint, add correct State Report JSON based on short-hand capability stored in MongoDB look for:
// Get State API, gets device "state" element from MongoDB, used for device status review in Alexa App
Modify to include new checkbox for capability:
<div class="row" align="justify">
<div class="col-sm">
<fieldset class="form-group" id="capabilityType">
<legend>Capabilities</legend>
Modify to include new Alexa App Icon (if necessary):
<div class="col-sm">
<fieldset class="form-group">
<legend>Alexa App Icon</legend>
Modify checkCapability function to include necessary logic to:
- Auto-assign correct icon (based on Capability Name)
- Prohibit additional selections (if necessary)
function checkCapability(check) {
Modify generateState function if this capability has a retrievable state
function generateState(deviceState) {