Json templating - ph meter, arduino uno and nodeMCU

Hi,
Since few days i’m struggling with data extraction from json string. I connected ph meter to arduino uno and nodeMCU and sending serial printout through mqtt (tasmota). The mqtt message is:
{"SSerialReceived":"sensor = 6.74 "}
What i’m trying to do is to set template, to read ph value- (sensor=)
I tried something like this:
{{ value_json['sensor'] }} or
{{ value_json['SSerialReceived'].sensor }} but it did not work.
Any help will be appreciated.
Cheers,
Jan

You’re problem is that your message recieved from MQTT is crap. It doesn’t follow any actual object type so it makes it a string. Try this:

{{ value_json.SSerialReceived.split(' = ')[-1].strip() | float }}

Hi thanks for replay. unfortunately your code does not work. That’s true i will try to fix the output from arduino to make it more simple. Right now i use this code:

const int analogInPin = A0; 
int sensorValue = 0; 
unsigned long int avgValue; 
float b;
int buf[10],temp;
void setup() {
 Serial.begin(9600);
}
 
void loop() {
 for(int i=0;i<10;i++) 
 { 
  buf[i]=analogRead(analogInPin);
  delay(10);
 }
 for(int i=0;i<9;i++)
 {
  for(int j=i+1;j<10;j++)
  {
   if(buf[i]>buf[j])
   {
    temp=buf[i];
    buf[i]=buf[j];
    buf[j]=temp;
   }
  }
 }
 avgValue=0;
 for(int i=2;i<8;i++)
 avgValue+=buf[i];
 float pHVol=(float)avgValue*5.0/1024/6;
 float phValue = -5.70 * pHVol + 21.34;
 Serial.print("sensor = ");
 Serial.println(phValue);
 
 delay(20);
}

So i think if get rid of sensor=, the output should be more simple
Right?

Yes, get rid of the sensor = bit then the value_template will be

{{ value_json.SSerialReceived | float }}

EDIT: Also, if the other template isn’t working, then something else is wrong with your MQTT setup (Home assistant configuration side).

Another try with no luck. Now when i do not define template the measurement in Hassio looks like this:
ph

… and why would you do that?

The MQTT payload clearly contains content that requires a template to extract the desired value. Use the template petro provided.


If for whatever reason you do not want to use a template, then you will need to modify the arduino’s code so that it simply sends a numeric value and nothing more.

Post your configuration because you must be putting the template in the wrong spot or something.

Hey i deleted template to see if mqtt message is arriving. My configuration of sensor looks like this:

mqtt:
  broker: 192.168.1.17
  port: 1883
  username: 
  password: 
  discovery: true
  discovery_prefix: homeassistant

sensor:
  
  - platform: rest
    scan_interval: 900
    name: Airly
    resource: https://airapi.airly.eu/v2/measurements/nearest?lat=49.74861&lng=18.633723&maxDistanceKM=1
    value_template: "{{ value_json['current']['values'][0]['value'] }} {{ value_json['current']['values'][1]['value'] }} {{ value_json['current']['values'][2]['value'] }} {{ value_json['current']['values'][3]['value'] }} {{ value_json['current']['values'][4]['value'] }} {{ value_json['current']['values'][5]['value'] }} {{ value_json['current']['indexes'][0]['level'] }} {{ value_json['current']['indexes'][0]['value'] }} {{ value_json['current']['indexes'][0]['description'] }}"
    headers:
      apikey: 
      Accept-Language: pl
  
  - platform: antistorm
    station_id: 49
    monitored_conditions:
      - 'storm_probability'
      - 'storm_time'
      - 'rain_probability'
      - 'rain_time'
      
  - platform: mqtt
    name: Temperatura w biurze
    state_topic: tele/office/SENSOR
    value_template: "{{ value_json['HTU21'].Temperature }}"
    unit_of_measurement: "°C"

  - platform: mqtt
    name: PH
    state_topic: ph_sensor/tele/RESULT
    value_template: "{{ value_json.SSerialReceived | float }}"
    unit_of_measurement: "Ph"

- platform: template
    sensors:
      airly_pm1:
        friendly_name: "Pył PM1"
        icon_template: mdi:jquery
        unit_of_measurement: "μg/m3"
        value_template: "{{ states.sensor.airly.state.split(' ')[0] }}"
      airly_pm25:
        friendly_name: "Pył PM25"
        icon_template: mdi:jquery
        unit_of_measurement: "μg/m3"
        value_template: "{{ states.sensor.airly.state.split(' ')[1] }}"
      airly_pm10:
        friendly_name: "Pył PM10"
        icon_template: mdi:jquery
        unit_of_measurement: "μg/m3"
        value_template: "{{ states.sensor.airly.state.split(' ')[2] }}"
      airly_pressure:
        friendly_name: "Ciśnienie"
        icon_template: mdi:gauge
        unit_of_measurement: "hPA"
        value_template: "{{ states.sensor.airly.state.split(' ')[3] | float | round(1) }}"
      airly_humidity:
        friendly_name: "Wilgotność"
        icon_template: mdi:water-percent
        unit_of_measurement: "%"
        value_template: "{{ states.sensor.airly.state.split(' ')[4] | float | round(0) }}"
      airly_temperature:
        friendly_name: "Temperatura"
        icon_template: mdi:thermometer
        unit_of_measurement: "°C"
        value_template: "{{ states.sensor.airly.state.split(' ')[5] | float | round(1) }}"
      airly_quality:
        friendly_name: "Jakość powietrza"
        icon_template: mdi:quicktime
        value_template: "{{ states.sensor.airly.state.split(' ')[6] }}"
      airly_level:
        friendly_name: "Poziom"
        icon_template: mdi:database
        value_template: "{{ states.sensor.airly.state.split(' ')[7] | float | round(0) }}"
      airly_description:
        friendly_name: "Komunikat"
        icon_template: mdi:alert
        value_template: "{{ states.sensor.airly.state.split(' ')[8:] | join(' ') }}"
     
      bateria_htc:
        friendly_name: "bateria htc"
        unit_of_measurement: "%"
        value_template: "{{ states.device_tracker.jasiek_htc.attributes ['battery_level'] }}"
      ph_sensor:
        friendly_name: "miernik ph"
        unit_of_measurement: "PH"
        value_template: "{{ value_json.SSerialReceived | float }}"

Is it possible that space after number in mqtt message is makeing a mess w json code?

no, float will truncate it and convert it to a float. Are you getting errors in the logs? Not the UI logs, in the homeassistant.log file.

I found something like this:
Template sensor ph_sensor has no entity ids configured to track nor were we able to extract the entities to track from the value template(s). This entity will only be able to be updated manually.

and
Could not render template miernik ph: UndefinedError: 'value_json' is undefined

That might be adding special characters, change it to

 Serial.print(phValue);

cast it as a string if you have to

 Serial.print((string)phValue);

I have to clarify, I have no idea what language that is. I’m taking a stab in the dark.

Ok, that was it - i removed line:
Serial.println(phValue);
and just left line:
Serial.print(phValue);
Than i used template provided by Petro:
{{ value_json.SSerialReceived | float }}
Works like charm!
Thank you very much, my shrimps will be pleased with ph monitoring :wink:ph

1 Like

I’m glad that actually worked. That last character must be a carriage return or something, which was causing the json parser to screw up.

What physical sensor are you using to test ph? Do you find it reliable?

Hi, is there anyway you can post your final working code and what sensor you are using? I am trying to get a ph sensor working and I am new to json code and have no idea where to start. I am just wanting to read ph to a esp32 and send it via mqtt to my home assistant,
thanks for any help you can provide…