Announcement

Collapse
No announcement yet.

Weather (YR / met.no) script

Collapse
X
 
  • Filter
  • Time
  • Show
Clear All
new posts

  • alexbk66
    replied
    Interesting...

    Leave a comment:


  • widert
    replied
    I did some testing with Mono, using vnbc, and interestingly by removing "Property" it is actually working.

    So hence, the class now looks like:

    Code:
    Public Class Geometry
      Public type As String
      Public coordinates As Double()
    End Class
    Public Class Units
      Public air_pressure_at_sea_level As String
      Public air_temperature As String
      Public cloud_area_fraction As String
      Public precipitation_amount As String
      Public relative_humidity As String
      Public wind_from_direction As String
      Public wind_speed As String
    End Class
    Public Class Meta
      Public updated_at As DateTime
      Public units As Units
    End Class
    Public Class Details
      Public air_pressure_at_sea_level As Double
      Public air_temperature As Double
      Public cloud_area_fraction As Double
      Public dew_point_temperature As Double
      Public relative_humidity As Double
      Public wind_from_direction As Double
      Public wind_speed As Double
    End Class
    Public Class Details2
      Public precipitation_amount as Double
    End Class
    Public Class Instant
      Public details As Details
    End Class
    Public Class Summary
      Public symbol_code As String
    End Class
    Public Class Next12Hours
      Public summary As Summary
    End Class
    Public Class Next1Hours
      Public summary As Summary
      Public details As Details2
    End Class
    Public Class Next6Hours
      Public summary As Summary
      Public details As Details2
    End Class
    Public Class Data
      Public instant As Instant
      Public next_12_hours As Next12Hours
      Public next_1_hours As Next1Hours
      Public next_6_hours As Next6Hours
    End Class
    Public Class Timesery
      Public time As DateTime
      Public data As Data
    End Class
    Public Class Properties
      Public meta As Meta
      Public timeseries As Timesery()
    End Class
    Public Class Weather
      Public type As String
      Public geometry As Geometry
      Public properties As Properties
    End Class
    Thank you very much for your help and guidance, really appreciate it!

    Leave a comment:


  • alexbk66
    replied
    widert so it's definitely Mono version issue, please Google. May be try updating to latest version (6.12?).
    In the worst case you'll have to add setters and getters to each property explicitly.

    Leave a comment:


  • widert
    replied
    Originally posted by alexbk66 View Post

    Just try something simple, i.e. just
    Code:
    Public Class Weather
    Public Property type As String
    End Class
    So, testing something simple:
    Code:
    Sub Main(parm as object)
      Dim test as weather
    End Sub
    Public Class Weather
       Public Property type As String
    End Class
    Gives me the following errors:


    Click image for larger version

Name:	Capture.PNG
Views:	116
Size:	119.3 KB
ID:	1459096

    Leave a comment:


  • alexbk66
    replied
    If necessary you can also use attribute to change the property name, i.e. if there's a space in json name:
    Code:
    [JsonProperty("time stamp")]
    public UInt64 TimeStamp { get; set; }

    Leave a comment:


  • rge
    replied
    Where there are classes/properties in the JSON with the same name the generated code is missing lines and/or it messes up the get/set parts.

    I can't remember the full details, but looking at my script I have these bits among the rest which are probably the relevant parts:

    Code:
    Public Class Details2
        Public Property precipitation_amount as Double
    End Class
    
    Public Class Next1Hours
        Public Property summary As Summary
        Public Property details As Details2
    End Class
    There may be other parts, but that's the general idea - each class should have the same properties as the corresponding part of JSON; the class names don't matter, hence the freedom to create a new distinct "Details2" class to represent that slightly different details element.

    Leave a comment:


  • alexbk66
    replied
    Originally posted by widert View Post
    As far as I can read from the above then RGE had the same issues, but solved them.
    Just try something simple, i.e. just
    Code:
    Public Class Weather
       Public Property type As String
    End Class

    Leave a comment:


  • alexbk66
    replied
    Originally posted by widert View Post
    As far as I can read from the above then RGE had the same issues, but solved them.
    I don't see that, what post do you refer to?
    Also, the error you mention - what line of code exactly is causing it?

    Leave a comment:


  • widert
    replied
    Originally posted by alexbk66 View Post

    I'm not expert in Linux and VB.NET but I suspect it's caused by Mono. Because it's nothing wrong with auto-implemented properties. I suggest to Google for this error in Mono
    As far as I can read from the above then RGE had the same issues, but solved them.

    Leave a comment:


  • alexbk66
    replied
    Originally posted by widert View Post
    Code:
    Property without a 'ReadOnly' or 'WriteOnly' specifier must provide both a 'Get' and a 'Set'
    I'm not expert in Linux and VB.NET but I suspect it's caused by Mono. Because it's nothing wrong with auto-implemented properties. I suggest to Google for this error in Mono

    Leave a comment:


  • widert
    replied
    Originally posted by rge View Post
    After some great pointers from alexbk66 I've updated the script to use proper classes and JSON deserialization.

    Code:
    Imports System.Web
    Imports System.Net
    Imports System.IO
    Imports System.Text
    Imports Newtonsoft.Json
    
    Sub Main(args As object)
    
    ' Get JSON data from web
    ' TODO put your location in the URL parameters
    Dim url as String = "https://api.met.no/weatherapi/locationforecast/2.0/compact?altitude=300&lat=47.36676&lon=8.54171"
    
    Dim wRequest as HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
    wRequest.Method = "GET"
    
    ' TODO put your email address in here
    wRequest.UserAgent = ""
    
    Dim wResponse As HttpWebResponse = DirectCast(wRequest.GetResponse(), HttpWebResponse)
    
    Dim sResponse As String
    
    Using srRead As New StreamReader(wResponse.GetResponseStream())
    sResponse = srRead.ReadToEnd()
    End Using
    
    ' Parse JSON data
    Dim w as Weather = JsonConvert.DeserializeObject(Of Weather)(sResponse)
    
    ' Get current values
    Dim offset as Integer = -1
    
    Do
    offset = offset + 1
    Loop Until w.properties.timeseries(offset).time.ToLocalTime() > Now Or offset = w.properties.timeseries.Length - 1
    
    If offset = w.properties.timeseries.Length - 1 Then
    hs.WriteLog("Weather", "ERROR: current weather timeseries not found")
    Exit Sub
    End If
    
    If offset > 0 Then
    offset = offset - 1
    End If
    
    With w.properties.timeseries(offset)
    
    hs.WriteLog("Weather", "Current: " & .time.ToLocalTime() & " (offset " & offset & ")")
    
    With .data.instant.details
    
    hs.WriteLog("Weather", "Barometer: " & .air_pressure_at_sea_level & " Wind direction: " & .wind_from_direction & " speed: " & .wind_speed)
    
    ' TODO update device numbers here
    
    hs.SetDeviceValueByRef(437, .air_pressure_at_sea_level, True)
    hs.SetDeviceValueByRef(438, .wind_speed, True)
    hs.SetDeviceValueByRef(439, .wind_from_direction, True)
    
    End With
    End With
    
    ' Get rain for next 12, 24 and 48 hours
    Dim rain12 as Double = 0.0
    Dim rain24 as Double = 0.0
    Dim rain48 as Double = 0.0
    
    For i as Integer = 0 to 42 step 6
    
    Dim rainslice as Double = w.properties.timeseries(i+offset).data.next_6_hours.details.precipitation_amount
    
    If i <= 6 Then
    rain12 = rain12 + rainslice
    End If
    
    If i <= 18 Then
    rain24 = rain24 + rainslice
    End If
    
    rain48 = rain48 + rainslice
    Next
    
    hs.WriteLog("Weather", "Rain 12h: " & rain12 & " 24h: " & rain24 & " 48h: " & rain48)
    
    ' TODO update device numbers here
    
    hs.SetDeviceValueByRef(440, rain12, True)
    hs.SetDeviceValueByRef(441, rain24, True)
    hs.SetDeviceValueByRef(442, rain48, True)
    End Sub
    
    Public Class Geometry
    Public Property type As String
    Public Property coordinates As Double()
    End Class
    
    Public Class Units
    Public Property air_pressure_at_sea_level As String
    Public Property air_temperature As String
    Public Property cloud_area_fraction As String
    Public Property precipitation_amount As String
    Public Property relative_humidity As String
    Public Property wind_from_direction As String
    Public Property wind_speed As String
    End Class
    
    Public Class Meta
    Public Property updated_at As DateTime
    Public Property units As Units
    End Class
    
    Public Class Details
    Public Property air_pressure_at_sea_level As Double
    Public Property air_temperature As Double
    Public Property cloud_area_fraction As Double
    Public Property dew_point_temperature As Double
    Public Property relative_humidity As Double
    Public Property wind_from_direction As Double
    Public Property wind_speed As Double
    End Class
    
    Public Class Details2
    Public Property precipitation_amount as Double
    End Class
    
    Public Class Instant
    Public Property details As Details
    End Class
    
    Public Class Summary
    Public Property symbol_code As String
    End Class
    
    Public Class Next12Hours
    Public Property summary As Summary
    End Class
    
    Public Class Next1Hours
    Public Property summary As Summary
    Public Property details As Details2
    End Class
    
    Public Class Next6Hours
    Public Property summary As Summary
    Public Property details As Details2
    End Class
    
    Public Class Data
    Public Property instant As Instant
    Public Property next_12_hours As Next12Hours
    Public Property next_1_hours As Next1Hours
    Public Property next_6_hours As Next6Hours
    End Class
    
    Public Class Timesery
    Public Property time As DateTime
    Public Property data As Data
    End Class
    
    Public Class Properties
    Public Property meta As Meta
    Public Property timeseries As Timesery()
    End Class
    
    Public Class Weather
    Public Property type As String
    Public Property geometry As Geometry
    Public Property properties As Properties
    End Class
    Trying to test the script but i get a lot of errors like these:

    Code:
    Property without a 'ReadOnly' or 'WriteOnly' specifier must provide both a 'Get' and a 'Set'
    Maybe related to my scriptingreferencese?
    Code:
    ScriptingReferences=Newtonsoft.Json;bin\homeseer\Newtonsoft.Json.dll
    Any suggestions?

    Code:
    Date/time=26/02/2021 09:31:52 CET
    Version=HS4 Standard Edition 4.1.12.0 (Linux)
    MONO Version=Mono JIT compiler version 6.8.0.105 (Debian 6.8.0.105+dfsg-3 Mon Apr 27 19:25:46 UTC 2020)
    
    License=Registered
    Confguration File=/opt/HomeSeer/Data/HomeSeerData.json
    Uptime=0 Days 17 Hours 52 Minutes 27 Seconds
    Lan IP=10.0.0.191 (ubuntu)
    Device Count=296
    Event Count=23
    Plugins Enabled=Z-Wave:,JowiHue:
    Modules/Threads=89 Modules, 49 Threads
    Available Threads=399
    HomeSeer Memory Used=169 Mbytes
    Plugins Installed=JowiHue 2.1.1.9,Z-Wave 3.0.2.0

    Leave a comment:


  • alexbk66
    replied
    Originally posted by rge View Post

    Yes, thanks! Was timing the script to check performance vs the self-parsing option - it's basically the same (just 1ms slower) on my system.
    Even if using proper parsing is slower - it shouldn't prevent you from using it. That's your development time and quality/reliability matter!

    Leave a comment:


  • rge
    replied
    Originally posted by jon00 View Post
    I assume you left stopwatch in by mistake?
    Yes, thanks! Was timing the script to check performance vs the self-parsing option - it's basically the same (just 1ms slower) on my system.

    Leave a comment:


  • jon00
    replied
    I assume you left stopwatch in by mistake?

    Leave a comment:


  • rge
    replied
    After some great pointers from alexbk66 I've updated the script to use proper classes and JSON deserialization.

    Code:
    Imports System.Web
    Imports System.Net
    Imports System.IO
    Imports System.Text
    Imports Newtonsoft.Json
    
    Sub Main(args As object)
    
      ' Get JSON data from web
      ' TODO put your location in the URL parameters
      Dim url as String = "https://api.met.no/weatherapi/locationforecast/2.0/compact?altitude=300&lat=47.36676&lon=8.54171"
    
      Dim wRequest as HttpWebRequest = DirectCast(WebRequest.Create(url), HttpWebRequest)
      wRequest.Method = "GET"
    
      ' TODO put your email address in here
      wRequest.UserAgent = ""
    
      Dim wResponse As HttpWebResponse = DirectCast(wRequest.GetResponse(), HttpWebResponse)
    
      Dim sResponse As String
    
      Using srRead As New StreamReader(wResponse.GetResponseStream())
        sResponse = srRead.ReadToEnd()
      End Using
    
      ' Parse JSON data
      Dim w as Weather = JsonConvert.DeserializeObject(Of Weather)(sResponse)
    
      ' Get current values
      Dim offset as Integer = -1
    
      Do
        offset = offset + 1
      Loop Until w.properties.timeseries(offset).time.ToLocalTime() > Now Or offset = w.properties.timeseries.Length - 1
    
      If offset = w.properties.timeseries.Length - 1 Then
        hs.WriteLog("Weather", "ERROR: current weather timeseries not found")
        Exit Sub
      End If
    
      If offset > 0 Then
        offset = offset - 1
      End If
    
      With w.properties.timeseries(offset)
    
        hs.WriteLog("Weather", "Current: " & .time.ToLocalTime() & " (offset " & offset & ")")
    
        With .data.instant.details
    
          hs.WriteLog("Weather", "Barometer: " & .air_pressure_at_sea_level & " Wind direction: " & .wind_from_direction & " speed: " & .wind_speed)
    
          ' TODO update device numbers here
    
          hs.SetDeviceValueByRef(437, .air_pressure_at_sea_level, True)
          hs.SetDeviceValueByRef(438, .wind_speed, True)
          hs.SetDeviceValueByRef(439, .wind_from_direction, True)
    
        End With
      End With
    
      ' Get rain for next 12, 24 and 48 hours
      Dim rain12 as Double = 0.0
      Dim rain24 as Double = 0.0
      Dim rain48 as Double = 0.0
    
      For i as Integer = 0 to 42 step 6
    
        Dim rainslice as Double = w.properties.timeseries(i+offset).data.next_6_hours.details.precipitation_amount
    
        If i <= 6 Then
          rain12 = rain12 + rainslice
        End If
    
        If i <= 18 Then
          rain24 = rain24 + rainslice
        End If
    
        rain48 = rain48 + rainslice
      Next
    
      hs.WriteLog("Weather", "Rain 12h: " & rain12 & " 24h: " & rain24 & " 48h: " & rain48)
    
      ' TODO update device numbers here
    
      hs.SetDeviceValueByRef(440, rain12, True)
      hs.SetDeviceValueByRef(441, rain24, True)
      hs.SetDeviceValueByRef(442, rain48, True)
    End Sub
    
    Public Class Geometry
      Public Property type As String
      Public Property coordinates As Double()
    End Class
    
    Public Class Units
      Public Property air_pressure_at_sea_level As String
      Public Property air_temperature As String
      Public Property cloud_area_fraction As String
      Public Property precipitation_amount As String
      Public Property relative_humidity As String
      Public Property wind_from_direction As String
      Public Property wind_speed As String
    End Class
    
    Public Class Meta
      Public Property updated_at As DateTime
      Public Property units As Units
    End Class
    
    Public Class Details
      Public Property air_pressure_at_sea_level As Double
      Public Property air_temperature As Double
      Public Property cloud_area_fraction As Double
      Public Property dew_point_temperature As Double
      Public Property relative_humidity As Double
      Public Property wind_from_direction As Double
      Public Property wind_speed As Double
    End Class
    
    Public Class Details2
      Public Property precipitation_amount as Double
    End Class
    
    Public Class Instant
      Public Property details As Details
    End Class
    
    Public Class Summary
      Public Property symbol_code As String
    End Class
    
    Public Class Next12Hours
      Public Property summary As Summary
    End Class
    
    Public Class Next1Hours
      Public Property summary As Summary
      Public Property details As Details2
    End Class
    
    Public Class Next6Hours
      Public Property summary As Summary
      Public Property details As Details2
    End Class
    
    Public Class Data
      Public Property instant As Instant
      Public Property next_12_hours As Next12Hours
      Public Property next_1_hours As Next1Hours
      Public Property next_6_hours As Next6Hours
    End Class
    
    Public Class Timesery
      Public Property time As DateTime
      Public Property data As Data
    End Class
    
    Public Class Properties
      Public Property meta As Meta
      Public Property timeseries As Timesery()
    End Class
    
    Public Class Weather
      Public Property type As String
      Public Property geometry As Geometry
      Public Property properties As Properties
    End Class

    Leave a comment:

Working...
X