Using HTTP binding, I have a flowmeter which provides a rotation count as an HTTP response.
My sitemap reports the rotation count.
This works fine.
However am trying to configure my setup such that if this device is offline, then my sitemap reports something along the lines of “Offline since [date & time]” instead of a rotation count.
I have attempted to create code to achieve this using Network binding, though appear to be having some trouble (although I am using Network binding for presence detection elsewhere - it seems to work fine).
Text item=Flowmeter_1_Message label="Rotations 1 - modified [%s]" icon="faucet"
Rules as follows:
rule "FlowVolume_Offline"
when
Item Flowmeter_1.state changed
then
if (Flowmeter_1.state == ON)
{
Flowmeter_1_Message.sendCommand(FlowVolume_data_1.state.toString)
}
else
{
Flowmeter_1_Message.sendCommand("Offline since {date}, sorry")
}
end
Any help welcome. The “Modified” entry - intended to display the text (Offline since…) does not appear to change from a rotations count (fixed at some point in the past).
In addition, I have no idea how to add in the date variable - though I believe this can be done using a channel in HTTP…
Thank you - helped me work it out.
Posting the code for a straightforward solution below (Rules file - rest unchanged)
rule "FlowVolume_Offline"
when
Item Flowmeter_1 changed or
Item FlowVolume_data_1 changed
then
if (Flowmeter_1.state == ON)
{
Flowmeter_1_Message.sendCommand(FlowVolume_data_1.state.toString)
}
else
{
Flowmeter_1_Message.sendCommand("Offline since "+Flowmeter_1_lastseentime.state)
}
end
Slightly longer solution (which achieves the text output I was looking for) below:
rule "FlowVolume_Offline1"
when
Item Flowmeter_1 changed or
Item FlowVolume_data_1 changed or
Time cron "0 0 0/1 1/1 * ? *"
then
if (Flowmeter_1.state == ON)
{
Flowmeter_1_Message.sendCommand(FlowVolume_data_1.state.toString)
}
else
{
var String timeMessage
var Number yearNow = now.getYear
var Number monthNow = now.getMonthOfYear
var Number dayNow = now.getDayOfMonth
var Number dayOfYearNow = now.getDayOfYear
var Number yearLastSeen = Integer::parseInt(Flowmeter_1_lastseentime.state.format("%1$tY"))
var Number monthLastSeen = Integer::parseInt(Flowmeter_1_lastseentime.state.format("%1$tm"))
var Number dayNameLastSeen = Flowmeter_1_lastseentime.state.format("%1$tA")
var Number dayLastSeen = Integer::parseInt(Flowmeter_1_lastseentime.state.format("%1$te"))
var Number hour12LastSeen = Integer::parseInt(Flowmeter_1_lastseentime.state.format("%1$tl"))
var String minuteLastSeen = Flowmeter_1_lastseentime.state.format("%1$tM")
var String meridianLastSeen = Flowmeter_1_lastseentime.state.format("%1$tp")
var Number dayOfTheYearLastSeen = Integer::parseInt(Flowmeter_1_lastseentime.state.format("%1$tj"))
if ((yearNow-yearLastSeen ==0) && (monthNow-monthLastSeen ==0) &&(dayNow-dayLastSeen ==0))
{
timeMessage="Offline since "+hour12LastSeen+":"+minuteLastSeen+meridianLastSeen
}
if ((yearNow-yearLastSeen ==0) && (dayOfYearNow-dayOfTheYearLastSeen ==1))
{
timeMessage="Offline since "+hour12LastSeen+":"+minuteLastSeen+meridianLastSeen+" yesterday"
}
if ((yearNow-yearLastSeen ==0) && (dayOfYearNow-dayOfTheYearLastSeen ==2))
{
timeMessage="Offline since the day before yesterday"
}
if ((yearNow-yearLastSeen ==0) && (dayOfYearNow-dayOfTheYearLastSeen >=3) && (dayOfYearNow-dayOfTheYearLastSeen <=7))
{
timeMessage="Offline since "+dayNameLastSeen+" "+meridianLastSeen
}
if ((yearNow-yearLastSeen !=0) || (dayOfYearNow-dayOfTheYearLastSeen >=8))
{
timeMessage="Offline for ages"
}
Flowmeter_1_Message.sendCommand("Was "+FlowVolume_data_1.state+": "+timeMessage)
}
end
If there is a more elegant solution I 'd be grateful to know; this feels like quite a lot of code for a simple output.
I also don’t quite understand why the variable “FlowVolume_data_1.state” in the last line appears to work (or persist) even though the device is offline… I do have a persistence database set up - is it automatically pulling from that without me being aware?
Once an Item state has been set, it stays that way. Was there some reason you expected it to change?
If you wanted it to change, you could for example use the expire binding to update to UNDEF after an hour with no updates, or similar. Or have your rule do that, as you are already detecting the condition.
If your http data Item showed an error, you wouldn’t need your separate ping.
Some bindings will set state UNDEF for certain failures by design, but not that one.
UNDEF can be useful, note that it doesn’t get persisted which can help suppress false data records, depending what you’re doing with your data.
I just cleared cache and upgraded to Openhab 2.5.3, but the above code now appears to be broken.
Error log is as follows:
Rule ‘FlowVolume_Offline1’ : Y != java.lang.String
When I comment out (in the code above), the following:
var Number yearLastSeen = Integer::parseInt(Flowmeter_1_lastseentime.state.format("%1$tY"))
then the error changes to:
Rule ‘FlowVolume_Offline1’ : m != java.lang.String
and so on.
So it appears that something to do with the date/time code is off.
Did I forget to include an addon when I updated Openhab?
Grateful for any help.
It would be helpful to your understanding of your problem to find out what that value is, at the time the rule runs. logInfo("test", "Last seen " + Flowmeter_1_lastseentime.state.toString)
Or you can interrogate Items at any time using the REST API