Problems formatting for InfluxDB out for Influxv1 Home Assistant

This is for the Home Assistant InfluxDB v5.0.2 embedded. and Home Assistant Node-red 21.0.7.

I have a pulse count electricity meter reader which works well, but I want to only take a meter reading once per month. I figured this out using a cronplus node addition. I then want to place this once per month reading into InfluxDB.

I have looked at the instructions in various places but cannot figure out how I set up “measurements”. As a trial I have used an inject node and debug to get the reading from HA, which returns a correct value. But I just cannot understand how I have to then setup the payload etc, so it will then put into InfluxDB. (I can configure the appropriate access to InfluxDB ok - no problems with that)

It is very embarrassing but I am really struggling with this. I have the flow working in the Node-Red but after looking at multiple YouTube tutorials and other instruction manuals on Node-red website I just cannot understand what information I need to “change” in the node to get it accepted by InfluxDB.

There is lots of info about generating this random number and that random number in JSON, but nothing for taking the reading from an actual entity and changing it to be accepted by InfluxDB.

Can someone please explain in simple language what I need to change and into what. I have very little JSON knowledge and maybe this is why I am struggling.

This is the current flow:

This is the expression for the current state node:

Any help greatly appreciated, but please keep simple for my lack of understanding.

Do you want a fixed measurement in that influxdb out node or do you want to include it in the message? If fixed then put the measurement name in the measurement field in the node config, if variable then, as described in the help text for the node:
" If the measurement field is not set in the node configuration, the user can send in data with a specified measurement name in msg.measurement".
So in your inject node set msg.measurement to the measurement name you want.

Note that if you want the timestamp to be the current time then don't provide a timestamp.

If you want to add a tag then again look in the help text for the node. In particular:
" If msg.payload is an array containing two objects, the first object will be written as the set of named fields, the second is the set of named tags."
So in msg.payload you might want something like

[
  {value: 12345},
  {entity_id: "the id"}
]

That will write a field "value" with 12345 and a tag "entity_id" containing "the_id".

I am trying to take a reading from a specific sensor, read once per month (in this case a utility pulse generated meter reading) using the node Cronplus. it is this reading I want to pass onto InfluxDB so I can link to Gafana and plot my monthly meter reading.

So in my flow I can get the payload as the current meter reading (at the time of using the test "inject" node) but when I look in InfluxDB there is an error "your query is syntactically correct but returned no results".

I guess for that reason there is an error in the fields or payload I am writing to the InfluxDB out node. Unfortunately I have no idea what the fields are.

I tried omitting the "measurement" in InfluxDB out and put it in the msg.measurement (kWh), it shows in the debug node and in InfluxDB but still with the same statement as above. however this then seems to corrupt the other sensors with the same measurement unit and so I put the kWh in the InfluxDB out node "measurement" again

Then I have to restart InfluxDB to get rid of the error.

Hope that is clear?

Let's start again.

What do you want to call the measurement? Note that the measurement is name should be a descriptor of the fields and tags within it. So it might be something like Meter_Reading.

Is there only one data value (field) for that? What do you want to call it? Possibly something like 'value' or 'value_kwh'
Do you also want a tag associated with each value? If you have multiple meters then that might be the meter id.

When experimenting I suggest always dropping the measurement each time you try something else so that any existing data does not cause confusion.

So the sensor I am trying to measure form Home assistant is "sensor.electricity_meter_input_2_pulse_counter_value" and it's unit is kWh".

It outputs the meter reading at that point in time.

this is the current state node I have:

You might find this terminology/config post of use:

You do not appear to have answered any of my questions. I don't need to know anything about where the data comes from.

Sorry, I misread your question

Measurement can be " Monthly Electricity Meter Read"
The value can be "kWh"
No Tags necessary

Thanks - its not so much about the InfluxDB per se but how I can format the info to get into the InfluxDB

Indeed, I use a standard flow to make sure I'm formatting the data correctly having previously ruined db's by sending the wrong data.

Here is the function node code:

/**
 * Validate input suitable for the influxdb-out node.
 * We will ALWAYS use the "array containing two objects" payload
 * OR the singe Object payload (if no tags being used).
 * See the Description tab for more details.
 */

// check measurement field is set - if not exit with error
if ( ! msg.measurement ) {
    node.error('msg.measurement is missing')
    node.send([null,msg])
    return
}

let fields,tags

// if payload is an object, assume that it contains fieldName:fieldValue pairs
if ( msg.payload!== null && msg.payload.constructor.name === 'Object' ) {
    fields = msg.payload
} else if ( msg.payload!== null && msg.payload.constructor.name === 'Array' ) {
    node.error('msg.payload cannot be an array. It must be an object containing fieldName:fieldValue pairs or a single value (which would be written to the `value` field name).')
    node.send([null,msg])
    return
} else {
    // Otherwise, we always use 'value' as the default field name
    fields = {'value': msg.payload}
}

const lstFields = Object.keys(fields)

// check to make sure that there is a value field name - if not, continue but with a warning
if ( ! lstFields.includes('value') ) {
    // Lets us turn off the warning if we know what we are doing :-)
    if ( msg.noValueField !== true )
        node.warn('Default field name "value" not present, was that deliberate? Set msg.noValueField=true or use the `value` field name to avoid this msg')
}

// check to make sure that all field values are numeric - if not, exit with a warning
let allNumeric = true
lstFields.forEach( key => {
    // I use On/Off for simple switch values in MQTT but these are not useful
    // in InfluxDB, so translate them to ON=1 and OFF=0 (ignoring case).
    try {
        if ( fields[key].toLowerCase() === 'on' ) fields[key] = 1
        if ( fields[key].toLowerCase() === 'off' ) fields[key] = 0
    } catch (e) {}

    // then check to make sure the field is actually a number
    if ( parseFloat(fields[key]) !== fields[key] ) {
        node.error(`Field msg.payload.${key} is not numeric. Only use numbers for field values, text should go in tags. Value=${fields[key]}`)
        allNumeric = false
        node.send([null,msg])
        return
    }
})
// @ts-ignore
if ( allNumeric === false ) {
    return
}

// check to make sure that if msg.tags is present, it is an object - if not, exit with a warning
if ( msg.tags ) {
    if ( !(msg.tags!== null && msg.tags.constructor.name === 'Object') ) {
        node.error('msg.tags is not an object - it must contain tagName:tagValue pairs')
        node.send([null,msg])
        return
    }
    tags = msg.tags
}

// Format the output to go to the InfluxDB out node
if ( msg.tags ) {
    msg.payload = [
        fields,
        tags,
    ]
} else {
    msg.payload = fields
}


return msg;

Mostly, I send data via MQTT.

In that case the relevant bit of the help text is:
" If msg.payload is an object containing multiple properties, the fields will be written to the measurement."

Assuming the value is in msg.payload then all you need in a function node is

msg.payload = {kWh: msg.payload}
msg.measurement = "Monthly Electricity Meter Read"
return msg

Though I recommend using a much shorter measurement name and I don't know whether spaces are allowed.

Thank-you - that has parsed the reading through. That is precisely what I needed and helped tremendously.

Thanks for that. As you can tell from the questions I was asking, this maybe a little beyond me, however I will try to dissect and understand.

Why do you want to store this separately in influxdb ? There is a 'history' node for home assistant, where you can gather the data from for any length of time, it returns an array with each recorded value

You can run it through a function node/change node and perform the calculation if needed.

example change node with a jsonata expression, something like:

$sum(*.$number(attributes.Power_Delivered_l1))

It returns the total for the array.

Thank you. That is great information and I was not aware of this. I am storing in Influx so that I can graph it in Grafana and then embed back into Home Assistant. I can then see my monthly usage over time.

I could just cut out Node red altogether and just constantly read the values from the sensor over time. But this is wasteful of space and I thought it was a good learning exercise for me.

As you can tell, I am new to this and not from a coding background.

Indeed i think you can query the ha data in grafana directly and it can perform the calculations at runtime. You may want to google for that, influx will be faster, but also consider how often you would want to see it.

Influx is also useful for other things. For example, I use it with the related Telegraf system monitoring tool. That writes all of the system data to Influx and Grafana can then be used to see what is happening. Though I also use Telegraf's MQTT outputs for realtime data.

Grafana is also effectively a no-code query tool for Influx, not sure if you get that part if working with the HA data?

The Home Assistant's implementation of Grafana works very well.

O also use Influx and Grafana as part of Openplotter which is very good.