Home Assistant, Dyson 연동

본 글은 임시 저장소를 포함하고 있습니다.
최하단에 걸린 제 저장소는 임시 저장소 입니다. 원 저장소에 포함되게 되면 해당 내용을 업데이트 하도록 하겠습니다.

기존에 사용하고 있던 가열식 가습기가 점점 부담이 되는 계절이 다가오고 있다.

아무래도 가열식 자체가 방안의 온도를 높이는 원인이 되기 때문에 결국 에어컨을 벌써부터 병행하다가 가습기를 바꿔야겠다는 생각에 도달하게 되었고, 고민에 고민을 거듭하다가 결국 다이슨 휴미디파이+쿨 포름알데히드 가습 공기청정기를 구입하게 되었다.

구입한 이유는 아래와 같았다.

1. Home Assistant 연동이 된다.
2. 왠만한 공기질 모니터링이 모두 가능하다.
3. 멋지다!

그래서 큰 마음을 먹고 백화점에서 구입을 해서 집으로 배송되기만을 두근두근 기다리고 있었다. 이 때는 몰랐다.

아무튼, 조립을 하고 가습기 물통도 청소 한 번 해주고 설치 위치도 다시 잡아주고 신나서 설치를 끝내고 Home Assistant에 연동을 하려던 순간

왜죠? 왜 Dyson이 통합구성요소에서 안보이는 거죠?

그날은 늦은 시간이었기에 일단 멘붕을 뒤로하고, 다음날 검색을 해보니… 공식 지원에서 빠져있었다. 분명 내 기억으로는 있었던 것 같은데…

그래서 다시 폭풍 검색 결과 다행스럽게도 커스텀 컴포넌트를 제작하신 분이 있었고 잘된다는 이야기도 있어서 설치를 진행하였다.

1차 시도 : 결론부터 보자면 실패

위의 두 저장소를 HACS를 통해 설치해주고 전체 재시작을 해준다음에 설정을 눌렀지만… 오류가 나면서 실행이 되지 않는다…

그래서 혹 같은 문제를 가진 사람이 있나 싶어서 검색을 해보았더니 이미 이슈에 등록된 글이 많았다. 그 중 한 글을 보니 해당 프로젝트를 이어받아서 진행하시는 분이 있었다. 그래서 2차 시도로 넘어가게 되었다.

2차 시도 : 결론적으로 보자면 실패이지만 원인은 찾았다.

프로젝트를 이어받아 진행하시는 분의 저장소를 참조하여 설치를 진행해보았다. 설치방법은 1차 시도와 동일하나 저장소만 달라졌다.

1차 시도에 사용된 커스텀 컴포넌트를 HACS에서 삭제해주고, 저장소를 삭제한 후 위의 두 저장소를 저장하고 재설치를 수행하였다.

클라우드를 통해 로그인을 시도하자 정상적으로 로그인이 진행되었고, 로컬로 추가할 수 있다는 알림이 떴다! 끝이다! 라고 생각하고 장치를 추가했지만… 실패…

그렇다면 할 수 없다. 소스코드를 직접 확인하면서 디버깅을 수행해보자.

확인해보니 생각보다 심플한 문제였다. 해당 라이브러리는 libdyson-neon이라는 라이브러리를 사용하는데 해당 libdyson-neon 내부에

DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE = "358E"

위의 코드가 들어 있는데, 내가 가진 제품의 모델명이 “358K” 인 것이 문제였다. 그래서 수정이 필요하다는 것을 알게되었는데… 문제는 나는 이 문제를 빨리 해결하고 싶었다. 그래서 과감하게 1차적으로 libdyson-neon 라이브러리는 ha-dyson, ha-dyson-cloud 컴포넌트에 통합하고 코드를 수정하기로 하였다.

3차 시도 : 결론부터 보자면 성공

2차에서 발견한 문제점을 해결하기 위해서 해당 저장소를 포크하여 수정을 시작하였다. 수정한 내용은 다음과 같다.

1. 358K 모델명 추가 및 관련 코드 수정
2. libdyson-neon 라이브러리를 코드에 포함

2번의 경우는 import 경로만 수정해주면 되는 일이니 별도의 설명은 생략하고 1번의 경우는 아래와 같이 변경되었다.

기존코드(const.py)

from enum import Enum, auto
DEVICE_TYPE_360_EYE = "N223"
DEVICE_TYPE_360_HEURIST = "276"
DEVICE_TYPE_PURE_COOL_LINK = "475"
DEVICE_TYPE_PURE_COOL_LINK_DESK = "469"
DEVICE_TYPE_PURE_COOL = "438"
DEVICE_TYPE_PURIFIER_COOL = "438K"
DEVICE_TYPE_PURE_COOL_FORMALDEHYDE = "438E"
DEVICE_TYPE_PURE_COOL_DESK = "520"
DEVICE_TYPE_PURE_HUMIDIFY_COOL = "358"
DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE = "358E"
DEVICE_TYPE_PURE_HOT_COOL_LINK = "455"
DEVICE_TYPE_PURE_HOT_COOL = "527"
DEVICE_TYPE_PURE_HOT_COOL_NEW = "527E"
DEVICE_TYPE_PURIFIER_HOT_COOL = "527K"
DEVICE_TYPE_NAMES = {
    DEVICE_TYPE_360_EYE: "360 Eye robot vacuum",
    DEVICE_TYPE_360_HEURIST: "360 Heurist robot vacuum",
    DEVICE_TYPE_PURE_COOL: "Pure Cool",
    DEVICE_TYPE_PURIFIER_COOL: "Purifier Cool",
    DEVICE_TYPE_PURE_COOL_FORMALDEHYDE: "Pure Cool Formaldehyde",
    DEVICE_TYPE_PURE_COOL_DESK: "Pure Cool Desk",
    DEVICE_TYPE_PURE_COOL_LINK: "Pure Cool Link",
    DEVICE_TYPE_PURE_COOL_LINK_DESK: "Pure Cool Link Desk",
    DEVICE_TYPE_PURE_HOT_COOL: "Pure Hot+Cool",
    DEVICE_TYPE_PURE_HOT_COOL_NEW: "Pure Hot+Cool (New)",
    DEVICE_TYPE_PURE_HOT_COOL_LINK: "Pure Hot+Cool Link",
    DEVICE_TYPE_PURE_HUMIDIFY_COOL: "Pure Humidify+Cool",
    DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE: "Purifier Humidify+Cool Formaldehyde",
    DEVICE_TYPE_PURIFIER_HOT_COOL: "Purifier Hot+Cool",
}
.
.
.

수정코드(const.py)

"""Constants for Dyson Python library."""
from enum import Enum, auto
DEVICE_TYPE_360_EYE = "N223"
DEVICE_TYPE_360_HEURIST = "276"
DEVICE_TYPE_PURE_COOL_LINK = "475"
DEVICE_TYPE_PURE_COOL_LINK_DESK = "469"
DEVICE_TYPE_PURE_COOL = "438"
DEVICE_TYPE_PURIFIER_COOL = "438K"
DEVICE_TYPE_PURE_COOL_FORMALDEHYDE = "438E"
DEVICE_TYPE_PURE_COOL_DESK = "520"
DEVICE_TYPE_PURE_HUMIDIFY_COOL = "358"
DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358E = "358E"
DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358K = "358K"
DEVICE_TYPE_PURE_HOT_COOL_LINK = "455"
DEVICE_TYPE_PURE_HOT_COOL = "527"
DEVICE_TYPE_PURE_HOT_COOL_NEW = "527E"
DEVICE_TYPE_PURIFIER_HOT_COOL = "527K"
DEVICE_TYPE_NAMES = {
    DEVICE_TYPE_360_EYE: "360 Eye robot vacuum",
    DEVICE_TYPE_360_HEURIST: "360 Heurist robot vacuum",
    DEVICE_TYPE_PURE_COOL: "Pure Cool",
    DEVICE_TYPE_PURIFIER_COOL: "Purifier Cool",
    DEVICE_TYPE_PURE_COOL_FORMALDEHYDE: "Pure Cool Formaldehyde",
    DEVICE_TYPE_PURE_COOL_DESK: "Pure Cool Desk",
    DEVICE_TYPE_PURE_COOL_LINK: "Pure Cool Link",
    DEVICE_TYPE_PURE_COOL_LINK_DESK: "Pure Cool Link Desk",
    DEVICE_TYPE_PURE_HOT_COOL: "Pure Hot+Cool",
    DEVICE_TYPE_PURE_HOT_COOL_NEW: "Pure Hot+Cool (New)",
    DEVICE_TYPE_PURE_HOT_COOL_LINK: "Pure Hot+Cool Link",
    DEVICE_TYPE_PURE_HUMIDIFY_COOL: "Pure Humidify+Cool",
    DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358E: "Purifier Humidify+Cool Formaldehyde",
    DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358K: "Purifier Humidify+Cool Formaldehyde",
    DEVICE_TYPE_PURIFIER_HOT_COOL: "Purifier Hot+Cool",
}
.
.
.

바뀐부분은 DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE를 DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358E와 DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358K로 나눈것이다. 이렇게 나누고 난 후 추가로 동작을 위해 __init__.py도 수정을 해주었다.

기존코드(__init__.py)

.
.
.
    if device_type == DEVICE_TYPE_PURE_HUMIDIFY_COOL:
        return DysonPureHumidifyCool(serial, credential, device_type)
    if device_type == DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE:
        return DysonPurifierHumidifyCoolFormaldehyde(serial, credential, device_type)
    return None

수정코드(__init__.py)

.
.
.
    if device_type == DEVICE_TYPE_PURE_HUMIDIFY_COOL:
        return DysonPureHumidifyCool(serial, credential, device_type)
    if device_type in [ DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358E, DEVICE_TYPE_PURIFIER_HUMIDIFY_COOL_FORMALDEHYDE_358K ]:
        return DysonPurifierHumidifyCoolFormaldehyde(serial, credential, device_type)
    return None

위의 두 수정 사항을 반영한 후 테스트를 수행해보았다. 정상동작을 확인하고 매우 매우 기뻤다. 설치를 위한 저장소 주소는 아래와 같다.

답글 남기기

이메일 주소는 공개되지 않습니다. 필수 필드는 *로 표시됩니다