windCompass

Using ideas and code from 2 different widgets, I created this option. I hope it will be useful to someone. The widgets I used are:

windCompass

uid: windCompass
tags:
  - Compass
  - direction
  - speed
  - wind
props:
  parameters:
    - context: item
      description: The source wind direction in degrees
      label: Direction Item
      name: directionItem
      required: false
      type: TEXT
    - default: "#ff8c1a"
      description: The wind direction needle color
      label: Direction Needle Color
      name: directionNeedleColor
      required: false
      type: TEXT
      advanced: true
    - description: The wind direction name in the tooltip
      label: Direction Name
      name: directionName
      required: false
      type: TEXT
    - default: "true"
      description: Whether to show the LCD
      label: Show LCD
      name: showLCD
      required: false
      type: BOOLEAN
    - default: "true"
      description: Whether to show wind direction
      label: Show Wind Direction
      name: showWindDir
      required: false
      type: BOOLEAN
    - context: item
      description: The wind speed
      label: Wind Speed
      name: windSpeed
      required: false
      type: TEXT
    - default: "#066a19"
      description: The wind speed needle color
      label: Speed Needle Color
      name: speedNeedleColor
      required: false
      type: TEXT
      advanced: true
    - description: The wind speed name in the tooltip
      label: Speed Name
      name: speedName
      required: false
      type: TEXT
    - context: item
      description: The wind gust speed
      label: Gust Speed
      name: gustSpeed
      required: false
      type: TEXT
    - default: "#ff4a19"
      description: The wind gust speed needle color
      label: Gust Needle Color
      name: gustNeedleColor
      required: false
      type: TEXT
      advanced: true
    - description: The wind gust speed name in the tooltip
      label: Gust Name
      name: gustName
      required: false
      type: TEXT
    - default: "40"
      description: The maximum wind speed to show
      label: Max Speed
      name: maxSpeed
      required: false
      type: DECIMAL
    - default: "13"
      description: The wind direction font size
      label: Direction Font Size
      name: directionFontSize
      required: false
      type: INTEGER
      min: 6
      max: 50
      advanced: true
    - default: "12"
      description: The wind speed font size
      label: Speed Font Size
      name: speedFontSize
      required: false
      type: INTEGER
      min: 6
      max: 50
      advanced: true
    - default: "#ddd"
      description: The gauge frame color
      label: Frame Color
      name: frameColor
      required: false
      type: TEXT
    - description: The widget height (in px, %, etc.)
      label: Height
      name: height
      required: false
      type: TEXT
      advanced: true
  parameterGroups: []
timestamp: Jan 6, 2025, 2:54:01 PM
component: oh-chart
config:
  height: =props.height
slots:
  series:
    - component: oh-data-series
      config:
        axisLabel:
          distance: 12
          fontSize: =props.directionFontSize
          formatter: =v=>(v===360)?'':v.toFixed(0)+''
        axisLine:
          show: false
        axisTick:
          distance: -10
          length: 10
          splitNumber: 6
        data:
          - itemStyle:
              color: =props.directionNeedleColor
            name: =["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","N"][Math.round((Number.parseFloat(items[props.directionItem].state)
              % 360) / 22.5)]
            value: =Number.parseFloat(items[props.directionItem].state)
        detail:
          backgroundColor: rgb(137,150,96)
          borderColor: "#000"
          borderWidth: 1
          color: "#000"
          fontFamily: Courier New
          fontSize: 1.4em
          fontWeight: 600
          formatter: =v=>v.toFixed(0)+'°'
          offsetCenter:
            - 0
            - 35%
          padding:
            - 0
            - 2
            - 0
            - 3
          show: =props.showLCD
          valueAnimation: true
          width: 50%
        endAngle: -270
        max: = 360
        min: = 0
        pointer:
          icon: arrow
          itemStyle:
            shadowBlur: 2
            shadowColor: "#000a"
            shadowOffsetX: 2
            shadowOffsetY: 2
          keepAspect: false
          length: 15%
          offsetCenter:
            - 0
            - -95%
          width: 15%
        radius: 66%
        splitLine:
          distance: -10
          length: 15
        splitNumber: 12
        startAngle: 90
        title:
          color: =props.directionNeedleColor
          fontSize: 1.4em
          fontWeight: 600
          offsetCenter:
            - 0
            - -35%
          show: =props.showWindDir
        tooltip:
          formatter: "=props.directionName ? p=>props.directionName+':
            <b>'+p.value.toFixed(1)+'°</b>' : NULL"
          valueFormatter: =v=>v.toFixed(1)+'°'
        type: gauge
    - component: oh-data-series
      config:
        axisLabel:
          distance: -13
          fontSize: =props.speedFontSize
          show: true
        axisLine:
          distance: -50
          lineStyle:
            color:
              - - 0.03
                - "#6271b833"
              - - 0.08
                - "#4a939b33"
              - - 0.2
                - "#52a44633"
              - - 0.3
                - "#a27e4933"
              - - 0.45
                - "#8e405f33"
              - - 0.55
                - "#5f66a044"
              - - 0.68
                - "#5b88a155"
              - - 0.8
                - "#8b48a166"
              - - 0.9
                - "#db489177"
              - - 1
                - "#ff3e4677"
            width: 15
        axisTick:
          distance: -15
          length: 10
          show: true
        data:
          - itemStyle:
              color: "=props.windSpeed ? props.speedNeedleColor : '#0000'"
            tooltip:
              formatter: "=props.speedName ? p=>props.speedName+': <b>'+p.value.toFixed(1)+'
                '+items[props.windSpeed].state.split(' ')[1]+'</b>' : NULL"
              valueFormatter: =v=>v.toFixed(1)+' '+items[props.windSpeed].state.split(" ")[1]
            value: =Number.parseFloat(items[props.windSpeed].state)
          - itemStyle:
              color: "=props.gustSpeed ? props.gustNeedleColor : '#0000'"
            tooltip:
              formatter: "=props.gustName ? p=>props.gustName+': <b>'+p.value.toFixed(1)+'
                '+items[props.gustSpeed].state.split(' ')[1]+'</b>' : NULL"
              valueFormatter: =v=>v.toFixed(1)+' '+items[props.gustSpeed].state.split(" ")[1]
            value: =Number.parseFloat(items[props.gustSpeed].state)
        detail:
          show: false
        max: =props.maxSpeed
        min: 0
        pointer:
          icon: arrow
          itemStyle:
            shadowBlur: 2
            shadowColor: "#000a"
            shadowOffsetX: 2
            shadowOffsetY: 2
          keepAspect: true
          length: 12%
          offsetCenter:
            - 0
            - -95%
          width: 10%
        radius: 88%
        splitLine:
          distance: -15
          length: 12
        splitNumber: 10
        title:
          show: false
        type: gauge
    - component: oh-data-series
      config:
        axisLabel:
          show: false
        axisLine:
          lineStyle:
            color:
              - - 1
                - =props.frameColor
            shadowBlur: 10
            shadowColor: "#0008"
            width: 8
          show: true
        axisTick:
          show: false
        detail:
          show: false
        endAngle: -270
        pointer:
          show: false
        radius: 75%
        splitLine:
          show: false
        title:
          show: false
        type: gauge
  tooltip:
    - component: oh-chart-tooltip
      config:
        show: true
2 Likes

Looks good.
I am confused as to the wind direction arrow. I have other wind direction indicators and they show the wind going to direction, so I guess yours is showing where it is coming from?

Below your widget:
Screenshot from 2025-01-07 08-04-37

One of my widgets:
Screenshot from 2025-01-07 08-05-32

And another one I use:
Screenshot from 2025-01-07 08-05-49

I do like SE (in this case) direction on the dial.

Thanks for the widget.

Hi Greg!

I changed widget and included an option for wind direction going to or comming from.

Please see the new widget.

I think the best option was to “rotate” the original arrow icon but I don’t know how to do it so I changed the icon to SVG.

Thank you.

windCompass-2

uid: windCompass
tags:
  - Compass
  - direction
  - speed
  - wind
props:
  parameters:
    - context: item
      description: The source wind direction in degrees
      label: Direction Item
      name: directionItem
      required: false
      type: TEXT
    - default: "#ff8c1a"
      description: The wind direction needle color
      label: Direction Needle Color
      name: directionNeedleColor
      required: false
      type: TEXT
      advanced: true
    - description: The wind direction name in the tooltip
      label: Direction Name
      name: directionName
      required: false
      type: TEXT
    - default: "true"
      description: Whether to show the LCD
      label: Show LCD
      name: showLCD
      required: false
      type: BOOLEAN
    - default: "false"
      description: Whether to reverse the wind direction indicator
      label: Reverse the wind direction indicator
      name: revertWindIndicator
      required: false
      type: BOOLEAN
    - default: "true"
      description: Whether to show wind direction
      label: Show Wind Direction
      name: showWindDir
      required: false
      type: BOOLEAN
    - context: item
      description: The wind speed
      label: Wind Speed
      name: windSpeed
      required: false
      type: TEXT
    - default: "#066a19"
      description: The wind speed needle color
      label: Speed Needle Color
      name: speedNeedleColor
      required: false
      type: TEXT
      advanced: true
    - description: The wind speed name in the tooltip
      label: Speed Name
      name: speedName
      required: false
      type: TEXT
    - context: item
      description: The wind gust speed
      label: Gust Speed
      name: gustSpeed
      required: false
      type: TEXT
    - default: "#ff4a19"
      description: The wind gust speed needle color
      label: Gust Needle Color
      name: gustNeedleColor
      required: false
      type: TEXT
      advanced: true
    - description: The wind gust speed name in the tooltip
      label: Gust Name
      name: gustName
      required: false
      type: TEXT
    - default: "40"
      description: The maximum wind speed to show
      label: Max Speed
      name: maxSpeed
      required: false
      type: DECIMAL
    - default: "13"
      description: The wind direction font size
      label: Direction Font Size
      name: directionFontSize
      required: false
      type: INTEGER
      min: 6
      max: 50
      advanced: true
    - default: "12"
      description: The wind speed font size
      label: Speed Font Size
      name: speedFontSize
      required: false
      type: INTEGER
      min: 6
      max: 50
      advanced: true
    - default: "#ddd"
      description: The gauge frame color
      label: Frame Color
      name: frameColor
      required: false
      type: TEXT
    - description: The widget height (in px, %, etc.)
      label: Height
      name: height
      required: false
      type: TEXT
      advanced: true
  parameterGroups: []
timestamp: Jan 7, 2025, 3:22:35 PM
component: oh-chart
config:
  height: =props.height
slots:
  series:
    - component: oh-data-series
      config:
        axisLabel:
          distance: 12
          fontSize: =props.directionFontSize
          formatter: =v=>(v===360)?'':v.toFixed(0)+''
        axisLine:
          show: false
        axisTick:
          distance: -10
          length: 10
          splitNumber: 6
        data:
          - itemStyle:
              color: =props.directionNeedleColor
            name: =["N","NNE","NE","ENE","E","ESE","SE","SSE","S","SSW","SW","WSW","W","WNW","NW","NNW","N"][Math.round((Number.parseFloat(items[props.directionItem].state)
              % 360) / 22.5)]
            value: =Number.parseFloat(items[props.directionItem].state)
        detail:
          backgroundColor: rgb(137,150,96)
          borderColor: "#000"
          borderWidth: 1
          color: "#000"
          fontFamily: Courier New
          fontSize: 1.4em
          fontWeight: 600
          formatter: =v=>v.toFixed(0)+'°'
          offsetCenter:
            - 0
            - 35%
          padding:
            - 0
            - 2
            - 0
            - 3
          show: =props.showLCD
          valueAnimation: true
          width: 50%
        endAngle: -270
        max: = 360
        min: = 0
        pointer:
          icon: '=(props.revertWindIndicator === false) ? "path://m19.707 9.293-7-7a1 1 0
            0 0-1.414 0l-7 7A1 1 0 0 0 5 11h3v10a1 1 0 0 0 1 1h6a1 1 0 0 0
            1-1V11h3a1 1 0 0 0 .707-1.707z" : "path://M19.924 13.617A1 1 0 0 0
            19 13h-3V3a1 1 0 0 0-1-1H9a1 1 0 0 0-1 1v10H5a1 1 0 0 0-.707 1.707l7
            7a1 1 0 0 0 1.414 0l7-7a1 1 0 0 0 .217-1.09z"'
          itemStyle:
            shadowBlur: 2
            shadowColor: "#000a"
            shadowOffsetX: 2
            shadowOffsetY: 2
          keepAspect: true
          length: 22%
          offsetCenter:
            - 0
            - -82%
          width: 15%
        radius: 66%
        splitLine:
          distance: -10
          length: 15
        splitNumber: 12
        startAngle: 90
        title:
          color: =props.directionNeedleColor
          fontSize: 1.4em
          fontWeight: 600
          offsetCenter:
            - 0
            - -35%
          show: =props.showWindDir
        tooltip:
          formatter: "=props.directionName ? p=>props.directionName+':
            <b>'+p.value.toFixed(1)+'°</b>' : NULL"
          valueFormatter: =v=>v.toFixed(1)+'°'
        type: gauge
    - component: oh-data-series
      config:
        axisLabel:
          distance: -13
          fontSize: =props.speedFontSize
          show: true
        axisLine:
          distance: -50
          lineStyle:
            color:
              - - 0.03
                - "#6271b833"
              - - 0.08
                - "#4a939b33"
              - - 0.2
                - "#52a44633"
              - - 0.3
                - "#a27e4933"
              - - 0.45
                - "#8e405f33"
              - - 0.55
                - "#5f66a044"
              - - 0.68
                - "#5b88a155"
              - - 0.8
                - "#8b48a166"
              - - 0.9
                - "#db489177"
              - - 1
                - "#ff3e4677"
            width: 15
        axisTick:
          distance: -15
          length: 10
          show: true
        data:
          - itemStyle:
              color: "=props.windSpeed ? props.speedNeedleColor : '#0000'"
            tooltip:
              formatter: "=props.speedName ? p=>props.speedName+': <b>'+p.value.toFixed(1)+'
                '+items[props.windSpeed].state.split(' ')[1]+'</b>' : NULL"
              valueFormatter: =v=>v.toFixed(1)+' '+items[props.windSpeed].state.split(" ")[1]
            value: =Number.parseFloat(items[props.windSpeed].state)
          - itemStyle:
              color: "=props.gustSpeed ? props.gustNeedleColor : '#0000'"
            tooltip:
              formatter: "=props.gustName ? p=>props.gustName+': <b>'+p.value.toFixed(1)+'
                '+items[props.gustSpeed].state.split(' ')[1]+'</b>' : NULL"
              valueFormatter: =v=>v.toFixed(1)+' '+items[props.gustSpeed].state.split(" ")[1]
            value: =Number.parseFloat(items[props.gustSpeed].state)
        detail:
          show: false
        max: =props.maxSpeed
        min: 0
        pointer:
          icon: arrow
          itemStyle:
            shadowBlur: 2
            shadowColor: "#000a"
            shadowOffsetX: 2
            shadowOffsetY: 2
          keepAspect: true
          length: 12%
          offsetCenter:
            - 0
            - -95%
          width: 10%
        radius: 88%
        splitLine:
          distance: -15
          length: 12
        splitNumber: 10
        title:
          show: false
        type: gauge
    - component: oh-data-series
      config:
        axisLabel:
          show: false
        axisLine:
          lineStyle:
            color:
              - - 1
                - =props.frameColor
            shadowBlur: 10
            shadowColor: "#0008"
            width: 8
          show: true
        axisTick:
          show: false
        detail:
          show: false
        endAngle: -270
        pointer:
          show: false
        radius: 75%
        splitLine:
          show: false
        title:
          show: false
        type: gauge
  tooltip:
    - component: oh-chart-tooltip
      config:
        show: true

Nice.
Thanks again.

FYI: I’ve updated the original widget so that it’s more stylable, and you can get it to look pretty close to this if you want to.

Thank you. The new “needle” splited into 2 parts looks very nice.

The new version lost tooltips as the entire widget is clickable.

You can turn that on and off in the configuration/props. If you turn off the “show chart”, the tooltips are back. There is a way to get both, but that only works with OH 4.3.0 and later, so I didn’t want to break the widget for all previous versions and didn’t use it. It it’s possible to have multiple versions of the same widget on the marketplace in the future, I can make a separate version from 4.3.0 and up where this is fixed.

Hi Nadar!

In the last version you released tooltips dows not work as the entire widget is clickable.

An option is an extra icon that one can click and open a page with Wind Details.

Something like the image below:

OH_Wind_Details

I know, and I’ve stated this in the previous post - and in the widget documentation. If you turn off Show Speed Chart, tooltips will work. You will have to choose between chart and tooltip at the moment.

There is a fix to this, but it only works from 4.3.0 and onwards. I don’t want to break the widget for older versions, so I’m holding back this fix. Alternatively I could make a second widget with a range from 4.3.0 only.

The third option is to make a separate button like your example, but I haven’t really considered that since there is a way to make both things work in the latest version of OH. If you can do without the chart, the tooltips are exactly like before.