MainUI: Buienradar (dutch rain forecast) widget

image

image

This widget visualizes the rain forecast using the data from the Buienradar binding. The Buienradar binding is required to retrieve the weather forecast (+2 hours).

The forecast data for each timestamp is mapped as follows:

  • 1 – 5: Light
  • 5 – 20: Medium
  • 20 – 100: Heavy

Note: Buienradar only provides Dutch weather forecasts.

Contents

Changelog

Version 0.1

  • initial release

Debugging and testing

While creating this widget, I needed some valid item values to test the widget. Unfortunately it didn’t actually rain at that time so I created some test items. Feel free to use it for some adjustments:
Debug Items:

Number buienradar_rain_prediction_mock_current
Number buienradar_rain_prediction_mock_5min 
Number buienradar_rain_prediction_mock_10min
Number buienradar_rain_prediction_mock_15min
Number buienradar_rain_prediction_mock_20min 
Number buienradar_rain_prediction_mock_25min 
Number buienradar_rain_prediction_mock_30min 
Number buienradar_rain_prediction_mock_35min 
Number buienradar_rain_prediction_mock_40min 
Number buienradar_rain_prediction_mock_45min 
Number buienradar_rain_prediction_mock_50min 
Number buienradar_rain_prediction_mock_55min 
Number buienradar_rain_prediction_mock_60min 
Number buienradar_rain_prediction_mock_65min 
Number buienradar_rain_prediction_mock_70min 
Number buienradar_rain_prediction_mock_75min 
Number buienradar_rain_prediction_mock_80min 
Number buienradar_rain_prediction_mock_85min 
Number buienradar_rain_prediction_mock_90min 
Number buienradar_rain_prediction_mock_95min 
Number buienradar_rain_prediction_mock_100min 
Number buienradar_rain_prediction_mock_105min 
Number buienradar_rain_prediction_mock_110min 
Number buienradar_rain_prediction_mock_115min 

Rule to set the initial value:

rule "buienradar mock"
when
     System reached start level 50
then
	buienradar_rain_prediction_mock_current.postUpdate(0)
    buienradar_rain_prediction_mock_5min.postUpdate(0.5) 
    buienradar_rain_prediction_mock_10min.postUpdate(1)
    buienradar_rain_prediction_mock_15min.postUpdate(1)
    buienradar_rain_prediction_mock_20min.postUpdate(0.75)
    buienradar_rain_prediction_mock_25min.postUpdate(1.25)
    buienradar_rain_prediction_mock_30min.postUpdate(1.5)
    buienradar_rain_prediction_mock_35min.postUpdate(1.75) 
    buienradar_rain_prediction_mock_40min.postUpdate(2.5)
    buienradar_rain_prediction_mock_45min.postUpdate(10) 
    buienradar_rain_prediction_mock_50min.postUpdate(15)
    buienradar_rain_prediction_mock_55min.postUpdate(15) 
    buienradar_rain_prediction_mock_60min.postUpdate(17) 
    buienradar_rain_prediction_mock_65min.postUpdate(20) 
    buienradar_rain_prediction_mock_70min.postUpdate(20) 
    buienradar_rain_prediction_mock_75min.postUpdate(20) 
    buienradar_rain_prediction_mock_80min.postUpdate(13) 
    buienradar_rain_prediction_mock_85min.postUpdate(10)
    buienradar_rain_prediction_mock_90min.postUpdate(4) 
    buienradar_rain_prediction_mock_95min.postUpdate(2) 
    buienradar_rain_prediction_mock_100min.postUpdate(5) 
    buienradar_rain_prediction_mock_105min.postUpdate(5) 
    buienradar_rain_prediction_mock_110min.postUpdate(3) 
    buienradar_rain_prediction_mock_115min.postUpdate(2)
end

Resources

Required thing (file configuration):

Thing buienradar:rain_forecast:home [ location="52.198864211111925,5.4192629660193585" ]

Required items (file configuration):

Number buienradar_rain_prediction_current "Current rain"  {channel="buienradar:rain_forecast:home:forecast_0" }
Number buienradar_rain_prediction_5min "Rain 5 min."  {channel="buienradar:rain_forecast:home:forecast_5" }
Number buienradar_rain_prediction_10min "Rain 10 min."  {channel="buienradar:rain_forecast:home:forecast_10" }
Number buienradar_rain_prediction_15min "Rain 15 min."{channel="buienradar:rain_forecast:home:forecast_15" }
Number buienradar_rain_prediction_20min "Rain 20 min."  {channel="buienradar:rain_forecast:home:forecast_20" }
Number buienradar_rain_prediction_25min "Rain 25 min."  {channel="buienradar:rain_forecast:home:forecast_25" }
Number buienradar_rain_prediction_30min "Rain 30 min."  {channel="buienradar:rain_forecast:home:forecast_30" }
Number buienradar_rain_prediction_35min "Rain 35 min."  {channel="buienradar:rain_forecast:home:forecast_35" }
Number buienradar_rain_prediction_40min "Rain 40 min."  {channel="buienradar:rain_forecast:home:forecast_40" }
Number buienradar_rain_prediction_45min "Rain 45 min."  {channel="buienradar:rain_forecast:home:forecast_45" }
Number buienradar_rain_prediction_50min "Rain 50 min."  {channel="buienradar:rain_forecast:home:forecast_50" }
Number buienradar_rain_prediction_55min "Rain 55 min."  {channel="buienradar:rain_forecast:home:forecast_55" }
Number buienradar_rain_prediction_60min "Rain 60 min."  {channel="buienradar:rain_forecast:home:forecast_60" }
Number buienradar_rain_prediction_65min "Rain 65 min."  {channel="buienradar:rain_forecast:home:forecast_65" }
Number buienradar_rain_prediction_70min "Rain 70 min."  {channel="buienradar:rain_forecast:home:forecast_70" }
Number buienradar_rain_prediction_75min "Rain 75 min."  {channel="buienradar:rain_forecast:home:forecast_75" }
Number buienradar_rain_prediction_80min "Rain 80 min."  {channel="buienradar:rain_forecast:home:forecast_80" }
Number buienradar_rain_prediction_85min "Rain 85 min."  {channel="buienradar:rain_forecast:home:forecast_85" }
Number buienradar_rain_prediction_90min "Rain 90 min."  {channel="buienradar:rain_forecast:home:forecast_90" }
Number buienradar_rain_prediction_95min "Rain 95 min."  {channel="buienradar:rain_forecast:home:forecast_95" }
Number buienradar_rain_prediction_100min "Rain 100 min."  {channel="buienradar:rain_forecast:home:forecast_100" }
Number buienradar_rain_prediction_105min "Rain 105 min."  {channel="buienradar:rain_forecast:home:forecast_105" }
Number buienradar_rain_prediction_110min "Rain 110 min."  {channel="buienradar:rain_forecast:home:forecast_110" }
Number buienradar_rain_prediction_115min "Rain 115 min."  {channel="buienradar:rain_forecast:home:forecast_115" }

Widget:

uid: buienradar_rain_prediction
tags: 
  - buienradar
  - rainprediction
  - madebyMatthijsV
props:
  parameters:
    - label: graph color (default= rgba(60, 149, 181, 0.5))
      name: graph_background
      required: false
      type: TEXT
    - label: graph x-axis text color (default= lightgrey)
      name: graph_x_axis_text_color
      required: false
      type: TEXT
    - label: graph y-axis text color (default= lightgrey)
      name: graph_y_axis_text_color
      required: false
      type: TEXT
    - label: graph axis line color (default= grey)
      name: graph_axis_line_color
      required: false
      type: TEXT
    - label: base item text (i.e.= 'RAIN_')
      name: base
      required: true
      type: TEXT
  parameterGroups: []
timestamp: Sep 29, 2023, 12:56:23 PM
component: oh-repeater
config:
  for: coords
  sourceType: array
  in:
    - p0: = 800 - (Number.parseFloat(items[props.base+"current"].state)<1?(Number.parseFloat(items[props.base+"current"].state*100)):(Number.parseFloat(items[props.base+"current"].state))<5? (Number.parseFloat(items[props.base+"current"].state*20 + 100)):(Number.parseFloat(items[props.base+"current"].state))<20? (Number.parseFloat(items[props.base+"current"].state*15 + 200)):800)
      p1: = 800 - (Number.parseFloat(items[props.base+   "5min"].state)<1?(Number.parseFloat(items[props.base+   "5min"].state*100)):(Number.parseFloat(items[props.base+   "5min"].state))<5? (Number.parseFloat(items[props.base+   "5min"].state*20 + 100)):(Number.parseFloat(items[props.base+   "5min"].state))<20? (Number.parseFloat(items[props.base+   "5min"].state*15 + 200)):800)
      p2: = 800 - (Number.parseFloat(items[props.base+  "10min"].state)<1?(Number.parseFloat(items[props.base+  "10min"].state*100)):(Number.parseFloat(items[props.base+  "10min"].state))<5? (Number.parseFloat(items[props.base+  "10min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "10min"].state))<20? (Number.parseFloat(items[props.base+  "10min"].state*15 + 200)):800)
      p3: = 800 - (Number.parseFloat(items[props.base+  "15min"].state)<1?(Number.parseFloat(items[props.base+  "15min"].state*100)):(Number.parseFloat(items[props.base+  "15min"].state))<5? (Number.parseFloat(items[props.base+  "15min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "15min"].state))<20? (Number.parseFloat(items[props.base+  "15min"].state*15 + 200)):800)
      p4: = 800 - (Number.parseFloat(items[props.base+  "20min"].state)<1?(Number.parseFloat(items[props.base+  "20min"].state*100)):(Number.parseFloat(items[props.base+  "20min"].state))<5? (Number.parseFloat(items[props.base+  "20min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "20min"].state))<20? (Number.parseFloat(items[props.base+  "20min"].state*15 + 200)):800)
      p5: = 800 - (Number.parseFloat(items[props.base+  "25min"].state)<1?(Number.parseFloat(items[props.base+  "25min"].state*100)):(Number.parseFloat(items[props.base+  "25min"].state))<5? (Number.parseFloat(items[props.base+  "25min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "25min"].state))<20? (Number.parseFloat(items[props.base+  "25min"].state*15 + 200)):800)
      p6: = 800 - (Number.parseFloat(items[props.base+  "30min"].state)<1?(Number.parseFloat(items[props.base+  "30min"].state*100)):(Number.parseFloat(items[props.base+  "30min"].state))<5? (Number.parseFloat(items[props.base+  "30min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "30min"].state))<20? (Number.parseFloat(items[props.base+  "30min"].state*15 + 200)):800)
      p7: = 800 - (Number.parseFloat(items[props.base+  "35min"].state)<1?(Number.parseFloat(items[props.base+  "35min"].state*100)):(Number.parseFloat(items[props.base+  "35min"].state))<5? (Number.parseFloat(items[props.base+  "35min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "35min"].state))<20? (Number.parseFloat(items[props.base+  "35min"].state*15 + 200)):800)
      p8: = 800 - (Number.parseFloat(items[props.base+  "40min"].state)<1?(Number.parseFloat(items[props.base+  "40min"].state*100)):(Number.parseFloat(items[props.base+  "40min"].state))<5? (Number.parseFloat(items[props.base+  "40min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "40min"].state))<20? (Number.parseFloat(items[props.base+  "40min"].state*15 + 200)):800)
      p9: = 800 - (Number.parseFloat(items[props.base+  "45min"].state)<1?(Number.parseFloat(items[props.base+  "45min"].state*100)):(Number.parseFloat(items[props.base+  "45min"].state))<5? (Number.parseFloat(items[props.base+  "45min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "45min"].state))<20? (Number.parseFloat(items[props.base+  "45min"].state*15 + 200)):800)
      p10: = 800 - (Number.parseFloat(items[props.base+  "50min"].state)<1?(Number.parseFloat(items[props.base+  "50min"].state*100)):(Number.parseFloat(items[props.base+  "50min"].state))<5? (Number.parseFloat(items[props.base+  "50min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "50min"].state))<20? (Number.parseFloat(items[props.base+  "50min"].state*15 + 200)):800)
      p11: = 800 - (Number.parseFloat(items[props.base+  "55min"].state)<1?(Number.parseFloat(items[props.base+  "55min"].state*100)):(Number.parseFloat(items[props.base+  "55min"].state))<5? (Number.parseFloat(items[props.base+  "55min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "55min"].state))<20? (Number.parseFloat(items[props.base+  "55min"].state*15 + 200)):800)
      p12: = 800 - (Number.parseFloat(items[props.base+  "60min"].state)<1?(Number.parseFloat(items[props.base+  "60min"].state*100)):(Number.parseFloat(items[props.base+  "60min"].state))<5? (Number.parseFloat(items[props.base+  "60min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "60min"].state))<20? (Number.parseFloat(items[props.base+  "60min"].state*15 + 200)):800)
      p13: = 800 - (Number.parseFloat(items[props.base+  "65min"].state)<1?(Number.parseFloat(items[props.base+  "65min"].state*100)):(Number.parseFloat(items[props.base+  "65min"].state))<5? (Number.parseFloat(items[props.base+  "65min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "65min"].state))<20? (Number.parseFloat(items[props.base+  "65min"].state*15 + 200)):800)
      p14: = 800 - (Number.parseFloat(items[props.base+  "70min"].state)<1?(Number.parseFloat(items[props.base+  "70min"].state*100)):(Number.parseFloat(items[props.base+  "70min"].state))<5? (Number.parseFloat(items[props.base+  "70min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "70min"].state))<20? (Number.parseFloat(items[props.base+  "70min"].state*15 + 200)):800)
      p15: = 800 - (Number.parseFloat(items[props.base+  "75min"].state)<1?(Number.parseFloat(items[props.base+  "75min"].state*100)):(Number.parseFloat(items[props.base+  "75min"].state))<5? (Number.parseFloat(items[props.base+  "75min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "75min"].state))<20? (Number.parseFloat(items[props.base+  "75min"].state*15 + 200)):800)
      p16: = 800 - (Number.parseFloat(items[props.base+  "80min"].state)<1?(Number.parseFloat(items[props.base+  "80min"].state*100)):(Number.parseFloat(items[props.base+  "80min"].state))<5? (Number.parseFloat(items[props.base+  "80min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "80min"].state))<20? (Number.parseFloat(items[props.base+  "80min"].state*15 + 200)):800)
      p17: = 800 - (Number.parseFloat(items[props.base+  "85min"].state)<1?(Number.parseFloat(items[props.base+  "85min"].state*100)):(Number.parseFloat(items[props.base+  "85min"].state))<5? (Number.parseFloat(items[props.base+  "85min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "85min"].state))<20? (Number.parseFloat(items[props.base+  "85min"].state*15 + 200)):800)
      p18: = 800 - (Number.parseFloat(items[props.base+  "90min"].state)<1?(Number.parseFloat(items[props.base+  "90min"].state*100)):(Number.parseFloat(items[props.base+  "90min"].state))<5? (Number.parseFloat(items[props.base+  "90min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "90min"].state))<20? (Number.parseFloat(items[props.base+  "90min"].state*15 + 200)):800)
      p19: = 800 - (Number.parseFloat(items[props.base+  "95min"].state)<1?(Number.parseFloat(items[props.base+  "95min"].state*100)):(Number.parseFloat(items[props.base+  "95min"].state))<5? (Number.parseFloat(items[props.base+  "95min"].state*20 + 100)):(Number.parseFloat(items[props.base+  "95min"].state))<20? (Number.parseFloat(items[props.base+  "95min"].state*15 + 200)):800)
      p20: = 800 - (Number.parseFloat(items[props.base+ "100min"].state)<1?(Number.parseFloat(items[props.base+ "100min"].state*100)):(Number.parseFloat(items[props.base+ "100min"].state))<5? (Number.parseFloat(items[props.base+ "100min"].state*20 + 100)):(Number.parseFloat(items[props.base+ "100min"].state))<20? (Number.parseFloat(items[props.base+ "100min"].state*15 + 200)):800)
      p21: = 800 - (Number.parseFloat(items[props.base+ "105min"].state)<1?(Number.parseFloat(items[props.base+ "105min"].state*100)):(Number.parseFloat(items[props.base+ "105min"].state))<5? (Number.parseFloat(items[props.base+ "105min"].state*20 + 100)):(Number.parseFloat(items[props.base+ "105min"].state))<20? (Number.parseFloat(items[props.base+ "105min"].state*15 + 200)):800)
      p22: = 800 - (Number.parseFloat(items[props.base+ "110min"].state)<1?(Number.parseFloat(items[props.base+ "110min"].state*100)):(Number.parseFloat(items[props.base+ "110min"].state))<5? (Number.parseFloat(items[props.base+ "110min"].state*20 + 100)):(Number.parseFloat(items[props.base+ "110min"].state))<20? (Number.parseFloat(items[props.base+ "110min"].state*15 + 200)):800)
      p23: = 800 - (Number.parseFloat(items[props.base+ "115min"].state)<1?(Number.parseFloat(items[props.base+ "115min"].state*100)):(Number.parseFloat(items[props.base+ "115min"].state))<5? (Number.parseFloat(items[props.base+ "115min"].state*20 + 100)):(Number.parseFloat(items[props.base+ "115min"].state))<20? (Number.parseFloat(items[props.base+ "115min"].state*15 + 200)):800)
      spacing: 96
      y_graph_start: 200
      y_graph_height: 800
      x_graph_start: 700
      graph_background: "=props.graph_background?props.graph_background:'rgba(60, 149, 181, 0.5)'"
      graph_x_axis_text_color: "=props.graph_x_axis_text_color?props.graph_x_axis_text_color :'lightgrey'"
      graph_y_axis_text_color: "=props.graph_y_axis_text_color?props.graph_y_axis_text_color :'lightgrey'"
      graph_axis_line_color: "=props.graph_axis_line_color?props.graph_axis_line_color :'grey'"
  fragment: true
slots:
  default:
    - component: f7-card
      config:
        style:
          border-radius: var(--f7-card-expandable-border-radius)
          margin-left: 5px
          margin-right: 5px
          padding: 0px
          height: 130px
          width: 315px
      slots:
        default:
          - component: f7-block
            config:
              style:
                display: flex
                flex-direction: column
                left: 0px
                position: absolute
                top: -5px
            slots:
              default:
                - component: Label
                  config:
                    style:
                      font-size: 12px
                      margin-top: 0px
                      color: =`${loop.coords.graph_y_axis_text_color}`
                    text: heavy
                - component: Label
                  config:
                    style:
                      font-size: 12px
                      margin-top: 10px
                      color: =`${loop.coords.graph_y_axis_text_color}`
                    text: medium
                - component: Label
                  config:
                    style:
                      font-size: 12px
                      margin-top: 10px
                      color: =`${loop.coords.graph_y_axis_text_color}`
                    text: light
                - component: f7-block
                  config:
                    style:
                      display: flex
                      flex-direction: row
                      left: 0px
                      position: absolute
                      top: 90px
                  slots:
                    default:
                      - component: Label
                        config:
                          style:
                            font-size: 12px
                            margin-left: 45px
                            color: =`${loop.coords.graph_x_axis_text_color}`
                          text: =dayjs().format('HH:mm')
                      - component: Label
                        config:
                          style:
                            font-size: 12px
                            margin-left: 25px
                            color: =`${loop.coords.graph_x_axis_text_color}`
                          text: =dayjs().add(30, 'minute').format('HH:mm')
                      - component: Label
                        config:
                          style:
                            font-size: 12px
                            margin-left: 25px
                            color: =`${loop.coords.graph_x_axis_text_color}`
                          text: =dayjs().add(60, 'minute').format('HH:mm')
                      - component: Label
                        config:
                          style:
                            font-size: 12px
                            margin-left: 25px
                            color: =`${loop.coords.graph_x_axis_text_color}`
                          text: =dayjs().add(90, 'minute').format('HH:mm')
                      - component: Label
                        config:
                          style:
                            font-size: 12px
                            margin-left: 25px
                            color: =`${loop.coords.graph_x_axis_text_color}`
                          text: =dayjs().add(120, 'minute').format('HH:mm')
          - component: svg
            config:
              height: 100px
              margin-left: 5px
              margin-right: 5px
              viewBox: 0 0 3000 1000
            slots:
              default:
                - component: polygon
                  config:
                    points: 650 200, 2950 200, 2950 210, 650 210
                    fill: =`${loop.coords.graph_axis_line_color}`
                - component: polygon
                  config:
                    points: 650 500, 2950 500, 2950 510, 650 510
                    fill: =`${loop.coords.graph_axis_line_color}`
                - component: polygon
                  config:
                    points: 650 800, 2950 800, 2950 810, 650 810
                    fill: =`${loop.coords.graph_axis_line_color}`
                - component: polygon
                  config:
                    points: 650 990, 2950 990, 2950 1000, 650 1000
                    fill: =`${loop.coords.graph_axis_line_color}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*0} ${loop.coords.y_graph_start + loop.coords.p0}, ${loop.coords.x_graph_start + loop.coords.spacing*1} ${loop.coords.y_graph_start + loop.coords.p1}, ${loop.coords.x_graph_start + loop.coords.spacing*1} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*1} ${loop.coords.y_graph_start + loop.coords.p1}, ${loop.coords.x_graph_start + loop.coords.spacing*2} ${loop.coords.y_graph_start + loop.coords.p2}, ${loop.coords.x_graph_start + loop.coords.spacing*2} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*1} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*2} ${loop.coords.y_graph_start + loop.coords.p2}, ${loop.coords.x_graph_start + loop.coords.spacing*3} ${loop.coords.y_graph_start + loop.coords.p3}, ${loop.coords.x_graph_start + loop.coords.spacing*3} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*2} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*3} ${loop.coords.y_graph_start + loop.coords.p3}, ${loop.coords.x_graph_start + loop.coords.spacing*4} ${loop.coords.y_graph_start + loop.coords.p4}, ${loop.coords.x_graph_start + loop.coords.spacing*4} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*3} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*4} ${loop.coords.y_graph_start + loop.coords.p4}, ${loop.coords.x_graph_start + loop.coords.spacing*5} ${loop.coords.y_graph_start + loop.coords.p5}, ${loop.coords.x_graph_start + loop.coords.spacing*5} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*4} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*5} ${loop.coords.y_graph_start + loop.coords.p5}, ${loop.coords.x_graph_start + loop.coords.spacing*6} ${loop.coords.y_graph_start + loop.coords.p6}, ${loop.coords.x_graph_start + loop.coords.spacing*6} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*5} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*6} ${loop.coords.y_graph_start + loop.coords.p6}, ${loop.coords.x_graph_start + loop.coords.spacing*7} ${loop.coords.y_graph_start + loop.coords.p7}, ${loop.coords.x_graph_start + loop.coords.spacing*7} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*6} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*7} ${loop.coords.y_graph_start + loop.coords.p7}, ${loop.coords.x_graph_start + loop.coords.spacing*8} ${loop.coords.y_graph_start + loop.coords.p8}, ${loop.coords.x_graph_start + loop.coords.spacing*8} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*7} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*8} ${loop.coords.y_graph_start + loop.coords.p8}, ${loop.coords.x_graph_start + loop.coords.spacing*9} ${loop.coords.y_graph_start + loop.coords.p9}, ${loop.coords.x_graph_start + loop.coords.spacing*9} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*8} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*9} ${loop.coords.y_graph_start + loop.coords.p9}, ${loop.coords.x_graph_start + loop.coords.spacing*10} ${loop.coords.y_graph_start + loop.coords.p10}, ${loop.coords.x_graph_start + loop.coords.spacing*10} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*9} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*10} ${loop.coords.y_graph_start + loop.coords.p10}, ${loop.coords.x_graph_start + loop.coords.spacing*11} ${loop.coords.y_graph_start + loop.coords.p11}, ${loop.coords.x_graph_start + loop.coords.spacing*11} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*10} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*11} ${loop.coords.y_graph_start + loop.coords.p11}, ${loop.coords.x_graph_start + loop.coords.spacing*12} ${loop.coords.y_graph_start + loop.coords.p12}, ${loop.coords.x_graph_start + loop.coords.spacing*12} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*11} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*12} ${loop.coords.y_graph_start + loop.coords.p12}, ${loop.coords.x_graph_start + loop.coords.spacing*13} ${loop.coords.y_graph_start + loop.coords.p13}, ${loop.coords.x_graph_start + loop.coords.spacing*13} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*12} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*13} ${loop.coords.y_graph_start + loop.coords.p13}, ${loop.coords.x_graph_start + loop.coords.spacing*14} ${loop.coords.y_graph_start + loop.coords.p14}, ${loop.coords.x_graph_start + loop.coords.spacing*14} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*13} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*14} ${loop.coords.y_graph_start + loop.coords.p14}, ${loop.coords.x_graph_start + loop.coords.spacing*15} ${loop.coords.y_graph_start + loop.coords.p15}, ${loop.coords.x_graph_start + loop.coords.spacing*15} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*14} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*15} ${loop.coords.y_graph_start + loop.coords.p15}, ${loop.coords.x_graph_start + loop.coords.spacing*16} ${loop.coords.y_graph_start + loop.coords.p16}, ${loop.coords.x_graph_start + loop.coords.spacing*16} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*15} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*16} ${loop.coords.y_graph_start + loop.coords.p16}, ${loop.coords.x_graph_start + loop.coords.spacing*17} ${loop.coords.y_graph_start + loop.coords.p17}, ${loop.coords.x_graph_start + loop.coords.spacing*17} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*16} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*17} ${loop.coords.y_graph_start + loop.coords.p17}, ${loop.coords.x_graph_start + loop.coords.spacing*18} ${loop.coords.y_graph_start + loop.coords.p18}, ${loop.coords.x_graph_start + loop.coords.spacing*18} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*17} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*18} ${loop.coords.y_graph_start + loop.coords.p18}, ${loop.coords.x_graph_start + loop.coords.spacing*19} ${loop.coords.y_graph_start + loop.coords.p19}, ${loop.coords.x_graph_start + loop.coords.spacing*19} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*18} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*19} ${loop.coords.y_graph_start + loop.coords.p19}, ${loop.coords.x_graph_start + loop.coords.spacing*20} ${loop.coords.y_graph_start + loop.coords.p20}, ${loop.coords.x_graph_start + loop.coords.spacing*20} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*19} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*20} ${loop.coords.y_graph_start + loop.coords.p20}, ${loop.coords.x_graph_start + loop.coords.spacing*21} ${loop.coords.y_graph_start + loop.coords.p21}, ${loop.coords.x_graph_start + loop.coords.spacing*21} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*20} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*21} ${loop.coords.y_graph_start + loop.coords.p21}, ${loop.coords.x_graph_start + loop.coords.spacing*22} ${loop.coords.y_graph_start + loop.coords.p22}, ${loop.coords.x_graph_start + loop.coords.spacing*22} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*21} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`
                - component: polygon
                  config:
                    points: =` ${loop.coords.x_graph_start + loop.coords.spacing*22} ${loop.coords.y_graph_start + loop.coords.p22}, ${loop.coords.x_graph_start + loop.coords.spacing*23} ${loop.coords.y_graph_start + loop.coords.p23}, ${loop.coords.x_graph_start + loop.coords.spacing*23} ${loop.coords.y_graph_start + loop.coords.y_graph_height}, ${loop.coords.x_graph_start + loop.coords.spacing*22} ${loop.coords.y_graph_start + loop.coords.y_graph_height}`
                    fill: =`${loop.coords.graph_background}`

5 Likes

Clever use of the repeater for a dynamic object variable; I like it.

You should check the market place on your OH, I’m not sure this post is currently formatted correctly to let users download the widget code. I think the widget still needs to be the final code block in the post if it’s to be downloaded.

2 Likes

Thanks!

I changed the order and now it’s available in the marketplace :grinning:

1 Like

Many thanks Matthijs for this very nice widget!

Hi,
I’m trying to download the widget via the marketplace, but that fails.
Installation of add-on marketplace:150006 failed
FWIW, Yours is not the only one though.
I’m using OH 4.2, if that matters.

Anyone using the widget ?
When are values displayed ? I mean what are the numbers that cause an image ?
I’m asking because nothing except the “background” is displayed : the times, the horizontal graph-lines and the left texts “heavy”, “medium” and “light” :
Screenshot_20240725_175204
These are the values I got from the thing :

2024-07-25 17:44:59.315 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Actual_DateTime' changed from 2024-07-25T17:40:00.000+0200 to 2024-07-25T17:45:00.000+0200
2024-07-25 17:44:59.317 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_current' changed from 0.7 mm/h to 1.07 mm/h
2024-07-25 17:44:59.319 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_10_min' changed from 1.54 mm/h to 2.21 mm/h
2024-07-25 17:44:59.320 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_15_min' changed from 2.37 mm/h to 2.05 mm/h
2024-07-25 17:44:59.320 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_20_min' changed from 1.65 mm/h to 2.05 mm/h
2024-07-25 17:44:59.321 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_30_min' changed from 1.91 mm/h to 1.07 mm/h
2024-07-25 17:44:59.321 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_35_min' changed from 1.43 mm/h to 1.65 mm/h
2024-07-25 17:44:59.322 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_45_min' changed from 1.54 mm/h to 0.1 mm/h
2024-07-25 17:44:59.322 [INFO ] [openhab.event.ItemStateChangedEvent ] - Item 'regen_voorspelling_Rainfall_in_50_min' changed from 0.29 mm/h to 0 mm/h

I’m using Openhab 4.2. I created the buienradar-thing and configured the location.
Then I used the model to create an equipment from a thing. There I selected all channels from my buienradar-thing.
This creates things with a name like this :
xxx_Rainfall_in_yy_min
where xxx is the name of the thing, and yy are the different times.
To avoid to have manually create all items I modified the widget like this :

     p0: = 800 -
        (Number.parseFloat(items[props.base+"current"].state)<1?(Number.parseFloat(items[props.base+"current"].state*100)):(Number.parseFloat(items[props.base+"current"].state))<5?
        (Number.parseFloat(items[props.base+"current"].state*20 +
        100)):(Number.parseFloat(items[props.base+"current"].state))<20?
        (Number.parseFloat(items[props.base+"current"].state*15 + 200)):800)
      p1: = 800 -
        (Number.parseFloat(items[props.base+   "in_5_min"].state)<1?(Number.parseFloat(items[props.base+   "in_5_min"].state*100)):(Number.parseFloat(items[props.base+   "in_5_min"].state))<5?
        (Number.parseFloat(items[props.base+   "in_5_min"].state*20 +
        100)):(Number.parseFloat(items[props.base+   "in_5_min"].state))<20?
        (Number.parseFloat(items[props.base+   "in_5_min"].state*15 + 200)):800)

etc.
The props.base is configured like this :
regen_voorspelling_Rainfall_

So, why isn’t anything displayed ? Do I miss something ? Did I make a typo somewhere ?
I can post the whole new widget if needed.
TIA

I’m currently running on 4.0.2 and not 4.2, so I can’t confirm if this still works on newer versions. I will try to find some time this week to upgrade my installation and test it.

Did you also try using the items and rules at the debug/testing section with the default widget code?

One thing that I noticed in your event log is that you are missing ‘regen_voorspelling_Rainfall_in_5_min’

Another one; your event log also prints the unit ‘mm/h’ where my values are dimensionless. Not sure if this interferes though.

Sorry for the late reply, but I gave up and just made text-files. I copied and pasted the item-code you provided and used your widget-code.
After some analyzing I also saw that your values are dimensionless. I added those dimensions because otherwise the values returned where very small. Adding those dimensions made the values similar in size to yours.