Extracting numeric info from "File Sensor" Template issues again! Victron VEDirect Monitoring

Tried JSON with no avail…

So I’ve set up a File Sensor to read a file called bmv700.txt which displays results as so:

{‘FW’: ‘0308’, ‘SOC’: ‘968’, ‘Relay’: ‘OFF’, ‘PID’: ‘0x203’, ‘H10’: ‘0’, ‘BMV’: ‘700’, ‘TTG’: ‘-1’, ‘H12’: ‘0’, ‘H18’: ‘222’, ‘I’: ‘6524’, ‘H11’: ‘0’, ‘Alarm’: ‘OFF’, ‘CE’: ‘-5795’, ‘H17’: ‘152’, ‘P’: ‘88’, ‘AR’: ‘0’, ‘V’: ‘13533’, ‘H8’: ‘14148’, ‘H9’: ‘77533’, ‘H2’: ‘-61453’, ‘H3’: ‘-60260’, ‘H1’: ‘-61453’, ‘H6’: ‘-126081’, ‘H7’: ‘4’, ‘H4’: ‘2’, ‘H5’: ‘0’}

in configuration.yaml as part of the File Sensor config i’m using a template of:

  - platform: file
    name: BMV - SOC
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ value.split(',')[1] }}

And getting exactly this in the front end:

‘SOC’: '968’

That is State of charge (batteries) at 96.8%.

I’d like to only display 96.8% and none of the letters or punctuation.

Any help greatly appreciated.

Wouldn’t Home Assistant recognize that as a JSON string and import it as a JSON object?

Try this and see if it works:

  - platform: file
    name: BMV - SOC
    file_path: /config/vedirect/bmv700.txt
    value_template: "{{ (value_json.SOC | int) / 10  }}"
    unit_of_measurement: '%'

If it fails then try this:

  - platform: file
    name: BMV - SOC
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value.split(',')[1].split(':')[1][2:-1] | int) / 10  }}
    unit_of_measurement: '%'

Definite progress :slight_smile:

First code came back as unknown on the sensor. Second has given a percentage reading of 0.0% which is good!
The sensor “SOC” (inside the file) is now at 1000 (100% fully charged)

See pic where I have applied the formula to TTG sensor.

33

So you’re saying Home Assistant failed to recognize the data as being a JSON string and so the first example I supplied failed?

Does the second example work? I can’t tell from your screenshots.

No it’s giving a result of 0%
Both of those sensors reference the SOC result from the file BMV700.txt
The actual state of charge now is 100%

Yes looks like it didn’t think it was JSON.
In states it said unknown but it did register % as it’s template.

So the contents of that file are not JSON. AFAIK, JSON requires double-quote characters. You didn’t format it so we can see it raw, but it looks like it’s using simple, single-quote characters.

If you replaced the single-quote characters with double-quote characters, then you could use the new from_json filter, something like this:

value_template: >
  {{ (value.replace("'",'"')|from_json).TTG ... }}

No joy.
Errors…
" Configuration invalid

Invalid config for [sensor.file]: invalid template (TemplateAssertionError: no filter named ‘from_json’) for dictionary value @ data[‘value_template’]. Got ‘{{ (value.replace(“'”,'"')|from_json).SOC }}\n’. (See ?, line ?). Please check the docs at https://home-assistant.io/integrations/sensor.file/"

  • platform: file
    name: BMV - SOC 2
    file_path: /config/vedirect/bmv700.txt
    value_template: >
    {{ (value.replace(“'”,‘"’)|from_json).SOC }}
    unit_of_measurement: ‘%’

What version are you using. These filters were added in 0.101. (I did say “new from_json filter.” :wink:)

Just upgraded and still have the same error. Will look into fixing the errors! Like the sound of the component…

Good news tho 123Taras
Now I’ve rebooted and re-pasted your code in. Its working! (may have been a glitch)

Not sure if when it hits 100% again it will go to 0% but we will find out tomorrow when they fully charge again.

Heres the layout!

Thanks for your help chaps :slight_smile:

FWIW, I tried it with 0.101.0 and it worked ok for me. In case it’s not obvious, the ... part meant to put in whatever other math you want. It wasn’t meant to be literal.

My bad. Removed … and no errors. However, no sensor has appeared in states. Re-labled the sensor in config to see if it was a glitch. But no cigar.

Probably me being a … lol


  - platform: file
    name: ABC
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value.replace("'",'"')|from_json).SOC }}

Tho it does turn out I’m probably going to need your option pnbruckner as when you reboot the NUC the format of the BMV700.txt can change the results order. Ie: SOC is not at the start of the list. Its in a different place.

This should work regardless of the location of SOC within the string. regex_findall_index will search through it, using a regex pattern (regular expressions), and extract the desired value.

  - platform: file
    name: BMV - SOC
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value | regex_findall_index("\'SOC\': \'(\d+)\'") | int) / 10 }}
    unit_of_measurement: '%'
1 Like

Working like a charm! Its reporting better than the comma separated sensor which reported unknown regularly.

Thank you again 123Taras!

Is there a variable that the formula requires more than one letter to search for? The code has found TTG (time to go) and SOC (state of charge) but when I add “I” (Current) to a formula on a new current sensor. The sensor doesnt appear.


  - platform: file
    name: Amps
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value | regex_findall_index("\'I\': \'(\d+)\'") | int) / 1000 }}

It can search for a single letter. The regex pattern you are using is valid. I confirmed it using regex101:

I’m not sure why the sensor fails to appear. The sensor should be created regardless of the template’s ability to report a value.

Will have a dig!
That new config is clearly more stable than the comma separated version.
Thank you…

Something rather strange going on.
The SOC sensor using the regex_findall_index working fine!
I added a sensor looking for TTG which worked for a little while then errored on reboot…

Now I’ve added several sensors looking for other values. CE, I, RELAY.
None of those sensors are showing in states (even tho they were made from a copy of SOC and letters modded).

Tho the original SOC using regex_findall_index is working!

#############################################################################
  - platform: file
    name: ABC Amps
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value | regex_findall_index("\'I\': \'(\d+)\'") | int) / 10 }}
    unit_of_measurement: 'amps'
#############################################################################
  - platform: file
    name: ABC - Time to go
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value | regex_findall_index("\'TTG\': \'(\d+)\'") | int) / 10 }}
    unit_of_measurement: 'hrs'
#############################################################################
  - platform: file
    name: ABC - CE
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value | regex_findall_index("\'CE\': \'(\d+)\'") | int) / 10 }}
    unit_of_measurement: '%'
#############################################################################

The regex expression is not accounting for the possible minus sign. Also, if you’re quoting the regex expression with double-quote characters you don’t need to escape the single-quote characters. Try:

{{ (value | regex_findall_index("'CE': '(-*\d+)'") | int) / 10 }}

I have no idea what happened but both your scripts now work!

So I’ve used the new code on the new sensors…
Displaying great :-):grinning:

A minor tweak is needed but certainly not essential. Round doesnt seem to be working, sometimes I’m getting X.XXXXX as a result.

Is this the wrong use of round?

  - platform: file
    name: Battery absorb/discharge
    file_path: /config/vedirect/bmv700.txt
    value_template: >
      {{ (value | regex_findall_index("'I': '(-*\d+)'") | int) / 1000 | round(1) }}
    unit_of_measurement: 'amps'