To complete this workshop you will need:

Languages used:

This workshop will show you how to:

UnityWebGL and Beebotte MQTT

Sign in on Beebotte;

new channel

In the new screen Create a new channel:

new channel

From the menu choose the tab Account Settings, select the tab Access Management and then Create new Token.

In Create an IAM Token:

API and tokens

From the menu choose the tab Dashboards and select Create Dashboard:

Dashboard

In this workshop, the data stream that will be published to the Beebotte channel is the CPU temperature's value of the RaspberryPi.

pip install beebotte
import os
import time
from beebotte import *
###Replace iamtkn_TOKEN_CONTENT with the token created in your Beebotte account
bbt=BBT(token='iamtkn_TOKEN_CONTENT')
## Resource(bbt,'CHANNEL','TOPIC')
temperature_resource=Resource(bbt,'MY_CHANNEL','MY_RESOURCE_TOPIC')
def measure_temp():
	temp=os.popen("vcgencmd measure_temp").readline()
	temp_string=temp.replace("temp=","").replace("'C","")
	print temp_string
	return temp_string
while True:
	try:
		temperature_resource.write(measure_temp())
		time.sleep(5)
	except KeyboardInterrupt:
		break

While the script is running, the Beebotte Dashboard will display the current temperature of the RaspberryPi.

Create an empty HTML file index.html in VSCode. The JavaScript client uses Beebotte and Socket.IO libraries (more information on the Beebotte GitHub repository).

The unique API Key can be found on the Beebotte platform, from the menu choose the tab Account Settings and select the tab Access Management.

API and tokens

Change also the channel and the resource to match the ones created on the Beebotte platform.

<!DOCTYPE html>
<html lang="en" dir="ltr">
  <head>
    <title>Test Beebotte Broker</title>
    <script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js" type="text/Javascript"></script>

<!--Beebotte js library can be downloaded from https://github.com/beebotte/bbt_client_js-->
    <script src="js/bbt.min.js"></script>
  </head>

  <body>
    <p>Test Beebotte MQTT Cloud Platform. See console logs for more information...</p>

<script type="text/Javascript">
    console.log('Setup...');
    var API_KEY='YOUR_BEEBOTTE_API_KEY'; //be aware of what data you are sharing and publishing https://www.freecodecamp.org/news/how-to-securely-store-api-keys-4ff3ea19ebda/
    
    var bbt = new BBT(API_KEY, {server: 'beebotte.com'});
    console.log('Connecting...');
    
    bbt.connect();

    bbt.subscribe({channel: 'MY_CHANNEL', resource: 'MY_RESOURCE_OR_TOPIC', read: true, write: true}, function(msg)
    {
      console.log(msg);
      console.log(msg.data); //to display just the data stream
    });
</script>
</body>
</html>

Unity3D cannot directly execute JavaScript files, however, it is possible to use an external JavaScript library in Unity through the plugin interface. The plugin is used to bridge the external JavaScript library with Unity MonoBehaviour, using regular C# scripts.

Create a new Unity project and in File -> Build Settings switch platform to WebGL

new Unity Project

var bbmqttplugin={

  $DataBB: 
        {
          //Settings
          server:"beebotte.com",
          channel:"MY_CHANNEL",
          resource:"MY_RESOURCE_TOPIC",
          API_KEY:"MY_API_KEY",

        //Variables
          bbt:"",
          out_msg:"0",
        },
}
autoAddDeps(bbmqttplugin, '$DataBB');
mergeInto(LibraryManager.library, bbmqttplugin);

The function MQTTconnectBB is used:

var bbmqttplugin={

  $DataBB: 
        {
          //Settings
          server:"beebotte.com",
          channel:"MY_CHANNEL",
          resource:"MY_RESOURCE_TOPIC",
          API_KEY:"MY_API_KEY",

        //Variables
          bbt:"",
          out_msg:"0",
        },
MQTTconnectBB: function ()
      {
      console.log("Connecting to BeeBotte");
      DataBB.bbt=new BBT(DataBB.API_KEY, {server: DataBB.server});

      DataBB.bbt.subscribe({channel: DataBB.channel, resource: DataBB.resource, read: true, write: false}, function(msg) 
      {
            console.log(msg.data);
            DataBB.out_msg=msg.data;
      }
      );
      },

}
autoAddDeps(bbmqttplugin, '$DataBB');
mergeInto(LibraryManager.library, bbmqttplugin);

Final step is to expose the data stream to Unity. While numerical data can be expose directly to Unity, any other data type, in this case string, need to be converted (more information on Unity Manual interact with browser scripting). The function responseBB takes care of this conversion:

var bbmqttplugin={
      $DataBB: 
        {
          //Settings
          server:"beebotte.com",
          channel:"MY_CHANNEL",
          resource:"MY_RESOURCE_TOPIC",
          API_KEY:"MY_API_KEY",

        //Variables
          bbt:"",
          out_msg:"0",
        },
 
 MQTTconnectBB: function ()
      {
      console.log("Connecting to BeeBotte");

      DataBB.bbt=new BBT(DataBB.API_KEY, {server: DataBB.server});

      DataBB.bbt.subscribe({channel: DataBB.channel, resource: DataBB.resource, read: true, write: false}, function(msg) 
      {
            console.log(msg.data);
            DataBB.out_msg=msg.data;
      }
      );
      },
responseBB: function()
{
    var bufferSize = lengthBytesUTF8(DataBB.out_msg) + 1;
    var buffer = _malloc(bufferSize);
    stringToUTF8(DataBB.out_msg, buffer, bufferSize);
    return buffer;
},
}
autoAddDeps(bbmqttplugin, '$DataBB');
mergeInto(LibraryManager.library, bbmqttplugin);
using System.Collections;
using System.Collections.Generic;
using UnityEngine;
using System.Runtime.InteropServices;

public class mqttBB_Response : MonoBehaviour
{
    [DllImport("__Internal")] private static extern void  MQTTconnectBB();
    [DllImport("__Internal")] private static extern string  responseBB(); //Attention to the data type: jslib returns a string

    public string response_mqtt; //the response string from the mqttBBpluginUnity.jslib exposed by responseBB();

    void Start()
    {
        response_mqtt=" ";
        StartCoroutine(incomingMsg());
    }

    IEnumerator incomingMsg ()
    {
        MQTTconnectBB();
            while(true)
            {
            response_mqtt=responseBB();
               Debug.Log(response_mqtt); 
               yield return null;
            }           
    }
}

A simple way to visualise the MQTT data stream is to create a Text mesh object in Unity and update the field text every time a new MQTT message is retrieved.

Unity Text Mesh

using System.Collections;
using System.Collections.Generic;
using UnityEngine;

public class mqttBB_Viz : MonoBehaviour
{
     public GameObject GO_textMQTT;
     public mqttBB_Response responseThis;
     public string value;

    void Update()
    {
        value = responseThis.response_mqtt;
        GO_textMQTT.GetComponent<TextMesh>().text=value;
    }
}

Unity Text Mesh

Build the scene

Final step is to add, to the index.html created by Unity, the Beebotte JavaScript library called by the JavaScript plugin. The library can be downloaded from https://github.com/beebotte/bbt_client_js.

      <script src="js/bbt.min.js" type="text/javascript"></script>
<script src="https://cdnjs.cloudflare.com/ajax/libs/socket.io/2.3.0/socket.io.js" type="text/javascript"></script>

The index.html will run the Unity WebGL application that displays, and update in real time, the value of the RaspberryPi temperature:

UnityWebGL and Beebotte MQTT