PowerShell and MQTT

A small blog entry how to use MQTT in Powershell, as a library I use M2MQTT.

M2MQTT installing

Download the M2Mqtt library manually, or by nuget.exe. The nuget.exe can be downlaoded here.

nuget.exe install M2Mqtt -o c:\lib

In Powershell the DLL can then be included via Add-Type -Path "C:\lib\M2Mqtt.4.3.0.0\lib\net45\M2Mqtt.Net.dll" so that the contained classes can be used.

Usage of M2MQTT

Connection setup

$MqttClient = [uPLibrary.Networking.M2Mqtt.MqttClient]("broker.hivemq.com")

# Connect
$mqttclient.Connect([guid]::NewGuid())

# Connect with username and password
$mqttclient.Connect([guid]::NewGuid(), "username","password")

# Connect and set LastWill
# Parameters: string clientid, username, password, willRetain [0/1], willQosLevel [0/1/2], willFlag [0/1], willTopic, willMessage, cleanSession [0/1], keepAlivePeriod) 
$mqttclient.Connect([guid]::NewGuid(), $null, $null, 0, 0, 1, "M2MQTT_Test/LW", "error", 1, 60 )

Publish message

# Publish
$MqttClient.Publish("M2MQTT_Test/message", [System.Text.Encoding]::UTF8.GetBytes("Hello World"))

# Publish with QoS 0 and Retain
$MqttClient.Publish("M2MQTT_Test/message", [System.Text.Encoding]::UTF8.GetBytes("Hello World"), 0, 1)

Subscribe topic

Since the Subscripe is an asynchronous process, there is an Event Handler class to not interrupt the script execution until a message is recived.

# Register EventHandler
Register-ObjectEvent -inputObject $MqttClient -EventName MqttMsgPublishReceived -Action { `
        Write-Host "Topic: "$args[1].topic; `
        Write-Host "Message: "([System.Text.Encoding]::ASCII.GetString($args[1].Message)) }

# Subscribe QoS 0
$MqttClient.Subscribe("M2MQTT_Test/message",0)

Disconnet

Disconnect the connection cleanly so that the LastWill is not executed.

$MqttClient.Disconnect()

Example Script

Add-Type -Path "C:\lib\M2Mqtt.4.3.0.0\lib\net45\M2Mqtt.Net.dll" 

function global:MQTTMsgReceived
{
    Param(
        [parameter(Mandatory=$true)]$mqtt
    )
    $topic = $mqtt.topic
    $msg = $([System.Text.Encoding]::ASCII.GetString($mqtt.Message))
    Write-Host ("Topic: " + $topic)
    Write-Host ("Message: " + $msg)
}

# Connect to broker.hivemq.com
$MqttClient = [uPLibrary.Networking.M2Mqtt.MqttClient]("broker.hivemq.com")
$mqttclient.Connect([guid]::NewGuid(), $null, $null, 0, 0, 1, "M2MQTTPSTest/statusLW", "error", 1, 30 )

# Publish message
$MqttClient.Publish("M2MQTTPSTest/status", [System.Text.Encoding]::UTF8.GetBytes("online"), 0, 0)

Register-ObjectEvent `
    -inputObject $MqttClient `
    -EventName MqttMsgPublishReceived `
    -Action { MQTTMsgReceived $($args[1]) }


# Subscribe QoS 0
$MqttClient.Subscribe("M2MQTTPSTest/message",0)

# Publish second message message (trigger our Subscribe)
$MqttClient.Publish("M2MQTTPSTest/message", [System.Text.Encoding]::UTF8.GetBytes("Hello World"), 0, 0)


for ($i=0; $i -lt 5; $i++)
{
    Start-Sleep 1
}

# Publish message
$MqttClient.Publish("M2MQTTPSTest/status", [System.Text.Encoding]::UTF8.GetBytes("offline"), 0, 0)

# Disconnect
$MqttClient.Disconnect()