Maker API, Nodered and InfluxDB


#1

I have been trying to write data to influx db using node red for off and on for a while but have never had any success and was hoping that someone could help me with the configuration. I have Nodered and influxdb running in dockers on the same server.

My websocket is configured
image

My database is configured
image

With this flow deployed but I am not getting values in the DB.

I know its a configuration problem somewhere but cant seem to track it down. Thanks for any help


#2

Probably better to post this in the NodeRed/influxdb thread as that's where the most knowledgeable congregate.

A couple things off the bat. Remove the leading "/" in the eventsocket uri. I can't tell exactly how you have it confiugred with the screenshot because you are showing the info tab instead of the configuration tab...but make sure you are using "connect to" and NOT "listen on".

Secondly, the influx node needs to be the influx batch node and not the influx out node. Take a look at the main thread. There are posts with flows that you can import and edit as needed. Much easier that way.


#3
  1. Start with just a websocket node piped to a debug node. Get that working 1st, as the influxdb part doesn't matter if you don't have data coming in...
  2. Get rid of the "/" at the beginning of the web socket path, that is definitely wrong.
  3. You can use the influxdb OUT node or BATCH node... I use the OUT node on all of mine, in fact, and it works fine. It all depends on how you construct the message. I'll go look, though, as there may be some benefits to running BATCH over OUT node that I haven't thought of.

#4

Good to know. I initially had mine with out node and could not get it to work (can't remember the exact issue now). Using the batch node as prescribed by the examples in the other thread seemed to fix my particular issue.


#5

Also, based on your screenshot, you have the websocket in node configured as "Listen On". That needs to be changed to "Connect to".

EDIT: Oh, @stephack already said that. LOL. I can confirm he is right. When set to "connect to" the connection string shows up in the client field, not the server field on the info page.


#6

Reconfigured the websocket as below

And wired the socket to a debug node.

Deployed the node and am seeing the below in the debug log


#7

Looking through the other thread, it looks like people are using a function node to properly format the websocket data for their database. If so I am a little confused on how to format this function node for influxdb rather than sql.


#8

Here's my function node. I customized a few things for my particular setup but all the basic functionality should work for you as well.

[
    {
        "id": "8a57a9c5.166098",
        "type": "function",
        "z": "51237af2.884334",
        "name": "Set Influx Data",
        "func": "\nconst ACTIVE = 'active';\nconst CLOSED = 'closed';\nconst DETECTED = 'detected';\nconst FOLLOW_SCHEDULE = 'follow schedule';\nconst GOOD = 'good';\nconst HEATING = 'heating';\nconst LOCKED = 'locked';\nconst MUTED = 'muted';\nconst OFF = 'off';\nconst ON = 'on';\nconst OPEN = 'open';\nconst PRESENT = 'present';\nconst PUSHED = 'pushed';\nconst SLEEPING = 'sleeping';\nconst TOUCHED = 'touched';\nconst WET = 'wet';\n\nvar v = {\n    'value' : null,\n    'isBinary' : null\n};\n\nif(msg.name == \"acceleration\") {\n    v.value = (msg.value == ACTIVE ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"alarm\") {\n    v.value = (msg.value != OFF ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"button\") {\n    v.value = (msg.value != PUSHED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"carbonMonoxide\") {\n    v.value = (msg.value == DETECTED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"consumableStatus\") {\n    v.value = (msg.value == GOOD ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"contact\") {\n    v.value = (msg.value == OPEN ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"door\") {\n    v.value = (msg.value != OPEN ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"lock\") {\n    v.value = (msg.value == LOCKED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"motion\") {\n    v.value = (msg.value == ACTIVE ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"mute\") {\n    v.value = (msg.value == MUTED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"presence\") {\n    v.value = (msg.value == PRESENT ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"shock\") {\n    v.value = (msg.value == DETECTED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"sleeping\") {\n    v.value = (msg.value == SLEEPING ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"smoke\") {\n    v.value = (msg.value == DETECTED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"sound\") {\n    v.value = (msg.value == DETECTED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"switch\") {\n    v.value = (msg.value == ON ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"tamper\") {\n    v.value = (msg.value == DETECTED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"thermostatMode\") {\n    v.value = (msg.value != OFF ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"thermostatFanMode\") {\n    v.value = (msg.value != OFF ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"thermostatOperatingState\") {\n    v.value = (msg.value == HEATING ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"thermostatSetpointMode\") {\n    v.value = (msg.value != FOLLOW_SCHEDULE ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"touch\") {\n    v.value = (msg.value != TOUCHED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"optimisation\") {\n    v.value = (msg.value == ACTIVE ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"windowFunction\") {\n    v.value = (msg.value == ACTIVE ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"water\") {\n    v.value = (msg.value == WET ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"windowShade\") {\n    v.value = (msg.value == CLOSED ? 1 : 0);\n    v.isBinary = true;\n}\n\nelse if(msg.name == \"threeAxis\") {\n    var vz = msg.value.split(',');\n    var x = vz[0];\n    var y = vz[1];\n    var z = vz[2];\n    v.value = {\n        x: vz[0],\n        y: vz[1],\n        z: vz[2]\n    };\n    v.isBinary = false;\n}\nelse if (msg.value.match(/.*[^0-9\\.,-].*/)) { // match if any characters are not digits, period, comma, or hyphen.\n    v.value = '\"' + msg.value + '\"';\n    v.isBinary = false;\n}\n\n// Catch any other general numerical event (carbonDioxide, power, energy, humidity, level, temperature, ultravioletIndex, voltage, etc).\nelse {\n    v.value = Number(msg.value);\n    v.isBinary = false;\n}\nif (msg.name == \"threeAxis\"){\n    msg.payload = [\n        {\n            measurement: msg.name,\n            fields: {\n                valueX: v.value.x,\n                valueY: v.value.y,\n                valueZ: v.value.z\n            },\n            tags:{\n                hub: msg.hubId ? msg.hubId : \"HE1\",\n                deviceId: msg.deviceId,\n                displayName: msg.displayName,\n                unit: msg.unit\n            },\n            timestamp: new Date()\n        }\n    ]\n} else if (v.isBinary)\n{\n    msg.payload = [\n        {\n            measurement: msg.name,\n            fields: {\n                value: msg.value,\n                valueBinary: v.value\n            },\n            tags:{\n                hub: msg.hubId ? msg.hubId : \"HE1\",\n                deviceId: msg.deviceId,\n                displayName: msg.displayName,\n                unit: msg.unit\n            },\n            timestamp: new Date()\n        }\n    ]    \n}\nelse\n{\n    msg.payload = [\n        {\n            measurement: msg.name,\n            fields: {\n                value: (Array.isArray(v.value) ? v.value.join(',') : v.value),\n            },\n            tags:{\n                hub: msg.hubId ? msg.hubId : \"HE1\",\n                deviceId: msg.deviceId,\n                displayName: msg.displayName,\n                unit: msg.unit\n            },\n            timestamp: new Date()\n        }\n    ]\n}\n//console.log(util.inspect(msg, {showHidden: false, depth: null}))\n\nreturn msg;",
        "outputs": 1,
        "noerr": 0,
        "x": 860,
        "y": 100,
        "wires": [
            [
                "b830779d.7c0cf8"
            ]
        ]
    }
]

#9

Do you mind elaborating a little on the "func": line?


#10

In terms of what? That is the function code he uses to parse the incoming message values/pieces into something you can shove into influxdb.


#11

@stephack, using your function node created a msg.payload entry in the hubitat DB but there arent any values in it.


#12

I'm not following what you are trying to do here. The function node takes the raw data flowing in from the event socket and transforms it into the correct format before inserting it into the database. None of this is my forte, I just followed the instructions and flows shared in the main thread and then customized it to suite my needs.

Have you considered installing influxdb without using docker. I remember trying to get this going in a container and it justed seemed to add more complexity than necessary to a relatively simple process.

I'll hunt down the post where @btk shared his entire flow for influxdb. It's what I used as my foundation.

Edit: my mistake, I stole that portion from @dan.t. See below.