Hello all,
I’ve put together an openHAB 3 widget to control my Roomba via the excellent iRobot binding. I used the Dishwasher Status widget as a starting point for this, and had some design inspiration from this Vacuum Card project. Some highlights:
- Ability to issue any commands the iRobot binding provides via a popup
- Displays the full text of any error messages (76 in total!)
- Displays its current state
- Animation when the vacuum is running
- Color coding of charging icon; lower battery indicator
Some TODOs here yet, but figured I’d release this early here for now!
- Some animation alignment issues on mobile to address yet
- General code cleanup
- Wire in support for Runtime Minutes - to show how long the Roomba has been working on the current Mission
Here’s a screenshot:
For a better overall appearance, I took the approach of using a PNG background instead of pure CSS. Download this image and place this in your openHAB html directory (probably /etc/openhab/html/vacuum.png)
Resources
And here is the widgets YAML code:
uid: Roomba_v20
tags: []
props:
parameters:
- description: Title of the card
label: Title
name: title
required: false
type: TEXT
- description: Header text
label: Header
name: header
required: false
type: TEXT
- description: Footer text
label: Footer
name: footer
required: false
type: TEXT
- context: item
description: Item for minutes since the begin of the current Mission (TODO, likely via a rule & custom item!)
label: Minutes running
name: runtime
required: true
type: TEXT
- context: item
description: Item for tracking the current Battery Percentage
label: Battery
name: battery
required: true
type: TEXT
- context: item
description: Item for tracking the current State (i.e. charge, new, run, resume, recharge, stuck, stop, pause (etc.)
label: State
name: state
required: true
type: TEXT
- context: item
description: Item to send Commands to (i.e. clean, pause, dock)
label: Command
name: command
required: true
type: TEXT
- context: item
description: Item for tracking Error Codes (i.e. Bin Full, Docking Issue, etc.)
label: Error
name: error
required: true
type: TEXT
parameterGroups: []
timestamp: Mar 14, 2021, 6:43:07 PM
component: f7-card
config:
title: =(props.title)
slots:
default:
- component: f7-card-content
config:
style:
height: 200px
slots:
default:
- component: f7-icon
config:
f7: bolt
style:
#right: 0
#border: 2px solid red
color: '=items[props.state].state == "charge" ? "green" : "gray"'
- component: Label
config:
text: "=items[props.battery].state + ' %'"
style:
color: '=items[props.battery].state >= 80 ? "green" : "red"'
height: 10px
float: right
- component: f7-row
config:
class:
- display-flex
- justify-content-center
style:
width: 100%
slots:
default:
- component: f7-col
config:
style:
height: 100%
width: 180px
slots:
default:
- component: f7-block-header
slots:
default:
- component: Label
config:
text: =props.header
style:
color: white
- component: oh-image
config:
url: static/vacuum.png
style:
position: absolute
transform: translate(-50%)
left: 50%
width: 180px
filter: invert(100%) drop-shadow(16px 16px 20px black)
- component: f7-block
config:
style:
height: auto
width: auto
slots:
default:
- component: f7-block
config:
style:
top: 19px
left: 38px
z-index: 10
slots:
default:
- component: oh-link
config:
f7: circle_fill
size: 35
color: green
style:
background: '=items[props.state].state == "run" ? "green" : "red"'
border-radius: 50%
height: 40px
width: 40px
action: options
actionItem: =[props.command]
actionOptions: clean=Clean,spot=Spot,pause=Pause,stop=Stop,dock=Dock
- component: f7-block
slots:
default:
- component: f7-preloader
config:
size: 50
colorTheme: green
visible: =items[props.state].state == "run"
style:
position: absolute
top: -30px
left: 48px
z-index: 10
- component: f7-block
slots:
default:
- component: Label
config:
size: 20
text: "=items[((!props.error) ? '' : props.error)].displayState"
visible: =items[props.error].state != 0
style:
color: red
white-space: nowrap
- component: f7-card-footer
config:
visible: =[props.footer]
slots:
default:
- component: Label
config:
size: 40
visible: =[props.footer]
text: "=items[((!props.state) ? '' : props.state)].displayState"
style:
font-weight: bold
color: white
I’d appreciate any and all feedback here on how to improve!
Best regards,
.