Thanks for the new Buttongrid widget on BasicUI sitemap!
Note, I created the sitemap using JRuby, but this can be easily created using an xtext sitemap file as well, and I’d imagine also through the Main UI although I have never looked into that.
The benefit of using jruby to generate the sitemap is that I can DRY repetitive things, e.g. I have multiple TVs in the house. I only need to write the TV section just once, and I can create the frames for all the TVs for me.
This is the code I used (WIP):
APP_COLUMNS = 4
APPLICATIONS = [
["youtube.leanback.v4", "Youtube", "if:fa:youtube"],
["netflix", "Netflix", "if:mdi:netflix"],
["amazon", "Amazon", "if:arcticons:primevideo"],
["com.pplus.webapp.prod-intl", "Paramount+", "if:arcticons:paramount-plus"],
["cdp-30", "Plex", "if:mdi:plex"],
["com.disney.disneyplus-prod", "Disney+", "if:tabler:brand-disney"]
].then do |apps|
max_row = (apps.size / APP_COLUMNS) + 1
columns_in_the_last_row = apps.size % APP_COLUMNS
# Center the last row by padding it with empty cells
last_row_padding = ((APP_COLUMNS - columns_in_the_last_row) / 2) + 1
apps.map.with_index do |app, i|
row = (i / APP_COLUMNS) + 1
col = (i % APP_COLUMNS) + ((row == max_row) ? last_row_padding : 1)
[row, col] + app
end
end.freeze
sitemaps.build do
sitemap "tv", label: "TV Control Panel" do
OpenHAB::DSL.items.equipments(Semantics::Television).sort_by(&:label).each do |tv|
frame label: tv.label do
switch item: tv.points(Semantics::Power).first, label: "Power"
mute_item = tv.members.tagged("Mute").first
setpoint item: tv.points(Semantics::SoundVolume).first,
label: "Volume [%d %%]",
icon: {
"0" => "if:icomoon-free:volume-mute",
"#{mute_item.name} == ON" => "if:icomoon-free:volume-mute2",
"< 9" => "if:icomoon-free:volume-low",
"< 13" => "if:icomoon-free:volume-medium",
">= 13" => "if:icomoon-free:volume-high",
:default => "if:icomoon-free:volume-mute"
}
application_item = tv.members.tagged("Application").first
buttongrid item: application_item, buttons: APPLICATIONS
rc_item = tv.members.tagged("RC").first
buttongrid item: rc_item,
buttons: [
[1, 1, "BACK", "Back", "iconify:carbon:return"],
[1, 2, "HOME", "Menu", "iconify:ep:menu"],
[1, 3, "YELLOW", "Search", "material:search"],
[2, 2, "UP", "Up", "iconify:mingcute:up-fill"],
[4, 2, "DOWN", "Down", "iconify:mingcute:down-fill"],
[3, 1, "LEFT", "Left", "iconify:mingcute:left-fill"],
[3, 3, "RIGHT", "Right", "iconify:mingcute:right-fill"],
[3, 2, "ENTER", "Enter", "material:adjust"]
]
buttongrid item: tv.points(Semantics::Player).first,
buttons: [
[1, 1, "REWIND", "Rewind", "iconify:mingcute:fast-rewind-fill"],
[1, 2, "PAUSE", "Pause", "iconify:mingcute:pause-fill"],
[1, 3, "PLAY", "Play", "iconify:mingcute:play-fill"],
[1, 4, "FASTFORWARD", "Fast Forward", "iconify:mingcute:fast-forward-fill"]
]
switch item: tv.members.tagged("Timer").first, label: "Timer", icon: "time",
mappings: {
"0" => "X",
"2" => "2",
"5" => "5",
"10" => "10",
"30" => "30"
}
switch item: tv.points(Semantics::TVLock).first,
label: "[RB(|input.length > 2 ? Time.parse(input).to_i.seconds.to_human(long: false) : ''):%s]",
icon: "lock",
mappings: {
"0" => "OFF",
"10 min" => "10m",
"30 min" => "30m",
"60 min" => "1h",
"4 h" => "4h",
"12 h" => "12h"
},
value_color: { "!=NULL" => "red" }
end
end
end
end
The current Android App and iOS App (Beta) both support Iconify and Material icons.
More examples of Buttongrid can be found in the following add-on documentation: