Jump to content

Send Json to an MQTT Broker - Escape character nightmare


Steven_H
 Share

Recommended Posts

I am trying to read data from a Win32 embroidery program and send the data when it changes to an MQTT Broker. The reading the data works great after some help in another post on the forum. I've attached a screenshot of the embroider program just for context but that part is working fine.

Below is my current code, everything works except the part where I try to use mosquitto_pub to send the Json, I end up in a complicated mess trying to escape quotes and after reading the documentation multiple times and trying variations of double quotes and single quotes I'm no further forward.

 

#include <FileConstants.au3>
#include <StringConstants.au3>
#include 'JSONgen.au3'

;~ Set a hotkey Escape to exit the script
HotKeySet("{ESC}", "_ExitScript")

; Set Global Variables - Change these to match your values
Global $sMqttPub = "C:\Program Files\Mosquitto\mosquitto_pub.exe"
Global $sHost = "192.168.0.81"
Global $sTopic = "home/amaya"

Run("AMAYA.exe")

getStats()

Func getStats()
    Local $sCstitch = "", $sOld = ""
    While 1
        If WinExists("AMAYA OS Lite") Then
            ; Read Data from Amaya OS
            Local $sData = WinGetText("AMAYA OS Lite")
            ; Split into an Array
            Local $aArray = StringSplit($sData, @CRLF)
            ; Copy Array values into variables (easier to understand what they are)
            Local $sJob = $aArray[12]
            Local $sJpct = $aArray[19]
            Local $sCstitch = $aArray[39]
            Local $sActifeed = $aArray[48]
            Local $sCspm = $aArray[17]
            Local $sTremain = $aArray[46]
            Local $sTstitch = $aArray[41]
            Local $sHoop = $aArray[45]

            ; Check if stitch count has increased, if not start loop again, else write to console and publish to MQTT
            If ($sCstitch == $sOld) Then
                Sleep(50)
                ContinueLoop
            Else

               ; Write to Console
               ConsoleWrite("Job Name = " & $sJob & @CRLF)
               ConsoleWrite("Current Spm = " & $sCspm & @CRLF)
               ConsoleWrite("Job % = " & $sJpct & @CRLF)
               ConsoleWrite("Stitch  = " & $sCstitch & @CRLF)
               ConsoleWrite("Total Stitch = " & $sTstitch & @CRLF)
               ConsoleWrite("Hoop = " & $sHoop & @CRLF)
               ConsoleWrite("Time Remaining = " & $sTremain & @CRLF)
               ConsoleWrite("Acti-feed = " & $sActifeed & @CRLF)

               $oJson = New_Json()

               Json_AddElement($oJson,  "cJob", $sJob)
               Json_AddElement($oJson,  "actifeed", $sActifeed)
               Json_AddElement($oJson,  "cStitch", $sCstitch)

               $TheJson = Json_GetJson($oJson)
               $sMQTT = "'" & $sMqttPub & " -h " & $sHost & " -t " & $sTopic & " -m " & "'" & $TheJson & "'"
               ConsoleWrite($sMQTT & @CRLF)

               ; Send to MQTT Broker
                run($sMQTT, '', @SW_HIDE)

                ; Set $sOld to current stitch count before loop starts again
                $sOld = $sCstitch
            EndIf
        EndIf
        Sleep (50)
    WEnd
EndFunc

; Exit the script
Func _ExitScript()
    Exit
EndFunc

 

This part 

run($sMQTT, '', @SW_HIDE)

basically should convert to this, but it's wrong and I know I'm not sending the path correctly and the quotes in the Json are not appearing even when writing to the console or using the command line manually to send the the same command:

run('C:\Program Files\Mosquitto\mosquitto_pub.exe -h 192.168.0.81 -t home/amaya -m '{"cJob":"_ABC Test.ofm","actifeed":"1","cStitch":"0"}', '',  @SW_HIDE)

 

I have basically got in a muddle trying to work out escaping quotes. Originally I just tried to build the Json from my variables and send that, but then thought building the Json first would help.

 

Hope someone can offer some pointers, thanks.

OS Lite Screen 2.PNG

Link to comment
Share on other sites

No way to test, but this should work:

; Set Global Variables - Change these to match your values
Global $sMqttPub = "C:\Program Files\Mosquitto\mosquitto_pub.exe"
Global $sHost = "192.168.0.81"
Global $sTopic = "home/amaya"

Local $sJob = "_ABC Test.ofm"
Local $sCstitch = "0"
Local $sActifeed = "1"

; Write to Console
ConsoleWrite("Job Name = " & $sJob & @CRLF)
ConsoleWrite("Stitch  = " & $sCstitch & @CRLF)
ConsoleWrite("Acti-feed = " & $sActifeed & @CRLF)

Local $TheJson = '{"cJob":"_ABC Test.ofm","actifeed":"1","cStitch":"0"}'

$sMQTT = '"' & $sMqttPub & '" -h ' & $sHost & " -t " & $sTopic & " -m " & "'" & $TheJson & "'"
ConsoleWrite($sMQTT & @CRLF)

; Send to MQTT Broker
;~                 run($sMQTT, '', @SW_HIDE)

 

This wonderful site allows debugging and testing regular expressions (many flavors available). An absolute must have in your bookmarks.
Another excellent RegExp tutorial. Don't forget downloading your copy of up-to-date pcretest.exe and pcregrep.exe here
RegExp tutorial: enough to get started
PCRE v8.33 regexp documentation latest available release and currently implemented in AutoIt beta.

SQLitespeed is another feature-rich premier SQLite manager (includes import/export). Well worth a try.
SQLite Expert (freeware Personal Edition or payware Pro version) is a very useful SQLite database manager.
An excellent eBook covering almost every aspect of SQLite3: a must-read for anyone doing serious work.
SQL tutorial (covers "generic" SQL, but most of it applies to SQLite as well)
A work-in-progress SQLite3 tutorial. Don't miss other LxyzTHW pages!
SQLite official website with full documentation (may be newer than the SQLite library that comes standard with AutoIt)

Link to comment
Share on other sites

Using StringFormat can be cleaner when there are a lot of concatenations involved.

$sMQTT = StringFormat('"%s" -h %s -t %s -m ' & "'%s'", $sMqttPub, $sHost, $sTopic, $TheJson)

P.S If you are casually browsing (like me) and don't know what's this about, it's related to home automation, it's certainly not related to stock trading as I had initially expected.

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Thanks both @jchd and @TheDcoder those work better than I had. However, it turns out the mosquitto_pub requires the quotes to be escapesdin the Jsonn

What I actually have to submit via the command line is this

"C:\Program Files\Mosquitto\mosquitto_pub.exe -h 192.168.0.81 -t home/amaya -m "{\"cJob\":\"_ABC Test.ofm\",\"actifeed\":\"3\",\"cStitch\":\"0\"}"

 

If I don't escape it what is sent is this, which isn't valid Json

{cJob:_ABC Test.ofm,actifeed:3,cStitch:0}

I created valid Json originally, but I think that has made it more complicated. Is there an easy way to insert a backslash before each quote in the Json or would it be better to ditch building Json and try to build what I need to send by using StringFormat()

 

Thanks again for the help

Link to comment
Share on other sites

4 minutes ago, Steven_H said:

Is there an easy way to insert a backslash before each quote

Have a look at the StringReplace function :)

EasyCodeIt - A cross-platform AutoIt implementation - Fund the development! (GitHub will double your donations for a limited time)

DcodingTheWeb Forum - Follow for updates and Join for discussion

Link to comment
Share on other sites

Create an account or sign in to comment

You need to be a member in order to leave a comment

Create an account

Sign up for a new account in our community. It's easy!

Register a new account

Sign in

Already have an account? Sign in here.

Sign In Now
 Share

  • Recently Browsing   0 members

    • No registered users viewing this page.
×
×
  • Create New...