Skip to content
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
72 changes: 37 additions & 35 deletions bundles/org.openhab.binding.warmup/README.md
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
# Warmup Binding

This binding integrates [Warmup](https://www.warmup.co.uk) Wifi enabled Thermostats via the API at <https://my.warmup.com/>.
This binding integrates [Warmup](https://www.warmup.co.uk) Wi‑Fi–enabled thermostats via the API at <https://my.warmup.com/>.

Devices known to work with the binding:

Expand All @@ -11,7 +11,7 @@ Device expected to work with the binding:

- [Warmup 6iE](https://www.warmup.co.uk/thermostats/smart/6ie-underfloor-heating)

Devices which might work with the binding:
Devices that might work with the binding:

- Other similar looking devices marketed under different brands, mentioned in the API
- [Laticrete](https://laticrete.com/)
Expand All @@ -20,31 +20,31 @@ Devices which might work with the binding:
- Equus
- [Savant](https://www.savant.com/)

Any Warmup device must be registered at <https://my.warmup.com/> prior to usage, or connected through the [MyHeating app](https://www.warmup.co.uk/thermostats/smart/myheating-app).
Any Warmup device must be registered at <https://my.warmup.com/> prior to use, or connected through the [MyHeating app](https://www.warmup.co.uk/thermostats/smart/myheating-app).

This API is not known to be documented publicly.
The binding api implementation has been derived from the implementations at <https://github.com/alyc100/SmartThingsPublic/blob/master/devicetypes/alyc100/warmup-4ie.src/warmup-4ie.groovy> and <https://github.com/alex-0103/warmup4IE/blob/master/warmup4ie/warmup4ie.py>, and enhanced by inspecting the [GraphQL endpoint](https://apil.warmup.com/graphql).
The API is not publicly documented.
The binding’s API implementation is derived from the implementations at <https://github.com/alyc100/SmartThingsPublic/blob/master/devicetypes/alyc100/warmup-4ie.src/warmup-4ie.groovy> and <https://github.com/alex-0103/warmup4IE/blob/master/warmup4ie/warmup4ie.py>, and has been enhanced by inspecting the [GraphQL endpoint](https://apil.warmup.com/graphql).

## Supported Things

The Warmup binding supports the following thing types:
The Warmup binding supports the following Thing types:

| Bridge | Label | Description |
|----------------|-------------------|----------------------------------------------------------------------------------------|
| `my-warmup` | My Warmup Account | The account credentials for my.warmup.com which acts as an API to the Warmup device(s) |
| Bridge | Label | Description |
|-------------|-------------------|-----------------------------------------------------------------------------------------|
| `my-warmup` | My Warmup Account | The account credentials for my.warmup.com, which acts as an API to the Warmup device(s) |

| Thing | Label | Description |
|----------|-------|------------------------------------------------------------------------------------------------|
| `room` | Room | A room containing an individual Warmup WiFi connected device which controls a heating circuit. |
| Thing | Label | Description |
|--------|-------|------------------------------------------------------------------------------------------------|
| `room` | Room | A room containing an individual Warmup Wi‑Fi–connected device that controls a heating circuit. |

**Room**
The device is optimised for controlling underfloor heating (electric or hydronic), although it can also control central heating circuits.
The device reports the temperature from one of two thermostats, either a floor temperature probe or the air temperature at the device.
It appears to be possible to configure two devices in a primary / secondary configuration, but it is not clear how this might be represented by the API and hasn't been implemented.
The device reports the temperature from one of two sensors: either a floor temperature probe or the air temperature at the device.
It appears to be possible to configure two devices in a primary/secondary configuration, but it is not clear how this might be represented by the API and has not been implemented.

## Discovery

Once credentials are successfully added to the bridge, any rooms (devices) detected will be added as things to the inbox.
Once credentials are successfully added to the bridge, any rooms (devices) detected will be added as Things to the Inbox.

## Thing Configuration

Expand All @@ -58,36 +58,38 @@ Once credentials are successfully added to the bridge, any rooms (devices) detec

### `room` Thing Configuration

Rooms are configured automatically with a Serial Number on discovery, or can be added manually using the "Device Number" from the device, excluding the last 3 characters. Changing the target temperature results in a temporary override to that temperature, for the duration configured on the thing. This defaults to 60 minutes.
Rooms are configured automatically with a serial number upon discovery, or can be added manually using the "Device Number" from the device, excluding the last 3 characters.
Changing the target temperature results in a temporary override to that temperature for the duration configured on the Thing.
This defaults to 60 minutes.

| config parameter | type | description | required | default |
|------------------|---------|--------------------------------------------------------------------|----------|---------|
| serialNumber | String | Device Serial Number, excluding last 3 characters | true | |
| overrideDuration | Integer | Duration in minutes of override when target temperature is changed | false | 60 |
| serialNumber | String | Device serial number, excluding the last 3 characters | true | |
| overrideDuration | Integer | Duration in minutes of override when target temperature is changed | true | 60 |
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I think it should rather be changed to required="false" here, since it has a default value:

<parameter name="overrideDuration" type="integer" unit="m" required="true">
<label>Override Duration</label>
<description>Duration in minutes of override when target temperature is changed</description>
<default>60</default>
</parameter>

Suggested change
| overrideDuration | Integer | Duration in minutes of override when target temperature is changed | true | 60 |
| overrideDuration | Integer | Duration in minutes of override when target temperature is changed | false | 60 |

Copy link
Contributor Author

@lsiepel lsiepel Feb 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Are you sure?
Up to now, i thought that having a default or not. Required also signals the UI to have a value.
But now i wonder if that is true, How ould one unset a default value. E.g. remove it from the jsondb to stick to the default value from the binding. aargh :-/

Copy link
Contributor

@jlaur jlaur Feb 1, 2026

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Example (defaults to required="false"):

<parameter name="currencyCode" type="text">
<label>Currency Code</label>
<description>Currency code in which to obtain spot prices.</description>
<default>DKK</default>
<options>
<option value="DKK">Danish Krone</option>
<option value="EUR">Euro</option>
</options>
</parameter>

/**
* Currency code for the prices.
*/
public String currencyCode = EnergiDataServiceBindingConstants.CURRENCY_DKK.getCurrencyCode();

Never set:

Image

Click to upper right corner to clear:

Image

Save - and it's back to default. Code tab:

version: 1
things:
  energidataservice:service:311fd75536:
    config:
      priceArea: DK1
      currencyCode: DKK
      hourlySpotPrices: false
      gridCompanyGLN: "5790000705184"
      energinetGLN: "5790000432752"
      reducedElectricityTax: false

Remove it:

version: 1
things:
  energidataservice:service:311fd75536:
    config:
      priceArea: DK1
      hourlySpotPrices: false
      gridCompanyGLN: "5790000705184"
      energinetGLN: "5790000432752"
      reducedElectricityTax: false

And save. It's back.

Warmup binding:

Image

Deleting the "0", now trying to delete "6", but that instantly causes it to go back to 60:

Image

If I delete it in the code tab, it automatically is restored. File-based configuration seems to work as well:

Thing warmup:room:test"Room" (warmup:my-warmup:test) [serialNumber="123"]
Image

So here the only problem seems to be that you can't actually delete it in the UI.

I think it's most logical to leave parameters having a default value as optional, since the binding can then just use the default value. I think there used to be more annoying issues, but right now can't remember or reproduce.

Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Anyway, that's how the binding is now, and you just updated the documentation to reflect that, so it's fine for this PR.


## Channels

| channel | type | description | read only |
|---------------------|--------------------|----------------------------------------------------------------------------------------------------------------------------------------------|-----------|
| currentTemperature | Number:Temperature | Currently reported temperature | true |
| targetTemperature | Number:Temperature | Target temperature | false |
| overrideRemaining | Number:Time | Duration remaining of the configured override | true |
| fixedTemperature | Number:Temperature | Target temperature for fixed mode | false |
| energyToday | Number:Energy | Today's current energy consumption. | true |
| runMode | String | Current operating mode of the thermostat, options listed below | false |
| frostProtectionMode | Switch | Toggles between the "Frost Protection" run mode and the previously configured "active" run mode (known options are either Fixed or Schedule) | false |
| airTemperature | Number:Temperature | Currently reported air temperature at the device | true |
| floor1Temperature | Number:Temperature | Currently reported temperature from floor probe 1 on the device | true |
| floor2Temperature | Number:Temperature | Currently reported temperature from floor probe 2 on the device | true |
| channel | type | description | read-only |
|---------------------|--------------------|------------------------------------------------------------------------------------------------------------------|-----------|
| currentTemperature | Number:Temperature | Currently reported temperature | true |
| targetTemperature | Number:Temperature | Target temperature | false |
| overrideRemaining | Number:Time | Remaining duration of the configured override | true |
| fixedTemperature | Number:Temperature | Target temperature for fixed mode | false |
| energyToday | Number:Energy | Today's current energy consumption | true |
| runMode | String | Current operating mode of the thermostat; options listed below | false |
| frostProtectionMode | Switch | Toggles between the "Frost Protection" run mode and the previously active run mode (typically Fixed or Schedule) | false |
| airTemperature | Number:Temperature | Currently reported air temperature at the device | true |
| floor1Temperature | Number:Temperature | Currently reported temperature from floor probe 1 on the device | true |
| floor2Temperature | Number:Temperature | Currently reported temperature from floor probe 2 on the device | true |

### Run Mode Statuses

These run mode statuses are defined for the API.
These run modes are defined for the API.
The descriptions are based on inspection of the device behaviour and are not sourced from documentation.
Only the value `schedule` is writeable, this reverts the device to the program/schedule configured on the device.
Only the value `schedule` is writable; this reverts the device to the program/schedule configured on the device.
The value `fixed` can be set by commanding the `fixedTemperature` channel. The value `override` can be set by commanding the `targetTemperature` channel.

| api value | ui name | description |
| api value | UI name | description |
|------------|------------------|---------------------------------------------------------------------------------|
| not_set | Not Set | Unknown |
| off | Off | Device turned off |
Expand All @@ -105,7 +107,7 @@ The value `fixed` can be set by commanding the `fixedTemperature` channel. The v

### setOverride(temperature, duration)

Sets a temporary temperature override on the device
Sets a temporary temperature override on the device.

Parameters:

Expand Down Expand Up @@ -151,7 +153,7 @@ Bridge warmup:my-warmup:MyWarmup [ username="test@example.com", password="test",

```java
Number:Temperature bathroom_temperature "Temperature [%.1f °C]" <temperature> (GF_Bathroom, Temperature) ["Temperature"] {channel="warmup:room:MyWarmup:bathroom:currentTemperature"}
Number:Temperature bathroom_setpoint "Set Point [%.1f °C]" <temperature> (GF_Bathroom) ["Set Point"] {channel="warmup:room:MyWarmup:bathroom:targetTemperature"}
Number:Temperature bathroom_setpoint "Setpoint [%.1f °C]" <temperature> (GF_Bathroom) ["Setpoint"] {channel="warmup:room:MyWarmup:bathroom:targetTemperature"}
Number:Time bathroom_overrideRemaining "Override Remaining [%d minutes]" (GF_Bathroom) {channel="warmup:room:MyWarmup:bathroom:overrideRemaining"}
String bathroom_runMode "Run Mode [%s]" (GF_Bathroom) {channel="warmup:room:MyWarmup:bathroom:runMode"}
Switch bathroom_frostProtection "Frost Protection Mode" (GF_Bathroom) {channel="warmup:room:MyWarmup:bathroom:frostProtectionMode"}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@

<type>binding</type>
<name>Warmup Binding</name>
<description>This is the binding for Warmup WiFi connected Thermostats primarily used for controlling underfloor
<description>This is the binding for Warmup Wi‑Fi–connected thermostats, primarily used for controlling underfloor
heating.</description>
<connection>cloud</connection>

Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,24 @@
# add-on

addon.warmup.name = Warmup Binding
addon.warmup.description = This is the binding for Warmup WiFi connected Thermostats primarily used for controlling underfloor heating.
addon.warmup.description = This is the binding for Warmup Wi‑Fi–connected thermostats, primarily used for controlling underfloor heating.

# thing types

thing-type.warmup.my-warmup.label = My Warmup Account
thing-type.warmup.my-warmup.description = Connection to the https://my.warmup.com site
thing-type.warmup.my-warmup.description = Connection to my.warmup.com
thing-type.warmup.room.label = Room
thing-type.warmup.room.description = Warmup WiFi connected Thermostat(s) controlling a room
thing-type.warmup.room.description = Warmup Wi‑Fi–connected thermostat(s) controlling a room
thing-type.warmup.room.channel.airTemperature.label = Air Temperature
thing-type.warmup.room.channel.airTemperature.description = Currently reported air temperature at the device
thing-type.warmup.room.channel.currentTemperature.label = Current Temperature
thing-type.warmup.room.channel.currentTemperature.description = Currently reported temperature in the room
thing-type.warmup.room.channel.energyToday.label = Energy Today
thing-type.warmup.room.channel.energyToday.description = Energy used today as reported by the device
thing-type.warmup.room.channel.floor1Temperature.label = Floor 1 Temperature
thing-type.warmup.room.channel.floor1Temperature.description = Currently reported temperature from floor probe 1 on the device
thing-type.warmup.room.channel.floor2Temperature.label = Floor 2 Temperature
thing-type.warmup.room.channel.floor2Temperature.description = Currently reported temperature from floor probe 2 on the device

# thing types config

Expand All @@ -24,18 +34,8 @@ thing-type.config.warmup.room.serialNumber.label = Serial Number

# channel types

channel-type.warmup.airTemperature.label = Air Temperature
channel-type.warmup.airTemperature.description = Currently reported air temperature at the device
channel-type.warmup.currentTemperature.label = Current Temperature
channel-type.warmup.currentTemperature.description = Current temperature in room, may be air or floor dependent on Heating Target
channel-type.warmup.energyToday.label = Energy Today
channel-type.warmup.energyToday.label = Today's current energy consumption.
channel-type.warmup.fixedTemperature.label = Fixed Temperature
channel-type.warmup.fixedTemperature.description = Target temperature for fixed mode on device
channel-type.warmup.floor1Temperature.label = Floor 1 Temperature
channel-type.warmup.floor1Temperature.description = Currently reported temperature from floor probe 1 on the device
channel-type.warmup.floor2Temperature.label = Floor 2 Temperature
channel-type.warmup.floor2Temperature.description = Currently reported temperature from floor probe 2 on the device
channel-type.warmup.frostProtectionMode.label = Frost Protection Mode
channel-type.warmup.overrideRemaining.label = Override Remaining
channel-type.warmup.overrideRemaining.description = How long until the override deactivates
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,7 @@

<bridge-type id="my-warmup">
<label>My Warmup Account</label>
<description>Connection to the https://my.warmup.com site</description>
<description>Connection to my.warmup.com</description>
<category>WebService</category>
<semantic-equipment-tag>WebService</semantic-equipment-tag>
<config-description>
Expand Down Expand Up @@ -34,20 +34,35 @@
</supported-bridge-type-refs>

<label>Room</label>
<description>Warmup WiFi connected Thermostat(s) controlling a room</description>
<description>Warmup Wi‑Fi–connected thermostat(s) controlling a room</description>
<category>RadiatorControl</category>
<semantic-equipment-tag>Thermostat</semantic-equipment-tag>
<channels>
<channel id="currentTemperature" typeId="system.indoor-temperature"/>
<channel id="currentTemperature" typeId="system.indoor-temperature">
<label>Current Temperature</label>
<description>Currently reported temperature in the room</description>
</channel>
<channel id="targetTemperature" typeId="targetTemperature"/>
<channel id="fixedTemperature" typeId="fixedTemperature"/>
<channel id="overrideRemaining" typeId="overrideRemaining"/>
<channel id="energyToday" typeId="system.electric-energy"/>
<channel id="energyToday" typeId="system.electric-energy">
<label>Energy Today</label>
<description>Energy used today as reported by the device</description>
</channel>
<channel id="runMode" typeId="runMode"/>
<channel id="frostProtectionMode" typeId="frostProtectionMode"/>
<channel id="airTemperature" typeId="system.indoor-temperature"/>
<channel id="floor1Temperature" typeId="system.indoor-temperature"/>
<channel id="floor2Temperature" typeId="system.indoor-temperature"/>
<channel id="airTemperature" typeId="system.indoor-temperature">
<label>Air Temperature</label>
<description>Currently reported air temperature at the device</description>
</channel>
<channel id="floor1Temperature" typeId="system.indoor-temperature">
<label>Floor 1 Temperature</label>
<description>Currently reported temperature from floor probe 1 on the device</description>
</channel>
<channel id="floor2Temperature" typeId="system.indoor-temperature">
<label>Floor 2 Temperature</label>
<description>Currently reported temperature from floor probe 2 on the device</description>
</channel>
</channels>

<properties>
Expand Down
Loading