Searching for text in yaml and py files

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.

search4text

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') }}"
1 Like

As an alternate, this command can be executed on the command line to recursively search all YAML and python files for a given string. It begins its search starting from the current directory (i.e. from whichever directory the command is executed).

grep --include=\*.{yaml,py} -rnw "hidden"
1 Like

Thanks Taras, I’m currently using this command line.

grep -i --before-context=3 --after-context=3 --line-number --with-filename --text --recursive "$*" /config --include=\*.{yaml,py}

Yep, ultimately both produce the same result (more or less). The only caveat with using grep is it had fewer available options on HassOS (or at least it used to).

Why not use a Code Editor like Visual Studio Code, even better with the Home Assistant Plugin or am I missing something?

A good suggestion, @Burningstone. It’s very well possible that I found a solution to a non-existing problem. I never tried a Code Editor. I just looked but it’s not in HACS, I think. I’m using Home Assistant Core, I would like to edit also when I’m on my phone or at work, I mainly use Notepad++ for editing, except for Yoomla on my otherwise Notepad++ power websites.Where can I find a Code Editor plugin and will it fill all my needs?

For Home Assistant there is a visual studio code add-on. I normally just use samba together with visual studio code, however I don’t edit my files on the go as I can not verigy some things outside home and I’d ragher not mess with the system when my wife is at home and I’m not.

Hello.
I’m using, on a windows PC, a mapping to /config and opening a powershell command window:

findstr /S /I /N (Read-Host -Prompt ‘Input string to look for’) *.yaml
(Don’t put the string to find in the command line above ! ! ! The prompt will do it :wink:
This is going to list all the files and line number containing the string the command ask for.

Again, why not just use visual studio code’s search function??

i just gave it a try now :slight_smile: and yes, looks so powerfull !
I’ll have to explore the so many possibilities.
Thanks

1 Like

Could someone possibly help me with getting this to work?

I have the package installed and have restarted.

When I go and create a new dashboard page within the lovelace editor and then go to the bottom and paste the configuration code that I copied from the repo (pasted below), I get the second screenshot. It’s almost as if, the ui editor isn’t reading things correctly? Has the way to write the code changed since this package was developed? Thank you all for any help you can provide.
EDIT: The below code didn’t seem to work (from the repo download)

type: vertical-stack
cards:
    type: entities
  - entities:
      - entity: input_text.search4text
        icon: 'mdi:magnify'
        name: Search yaml en py files for
      - entity: input_boolean.search4text_filesonly
        icon: 'mdi:file-tree'
        name: Return only filenames
      - action_name: Search It ...
        icon: 'mdi:information-outline'
        name: (Refresh frame for updated results)
        service: script.search4text
        type: call-service
  - aspect_ratio: 50%
    type: iframe
    url: /local/found_text.html

EDIT: This code seemed to work but produced a “404: Not Found” error in the iFrame area. Maybe this error will go away after a successful run of the search?

type: vertical-stack
cards:
  - type: entities
    entities:
      - entity: input_text.search4text
        icon: 'mdi:magnify'
        name: Search yaml en py files for
      - entity: input_boolean.search4text_filesonly
        icon: 'mdi:file-tree'
        name: Return only filenames
      - action_name: Search It ...
        icon: 'mdi:information-outline'
        name: (Refresh frame for updated results)
        service: script.search4text
        type: call-service
  - aspect_ratio: 50%
    type: iframe
    url: /local/found_text.html