Parsing Vera User Data - Loadable as .NET Dataset
From MiOS
This is most likely not an elegant way to dothis, but in case someone wants something similar feel free to use this. Please suggest if there are better ways of accomplishing this and if you happen to know so, update this page :)
1. This will give you a single xml file you could load in .NET through Dataset.Readxml and you will get about 14 tables.
2. Devices have states and ControlURLs , these become a separate table with a new attribute added to refer what Device ID a row in these tables would relate to the devices table.
Private Sub Parse_UserData_To_DataSet(ByVal OutputFolder As String, _
Optional ByVal veraURL As String = "http://myhome:49451")
Dim Entries As New ArrayList
Dim ds As New DataSet
Dim userDatajson As String = GetWebPageContent(veraURL & "/data_request?output_format=json&id=user_data")
Dim userData As String = GetWebPageContent(veraURL & "/data_request?output_format=xml&id=user_data")
'Create Root Data file
Dim si As Integer = userData.IndexOf("<root")
Dim ei As Integer = userData.IndexOf(">", si)
Dim rootstr As String = userData.Substring(si, ei - si + 1)
rootstr = rootstr.Replace(vbLf, "") & "</root>"
Dim fo As New IO.StreamWriter(OutputFolder & "\root.xml")
fo.WriteLine(rootstr)
fo.Close()
Entries.Add("root")
'create rest of it!
Dim jo As New JSONObject(userDatajson)
For Each s As KeyValuePair(Of String, String) In jo._properties
si = userData.IndexOf("<" & s.Key & ">")
ei = userData.IndexOf("</" & s.Key & ">")
If si >= 0 AndAlso ei > 0 Then
Dim thisEntry As String = userData.Substring(si, ei - si + ("</" & s.Key & ">").Length)
Dim fname As String = OutputFolder & "\" & s.Key & ".xml"
Dim fo1 As New IO.StreamWriter(fname)
fo1.WriteLine(thisEntry)
fo1.Close()
Entries.Add(s.Key)
End If
Next
'Put all the tables in a single dataset
Dim finalDS As New DataSet
For Each s As String In Entries
Dim fname As String = OutputFolder & "\" & s & ".xml"
ds = New DataSet
ds.ReadXml(fname)
Try
ds.Tables(0).TableName = s
finalDS.Tables.Add(ds.Tables(0).Copy)
finalDS.Tables(finalDS.Tables.Count - 1).TableName = s
Catch ex As Exception
End Try
Next
'devices have controlURL & states
DeviceParse(OutputFolder)
ds = New DataSet
ds.ReadXml(OutputFolder & "\states.xml")
Try
ds.Tables(0).TableName = "states"
finalDS.Tables.Add(ds.Tables(0).Copy)
finalDS.Tables(finalDS.Tables.Count - 1).TableName = "states"
Catch ex As Exception
End Try
ds = New DataSet
ds.ReadXml(OutputFolder & "\ControlURLs.xml")
Try
ds.Tables(0).TableName = "ControlURLs"
finalDS.Tables.Add(ds.Tables(0).Copy)
finalDS.Tables(finalDS.Tables.Count - 1).TableName = "ControlURLs"
Catch ex As Exception
MsgBox(ex.Message)
End Try
finalDS.WriteXml(OutputFolder & "\UserData.xml")
End Sub
Sub DeviceParse(ByVal OutputFolder As String)
'ControlURLs
'states
Dim filename As String = OutputFolder & "\devices.xml"
Dim ControlURL As String = "<ControlURLs>" & vbCrLf
Dim States As String = "<states>" & vbCrLf
Dim ServiceID As Integer = 1
Dim settings As New XmlReaderSettings()
settings.DtdProcessing = DtdProcessing.Parse
Dim reader As XmlReader = XmlReader.Create(filename, settings)
Dim doc As New XmlDocument()
doc.Load(reader)
Dim root As XmlNode = doc.DocumentElement
Dim ienum As IEnumerator = root.GetEnumerator()
Dim device As XmlNode
While (ienum.MoveNext())
device = CType(ienum.Current, XmlNode)
Dim DeviceID As String = device.Attributes.GetNamedItem("id").InnerText
Dim DeviceDetails As XmlNode
Dim devenum As IEnumerator = device.GetEnumerator
While (devenum.MoveNext)
DeviceDetails = CType(devenum.Current, XmlNode)
Dim devChildNode As XmlNode
Dim childEnum As IEnumerator = DeviceDetails.GetEnumerator
While childEnum.MoveNext
devChildNode = CType(childEnum.Current, XmlNode)
Dim DeviceIDAttr As XmlAttribute = doc.CreateAttribute("DeviceID")
DeviceIDAttr.InnerText = DeviceID
devChildNode.Attributes.Append(DeviceIDAttr)
If devChildNode.OuterXml.StartsWith("<state") Then
States &= devChildNode.OuterXml & vbCrLf
Else
Dim serviceIDstr As String = "<service_" & ServiceID
Dim strtoWrite As String = devChildNode.OuterXml.Replace(serviceIDstr, "<service ID=""" & ServiceID & """ ")
strtoWrite = strtoWrite.Replace("</service_" & ServiceID & ">", "</service>")
ControlURL &= strtoWrite & vbCrLf
ServiceID += 1
End If
End While
End While
End While
States &= "</states>"
ControlURL &= "</ControlURLs>"
Dim fout As New IO.StreamWriter(OutputFolder & "\states.xml")
fout.Write(States)
fout.Close()
fout = New IO.StreamWriter(OutputFolder & "\controlurls.xml")
fout.Write(ControlURL)
fout.Close()
End Sub
Private Function GetWebPageContent(ByVal strURL As String) As String
Dim retVal As String = ""
Try
Dim srRead As System.IO.StreamReader = New System.IO.StreamReader(System.Net.WebRequest.Create(strURL).GetResponse.GetResponseStream)
retVal = srRead.ReadToEnd
Catch ex As Exception
retVal = "Hmm.."
End Try
Return retVal
End Function