Skip to content

Commit 921c9f7

Browse files
authored
Merge pull request #3 from yutoyazaki/feature/device_sensor
Display current temperature
2 parents 905c979 + 9eb9247 commit 921c9f7

File tree

4 files changed

+72
-54
lines changed

4 files changed

+72
-54
lines changed

README.md

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -2,10 +2,9 @@
22

33
Yet another [Home Assistant](https://www.home-assistant.io) component for [Nature Remo](https://en.nature.global/en/).
44

5-
⚠️This integration is not well-tested, very early alpha version and may not be maintained in the future. **Use at your own risk.** ⚠️
5+
⚠️This integration is neither Nature Remo official nor Home Assistant official. **Use at your own risk.** ⚠️
66

7-
<img src="./assets/screenshot_1.png" width="700">
8-
<img src="./assets/screenshot_2.png" width="300">
7+
<img src="./assets/screenshot_1.png" width="600"><img src="./assets/screenshot_2.png" width="200">
98

109
## Supported features
1110

@@ -14,6 +13,7 @@ Yet another [Home Assistant](https://www.home-assistant.io) component for [Natur
1413
- [x] Set temperature
1514
- [x] Set fan mode
1615
- [x] Set swing mode
16+
- [x] Show current temperature
1717
- [x] Remember previous target temperatures when switching modes back and forth
1818
- [x] Energy Sensor (Nature Remo E/E Lite)
1919
- [x] Fetch current power usage
@@ -61,4 +61,4 @@ nature_remo:
6161
access_token: YOUR_ACCESS_TOKEN
6262
```
6363
64-
※Tested on Home Assistant Core on Docker v0.110.5
64+
※Tested on Home Assistant Core on Docker v0.114.3

__init__.py

Lines changed: 44 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
from homeassistant.helpers import config_validation as cv, discovery
77
from homeassistant.helpers.aiohttp_client import async_get_clientsession
88
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
9+
from homeassistant.helpers.entity import Entity
910
from homeassistant.const import CONF_ACCESS_TOKEN
1011

1112
_LOGGER = logging.getLogger(__name__)
@@ -71,11 +72,14 @@ def __init__(self, access_token, session):
7172
self._session = session
7273

7374
async def get(self):
74-
"""Get appliance list"""
75-
_LOGGER.debug("Trying to fetch appliance list from API.")
75+
"""Get appliance and device list"""
76+
_LOGGER.debug("Trying to fetch appliance and device list from API.")
7677
headers = {"Authorization": f"Bearer {self._access_token}"}
7778
response = await self._session.get(f"{_RESOURCE}/appliances", headers=headers)
78-
return {x["id"]: x for x in await response.json()}
79+
appliances = {x["id"]: x for x in await response.json()}
80+
response = await self._session.get(f"{_RESOURCE}/devices", headers=headers)
81+
devices = {x["id"]: x for x in await response.json()}
82+
return {"appliances": appliances, "devices": devices}
7983

8084
async def post(self, path, data):
8185
"""Post any request"""
@@ -85,3 +89,40 @@ async def post(self, path, data):
8589
f"{_RESOURCE}{path}", data=data, headers=headers
8690
)
8791
return await response.json()
92+
93+
94+
class NatureRemoBase(Entity):
95+
"""Nature Remo entity base class."""
96+
97+
def __init__(self, coordinator, appliance):
98+
self._coordinator = coordinator
99+
self._name = f"Nature Remo {appliance['nickname']}"
100+
self._appliance_id = appliance["id"]
101+
self._device = appliance["device"]
102+
103+
@property
104+
def name(self):
105+
"""Return the name of the sensor."""
106+
return self._name
107+
108+
@property
109+
def unique_id(self):
110+
"""Return a unique ID."""
111+
return self._appliance_id
112+
113+
@property
114+
def should_poll(self):
115+
"""Return the polling requirement of the entity."""
116+
return False
117+
118+
@property
119+
def device_info(self):
120+
"""Return the device info for the sensor."""
121+
# Since device registration requires Config Entries, this dosen't work for now
122+
return {
123+
"identifiers": {(DOMAIN, self._device["id"])},
124+
"name": self._device["name"],
125+
"manufacturer": "Nature Remo",
126+
"model": self._device["serial_number"],
127+
"sw_version": self._device["firmware_version"],
128+
}

climate.py

Lines changed: 18 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -17,7 +17,7 @@
1717
SUPPORT_TARGET_TEMPERATURE,
1818
)
1919
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
20-
from . import DOMAIN, CONF_COOL_TEMP, CONF_HEAT_TEMP
20+
from . import DOMAIN, CONF_COOL_TEMP, CONF_HEAT_TEMP, NatureRemoBase
2121

2222
_LOGGER = logging.getLogger(__name__)
2323

@@ -50,7 +50,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
5050
coordinator = hass.data[DOMAIN]["coordinator"]
5151
api = hass.data[DOMAIN]["api"]
5252
config = hass.data[DOMAIN]["config"]
53-
appliances = coordinator.data
53+
appliances = coordinator.data["appliances"]
5454
async_add_entities(
5555
[
5656
NatureRemoAC(coordinator, api, appliance, config)
@@ -60,47 +60,36 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
6060
)
6161

6262

63-
class NatureRemoAC(ClimateEntity):
63+
class NatureRemoAC(NatureRemoBase, ClimateEntity):
6464
"""Implementation of a Nature Remo E sensor."""
6565

6666
def __init__(self, coordinator, api, appliance, config):
67-
self._coordinator = coordinator
67+
super().__init__(coordinator, appliance)
6868
self._api = api
6969
self._default_temp = {
7070
HVAC_MODE_COOL: config[CONF_COOL_TEMP],
7171
HVAC_MODE_HEAT: config[CONF_HEAT_TEMP],
7272
}
73-
self._name = f"Nature Remo {appliance['nickname']}"
74-
self._appliance_id = appliance["id"]
7573
self._modes = appliance["aircon"]["range"]["modes"]
7674
self._hvac_mode = None
75+
self._current_temperature = None
7776
self._target_temperature = None
7877
self._remo_mode = None
7978
self._fan_mode = None
8079
self._swing_mode = None
8180
self._last_target_temperature = {v: None for v in MODE_REMO_TO_HA}
8281
self._update(appliance["settings"])
8382

84-
@property
85-
def name(self):
86-
"""Return the name of the sensor."""
87-
return self._name
88-
89-
@property
90-
def unique_id(self):
91-
"""Return a unique ID."""
92-
return self._appliance_id
93-
94-
@property
95-
def should_poll(self):
96-
"""Return the polling requirement of the entity."""
97-
return False
98-
9983
@property
10084
def supported_features(self):
10185
"""Return the list of supported features."""
10286
return SUPPORT_FLAGS
10387

88+
@property
89+
def current_temperature(self):
90+
"""Return the current temperature."""
91+
return self._current_temperature
92+
10493
@property
10594
def temperature_unit(self):
10695
"""Return the unit of measurement which this thermostat uses."""
@@ -216,7 +205,7 @@ async def async_update(self):
216205
"""
217206
await self._coordinator.async_request_refresh()
218207

219-
def _update(self, ac_settings):
208+
def _update(self, ac_settings, device=None):
220209
# hold this to determin the ac mode while it's turned-off
221210
self._remo_mode = ac_settings["mode"]
222211
try:
@@ -233,9 +222,15 @@ def _update(self, ac_settings):
233222
self._fan_mode = ac_settings["vol"] or None
234223
self._swing_mode = ac_settings["dir"] or None
235224

225+
if device is not None:
226+
self._current_temperature = float(device["newest_events"]["te"]["val"])
227+
236228
@callback
237229
def _update_callback(self):
238-
self._update(self._coordinator.data[self._appliance_id]["settings"])
230+
self._update(
231+
self._coordinator.data["appliances"][self._appliance_id]["settings"],
232+
self._coordinator.data["devices"][self._device["id"]],
233+
)
239234
self.async_write_ha_state()
240235

241236
async def _post(self, data):

sensor.py

Lines changed: 6 additions & 24 deletions
Original file line numberDiff line numberDiff line change
@@ -7,8 +7,7 @@
77
POWER_WATT,
88
DEVICE_CLASS_POWER,
99
)
10-
from homeassistant.helpers.entity import Entity
11-
from . import DOMAIN
10+
from . import DOMAIN, NatureRemoBase
1211

1312
_LOGGER = logging.getLogger(__name__)
1413

@@ -19,7 +18,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
1918
return
2019
_LOGGER.debug("Setting up sensor platform.")
2120
coordinator = hass.data[DOMAIN]["coordinator"]
22-
appliances = coordinator.data
21+
appliances = coordinator.data["appliances"]
2322
async_add_entities(
2423
[
2524
NatureRemoE(coordinator, appliance)
@@ -29,35 +28,18 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
2928
)
3029

3130

32-
class NatureRemoE(Entity):
31+
class NatureRemoE(NatureRemoBase):
3332
"""Implementation of a Nature Remo E sensor."""
3433

3534
def __init__(self, coordinator, appliance):
36-
self._coordinator = coordinator
37-
self._name = f"Nature Remo {appliance['nickname']}"
38-
self._state = None
35+
super().__init__(coordinator, appliance)
3936
self._unit_of_measurement = POWER_WATT
40-
self._appliance_id = appliance["id"]
41-
42-
@property
43-
def name(self):
44-
"""Return the name of the sensor."""
45-
return self._name
46-
47-
@property
48-
def unique_id(self):
49-
"""Return a unique ID."""
50-
return self._appliance_id
51-
52-
@property
53-
def should_poll(self):
54-
"""Return the polling requirement of the entity."""
55-
return False
5637

5738
@property
5839
def state(self):
5940
"""Return the state of the sensor."""
60-
smart_meter = self._coordinator.data[self._appliance_id]["smart_meter"]
41+
appliance = self._coordinator.data["appliances"][self._appliance_id]
42+
smart_meter = appliance["smart_meter"]
6143
echonetlite_properties = smart_meter["echonetlite_properties"]
6244
measured_instantaneous = next(
6345
value["val"] for value in echonetlite_properties if value["epc"] == 231

0 commit comments

Comments
 (0)