MQTT whirlpool control

Hello,

i want to control my whirlpool with mqtt and this project

I need 3 types of channels. 1. Read out value. I managed that. 2. value control and the current display. it can be controlled, but it does not read out the current value of the device, it only remembers what is controlled in openhab. 3. Set a value and display the current one. I can’t do that at all.
the mqtt commands are available at https://github.com/visualapproach/WiFi-remote-for-Bestway-Lay-Z-SPA/blob/master/Build-instructions-Bestway-WiFi-remote.pdf
described. can someone tell me how I can create this in the GUI?

Do you have a tool like mqtt.fx or mqtt spy? Just to get real data…

Yes. The string from e.g. “message” is:

{“CONTENT”:“STATES”,“LCK”:1,“PWR”:1,“UNT”:1,“AIR”:0,“GRN”:0,“RED”:0,“FLT”:1,“TGT”:30,“TMP”:24,“CH1”:32,“CH2”:50,“CH3”:52,“HJT”:1}

So you can get all informations to different Items by using JSONPATH transformation (i.e. define one channel with stateTopic BW_2.0.0/message

You need to build a Number Item for each value, then connect the Items to the channel and add a profile JSONPATH transformation with the key word, e.g. $.AIR for the bubbles.
You could also use the JSONPATH transformation within the channel, but you have to create more channels with the same stateTopic then.

{
    "CONTENT": "STATES",
    "LCK": 1,
    "PWR": 1,
    "UNT": 1,
    "AIR": 0,
    "GRN": 0,
    "RED": 0,
    "FLT": 1,
    "TGT": 30,
    "TMP": 24,
    "CH1": 32,
    "CH2": 50,
    "CH3": 52,
    "HJT": 1
}

HJT is not mentioned in the documentation.
This is the input part.:slight_smile:
For commands, I think it will be necessary to build a rule to create the JSON object.

The commands look a little tricky here. What I would do for BUBBLES, for example:

  • Create a Channel with the following settings:
    • Identifier: sSpaBubbles
    • Label: Spa Bubbles
    • Channel type: On/Off Switch
    • MQTT State Topic: BW_2.0.0/message
    • MQTT Command Topic: BW_2.0.0/command
    • Custom On/Open Value: 1
    • Custom Off/Closed Value: 0
    • Incoming Value Transformation: JSONPATH:$.AIR
    • Outgoing Value Format: {"CMD":2,"VALUE":%s,"XTIME":0,"INTERVAL":0}
The above, but in YAML in the UI
channels:
  - id: sSpaBubbles
    channelTypeUID: mqtt:switch
    label: Spa Bubbles
    description: ""
    configuration:
      commandTopic: BW_2.0.0/command
      formatBeforePublish: '{"CMD":2,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: BW_2.0.0/message
      transformationPattern: JSONPATH:$.AIR
      off: "0"
      on: "1"

The %s in the Outgoing Value Format is automatically filled in with ON or OFF once linked to a switch, and this is in turn transformed to either 1 or 0 respectively.

Note that it’s not quite clear to me whether CMD and VALUE and XTIME and INTERVAL need the double quote marks around it - the documentation doesn’t specify, but because the message string includes double quotes around the keys I’ve done the same!

You then link the Channel to an Switch Item of your creation.

With this:

  • When you flick the openHAB switch, openHAB will send the following to BW_2.0.0/command when flicking the switch ON:
{"CMD":2,"VALUE":1,"XTIME":0,"INTERVAL":0}

image

  • When you flick the openHAB switch, openHAB will send the following to BW_2.0.0/command when flicking the switch OFF:
{"CMD":2,"VALUE":0,"XTIME":0,"INTERVAL":0}

image

  • When your device sends the message, the openHAB switch will be updated with the current state of the air bubbles through the AIR value in the message.

This should get you going for now!

wow, thank you both! i’m testing this tonight after work. how can I then e.g. set a certain temperature?

EDIT: Now it works. I change the row in the code format “formatBeforePublish:” and now it looks like this:

But how can I send commands with numbers to set the temperature?

Now I tested your, but it sends only 1 or 0 to the MQTT device with this settings (I tested it with the pump):

2

As you’ve found, you used the wrong field for the JSON string.

It works now =) see the post further up.

The only thing missing now is to set the temperature with a number

Temperature is essentially the same deal, except use a Number Channel and Number Item instead. How you represent the Number Item in the UI is then up to you - maybe a slider?

Setting the temperature was really easy. Worked exactly like that. MANY THANKS. And yes, I installed it with a slider =)

I have one last think (I hope :D). The heater has two on states, RED for heating and GRN for standby, if the temperature is below the set temperature. How can I set this in “Incoming Value Transformation” ?

Edit: The absolute best where if the state is RED, the switch color is red and when the state us GRN the switch shows green =)

You will want a Switch Channel and Switch Item. Setup and configuration is the same as you’ve done before, but also add GRN into Custom Off/Closed Value and RED into Custom On/Open Value in the Switch Channel configuration.

I would recommend checking the documentation as you should now understand the basics of setting up MQTT stuff in openHAB.

This would be configured in whatever user interface you’re using. Check the documentation here.

I think you don’t understand what I want. GRN and RED are both on states. The documentation links are not helpful. I read that before I post here the first time, but I don’t unterstand it…. That’s the reason I asking for help here :frowning:
I use the basic ui.

You said:

which is as close as your going to get for ON and OFF. You also said:

which suggests you want a switch.

What I described is how to set this up with a Switch, as asked.

OK, perhaps try to explain it more clearly. Good luck!

Comment; multistate switch devices (off/low/med/high style) can be represented in openHAB as String type Items, where the string state is a selection of values.
An alternative is to represent by Number type (0-3 in our example) and MAP is a useful transformation to give numbers meaning.

I want to do the same project.
I use openHAB for a while but only with bindings so I am brand new to MQTT.
What I have so far is, I have my MQTT Server running and see the whirlpool device in MQTT explorer.
{“CONTENT”:“STATES”,“TIME”:1715346937,“LCK”:1,“PWR”:1,“UNT”:1,“AIR”:0,“GRN”:0,“RED”:1,“FLT”:1,“CH1”:32,“CH2”:51,“CH3”:50,“HJT”:0,“BRT”:8,“ERR”:0,“GOD”:0,“TGT”:32,“TMP”:32,“VTMC”:32.56245041,“VTMF”:90.6124115,“AMBC”:31,“AMBF”:88,“AMB”:31,“VTM”:32.56245041,“TGTC”:32,“TMPC”:32,“TGTF”:90,“TMPF”:90}

I installed the MQTT binding within openHAB.
What Things do I need to create to be able to create the channels which are already described in this thread?

I’ve got mine working with OpenHAB now and thought my config might be helpful for others.

There is one thing that’s bugging me, and I hope someone might have a better solution. Currently, I have two items to heat the tub: ‘Heater Red’ and ‘Heater Green.’ These indicate the state when the tub has reached temp and when it hasn’t. I would like this to be a single ‘Heater’ item that indicates red, green, or off. Any ideas? Thanks.

mqtt.things

    //Lay Z Spa Wifi  https://community.openhab.org/t/mqtt-whirlpool-control/124283/4
    Thing topic layZSpa "Hot Tub" @ "Outside" {
        Channels: 
            // Control
            Type number : actualTemperature  [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.TMPC" ]
            Type number : virtualTemperature [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.VTMC" ]
            Type number : targetTemperature  [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.TGTC", commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":0,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}" ]  
            Type number : ambientTemperature [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.AMBC", commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":15,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}" ]  
            Type number : brightness         [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.BRT",  commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":12,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}" ]  
            // Buttons
            Type switch : bubbles            [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.AIR",  commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":2,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}", on="1", off="0" ]  
            Type switch : heater             [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.RED", commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":3,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}", on="1", off="0" ]  
            Type switch : heater2            [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.GRN", commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":3,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}", on="1", off="0" ]  
            Type switch : pump               [ stateTopic="layzspa/message", transformationPattern="JSONPATH:$.FLT",  commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":4,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"openHAB\"}", on="1", off="0" ]  
            // Other
            Type number : beep               [ commandTopic="layzspa/command", formatBeforePublish="{\"CMD\":13,\"VALUE\":%s,\"XTIME\":0,\"INTERVAL\":0,\"TXT\":\"furelise.mel\"}" ]              
    }

mqtt.items

Group   LayZSpa               "Hot Tub"		   <water> 
Number  LayZSpaActualTemp     "Actual Temp [%.1f °C]"  <temperature> (LayZSpa,gPoolTemperatures)  { channel="mqtt:topic:mosquitto:layZSpa:actualTemperature"  }
Number  LayZSpaVirtualTemp    "Virtual Temp [%.1f °C]" <temperature> (LayZSpa,gPoolTemperatures)  { channel="mqtt:topic:mosquitto:layZSpa:virtualTemperature"  }
Number  LayZSpaTargetTemp     "Target Temp [%.1f °C]"  <temperature> (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:targetTemperature"  }
Number  LayZSpaAmbientTemp    "Ambient Temp [%.1f °C]" <temperature> (LayZSpa,gPoolTemperatures)  { channel="mqtt:topic:mosquitto:layZSpa:ambientTemperature" }
Number  LayZSpaBrightness     "Brightness [%s]"        <light>       (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:brightness" }
Switch  LayZSpaBubbles        "Bubbles"                <smoke>       (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:bubbles" }
Switch  LayZSpaHeater         "Heater Red"             <fire>        (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:heater" }
Switch  LayZSpaHeater2        "Heater Green"           <fire>        (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:heater2" }
Switch  LayZSpaPump           "Pump"                   <pump>        (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:pump" }
Number  LayZSpaBeep           "Beep [%s]"              <soundvolume> (LayZSpa)                    { channel="mqtt:topic:mosquitto:layZSpa:beep" }

default.sitemap

Frame label="Pump [%.1f °C]" item=LayZSpaActualTemp icon=pump {
	Text   item=LayZSpaActualTemp 	
	Text   item=LayZSpaVirtualTemp 	 
	Text   item=LayZSpaAmbientTemp //minValue=-40 maxValue=60 
	Setpoint item=LayZSpaTargetTemp  minValue=20  maxValue=40 step=1 
	Slider item=LayZSpaBrightness  minValue=0   maxValue=8 
	Switch item=LayZSpaBubbles	
	Switch item=LayZSpaHeater
	Switch item=LayZSpaHeater2	
	Switch item=LayZSpaPump	   
	Selection item=LayZSpaBeep mappings=[0=Beep,1=Chirp,3=Melody]	
}

Time for a dip :sweat_droplets::blush:

widget by Gemini

uid: whirlpool_control_v2
tags: []
props:
  parameters:
    - context: item
      description: Item für die Filtersteuerung (Switch)
      label: Filter Item
      name: filterItem
      required: true
      type: TEXT
    - context: item
      description: Item für die Heizungssteuerung (Switch)
      label: Heizung Item
      name: heatingItem
      required: true
      type: TEXT
    - context: item
      description: Item für die Blubbersteuerung (Switch)
      label: Blubber Item
      name: blubberItem
      required: true
      type: TEXT
    - context: item
      description: Item für die aktuelle Temperatur (Number:Temperature)
      label: Ist-Temperatur Item
      name: actualTempItem
      required: true
      type: TEXT
    - context: item
      description: Item für die Solltemperatur (Number:Temperature)
      label: Soll-Temperatur Item
      name: setpointTempItem
      required: true
      type: TEXT
    - context: item
      description: Item für die Pool Ein/Aus Steuerung (Switch)
      label: Pool Ein/Aus Item
      name: poolPowerItem
      required: true
      type: TEXT
    - context: item
      description: Item für roten Heizungsstatus (Switch)
      label: Rot Status Item
      name: redItem
      required: false
      type: TEXT
    - context: item
      description: Item für grünen Heizungsstatus (Switch)
      label: Grün Status Item
      name: greenItem
      required: false
      type: TEXT
    - context: item
      description: Item für die Zeit bis zur Solltemperatur (z.B. String oder Number)
      label: Zeit bis Aufgeheizt Item
      name: timeToHeatItem
      required: false
      type: TEXT
    - context: item
      description: Item für die Display Helligkeit (Number)
      label: Display Helligkeit Item
      name: displayBrightnessItem
      required: true
      type: TEXT
    - context: item
      description: Item für den aktuellen Stromverbrauch (Number:Power)
      label: Stromverbrauch Item
      name: powerConsumptionItem
      required: false
      type: TEXT
    - context: item
      description: Item für kWH Verbrauch (Number)
      label: kWh Verbrauch
      name: powerkwhItem
      required: false
      type: TEXT
timestamp: Jun 6, 2025, 9:22:25 AM
component: f7-card
config:
  title: Whirlpool Steuerung
slots:
  default:
    - component: f7-block
      slots:
        default:
          - component: f7-row
            slots:
              default:
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - text-color-lightgray
                            - text-align-right
                            - margin-right
                          text: "Gesamt Verbrauch:"
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: analyzer
                          actionAnalyzerItems: =props.powerkwhItem
                          class:
                            - no-padding
                            - no-margin
                            - display-inline-block
                        slots:
                          default:
                            - component: Label
                              config:
                                class:
                                  - font-weight-bold
                                  - text-align-left
                                  - text-xl
                                text: =items[props.powerkwhItem].displayState ||
                                  items[props.powerkwhItem].state || '-'
          - component: f7-row
            slots:
              default:
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - text-color-lightgray
                            - text-align-right
                            - margin-right
                          text: "Stromverbrauch:"
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: analyzer
                          actionAnalyzerItems: =props.powerConsumptionItem
                          class:
                            - no-padding
                            - no-margin
                            - display-inline-block
                        slots:
                          default:
                            - component: Label
                              config:
                                class:
                                  - font-weight-bold
                                  - text-align-left
                                  - text-xl
                                text: =items[props.powerConsumptionItem].displayState ||
                                  items[props.powerConsumptionItem].state || '-'
          - component: f7-row
            slots:
              default:
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - text-color-lightgray
                            - text-align-right
                            - margin-right
                          text: "Aktuelle Temperatur:"
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: analyzer
                          actionAnalyzerItems: =props.actualTempItem
                          class:
                            - no-padding
                            - no-margin
                            - display-inline-block
                        slots:
                          default:
                            - component: Label
                              config:
                                class:
                                  - font-weight-bold
                                  - text-align-left
                                  - text-7xl
                                text: =items[props.actualTempItem].displayState ||
                                  items[props.actualTempItem].state
          - component: f7-row
            slots:
              default:
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - text-color-lightgray
                            - text-align-right
                            - margin-right
                          text: "Zeit bis Aufgeheizt:"
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - font-weight-bold
                            - text-align-left
                            - text-lg
                          text: =items[props.timeToHeatItem].displayState ||
                            items[props.timeToHeatItem].state || '-'
    - component: f7-block
      slots:
        default:
          - component: f7-row
            config:
              class:
                - margin-top
                - margin-bottom-half
            slots:
              default:
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - text-align-right
                            - text-color-lightgray
                            - margin-right
                          text: "Solltemperatur einstellen:"
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: oh-link
                        config:
                          action: analyzer
                          actionAnalyzerItems: =props.setpointTempItem
                          class:
                            - no-padding
                            - no-margin
                            - display-inline-block
                        slots:
                          default:
                            - component: Label
                              config:
                                class:
                                  - font-weight-bold
                                  - text-align-left
                                  - text-xl
                                text: =items[props.setpointTempItem].displayState ||
                                  items[props.setpointTempItem].state
          - component: oh-slider
            config:
              class:
                - margin-bottom
              item: =props.setpointTempItem
              label: true
              max: 40
              min: 20
              releaseOnly: true
              scale: true
              scaleSteps: 6
              scaleSubSteps: 0
              step: 1
              unit: °C
          - component: f7-row
            config:
              class:
                - margin-top
                - margin-bottom-half
            slots:
              default:
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - text-align-right
                            - text-color-lightgray
                            - margin-right
                          text: "Display Helligkeit:"
                - component: f7-col
                  config:
                    width: 50
                  slots:
                    default:
                      - component: Label
                        config:
                          class:
                            - font-weight-bold
                            - text-align-left
                            - text-xl
                          text: =items[props.displayBrightnessItem].displayState ||
                            items[props.displayBrightnessItem].state
          - component: oh-slider
            config:
              class:
                - margin-bottom
              item: =props.displayBrightnessItem
              label: true
              max: 8
              min: 0
              scale: true
              scaleSteps: 4
              scaleSubSteps: 0
              step: 1
          - component: f7-row
            config:
              class:
                - margin-top
                - margin-bottom
            slots:
              default:
                - component: f7-col
                  slots:
                    default:
                      - component: f7-row
                        slots:
                          default:
                            - component: f7-col
                              config:
                                class:
                                  - display-flex
                                  - flex-direction-column
                                  - align-items-center
                                width: 50
                              slots:
                                default:
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =props.poolPowerItem
                                  - component: Label
                                    config:
                                      class:
                                        - text-color-lightgray
                                        - text-align-center
                                        - margin-top-half
                                        - text-xs
                                      text: Pool Ein/Aus
                            - component: f7-col
                              config:
                                class:
                                  - display-flex
                                  - flex-direction-column
                                  - align-items-center
                                width: 50
                              slots:
                                default:
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =props.filterItem
                                  - component: Label
                                    config:
                                      class:
                                        - text-color-lightgray
                                        - text-align-center
                                        - margin-top-half
                                        - text-xs
                                      text: Filter
                - component: f7-col
                  slots:
                    default:
                      - component: f7-row
                        slots:
                          default:
                            - component: f7-col
                              config:
                                class:
                                  - display-flex
                                  - flex-direction-column
                                  - align-items-center
                                width: 50
                              slots:
                                default:
                                  - component: oh-toggle
                                    config:
                                      color: green
                                      item: =props.blubberItem
                                  - component: Label
                                    config:
                                      class:
                                        - text-color-lightgray
                                        - text-align-center
                                        - margin-top-half
                                        - text-xs
                                      text: Blubber
                            - component: f7-col
                              config:
                                class:
                                  - display-flex
                                  - flex-direction-column
                                  - align-items-center
                                width: 50
                              slots:
                                default:
                                  - component: oh-toggle
                                    config:
                                      color: '=(items[props.redItem].state == "1") ? "red" :
                                        ((items[props.greenItem].state == "1") ?
                                        "green" : "orange")'
                                      item: =props.heatingItem
                                  - component: Label
                                    config:
                                      class:
                                        - text-color-lightgray
                                        - text-align-center
                                        - margin-top-half
                                        - text-xs
                                      text: Heizung
    - component: f7-block
      config:
        class:
          - margin-top-half
          - margin-bottom
      slots:
        default: []


Things

UID: mqtt:topic:whirlpool:whirlpool
label: whirlpool
thingTypeUID: mqtt:topic
configuration:
  payloadNotAvailable: Dead
  availabilityTopic: layzspa-01D31B/Status
  payloadAvailable: Alive
bridgeUID: mqtt:broker:98f4fc70e6
channels:
  - id: LockedState
    channelTypeUID: mqtt:number
    label: LockedState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.LCK
  - id: PowerState
    channelTypeUID: mqtt:number
    label: PowerState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.PWR
  - id: UnitState
    channelTypeUID: mqtt:number
    label: UnitState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.UNT
  - id: BubbleState
    channelTypeUID: mqtt:number
    label: BubbleState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.AIR
  - id: HeatGreenState
    channelTypeUID: mqtt:number
    label: HeatGreenState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.GRN
  - id: HeatRedState
    channelTypeUID: mqtt:number
    label: HeatRedState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.RED
  - id: PumpState
    channelTypeUID: mqtt:number
    label: PumpState
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.FLT
  - id: Display
    channelTypeUID: mqtt:string
    label: Display
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.concat($.CH1,$.CH2,$.CH3)
  - id: SetUnit
    channelTypeUID: mqtt:switch
    label: SetUnit
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":1,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      off: "0"
      on: "1"
  - id: SetBubbles
    channelTypeUID: mqtt:switch
    label: SetBubbles
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":2,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.AIR
      off: "0"
      on: "1"
  - id: SetHeater
    channelTypeUID: mqtt:switch
    label: SetHeater
    configuration:
      commandTopic: layzspa-01D31B/command
      postCommand: false
      formatBeforePublish: '{"CMD":3,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      off: "0"
      on: "1"
  - id: SetPump
    channelTypeUID: mqtt:switch
    label: SetPump
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":4,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.FLT
      off: "0"
      on: "1"
  - id: ResetQueue
    channelTypeUID: mqtt:switch
    label: ResetQueue
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":5,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      off: "0"
      on: "1"
  - id: RebootESP
    channelTypeUID: mqtt:switch
    label: RebootESP
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":6,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      off: "0"
      on: "1"
  - id: ResetTimes
    channelTypeUID: mqtt:switch
    label: ResetTimes
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":8,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      off: "0"
      on: "1"
  - id: ResetTimerChlorine
    channelTypeUID: mqtt:switch
    label: ResetTimerChlorine
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":9,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      off: "0"
      on: "1"
  - id: ResetTimerFilter
    channelTypeUID: mqtt:switch
    label: ResetTimerFilter
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":10,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      off: "0"
      on: "1"
  - id: SetBeep
    channelTypeUID: mqtt:number
    label: SetBeep
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":13,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.SETBEEB
  - id: SetTargetBrightness
    channelTypeUID: mqtt:number
    label: SetTargetBrightness
    configuration:
      commandTopic: layzspa-01D31B/command
      min: 0
      formatBeforePublish: '{"CMD":12,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.BRT
      max: 8
  - id: TargetTemperature
    channelTypeUID: mqtt:number
    label: TargetTemperature
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.TGT
      unit: °C
  - id: Temperature
    channelTypeUID: mqtt:number
    label: Temperature
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.TMP
      unit: °C
  - id: Watt
    channelTypeUID: mqtt:number
    label: Watt
    configuration:
      stateTopic: layzspa-01D31B/times
      transformationPattern:
        - JSONPATH:$.WATT
  - id: KWH
    channelTypeUID: mqtt:number
    label: KWH
    configuration:
      stateTopic: layzspa-01D31B/times
      transformationPattern:
        - JSONPATH:$.KWH
  - id: SetTargetAmbient
    channelTypeUID: mqtt:number
    label: SetTargetAmbient
    configuration:
      postCommand: false
      retained: false
      min: -40
      formatBeforePublish: '{"CMD":15,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      max: 60
      commandTopic: layzspa-01D31B/command
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.AMBC
  - id: SetTargetTemperature
    channelTypeUID: mqtt:number
    label: SetTargetTemperature
    configuration:
      commandTopic: layzspa-01D31B/command
      min: 20
      formatBeforePublish: '{"CMD":0,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.TGT
      max: 40
  - id: ERR
    channelTypeUID: mqtt:string
    label: ERR
    configuration:
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.ERR
  - id: T2R
    channelTypeUID: mqtt:number
    label: T2R
    configuration:
      stateTopic: layzspa-01D31B/times
      transformationPattern:
        - JSONPATH:$.T2R
  - id: PowerSwitch
    channelTypeUID: mqtt:switch
    label: PowerSwitch
    configuration:
      commandTopic: layzspa-01D31B/command
      formatBeforePublish: '{"CMD":24,"VALUE":%s,"XTIME":0,"INTERVAL":0}'
      stateTopic: layzspa-01D31B/message
      transformationPattern:
        - JSONPATH:$.PWR
      off: "0"
      on: "1"