We’ve always labelled food which goes in the freezer, it makes a freezer rummage much easier, and avoid mystery meals.
The Dymo printer does a decent job, but it’s really limited to desktop computers (unless you buy yet another dymo), which makes it a pain to print the food labels. My handwriting beyond abysmal…
First, there isn’t a home assistant integration for a dymo label printer, so we’re in to dirty hacks pretty quickly.
First, setup lprint on a linux box, the instructions seemed to work fine for my LabelWriter 450 Duo.
Next problem, lprint it doesn’t take text files directly, You’ll see it needs PNG files, which ImageMagick can do relatively easily. It doesn’t automatically resize based on content length, so I added a little bit of branch logic based on the size of the first line. The last line finishes with the number of labels required
wishy@niska:~$ cat printlabel.sh
#!/bin/bash
declare -a lines
readarray -d "\n" lines <<< "$1"
char_count=${#lines[0]}
label=$(head -c -3 <<<"$1")
prints=$(tail -c 2 <<<"$1")
if [[ $char_count -lt 13 ]]; then
convert -size 673x378 xc:white -font "AvantGarde-Book" -pointsize 96 -fill black -annotate +30+100 "$label" image.png
else
convert -size 673x378 xc:white -font "AvantGarde-Book" -pointsize 64 -fill black -annotate +30+130 "$label" image.png
fi
lprint image.png -o media=oe_md-multipurpose-label_2.25x1.25in -n "$prints"
We can test using
./printlabel.sh 'Toad in the Hole\n2 Portion\n10/03/2024,1'
Now, how do we hook that up to home assistant. First, write a short calling script. This SSHs to the linux box and runs the print command, you’ll need to set up SSH keys for authentication from the homeassistant user. I added a little escaping for ’ as is breaks the script
root@nandi:/home/homeassistant# cat printlabel.sh
#!/bin/bash
MESSAGE=$(cat)
CLEAN_MESSAGE=$(echo "$MESSAGE" | tr -d "'")
/usr/bin/ssh [email protected] "./printlabel.sh '$CLEAN_MESSAGE'"
And we can hook that up via command line notify
command_line:
- notify:
command: /home/homeassistant/printlabel.sh
name: "Print Dymo Label"
Finally, the voice bit! We could just work directly from a single prompt, but I decided that I probably didn’t want labels printed until I’ve had a chance to see what speech to text has come back with. Hence one automation to create labels and save these to helpers
alias: Dymo Create Label by Voice
description: ""
trigger:
- platform: conversation
command:
- >-
[Create|Print] [a] [dymo|food] label {quantity} [portions|portion] [of]
{food}
condition: []
action:
- service: input_text.set_value
metadata: {}
data:
value: "{{ trigger.slots.food |title}}"
target:
entity_id: input_text.dymo_food_label
- service: input_text.set_value
metadata: {}
data:
value: "{{ trigger.slots.quantity }}"
target:
entity_id: input_text.dymo_food_portion
- set_conversation_response: OK, {{ trigger.slots.food | title}}. Say 'print 2 labels'
mode: single
and another to actually print. I had some problems here, I need to pass an integer number of prints to the script, but speech-to-text tends to use words rather than digits. It would be handy if custom sentence could somehow be cast as integers with some reasonably logic around it, but for the moment, I’ve just bodged some find and replace logic for two->2. I also found some words are commonly mistaken by speech-to-text (Too instead of two, Free instead of Three) and hard coded some corrections in
alias: Dymo Label - Print Food Label (Voice)
description: ""
trigger:
- platform: state
entity_id:
- input_button.dymo_print_label
- platform: conversation
command:
- Print {number} Labels
- Print Label
- Print [1|one|a] [Label|Labels]
condition: []
action:
- if:
- condition: template
value_template: "{{ trigger.slots.number|length != 0 }}"
- condition: template
value_template: >-
{{trigger.slots.number|replace('one','1')|replace('to','2')|replace('too','2')|replace('two','2')|replace('free','3')|replace('three','3')|replace('four','4')|replace('five','5')|replace('six','6')|int<7}}
then:
- service: notify.print_dymo_label
data:
message: >-
{{states('input_text.dymo_food_label')}}\n{{states('input_text.dymo_food_portion')}}
Portion\n{{now().day}}/{{now().month}}/{{now().year}},{{trigger.slots.number|replace('one','1')|replace('two','2')|replace('to','2')|replace('too','2')|replace('free','3')|replace('three','3')|replace('four','4')|replace('five','5')|replace('six','6')}}
else:
- service: notify.print_dymo_label
data:
message: >-
{{states('input_text.dymo_food_label')}}\n{{states('input_text.dymo_food_portion')}}
Portion\n{{now().day}}/{{now().month}}/{{now().year}},1
mode: single
Final result, it works, even if there are some dirty hacks.
As far as I can see I’m the first to hook up a Dymo to home assistant, so I hope it’s useful for others in the future.