Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Fixes issue #40 and general improvements #58

Open
wants to merge 9 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Jump to
Jump to file
Failed to load files.
Diff view
Diff view
7 changes: 7 additions & 0 deletions .idea/hass-intesisbox.iml
Copy link
Collaborator

Choose a reason for hiding this comment

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

It looks like you added quite a few files to the PR unintentionally. Could you push another commit that removes these again please?

Copy link
Author

Choose a reason for hiding this comment

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

Goodness, that was fun, my bad. Removed and added to .gitignore.

Copy link
Author

Choose a reason for hiding this comment

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

@jbergler are we good to go here?

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 6 additions & 0 deletions .idea/inspectionProfiles/profiles_settings.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/misc.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 4 additions & 0 deletions .idea/shelf/Changes.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

112 changes: 112 additions & 0 deletions .idea/shelf/Changes/shelved.patch

Large diffs are not rendered by default.

6 changes: 6 additions & 0 deletions .idea/vcs.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

102 changes: 102 additions & 0 deletions .idea/workspace.xml

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

Binary file added custom_components/.DS_Store
Binary file not shown.
Binary file added custom_components/intesisbox/.DS_Store
Binary file not shown.
8 changes: 6 additions & 2 deletions custom_components/intesisbox/climate.py
Expand Up @@ -4,6 +4,8 @@
https://github.com/jnimmo/hass-intesisbox
"""

from __future__ import annotations

import asyncio
from datetime import timedelta
import logging
Expand Down Expand Up @@ -406,8 +408,10 @@ def hvac_mode(self):

@property
def target_temperature(self):
"""Return the current setpoint temperature if unit is on."""
return self._target_temperature
"""Return the current setpoint temperature if unit is on and not FAN or OFF Mode."""
if self._power and self.hvac_mode not in [HVACMode.FAN_ONLY, HVACMode.OFF]:
return self._target_temperature
return None

@property
def supported_features(self):
Expand Down
48 changes: 41 additions & 7 deletions custom_components/intesisbox/intesisbox.py
@@ -1,5 +1,7 @@
"""Communication with an Intesisbox device."""

from __future__ import annotations

import asyncio
from asyncio import BaseTransport, ensure_future
from collections.abc import Callable
Expand Down Expand Up @@ -78,6 +80,15 @@ async def keep_alive(self):
else:
_LOGGER.debug("Not connected, skipping keepalive")

async def poll_ambtemp(self):
"""Retrieve Ambient Temperature to prevent integration timeouts."""
while self.is_connected:
_LOGGER.debug("Sending AMBTEMP")
self._write("GET,1:AMBTEMP")
await asyncio.sleep(10)
jbergler marked this conversation as resolved.
Show resolved Hide resolved
else:
_LOGGER.debug("Not connected, skipping Ambient Temp Request")

async def query_initial_state(self):
"""Fetch configuration from the device upon connection."""
cmds = [
Expand All @@ -96,6 +107,12 @@ def _write(self, cmd):
self._transport.write(f"{cmd}\r".encode("ascii"))
_LOGGER.debug(f"Data sent: {cmd!r}")

async def _writeasync(self, cmd):
"""Async write to slow down commands and await response from units."""
self._transport.write(f"{cmd}\r".encode("ascii"))
_LOGGER.debug(f"Data sent: {cmd!r}")
await asyncio.sleep(1)
jbergler marked this conversation as resolved.
Show resolved Hide resolved

def data_received(self, data):
"""Asyncio callback when data is received on the socket."""
linesReceived = data.decode("ascii").splitlines()
Expand All @@ -111,8 +128,8 @@ def data_received(self, data):
if cmd == "ID":
self._parse_id_received(args)
self._connectionStatus = API_AUTHENTICATED
_ = asyncio.ensure_future(self.keep_alive())
_ = asyncio.ensure_future(self.poll_status())
_ = asyncio.ensure_future(self.poll_ambtemp())
elif cmd == "CHN,1":
self._parse_change_received(args)
statusChanged = True
Expand Down Expand Up @@ -244,17 +261,34 @@ def set_horizontal_vane(self, vane: str):
def _set_value(self, uid: str, value: str | int) -> None:
"""Change a setting on the thermostat."""
try:
self._write(f"SET,1:{uid},{value}")
asyncio.run(self._writeasync(f"SET,1:{uid},{value}"))
except Exception as e:
_LOGGER.error("%s Exception. %s / %s", type(e), e.args, e)

def set_mode(self, mode: str) -> None:
"""Change the thermostat mode (heat, cool, etc)."""
if not self.is_on:
self.set_power_on()

def set_mode(self, mode):
"""Send mode and confirm change before turning on."""
"""Some units return responses out of order"""
_LOGGER.debug(f"Setting MODE to {mode}.")
if mode in MODES:
self._set_value(FUNCTION_MODE, mode)
if not self.is_on:
"""Check to ensure in correct mode before turning on"""
retry = 30
while self.mode != mode and retry > 0:
jbergler marked this conversation as resolved.
Show resolved Hide resolved
_LOGGER.debug(
f"Waiting for MODE to return {mode}, currently {str(self.mode)}"
)
_LOGGER.debug(f"Retry attempt = {retry}")
asyncio.run(self._writeasync("GET,1:MODE"))
retry -= 1
else:
if retry != 0:
_LOGGER.debug(
f"MODE confirmed now {str(self.mode)}, proceed to Power On"
)
self.set_power_on()
else:
_LOGGER.error("Cannot set Intesisbox mode giving up...")

def set_mode_dry(self):
"""Public method to set device to dry asynchronously."""
Expand Down