Time Stamp and Influx DB problem

Hello, I'm injecting in my database an array of 2 elements: the first one is the fields and the second one is the tags as sugested here : [Influx DB contrib ][(https://flows.nodered.org/node/node-red-contrib-influxdb)]

In field I have put my timestamp because I don't want Influx DB to set the time_stamp, I wan't to set it.

This is my debug message (msg.payload) before the input of InfluxDB node (the classic one not the Batch node):

[{"time":1564134384,"Concentration_C02":4080,"Temperature":40.8,"Relative_Humidity":102,"Frame_Index":2},{"Device":"test_datalog","Type_Produit":"Insafe_Carbon_Sigfox","Type_Message":"Datalog"}]

This my error message coming from InfluxDB node: Error: A 400 Bad Request error occurred: {"error":"partial write: points beyond retention policy dropped=1"}

This my DB retention configuration: ( I have deleted autogen retention policy)

name  duration  shardGroupDuration replicaN default
----  --------  ------------------ -------- -------
un_an 8760h0m0s 168h0m0s           1        true

Thank you for your help

Try adding three zeros to the end of the timestamp. I believe it needs to be a javascript timestamp, which is in milliseconds.

Thank you for your answer now node-red recognize that it's a timestamp and display it as a date (without any other node as moment) but I still have the same problem :Error: A 400 Bad Request error occurred: {"error":"partial write: points beyond retention policy dropped=1"}

Is it ok if you don't give it the timestamp, so that influx adds the timestamp? I know you don't want to do this, just checking whether it is ok otherwise.
Also I notice that the influxdb out node does not say that you can include a timestamp. Have you tried the same thing using the batch node, which does say a timestamp can be included.

Yes it's working very well when I don't change my timestamp but I'm receiving one payload every hour but each payload contains 3 messages (one measurement every 20 minutes).

I have just checked the InfluxDB contrib info and the time can be injected I think:

msg.payload = [
    [{
        numValue: 10,
        randomValue: Math.random()*10,
        strValue: "message1",
        time: new Date("2015-12-28T19:41:13Z").getTime()
    },
    {
        tag1:"sensor1",
        tag2:"device2"
    }],
    [{
        numValue: 20,
        randomValue: Math.random()*10,
        strValue: "message2",
        time: new Date("2015-12-28T19:41:14Z").getTime()
    },
    {
        tag1:"sensor1",
        tag2:"device2"
    }]
];
return msg;

Where have you found that example? Also the example shows an array of arrays whereas you have just shown an array in the data you showed.

You are right it was a mistake, finally I have choosen the batch node and I'm injecting a message according to the influx node doc(the last exampke) but I still have the same error message

Error: A 400 Bad Request error occurred: {"error":"partial write: points beyond retention policy dropped=3"}

[{"measurement":"real_time","fields":{"Concentration_C02":3400,"Temperature":34,"Relative_Humidity":85,"Frame_Index":2},"tags":{"Device":"test_datalog_now","Type_Produit":"Insafe_Carbon_Sigfox","Type_Message":"Datalog"},"timestamp":1564128384000},{"measurement":"real_time","fields":{"Concentration_C02":3740,"Temperature":37.4,"Relative_Humidity":93.5,"Frame_Index":2},"tags":{"Device":"test_datalog_now","Type_Produit":"Insafe_Carbon_Sigfox","Type_Message":"Datalog"},"timestamp":1564131384000},{"measurement":"real_time","fields":{"Concentration_C02":4080,"Temperature":40.8,"Relative_Humidity":102,"Frame_Index":2},"tags":{"Device":"test_datalog_now","Type_Produit":"Insafe_Carbon_Sigfox","Type_Message":"Datalog"},"timestamp":1564134384000}]

Thank you for your support

From the error message, it looks like the timestamps you've provided to the Batch output node are numbers, so these will be passed in to InfluxDb for parsing. Since InfluxDb uses nanosecond precision by default, these millisecond dates may be outside of your retention policy, causing this error to be thrown.

https://node-influx.github.io/class/src/index.js~InfluxDB.html#instance-method-writePoints

Have you tried using Javascript Date objects for your timestamps as in the example? E.g. "timestamp": new Date(1564128384000) rather than "timestamp":1564128384000? This should cause the library to convert to the right precision. I think another option might be to specify the precision (e.g. 'ms') with the writes as in the writePoints documentation.

2 Likes

If I let my time-stamp in miliseconds Node Red recongnize automatically that it's a timestamp and in the debug I can display it as a date.
If I multiply by 1000 (to have a nanoseconds) node red don't recognize that it's a date.

Solution: To use a batchnode and using the Date object using a miliseconds precision

Thank you for your help !

1 Like

You only need to multiply it by 1000 when sending it to the influx node. Leave it as a javascript date when using it elsewhere. That would be an alternative solution.

Multiplying an epoch in milliseconds (1564128384000) by 1000 results in microseconds.
Should be multiply by 1000000 which gives (1564128384000000000)

2 Likes

Somewhat late to the party, but I had pretty-much the same requirement - and the same frustration, trying to get influxdb to accept input with a time value of my choosing. (I kept getting an error message that said the time wasn't between the permitted ranges, while quoting back at me my value, which clearly was!)

Long story short:

  1. use the influx batch node;
  2. leave the time precision in the node as Default;
  3. create a payload that's an array of objects, where every object is one row to add to the db;
  4. send the time value as an integer number of nanoseconds (irrespective of whatever precision you use).

By way of example, here's the (working!) test payload I constructed:

msg.payload = [
    {   // first row
        measurement: "test", 
        fields: {
            numValue: 10,
            randomValue: Math.random()*10,
            strValue: "message1",
            mytime: new Date().getTime()
        },
        tags: {
            tag1:"sensor1",
            tag2:"device2"
        },
        timestamp : new Date().getTime() * 1e6  // time now; convert milliseconds to nanoseconds
    },
    {   // second row
        measurement: "test",
        fields: {
            numValue: 20,
            randomValue: Math.random()*10,
            strValue: "message2",
            mytime: new Date().getTime() + 6000000
        },
        tags: {
            tag1:"sensor1",
            tag2:"device2"
        },
        timestamp : (new Date().getTime() + 6000000 ) * 1e6   // (arbitrary) 6000s in the future
    }
];
return msg;

I hope that helps someone.

Still, I'd like to know why it doesn't work with the Influxdb out node... That's pretty strange.

Why what doesn't work with the influx out node?

I also had problems setting an arbitrary timestamp using the influx out node.

I sorted it out by setting the Time Precision setting to ms and feeding the node with an array of array containing an object with the fields and values :

[
   [{"time":1648567800000,"Power":120}],
   [{"time":1648567500000,"Power":144}]
]

You haven't shown an example of what doesn't work.

Right. I didn't set an array of array of object, only an array of object. I believe that's the same for OP, beside the time precision issue.

I know it adds a bit more CPU overhead, but when dealing with timestamps going to influx, I prefer to simply throw a node-red-contrib-moment node in the flow with the output format set to "x" (lower case is important for the formatting.) This will get your timestamp into a format that influx likes.

Here's an example payload structure I'm sending. The output of the moment node would be going to msg.time before the flow heads into a function that looks as follows:

msg.payload=[
    {
        [msg.payload.col7]:msg.payload.col10,
        time:msg.time,
    },
    {
        MRN:msg.payload.col1,
        bed:msg.payload.col6,
        dateOfBirth:msg.DOB,
        valUnval:"UNVALIDATED",
        deviceName:msg.payload.col6,
        flowsheetRowName:msg.payload.col7
    },
];
return msg;

I then send the output of this to a join node (my source data for this flow is coming from a CSV file, so it already has the split metadata) to turn it into an array of arrays.

edit: this is assuming influx 2.0.

Please provide example of a payload that does not work.

[Edit] and tell us which influx node you want to send it to. Influxdb Out or Batch?

The OP could not write data to an InfluxDB using the Influx Out node.

There were some discussions regarding the time format, and then someone (you ?) said that writing multiple fields at a time must be done using the batch node. That's not true. You must provide an array of array of objects containing the data (fields and tags).

@JayDickson : the timestamps are not that complicated. Javascript date-related functions have a resolution to the ms. Simply configure the influx nodes ("Time Precision") to the one you use in your project.