Heating system UI widget

A UI for a heating system showing temperatures, electric heater status and pump status.

Screenshots

image

Resources

uid: heating_system
tags: []
props:
  parameters:
    - context: item
      label: Heater temperature
      name: heaterTemp
      required: false
      type: TEXT
    - context: item
      label: Heater in temperature
      name: heatingInTemp
      required: false
      type: TEXT
    - context: item
      label: Heating out temperature
      name: heatingOutTemp
      required: false
      type: TEXT
    - context: item
      label: Heating pump switch
      name: heatingPump
      required: false
      type: TEXT
    - context: item
      label: Water temperature
      name: waterTemp
      required: false
      type: TEXT
    - context: item
      label: Water in temperature
      name: waterInTemp
      required: false
      type: TEXT
    - context: item
      label: Water out temperature
      name: waterOutTemp
      required: false
      type: TEXT
    - context: item
      label: Water heater switch
      name: waterHeater
      required: false
      type: TEXT
    - context: item
      label: Water heater pump switch
      name: waterHeaterPump
      required: false
      type: TEXT
timestamp: Jan 4, 2025, 3:07:53 PM
component: f7-card
config:
  title: Heating System
slots:
  default:
    - component: f7-card-content
      config:
        style:
          height: 175px
      slots:
        default:
          - component: f7-row
            config:
              class:
                - display-flex
                - justify-content-center
                - align-items-center
              style:
                width: 100%
            slots:
              default:
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                    style:
                      height: 100%
                      width: 50px
                  slots:
                    default:
                      - component: Label
                        config:
                          text: '=items[props.heatingInTemp].displayState == "" ?
                            items[props.heatingInTemp].state :
                            items[props.heatingInTemp].displayState'
                      - component: f7-block
                        slots:
                          default:
                            - component: f7-col
                              slots:
                                default:
                                  - component: f7-col
                                    slots:
                                      default:
                                        - component: f7-row
                                          config:
                                            tag: svg
                                            viewBox: 0 0 50 110
                                            width: 50px
                                            xmlns: http://www.w3.org/2000/svg
                                          slots:
                                            default:
                                              - component: f7-row
                                                config:
                                                  d: M5 12 l20 0
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 5
                                                  tag: path
                                                  stroke-linecap: round
                                              - component: f7-row
                                                config:
                                                  d: M25 12 l20 0
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 5
                                                  tag: path
                                              - component: f7-row
                                                config:
                                                  d: M5 30 l20 0
                                                  fill: none
                                                  stroke: rgb(33, 150, 243)
                                                  stroke-width: 5
                                                  tag: path
                                                  stroke-linecap: round
                                              - component: f7-row
                                                config:
                                                  d: M25 30 l0 75
                                                  stroke-linecap: round
                                                  stroke: rgb(33, 150, 243)
                                                  stroke-width: 5
                                                  tag: path
                                              - component: f7-row
                                                config:
                                                  d: M25 105 l20 0
                                                  fill: none
                                                  stroke: rgb(33, 150, 243)
                                                  stroke-width: 5
                                                  tag: path
                                              - component: f7-row
                                                config:
                                                  fill: lightgray
                                                  r: 10
                                                  cx: 25
                                                  cy: 12
                                                  stroke-width: 2
                                                  tag: circle
                                                  stroke: rgb(230,74,25)
                                              - component: f7-row
                                                config:
                                                  d: M19 6 l12 12
                                                  fill: none
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 2
                                                  tag: path
                                                  id: heatingPump1
                                              - component: f7-row
                                                config:
                                                  d: M19 18 l12 -12
                                                  fill: none
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 2
                                                  tag: path
                                                  id: heatingPump2
                                              - component: f7-row
                                                config:
                                                  dur: 1
                                                  begin: 0
                                                  from: 0 25 12
                                                  to: 360 25 12
                                                  repeatCount: indefinite
                                                  tag: animateTransform
                                                  type: rotate
                                                  attributeName: transform
                                                  attributeType: XML
                                                  xlink:href: '=(items[props.heatingPump].state === "ON") ? "#heatingPump1" :
                                                    "#heatingPump1_disable"'
                                              - component: f7-row
                                                config:
                                                  dur: 1
                                                  begin: 0
                                                  from: 0 25 12
                                                  to: 360 25 12
                                                  repeatCount: indefinite
                                                  tag: animateTransform
                                                  type: rotate
                                                  attributeName: transform
                                                  attributeType: XML
                                                  xlink:href: '=(items[props.heatingPump].state === "ON") ? "#heatingPump2" :
                                                    "#heatingPump2_disable"'
                      - component: Label
                        config:
                          text: =items[props.heatingOutTemp].state
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                      - justify-content-space-evenly
                    style:
                      height: 100%
                      width: 90px
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - display-flex
                            - flex-direction-column
                            - align-items-center
                          style:
                            background: lightgray
                            border: 2pt solid rgb(230,74,25)
                            border-radius: 5px 5px 5px 5px
                            height: 150px
                            width: 90px
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-flex-end
                                  - align-items-center
                                  - flex-shrink-0
                                  - no-margin
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        font-weight: bold
                                        color: black
                                        padding-top: 10px
                                        padding-bottom: 20px
                                        white-space: nowrap
                                      text: '=items[props.heaterTemp].displayState == "" ?
                                        items[props.heaterTemp].state :
                                        items[props.heaterTemp].displayState'
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-center
                                  - align-items-center
                                style:
                                  border: '=(Number.parseFloat(items[props.heaterTemp].state) > 30) ? "4pt solid
                                    rgb(230,74,25)" : "4pt solid darkgray"'
                                  box-shadow: 0 0 10px 2px darkgray inset
                                  height: 70px
                                  margin-top: 7px
                                  width: 70px
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: flame_fill
                                      size: 50
                                      style:
                                        color: '=(Number.parseFloat(items[props.heaterTemp].state) > 30) ?
                                          "rgb(230,74,25)" : "darkgray"'
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                    style:
                      height: 100%
                      width: 50px
                  slots:
                    default:
                      - component: f7-col
                      - component: Label
                        config:
                          text: '=items[props.waterInTemp].displayState == "" ?
                            items[props.waterInTemp].state :
                            items[props.waterInTemp].displayState'
                          config:
                            padding-bootom: 20px
                      - component: f7-block
                        slots:
                          default:
                            - component: f7-col
                              slots:
                                default:
                                  - component: f7-row
                                    config:
                                      tag: svg
                                      viewBox: 0 0 50 110
                                      width: 50px
                                      xmlns: http://www.w3.org/2000/svg
                                    slots:
                                      default:
                                        - component: f7-row
                                          config:
                                            d: M5 11 l40 0
                                            fill: none
                                            stroke: rgb(230,74,25)
                                            stroke-width: 5
                                            tag: path
                                            vector-effect: non-scaling-stroke
                                        - component: f7-row
                                          config:
                                            fill: lightgray
                                            stroke: rgb(230,74,25)
                                            r: 10
                                            cx: 25
                                            cy: 12
                                            stroke-width: 2
                                            tag: circle
                                        - component: f7-row
                                          config:
                                            d: M19 6 l12 12
                                            fill: none
                                            stroke: rgb(230,74,25)
                                            stroke-width: 2
                                            tag: path
                                            id: waterHeaterPump1
                                        - component: f7-row
                                          config:
                                            d: M19 18 l12 -12
                                            fill: none
                                            stroke: rgb(230,74,25)
                                            stroke-width: 2
                                            tag: path
                                            id: waterHeaterPump2
                                        - component: f7-row
                                          config:
                                            dur: 1
                                            begin: 0
                                            from: 0 25 12
                                            to: 360 25 12
                                            repeatCount: indefinite
                                            tag: animateTransform
                                            type: rotate
                                            attributeName: transform
                                            attributeType: XML
                                            xlink:href: '=items[props.waterHeaterPump].state === "ON" ? "#waterHeaterPump1"
                                              : "#waterHeaterPump1_disable"'
                                        - component: f7-row
                                          config:
                                            dur: 1
                                            begin: 0
                                            from: 0 25 12
                                            to: 360 25 12
                                            repeatCount: indefinite
                                            tag: animateTransform
                                            type: rotate
                                            attributeName: transform
                                            attributeType: XML
                                            xlink:href: '=items[props.waterHeaterPump].state === "ON" ? "#waterHeaterPump2"
                                              : "#waterHeaterPump2_disable"'
                                        - component: f7-row
                                          config:
                                            d: M5 105 l40 0
                                            fill: none
                                            stroke: rgb(33, 150, 243)
                                            stroke-width: 5
                                            tag: path
                      - component: Label
                        config:
                          text: '=items[props.waterOutTemp].displayState == "" ?
                            items[props.waterOutTemp].state :
                            items[props.waterOutTemp].displayState'
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                      - justify-content-space-evenly
                    style:
                      height: 100%
                      width: 60px
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - display-flex
                            - flex-direction-column
                            - align-items-center
                          style:
                            border: 2pt solid rgb(33, 150, 243)
                            background: lightgray
                            box-shadow: 0 0 10px 2px darkgray inset
                            border-radius: 5px 5px 5px 5px
                            height: 150px
                            width: 60px
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-flex-end
                                  - align-items-center
                                  - flex-shrink-0
                                  - no-margin
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        font-weight: bold
                                        color: black
                                        padding-top: 10px
                                        padding-bottom: 10px
                                        white-space: nowrap
                                      text: '=items[props.waterTemp].displayState == "" ? items[props.waterTemp].state
                                        : items[props.waterTemp].displayState'
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-center
                                  - align-items-center
                                style:
                                  height: 80px
                                  margin-top: 7px
                                  width: 70px
                              slots:
                                default:
                                  - component: f7-col
                                    slots:
                                      default:
                                        - component: f7-icon
                                          config:
                                            f7: '=(items[props.waterHeater].state === "ON") ? "bolt_circle_fill" :
                                              "drop_fill"'
                                            size: 50
                                            style:
                                              color: '=(Number.parseFloat(items[props.waterTemp].state) > 40) ?
                                                "rgb(230,74,25)" : "rgb(33, 150,
                                                243)"'
                                        - component: f7-icon
                                          config:
                                            f7: '=(items[props.waterHeater].state == "ON") ? "bolt_circle_fill" :
                                              "bolt_slash"'
                                            size: 50
                                            style:
                                              color: '=(items[props.waterHeater].state === "ON") ? "rgb(33, 150, 243)" :
                                                "darkgray"'
1 Like

Thanks for your widget, looks good.
Had an isue with heatingOutTemp, where you did not check for displayState

In General, you can simplify your temperature label from

                      - component: Label
                        config:
                          text: '=items[props.heatingInTemp].displayState == "" ?
                            items[props.heatingInTemp].state :
                            items[props.heatingInTemp].displayState'

to

                      - component: Label
                        config:
                          text: =@(props.heatingInTemp)

It will first check for existing displayState and use state as fallback.

2 Likes

Thanks @hmerk That is a great tip. Here is v2 with this used:

uid: heating_system_v2
tags: []
props:
  parameters:
    - context: item
      label: Heater temperature
      name: heaterTemp
      required: false
      type: TEXT
    - context: item
      label: Heater in temperature
      name: heatingInTemp
      required: false
      type: TEXT
    - context: item
      label: Heating out temperature
      name: heatingOutTemp
      required: false
      type: TEXT
    - context: item
      label: Heating pump switch
      name: heatingPump
      required: false
      type: TEXT
    - context: item
      label: Water temperature
      name: waterTemp
      required: false
      type: TEXT
    - context: item
      label: Water in temperature
      name: waterInTemp
      required: false
      type: TEXT
    - context: item
      label: Water out temperature
      name: waterOutTemp
      required: false
      type: TEXT
    - context: item
      label: Water heater switch
      name: waterHeater
      required: false
      type: TEXT
    - context: item
      label: Water heater pump switch
      name: waterHeaterPump
      required: false
      type: TEXT
timestamp: Jan 5, 2025, 8:40:43 AM
component: f7-card
config:
  title: Heating System
slots:
  default:
    - component: f7-card-content
      config:
        style:
          height: 175px
      slots:
        default:
          - component: f7-row
            config:
              class:
                - display-flex
                - justify-content-center
                - align-items-center
              style:
                width: 100%
            slots:
              default:
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                    style:
                      height: 100%
                      width: 50px
                  slots:
                    default:
                      - component: Label
                        config:
                          text: =@(props.heatingInTemp)
                      - component: f7-block
                        slots:
                          default:
                            - component: f7-col
                              slots:
                                default:
                                  - component: f7-col
                                    slots:
                                      default:
                                        - component: f7-row
                                          config:
                                            tag: svg
                                            viewBox: 0 0 50 110
                                            width: 50px
                                            xmlns: http://www.w3.org/2000/svg
                                          slots:
                                            default:
                                              - component: f7-row
                                                config:
                                                  d: M5 12 l20 0
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 5
                                                  tag: path
                                                  stroke-linecap: round
                                              - component: f7-row
                                                config:
                                                  d: M25 12 l20 0
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 5
                                                  tag: path
                                              - component: f7-row
                                                config:
                                                  d: M5 30 l20 0
                                                  fill: none
                                                  stroke: rgb(33, 150, 243)
                                                  stroke-width: 5
                                                  tag: path
                                                  stroke-linecap: round
                                              - component: f7-row
                                                config:
                                                  d: M25 30 l0 75
                                                  stroke-linecap: round
                                                  stroke: rgb(33, 150, 243)
                                                  stroke-width: 5
                                                  tag: path
                                              - component: f7-row
                                                config:
                                                  d: M25 105 l20 0
                                                  fill: none
                                                  stroke: rgb(33, 150, 243)
                                                  stroke-width: 5
                                                  tag: path
                                              - component: f7-row
                                                config:
                                                  fill: lightgray
                                                  r: 10
                                                  cx: 25
                                                  cy: 12
                                                  stroke-width: 2
                                                  tag: circle
                                                  stroke: rgb(230,74,25)
                                              - component: f7-row
                                                config:
                                                  d: M19 6 l12 12
                                                  fill: none
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 2
                                                  tag: path
                                                  id: heatingPump1
                                              - component: f7-row
                                                config:
                                                  d: M19 18 l12 -12
                                                  fill: none
                                                  stroke: rgb(230,74,25)
                                                  stroke-width: 2
                                                  tag: path
                                                  id: heatingPump2
                                              - component: f7-row
                                                config:
                                                  dur: 1
                                                  begin: 0
                                                  from: 0 25 12
                                                  to: 360 25 12
                                                  repeatCount: indefinite
                                                  tag: animateTransform
                                                  type: rotate
                                                  attributeName: transform
                                                  attributeType: XML
                                                  xlink:href: '=(items[props.heatingPump].state === "ON") ? "#heatingPump1" :
                                                    "#heatingPump1_disable"'
                                              - component: f7-row
                                                config:
                                                  dur: 1
                                                  begin: 0
                                                  from: 0 25 12
                                                  to: 360 25 12
                                                  repeatCount: indefinite
                                                  tag: animateTransform
                                                  type: rotate
                                                  attributeName: transform
                                                  attributeType: XML
                                                  xlink:href: '=(items[props.heatingPump].state === "ON") ? "#heatingPump2" :
                                                    "#heatingPump2_disable"'
                      - component: Label
                        config:
                          text: =@(props.heatingOutTemp)
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                      - justify-content-space-evenly
                    style:
                      height: 100%
                      width: 90px
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - display-flex
                            - flex-direction-column
                            - align-items-center
                          style:
                            background: lightgray
                            border: 2pt solid rgb(230,74,25)
                            border-radius: 5px 5px 5px 5px
                            height: 150px
                            width: 90px
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-flex-end
                                  - align-items-center
                                  - flex-shrink-0
                                  - no-margin
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        font-weight: bold
                                        color: black
                                        padding-top: 10px
                                        padding-bottom: 20px
                                        white-space: nowrap
                                      text: =@(props.heaterTemp)
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-center
                                  - align-items-center
                                style:
                                  border: '=(Number.parseFloat(items[props.heaterTemp].state) > 30) ? "4pt solid
                                    rgb(230,74,25)" : "4pt solid darkgray"'
                                  box-shadow: 0 0 10px 2px darkgray inset
                                  height: 70px
                                  margin-top: 7px
                                  width: 70px
                              slots:
                                default:
                                  - component: f7-icon
                                    config:
                                      f7: flame_fill
                                      size: 50
                                      style:
                                        color: '=(Number.parseFloat(items[props.heaterTemp].state) > 30) ?
                                          "rgb(230,74,25)" : "darkgray"'
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                    style:
                      height: 100%
                      width: 50px
                  slots:
                    default:
                      - component: f7-col
                      - component: Label
                        config:
                          text: =@(props.waterInTemp)
                          config:
                            padding-bootom: 20px
                      - component: f7-block
                        slots:
                          default:
                            - component: f7-col
                              slots:
                                default:
                                  - component: f7-row
                                    config:
                                      tag: svg
                                      viewBox: 0 0 50 110
                                      width: 50px
                                      xmlns: http://www.w3.org/2000/svg
                                    slots:
                                      default:
                                        - component: f7-row
                                          config:
                                            d: M5 11 l40 0
                                            fill: none
                                            stroke: rgb(230,74,25)
                                            stroke-width: 5
                                            tag: path
                                            vector-effect: non-scaling-stroke
                                        - component: f7-row
                                          config:
                                            fill: lightgray
                                            stroke: rgb(230,74,25)
                                            r: 10
                                            cx: 25
                                            cy: 12
                                            stroke-width: 2
                                            tag: circle
                                        - component: f7-row
                                          config:
                                            d: M19 6 l12 12
                                            fill: none
                                            stroke: rgb(230,74,25)
                                            stroke-width: 2
                                            tag: path
                                            id: waterHeaterPump1
                                        - component: f7-row
                                          config:
                                            d: M19 18 l12 -12
                                            fill: none
                                            stroke: rgb(230,74,25)
                                            stroke-width: 2
                                            tag: path
                                            id: waterHeaterPump2
                                        - component: f7-row
                                          config:
                                            dur: 1
                                            begin: 0
                                            from: 0 25 12
                                            to: 360 25 12
                                            repeatCount: indefinite
                                            tag: animateTransform
                                            type: rotate
                                            attributeName: transform
                                            attributeType: XML
                                            xlink:href: '=items[props.waterHeaterPump].state === "ON" ? "#waterHeaterPump1"
                                              : "#waterHeaterPump1_disable"'
                                        - component: f7-row
                                          config:
                                            dur: 1
                                            begin: 0
                                            from: 0 25 12
                                            to: 360 25 12
                                            repeatCount: indefinite
                                            tag: animateTransform
                                            type: rotate
                                            attributeName: transform
                                            attributeType: XML
                                            xlink:href: '=items[props.waterHeaterPump].state === "ON" ? "#waterHeaterPump2"
                                              : "#waterHeaterPump2_disable"'
                                        - component: f7-row
                                          config:
                                            d: M5 105 l40 0
                                            fill: none
                                            stroke: rgb(33, 150, 243)
                                            stroke-width: 5
                                            tag: path
                      - component: Label
                        config:
                          text: =@(props.waterOutTemp)
                - component: f7-col
                  config:
                    class:
                      - display-flex
                      - flex-direction-column
                      - align-items-center
                      - justify-content-space-evenly
                    style:
                      height: 100%
                      width: 60px
                  slots:
                    default:
                      - component: f7-col
                        config:
                          class:
                            - display-flex
                            - flex-direction-column
                            - align-items-center
                          style:
                            border: 2pt solid rgb(33, 150, 243)
                            background: lightgray
                            box-shadow: 0 0 10px 2px darkgray inset
                            border-radius: 5px 5px 5px 5px
                            height: 150px
                            width: 60px
                        slots:
                          default:
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-flex-end
                                  - align-items-center
                                  - flex-shrink-0
                                  - no-margin
                              slots:
                                default:
                                  - component: Label
                                    config:
                                      style:
                                        font-weight: bold
                                        color: black
                                        padding-top: 10px
                                        padding-bottom: 10px
                                        white-space: nowrap
                                      text: =@(props.waterTemp)
                            - component: f7-block
                              config:
                                class:
                                  - display-flex
                                  - justify-content-center
                                  - align-items-center
                                style:
                                  height: 80px
                                  margin-top: 7px
                                  width: 70px
                              slots:
                                default:
                                  - component: f7-col
                                    slots:
                                      default:
                                        - component: f7-icon
                                          config:
                                            f7: '=(items[props.waterHeater].state === "ON") ? "bolt_circle_fill" :
                                              "drop_fill"'
                                            size: 50
                                            style:
                                              color: '=(Number.parseFloat(items[props.waterTemp].state) > 40) ?
                                                "rgb(230,74,25)" : "rgb(33, 150,
                                                243)"'
                                        - component: f7-icon
                                          config:
                                            f7: '=(items[props.waterHeater].state == "ON") ? "bolt_circle_fill" :
                                              "bolt_slash"'
                                            size: 50
                                            style:
                                              color: '=(items[props.waterHeater].state === "ON") ? "rgb(33, 150, 243)" :
                                                "darkgray"'