Sub Process_Globals
Public Serial1 As Serial
Private jsontext() As Byte = "{ ""id"": ""84F3EBE3621A"", ""name"": ""Kitchen"", ""get_status"": ""0,1,1,1,0,1,1,0"", ""set_status"": ""0,1,1,1,0,1,1,0"", ""get"": { ""index"": 8, ""value"": 1 }, ""set"": { ""index"": 8, ""value"": 2 }}"
Private quotearray() As Byte = """"
Private LastIndex As Int
End Sub
Private Sub AppStart
Serial1.Initialize(115200)
Delay(100)
Dim MaxSize As Int = 20
Dim buffer(MaxSize) As Byte
GetTextValueFromKey(jsontext, "name", 0, buffer, MaxSize)
Log(buffer)
GetTextValueFromKey(jsontext, "get_status", 0, buffer, MaxSize)
Log(buffer)
Log(GetNumberValueFromKey(jsontext, "value", 0))
Log(GetNumberValueFromKey(jsontext, "value", LastIndex)) 'second value
End Sub
' Extracts a string value from JSON by key with robust error handling
' Parameters:
' JSON() - source JSON byte array
' Key() - key to search for
' StartIndex - position to start searching from
' ResultBuffer() - output buffer for the value
' MaxLength - maximum characters to copy
Sub GetTextValueFromKey (JSON() As Byte, Key() As Byte, StartIndex As Int, ResultBuffer() As Byte, MaxLength As UInt)
Dim bc As ByteConverter
Dim qkey() As Byte = JoinBytes(Array(quotearray, Key, quotearray))
Dim i As Int = bc.IndexOf2(JSON, qkey, StartIndex)
If i = -1 Then
bc.ArrayCopy(Array As Byte(), ResultBuffer)
Return
End If
' Find opening quote of the value
Dim i1 As Int = bc.IndexOf2(JSON, quotearray, i + qkey.Length + 1)
' CRITICAL FIX: Validate that the opening quote exists
If i1 = -1 Then
bc.ArrayCopy(Array As Byte(), ResultBuffer)
Return
End If
' Find closing quote of the value
Dim i2 As Int = bc.IndexOf2(JSON, quotearray, i1 + 1)
' CRITICAL FIX: Validate that the closing quote exists
If i2 = -1 Then
bc.ArrayCopy(Array As Byte(), ResultBuffer)
Return
End If
' Extract the value with length limit
bc.ArrayCopy(bc.SubString2(JSON, i1 + 1, Min(i2, i1 + 1 + MaxLength)), ResultBuffer)
LastIndex = i2
End Sub
'=============================================================================
' Extracts a numeric value from a JSON byte array by searching for a specific key
'
' @param json() As Byte - The JSON data as a byte array
' @param Key() As Byte - The key to search for (without quotes)
' @param StartIndex As Int - Starting position to begin the search
' @return Double - The numeric value found, or 0 if not found
'
' The extracted number is stored in the global variable LastIndex for further parsing
'=============================================================================
Sub GetNumberValueFromKey (json() As Byte, Key() As Byte, StartIndex As Int) As Double
' Initialize ByteConverter for byte array operations
Dim bc As ByteConverter
' Create the quoted key by wrapping the key with double quotes
Dim qkey() As Byte = JoinBytes(Array(quotearray, Key, quotearray))
' Find the position of the quoted key in the JSON
Dim i As Int = bc.IndexOf2(json, qkey, StartIndex)
If i = -1 Then
Log("GetNumberValueFromKey: Key not found")
Return 0
End If
' Find the colon that separates the key from its value
Dim colon As Int = bc.IndexOf2(json, ":", i + qkey.Length)
If colon = -1 Then
Log("GetNumberValueFromKey: Colon not found")
Return 0
End If
' Start searching for the number after the colon
Dim pos As Int = colon + 1
' Skip any whitespace characters (space = ASCII 32)
Do While pos < json.Length And json(pos) = 32
pos = pos + 1
Loop
If pos >= json.Length Then
Log("GetNumberValueFromKey: End of JSON reached")
Return 0
End If
'======================================================================
' ENHANCED NUMBER PARSING
' Supports: integers, decimals, negative numbers, and scientific notation
'======================================================================
Dim numStart As Int = pos
Dim numEnd As Int = pos
' Allowed characters in a number: digits, period, minus, plus, e, E
Dim IsItNumber As Boolean = False
' Scan through the JSON to extract the complete number
Do While numEnd < json.Length
Dim ch As Byte = json(numEnd)
' Check if the character is part of a valid number
If (ch >= 48 And ch <= 57) Or _ ' 0-9 digits
ch = 46 Or _ ' . decimal point
ch = 45 Or _ ' - minus sign
ch = 43 Or _ ' + plus sign
ch = 101 Or ch = 69 Then ' e or E for scientific notation
IsItNumber = True
numEnd = numEnd + 1
Else
' Reached a delimiter (comma, brace, bracket, etc.) - stop parsing
Exit
End If
Loop
' CRITICAL FIX: Validate that a delimiter was found
If Not(IsItNumber) Or numEnd = numStart Then
Log("GetNumberValueFromKey: No number found")
LastIndex = numEnd
Return 0
End If
' Extract the number bytes and convert to string
Dim numBytes() As Byte = bc.SubString2(json, numStart, numEnd)
Dim numStr As String = bc.StringFromBytes(numBytes)
Log("GetNumberValueFromKey: Extracted number: '", numStr, "'")
' Convert string to Double (B4R will handle invalid conversion gracefully)
Dim value As Double = numStr
' Update the global LastIndex to continue parsing from after this number
LastIndex = numEnd + 1
Return value
End Sub