OpenSprinkler Forums Hardware Questions OpenSprinkler Pi (OSPi) Using MQTT to log data Reply To: Using MQTT to log data

#34318

Ian
Participant

Ok – here is a node red application that gets the station names and number of the master valve from OSPI, then polls the status of the stations. When a station turns on, it sends a message to the MQTT broker, and saves the start time. When a station turns off, it calculates the run time, and posts another message to MQTT. Errors such as failure of the OSPI to respond, or other http errors result in a MQTT message.

The start and stop messages are processed. The start messages go to XBMC and appear on my TV as a notification, The stop messages go to Emoncms to record the run times.

There is still some work to do – tidying up MQTT topics, developing some configuration nodes, and better handling errors. It may also be useful to periodically repoll the station names in case they change.

There are comments in the code, and in comment nodes. Instructions for configuring and running it are in the comment nodes. There is a “debug” environment included so you can start and stop the flows (otherwise the debug messages go too fast!).

This is more of a demonstration. I now intend to develop a plugin (or give input to someone else who will write it!) that will watch OSPI variables and send changes via MQTT, rather than have node-red continuously polling OSPI. Some of this code will then be reused in that new application. I suspect the best way to do this in OSPi is to mirror the web API. ie the  an OSPI/jn topic will mirror the values sent in response to a http://host:port/jn?pw=password request, and so on.

 

Here is the node-red code.

[{“id”:”d7f98065.28068″,”type”:”function”,”name”:”fnBuildurl”,”func”:”// The received message is stored in ‘msg’\n// It will have at  least a ‘payload’ property:\n\n// The ‘context’ object is available to store state\n// between  invocations of the function\n//   context = {};\n\n// The payload of the injected message contains the hostname and port\n// of the OSPI as csv’s\n\n// global context variables are preset in settings.js\n// countresp is updated in fnProcesshttpresp\n// It is used to count the number of times through fnProcesshttpresponse\n// to ensure we have had as many responses as requests \n//Initialise it here\n// The first time through the number of responses will be 0\n\n// context.global.countstart and context.global.countresp are set to 0 in fn Set Global\n\n\n// check to see that the last http request was responded to\n// context.global.countresp is incremented while processing the response\n// so if it is not equal to context.countstart there was no response last time\n// doesn’t apply first time through\nmsgo = msg;\n\n   context.host=msg.payload.split(\”,\”);\n\n\nif (context.global.countstart > 0) {\n\n// As we have sent a request, then the no of responses should equal the number of requests\n\n   if ((context.global.countstart == context.global.countresp)  ) {\n\n//  If it was responded to they will be equal. Send success diagnostic\n\n      msgo.topic   = \”Garden/OSPI/stationrun/api-responses\”;\n      msgo.payload = \”Reached server – fnBuildurl \”  ;\n      msgo.payload = msgo.payload + context.global.countstart.toString() + ‘ ‘ + context.global.countresp.toString();\n   }\n\n\n// First time through there was no previous response to have\n\n   if ((context.global.countstart != context.global.countresp) ) {\n\n      msgo.topic   = \”Garden/OSPI/stationrun/api-response\”;\n      msgo.payload = \”Error reaching server – fnBuildurl \”  ;\n// add some diagnostics\n      msgo.payload = msgo.payload + context.global.countstart.toString() + ‘ ‘ + context.global.countresp.toString();\n      \n// set them equal so next time the check will work\n\n      context.global.countresp = context.global.countstart;\n   }\n}\n//if first time get station names.\nif (context.global.countstart   == 0) {\n\n//   only do this the first time\n\n   msgo.url = ‘http://’ + context.host[0] +’:’ + context.host[1] + ‘/jn?pw=’ + context.host[2];\n// add some diagnostics\n   msgo.payload = msgo.url+ \” Get Station names \”;\n   msgo.payload = msgo.payload + context.global.countstart.toString() + ‘ ‘ + context.global.countresp.toString();\n\n   }\n\n//if second time get master valve number\n\nif (context.global.countstart == 1) {\n   msgo.url = ‘http://’ + context.host[0] +’:’ + context.host[1] + ‘/jo?pw=’ + context.host[2];\n   msgo.payload = msgo.url+ \” Get Master Valve no \”;\n   msgo.payload = msgo.payload + context.global.countstart.toString() + ‘ ‘ + context.global.countresp.toString();\n\n   }\n// All subsequent times just get station status\nif (context.global.countstart > 1) {\n   msgo.url = ‘http://’ + context.host[0] +’:’ + context.host[1] + ‘/js?pw=’ + context.host[2];\n   msgo.payload = msgo.url+ \” Get Status \”;\n   msgo.payload = msgo.payload + context.global.countstart.toString() + ‘ ‘ + context.global.countresp.toString();\n\n}\ncontext.global.countstart = context.global.countstart + 1;\nreturn [msgo];”,”outputs”:”1″,”x”:163.04559326171875,”y”:255.93939971923828,”z”:”c3e73b60.3c18c8″,”wires”:[[“4b28d045.b4d73″,”2c641a61.d39be6”]]}]