(thumbnail image source1)
(thumbnail image source2)
(thumbnail image source3)
개인적으로 Home Assistant를 소소하지만 재밌게 세팅해서 사용중입니다. 개인적인 세팅에 대해서 기록겸 혹시 보실 분 있을까 겸사해서 올려보려고 합니다. ㅎㅎ
역시 많은 블로그를 통해서 flask 도커 구성 방법을 배워서 설정해보았습니다. 항상 지식 공유해주시는 분들 감사합니다.
우선 누추하지만 제 메인 화면을 보여드리겠습니다.
ESP home을 이용한 온도센서, NEOPixel LED바, PC WOL, 보일러, LG 공기 청정기 구성입니다. 자동화 또한 몇 개 없어 누추합니다...
아무튼 이정도로 구성했고, 개인적으로 별거 없지만 만족하면서 사용중입니다. 하지만 제 구성에서 조금 특이한 점은, 월패드 보일러 제어 부분을 연결해서 보일러를 제어하지만, 월패드에 RS485 모듈을 붙이거나 하는 것이 아닌, 인터넷을 이용한다는 점일겁니다.
이 부분에 대해서 혼자 오래 삽질해서 구현했는데, 혹시 다른분들도 아이디어를 얻으실 수 있을까 해서 제 방법을 자세히 공유해봅니다.
먼저, 저희집은 CVnet 월패드이고, CVnet smart home 앱을 이용해서 제어합니다.
이 부분에서 큰 힌트를 얻었는데요, CVnet smart home 앱은 웹뷰 형식이라 사실 인터넷 사이트에 접속하는 것과 같습니다. 그래서 이 어플에서 접속하는 주소를 따서 접속해봤습니다.
PC로 접속해보니 태블릿모드의 화면이 뜨더군요. 스마트폰용앱에 비해서 인증이 덜 까다롭고, 그만큼 제어할 수 있는 부분이 적긴 합니다만, 난방이 목표였던 저에게는 이거면 충분해서 이 사이트를 3일간 분석해서 리버스 엔지니어링(...)끝에 웹에 로그인부터 제어 신호를 보내는 것까지 python 코드로 제작했습니다. 지식이 없었어서 삽질이 오래 걸려서 그렇지 매우 쉬웠습니다.
그래서 이 부분을 어떻게 HA와 연결할 수 있을까 고민했는데, 자료를 뒤지던중 configuration에서 http requests를 보낼 수 있는 것을 발견해 이 부분을 이용해서 http 센서와 http 보내기를 만들었습니다. (이 부분도 시간을 상당히 소요했는데, 역시 지식이 없어서...)
서버와 주고받을 json 형태에 맞춰서 restful 요소 configuration을 작성해줍니다.
configuration.yaml >>
sensor:
- platform: rest
name: heater_get_all
resource: http://loaclhost:7950/heater/get
method: POST
headers:
Content-Type: "application/json"
payload: '{
"ID": "cvnet_id",
"PW": "cvnet_pw"
}'
json_attributes:
- room1
- room2
- room3
- room4
- room5
value_template: "OK"
rest_command:
heater_control:
url: http://loaclhost:7950/heater/control
method: POST
payload: '{
"ID": "cvnet_id",
"PW": "cvnet_pw"
"room_number": "{{room_number}}",
"onoff": "on",
"target_temperature": "{{temp}}",
}'
content_type: "application/json; charset=utf-8"
input_number:
heater_slider_1:
name: Slider
initial: 18
min: 18
max: 32
step: 1
슬라이더를 통해서 보일러 설정 온도를 제어하기 위해서 자동화를 추가해줍니다.
automation.yaml >>
- id:
alias: 보일러 동작 트리거 (1)
description: 슬라이더의 값이 바뀌면 보일러의 온도를 슬라이더의 값으로 설정합니다.
trigger:
- platform: state
entity_id:
- input_number.heater_slider_1
condition: []
action:
- service: rest_command.heater_control
data:
temp: '{{ states(''input_number.heater_slider_1'') | int }}'
room_number: '{{ 1 }}'
mode: restart
다음으로 HA에서 전송하는 http request를 처리할 부분을 제작해야겠죠. flask를 이용해서 간단하게 http request를 전송하면 json으로 방별 현재 온도, 설정 온도 값을 리턴하고, 제어할 수 있도록 코드를 작성하였습니다.
flask.py >>
@app_route.route('/heater/get', methods=['POST'])
def heat_info():
login(login_info)
response = get_heater_reduced(ID)
return jsonify(response)
@app_route.route('/heater/control', methods=['POST'])
def heat_control():
if (request.is_json):
login(login_info)
control_heater_reduced(ID, room_number, onoff, target_temperature)
return "Done!"
그리고 이 flask를 uwsgi 모듈과 연결하여 http로 서비스 하도록 연결해 도커 이미지를 빌드해서 올렸습니다. (처음 해봤는데 여러 블로거 분들의 글을 통해서 도움 많이 받았습니다. ㅎㅎ)
dockerfile >>
FROM python:3.8
WORKDIR /app
ADD . /app
RUN pip install -r requirements.txt
CMD ["uwsgi","uwsgi.ini"]
uwsgi.ini >>
* 웹서버를 따로 사용하지 않고 uwsgi단독 실행이므로 socket이 아닌 http-socket을 사용.
[uwsgi]
wsgi-file = app.py
callable = app
http-socket = :7950
processes = 4
threads = 2
master = true
vacum = true
chmod-socket = 660
die-on-term = true
logto = uwsgi_log/@(exec://date +%%Y-%%m-%%d).log
log-reopen = true
docker-compose >>
version: "3"
services:
home_ws_controller:
build: ./build
container_name: home_ws
volumes:
- ./logs:/app/uwsgi_log #로그 확인용
restart: always
environment:
- PUID= 0
- GUID= 0
- APP_NAME=home_ws
# expose:
# - 3032
ports:
- "7950:7950"
portainer 상에서 작동중이 확인되는 이미지
순서 다이어그램은 다음과 같습니다.
control | sensor |
![]() |
![]() |
물론 단점도 있습니다. 보일러 슬라이더가 움직이면 보일러가 그 값으로 변하지만, 슬라이더가 초기화되면 그때는 슬라이더가 초기값에 가있고 보일러 값이 슬라이더와 맞지 않으니까요... 그래서 보일러 현재 설정 온도를 추가해서 확인할 수 있도록 만들었습니다. 그런데 이 http 센서는 HA상에 표시되는 값이 반영이 매우 느립니다.(로그를 확인해보니 대충 30초에 한 번 확인하는 것 같습니다.)
아무쪼록 혼자 멘땅에 헤딩하며 열심히 구성했던 것인데, 혹시 이걸보고 아이디어가 될 수 있을까 하여 올려봅니다.! 혹시 개선할 부분이 있다면 조언도 부탁드립니다!
끝까지 다 읽어보셨다면... 읽어주셔서 감사합니다.
이해가 안 가요