Examples (17)


Visualizing Mqtt JSON Payload 1

This post describes how to visualize Mqtt data when the Mqtt payload is JSON. I updated this post on 26th May 2019 for version 2.2. The example in this post will not work for versions prior to 2.2!

How is MqttCogs data stored?

Recall that data arriving from the Mqtt broker is persisted to a WordPress table. The data from my MySensors projects looks something like this. You can see that my data is pretty simple – numeric temperature and moisture levels.

By default, when I visualize this data I see a graph that plots utc against payload. Here is the graph that plucks out temperature data for probe 95. I’ve removed all the axes formatting to make the shortcode more readable. (Underneath the surface Mqttcogs returns a datetime and a number/string for each row of data for the Google Visualization)

[ mqttcogs_drawgoogle options="{height:300}" ajax="true" ] 
	[ mqttcogs_data from="-3" limit="99999" topics="mysensors_out/95/1/1/0/0"] 
[ /mqttcogs_drawgoogle ]

So now lets examine some data that has arrived from the Mqtt broker with a JSON payload. I’ve manually added a couple of rows. As you can see they contain latitude and longitude – can you see where this is going?

To extract and plot the values from my json payload I need to instruct MqttCogs how these should be extracted from the JSON data. Prior to version 2.2 this was done server-side. This wasn’t very flexible and only worked with very simple ‘flat’ JSON.

Version 2.2 provides the ability to manipulate the JSON in the client browser using a script. In this simple example we don’t even need to do this!

The default JSON script that is bundled with version 2.2 looks for a longitude and latitude in the JSON data (it’ll scan for lon, longitude, lng and lat, latitude) and uses that to plot the data. It also constructs a simple flag using the the topic name and datetime.

[ mqttcogs_drawgoogle charttype="Map" options="{height:300}"  ]
  [ mqttcogs_data 
	limit="99999" 
	topics="jsontest/a" ] 
[ /mqttcogs_drawgoogle ]

This great! I can now plot lat, lng on a google map. I could even get the map to update if something was moving!

The above is a really simple example introducing JSON payloads. Take a look at Part 2. This shows how we can use the ‘script’ attribute to properly manipulate the JSON data before we use it in our visualization.




Just get me the last value!

There are instances where a graph might not be appropriate. I might simply want to display the current temperature outside. I don’t want any fancy formatting I simply want to embed the value in one of my posts. Which value though? The temperature is only meaningful if you know the date and time at which the reading was taken.

Last known temperature reading is 17.5C  taken at 2019-09-20 15:07:55

It is possible to display both using the [ mqttcogs_get ] shortcode. In it’s most basic form it will return the most recent datetime or payload field. Here’s the code to display the text above:

Last known temperature reading is [ mqttcogs_get topic='mysensors_out/99/2/1/0/0' field='payload']C  
taken at [ mqttcogs_get topic='mysensors_out/99/2/1/0/0' field='datetime' dateformat='Y-m-d H:i:s' local='false']

What about other days?

It’s also possible to specify a ‘from’ and ‘to’ attribute and a sort attribute. This would allow you to get the start and end temperature for a given date range. I’m not sure why you might want to do this!




Publish Data Using An MqttCogs Shortcode

Not only can you visualize data using Mqttcogs but it is also possible to publish data to your Mqtt broker using the [mqttcogs_set] shortcode. The ability to publish data is useful, here are a couple of reasons I wanted to do this.

Number 1: I can publish data directly to my blog without having to use a generic Mqtt client.

Number 2: In the IOT (internet of things) world iot devices can be controlled by publishing appropriate messages. For example, you might be able to control your outside lights by publishing to a topic such as myhouse\lights\outside.

Remember though – you can’t have just ANYONE publishing to your broker!!

Lets start with a basic example

If you want to see the results on the page you need to subscribe to this blog and make sure you are logged in. You need to have a role of ‘subscriber’ to have the ability to publish on this page. If you aren’t logged in, you’ll see the code & graph only.

I decided to open this up. If there is a lot of ‘spam-a-lot’ then I’ll put the restriction back in. I’ve added the strikethrough to the shortcode attributes below so that you can see what I removed.

Here is the code for the graph and underneath the shortcode for publishing to the tests/blog/publishingdata topic. The results are shown underneath.

[ mqttcogs_drawgoogle options="{width:'100%'}" ]
       [ mqttcogs_data topics="tests/blog/publishingdata" ]
[ /mqttcogs_drawgoogle]

[ mqttcogs_set topic='tests/blog/publishingdata'
     minrole='Subscriber' 
     label_text='Enter a new value here:' ] 

I have used the [ mqttcogs_set ] shortcode. You’ll notice that the field is automatically populated with the last value stored in the database. I’ve used the minimum number of attributes in the shortcode that I could get away with.

topic – the fixed topic to send the new messages to
minrole – the minimum wordpress role that is required for the fields to be displayed
label_text – the label shown above the field

….but you’ll notice a problem! There is no field validation. I could enter anything into the field and it will published!!

You’ll also notice that adding a new value doesn’t automatically update the graph. The graph refresh is independent of the ‘add’. There is no link between the add and the visualization. You will need to wait until the next ‘refresh’ time for the graph to update.

Lets add some validation!

Validation is applied in the browser by using HTML5 validation. There are a number of attributes starting ‘input_’. Each is mapped directly to a HTML5 attribute on the input element. You can even change the input type to ‘range’ or ‘number’ but more about this later.

Ok, so we’ll update the attributes in the shortcode to make the field accept numeric integer values only between 0 and 50.

[ mqttcogs_set  
	topic='tests/blog/publishingdata'
	minrole='Subscriber' 
	label_text='Enter a new value here:'  
	input_type='number' 
	input_min='0' 
	input_max='50' 
	input_title='Please enter a whole number between 0 and 50' ]

We’ve now restricted the field to accept values between 0 and 50. It’ll also notify the user if the input is invalid. Our numerical entry now looks like this:

Validation to 2 decimal places

I might decide that actually I want to allow decimals, say to 2 decimal places. I could achieve this using the HTML5 step attibute:

[ mqttcogs_set  
	topic='tests/blog/publishingdata'
	minrole='Subscriber'
	label_text='Enter a new value here:'
	input_type='number' 
	input_min='0'
	input_max='50'
	input_step='0.01'
	input_title='Please enter a number between 0 and 50 to 2dp maximum' ]

You can even do sliders

You can do this by setting the input_type to ‘range’. What is rendered will depend on your browser. The result isn’t particularly pretty in firefox. There is no feedback showing what the current slider value actually is.

A full list of supported HTML5 shortcode attributes are documented here

Ok, so this isn’t very pretty?

Being pretty has never been my strongpoint. There is also a ‘class’ shortcode attribute. So we can tidy things up by specifying a class to apply

[ mqttcogs_set  
	topic='tests/blog/publishingdata'
	text='Add'
	label_text='Enter a new value here:'
	minrole='Subscriber'
	input_type='number'
	input_min='0'
	input_max='50'
	input_title='Please enter a number between 0 and 50' 
	class='mqttcogs_set' ]

My css looks something like this. I added this under the Appearance…Custom CSS option in the wordpress menu.

.mqttcogs_set label {
	display:block;
} 
.mqttcogs_set input {
	display:inline-block;
	margin-right:5px; 
} 

.mqttcogs_set input[type="text"] { 
	margin-bottom: 10px;   width:66%; 
}

….the result now looks like this. A little better!




My Basil

This page is entirely devoted to my Basil plant.  The plant sits on my kitchen windowsill and is south facing. I love my Basil plant. I use it for Pizza and Tomato sauces. It has very green leaves and smells fantastic. It’s not growing very fast at the moment as it’s winter and we are only getting about 8 hours of light.

[ mqttcogs_drawgoogle 
	options="{
				series: {1:{labelInLegend: 'Air'},0:{labelInLegend: 'Soil'}},
				animation:{startup:true,duration:5},
				curveType:'function',
				title:'(92) My Kitchen Basil Temperature',
				height:300,
				hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
				vAxis: { title: 'Temp (C)' }}"]

	[ mqttcogs_data limit="9999" topics="mysensors_out/92/1/1/0/0,mysensors_out/92/2/1/0/0"]
[/mqttcogs_drawgoogle]

Here’s another graph that shows moisture. The moisture is measured by a capacitive sensor. The units are arbitrary. This is work in progress!

[ mqttcogs_drawgoogle 
	options="{   
			series: {1:{labelInLegend: 'Air'},0:{labelInLegend: 'Soil'}},
			animation:{startup:true,duration:5},
			curveType:'function',
			title:'(100) My Kitchen Basil Moisture',
			height:300,
			hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
			vAxis: { title: 'Moisture' }}"]
	[ mqttcogs_data limit="100" topics="mysensors_out/92/0/1/0/37"]
[/mqttcogs_drawgoogle]



Multiple Series

The Really Simple example showed how to create simple LineChart and show one series. It’s possible to show multiple series on the same graph. In this example I’m going to show the air temperature and soil temperature for my basil plant that sits on my kitchen window sill. This example shows how to use the topics attribute.

Lets recap. We’ve got a graph on the screen using the following code:

[ mqttcogs_drawgoogle ]
       [ mqttcogs_data topics="mysensors_out/100/1/1/0/0" ]
[ /mqttcogs_drawgoogle ]

Adding another series to the same graph is pretty easy. The topics attribute accepts a comma delimited list of topics. So I can simply change my shortcode to include the second temperature sensor that I have on this probe:

[ mqttcogs_drawgoogle ]
       [ mqttcogs_data topics="mysensors_out/100/1/1/0/0,mysensors_out/100/2/1/0/0" ]
[ /mqttcogs_drawgoogle ]

The output looks like this:

Obviously, we can tidy things up a bit by setting the options attribute as well as described in Labelling Axes. Our shortcode then becomes:

[ mqttcogs_drawgoogle 
	options="{
			series:{0:{labelInLegend: 'Soil'},1:{labelInLegend: 'Air'}},
			curveType:'function',
			title:'(100) My Kitchen Basil Temperature',
			height:300,
			hAxis: {title: 'DateTime(UTC)',format:'dd MMM HH:mm' },
			vAxis: { title: 'Temp (C)' }}" ]
    [ mqttcogs_data limit="100" topics="mysensors_out/100/1/1/0/0,mysensors_out/100/2/1/0/0" ]
[/mqttcogs_drawgoogle ]

The pretty excellent result looks like this:




Labelling Axes

The Really Simple example showed how to create simple LineChart using a tiny amount of code. The graph showed some data but was missing horizontal and vertical axes. It was also missing a title. This example shows how to use the options attribute to make your graph look a bit more presentable.

Lets recap. We’ve got a graph on the screen using the following code:

[ mqttcogs_drawgoogle ]
       [ mqttcogs_data topics="mysensors_out/100/1/1/0/0" ]
[ /mqttcogs_drawgoogle ]

We are going to extend this and add a legend and axis labels to our graph. Here is the example updated to include some labelling

[ mqttcogs_drawgoogle options="{  series: {0:{labelInLegend: 'Soil'}},  curveType:'function',  title:'(100) My Kitchen Basil Temperature',  height:300,  hAxis: { title: 'DateTime(UTC)',format:'dd MMM HH:mm' },  vAxis: { title: 'Temp (C)' }}" ]
              [ mqttcogs_data limit="100" topics="mysensors_out/100/1/1/0/0" ] 
[/mqttcogs_drawgoogle ]

There aren’t any secrets here, the options attribute is a javascript object literal that is passed into the Google Visualization graph constructor. Here is a link to show the options attribute explained for the Google LineChart. The result is:

Notes:

  • I haven’t specified a width as the chart will automatically grow to fit the container.
  • I’ve changed the curveType to ‘function’ to smooth out the graph



Really Simple

This example shows how to create simple LineChart using the smallest amount of code. Lets start by taking a look at the shortcode. As with all the examples, I’ve added a space after/before any square brackets to make sure that the shortcode is not processed. You need to remove this if you are copying this code!

[ mqttcogs_drawgoogle charttype="LineChart" options="{}" ] 
      [ mqttcogs_data topics="mysensors_out/100/1/1/0/0" ]
[ /mqttcogs_drawgoogle ]

There are two shortcodes you need to use. The outer shortcode mqttcogs_drawgoogle  to tell the plugin that you want to draw a graph and the inner shortcode mqtt_data to tell the plugin what data you want to use.

As you can see from the example, the only required at attribute you need to draw a graph is the topic you want to use as your series. Any attribute that is not specified is set to it’s default value.

The topic that I want to graph is mysensors_out/100/1/1/0/0. This is the standard MySensors format for sensor id 100’s temperature. You don’t have to use MySensors you can graph any MQTT data stream!

The output of this looks like this: