Edit: I added a solution that does not require node-red at the bottom of the post, though I’ve not tested it
I recently purchased the Kogan 1.7 Smart Kettle, when it was on sale for AUD $35.
I was able to achieve the following with the custom firmware Tasmota 8.3.1
.
- Control the boiler (2 way, turning on/off on boiler will reflect on HA)
- Display Temperature
- Keep warm (2-way control, changing the value in kettle will reflect on HA)
Here’s how it looks like:
Here’s how I did it:
Following this video and using this template, I was able to flash the kettle with the Tasmota firmware with tuya-convert (Raspberry Pi + ESP8266 doner, I also updated to the latest Tasmota, but this wasn’t required.)
After you setup Tasmota, you need to enable option 66 by typing in the console: SetOption66 1
This will make Tasmota forward all Tuya payloads via MQTT in the tele
topic. This could be
tele/<topic>/RESULT
by default, or
<topic>/tele/RESULT
if you use auto-discovery.
This is very important, or the kettle -> HA dropdown
integration would not work.
However, the value template provided in the guide mismatch what I receive from TuyaReceived
.
Some other community members using Tasmota 8.3.1
have reported the same issue
I had to use this instead:
{% if "5" in value_json["TuyaReceived"] %}
{{ value_json["TuyaReceived"]["5"]["DpIdData"]|int(base=16) }}
{% else %}
{{ states("sensor.kettle_temp") }}
{% endif %}
where kettle_temp
is the id of the entity.
The whole sensor block:
sensor:
- platform: mqtt
unique_id: kettle.temp
name: kettle_temp
state_topic: "tele/kettle/RESULT"
availability_topic: "tele/kettle/LWT"
payload_available: "Online"
payload_not_available: "Offline"
value_template: >
{% if "5" in value_json["TuyaReceived"] %}
{{ value_json["TuyaReceived"]["5"]["DpIdData"]|int(base=16) }}
{% else %}
{{ states("sensor.kettle_temp") }}
{% endif %}
unit_of_measurement: '℃'
This gives me the temperature readings.
As for switching the boiler on & off, it’s the same as any MQTT switch. You can find it in the home assistant’s MQTT Switch
documentation.
Here’s my sample definition.
switch:
- platform: mqtt
name: kettle
unique_id: kettle.power
state_topic: "stat/kettle/POWER"
command_topic: "cmnd/kettle/POWER"
availability_topic: "tele/kettle/LWT"
payload_on: "ON"
payload_off: "OFF"
payload_available: "Online"
payload_not_available: "Offline"
retain: false
Then comes the complicated part, the “Keep Warm” feature. I can’t find a slider that allows me to skip a value, or have “OFF” as one of the labels, and I don’t really want to write a plugin for it, so I opted for a dropdown. Here’s what it looks like:
input_select:
kettle_keep_warm:
name: "Keep Warm"
options:
- "OFF"
- "40 ℃"
- "50 ℃"
- "60 ℃"
- "80 ℃"
- "90 ℃"
This dropdown by itself doesn’t do anything, you can set it up, so when the value change, it will publish an MQTT message to the kettle, and when you receive a message from the kettle, update the dropdown. You can do this in HA scripts/automation, but I’m using node-red here.
If you use Hass.io, you can follow this documentation to setup node-red.
Home Assistant Community Add-on: Node-RED
I use the docker version of home assistant, so I need to manually set it up with the docker version of node-red. If you’re interested in this configuration, comment below and I could write another post about my setup.
Overview of the node-red flow
The first row handles HA dropdown value change → send MQTT message to Kettle
Settings for the Dropdown Change in HA
, type: trigger: state
Settings for the Temperature to TuyaPayload
, type: function
Code for the Temperature to TuyaPayload
/*
* if you prefer not to use a function node,
* you should be able to do this with a `change` node
* with conditions, I'm a developer so the function node is
* always the easiest for me.
*/
const mapping = {
// the string for the keys (string on the left side of the colon) needs to match exactly to what you set in the `input_select.<your_input_name>.options`
"OFF": "102,0",
"40 ℃": "102,1",
"50 ℃": "102,2",
"60 ℃": "102,3",
"80 ℃": "102,4",
"90 ℃": "102,5",
};
return {
payload: mapping[msg.payload]
};
Settings for the Send MQTT to Kettle
, type: mqtt out
Then comes the handling of kettle keep warm state change → update HA dropdown value
Settings for the Received Tuya Payload from Kettle Tele
, type: mqtt in
Settings for the Keep Warm State Change
, type: function
Code for the Keep Warm State Change
// achievable through `change` node too
const mapping = {
0: "OFF",
1: "40 ℃",
2: "50 ℃",
3: "60 ℃",
4: "80 ℃",
5: "90 ℃",
};
let value;
try { // TuyaReceived.DpType4Id102 might not be in payload
value = msg.payload.TuyaReceived.DpType4Id102;
} catch(e) {
return; // the message received was not temperature data, terminate flow
}
const label = mapping[value];
if (!label) {
return; // the return value isn't in the range of 0 - 5, terminate flow
}
return {payload: label};
Settings for the Update Home Assistant Dropdown Value
, type: call service
JSON
payload for the Update Home Assistant Dropdown Value
*Remember to change input_select.kettle_keep_warm
to your dropdown’s entity id
{
"entity_id": "input_select.kettle_keep_warm",
"option": msg.payload
}
This last one is optional, it sends a notification to your phone (if you have the HA app installed) after it finish boiling the water.
The idea here is when the temperature goes above 98 degrees, and the boiler power state goes from ON
to OFF
, we consider it finished boiling, there might be a Tuya Payload I could tap into to avoid this check, but for now, this works fine.
Settings for the Water boiled
, type: trigger: state
Settings for the Notify
, type: call service
JSON
for theNotify
{
"message": "Water is boiling!",
"title": "Smart Kettle"
}
If you don’t want to use node-red, here’s how I imagine this setup could work
-
For the
HA dropdown -> Kettle
part, you can use the automation. Community member myle has done some great work here . -
For the
Kettle -> HA dropdown
part, you should be able to set up an MQTT sensor, following documentation. You would need to use thevalue_template
in a similar manner to how you use the temperature sensor, I imagine it to be something like this, though I have not tested this, let me know if it doesn’t work.
{% set mapping = {
0: "OFF",
1: "40 ℃",
2: "50 ℃",
3: "60 ℃",
4: "80 ℃",
5: "90 ℃",
} %}
{% if "DpType4Id102" in value_json["TuyaReceived"] %}
{% set raw_value = value_json["TuyaReceived"]["DpType4Id102"] %}
{% if 0 <= raw_value and raw_value <= 5 %}
{{ mapping[raw_value] }}
{% else %}
{{ states("sensor.kettle_keep_warm") }}
{% endif %}
{% else %}
{{ states("sensor.kettle_keep_warm") }}
{% endif %}
Then, you can set up automation to set the sensor value to your dropdown.
Hope it helps