JKBMS UI widget (4s to 16s)

Widget_JKBMS_16S

Widget to visualize a LFP Batterypack, in my case I use JKBMS for my Batterypacks. The data are collected via the Sissi Project, which establish a communicate between a ESp32 and a JK BMS via UART-TTL or BLE found here:

The widget visualize, based on the cell count delivered from the BMS, the rows with the values for each cell

Screenshots

Example for a 8s Batterypack (disabled switches for Balance, Charge and Discharge)

Widget_JKBMS_8S

Settings

Settings are now prefilled with default values.

to enable the switches for Balance, Charge and Discharge enter in the settings “true” in lower cases

Changelog

Version 2

  • Adjustments in the settings, they are now prefilled with default values
  • added possibility to set another fontcolor

Version 1

  • initial release

Resources

widget

uid: JKBMS_V2
tags:

  • JKBMS
  • Sissi ESPHome JK BMS
  • VenusOS
    props:
    parameters:
    • default: Batterypack_1
      description: First part of the Battery Items (e.g. Batterypack_1)
      label: Batterypack thingname
      name: battery
      required: true
      type: TEXT
    • default: Batterypackname
      description: Name of the battery pack
      label: Batterypack Name
      name: batterypackname
      required: true
      type: TEXT
    • default: “false”
      description: manageable via OH
      label: allow to edit the JKBMS, Default is false
      name: batterymanageable
      required: true
      type: BOOLEAN
      advanced: true
    • default: lime
      description: fontcolor
      label: allow to set another fontcolor
      name: widgetfonttext
      required: false
      type: TEXT
      advanced: true
      parameterGroups:
      timestamp: Sep 25, 2025, 3:38:34 PM
      component: f7-card
      config:
      backdrop: true
      class:
    • card-expandable-animate-width
    • card-outline
      expandable: true
      hideStatusbarOnOpen: true
      style:
      –f7-card-outline-border-color: “‘gray’ : ‘’”
      //box-shadow: var(–f7-card-expandable-box-shadow)
      background-color: rgba(18,18,18,0.75)
      height: =((Number.parseInt(items[props.battery+“_Cellcount”].state) / 4 *
      62)+225) +‘px’
      margin-bottom: -25px
      margin-left: 0px
      margin-right: 0px
      margin-top: 0px
      width: auto
      swipeToClose: true
      slots:
      default:
    • component: f7-card-content
      config:
      style:
      width: 100%
      slots:
      default:
      • component: f7-row
        config:
        class:
      • display-flex
      • flex-direction-row
      • justify-content-flex-end
      • align-items-baseline
        style:
        height: 0px
        width: 100%
      • component: f7-block
        config:
        style:
        height: 100px
        margin-top: -12px
        slots:
        default:
      • component: f7-row
        config:
        class:
      • display-flex
      • align-items-center
      • justify-content-space-between
      • card-prevent-open
        style:
        flex-wrap: nowrap
        height: 60px
        weight: 100%
        white-space: nowrap
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 23px
        font-weight: 400
        text: =props.batterypackname
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Battery Pack
      • component: f7-row
        config:
        class:
      • display-flex
      • align-items-center
      • justify-content-space-between
      • card-prevent-open
        style:
        flex-wrap: nowrap
        height: 60px
        weight: 100%
        white-space: nowrap
        visible: “=props.batterymanageable === true? true : false”
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: oh-button
        config:
        action: toggle
        actionCommand: ON
        actionCommandAlt: OFF
        actionItem: =[props.battery+“_AllowToBalance”]
        fill: ‘=items[props.battery+“_AllowToBalance”].state === “ON” ? true : false’
        margin-top: -9px
        outline: true
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_AllowToBalance”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Balance
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: oh-button
        config:
        action: toggle
        actionCommand: ON
        actionCommandAlt: OFF
        actionItem: =[props.battery+“_AllowToCharge”]
        fill: ‘=items[props.battery+“_AllowToCharge”].state === “ON” ? true : false’
        margin-top: -9px
        outline: true
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 17px
        font-weight: 400
        text: =items[props.battery+“_AllowToCharge”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Charge
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: oh-button
        config:
        action: toggle
        actionCommand: ON
        actionCommandAlt: OFF
        actionItem: =[props.battery+“_AllowToDischarge”]
        fill: ‘=items[props.battery+“_AllowToDischarge”].state === “ON” ? true : false’
        margin-top: -9px
        outline: true
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 17px
        font-weight: 400
        text: =items[props.battery+“_AllowToDischarge”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Discharge
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 17px
        font-weight: 400
        text: =items[props.battery+“_Mosfet”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Mosfet
      • component: f7-row
        config:
        class:
      • display-flex
      • align-items-center
      • justify-content-space-between
      • card-prevent-open
        style:
        flex-wrap: nowrap
        height: 60px
        weight: 100%
        white-space: nowrap
        visible: “=props.batterymanageable === true? false : true”
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_AllowToBalance”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Balance
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_AllowToCharge”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Charge
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_AllowToDischarge”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Discharge
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_Mosfet”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Mosfet
      • component: f7-row
        config:
        class:
      • display-flex
      • align-items-center
      • justify-content-space-between
      • card-prevent-open
        style:
        flex-wrap: nowrap
        height: 60px
        weight: 100%
        white-space: nowrap
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_Power”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Power
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_Current”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Current
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_Balancing”].state
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Balancing
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_CapacityRemaining”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Capacity
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_BatTemperature”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Battery
      • component: f7-row
        config:
        class:
      • display-flex
      • align-items-center
      • justify-content-space-between
      • card-prevent-open
        style:
        flex-wrap: nowrap
        height: 60px
        weight: 100%
        white-space: nowrap
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_Voltage”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Voltage
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_MinCellVoltage”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: ‘= “Min: " + items[props.battery+”_CellLow"].state’
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_CelDiff”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: Diff
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_MaxCellVoltage”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: ‘= “Max: " + items[props.battery+”_CellHigh"].state’
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        margin-top: -9px
        style:
        class:
      • text-align-center
        color: =props.widgetfonttext
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_SoC”].displayState
      • component: Label
        config:
        style:
        color: =props.widgetfonttext
        font-size: 12px
        font-weight: 600
        text: SoC
      • component: f7-row
        config:
        class:
      • display-flex
      • flex-direction-row
      • justify-content-space-around
      • card-prevent-open
        style:
        height: 60px
        width: 100%
        visible: “=items.Battery_Cellcount.state >= 4 ? true : false”
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘1’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘1’) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+“_C1”].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘1’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘1’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 1
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘2’) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘2’) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C2’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘2’) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘2’) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 2
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘3’) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘3’) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C3’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘3’) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘3’) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 3
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘4’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘4’) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C4’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘4’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘4’) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 4
      • component: f7-row
        config:
        class:
      • display-flex
      • flex-direction-row
      • justify-content-space-around
      • card-prevent-open
        style:
        height: 60px
        width: 100%
        visible: “=items[props.battery+‘_Cellcount’].state >= 8 ? true : false”
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘5’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘5’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C5’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘5’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘5’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 5
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘6’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘6’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C6’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘6’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘6’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 6
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘7’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘7’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C7’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘7’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘7’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 7
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘8’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘8’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C8’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘8’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘8’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 8
      • component: f7-row
        config:
        class:
      • display-flex
      • flex-direction-row
      • justify-content-space-around
      • card-prevent-open
        style:
        height: 60px
        width: 100%
        visible: “=items[props.battery+‘_Cellcount’].state >= 12 ? true : false”
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘9’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘9’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C9’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘9’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘9’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 9
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘10’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘10’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C10’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘10’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘10’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 10
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘11’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘11’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items.Battery_C11.displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘11’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘11’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 11
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘12’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘12’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C12’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘12’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘12’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 12
      • component: f7-row
        config:
        class:
      • display-flex
      • flex-direction-row
      • justify-content-space-around
      • card-prevent-open
        style:
        height: 60px
        width: 100%
        visible: “=items[props.battery+‘_Cellcount’].state >= 16 ? true : false”
        slots:
        default:
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: -9px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘13’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘13’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C13’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘13’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘13’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 13
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘14’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘14’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 400
        text: =items[props.battery+‘_C14’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘14’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘14’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 14
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘15’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘15’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 600
        text: =items[props.battery+‘_C15’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘15’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘15’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 15
      • component: f7-col
        config:
        class:
      • display-flex
      • flex-direction-column
      • text-align-center
        style:
        margin-top: -9px
        slots:
        default:
      • component: Label
        config:
        class:
      • text-align-center
        margin-top: px
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘16’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘16’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 18px
        font-weight: 600
        text: =items[props.battery+‘_C16’].displayState
      • component: Label
        config:
        style:
        color: “=(items[props.battery+‘_CellHigh’].state === ‘16’ ) ? ‘#8bbcf7’ :
        (items[props.battery+‘_CellLow’].state ===
        ‘16’ ) ? ‘red’ : props.widgetfonttext”
        font-size: 12px
        font-weight: 600
        text: Cell 16

In the thing-file add the ip-address of your MQTT broker, replace “Batterypack_1” with your thing name (this name will be used in the widget settings) and search and replace “jk-bms-ruby” with your definition from the esphome project

The thing file create a MQTT bridge called batterypack

save this as a thing file in openhab

(location: /srv/openhab-conf/things)

Thing file

Bridge mqtt:broker:batterypack “MQTT Battery Broker” [
host=“IP-Address”,
port=1883,
clientID=“BatteryPacks”
] {
Thing topic Batterypack_1PV Battery Pack Ruby” {
Channels:
Type number : cell1 “Cell 1 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_1/state” ]
Type number : cell2 “Cell 2 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_2/state” ]
Type number : cell3 “Cell 3 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_3/state” ]
Type number : cell4 “Cell 4 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_4/state” ]
Type number : cell5 “Cell 5 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_5/state” ]
Type number : cell6 “Cell 6 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_6/state” ]
Type number : cell7 “Cell 7 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_7/state” ]
Type number : cell8 “Cell 8 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_8/state” ]
Type number : cell9 “Cell 9 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_9/state” ]
Type number : cell10 “Cell 10 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_10/state” ]
Type number : cell11 “Cell 11 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_11/state” ]
Type number : cell12 “Cell 12 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_12/state” ]
Type number : cell13 “Cell 13 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_13/state” ]
Type number : cell14 “Cell 14 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_14/state” ]
Type number : cell15 “Cell 15 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_15/state” ]
Type number : cell16 “Cell 16 Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_cell_voltage_16/state” ]
Type number : Mosfet “Mosfet Temperature” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_power_tube_temperature/state” ]
Type number : Cell_Diff “Cell Difference” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_delta_cell_voltage/state” ]
Type number : BatVoltage “Cell Voltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_total_voltage/state” ]
Type number : Cellcount “Cell Count” [ stateTopic=“jk-bms-ruby/number/jk-bms-ruby_cell_count/state” ]
Type string : CellLow “Cell ID Low” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_min_voltage_cell/state” ]
Type string : CellHigh “Cell ID High” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_max_voltage_cell/state” ]
Type number : Capacity “Capacity” [ stateTopic=“jk-bms-ruby/number/jk-bms-ruby_total_battery_capacity/state” ]
Type number : BatTemperature “MaxCellTemperature” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_temperature_sensor_1/state” ]
Type number : MinCellVoltage “MinCellVoltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_min_cell_voltage/state” ]
Type number : MaxCellVoltage “MaxCellVoltage” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_max_cell_voltage/state” ]
Type number : Balancing “Balancing” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_balancing/state” ]
Type number : InstalledCapacity “InstalledCapacity” [ stateTopic=“jk-bms-ruby/number/jk-bms-ruby_total_battery_capacity/state” ]
Type number : Balancing “Balancing” [ stateTopic=“jk-bms-ruby/binary_sensor/jk-bms-ruby_balancing/state” ]
Type number : SoC “State of Charge” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_state_of_charge/state” ]
Type number : Current “Current A” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_current/state” ]
Type number : Power “Power in W” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_power/state” ]
Type switch : AllowToCharge “AllowToCharge” [ commandTopic=“jk-bms-ruby/switch/jk-bms-ruby_charging/state”, stateTopic=“jk-bms-ruby/switch/jk-bms-ruby_charging/state” ]
Type switch : AllowToDischarge “AllowToDischarge” [ commandTopic=“jk-bms-ruby/switch/jk-bms-ruby_discharging/state”, stateTopic=“jk-bms-ruby/switch/jk-bms-ruby_discharging/state” ]
Type switch : AllowToBalance “AllowToBalance” [ commandTopic=“jk-bms-ruby/switch/jk-bms-ruby_balancer/state”, stateTopic=“jk-bms-ruby/switch/jk-bms-ruby_balancer/state” ]
Type number : CapacityRemaining “Capacity Remaining” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_capacity_remaining/state” ]
Type number : ChargingPower “Charging Power” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_charging_power/state” ]
Type number : DischargingPower “Discharging Power” [ stateTopic=“jk-bms-ruby/sensor/jk-bms-ruby_discharging_power/state” ]

}

}

in the item file below replace “Batterypack_1” with your thing name and save this as a item file

(location: /srv/openhab-conf/items)

Item file

Number Batterypack_1_C1 “Zelle 1 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell1” }
Number Batterypack_1_C2 “Zelle 2 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell2” }
Number Batterypack_1_C3 “Zelle 3 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell3” }
Number Batterypack_1_C4 “Zelle 4 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell4” }
Number Batterypack_1_C5 “Zelle 5 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell5” }
Number Batterypack_1_C6 “Zelle 6 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell6” }
Number Batterypack_1_C7 “Zelle 7 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell7” }
Number Batterypack_1_C8 “Zelle 8 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell8” }
Number Batterypack_1_C9 “Zelle 9 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell9” }
Number Batterypack_1_C10 “Zelle 10 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell10” }
Number Batterypack_1_C11 “Zelle 11 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell11” }
Number Batterypack_1_C12 “Zelle 12 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell12” }
Number Batterypack_1_C13 “Zelle 13 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell13” }
Number Batterypack_1_C14 “Zelle 14 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell14” }
Number Batterypack_1_C15 “Zelle 15 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell15” }
Number Batterypack_1_C16 “Zelle 16 [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:cell16” }
Number Batterypack_1_Voltage “Voltage [%.2f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:BatVoltage” }
Number Batterypack_1_Mosfet “Mosfet Temperature [%.1f °C]” { channel=“mqtt:topic:batterypack:Batterypack_1:Mosfet” }
Number Batterypack_1_CelDiff “Cell Difference [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:Cell_Diff” }
Number Batterypack_1_Cellcount “NrOfCellsPerBattery” { channel=“mqtt:topic:batterypack:Batterypack_1:Cellcount” }
Number Batterypack_1_BatTemperature “Battery Temperature [%.1f °C]” { channel=“mqtt:topic:batterypack:Batterypack_1:BatTemperature” }
String Batterypack_1_CellLow “Cell ID Low” { channel=“mqtt:topic:batterypack:Batterypack_1:CellLow” }
String Batterypack_1_CellHigh “Cell ID High” { channel=“mqtt:topic:batterypack:Batterypack_1:CellHigh” }
Number Batterypack_1_Capacity “Capacity [%.2f Ah]” { channel=“mqtt:topic:batterypack:Batterypack_1:Capacity” }
Number Batterypack_1_MaxCellVoltage “Voltage [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:MaxCellVoltage” }
Number Batterypack_1_MinCellVoltage “Voltage [%.3f V]” { channel=“mqtt:topic:batterypack:Batterypack_1:MinCellVoltage” }
String Batterypack_1_CustomeName “CustomName” { channel=“mqtt:topic:batterypack:Batterypack_1:CustomName” }
Number Batterypack_1_installedCapacity “Capacity” { channel=“mqtt:topic:batterypack:Batterypack_1:InstalledCapacity” }
Number Batterypack_1_Balancing “Balancing” { channel=“mqtt:topic:batterypack:Batterypack_1:Balancing” }
Switch Batterypack_1_AllowToCharge “AllowToCharge” { channel=“mqtt:topic:batterypack:Batterypack_1:AllowToCharge” }
Switch Batterypack_1_AllowToDischarge “AllowToDischarge” { channel=“mqtt:topic:batterypack:Batterypack_1:AllowToDischarge” }
Switch Batterypack_1_AllowToBalance “AllowToBalance” { channel=“mqtt:topic:batterypack:Batterypack_1:AllowToBalance” }
Number Batterypack_1_SoC “State of Charge [%.1f %%]” { channel=“mqtt:topic:batterypack:Batterypack_1:SoC” }
Number Batterypack_1_Current “Current [%.2f A]” { channel=“mqtt:topic:batterypack:Batterypack_1:Current” }
Number Batterypack_1_Power “Power [%.1f W]” { channel=“mqtt:topic:batterypack:Batterypack_1:Power” }
Number Batterypack_1_CapacityRemaining “Remaining [%.2f Ah]” { channel=“mqtt:topic:batterypack:Batterypack_1:CapacityRemaining” }
Number Batterypack_1_ChargingPower “Power [%.1f W]” { channel=“mqtt:topic:batterypack:Batterypack_1:ChargingPower” }
Number Batterypack_1_DischargingPower “Discharging Power [%.1f W]” { channel=“mqtt:topic:batterypack:Batterypack_1:DischargingPower” }
Switch Batterypack_1_Balancing “Balancing” { channel=“mqtt:topic:batterpack:Batterypack_1:Balancing” }