Skip to content

Commit

Permalink
Merge pull request #3 from yutoyazaki/feature/device_sensor
Browse files Browse the repository at this point in the history
Display current temperature
  • Loading branch information
yutoyazaki authored Aug 22, 2020
2 parents 905c979 + 9eb9247 commit 921c9f7
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 54 deletions.
8 changes: 4 additions & 4 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,9 @@

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

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

<img src="./assets/screenshot_1.png" width="700">
<img src="./assets/screenshot_2.png" width="300">
<img src="./assets/screenshot_1.png" width="600"><img src="./assets/screenshot_2.png" width="200">

## Supported features

Expand All @@ -14,6 +13,7 @@ Yet another [Home Assistant](https://www.home-assistant.io) component for [Natur
- [x] Set temperature
- [x] Set fan mode
- [x] Set swing mode
- [x] Show current temperature
- [x] Remember previous target temperatures when switching modes back and forth
- [x] Energy Sensor (Nature Remo E/E Lite)
- [x] Fetch current power usage
Expand Down Expand Up @@ -61,4 +61,4 @@ nature_remo:
access_token: YOUR_ACCESS_TOKEN
```
※Tested on Home Assistant Core on Docker v0.110.5
※Tested on Home Assistant Core on Docker v0.114.3
47 changes: 44 additions & 3 deletions __init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,7 @@
from homeassistant.helpers import config_validation as cv, discovery
from homeassistant.helpers.aiohttp_client import async_get_clientsession
from homeassistant.helpers.update_coordinator import DataUpdateCoordinator
from homeassistant.helpers.entity import Entity
from homeassistant.const import CONF_ACCESS_TOKEN

_LOGGER = logging.getLogger(__name__)
Expand Down Expand Up @@ -71,11 +72,14 @@ def __init__(self, access_token, session):
self._session = session

async def get(self):
"""Get appliance list"""
_LOGGER.debug("Trying to fetch appliance list from API.")
"""Get appliance and device list"""
_LOGGER.debug("Trying to fetch appliance and device list from API.")
headers = {"Authorization": f"Bearer {self._access_token}"}
response = await self._session.get(f"{_RESOURCE}/appliances", headers=headers)
return {x["id"]: x for x in await response.json()}
appliances = {x["id"]: x for x in await response.json()}
response = await self._session.get(f"{_RESOURCE}/devices", headers=headers)
devices = {x["id"]: x for x in await response.json()}
return {"appliances": appliances, "devices": devices}

async def post(self, path, data):
"""Post any request"""
Expand All @@ -85,3 +89,40 @@ async def post(self, path, data):
f"{_RESOURCE}{path}", data=data, headers=headers
)
return await response.json()


class NatureRemoBase(Entity):
"""Nature Remo entity base class."""

def __init__(self, coordinator, appliance):
self._coordinator = coordinator
self._name = f"Nature Remo {appliance['nickname']}"
self._appliance_id = appliance["id"]
self._device = appliance["device"]

@property
def name(self):
"""Return the name of the sensor."""
return self._name

@property
def unique_id(self):
"""Return a unique ID."""
return self._appliance_id

@property
def should_poll(self):
"""Return the polling requirement of the entity."""
return False

@property
def device_info(self):
"""Return the device info for the sensor."""
# Since device registration requires Config Entries, this dosen't work for now
return {
"identifiers": {(DOMAIN, self._device["id"])},
"name": self._device["name"],
"manufacturer": "Nature Remo",
"model": self._device["serial_number"],
"sw_version": self._device["firmware_version"],
}
41 changes: 18 additions & 23 deletions climate.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,7 +17,7 @@
SUPPORT_TARGET_TEMPERATURE,
)
from homeassistant.const import ATTR_TEMPERATURE, TEMP_CELSIUS
from . import DOMAIN, CONF_COOL_TEMP, CONF_HEAT_TEMP
from . import DOMAIN, CONF_COOL_TEMP, CONF_HEAT_TEMP, NatureRemoBase

_LOGGER = logging.getLogger(__name__)

Expand Down Expand Up @@ -50,7 +50,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
coordinator = hass.data[DOMAIN]["coordinator"]
api = hass.data[DOMAIN]["api"]
config = hass.data[DOMAIN]["config"]
appliances = coordinator.data
appliances = coordinator.data["appliances"]
async_add_entities(
[
NatureRemoAC(coordinator, api, appliance, config)
Expand All @@ -60,47 +60,36 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
)


class NatureRemoAC(ClimateEntity):
class NatureRemoAC(NatureRemoBase, ClimateEntity):
"""Implementation of a Nature Remo E sensor."""

def __init__(self, coordinator, api, appliance, config):
self._coordinator = coordinator
super().__init__(coordinator, appliance)
self._api = api
self._default_temp = {
HVAC_MODE_COOL: config[CONF_COOL_TEMP],
HVAC_MODE_HEAT: config[CONF_HEAT_TEMP],
}
self._name = f"Nature Remo {appliance['nickname']}"
self._appliance_id = appliance["id"]
self._modes = appliance["aircon"]["range"]["modes"]
self._hvac_mode = None
self._current_temperature = None
self._target_temperature = None
self._remo_mode = None
self._fan_mode = None
self._swing_mode = None
self._last_target_temperature = {v: None for v in MODE_REMO_TO_HA}
self._update(appliance["settings"])

@property
def name(self):
"""Return the name of the sensor."""
return self._name

@property
def unique_id(self):
"""Return a unique ID."""
return self._appliance_id

@property
def should_poll(self):
"""Return the polling requirement of the entity."""
return False

@property
def supported_features(self):
"""Return the list of supported features."""
return SUPPORT_FLAGS

@property
def current_temperature(self):
"""Return the current temperature."""
return self._current_temperature

@property
def temperature_unit(self):
"""Return the unit of measurement which this thermostat uses."""
Expand Down Expand Up @@ -216,7 +205,7 @@ async def async_update(self):
"""
await self._coordinator.async_request_refresh()

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

if device is not None:
self._current_temperature = float(device["newest_events"]["te"]["val"])

@callback
def _update_callback(self):
self._update(self._coordinator.data[self._appliance_id]["settings"])
self._update(
self._coordinator.data["appliances"][self._appliance_id]["settings"],
self._coordinator.data["devices"][self._device["id"]],
)
self.async_write_ha_state()

async def _post(self, data):
Expand Down
30 changes: 6 additions & 24 deletions sensor.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,8 +7,7 @@
POWER_WATT,
DEVICE_CLASS_POWER,
)
from homeassistant.helpers.entity import Entity
from . import DOMAIN
from . import DOMAIN, NatureRemoBase

_LOGGER = logging.getLogger(__name__)

Expand All @@ -19,7 +18,7 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
return
_LOGGER.debug("Setting up sensor platform.")
coordinator = hass.data[DOMAIN]["coordinator"]
appliances = coordinator.data
appliances = coordinator.data["appliances"]
async_add_entities(
[
NatureRemoE(coordinator, appliance)
Expand All @@ -29,35 +28,18 @@ async def async_setup_platform(hass, config, async_add_entities, discovery_info=
)


class NatureRemoE(Entity):
class NatureRemoE(NatureRemoBase):
"""Implementation of a Nature Remo E sensor."""

def __init__(self, coordinator, appliance):
self._coordinator = coordinator
self._name = f"Nature Remo {appliance['nickname']}"
self._state = None
super().__init__(coordinator, appliance)
self._unit_of_measurement = POWER_WATT
self._appliance_id = appliance["id"]

@property
def name(self):
"""Return the name of the sensor."""
return self._name

@property
def unique_id(self):
"""Return a unique ID."""
return self._appliance_id

@property
def should_poll(self):
"""Return the polling requirement of the entity."""
return False

@property
def state(self):
"""Return the state of the sensor."""
smart_meter = self._coordinator.data[self._appliance_id]["smart_meter"]
appliance = self._coordinator.data["appliances"][self._appliance_id]
smart_meter = appliance["smart_meter"]
echonetlite_properties = smart_meter["echonetlite_properties"]
measured_instantaneous = next(
value["val"] for value in echonetlite_properties if value["epc"] == 231
Expand Down

0 comments on commit 921c9f7

Please sign in to comment.