hi there
i’m using a slider to control blinds and i want to limit the slider max to 13 or any desired value to set the max and min for the slider other than 0 to 100
max is the number of rotations i need
I’ve dug into this for some items I’ve got in my setup, and there’s really no way to do it. Its a serious (and strange) limitation of sitemaps that people just have to work around however is appropriate.
I ended up using rules to scale the sliders with proxy items-- for devices I’ve got that are 0-15 (for example), I just divide or multiply by 6.25 to get a 0-100 scale out of it. When I get a command changing the item to something like, say, 51, I’ll send 51/6.25 (8) to the real device, and then update the proxy to set the value to 8*6.25 (50) so the slider stays at the coarser increments. I’ve had to do that with all my volume controls, for example.
Its a hacky work-around, but it does work.
SetPoints are so poorly implemented in the mobile apps (we, at least the Android one) they’re basically useless for this particular scenario.
that was also my idea. See the 0…100 just as a representation of 0%…100% and use rules to scale to whatever value you want to use. I guess this was also the intention of slider.
So the slider sets e.g. an item BlindsPercentage that is used in a rule to calculate the value for your item Blinds.
I don’t have a super simple one I can cut-n-paste easily… the ones I’m using for this use a lambda, and they handle multiple command formats (you can set the proxy item to a Decimal, a Percent, or use Dimmer INCREASE/DECREASE commands)
Basically you’d set up a Number item for the target, and have a “received command” rule for it. In the rule, just do the math and send it to the target item.
Paraphrased:
rule "Test Rule"
when
Item ProxyItem received command
then
targetItem.sendCommand(receivedCommand / 6.25)
end
Something like that, basically. So if ProxyItem gets “51”, you’ll send “8” to targetItem.
I’m just typing that in here, the syntax may not be quite right, but its basically what you would do.
Post what you did. You need to have two items, one that is the proxy and is 0-100, and the target one that is going to mqtt. Make sure your sitemap is bound to the proxy item, not the target one.
Dimmer ShadePosition “Shade” {mqtt=">[mosquitto:shadePosition/shade:command:*:default]"}
Dimmer ShadePercentage "Shade Percentage"
Slider item=ShadePercentage icon=“blinds”
rule “shade”
when
Item ShadePercentage received command
then
ShadePosition.sendCommand(receivedCommand / 20)
ShadePercentage.postUpdate(receivedCommand / 20)
end
You have to have two Item entries – one for the actual value, one for the proxy value. You can do an inverse rule to handle changes in ShadePosition as well:
Like I said in my original reply, its a hacky, ugly fix to something that should just be supported in the framework.
Its hard to say why. You may have some evidence whats going on in the logs.
Its possible Xtend isn’t autoboxing correctly.
Try this:
rule “shade”
when
Item ShadePercentage received command
then
ShadePosition.sendCommand(receivedCommand.intValue / 20)
ShadePercentage.postUpdate(receivedCommand.intValue / 20)
end
This is one of the big problems with xtend scripting – it does some conversions and operator overloads, but not all, and it doesn’t tell you when there isn’t a valid one. That code won’t work with all the possible commands you may get (you need a bunch of instanceof checks and separate tests for that), but it should handle it.
Regardless, you can do it and that should get you down the right path. You may have to just do a bunch more reading to understand how OH and its rules work more. OH2 really isn’t a good platform for doing these sort of things if you’re simply looking for cut-n-paste solutions.
Well, here’s the actual lamba I’m using, which does work. I do more casting and stuff, but maybe it’ll help you figure out what is going on with your code.
val getScaledValueForSlider = [ org.openhab.core.types.Command cmd, GenericItem targetItem, Integer max |
logDebug("Rule", "getScaledValueForSlider(), " + targetItem.toString)
var Integer currentVal = targetItem.getStateAs(DecimalType).intValue()
if (cmd instanceof PercentType)
{
var PercentType percentCommand = cmd as PercentType
var int newValue = percentCommand.intValue
currentVal = (newValue * max / 100).intValue //Scale percentage of volume to Monoprice scale (0 to 38)
}
else
{
if(cmd==INCREASE) //We received input from the UP/DOWN buttons
{
currentVal ++
}
if(cmd==DECREASE)
{
currentVal --
}
}
if (currentVal > max)
{
currentVal = max
}
if (currentVal < 0)
{
currentVal = 0
}
new DecimalType(currentVal)
]
then it gets used like this:
rule "Test Rule"
when
Item Test_Volume received command
then
var DecimalType x = getScaledValueForSlider.apply(receivedCommand, Test_Volume, 38)
targetItem.sendCommand(x)
end
That does a 0-38 mapping of volume level. That code, as-is, works for me. (I changed item names, and the sendCommand is actually another function that is routing things out to a TCP binding in a specific protocol, but otherwise its a straight cut-n-paste)
Its more complex than what you were looking at, but that handles all the various Dimmer commands (Percentages and INCREASE/DECREASE)
rule “shade”
when
Item ShadePercentage received command
then
ShadePosition.sendCommand((receivedCommand as Number) / 20)
ShadePercentage.postUpdate((receivedCommand as Number) / 20)
end