yes, I think so but I don’t have this feature on my system
I can share the python script that I use to pull some information then if it works for you I can include on HA component.
yes, I think so but I don’t have this feature on my system
I can share the python script that I use to pull some information then if it works for you I can include on HA component.
We can try that, but I would need some info how to run it, I am not a pro when it comes to HA.
Hello,
I have moved the besmart integration script into a separate github repository in order to avoid confusion with other stuff.
Link https://github.com/muchasuerte/ha-besmart
I have done a pull request to include it on HACS repository list
Hi @etreus ,
I am trying to integrate this and I am getting an error on configuration.yaml check that beretta does not exist. I have added the same lines as in your example on github (chaning the username and password of course) and moved the custom _components folder on my installation
Error is Platform error climate.Besmart - Integration ‘Besmart’ not found.
can you help me out? I could not find the integration on HACS.
Thanks a lot
You need to add https://github.com/muchasuerte/ha-besmart into custom repositories in HACS options.
For me it is working perfectly, I can control all of my 3 besmarts from HA and I can see which of them and when were calling boiler for heating. I only miss info for domesitc heat water, I would love to have info when and for how long boiler was preparing DHW to adjust some other thing basing on that. On besmart preparing DHW is indicated by blinking faucet:
the steps are:
I’m using HA 0.113 which version are you using?
@etreus, thanks for your answer, I already copied what you have in the custom_components under a new folder called besmart. I already had custom_components created from other integrations instaled via HACS. I cannot find yours in HACS. I am getting the error described above
Platform error climate.Besmart - Integration ‘Besmart’ not found.
I am using 0.118
Hi @Gutek,
Thanks for your answer
I cannot find HACS options…in HACS I have Integrations to install and I cannot find this one there. I tried what @etreus suggested below before asking here but I still get that error. whcat do you mean by adding into custom repositories in HACS? adding to custom_component folder in homeassistant/config? as a folder next to the other components installed via HACS? because I already did that.
Thanks,
Vlad
Thanks, that really helped. Now I have the integration found in HACS after the restart (I cannot see it in HA -> Integration)
The next step was to go on the configuration.yaml and add:
climate:
with my own user and password of course. saved the file and when I go to check configuration I get the same:
Platform error climate.Besmart - Integration ‘Besmart’ not found.
Is it because of the HA version or I am still missing something?
the solution was simple…the platform is with a lower b so besmart not Besmart
now I am checking why I am seeing -17.8 - Off and Idle even though I have 22 degrees and it’s on…I checked the logs and it was because of the room, you have to set the same as the one in your Besmart phone application
thanks for this integration @etreus
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.