0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?

【HomeAssistant】Nature Remo E Liteから電力情報を取得する

Last updated at Posted at 2025-03-27

はじめに

これまで利用していたNature Remo用のカスタムインテグレーションが、HomeAssistantのバージョンアップに伴い不安定になってしまったため、この機会に自作でのカスタムインテグレーション開発に挑戦することにしました。

この記事では、Nature Remo E Liteを用いて、スマートメーターの電力情報(買電・売電・瞬時電力)をセンサーとして取得し、HomeAssistantで表示できるようにした内容をメモとしてまとめています。

環境

  • Ubuntu 24.04
  • HomeAssistant Core(開発環境)
  • Nature Remo E Lite(スマートメーター接続済み)
  • Python 3.13(venvによる仮想環境)
  • カスタムコンポーネント構成(custom_components/nature_remo/

使用したAPI:GET /1/appliances

Nature Remo Cloud APIの /1/appliances から、以下の電力情報が取得できます。
電力データ算出方法 | Nature Developer Page

name epc 内容
coefficient 211 倍率
cumulative_electric_energy_unit 225 単位補正(指数)
normal_direction_cumulative_electric_energy 224 買電(積算kWh)
reverse_direction_cumulative_electric_energy 227 売電(積算kWh)
measured_instantaneous 231 瞬時電力(W)

ディレクトリ構成(必要なファイルのみ抜粋)

custom_components/nature_remo/
├── __init__.py
├── api.py
├── sensor.py
└── coordinator.py

センサー処理の流れ

※今回の作業で追加した部分のみ抽出しています。

__init__.py
PLATFORMS = ["climate", "light", "sensor"] 

async def async_setup(hass: HomeAssistant, config: ConfigType) -> bool:
    """YAML設定をサポートするためのセットアップ処理."""
    hass.data.setdefault(DOMAIN, {})

    # YAMLの設定を保存
    if DOMAIN in config:
        _LOGGER.info("load config!!!")
        hass.data[DOMAIN] = config[DOMAIN]

    # APIクラスのインスタンスを作成して保存
    api = await create_api_client(token)
    hass.data[DOMAIN]["api"] = api

    # コーディネーターをHomeAssistantのデータ領域に保存
    coordinator = NatureRemoCoordinator(hass, api)
    hass.data[DOMAIN]["coordinator"] = coordinator

    # 初回更新
    await coordinator.async_refresh()

    for platform in PLATFORMS:
        hass.async_create_task(
            async_load_platform(hass, platform, DOMAIN, {}, hass.data[DOMAIN])
        )

    return True
api.py
def parse_smart_meter_properties(properties: list[dict]) -> dict:
    """
    Nature Remo E Liteのechonetlite_propertiesを元に
    買電・売電・瞬時電力を変換して返却する
    """
    # 値が欠損している場合にも備え、各種初期値を定義
    coefficient = 1
    unit_power = 0
    buy_power_raw = 0
    sold_power_raw = 0
    instant_power = 0

    for prop in properties:
        epc = int(prop.get("epc"))
        val_str = prop.get("val", "0")
        try:
            val = int(val_str)
        except ValueError:
            val = 0

        # epc(Echonet Lite Property)に応じて各値を格納
        if epc == 211:  # 係数
            coefficient = val
        elif epc == 215:  # 有効桁数(今回は使用せず)
            continue
        elif epc == 224:  # 積算買電量
            buy_power_raw = val
        elif epc == 225:  # 単位(指数)
            unit_power = val
        elif epc == 227:  # 積算売電量
            sold_power_raw = val
        elif epc == 231:  # 瞬時電力(W)
            instant_power = val

    # 単位変換テーブルを定義
    unit_table = {
        0x00: 1,
        0x01: 0.1,
        0x02: 0.01,
        0x03: 0.001,
        0x04: 0.0001,
        0x0A: 10,
        0x0B: 100,
        0x0C: 1000,
        0x0D: 10000
    }

    # 取得した値を変換
    factor = coefficient * unit_table.get(unit_power, 1)
    buy_power = buy_power_raw * factor
    sold_power = sold_power_raw * factor

    # センサー用データとして返却
    return {
        "buy_power": buy_power,
        "sold_power": sold_power,
        "instant_power": instant_power
    }
sensor.py
from homeassistant.components.sensor import SensorEntity
from homeassistant.helpers.update_coordinator import CoordinatorEntity

from .coordinator import NatureRemoCoordinator

DOMAIN = "nature_remo"

SENSOR_TYPES = {
    # センサー種別ごとの属性定義(表示名、単位、分類など)
    "buy_power": {
        "name": "Buy Power",
        "unit": "kWh",
        "device_class": "energy",    # energy device_class によりエネルギー統計に対応
        "state_class": "total_increasing",  # 積算データ扱いにすることでグラフ化などが可能に
    },
    "sold_power": {
        "name": "Sold Power",
        "unit": "kWh",
        "device_class": "energy",
        "state_class": "total_increasing",
    },
    "current_power": {
        "name": "Current Power",
        "unit": "W",
        "device_class": "power",
        "state_class": "measurement",
    },
}

async def async_setup_platform(hass, config, async_add_entities, discovery_info=None):
    coordinator = hass.data[DOMAIN]["coordinator"]
    entities = []

    # スマートメーターごとに、センサー(buy/sold/current)を生成
    for appliance_id, data in coordinator.smart_meters.items():
        for key, desc in SENSOR_TYPES.items():
            entities.append(
                NatureRemoSensor(
                    coordinator,
                    appliance_id,
                    data["name"],  # Remoの表示名
                    key,           # センサーの種類(buy/sold/current)
                    desc           # 属性(unit, device_classなど)
                )
            )
    # エンティティとしてHome Assistantに追加
    async_add_entities(entities)

class NatureRemoSensor(CoordinatorEntity, SensorEntity):
    def __init__(self, coordinator, appliance_id, name, key, description):
        super().__init__(coordinator)
        
        # センサーの基本情報をセット(Home Assistantが認識できる形式)
        self._appliance_id = appliance_id
        self._attr_name = f"{name} {description['name']}"
        self._attr_unique_id = f"{appliance_id}_{key}"  # 複数センサーが被らないように一意に設定
        self._attr_native_unit_of_measurement = description["unit"]
        self._attr_device_class = description["device_class"]
        self._attr_state_class = description["state_class"]
        self._key = key

    @property
    def native_value(self):
        # 現在の値をcoordinatorから取得して返す
        return self.coordinator.smart_meters[self._appliance_id][self._key]
coordinator.py
    async def _async_update_data(self):
        """APIを1回だけ呼び、appliancesの情報を取得."""
        try:
            self.smart_meters = {}
            appliances = await self.api.get_appliances()

            # 取得したappliancesからスマートメータの情報を取得
            for appliance in appliances:
                appliance_type = appliance.get("type")
                appliance_id = appliance.get("id")
                nickname = appliance.get("nickname", "Smart Meter")

                if appliance_type == "EL_SMART_METER":
                    properties = appliance.get("smart_meter", {}).get("echonetlite_properties", [])
                    parsed = parse_smart_meter_properties(properties)

                    self.smart_meters[appliance_id] = {
                        "name": nickname,
                        "buy_power": parsed["buy_power"],
                        "sold_power": parsed["sold_power"],
                        "current_power": parsed["instant_power"],
                    }

            return {ac["id"]: ac for ac in appliances}
        except ClientError as err:
            raise UpdateFailed(f"通信エラー: {err}") from err  # ネットワーク系のエラー

センサー表示例

エンティティ 単位 属性
sensor.sumatometa_buy_power 2647.52 kWh total_increasing, energy
sensor.sumatometa_sold_power 736.66 kWh total_increasing, energy
sensor.sumatometa_current_power 529 W measurement, power

今後の展望

  • エネルギーダッシュボードへの対応・視覚化
  • オートメーション連携(ピーク時通知、機器制御など)

まとめ

今回は、Nature Remo E Liteの電力情報を取得し、HomeAssistant上でセンサー化することで、エネルギーの見える化を実現しました。

同じようにスマートメーター連携を試してみたい方の参考になればと思います。

関連リンク

0
1
0

Register as a new user and use Qiita more conveniently

  1. You get articles that match your needs
  2. You can efficiently read back useful information
  3. You can use dark theme
What you can do with signing up
0
1

Delete article

Deleted articles cannot be recovered.

Draft of this article would be also deleted.

Are you sure you want to delete this article?