Searching for text in YAML and py files
This package was created specifically for the ‘hide_entity’ error, that does not show where it has found the entries, but I found it also useful for finding entities that I wanted to rename in the UI, but were linked to various automations, scripts and other places.
The package on github: HA-search4text
Tested on Home Assistant Core, version 0.107, running in a.Docker image on a Synology NAS.
Installing:
- Put the yaml file in your packages folder.
- Put the lovelace file in your lovelace configuration.
Usage:
- Enter text in the input-box
- Click ‘SEARCH IT…’
- Wait for a few seconds
- Right-click on the lower part of the windows and choose ‘Refresh this frame’, of whatever your browser calls it
- The search results will show up
The search results are grepped, with above and below three lines for context. The text output is converted to html and presented in a webframe card.
The search results will also be present in the /config folder of Home Assistant.
If you only want to see the files and not the contents, set the option ‘Return only filenames’ to ‘on’.
Issues:
If you have a solution for the manual refresh problem, please let me know.
Random comments:
To make this package I learned a lot about YAML, jijna, linux and python and had to overcome some (actually a lot) of limitations of Home Assistant, YAML, jinja and python. Here are some of them.
Passing parameters from a script to a shell_command
My first idea was to do something like this:
shell_command:
find_text: >-
grep -i --recursive {{ text }} /config --include "*.yaml" >> /config/found_text.txt
scripts:
find_text:
alias: Find Text
description: Search files for text. Output in /config/found_text.txt.
fields:
text:
description: Text to search for
example: 'hide_entity'
sequence:
- service: shell_command.find_text
data_template:
text: "{{ text }}"
The problem was that a shell_command does not allow templating and shell redirection in one command. I ended up with one shell_command to create a shell_script and another to call the script. Like this:
shell_command:
find_text_create_script:
echo 'grep -i --recursive "$*" /config --include "*.yaml" >> /config/found_text3.txt' >> /config/find.sh
find_text: ./find.sh {{ text }}
scripts:
find_text:
alias: Find Text
description: Search files for text. Output in /config/found_text.txt.
fields:
text:
description: Text to search for
example: 'hide_entity'
sequence:
- service: shell_command.find_text_create_script
- service: shell_command.find_text
data_template:
text: "{{ text }}"
Dealing with large files
I used this sensor to retrieve the contents of the results file.
sensor:
- platform: command_line
name: find text
scan_interval: 3600
command: 'cat /config/found.txt'
and displayed the sensor state in a lovelace card. But a sensor can only contain 255 characters, so for large queries the state was left empty. The solution was to convert it to a web page and use the webframe card.
Templating service_data in lovelace cards
On of my first attemps at a lovelace card was this:
type: entities
entities:
- entity: input_text.search4text
icon: 'mdi:magnify'
name: Search yaml en py files for
- action_name: Search It ...
name: ' '
service: script.search4text
service_data_template:
text: {{ input_text.search4text }}
type: call-service
The tag service_data_template does not exist and the template was not extended. The solution for this was accessing the {{ input_text.search4text }} entry directly in the script:
- service: shell_command.find_text
data_template:
text: "{{ states('input_text.search4text') }}"