Skip to content

Commit

Permalink
Merge branch 'master' of https://github.com/PeteRager/lennoxs30
Browse files Browse the repository at this point in the history
  • Loading branch information
PeteRager committed Jan 20, 2024
2 parents 5d14233 + 76e0b80 commit c3cf764
Show file tree
Hide file tree
Showing 40 changed files with 467 additions and 143 deletions.
22 changes: 14 additions & 8 deletions .vscode/launch.json
Original file line number Diff line number Diff line change
@@ -1,11 +1,17 @@
{
"version": "0.2.0",
"configurations": [
{
"name": "Debug test",
"type": "python",
"request": "attach",
"justMyCode": false
}
]
{
"name": "Python: Debug Tests",
"type": "python",
"request": "launch",
"program": "${file}",
"purpose": ["debug-test"],
"console": "integratedTerminal",
"justMyCode": false,
"presentation": {
"hidden": true, // keep original launch order in 'run and debug' tab
}
},
],
"version": "0.2.0"
}
8 changes: 6 additions & 2 deletions .vscode/settings.json
Original file line number Diff line number Diff line change
@@ -1,7 +1,10 @@
{
"python.testing.pytestArgs": ["tests", "--asyncio-mode=auto"],
"python.testing.pytestArgs": [
"tests","--asyncio-mode=auto"
],
"python.testing.unittestEnabled": false,
"python.testing.pytestEnabled": true,
"python.experiments.enabled": false,
"cSpell.words": [
"ASHRAE",
"automations",
Expand All @@ -26,5 +29,6 @@
"python.linting.flake8Enabled": false,
"python.linting.enabled": true,
"python.linting.flake8Args": ["--config=setup.cfg", "--doctests"],
"python.linting.pylintEnabled": true
"python.linting.pylintEnabled": true,

}
54 changes: 18 additions & 36 deletions README.MD
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ Cloud Connections depending on the device model. We believe these configurations
- Passwords with special characters are not properly supported by the Lennox Cloud API and may not work. Known special characters that cause issues are & and ^. If your password contains these characters you may need to change it prior to using the integration.
- Adjusting the fan CFM in a single zone system causes some diagnostics to stop updating. Changing the diag_level to 0 and back to 2 solves the issue. A script is available [here](./samples/set_fan_cfm)
- A power outage to the Lennox Controller causes the diag_level to be reset to 0 on reboot. An automation/package is available [here](./samples/diaglevel) to automatically reset.
- If you add new equipment (BLE Sensors), restart HA in order for the integration to pickup the new equipment.

# Planning your install

Expand Down Expand Up @@ -58,43 +59,9 @@ If you like this integration

HACS is recommended as it provides automated install and will notify you when updates are available.

This assumes you have [HACS](https://github.com/hacs/integration) installed and know how to use it. If you need help with this, go to the HACS project documentation. This documentation is based on HACS 1.23.0 - other versions may have different UI.
This assumes you have [HACS](https://github.com/hacs/integration) installed and know how to use it. If you need help with this, go to the HACS project documentation.

Add custom repository in _HACS_

1. Click on HACS in your menu to open the HACS panel, then click on integrations (https://your.domain/hacs/integrations).
1. Click on the 3 dots in the top right corner.
1. Select "Custom repositories"
1. Add the URL to the repository: `https://github.com/PeteRager/lennoxs30`
1. Select the integration category.
1. Click the "ADD" button.

Once done, you should see the new repository, appearing in a list like this. Click the **Download** button

![plot](./doc_images/hacs_1.PNG)

After clicking download, you will be prompted for which version to download. Select the latest - which will be the default - and click download.

![plot](./doc_images/hacs_2.PNG)

Once the download is complete, you will see that to make the component available requires a restart. Restart Home Assistant.

![plot](./doc_images/hacs_3.PNG)

Once Home Assistant restarts and you navigate to HACS. This screen should appear showing the component is added.

![plot](./doc_images/hacs_4.PNG)

Next go to Home Assistant / Configuration / Integrations and select add integration. Search for lennox. Select the integration and follow the [Configuration Steps](#Configuration)

![plot](./doc_images/hacs_5.PNG)

Alternate HACS instructions for old versions - Add integration in _HACS_

1. In the HACS panel, go to integrations and click the '+ Explore & add repositories' button.
1. Search for `Lennox iComfort WiFi Thermostat Integration` and click `Install this repository in HACS`.
1. Restart HA to load the integration into HA.<br>
1. Follow the Configuration Instructions below
As of October 2023, this integration is included in the HACS default configuration.

## Manually

Expand Down Expand Up @@ -489,6 +456,21 @@ Example JSON
]
```

### wifi_rssi

Local Connections Only. Reports the WIFI signal strength, this sensor can be used to diagnose WIFI dropout issues.

Attribute | Type | Description |
| -------------------------- | ----------- | ------------------------------------------------------------------- |
| macAddr | string | MAC Address of the controller |
| ssid | string | WIFI network name |
| ip | string | IP Address of the controller |
| router | string | IP Address of the router gateway |
| dns | string | DNS IP Address |
| dns2 | string | Secondary DNS IP address |
| subnetMask | string | LAN subnet mask |
| bitrate | float | WIFI connection bitrate |

## Select Entities

### Humidity Mode
Expand Down
11 changes: 5 additions & 6 deletions custom_components/lennoxs30/binary_sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,8 +12,7 @@
from homeassistant.helpers.entity_platform import AddEntitiesCallback
from homeassistant.helpers.entity import DeviceInfo, EntityCategory
from homeassistant.components.binary_sensor import (
DEVICE_CLASS_PRESENCE,
DEVICE_CLASS_CONNECTIVITY,
BinarySensorDeviceClass,
BinarySensorEntity,
)

Expand Down Expand Up @@ -181,7 +180,7 @@ def device_info(self) -> DeviceInfo:

@property
def device_class(self):
return DEVICE_CLASS_PRESENCE
return BinarySensorDeviceClass.PRESENCE


class S30InternetStatus(S30BaseEntityMixin, BinarySensorEntity):
Expand Down Expand Up @@ -241,7 +240,7 @@ def device_info(self) -> DeviceInfo:

@property
def device_class(self):
return DEVICE_CLASS_CONNECTIVITY
return BinarySensorDeviceClass.CONNECTIVITY

@property
def entity_category(self):
Expand Down Expand Up @@ -304,7 +303,7 @@ def device_info(self) -> DeviceInfo:

@property
def device_class(self):
return DEVICE_CLASS_CONNECTIVITY
return BinarySensorDeviceClass.CONNECTIVITY

@property
def entity_category(self):
Expand Down Expand Up @@ -376,7 +375,7 @@ def device_info(self) -> DeviceInfo:

@property
def device_class(self):
return DEVICE_CLASS_CONNECTIVITY
return BinarySensorDeviceClass.CONNECTIVITY

@property
def entity_category(self):
Expand Down
11 changes: 5 additions & 6 deletions custom_components/lennoxs30/climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -25,8 +25,7 @@
)
from homeassistant.const import (
ATTR_TEMPERATURE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
UnitOfTemperature,
)
from homeassistant.core import HomeAssistant
from homeassistant.config_entries import ConfigEntry
Expand Down Expand Up @@ -225,8 +224,8 @@ def supported_features(self):
def temperature_unit(self):
"""Return the unit of measurement."""
if self._manager.is_metric is False:
return TEMP_FAHRENHEIT
return TEMP_CELSIUS
return UnitOfTemperature.FAHRENHEIT
return UnitOfTemperature.CELSIUS

@property
def min_temp(self):
Expand All @@ -237,7 +236,7 @@ def min_temp(self):
if self._manager.is_metric is False:
return self._zone.minCsp
return self._zone.minCspC
if self._zone.systemMode == LENNOX_HVAC_HEAT:
if self._zone.systemMode in [LENNOX_HVAC_HEAT,LENNOX_HVAC_EMERGENCY_HEAT]:
if self._manager.is_metric is False:
return self._zone.minHsp
return self._zone.minHspC
Expand All @@ -264,7 +263,7 @@ def max_temp(self):
if self._manager.is_metric is False:
return self._zone.maxCsp
return self._zone.maxCspC
if self._zone.systemMode == LENNOX_HVAC_HEAT:
if self._zone.systemMode in [LENNOX_HVAC_HEAT,LENNOX_HVAC_EMERGENCY_HEAT]:
if self._manager.is_metric is False:
return self._zone.maxHsp
return self._zone.maxHspC
Expand Down
1 change: 1 addition & 0 deletions custom_components/lennoxs30/const.py
Original file line number Diff line number Diff line change
Expand Up @@ -46,6 +46,7 @@
UNIQUE_ID_SUFFIX_BLE: Final = "_BLE"
UNIQUE_ID_SUFFIX_BLE_COMMSTATUS: Final = "_BLE_COMMSTATUS"
UNIQUE_ID_SUFFIX_VENTILATION_SELECT: Final = "_VENT_SELECT"
UNIQUE_ID_SUFFIX_WIFI_RSSI: Final = "_WIFI_RSSI"

VENTILATION_EQUIPMENT_ID = -900

Expand Down
2 changes: 1 addition & 1 deletion custom_components/lennoxs30/diagnostics.py
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
"""Diagnostics support for Nest."""
"""Diagnostics support for LennoxS30."""
# pylint: disable=line-too-long
from __future__ import annotations
from typing import Any
Expand Down
4 changes: 2 additions & 2 deletions custom_components/lennoxs30/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,6 @@
"iot_class": "local_push",
"issue_tracker" : "https://github.com/PeteRager/lennoxs30/issues",
"quality_scale": "platinum",
"requirements": ["lennoxs30api==0.2.10"],
"version": "2023.10.1"
"requirements": ["lennoxs30api==0.2.12"],
"version": "2024.1.1"
}
11 changes: 5 additions & 6 deletions custom_components/lennoxs30/number.py
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,8 @@
from homeassistant.components.number import NumberEntity
from homeassistant.const import (
PERCENTAGE,
TEMP_CELSIUS,
TEMP_FAHRENHEIT,
TIME_MINUTES,
UnitOfTemperature,
UnitOfTime,
)
from homeassistant.helpers import config_validation as cv
from homeassistant.exceptions import HomeAssistantError
Expand Down Expand Up @@ -234,8 +233,8 @@ def name(self):
@property
def native_unit_of_measurement(self):
if self._manager.is_metric is False:
return TEMP_FAHRENHEIT
return TEMP_CELSIUS
return UnitOfTemperature.FAHRENHEIT
return UnitOfTemperature.CELSIUS

@property
def native_max_value(self) -> float:
Expand Down Expand Up @@ -427,7 +426,7 @@ async def async_set_native_value(self, value: float) -> None:

@property
def native_unit_of_measurement(self):
return TIME_MINUTES
return UnitOfTime.MINUTES

@property
def device_info(self) -> DeviceInfo:
Expand Down
5 changes: 4 additions & 1 deletion custom_components/lennoxs30/sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -48,9 +48,9 @@
from .ble_device_21p02 import lennox_21p02_sensors, lennox_iaq_sensors
from .sensor_ble import S40BleSensor
from .sensor_iaq import S40IAQSensor
from .sensor_wifi import WifiRSSISensor
from .sensor_wt_env import lennox_wt_env_sensors, WTEnvSensor, lennox_wt_env_sensors_metric, lennox_wt_env_sensors_us


_LOGGER = logging.getLogger(__name__)

DOMAIN = "lennoxs30"
Expand Down Expand Up @@ -175,6 +175,9 @@ async def async_setup_entry(hass: HomeAssistant, entry: ConfigEntry, async_add_e
ble_device.controlModelNumber,
)

if manager.api.isLANConnection:
sensor_list.append(WifiRSSISensor(hass, manager, system))

if len(sensor_list) != 0:
async_add_entities(sensor_list, True)
return True
Expand Down
92 changes: 92 additions & 0 deletions custom_components/lennoxs30/sensor_wifi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
"""Support for Lennoxs30 outdoor temperature sensor"""
# pylint: disable=global-statement
# pylint: disable=broad-except
# pylint: disable=unused-argument
# pylint: disable=line-too-long
# pylint: disable=invalid-name
import logging
from typing import Any

from homeassistant.core import HomeAssistant
from homeassistant.helpers.entity import DeviceInfo
from homeassistant.components.sensor import SensorEntity
from homeassistant.components.sensor import SensorStateClass, SensorDeviceClass
from homeassistant.const import SIGNAL_STRENGTH_DECIBELS_MILLIWATT
from homeassistant.helpers.entity import EntityCategory

from lennoxs30api import lennox_system

from . import Manager
from .base_entity import S30BaseEntityMixin
from .const import LENNOX_DOMAIN, UNIQUE_ID_SUFFIX_WIFI_RSSI

_LOGGER = logging.getLogger(__name__)

class WifiRSSISensor(S30BaseEntityMixin, SensorEntity):
"""Class for Lennox S40 WTEnvSensor Sensors."""

def __init__(self, hass: HomeAssistant, manager: Manager, system: lennox_system):
super().__init__(manager, system)
self._hass = hass
self._myname = self._system.name + "_wifi_rssi"

async def async_added_to_hass(self) -> None:
"""Run when entity about to be added to hass."""
_LOGGER.debug("async_added_to_hass WifiRSSISensor myname [%s]", self._myname)
self._system.registerOnUpdateCallback(
self.update_callback,
["wifi_rssi", "wifi_macAddr", "wifi_ssid", "wifi_ip", "wifi_router","wifi_dns","wifi_dns2","wifi_subnetMask","wifi_bitRate"],
)
await super().async_added_to_hass()

def update_callback(self):
"""Callback to execute on data change"""
_LOGGER.debug("update_callback WifiRSSISensor myname [%s]", self._myname)
self.schedule_update_ha_state()

@property
def unique_id(self) -> str:
return (self._system.unique_id + UNIQUE_ID_SUFFIX_WIFI_RSSI).replace("-", "")

@property
def extra_state_attributes(self):
"""Return the state attributes."""
attrs: dict[str, Any] = {}
attrs["macAddr"] = self._system.wifi_macAddr
attrs["ssid"] = self._system.wifi_ssid
attrs["ip"] = self._system.wifi_ip
attrs["router"] = self._system.wifi_router
attrs["dns"] = self._system.wifi_dns
attrs["dns2"] = self._system.wifi_dns2
attrs["subnetMask"] = self._system.wifi_subnetMask
attrs["bitRate"] = self._system.wifi_bitRate
return attrs
@property
def name(self):
return self._myname

@property
def native_value(self):
return self._system.wifi_rssi

@property
def native_unit_of_measurement(self):
return SIGNAL_STRENGTH_DECIBELS_MILLIWATT

@property
def device_class(self):
return SensorDeviceClass.SIGNAL_STRENGTH

@property
def state_class(self):
return SensorStateClass.MEASUREMENT

@property
def device_info(self) -> DeviceInfo:
return {
"identifiers": {(LENNOX_DOMAIN, self._system.unique_id)},
}

@property
def entity_category(self):
return EntityCategory.DIAGNOSTIC

0 comments on commit c3cf764

Please sign in to comment.