A codec can be used to apply transformations to incoming and outgoing data. Unlike apply functions, a codec is written in a separate JavaScript file which is referenced by the configuration.
To use a codec, configure the path to its JavaScript file using the codec
configuration setting. The codec will then be called to encode data before
publishing and to decode received data for all configured topics. The codec can decide which topics and properties to process, and can suppress messages
and generate additional messages as required.
A codec is a Node.js module which makes encode() and decode() functions available, which are called for
all properties or specific properties of the configured accessory. Codecs must implement a single function, init()
, exported through module.exports
. For example, here is a minimal codec implementation which does nothing:
function init() {
function encode( message ) {
return message; // no-op
}
function decode( message ) {
return message; // no-op
}
// return encode and decode functions
return {
encode,
decode
};
}
module.exports = {
init
};
This could also be written more concisely as:
module.exports = {
init: function() {
return {
encode( message ) {
return message;
},
decode( message ) {
return message;
}
}
}
}
A codec that is used by multiple accessories will only be loaded once, so any accessory-specific state must be stored within the init()
function. The choice to return encode()
and decode()
functions from init()
(as opposed to exporting them directly) is intended to make this easier.
The init()
function is passed a single object containing initialisation parameters for the accessory.
params.log
can be used to write to Homebridge's log.params.config
is the accessory's configuration (as configured inconfig.json
). This gives the codec access to the standard configuration settings, and lets it use its own if required.params.publish
may be used to publish to MQTT directlyparams.notify
may be used to send MQTT-Thing a property notification
The init()
function must return an object containing encode()
and decode()
functions (as described below). This can be just single encode()
and decode()
functions for all properties as above. More commonly a properties map containing property-specific functions is used, as follows:
function init() {
return {
properties: {
targetProp1: {
encode: encodeFunction1,
decode: decodeFunction1
},
targetProp2: {
encode: encodeFunction2
},
},
encode: defaultEncodeFunction,
decode: defaultDecodeFunction
}
}
The allows different encoding/decoding logic for each property. The default encode()
/decode()
functions are called for properties for which no property-specific function is defined.
The encode()
function is called to encode a message before publishing it to MQTT. It is passed three parameters:
message
is the message to be encodedinfo
is an object holding:info.topic
- the MQTT topic to be publishedinfo.property
- the property associated with the publishing operation
output
is a function which may be called to deliver the encoded value asynchronously
The encode()
function may either return the encoded message, or it may deliver it asynchronously by passing it as a parameter to the provided output
function. It if does neither, no value will be published.
The decode
() function is called to decode a message received from MQTT before passing it for processing by MQTT-Thing. It takes three parameters:
message
is the message to be decodedinfo
is an object holding:info.topic
- the MQTT topic receivedinfo.property
the property associated with the received message
output
is a function which may be called to deliver the decoded value asynchronously
The decode()
function may either return the decoded message, or it may deliver it asynchronously by passing it as a parameter to the provided output
function. If it does neither, no notification will be passed on to MQTT-Thing.
The publish()
function provided in init()
's params
may be used to publish a message directly to MQTT.
topic
is the MQTT topic to publishmessage
is the message to publish to MQTT
The message is published directly to MQTT, ignoring any apply function usually with the topic and not passing through the Codec's encode()
function.
The notify()
function provided in init()
's params
may be used to notify MQTT-Thing of the new value for a property. This will deliver the notification to all internal subscribers to the property. Note that generally a corresponding MQTT 'get' topic must have been configured in order for internal subscribers to exist.
property
is the MQTT-Thing property to updatemessage
is the value to be passed to MQTT-Thing
The message is passed directly to MQTT-Thing. It does not pass through any apply function or through the Codec's decode()
function.
When writing a codec, you may find it helpful to start with the no-op implementation in test/empty-codec.js
.
Test examples of codec capabilities can be found in test/test-codec.js
.
This section lists the properties available for each accessory type. All accessories may also support batteryLevel
, chargingState
and statusLowBattery
.
airPressure
, statusActive
, statusFault
, statusTampered
, statusLowBattery
airQuality
, statusActive
, statusFault
, statusTampered
, statusLowBattery
, carbonDioxideLevel
, pm10density
, pm2_5density
, ozonedensity
, nitrogenDioxideDensity
, sulphurDioxideDensity
, VOCDensity
, carbonMonoxideLevel
, airQualityPPM
, currentTemperature
, currentRelativeHumidity
carbonDioxideDetected
, carbonDioxideLevel
, carbonDioxidePeakLevel
, statusActive
, statusFault
, statusTampered
, statusLowBattery
contactSensorState
, statusActive
, statusFault
, statusTampered
, statusLowBattery
switch
, brightness
, volume
, motionDetected
on
, rotationDirection
, rotationSpeed
targetDoorState
, currentDoorState
, doorMoving
, obstructionDetected
, lockTargetState
, lockCurrentState
active
, currentHeaterCoolerState
, targetHeaterCoolerState
, currentTemperature
, lockPhysicalControls
, swingMode
, coolingThresholdTemperature
, heatingThresholdTemperature
, temperatureDisplayUnits
, rotationSpeed
currentRelativeHumidity
, statusActive
, statusFault
, statusTampered
, statusLowBattery
leakDetected
, statusActive
, statusFault
, statusTampered
, statusLowBattery
on
, brightness
, hue
, saturation
, colorTemperature
, white
, HSV
, RGB
, RGBW
, RGBWW
currentAmbientLightLevel
, statusActive
, statusFault
, statusTampered
, statusLowBattery
lockTargetState
, lockCurrentState
mute
, volume
motionDetected
, statusActive
, statusFault
, statusTampered
, statusLowBattery
occupancyDetected
, statusActive
, statusFault
, statusTampered
, statusLowBattery
on
, outletInUse
, currentConsumption
, voltage
, electricCurrent
, totalConsumption
targetState
, currentState
, statusFault
, statusTampered
mute
, volume
switch
, switch0
, switch1
, switch2
, ...
on
active
, input
XX
currentTemperature
, statusActive
, statusFault
, statusTampered
, statusLowBattery
currentHeatingCoolingState
, targetHeatingCoolingState
, currentTemperature
, targetTemperature
, temperatureDisplayUnits
, currentRelativeHumidity
, targetRelativeHumidity
, coolingThresholdTemperature
, heatingThresholdTemperature
active
, inUse
, setDuration
, remainingDuration
currentTemperature
, statusActive
, statusFault
, statusTampered
, statusLowBattery
, currentRelativeHumidity
, airPressure
, weatherCondition
, rain1h
, rain24h
, uvIndex
, visibility
, windDirection
, windSpeed
currentPosition
, targetPosition
, positionState
, holdPosition
, obstructionDetected
currentPosition
, targetPosition
, positionState
, holdPosition
, obstructionDetected
, targetHorizontalTiltAngle
, currentHorizontalTiltAngle
, targetVerticalTiltAngle
, currentVerticalTiltAngle