I got this working. Thanks for the help.
I didn’t need to use a string because a normal switch (as opposed to a dimmer) uses ON and OFF rather than numbers.
Here are my configs, in case any one is interested.
Number officeSmartVentProxy "Office Smart Vent [%d %%]" <heating> (Temperature)
Dimmer officeSmartVentLevel "Office Smart Vent Level [%d %%]" <heating> (Temperature) {mqtt="<[mosquitto:smartthings/Office Smart Vent/level:state:default],
>[mosquitto:smartthings/Office Smart Vent/level:command:*:default]"}
Switch officeSmartVentSwitch "Office Smart Vent Switch [%s]" (Temperature) {mqtt="<[mosquitto:smartthings/Office Smart Vent/switch:state:MAP(onOffLowerToUpper.map)],
>[mosquitto:smartthings/Office Smart Vent/switch:command:*:MAP(onOffUpperToLower.map)"}
And here are my rules, using the jsr223 engine and javascript. I required that the items follow a naming pattern so that I can calculate the Proxy, Switch, and Level item name based on the name of the item that triggered the rule.
var mqttSmartVentProxyRule = new Rule(){
getEventTrigger: function () {
return [
new CommandEventTrigger("officeSmartVentProxy", null)
]
},
execute: function (event) {
var proxy = event.getItem();
var itemName = proxy.getName();
var command = event.getCommand();
if(command == null){ return; }
oh.logInfo("mqttSmartVentProxy", "Smart Vent Proxy recived command, item=[{}], command=[{}], event=[{}]", itemName, command, event);
var switchName = itemName.substring(0, itemName.length() - 5) + "Switch";
var switchItem = ir.getItem(switchName);
var levelName = itemName.substring(0, itemName.length() - 5) + "Level";
var levelItem = ir.getItem(levelName);
if(command == 0){
oh.logInfo("mqttSmartVentProxy", "State is 0");
oh.logInfo("mqttSmartVentProxy", "switchItem=[{}]", switchItem);
be.sendCommand(switchItem, OnOffType.OFF);
be.postUpdate(levelItem, 0);
}
else{
oh.logInfo("mqttSmartVentProxy", "Nonzero state is [{}]", command);
if(switchItem.state == OnOffType.OFF){
oh.logInfo("mqttSmartVentProxy", "Turning switch OFF");
be.sendCommand(switchItem, OnOffType.ON);
}
be.sendCommand(levelItem, command);
}
}
}
var mqttSmartVentLevelRule = new Rule(){
getEventTrigger: function () {
return [
new ChangedEventTrigger("officeSmartVentLevel")
]
},
execute: function (event) {
var levelItem = event.getItem();
var itemName = levelItem.getName();
oh.logInfo("mqttSmartVentLevel", "Smart Vent Level received command, item=[{}], event=[{}]", itemName, event);
var proxyName = itemName.substring(0, itemName.length() - 5) + "Proxy";
var proxyItem = ir.getItem(proxyName);
if(levelItem.state != proxyItem.state){
oh.logInfo("mqttSmartVentLevel", "Got a different value. Updating proxy.");
be.postUpdate(proxyItem, event.getNewState());
}
}
}
var mqttSmartVentSwitchRule = new Rule(){
getEventTrigger: function () {
return [
new ChangedEventTrigger("officeSmartVentSwitch")
]
},
execute: function (event) {
var switchItem = event.getItem();
var itemName = switchItem.getName();
oh.logInfo("mqttSmartVentSwitch", "Smart Vent Switch received command, item=[{}], event=[{}]", itemName, event);
var proxyName = itemName.substring(0, itemName.length() - 6) + "Proxy";
var proxyItem = ir.getItem(proxyName);
var levelName = itemName.substring(0, itemName.length() - 6) + "Level";
var levelItem = ir.getItem(levelName);
var prevLevel = pe.previousState(levelItem, true);
var prevState = null;
if(prevLevel != null){
prevState = prevLevel.state.toString();
}
oh.logInfo("mqttSmartVentSwitch", "Current Level state = [{}], previous=[{}]", levelItem.state, prevState);
setTimeout(function(){
if(event.getNewState() == OnOffType.OFF) {
be.postUpdate(levelItem, 0);
}
else if(prevState != null && levelItem.state == 0){
be.postUpdate(levelItem, prevState);
}
}, 5);
}
}
I might have a few small issues to work out as occasionally there is some weird behavior when a vent is switched from off to on or vice versa, but overall it is working quite well.