Combine things to one output?

Hello,
is there some simplier way how to combine two Things to one other than by rules?

Typical usecase would be to store data separately, so need for two things is obvious but you wanna output just one line in the sitemap.

Something like test.items:

Number Item_one {mqtt:channel_1} 
Number Item_two {mqtt:channel_2}

and something like test.sitemap

Frame label="test"{
Text item=Item_one,Item_two
}

or when you wanna print humidity in the room / humidity in the house for quick overview etc.

Nothing I can’t solve by rules, but it does look to me too unnecessary to create third item and bunch of lines in rule file just to do oneline less in the sitemap, but for UX it’s not always best to throw everysingle item to separate line.

IMHO each sitemap element will accept only one one item. What you want might be possible in a webview or using Habpanel.as an UI.

True, but that Item can be a group with several items as members.

yes sure, but basicUI will draw them on separate rows (which is correct indeed)
I’m looking just for string combining if there is any other than thorough the rules :wink:

So I found this:

but it’s 3yrs old, so … is this approach still valid in OH2 or not?

That should still work.

sadly same errors as in original thread… well I guess I need bit of help here :stuck_out_tongue:

The above link is a way to use profiles on your items, and I leverage this with two Lifx light bulbs (I used the follow profile). I don’t know how it would work with mqtt items, but it would provide 1 item to be set on your site map.

1 Like

Well, the simple way is to use a virtual Item for displaying and a rule to build the string to be displayed.

There might be an option to manipulate the label of the Item, but that would also need a rule, and I think it’s more complex.
In some situations, especially if it’s a boolean information to display, you could use visibility to change appearance of a widget through another item, but that’s no option for two number items.

btw why output to display layer, eg to basicui is number anyway?
Wouldnt make sense everything act as a string so combining them would be as easy as possible?

@anonymous.one thanks for link, but I dont thing this is how it should be done, way too complex for that simple task imho

No idea. Choose what you like, it’s not that difficult

rule "my string combiner"
when
   Item myItemA changed or
   Item myItemB changed
then
   myMagicOutputString.postUpdate ( myItemA.state.toString + " , " + myItemB.state.toString)
end

thanks @rossko57 that helped,

just one small need… how do I format those Items before converting to strings for output?
eg

Item myItemA [%.2f %%]

Well, because the item has a status, and this status is most likely to be used in rules. You don’t want to parse strings everytime you want to compare or add something :wink: It’s easy to change display behavior and it’s easy to build a string from a number in a rule.
Take a look at this rule:

rule "PV-Anlage Update"
when 
	Item PV_Current received update
then
	MyPV.postUpdate(PV_Current.state.toString+"W "+PV_DaySum.state.toString+"Wh/d "+PV_YearSum.state.toString+"Wh/y "+PV_Total.state.toString+"Wh/t")
end

Each time PV_Current gets an update, MyPV is updated, too, but with additional items. It looks like this:
pv

In fact, as time goes by, I already have a more feature-complete version of the rule:

rule "PV-Anlage Update"
 when 
	Item PV_Current received update
 then
	var String strCurr  = "Err; "
	var String strDay   = "Err; "
	var String strYear  = "Err; "
	var String strTotal = "Err; "
	logDebug("PV-update", "Start der Rule")
	if (PV_Current.state instanceof Number) {
		if (PV_Current.state > 1000) 
			strCurr = String::format("%.2f kW; ", (PV_Current.state as Number) / 1000)
		else 
			strCurr = PV_Current.state.format("%d W; ")
	}
	logDebug("PV-update", "strCurr = {}",strCurr)
	if (PV_DaySum.state instanceof Number) {
		if (PV_DaySum.state > 1000)
			strDay = String::format("%.2f kWh/d; ", (PV_DaySum.state as Number) / 1000)
		else
			strDay = PV_DaySum.state.format("%d Wh/d; ")
	}
	logDebug("PV-update", "strDay = {}",strDay)
	if (PV_YearSum.state instanceof Number) {
		if (PV_YearSum.state > 1000000)
			strYear = String::format("%.2f mWh/y; ", (PV_YearSum.state as Number) / 1000000)
		else if (PV_YearSum.state > 1000)
			strYear = String::format("%.2f kWh/y; ", (PV_YearSum.state as Number) / 1000)
		else
			strYear = PV_YearSum.state.format("%d Wh/y; ")
	}
	logDebug("PV-update", "strYear = {}",strYear)
	if (PV_Total.state instanceof Number) {
		if (PV_Total.state > 1000000)
			strTotal = String::format("%.2f mWh/t", (PV_Total.state as Number) / 1000000)
		else if (PV_Total.state > 1000)
			strTotal = String::format("%.2f kWh/t", (PV_Total.state as Number) / 1000)
		else
			strTotal = PV_Total.state.format("%d Wh/t")
	}
	logDebug("PV-update", "strTotal = {}",strTotal)
	MyPV.postUpdate(strCurr + strDay + strYear + strTotal)
end

And the output is like this:
pv2
And as you can see, I have an issue in this rule It should be MWh, not mWh :smiley: but guess what: changed that already…

thanks @Udo_Hartmann , that’s kind of what I have been looking for! :slight_smile:

btw what’s the difference between Item received update and Item changed? I guess they are doing the same

what you have imported into rules?
It does look I’m missing something

Rule 'calculate percentage': f != org.eclipse.smarthome.core.library.types.DecimalType
``

An update triggers the Rule when an Item receives an event whether or not the Item changed state. Changed triggers the Rule only when the Item changed state.

Udo’s Rule above, based on a quick scan, requires no imports. You do not need import DecimalType. That error (is it an error) indicates that f isn’t of type DecimalType. Most likely it is UNDEF or NULL or a QuantityType.

it’s Number, and it’s not NULL nor UNDEF
things

Number  Kidsroom_AirQ
Number  Kidsroom_sIAQ

rule

rule "calculate percentage"
when
    Item Kidsroom_sIAQ changed
then
    var String airQ = "Err "
    var String iIAQ = "Err "
    val max = 500
    val min = 0

    val k = (Kidsroom_sIAQ.state as Number).floatValue
    
    val kq = 100 - ( ( (k - min) * 100) / (max - min))

    postUpdate(Kidsroom_AirQ, kq)

    airQ = String::format("%.0f %%", Kidsroom_AirQ.state as Number)
    sIAQ = String::format("%.0f",    Kidsroom_sIAQ.state as Number)
    Kidsroom_AirLabel.postUpdate(airQ + " (" + sIAQ + ")")

end

Do I need something somewhere? Thanks!

Your error

Your rule

I think it’s correct - you’ve supplied a Number state for formatting, not a DecimalType
Formatter being picky.
Try using a .floatValue as you do earlier in the rule.

Don’t forget that if you use an Item state immediately after sending it a postUpdate, you will probably still get the previous state.

If using an Item to save a number, you have to give openHAB time to update the state.

1 Like

Oh, some seconds too late :wink:

I don’t mind if there will be older value, it’s updating quite often so I don’t really care, not worth to write some delays or another rule …

it does look that this did a trick, thanks! :slight_smile:

and for some reason, one part of the rule started to work after OH restart… before restart it complained that something something cannot be resolved to an item or type;
After restart it works, I assume OH sometimes having difficulties to read .items file correctly or smthing