Hi @etreus, there is no way to control the thermostat locally and not through their cloud?
the WI-FI BOX does not expose a local server?
thanks.
Hi @etreus, there is no way to control the thermostat locally and not through their cloud?
the WI-FI BOX does not expose a local server?
thanks.
Hi, i just found that the only opened port of the box is 80.
You can reach it via browser but it asks for a user and password , nothing i tryed worked.
hello e treus thanks for having done this integration, I’m new to Home assistant, could you explain better how to upload your integration?
where should i create the folder?
Why can’t I find the home / homeassistant path …
thanks for the help
hello @nicolamodo88,
you can install the component in 2 ways:
then you have to configure
climate:
- platform: besmart
name: Besmart Thermostat
username: <my-username>
password: <my-password>
room: <name assigned using BeSmart Application>
scan_interval: 10
I did several check but I did not found how manage the communication locally, sniffing the box traffic I have found that it is doing polling here http://api.besmart-home.com/fwUpgrade/PR06549/version.txt then I have found the firmware and using this you can find the username and password strings -n 10 be_smart_0654917080101.bin > string.out
but is quite useless since the webUI is working bad and has no smart function
if someone would like play whit his thermostat herewith the standalone version just set CONF_USERNAME and CONF_PASSWORD copy it in a file (you need requests module installed)
#! /usr/bin/env python
import logging
from datetime import datetime, timedelta
import requests
_LOGGER = logging.getLogger(__name__)
logging.basicConfig(format='%(levelname)s:%(message)s', level=logging.DEBUG)
# pylint: disable=abstract-method
# pylint: disable=too-many-instance-attributes
class Besmart(object):
"""Representation of a Besmart thermostat."""
BASE_URL = "http://www.besmart-home.com/Android_vokera_20160516/"
LOGIN = "login.php"
ROOM_MODE = "setRoomMode.php"
ROOM_LIST = "getRoomList.php?deviceId={0}"
ROOM_DATA = "getRoomData196.php?therId={0}&deviceId={1}"
ROOM_PROGRAM = "getProgram.php?roomId={0}"
ROOM_TEMP = "setRoomTemp.php"
ROOM_ECON_TEMP = "setEconTemp.php"
ROOM_FROST_TEMP = "setFrostTemp.php"
ROOM_CONF_TEMP = "setComfTemp.php"
GET_SETTINGS = "getSetting.php"
SET_SETTINGS = "setSetting.php"
def __init__(self, username, password):
"""Initialize the thermostat."""
self._username = username
self._password = password
self._lastupdate = None
self._device = None
self._rooms = None
self._timeout = 30
self._s = requests.Session()
def _fahToCent(self, temp):
return str(round((temp - 32.0) / 1.8, 1))
def _centToFah(self, temp):
return str(round(32.0 + (temp * 1.8), 1))
def login(self):
try:
resp = self._s.post(
self.BASE_URL + self.LOGIN,
data={"un": self._username, "pwd": self._password, "version": "32"},
timeout=self._timeout,
)
if resp.ok:
self._device = resp.json()
except Exception as ex:
_LOGGER.warning(ex)
self._device = None
def rooms(self):
if not self._device:
self.login()
try:
if self._device:
resp = self._s.post(
self.BASE_URL + self.ROOM_LIST.format(self._device.get("deviceId")),
timeout=self._timeout,
)
if resp.ok:
self._lastupdate = datetime.now()
self._rooms = dict(
(y.get("name").lower(), y)
for y in filter(lambda x: x.get("id") != None, resp.json())
)
_LOGGER.debug("rooms: {}".format(self._rooms))
if len(self._rooms) == 0:
self._device = None
self._lastupdate = None
return None
return self._rooms
else:
_LOGGER.debug("get rooms failed!")
except Exception as ex:
_LOGGER.warning(ex)
self._device = None
return None
def roomdata(self, room):
self.login()
try:
if self._device:
resp = self._s.get(
self.BASE_URL
+ self.ROOM_DATA.format(
room.get("therId"), self._device.get("deviceId")
),
timeout=self._timeout,
)
if resp.ok:
return resp.json()
else:
_LOGGER.debug("refresh roomdata failed for: {}".format(room))
except Exception as ex:
_LOGGER.warning(ex)
self._device = None
return None
def program(self, room):
self.login()
try:
resp = self._s.get(
self.BASE_URL + self.ROOM_PROGRAM.format(room.get("id")),
timeout=self._timeout,
)
if resp.ok:
return resp.json()
except Exception as ex:
_LOGGER.warning(ex)
self._device = None
return None
def roomByName(self, name):
if self._lastupdate is None or datetime.now() - self._lastupdate > timedelta(
seconds=120
):
_LOGGER.debug("refresh rooms state")
self.rooms()
if self._rooms:
return self.roomdata(self._rooms.get(name.lower()))
return None
def setRoomMode(self, room_name, mode):
room = self.roomByName(room_name)
if self._device and room:
data = {
"deviceId": self._device.get("deviceId"),
"therId": room.get("roomMark"),
"mode": mode,
}
resp = self._s.post(
self.BASE_URL + self.ROOM_MODE, data=data, timeout=self._timeout
)
if resp.ok:
msg = resp.json()
_LOGGER.debug("resp: {}".format(msg))
if msg.get("error") == 1:
return True
return None
def setRoomConfortTemp(self, room_name, new_temp):
return self.setRoomTemp(room_name, new_temp, self.ROOM_CONF_TEMP)
def setRoomECOTemp(self, room_name, new_temp):
return self.setRoomTemp(room_name, new_temp, self.ROOM_ECON_TEMP)
def setRoomFrostTemp(self, room_name, new_temp):
return self.setRoomTemp(room_name, new_temp, self.ROOM_FROST_TEMP)
def setRoomTemp(self, room_name, new_temp, url=None):
url = url or self.ROOM_TEMP
room = self.roomByName(room_name)
if room and self._device.get("deviceId"):
new_temp = round(new_temp, 1)
_LOGGER.debug("room: {}".format(room))
if room.get("tempUnit") in {"N/A", "0"}:
tpCInt, tpCIntFloat = str(new_temp).split(".")
else:
tpCInt, tpCIntFloat = self._fahToCent(new_temp).split(".")
_LOGGER.debug(
"setRoomTemp: {} - {} - {}".format(new_temp, tpCInt, tpCIntFloat)
)
data = {
"deviceId": self._device.get("deviceId"),
"therId": room.get("roomMark"),
"tempSet": tpCInt + "",
"tempSetFloat": tpCIntFloat + "",
}
_LOGGER.debug("url: {}".format(self.BASE_URL + url))
_LOGGER.debug("data: {}".format(data))
resp = self._s.post(self.BASE_URL + url, data=data, timeout=self._timeout)
if resp.ok:
msg = resp.json()
_LOGGER.debug("resp: {}".format(msg))
if msg.get("error") == 1:
return True
else:
_LOGGER.warning("error on get the room by name: {}".format(room_name))
return None
def getSettings(self, room_name):
room = self.roomByName(room_name)
if self._device and room:
data = {
"deviceId": self._device.get("deviceId"),
"therId": room.get("roomMark"),
}
resp = self._s.post(
self.BASE_URL + self.GET_SETTINGS, data=data, timeout=self._timeout
)
if resp.ok:
msg = resp.json()
_LOGGER.debug("resp: {}".format(msg))
if msg.get("error") == 0:
return msg
return None
def setSettings(self, room_name, season):
room = self.roomByName(room_name)
if self._device and room:
old_data = self.getSettings(room_name)
if old_data.get("error") == 0:
min_temp_set_point_ip, min_temp_set_point_fp = str(
old_data.get("minTempSetPoint", "30.0")
).split(".")
max_temp_set_point_ip, max_temp_set_point_fp = str(
old_data.get("maxTempSetPoint", "30.0")
).split(".")
temp_curver_ip, temp_curver_fp = str(
old_data.get("tempCurver", "0.0")
).split(".")
data = {
"deviceId": self._device.get("deviceId"),
"therId": room.get("roomMark"),
"minTempSetPointIP": min_temp_set_point_ip,
"minTempSetPointFP": min_temp_set_point_fp,
"maxTempSetPointIP": max_temp_set_point_ip,
"maxTempSetPointFP": max_temp_set_point_fp,
"sensorInfluence": old_data.get("sensorInfluence", "0"),
"tempCurveIP": temp_curver_ip,
"tempCurveFP": temp_curver_fp,
"unit": old_data.get("unit", "0"),
"season": season,
"boilerIsOnline": old_data.get("boilerIsOnline", "0"),
}
resp = self._s.post(
self.BASE_URL + self.SET_SETTINGS, data=data, timeout=self._timeout
)
if resp.ok:
msg = resp.json()
_LOGGER.debug("resp: {}".format(msg))
if msg.get("error") == 0:
return msg
return None
if __name__ == "__main__":
CONF_USERNAME=""
CONF_PASSWORD=""
client = Besmart(CONF_USERNAME, CONF_PASSWORD)
client.rooms()
thanks i managed to install everything, now it works perfectly, it was my problem on hacs.
excellent application, I am a beretta technician forced to use BeSmart … unfortunately the owner app occasionally leaves something to be desired …
Since few HA updates I am getting this warning. Is this something that can be easly fixed by You etreus?
2021-04-26 11:29:25 WARNING (MainThread) [homeassistant.loader] No ‘version’ key in the manifest file for custom integration ‘Besmart’. As of Home Assistant 2021.6, this integration will no longer be loaded. Please report this to the maintainer of ‘Besmart’
I love Your component but I don’t want to be stuck on version 2021.5 forever
Also did You have time to check if there is possibility to somehow track DHT heating time (indicated on besmart by blinking faucet and in mobile app by glowing faucet + fire) same as I am tracking central heating time?
You can add a line in the manifest to “bypass” the lack of the version, for example:
“version”: “0.9.9”
You wll not have the warning and you’ll be able to install new ha core version. Obviously is a workaround while waiting for the codeowner to update the “real” manifest with the “real” version number.
I have pushed a manifest with the version attribute let me know if it works, sorry but I have no enough time those days to play whit HA.
Salve a tutti, scusate la mia domanda da puro ignorante, ma ho installato il component solo che avendo 2 besmart, non riesco ad integrarli insieme, ma soltanto uno.
Mi sapreste indicare come fare?
Grazie mille
Hi guys, how can i set double climates with this component? The climates are under the same wifi and in the same house.
Thanks in advance
To configure more than 1 thermostat you just simply create 2 or more platform: besmart under the climate section of your yaml configuration.
Every section must have The room: parameter Like The name of the different room (thermostat) you gave in the besmart app.
@etreus how is Your free time nowadays? Any chance to dig into integration and try to pull DHT water heating notification/status which I mentioned Nov '20 It is also visible in besmart mobile app so the module definitely holds it somewhere
Hi @etreus ,
sorry for that, but to make it working locally, you suggested to change self._username and self._password, but I don’t get if CONF_USERNAME and CONF_PASSWORD are the value to set , that’s correct?
in order to connect locally do we need also to change the
BASE_URL = "http://www.besmart-home.com/Android_vokera_20160516/"
to point to local website?
regards
Hi guys, I’ve installed the integration some weeks ago and it worked great. Until today. I’ve updated home assistant to the last version (2022.2.0) and it stop working, I think that probably it’s a python issue. How can I fix the problem?
Thanks in Advance
This is what happens when I try to verify the configuration:
Platform error climate.besmart - cannot import name ‘ClimateDevice’ from ‘homeassistant.components.climate’ (/usr/src/homeassistant/homeassistant/components/climate/init.py)
Thanks
Did you solve it?
Or anyone else managed to upgrade to 2022.2.0 with no breaking change?
@Gianlu_Pi and @faxbio , ho ancora HA 2021, nel weekend provo ad aggiornare tutto e vedo se riesco a risolvere il problema
i’m on 2022.7.7 . Everything seems to work here.