Wifi thermostat (Beok, Floureon, Beca Energy) component

You need to download the climate component form github and add it to your config/custom_components/climate/

I don’t know, It seen to be the same device, but I do not own it :wink:
Let me know if you try it !

Could you try with only the following config ?

climate:
  - platform: broadlink
    name: "termostat_obyvak"
    mac: "84:F3:EB:52:53:F8"
    host: "192.168.0.110"

Please check, I get following with suggested config

root@hass:/home/homeassistant/.homeassistant# cat home-assistant.log 
2018-09-14 10:34:12 WARNING (MainThread) [homeassistant.loader] You are using a custom component for climate.broadlink which has not been tested by Home Assistant. This component might cause stability problems, be sure to disable it if you do experience issues with Home Assistant.
2018-09-14 10:34:13 ERROR (MainThread) [homeassistant.components.climate] Error while setting up platform broadlink
Traceback (most recent call last):
  File "/srv/homeassistant/lib/python3.6/site-packages/homeassistant/helpers/entity_platform.py", line 128, in _async_setup_platform
    SLOW_SETUP_MAX_WAIT, loop=hass.loop)
  File "/usr/lib/python3.6/asyncio/tasks.py", line 358, in wait_for
    return fut.result()
  File "/usr/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/home/homeassistant/.homeassistant/custom_components/climate/broadlink.py", line 102, in setup_platform
    config[CONF_ADVANCED_CONFIG],
KeyError: 'advanced_config'

Mister_Slowhand Are there any news?
Also I am interested in an independent internet solution with the BEOK BOT-313.
Before proceeding with the purchase I would like to know if there is anyone who tried the BEOK BOT-313 thermostat with clementTal plugin
Thanks in advance.

I haven’t tried yet, I still hope for someone who’d tried


I’ve been on the company’s site, all devices are shown altogether, might be the same API. Maybe we could try to contact their support ?

I am no longer sure to buy Beok BOT-313 because I have read in some customer reviews that the minimum differential that can be set is + - 1 degree Celsius.
So if you set the temperature to 20 degrees the thermostat turns off at 21 degrees and turns it on at 19 degrees.
Two degrees of temperature variation is certainly not comfortable.
I do not think other Wifi thermostats model have this problem.

That is not something I would not care for. Just because the point in HA is to use more intelligence than what’s in the device itself.
I’m looking for a way to start my boiler, depending on the temperature in a room (different one depending on the hour), the external temperature, the house occupancy etc etc
 Right now, I have the logic already coded, it only turns a light on.Based on Aqara sensors and motion detection. A dry relay would work, though I can’t find one that is natively supported in HA (sonoff uses MQTT which I don’t use). Most thermostats rely on the cloud which I want to avoid too.
So this device seems to fit perfectly : native support with this component, works locally and last but not least, inexpensive !

I’ve contacted Beok support and they answered the same day. I asked if the API was the same among all their wifi devices, they answered that the APP is the same :thinking:
Worth a try though !

Any update on this? Do you have any idea, is it possible to fix it in the future? Are you able to reproduce it? Or the problem is only in my version or configuration? Thanks man.

I’m giving a try to reproduce it tonight.
I hope I’ll find whats going wrong.

I’ll let you know

Should be fixed :slight_smile:
Let me know if you get into trouble again !

Looks like the same hardware, but I canot garanted it


This is haw thermostats works, sadly.
But 2° is a big gap !

But with HA, you can bypass the process and manage to swith it on/off at the value you wanted !

If the app is the same, so the API is !
BEOK is not the manufacturer. It’s broadlink. Both looks like based on same hardware.
Worth a try !, let me know

Yes, I’ll try that. Time to go shopping, tomorrow I expect some spare time

From aliexpress ? Amazon seems to send from China too.

I am getting the following error in my logs

2018-09-24 19:54:07 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 390, in start
    resp = await self._request_handler(request)
  File "/usr/local/lib/python3.6/site-packages/aiohttp/web_app.py", line 366, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.6/site-packages/aiohttp/web_middlewares.py", line 106, in impl
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/static.py", line 66, in staticresource_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/real_ip.py", line 34, in real_ip_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/ban.py", line 67, in ban_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/auth.py", line 68, in auth_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/real_ip.py", line 34, in real_ip_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/ban.py", line 67, in ban_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/auth.py", line 68, in auth_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/view.py", line 113, in handle
    result = await result
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/config/core.py", line 24, in post
    errors = yield from async_check_ha_config_file(request.app['hass'])
  File "/usr/local/lib/python3.6/site-packages/homeassistant/config.py", line 793, in async_check_ha_config_file
    check_ha_config_file, hass)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/scripts/check_config.py", line 372, in check_ha_config_file
    platform = loader.get_platform(hass, domain, p_name)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/loader.py", line 62, in get_platform
    return get_component(hass, PLATFORM_FORMAT.format(domain, platform))
  File "/usr/local/lib/python3.6/site-packages/homeassistant/loader.py", line 94, in get_component
    module = importlib.import_module(path)
  File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/config/custom_components/climate/broadlink.py", line 149
    def handle_set_schedule(service):
    ^
IndentationError: unexpected indent

any idea why am I receiving this error.

Maybe a copy/past error, make sure you have the 4 spaces (" ") before the line

def handle_set_schedule(service):

But that strage because the line number should be 150, not 149
 have you updated to the last file ?

yes its 4 spaces. this is what I have copied

"""
    Support for Chinese wifi thermostats (Floureon, Beok, Beca Energy)
    For more details about this platform, please refer to the documentation at
    https://home-assistant.io/components/climate.broadlink/
    """
import asyncio
import json
import logging

import voluptuous as vol

from homeassistant.components.climate import (
                                              DOMAIN, ClimateDevice,
                                              SUPPORT_OPERATION_MODE,
                                              SUPPORT_TARGET_TEMPERATURE,
                                              PLATFORM_SCHEMA, STATE_HEAT, STATE_OFF, STATE_AUTO)
from homeassistant.const import (
                                 TEMP_CELSIUS, ATTR_TEMPERATURE,
                                 CONF_NAME, CONF_HOST, CONF_MAC)
import homeassistant.helpers.config_validation as cv

_LOGGER = logging.getLogger(__name__)

REQUIREMENTS = ['broadlink==0.9.0', 'BroadlinkWifiThermostat==1.0.1']

DEFAULT_NAME = 'broadlink'
POWER_ON = 1
POWER_OFF = 0
AUTO = 1
MANUAL = 0
CONF_MODE_LIST = 'modes'
CONF_MIN_TEMP = 'min_temp'
CONF_MAX_TEMP = 'max_temp'
CONF_ADVANCED_CONFIG = 'advanced_config'
CONF_SCHEDULE_WEEKDAY = 'schedule_week_day'
CONF_SCHEDULE_WEEKEND = 'schedule_week_end'
CONF_WEEKDAY = "weekday"
CONF_WEEKEND = "weekend"

# Validation of the user's configuration
PLATFORM_SCHEMA = PLATFORM_SCHEMA.extend({
                                         vol.Required(CONF_HOST): cv.string,
                                         vol.Required(CONF_MAC): cv.string,
                                         vol.Required(CONF_NAME): cv.string,
                                         vol.Optional(CONF_MIN_TEMP, default=5): cv.positive_int,
                                         vol.Optional(CONF_MAX_TEMP, default=35): cv.positive_int,
                                         vol.Optional(CONF_ADVANCED_CONFIG,
                                                      default='{"loop_mode": 0, '
                                                      '"sen": 0, '
                                                      '"osv": 42, '
                                                      '"dif": 2, '
                                                      '"svh": 35, '
                                                      '"svl": 5, '
                                                      '"adj": 0, '
                                                      '"fre": 1, '
                                                      '"pon": 0}'): cv.string,
                                         vol.Optional(CONF_SCHEDULE_WEEKDAY,
                                                      default='[{"start_hour":6, '
                                                      '"start_minute":30, '
                                                      '"temp":20}, '
                                                      '{"start_hour":9, '
                                                      '"start_minute":0, '
                                                      '"temp":17}, '
                                                      '{"start_hour":12, '
                                                      '"start_minute":0, '
                                                      '"temp":20}, '
                                                      '{"start_hour":14, '
                                                      '"start_minute":0, '
                                                      '"temp":17}, '
                                                      '{"start_hour":18, '
                                                      '"start_minute":0, '
                                                      '"temp":20}, '
                                                      '{"start_hour":22, '
                                                      '"start_minute":30, '
                                                      '"temp":17}]'): cv.string,
                                         vol.Optional(CONF_SCHEDULE_WEEKEND,
                                                      default='[{"start_hour":8, '
                                                      '"start_minute":30, '
                                                      '"temp":20}, '
                                                      '{"start_hour":23, '
                                                      '"start_minute":0, '
                                                      '"temp":17}]'): cv.string
                                         })

SET_SCHEDULE_SCHEMA = vol.Schema({
                                 vol.Required(CONF_WEEKDAY,
                                              default='[{'
                                              '"start_hour":6, '
                                              '"start_minute":30, '
                                              '"temp":20}, '
                                              '{"start_hour":9, '
                                              '"start_minute":0, '
                                              '"temp":17}, '
                                              '{"start_hour":12, '
                                              '"start_minute":0, '
                                              '"temp":20}, '
                                              '{"start_hour":14, '
                                              '"start_minute":0, '
                                              '"temp":17}, '
                                              '{"start_hour":18, '
                                              '"start_minute":0, '
                                              '"temp":20}, '
                                              '{"start_hour":22, '
                                              '"start_minute":30, '
                                              '"temp":17}]'): cv.string,
                                 vol.Required(CONF_WEEKEND,
                                              default='[{"start_hour":8, '
                                              '"start_minute":30, '
                                              '"temp":20}, '
                                              '{"start_hour":23, '
                                              '"start_minute":0, '
                                              '"temp":17}]'): cv.string
                                 })

SET_ADVANCED_CONF_SCHEMA = vol.Schema({
                                      vol.Required(CONF_ADVANCED_CONFIG,
                                                   default='{"loop_mode": 0, '
                                                   '"sen": 0, '
                                                   '"osv": 42, '
                                                   '"dif": 2, '
                                                   '"svh": 35, '
                                                   '"svl": 5, '
                                                   '"adj": 0, '
                                                   '"fre": 1, '
                                                   '"pon": 0}'): cv.string,
                                      })


def setup_platform(hass, config, add_devices, discovery_info=None):
    """Set up the broadlink thermostat platform."""
    import BroadlinkWifiThermostat
    wifi_thermostat = BroadlinkWifiThermostat.\
        Thermostat(config[CONF_MAC],
                   config[CONF_HOST],
                   config[CONF_NAME],
                   config[CONF_ADVANCED_CONFIG],
                   config[CONF_SCHEDULE_WEEKDAY],
                   config[CONF_SCHEDULE_WEEKDAY],
                   config[CONF_MIN_TEMP],
                   config[CONF_MAX_TEMP],
                   STATE_OFF,
                   STATE_HEAT,
                   STATE_AUTO
                   )

    add_devices([BroadlinkThermostat(wifi_thermostat)], True)

@asyncio.coroutine
    def handle_set_schedule(service):
        """Handle data for the set_schedule service call."""
        schedule_wd = service.data.get(CONF_WEEKDAY)
        schedule_we = service.data.get(CONF_WEEKEND)
        wifi_thermostat.set_schedule(
                                     {CONF_WEEKDAY:
                                     json.loads(schedule_wd.replace("'", '"')),
                                     CONF_WEEKEND:
                                     json.loads(schedule_we.replace("'", '"'))})
    
    hass.services.register(DOMAIN,
                           'set_schedule',
                           handle_set_schedule,
                           schema=SET_SCHEDULE_SCHEMA)
        
                           @asyncio.coroutine
                           def handle_set_advanced_conf(service):
                               """Handle data for the set_advanced_conf service call."""
                                   advanced_conf = service.data.get(CONF_ADVANCED_CONFIG)
                                   wifi_thermostat.set_advanced_config(
                                                                       json.loads(advanced_conf.replace("'", '"')))

hass.services.register(DOMAIN,
                       'set_advanced_conf',
                       handle_set_advanced_conf,
                       schema=SET_ADVANCED_CONF_SCHEMA)

_LOGGER.debug("Wifi Thermostat: Component successfully added !")


class BroadlinkThermostat(ClimateDevice):
    """Representation of a Broadlink Thermostat device."""
    
    def __init__(self, device):
        """Initialize the climate device."""
        self._device = device
    
    @property
    def state(self):
        return self._device.current_operation
    
    @property
    def supported_features(self):
        """Return the list of supported features."""
        return SUPPORT_TARGET_TEMPERATURE \
            | SUPPORT_OPERATION_MODE

@property
    def should_poll(self):
        """Return the polling state."""
        return True
    
    @property
    def name(self):
        """Return the name of the thermostat."""
        return self._device.name
    
    @property
    def temperature_unit(self):
        """Return the unit of measurement."""
        return TEMP_CELSIUS
    
    @property
    def current_temperature(self):
        """Return the sensor temperature."""
        return self._device.current_temp
    
    @property
    def target_temperature(self):
        """Return the temperature we try to reach."""
        return self._device.target_temperature
    
    @property
    def target_temperature_high(self):
        """Return the highbound target temperature we try to reach."""
        return self._device.max_temp
    
    @property
    def target_temperature_low(self):
        """Return the lowbound target temperature we try to reach."""
        return self._device.min_temp
    
    @property
    def current_operation(self):
        """Return current operation."""
        return self._device.current_operation
    
    @property
    def operation_list(self):
        """List of available operation modes."""
        return [STATE_AUTO, STATE_HEAT, STATE_OFF]
    
    def set_temperature(self, **kwargs):
        """Set new target temperature."""
        if kwargs.get(ATTR_TEMPERATURE) is not None:
            self._device.set_temperature(kwargs.get(ATTR_TEMPERATURE))
        self.schedule_update_ha_state()
    
    def set_operation_mode(self, operation_mode):
        """Set operation mode."""
        self._device.set_operation_mode(operation_mode)
        self.schedule_update_ha_state()
    
    @property
    def is_on(self):
        """Return true if the device is on."""
        return False if self._device.current_operation == STATE_OFF else True
    
    def set_advance_config(self, config_json):
        """Set the thermostat advanced config"""
        self._device.set_advanced_config(json.loads(config_json))
        self.schedule_update_ha_state()
    
    def set_schedule(self, schedule_json):
        """Set the thermostat schedule"""
        self._device.set_schedule(json.loads(schedule_json))
        self.schedule_update_ha_state()
    
    def update(self):
        """Update component data"""
        self._device.read_status()

still receiving errors

2018-09-24 21:27:46 ERROR (MainThread) [aiohttp.server] Error handling request
Traceback (most recent call last):
  File "/usr/local/lib/python3.6/site-packages/aiohttp/web_protocol.py", line 390, in start
    resp = await self._request_handler(request)
  File "/usr/local/lib/python3.6/site-packages/aiohttp/web_app.py", line 366, in _handle
    resp = await handler(request)
  File "/usr/local/lib/python3.6/site-packages/aiohttp/web_middlewares.py", line 106, in impl
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/static.py", line 66, in staticresource_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/real_ip.py", line 34, in real_ip_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/ban.py", line 67, in ban_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/auth.py", line 68, in auth_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/real_ip.py", line 34, in real_ip_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/ban.py", line 67, in ban_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/auth.py", line 68, in auth_middleware
    return await handler(request)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/http/view.py", line 113, in handle
    result = await result
  File "/usr/local/lib/python3.6/site-packages/homeassistant/components/config/core.py", line 24, in post
    errors = yield from async_check_ha_config_file(request.app['hass'])
  File "/usr/local/lib/python3.6/site-packages/homeassistant/config.py", line 793, in async_check_ha_config_file
    check_ha_config_file, hass)
  File "/usr/local/lib/python3.6/concurrent/futures/thread.py", line 56, in run
    result = self.fn(*self.args, **self.kwargs)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/scripts/check_config.py", line 372, in check_ha_config_file
    platform = loader.get_platform(hass, domain, p_name)
  File "/usr/local/lib/python3.6/site-packages/homeassistant/loader.py", line 62, in get_platform
    return get_component(hass, PLATFORM_FORMAT.format(domain, platform))
  File "/usr/local/lib/python3.6/site-packages/homeassistant/loader.py", line 94, in get_component
    module = importlib.import_module(path)
  File "/usr/local/lib/python3.6/importlib/__init__.py", line 126, in import_module
    return _bootstrap._gcd_import(name[level:], package, level)
  File "<frozen importlib._bootstrap>", line 994, in _gcd_import
  File "<frozen importlib._bootstrap>", line 971, in _find_and_load
  File "<frozen importlib._bootstrap>", line 955, in _find_and_load_unlocked
  File "<frozen importlib._bootstrap>", line 665, in _load_unlocked
  File "<frozen importlib._bootstrap_external>", line 674, in exec_module
  File "<frozen importlib._bootstrap_external>", line 781, in get_code
  File "<frozen importlib._bootstrap_external>", line 741, in source_to_code
  File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
  File "/config/custom_components/climate/broadlink.py", line 150
    def handle_set_schedule(service):
    ^
IndentationError: unexpected indent

This is my folder structure.

@mufidsyed:
It seems you have somsming wierd with your copy/past, maybe i’ts from github,
Try whith this: https://raw.githubusercontent.com/clementTal/home-assistant/add_broadlink_climate/homeassistant/components/climate/broadlink.py
(right click, save as)

you were right. some weird copy paste error. now all that is done it is starting up. but now I have a new problem.

2018-09-24 22:03:23 WARNING (MainThread) [homeassistant.helpers.entity] Update of climate.main_hall is taking over 10 seconds
2018-09-24 22:03:23 ERROR (SyncWorker_18) [BroadlinkWifiThermostat] read_status timeout
2018-09-24 22:03:34 WARNING (MainThread) [homeassistant.helpers.entity] Update of climate.master_bedroom is taking over 10 seconds
2018-09-24 22:03:34 ERROR (SyncWorker_5) [BroadlinkWifiThermostat] read_status timeout

I am trying to fix this but do you have any idea??

I have the below in my config,yaml.

climate:
  - platform: broadlink
    name: "main_hall"
    mac: "XX:XX:XX:XX:XX:XX"
    host: "192.168.1.106"
  - platform: broadlink
    name: "master_bedroom"
    mac: "XX:XX:XX:XX:XX:XX"
    host: "192.168.1.204"

the Mac address is hidden and I have used the ip for the thermostat from my router for the host address