That’s a great idea!
I’ve been using shelly scripts on my Shelly2PM relays to make a smart switch for smart light bulbs, that can act, if needed also as a clasic switch.
So, as I had some resources already at hand, I took your idea and made a script for BLU GW, to react on events and automatically push the status over mqtt as you did.
Each time a TRV has an event, the script will push to the appropriate MQTT topic for the TRV component. I’ve tested with target temperature changes and position changes done automatically by the TRV itself.
The script has a default topic defined “/remotestatus/{component}/trv”, but this can be overridden by adding a key in BLU GW KVS with name “publish_remotestatus_topic”.
Nonetheless the topic should have a {component} placeholder, as the script is replacing this with the appropriate value for the component that triggered the event.
An advantage would be that is a generic script, that pushes only when a change happens.
A disadvantage is the lack of an initial status if no event is happening on the TRV.
let publishRemoteStatusTopicKey = "publish_remotestatus_topic";
let publishRemoteStatusTopicDefaultValue = "/remotestatus/{component}/trv";
let topicPrefix = null;
// Create an object to act as a map, where key value settings for the Shelly BLU GW device are persisted in memory
var keyValueSettings = {};
/**
* Gets the value of a key from the Shelly's KVS
* @param {*} key the key for which the value will be retrieved
* @param {*} defaultValue the default value for the key, in case no entry is found in KVS
*/
function kvsGet(key, defaultValue) {
try {
var userDataParam = {"key": key, "defaultValue": defaultValue};
Shelly.call(
"KVS.get",
{"key": key},
function (result, error_code, error_message, userData) {
var keyValueSettingObj = null;
if (error_code === 0) {
keyValueSettingObj = {"key": userData.key, "value": result.value, "etag": result.etag};
} else {
keyValueSettingObj = {"key": userData.key, "value": userData.defaultValue, "etag": null};
}
keyValueSettings[key] = keyValueSettingObj;
},
userDataParam
);
} catch (e1) {
console.log("kvsGet has failed for key '", key, "'. Error: ", e1);
}
}
function getMqttConfigHandler(config) {
topicPrefix = config.topic_prefix;
}
function getMqttConfig() {
try {
Shelly.call("MQTT.GetConfig", {}, getMqttConfigHandler);
} catch (e) {
console.log("getMqttConfig has failed. Error: ", e1);
}
}
function bluTrvGetRemoteStatusHandler(status, errNo, errMsg, userData) {
// console.log("bluTrvGetRemoteStatusHandler status: ", status, ", errNo: ", errNo, ", errMsg: ", errMsg, ", userData: ", userData)
if (errNo !== 0) {
console.log("bluTrvGetRemoteStatusHandler error no: ", errNo, ", errMsg: '", errMsg, "', userData: ", userData);
return;
}
if (keyValueSettings[publishRemoteStatusTopicKey] && keyValueSettings[publishRemoteStatusTopicKey].value) {
var topic = topicPrefix + keyValueSettings[publishRemoteStatusTopicKey].value.replace("{component}", userData.component);
MQTT.publish(topic, JSON.stringify(status.status["trv:0"]));
} else
console.log("KVS missing and no default value for key: ", publishRemoteStatusTopicKey);
}
function sendTrvStatus(component, id) {
if (topicPrefix !== null) {
Shelly.call("BluTrv.GetRemoteStatus", {"id": id}, bluTrvGetRemoteStatusHandler, {component: component, id: id});
} else
console.log("sendTrvStatus topicPrefix is null");
};
function eventHandler(event) {
try {
// console.log("event=", event);
if (event && event.info) {
sendTrvStatus(event.info.component, event.info.id)
} else
console.log("eventHandler (event && event.info) is false");
} catch (e1) {
console.log("Shelly handle event '", event, "' has failed. Error: ", e1);
}
}
function addEventHandler() {
try {
console.log("addEventHandler...");
Shelly.addEventHandler(eventHandler);
console.log("addEventHandler done.");
} catch (e1) {
console.log("addEventHandler has failed. Error: ", e1);
}
}
function initScript() {
try {
kvsGet(publishRemoteStatusTopicKey, publishRemoteStatusTopicDefaultValue);
getMqttConfig();
addEventHandler();
} catch (e) {
console.log("initScript has failed. Error: ", e1);
}
}
initScript();