A very simple card to view and control dispenser schedules for the Home Assistant Lovelace / Grace UI
Or follow these steps:
- Open HACS (Home Assistant Community Store)
- Click on the three dots in the top right corner
- Click on
Custom repositories - In the Repository field, enter https://github.com/cristianchelu/dispenser-schedule-card/
- In the Category field, select
Dashboard - Click on
Add - Search for
Dispenser Schedule Cardin the list - Install the card
More information and screenshots in the official guide: https://hacs.xyz/docs/faq/custom_repositories/
Download dispenser-schedule-card.min.js from the Releases tab of this
repository and place it in under your www folder, then add this as resource
type "Javascript Module", by following the official HA guide:
https://developers.home-assistant.io/docs/frontend/custom-ui/registering-resources
Typical YAML:
type: custom:dispenser-schedule-card
entity: sensor.feeder_raw_feed_plan
switch: switch.feeder_feeding_schedule
actions:
add: esphome.feeder_add_scheduled_feed
edit: esphome.feeder_edit_scheduled_feed
remove: esphome.feeder_remove_scheduled_feed
alternate_unit:
unit_of_measurement: g
conversion_factor: 5
approximate: true| Name | Required | Description |
|---|---|---|
entity |
Required | An entity_id in the sensor domain containing the schedule |
switch |
Optional | An entity_id in the switch domain containing the on/off toggle for the schedule. |
actions |
Optional | add, edit, remove, and toggle (enable/disable individual entry) actions. |
editable |
Optional | Whether the schedule is editable. always, toggle, or never.Default toggle if actions are defined, otherwise never. |
unit_of_measurement |
Optional | Unit label. String or object with plural forms. See Pluralization. Default portions. |
alternate_unit |
Optional | Configuration to display a secondary unit of measurement, with a conversion factor. |
device |
Optional | See Custom Device Parsing |
display |
Optional | See Display customization |
| Name | Required | Description |
|---|---|---|
add |
Optional | action_id that accepts id, hour, minute, amount *. |
edit |
Optional | action_id that accepts id, hour, minute, amount *. |
remove |
Optional | action_id that accepts id. |
toggle |
Optional | action_id that accepts id. |
* - portions (legacy) is also accepted as a parameter instead of amount.
| Name | Required | Description |
|---|---|---|
unit_of_measurement |
Required | Secondary unit label. String or object with plural forms. See Pluralization. |
conversion_factor |
Required | Number to multiply the primary amount by |
approximate |
Optional | Whether the alternate unit is an approximation. Adds a ~ prefix to the value |
Both unit_of_measurement and alternate_unit.unit_of_measurement support
pluralization based on
Unicode plural rules.
Simple string format:
unit_of_measurement: portions
alternate_unit:
unit_of_measurement: gramsPluralization object format:
unit_of_measurement:
one: portion
other: portions
alternate_unit:
unit_of_measurement:
one: gram
other: gramsLanguage for which the pluralization rules apply is always the current logged in user's language setting.
This card was originally created for the Xiaomi Smart Pet Feeder running ESPHome firmware with the esphome-miot component and offers full support for it.
The sensor entity state follows this comma-separated format:
[int id],[int hour],[int minute],[int amount],[int status]
Where:
id- entry index (0-9)hour- dispense hour (0-23)minute- dispense minute (0-59)amount- portions to dispense (1-30)status- current state:0(dispensed),1(failed),254(dispensing),255(pending)
Example: 0,10,30,5,0,1,12,0,10,255 represents two entries:
- Entry 0: 10:30, dispense 5 portions, already dispensed
- Entry 1: 12:00, dispense 10 portions, pending
See how this format is parsed using regex in Custom Device Parsing.
Feeders with the original firmware are NOT currently supported as much of the logic is not handled by the device itself.
The homeassistant_petkit custom integration by @Jezza34000 is compatible with this card.
View this ESPHome config example to get started. It features a 10-entry schedule completely on device, compatible with this card.
You may use it as a starting point for, or as an enhancement to your own DIY cat/dog/bird/fish feeders, or other generic dispensers that require offline or battery-powered scheduling.
Please note that it is modelled after the original xiaomi device behavior and may not be the best way of handling an on-device schedule, especially as the ESPHome project matures and gains new features with time.
Support for other types of dispensers can be added if enough is known about the structure.
Please open an issue including as much detail as available.
The card supports custom device parsing for advanced use cases. This allows you to define custom schedules, statuses, and display options for devices that do not follow the Xiaomi structure.
The card automatically calculates additional status options for better clarity:
skipped status is assumed when:
- the schedule entry is status
pendingand, - the current Home Assistant time is greater than the dispense time.
This indicates an entry was not dispensed due to external factors such as a lack of power or the schedule being disabled at the dispense time, but not a failure of the device itself.
disabled status is assumed when:
- the schedule entry is status
pendingand, - the dispense time is greater than current Home Assistant time and,
- there exists a
switchentry in the card config and, - the
switchentity is off.
This indicates that future dispense entries will not be executed because the schedule is currently disabled.
| Name | Required | Description |
|---|---|---|
type |
Required | Must be set to custom to enable custom parsing. |
max_entries |
Required | Maximum number of schedule entries supported by the device. |
min_amount |
Required | Minimum amount that can be dispensed. |
max_amount |
Required | Maximum amount that can be dispensed. |
step_amount |
Required | Step size for the amount to dispense. |
status_map |
Required | A mapping of status codes to their corresponding states. |
status_pattern |
Required | A regex pattern to extract schedule details from the entity state. Named groups are required. |
Here's a complete example of custom device parsing configuration:
type: custom:dispenser-schedule-card
entity: sensor.my_custom_feeder_schedule
switch: switch.my_feeder_schedule_enable
actions:
add: esphome.my_feeder_add_feed
edit: esphome.my_feeder_edit_feed
remove: esphome.my_feeder_remove_feed
toggle: esphome.my_feeder_toggle_feed
device:
type: custom
max_entries: 8
min_amount: 1
max_amount: 20
step_amount: 1
status_map:
0: dispensed
1: failed
2: pending
3: dispensing
4: My Custom State
status_pattern: "(?<id>[0-9]),(?<hour>[0-9]{1,2}),(?<minute>[0-9]{1,2}),(?<amount>[0-9]{1,2}),(?<status>[0-9]),?"
unit_of_measurement:
one: portion
other: portions
alternate_unit:
unit_of_measurement: g
conversion_factor: 5
approximate: true
display:
failed:
color: var(--error-color)
icon: mdi:alert-circle
My Custom State:
color: hotpink
icon: mdi:scale
label: Custom StatusThe status_map defines how status codes from the entity state are
interpreted. In the example above:
0: dispensed- Status code0maps to thedispensedstate.1: failed- Status code1maps to thefailedstate.2: pending- Status code2maps to thependingstate.3: dispensing- Status code3maps to thedispensingstate.4: My Custom State- Status code4maps to a custom state.
Mapping to any of the following states is automatically translated in the supported languages (case sensitive):
dispensed,dispensing,pending,failed,skipped,disabled,unknown.
Custom labels can be configured via the display option
The status_pattern uses a regex to extract schedule details from the entity state. Named groups are required for the following fields:
id: The entry index.hour: The hour of the schedule (23h format).minute: The minute of the schedule.amount: The amount to dispense (portions, grams, etc.).status: The status code of the schedule entry.
Example using Xiaomi format: The Xiaomi Smart Pet Feeder uses this pattern:
(?<id>[0-9]),(?<hour>[0-9]{1,3}),(?<minute>[0-9]{1,3}),(?<amount>[0-9]{1,3}),(?<status>[0-9]{1,3}),?Applied to the entity state 0,10,30,5,0,1,12,0,10,255, this extracts:
- Entry 0:
id=0,hour=10,minute=30,amount=5,status=0 - Entry 1:
id=1,hour=12,minute=0,amount=10,status=255
You can customize the display of specific statuses using the display option.
Each status can have the following properties:
| Name | Required | Description |
|---|---|---|
color |
Optional | CSS color value to use for the status. |
icon |
Optional | Icon to display for the status. Uses Material Design Icons (e.g., mdi:icon). |
label |
Optional | The text label for the status, overriding any default translation. |
For example:
display:
failed:
color: var(--success-color)
label: Task failed successfully
My Custom State:
color: hotpink
icon: mdi:scaleThis will display the failed status in the --success-color of the home
assistant theme and the label "Task failed successfully", and the custom state
My Custom State, in hot pink with the mdi:scale icon.
Translations are currently available for the following languages:
- Català (Catalan)
- Deutsch (German)
- English
- Español (Spanish)
- Français (French)
- Italiano (Italian)
- Română (Romanian)
- Türkçe (Turkish)
Contributions are welcome!
