준비물
Node.js 가 실행되는 라즈베리파이 등(ex: 아두이노)
USB to RS485 3개. (월패드1개, 환기장치2개)
수정
엘레베이터 호출 추가
환기장치 연동
안녕하세요. 랜이입니다.
앞전에 올렸던 글에서 그렉스 환기장치를 연동하게 되어서 설정기와 자바스크립트 파일을 공유하려합니다.
내용을 시작하기에 앞서 우리집의 환기장치에 대해서 먼저 설명할게요.
환기장치 제어기는 1초에 4~5회 정도 환기장치에게 현재 모드에 대한 신호를 보냅니다.
현재 "자동" 모드이면 자동~~~~~~~
현재 "취침" 모드이면 취침~~~~~~~
현재 "수동1단" 모드이면 수동1~~~~~~
이런식으로요.
그러면 GREX환기장치는 신호에 대해서 모드를 바꾸고 제어기 신호에 대해 1:1 응답을 합니다.
1:1 응답을 못하는 경우 환기장치 제어기는 "통신에러"를 뿜어내죠.
여기에서 문제가 하나 발생합니다.
아래와 같이 RS485 연결을 해서 패킷신호를 보내서 작동을 하려해도
환기장치 제어기가 신호를 지속적으로 보내기 때문에 환기장치 제어기의 신호로 덮어씌워지게 됩니다.
그렇기 때문에 아래와 같이 작동을 해야 할 필요성이 있었습니다.
라즈베라파이에 시리얼포트를 2개를 OPEN 하고
라즈베리파이가 환기장치 제어기의 지속적인 신호에 FAKE 응답을 보내고
라즈베리파이가 GREX 환기장치에 별도의 제어신호를 주게 하는것이죠.
이렇게 할 경우
수동제어와 스마트제어 모두 가능해집니다.
수동제어를 할 경우
> 라즈베리파이에서 환기장치에 신호 전송.
> GREX 환기장치의 응답 패킷을 제어기에 발송.
> GREX 환기장치의 응답을 HA로 전송.
스마트제어를 할 경우
> 원하는 모드를 GREX 환기장치에 전송.
> GREX 환기장치의 응답을 HA로 전송.
> 제어기에는 FAKE 패킷을 전송하여 통신에러를 방지
중요한점은 제어기와 환기장치의 변수를 따로 구분해서 통신에러가 발생하지 않도록 하는것이죠.
그래서.. 환기장치를 위한 "USB to RS485"가 2개 필요하고
월패드를 위해서 1개. 총 3개의 "USB to RS485"가 필요하네요.
이상 GREX 환기장치에 대한 설명이었습니다.
(환기장치를 추가하시기 전에 패킷을 꼭 분석하셔야합니다!)
아래는 HA에서 월패드와 환기장치 제어하기 위한 소스입니다.
HA - automations.yaml
- id: command_airgrex_automation
alias: 환기장치 이산화탄소 자동화
trigger:
- platform: state
entity_id: sensor.awair_co2_bedroom
- platform: state
entity_id: sensor.awair_co2_livingroom
- platform: state
entity_id: input_select.air_grex_mode
to: "이산화탄소"
condition:
- condition: template
value_template: '{% if states("input_select.air_grex_mode") == "이산화탄소" %}true{% endif %}'
action:
- data:
entity_id: timer.airgrex_timer
service: timer.cancel
- entity_id: timer.airgrex_delay_timer
service: timer.cancel
- service: mqtt.publish
data_template:
topic: "kocom/air/grex/mode/command"
payload_template: >
{% if states("input_select.air_grex_mode") == "이산화탄소" and (states("sensor.awair_co2_bedroom")|int + states("sensor.awair_co2_livingroom")|int)/2|float - states("input_number.air_grex_automation_co2")|float > 100 %}수동3단
{% elif states("input_select.air_grex_mode") == "이산화탄소" and (states("sensor.awair_co2_bedroom")|int + states("sensor.awair_co2_livingroom")|int)/2|float - states("input_number.air_grex_automation_co2")|float > 0 %}수동2단
{% else %}정지
{% endif %}
retain: true
- id: set_airgrex
alias: 환기장치 수동작동
trigger:
- platform: state
entity_id: sensor.grexmode
- platform: state
entity_id: sensor.grexspeed
condition:
- condition: template
value_template: '{% if states("input_select.air_grex_mode") != "이산화탄소" and states("input_select.air_grex_mode") != "대기" %}true{% endif %}'
action:
- service: homeassistant.turn_off
entity_id: automation.hwangijangci_jagdong
- service: input_select.select_option
data_template:
entity_id: input_select.air_grex_mode
option: >
{% if states("sensor.grexmode") == "수동" %}{{ states("sensor.grexmode") }}{{ states("sensor.grexspeed") }}
{% elif states("sensor.grexmode") == "수동" and states("sensor.grexspeed") == "0단" %}대기
{% elif states("sensor.grexmode") == "자동" or states("sensor.grexmode") == "취침" %}{{ states("sensor.grexmode") }}
{% endif %}
- service: homeassistant.turn_on
entity_id: automation.hwangijangci_jagdong
- id: command_airgrex
alias: 환기장치 작동
trigger:
- platform: state
entity_id: input_select.air_grex_mode
condition:
- condition: template
value_template: '{% if trigger.to_state.state != "이산화탄소" and trigger.to_state.state != "대기" %}true{% endif %}'
action:
- service: mqtt.publish
data_template:
topic: "kocom/air/grex/mode/command"
payload_template: '{{ states("input_select.air_grex_mode") }}'
retain: true
- id: command_airgrex_timer_start
alias: 환기장치 타이머 시작
trigger:
- platform: state
entity_id: input_select.air_grex_mode
to: '수동1단'
- platform: state
entity_id: input_select.air_grex_mode
to: '수동2단'
- platform: state
entity_id: input_select.air_grex_mode
to: '수동3단'
- platform: state
entity_id: input_select.air_grex_mode
to: '자동'
- platform: state
entity_id: input_select.air_grex_mode
to: '취침'
- platform: state
entity_id: input_number.air_grex_manual_minute_per_hour
condition:
- condition: template
value_template: '{% if states("input_number.air_grex_manual_minute_per_hour") | int != 60 and (trigger.to_state.state == "수동1단" or trigger.to_state.state == "수동2단" or trigger.to_state.state == "수동3단" or trigger.to_state.state == "자동" or trigger.to_state.state == "취침" or (trigger.entity_id == "input_number.air_grex_manual_minute_per_hour" and (states("input_select.air_grex_mode") == "수동1단" or states("input_select.air_grex_mode") == "수동2단" or states("input_select.air_grex_mode") == "수동3단"))) %}true{% endif %}'
action:
- service: timer.cancel
entity_id: timer.airgrex_delay_timer
- service: timer.cancel
entity_id: timer.airgrex_timer
- service: timer.start
entity_id: timer.airgrex_timer
data_template:
duration: '00:{% if trigger.to_state.state == "수동1단" or trigger.to_state.state == "수동2단" or trigger.to_state.state == "수동3단" or (trigger.entity_id == "input_number.air_grex_manual_minute_per_hour" and (states("input_select.air_grex_mode") == "수동1단" or states("input_select.air_grex_mode") == "수동2단" or states("input_select.air_grex_mode") == "수동3단")) %}{{ states("input_number.air_grex_manual_minute_per_hour") | int }}{% elif trigger.to_state.state == "자동" %}30{% elif trigger.to_state.state == "취침" %}15{% endif %}:00'
- id: command_airgrex_timer_cancel
alias: 환기장치 타이머 취소
trigger:
- platform: state
entity_id: input_select.air_grex_mode
to: '정지'
- platform: state
entity_id: sensor.grexmode
- platform: state
entity_id: sensor.grexspeed
- platform: state
entity_id: input_number.air_grex_manual_minute_per_hour
condition:
- condition: template
value_template: '{% if trigger.entity_id == "input_select.air_grex_mode" or (trigger.entity_id == "input_number.air_grex_manual_minute_per_hour" and states("input_number.air_grex_manual_minute_per_hour") | int == 60) %}true{% endif %}'
action:
- data:
entity_id: timer.airgrex_timer
service: timer.cancel
- entity_id: timer.airgrex_delay_timer
service: timer.cancel
- id: command_airgrex_timer_finish
alias: 환기장치 타이머 완료
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.airgrex_timer
condition: []
action:
- service: input_select.select_option
data_template:
entity_id: input_select.air_grex_mode_copy
option: '{{ states("input_select.air_grex_mode") }}'
- service: mqtt.publish
data_template:
topic: "kocom/air/grex/mode/command"
payload_template: >
{% if states("input_select.air_grex_mode") == "자동" %}자동0단
{% elif states("input_select.air_grex_mode") == "취침" %}취침0단
{% elif states("input_select.air_grex_mode") == "수동1단" or states("input_select.air_grex_mode") == "수동2단" or states("input_select.air_grex_mode") == "수동3단" %}수동0단
{% endif %}
retain: true
- service: timer.start
entity_id: timer.airgrex_delay_timer
data_template:
duration: '00:{% if (is_state("input_select.air_grex_mode", "수동1단") or is_state("input_select.air_grex_mode", "수동2단") or is_state("input_select.air_grex_mode", "수동3단")) %}{{ 60 - states("input_number.air_grex_manual_minute_per_hour") | int }}{% elif is_state("input_select.air_grex_mode", "자동") %}30{% elif is_state("input_select.air_grex_mode", "취침") %}45{% endif %}:00'
- id: command_airgrex_delay_timer_finish
alias: 환기장치 딜레이 타이머 완료
trigger:
- platform: event
event_type: timer.finished
event_data:
entity_id: timer.airgrex_delay_timer
condition: []
action:
- service: mqtt.publish
data_template:
topic: "kocom/air/grex/mode/command"
payload_template: '{{ states("input_select.air_grex_mode_copy") }}'
retain: true
- service: timer.start
entity_id: timer.airgrex_timer
data_template:
duration: '00:{% if (is_state("input_select.air_grex_mode", "수동1단") or is_state("input_select.air_grex_mode", "수동2단") or is_state("input_select.air_grex_mode", "수동3단")) %}{{ states("input_number.air_grex_manual_minute_per_hour") | int }}{% elif is_state("input_select.air_grex_mode", "자동") %}30{% elif is_state("input_select.air_grex_mode", "취침") %}15{% endif %}:00'
HA - input_select.yaml
air_grex_mode:
name: 환기장치 모드
options:
- 정지
- 자동
- 취침
- 수동1단
- 수동2단
- 수동3단
- 이산화탄소
- 대기
initial: 정지
air_grex_mode_copy:
name: 환기장치 모드 카피
options:
- 정지
- 자동
- 취침
- 수동1단
- 수동2단
- 수동3단
- 이산화탄소
- 대기
initial: 정지
HA - input_number.yaml
air_grex_manual_minute_per_hour:
name: 환기장치 수동작동
min: 5
max: 60
step: 5
air_grex_automation_co2:
name: CO2 자동화
min: 500
max: 1200
step: 50
HA - sensors.yaml
- platform: mqtt
state_topic: "kocom/air/grex/state"
name: "GrexMode"
value_template: >
{% if value_json.mode == "0000" %}정지
{% elif value_json.mode == "0100" %}자동
{% elif value_json.mode == "0200" %}수동
{% elif value_json.mode == "0300" %}취침
{% endif %}
icon: mdi:format-list-bulleted
- platform: mqtt
state_topic: "kocom/air/grex/state"
name: "GrexSpeed"
value_template: >
{% if value_json.speed == "0000" %}0단
{% elif value_json.speed == "0101" %}1단
{% elif value_json.speed == "0202" %}2단
{% elif value_json.speed == "0303" %}3단
{% endif %}
icon: mdi:speedometer
HA - timer.yaml
airgrex_timer:
name: AirGrex Timer
airgrex_delay_timer:
name: AirGrex Delay Timer
HA - switchs.yaml
# 엘레베이터
- platform: mqtt
name: elevator
command_topic: "kocom/elevator/ev/call/command"
state_topic: "kocom/elevator/ev/state"
value_template: "{{ value_json.call }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
# 아래는 전등제어
- platform: mqtt
name: livingroom_light1
command_topic: "kocom/livingroom/light/1/command"
state_topic: "kocom/livingroom/light/state"
value_template: "{{ value_json.light1 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: livingroom_light2
command_topic: "kocom/livingroom/light/2/command"
state_topic: "kocom/livingroom/light/state"
value_template: "{{ value_json.light2 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: livingroom_light3
command_topic: "kocom/livingroom/light/3/command"
state_topic: "kocom/livingroom/light/state"
value_template: "{{ value_json.light3 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: kitchen_light1
command_topic: "kocom/kitchen/light/1/command"
state_topic: "kocom/kitchen/light/state"
value_template: "{{ value_json.light1 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: kitchen_light2
command_topic: "kocom/kitchen/light/2/command"
state_topic: "kocom/kitchen/light/state"
value_template: "{{ value_json.light2 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: kitchen_light3
command_topic: "kocom/kitchen/light/3/command"
state_topic: "kocom/kitchen/light/state"
value_template: "{{ value_json.light3 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: bedroom_light1
command_topic: "kocom/bedroom/light/1/command"
state_topic: "kocom/bedroom/light/state"
value_template: "{{ value_json.light1 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: bedroom_light2
command_topic: "kocom/bedroom/light/2/command"
state_topic: "kocom/bedroom/light/state"
value_template: "{{ value_json.light2 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: room1_light1
command_topic: "kocom/room1/light/1/command"
state_topic: "kocom/room1/light/state"
value_template: "{{ value_json.light1 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: room1_light2
command_topic: "kocom/room1/light/2/command"
state_topic: "kocom/room1/light/state"
value_template: "{{ value_json.light2 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: room2_light1
command_topic: "kocom/room2/light/1/command"
state_topic: "kocom/room2/light/state"
value_template: "{{ value_json.light1 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
- platform: mqtt
name: room2_light2
command_topic: "kocom/room2/light/2/command"
state_topic: "kocom/room2/light/state"
value_template: "{{ value_json.light2 }}"
payload_on: "on"
payload_off: "off"
qos: 0
retain: true
HA - climate.yaml
- platform: mqtt
name: "Livingroom Thermo"
mode_state_topic: "kocom/livingroom/thermo/state"
mode_command_topic: "kocom/livingroom/thermo/heat_mode/command"
mode_state_template: "{{ value_json.heat_mode }}"
temperature_state_topic: "kocom/livingroom/thermo/state"
temperature_command_topic: "kocom/livingroom/thermo/set_temp/command"
temperature_state_template: "{{ value_json.set_temp }}"
current_temperature_topic: "kocom/livingroom/thermo/state"
current_temperature_template: "{{ value_json.cur_temp }}"
modes:
- "off"
- "away"
- "on"
min_temp: 5
max_temp: 40
- platform: mqtt
name: "Bedroom Thermo"
mode_state_topic: "kocom/bedroom/thermo/state"
mode_command_topic: "kocom/bedroom/thermo/heat_mode/command"
mode_state_template: "{{ value_json.heat_mode }}"
temperature_state_topic: "kocom/bedroom/thermo/state"
temperature_command_topic: "kocom/bedroom/thermo/set_temp/command"
temperature_state_template: "{{ value_json.set_temp }}"
current_temperature_topic: "kocom/bedroom/thermo/state"
current_temperature_template: "{{ value_json.cur_temp }}"
modes:
- "off"
- "away"
- "on"
min_temp: 5
max_temp: 40
- platform: mqtt
name: "Room1 Thermo"
mode_state_topic: "kocom/room1/thermo/state"
mode_command_topic: "kocom/room1/thermo/heat_mode/command"
mode_state_template: "{{ value_json.heat_mode }}"
temperature_state_topic: "kocom/room1/thermo/state"
temperature_command_topic: "kocom/room1/thermo/set_temp/command"
temperature_state_template: "{{ value_json.set_temp }}"
current_temperature_topic: "kocom/room1/thermo/state"
current_temperature_template: "{{ value_json.cur_temp }}"
modes:
- "off"
- "away"
- "on"
min_temp: 5
max_temp: 40
- platform: mqtt
name: "Room2 Thermo"
mode_state_topic: "kocom/room2/thermo/state"
mode_command_topic: "kocom/room2/thermo/heat_mode/command"
mode_state_template: "{{ value_json.heat_mode }}"
temperature_state_topic: "kocom/room2/thermo/state"
temperature_command_topic: "kocom/room2/thermo/set_temp/command"
temperature_state_template: "{{ value_json.set_temp }}"
current_temperature_topic: "kocom/room2/thermo/state"
current_temperature_template: "{{ value_json.cur_temp }}"
modes:
- "off"
- "away"
- "on"
min_temp: 5
max_temp: 40
'IT Info > IoT' 카테고리의 다른 글
피바로 홈센터3 - 어웨어 연동기(실내공기질측정) (0) | 2020.03.07 |
---|---|
피바로 홈센터3 - 개봉기 (스마트홈의 끝판왕) (1) | 2020.03.06 |
[HA] Custom Component. 스마트씽큐 건조기,세탁기 완료알림 자동화 (0) | 2019.05.27 |
[HA] Custom Component. 스마트싱큐 센서yaml 설정파일 (0) | 2019.05.27 |
[RS485] 월패드를 시리얼포트로 제어하기 (0) | 2019.05.27 |