Parsing Vera User Data - Loadable as .NET Dataset

From MiOS
Revision as of 18:53, 24 September 2011 by Mysticjay (Talk | contribs)

Jump to: navigation, search

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.

Parse.jpg



Note: For the JSONObject used here: 'Credits: http://www.vbforums.com/showthread.php?t=645037



   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
Personal tools