Parsing Vera User Data - Loadable as .NET Dataset
From MiOS
There 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