Hello all,
Following an advice I got I’m posting here a rule script with which I have challenges.
Purpose
I want to make sure that I don’t miss some municipal dates: We have several different types of trash and the city switches dates a couple times a year. I created a habpanel widget to show the extracted dates and highlight them when they’re due tomorrow.
The approach below should work but I’m trying to improve both my understanding of openhab rules as well as learn what better approaches exist.
What I already do
The script pulls an ics from a web server, searches for the appropriate strings within them and extracts the dates for the four types I’m currently handling. Those dates are written in appropriate items and then pulled in a hardcoded order. The items look like:
DateTime Bioabfall "%1$tm %1$te,%1$tY"
This results in a list like this:
- Trash 1: 5th of May 2019
- Trash 2: 22nd of Feb 2019
- Trash 3: 27th of Feb 2019
- Trash 4: 8th of May 2019
This list gets populated on boot and once a day - this part works completely fine.
What I would LIKE to do
Instead of having a hardcoded order of elements I would like them to be ordered by date.
What I tried to achieve this is expand the items to
String trash1_label
DateTime trash1_date
etc. Then I wanted to populate them with trash1 having the next upcoming date and so forth.
My current approach is to put the dates in a HashMap and then create a sortedList with a manually implemented insertSort. But this seems so … wrong
I’m looking now for advice or ideas or even completely different approaches to achieve the same thing. The only two aspects I can’t change:
- The source is an ics
- The target is a list of elements sorted by an associated date
The script I currently have (including everything - it runs like this and works.)
import java.text.SimpleDateFormat
import java.util.HashMap
rule "<Test>"
when
Item test received update ON or
Time cron " 0 0 4 1/1 * ? *" or
System started
then
var ft = new SimpleDateFormat ("yyyyMMdd")
var http = sendHttpGetRequest("http://www.awsh.de/api_v2/collection_dates/1/ort/553/strasse/290/hausnummern/0/abfallarten/R02-B02-D02-P04-W0/kalender.ics")
val lines = http.split("\r?\n")
// the strings which are used within the ics.
val trashIdentifier = newArrayList(
"SUMMARY:Restabfall 40L-240L(2-wöchentlich)",
"SUMMARY:Gelber Sack(2-wöchentlich)",
"SUMMARY:Papiertonne(monatlich)",
"SUMMARY:Bioabfall(2-wöchentlich)"
)
//human readable identifier used as item names
val trashType = newArrayList(
"Restabfall",
"GelberSack",
"Papierabfall",
"Bioabfall"
)
var HashMap<String, DateTime> trashMap = new HashMap<String, DateTime>();
for (var i = 0; i < trashIdentifier.size(); i++) {
var dateRaw = lines.get(lines.indexOf(trashIdentifier.get(i))-3)
var date = dateRaw.substring(dateRaw.length()-8)
trashMap.put(trashType.get(i), new DateTime(ft.parse(date)))
//original, working part: This gives me an unsorted list of items with the correct date.
// postUpdate("trashName"+i, trashType.get(i))
// postUpdate("trashDate"+i, new DateTime(ft.parse(date)).toString)
// postUpdate(trashType.get(i), new DateTime(ft.parse(date)).toString)
}
//proof that the hashmap is populated correctly.
logInfo("test2: ", ""+trashMap)
var sortedList = newArrayList();
//initialize with first item, then iterate over the rest and go over an if/else tree to insert them.
sortedList.add(0, trashType.get(0).toString)
for (var i = 1; i < trashIdentifier.size(); i++)
{
if (trashMap.get(trashType.get(i-1)).isBefore(trashMap.get(trashType.get(i)))) {
logInfo("asd:_ ", "__ " + trashMap.get(trashType.get(i)).toString)
}
}
end
Thanks for any comments, hints, critique and pointers!