Sub Process_Globals
Private Const SHELLY As String = "192.168.5.188:80"
Private username As String = "admin"
Private password As String = "password"
Private realm As String = "shellyplus2pm-f008d1d8b8b8"
End Sub
Sub AppStart (Args() As String)
Dim data As Map = CreateMap("id": 1, "method": "Shelly.GetStatus")
ShellyHttpCall("Post", $"http://${SHELLY}/rpc"$, data.As(JSON).ToCompactString)
StartMessageLoop
End Sub
Sub ShellyHttpCall (HttpMethod As String, Link As String, JsonData As String)
Private AuthParams As Map
AuthParams.Initialize
Dim job As HttpJob
job.Initialize("", Me)
If HttpMethod.ToUpperCase = "POST" Then
job.PostString(Link, JsonData)
job.GetRequest.SetContentType("application/json")
Else If HttpMethod.ToUpperCase = "GET" Then
job.Download(Link)
Else
Log($"[${HttpMethod.ToUpperCase}] Is this supported?"$)
Return
End If
Wait For (job) JobDone(job As HttpJob)
If job.Success Then
Log(job.GetString)
Else
Log(job.ErrorMessage)
If job.Response.StatusCode = 401 Then
Dim headers As List
headers = job.response.GetHeaders.Get("WWW-Authenticate")
For Each header In headers
Log(header)
Dim keyvalue() As String
keyvalue = Regex.Split("=", header)
If keyvalue.Length = 2 Then
AuthParams.Put(keyvalue(0), keyvalue(1))
End If
Next
ShellyHttpCall(HttpMethod, Link, GetAuthData(AuthParams, JsonData))
End If
End If
job.Release
End Sub
Sub GetAuthData (AuthParams As Map, JsonString As String) As String
Dim algorithm As String = "SHA-256"
Dim ha1 As String = SHA256($"${username}:${realm}:${password}"$)
Dim ha2 As String = SHA256("dummy_method:dummy_uri")
Dim nonce As Int = AuthParams.Get("nonce")
Dim cnonce As Int = Rnd(100000000, 999999999)
Dim nc As Int = 1
Dim response As String = SHA256($"${ha1}:${nonce}:${nc}:${cnonce}:auth:${ha2}"$)
Dim authMap As Map
authMap.Initialize
authMap.Put("realm", realm)
authMap.Put("username", username)
authMap.Put("nonce", nonce)
authMap.Put("cnonce", cnonce)
authMap.Put("response", response)
authMap.Put("algorithm", algorithm)
Dim JsonMap As Map = JsonString.As(JSON).ToMap
JsonMap.Put("auth", authMap.As(JSON).ToCompactString)
Return JsonMap.As(JSON).ToCompactString
End Sub
' Return SHA-256 in hexadecimal
Public Sub SHA256 (str As String) As String
Dim data() As Byte
Dim MD As MessageDigest
Dim BC As ByteConverter
data = BC.StringToBytes(str, "UTF8")
data = MD.GetMessageDigest(data, "SHA-256")
Return BC.HexFromBytes(data).ToLowerCase
End Sub