@@ -74,7 +74,7 @@ alternate_unit:
7474| `remove` | _Optional_ | action_id that accepts `id`. |
7575| `toggle` | _Optional_ | action_id that accepts `id`. |
7676
77- ` *` - `portions` is also accepted as a parameter instead of `amount`.
77+ ` *` - `portions` (legacy) is also accepted as a parameter instead of `amount`.
7878
7979# ### `alternate_unit` options
8080
@@ -86,7 +86,9 @@ alternate_unit:
8686
8787# ## Pluralization
8888
89- Both `unit_of_measurement` and `alternate_unit.unit_of_measurement` support pluralization based on [Unicode plural rules](https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html).
89+ Both `unit_of_measurement` and `alternate_unit.unit_of_measurement` support
90+ pluralization based on
91+ [Unicode plural rules](https://www.unicode.org/cldr/charts/43/supplemental/language_plural_rules.html).
9092
9193Simple string format :
9294
@@ -108,6 +110,9 @@ alternate_unit:
108110 other: grams
109111` ` `
110112
113+ Language for which the pluralization rules apply is always the current logged in
114+ user's language setting.
115+
111116# # Compatibility
112117
113118# ## Xiaomi Smart Pet Feeder (`mmgg.feeder.fi1`)
@@ -116,6 +121,24 @@ This card was originally created for the Xiaomi Smart Pet Feeder running
116121ESPHome firmware with the [esphome-miot](https://github.com/dhewg/esphome-miot/blob/main/config/mmgg.feeder.fi1.yaml)
117122component and offers full support for it.
118123
124+ The sensor entity state follows this comma-separated format :
125+ ` [int id],[int hour],[int minute],[int amount],[int status]`
126+
127+ Where :
128+
129+ - ` id` - entry index (0-9)
130+ - ` hour` - dispense hour (0-23)
131+ - ` minute` - dispense minute (0-59)
132+ - ` amount` - portions to dispense (1-30)
133+ - `status` - current state : ` 0` (dispensed), `1` (failed), `254` (dispensing), `255` (pending)
134+
135+ Example : ` 0,10,30,5,0,1,12,0,10,255` represents two entries:
136+
137+ - Entry 0 : 10:30, dispense 5 portions, already dispensed
138+ - Entry 1 : 12:00, dispense 10 portions, pending
139+
140+ See how this format is parsed using regex in [Custom Device Parsing](#status_pattern-details).
141+
119142Feeders with the original firmware are _NOT_ currently supported as much of the
120143logic is not handled by the device itself.
121144
@@ -143,60 +166,34 @@ about the structure.
143166
144167Please open an issue including as much detail as available.
145168
146- # ## General points
147-
148- For a device to be compatible with this card, `entity` state currently must
149- contain a string with the the structure
150- ` [int id],[int hour],[int minute],[int amount],[int status]` , as a
151- comma-separated list, where `id` is the entry index, `hour` is the 23h formatted
152- hour at which to dispense, `minute` is the minute of the hour at which to dispense, `amount`
153- is the amount to dispense (portions, grams, etc) and `status` is an
154- integer with the following meaning :
155-
156- - 0 - dispensed successfully for today
157- - 1 - dispense failed for today (lack of food, food stuck, etc)
158- - 254 - currently dispensing
159- - 255 - pending for today
160-
161- Example :
162-
163- ` 0,10,30,5,0,1,12,0,10,255`
169+ # ## Custom Device Parsing
164170
165- - entry 0 : 10:30 dispense 5 portions, dispensed successfully.
166- - entry 1 : 12:00 dispense 10 portions, pending.
171+ The card supports custom device parsing for advanced use cases.
172+ This allows you to define custom schedules, statuses, and display options for
173+ devices that do not follow the Xiaomi structure.
167174
168- # ### Assumed statuses
175+ # ### Computed Statuses
169176
170- There are a few entry status options that the card itself calculates and
171- displays to bring more clarity into events of the schedule :
177+ The card automatically calculates additional status options for better clarity :
172178
173- `skipped` status is assumed by the card when :
179+ ** `skipped`** status is assumed when:
174180
175181- the schedule entry is status `pending` and,
176182- the current Home Assistant time is greater than the dispense time.
177183
178- * Useful to know if an entry was not dispensed due to external factors
179- such as a lack of power or the schedule being disabled at the dispense time,
180- but not a failure of the device itself.
184+ This indicates an entry was not dispensed due to external factors
185+ such as a lack of power or the schedule being disabled at the dispense time,
186+ but not a failure of the device itself.
181187
182- `disabled` status is assumed by the card when :
188+ ** `disabled`** status is assumed when:
183189
184190- the schedule entry is status `pending` and,
185191- the dispense time is greater than current Home Assistant time and,
186192- there exists a `switch` entry in the card config and,
187193- the `switch` entity is off.
188194
189- * Useful to know that future dispense entries will **not** be executed because
190- the schedule is currently disabled.
191-
192- A customizable option using Jinja2 templates to extract the schedule from
193- arbitrary entities is also under consideration.
194-
195- # ## Custom Device Parsing
196-
197- The card supports custom device parsing for advanced use cases.
198- This allows you to define custom schedules, statuses, and display options for
199- devices that do not follow the Xiaomi structure.
195+ This indicates that future dispense entries will **not** be executed because
196+ the schedule is currently disabled.
200197
201198# ### `device` Options
202199
@@ -210,23 +207,68 @@ devices that do not follow the Xiaomi structure.
210207| `status_map` | **Required** | A mapping of status codes to their corresponding states. |
211208| `status_pattern` | **Required** | A regex pattern to extract schedule details from the `entity` state. Named groups are required. |
212209
213- # ### Example `status_map`
210+ # ### Complete Device Configuration Example
211+
212+ Here's a complete example of custom device parsing configuration :
213+
214+ ` ` ` yaml
215+ type: custom:dispenser-schedule-card
216+ entity: sensor.my_custom_feeder_schedule
217+ switch: switch.my_feeder_schedule_enable
218+ actions:
219+ add: esphome.my_feeder_add_feed
220+ edit: esphome.my_feeder_edit_feed
221+ remove: esphome.my_feeder_remove_feed
222+ toggle: esphome.my_feeder_toggle_feed
223+ device:
224+ type: custom
225+ max_entries: 8
226+ min_amount: 1
227+ max_amount: 20
228+ step_amount: 1
229+ status_map:
230+ 0: dispensed
231+ 1: failed
232+ 2: pending
233+ 3: dispensing
234+ 4: My Custom State
235+ status_pattern: "(?<id>[0-9]),(?<hour>[0-9]{1,2}),(?<minute>[0-9]{1,2}),(?<amount>[0-9]{1,2}),(?<status>[0-9]),?"
236+ unit_of_measurement:
237+ one: portion
238+ other: portions
239+ alternate_unit:
240+ unit_of_measurement: g
241+ conversion_factor: 5
242+ approximate: true
243+ display:
244+ failed:
245+ color: var(--error-color)
246+ icon: mdi:alert-circle
247+ My Custom State:
248+ color: hotpink
249+ icon: mdi:scale
250+ label: Custom Status
251+ ` ` `
252+
253+ # ### `status_map` Details
214254
215255The `status_map` defines how status codes from the `entity` state are
216- interpreted. For example :
256+ interpreted. In the example above :
217257
218- - `0 -> dispensed` : Status code `0` maps to the `dispensed` state.
219- - `1 -> failed` : Status code `1` maps to the `failed` state.
220- - `2 -> My Custom State` : Status code `2` maps to a custom state called `My Custom State`.
258+ - `0 : dispensed` - Status code `0` maps to the `dispensed` state.
259+ - `1 : failed` - Status code `1` maps to the `failed` state.
260+ - `2 : pending` - Status code `2` maps to the `pending` state.
261+ - `3 : dispensing` - Status code `3` maps to the `dispensing` state.
262+ - `4 : My Custom State` - Status code `4` maps to a custom state.
221263
222264Mapping to any of the following states is automatically translated in the
223265supported languages (case sensitive) :
224266
225267- ` dispensed` , `dispensing`, `pending`, `failed`, `skipped`, `disabled`, `unknown`.
226268
227- Custom labels can be configured via the [`display` option](#example- display-customization)
269+ Custom labels can be configured via the [`display` option](#display-customization)
228270
229- # ### Example `status_pattern`
271+ # ### `status_pattern` Details
230272
231273The `status_pattern` uses a regex to extract schedule details from the `entity` state. Named groups are required for the following fields :
232274
@@ -236,12 +278,17 @@ The `status_pattern` uses a regex to extract schedule details from the `entity`
236278- `amount` : The amount to dispense (portions, grams, etc.).
237279- `status` : The status code of the schedule entry.
238280
239- Example pattern :
281+ ** Example using Xiaomi format:** The [Xiaomi Smart Pet Feeder](#xiaomi-smart-pet-feeder-mmggfeederfi1) uses this pattern:
240282
241283` ` ` regex
242284(?<id>[0-9]),(?<hour>[0-9]{1,3}),(?<minute>[0-9]{1,3}),(?<amount>[0-9]{1,3}),(?<status>[0-9]{1,3}),?
243285` ` `
244286
287+ Applied to the entity state `0,10,30,5,0,1,12,0,10,255`, this extracts :
288+
289+ - Entry 0 : ` id=0` , `hour=10`, `minute=30`, `amount=5`, `status=0`
290+ - Entry 1 : ` id=1` , `hour=12`, `minute=0`, `amount=10`, `status=255`
291+
245292# ## Display Customization
246293
247294You can customize the display of specific statuses using the `display` option.
0 commit comments