담다패드 - 월패드만 있으면 우리집은 이미 스마트홈?!
담다패드 - 월패드만 있으면 우리집은 이미 스마트홈?! 스마트폰, 스마트전구, IoT가전제품, AI스피커 ...... 스마트한 세상에 살고계신 여러분. 월패드가 있는 우리집이 이미 스마트홈 이라는
mscg.kr
피바로 홈센터3 - 월패드(RS485) 연동
피바로 홈센터3 - 월패드(RS485) 연동 홈센터3 개봉기에서 이미 언급했지만 새롭게 스마트홈(혹은 상업공간)을 구축할 예정이거나 기존의 플랫폼에 한계를 느낀다면 홈센터3를 강력 추천. (인테
mscg.kr
준비물
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 |