├── .gitignore ├── LICENSE ├── README.md ├── ha_config_alarm_clock ├── Alarm_clock.png ├── README.md └── configuration │ ├── automations.yaml │ ├── configuration.yaml │ ├── customize.yaml │ ├── groups.yaml │ ├── input_booleans.yaml │ ├── input_numbers.yaml │ ├── media_players.yaml │ └── sensors.yaml ├── ha_config_zigate └── README.md ├── ha_mqtt_binary_sensor_ble_scanner ├── README.md ├── esp32.jpg ├── example.config.h ├── ha_mqtt_binary_sensor_ble_scanner.ino └── occupancy.png ├── ha_mqtt_binary_sensor_door ├── README.md ├── Steps.png └── ha_mqtt_binary_sensor_door.ino ├── ha_mqtt_binary_sensor_nfc_scanner ├── README.md ├── example.config.h ├── ha.png ├── ha_mqtt_binary_sensor_nfc_scanner.ino └── nfc_scanner.jpg ├── ha_mqtt_binary_sensor_pir ├── README.md ├── Schematic.png └── ha_mqtt_binary_sensor_pir.ino ├── ha_mqtt_light ├── README.md ├── Schematic.png └── ha_mqtt_light.ino ├── ha_mqtt_light_arilux ├── LICENSE ├── README.md ├── example.config.h └── ha_mqtt_light_arilux.ino ├── ha_mqtt_light_with_WiFiManager_mDNS_and_OTA ├── README.md ├── Schematic.jpg └── ha_mqtt_light_with_WiFiManager_mDNS_and_OTA.ino ├── ha_mqtt_light_with_brightness ├── README.md ├── Schematic.png └── ha_mqtt_light_with_brightness.ino ├── ha_mqtt_multisensor ├── Configuration │ ├── example.binary_sensor.yaml │ ├── example.group.yaml │ └── example.sensor.yaml ├── Images │ └── Schematic.jpg ├── LICENSE ├── MultiSensor.cpp ├── MultiSensor.h ├── README.md ├── example.config .h └── ha_mqtt_multisensor.ino ├── ha_mqtt_rgb_light ├── README.md ├── Schematic.png ├── ha_mqtt_rgb_light.ino └── screenshot.png ├── ha_mqtt_rgbw_light_with_discovery ├── README.md ├── config.example.h ├── ha_mqtt_rgbw_light_with_discovery.cpp ├── ha_mqtt_rgbw_light_with_discovery.h └── ha_mqtt_rgbw_light_with_discovery.ino ├── ha_mqtt_sensor_dht22 ├── README.md ├── Schematic.png └── ha_mqtt_sensor_dht22.ino ├── ha_mqtt_sensor_photocell ├── README.md ├── Schematic.png └── ha_mqtt_sensor_photocell.ino ├── ha_mqtt_switch ├── README.md ├── Schematic.png └── ha_mqtt_switch.ino └── openhome ├── README.md ├── configuration ├── home_assistant │ ├── automation.yaml │ ├── automation │ │ ├── automation_1a.yaml │ │ ├── automation_1b.yaml │ │ ├── automation_1c.yaml │ │ ├── automation_1d.yaml │ │ ├── automation_2a.yaml │ │ ├── automation_2b.yaml │ │ ├── automation_3a.yaml │ │ ├── automation_3b.yaml │ │ ├── automation_3c.yaml │ │ └── automation_4a.yaml │ ├── binary_sensors.yaml │ ├── configuration.yaml │ ├── customize.yaml │ ├── groups.yaml │ ├── input_numbers.yaml │ ├── known_devices.yaml │ ├── lights.yaml │ └── sensors.yaml └── mosquitto │ ├── aclfile │ ├── mosquitto.conf │ └── pwfile ├── images ├── Architecture_MQTT.png ├── Architecture_Network.png ├── Features.png ├── Home.png ├── Owntracks.png └── Youtube.png └── sketches ├── Bedroom ├── Bedroom.ino └── Schematic.png ├── Entrance ├── Entrance.ino └── Schematic.png └── Livingroom ├── Livingroom.ino └── Schematic.png /.gitignore: -------------------------------------------------------------------------------- 1 | 2 | .DS_Store 3 | ha_mqtt_multisensor/config.h 4 | ha_mqtt_multisensor/Configuration/binary_sensor.yaml 5 | ha_mqtt_multisensor/Configuration/sensor.yaml 6 | ha_mqtt_sensor_dht22/config.h 7 | ha_mqtt_binary_sensor_ble_scanner/config.h 8 | ha_mqtt_binary_sensor_nfc_scanner/config.h 9 | ha_mqtt_light_arilux/config.h 10 | -------------------------------------------------------------------------------- /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2016 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # Open Home Automation 2 | 3 | **THIS REPOSITORY IS NOT MAINTAINED ANYMORE, SEE [ESPHome](https://esphome.io/) AS AN ALTERNATIVE.** 4 | 5 | ## Introduction 6 | Nowadays everything becomes connected to the Internet and gives us a glimpse of many new possibilities. Home automation is part of it and offers many advantages for their users. 7 | This repository is dedicated to [Home Assistant](https://home-assistant.io), an open source project with an amazing community, ESP8266 and ESP32 modules, the MQTT protocol and much more [...]. 8 | 9 | ### Home Assistant 10 | > Home Assistant is a home automation platform running on Python 3. The goal of Home Assistant is to be able to track and control all devices at home and offer a platform for automating control [[Home-Assistant](https://github.com/home-assistant/home-assistant)]. 11 | 12 | ### MQTT 13 | > MQTT is a machine-to-machine (M2M)/"Internet of Things" connectivity protocol. It was designed as an extremely lightweight publish/subscribe messaging transport. It is useful for connections with remote locations where a small code footprint is required and/or network bandwidth is at a premium [[mqtt.org](http://mqtt.org)]. 14 | 15 | ![Home-Assistant](openhome/images/Features.png) 16 | 17 | ## Content 18 | ### Requirements 19 | Most of the examples below are using the MQTT protocol and so require to integrate MQTT into Home Assistant by defining a MQTT broker. More information can be found at the [MQTT component's page](https://home-assistant.io/components/mqtt/). 20 | 21 | #### Stock Home Assistant 22 | configuration.yaml : 23 | 24 | ```yaml 25 | mqtt: 26 | broker: 127.0.0.1 27 | port: 1883 28 | username: '[Redacted]' 29 | password: '[Redacted]' 30 | discovery: true # optional 31 | discovery_prefix: homeassistant # optional 32 | ``` 33 | 34 | #### Hass.io 35 | configuration.yaml : 36 | 37 | ```yaml 38 | mqtt: 39 | broker: core-mosquitto 40 | username: '[Redacted]' 41 | password: '[Redacted]' 42 | discovery: true # optional 43 | discovery_prefix: homeassistant # optional 44 | ``` 45 | 46 | More options to connect the broker are available and described [here](https://home-assistant.io/docs/mqtt/broker/#embedded-broker). 47 | 48 | ### Sketches for ESP8266/ESP32 modules 49 | Lights, sensors, switches and more can be built on top of MQTT. This section contains a few examples based on MQTT and on a NodeMCU board (ESP8266/ESP32). 50 | 51 | | Title / link | Description | 52 | |-----------------------------------------------|-----------------------------------------------------------------------| 53 | | [Light](/ha_mqtt_light) | A simple example to control a **led** | 54 | | [Light](/ha_mqtt_light_with_brightness) | A simple example to control a **led** and its brightness | 55 | | [Light](/ha_mqtt_rgb_light) | A simple example to control a **RGB led** | 56 | | [Light](/ha_mqtt_light_with_WiFiManager_mDNS_and_OTA) | A simple example to control a **RGB led** (with **OTA** and **mDNS**)| 57 | | [Light](https://github.com/mertenats/Arilux_AL-LC03)| An alternative firmware for the **Arilux AL-LC0X LED controller** | 58 | | [Light](/ha_mqtt_light_arilux)| An alternative firmware for the **Arilux AL-LC0X LED controller** with multiple effects from the [WS2812FX](https://github.com/kitesurfer1404/WS2812FX) | 59 | | [Light](/ha_mqtt_rgbw_light_with_discoveryw) | A simple example to control a **RGBW led**, based on the **MQTT JSON Light** component (brightness, rgb, white, color temperature and effects) and including the **MQTT Discovery** | 60 | | [Light](https://github.com/mertenats/AI-Thinker_RGBW_Bulb) | An alternative firmware for **AI-Thinker RGBW bulbs**, based on the **MQTT JSON Light** component and including the **MQTT Discovery** functionality | 61 | | [Switch](/ha_mqtt_switch) | A simple example to control a **switch** 62 | | [Switch](https://github.com/mertenats/Itead_Sonoff/tree/master/Sonoff_Basic) | An alternative firmware for the **Sonoff Basic** switches | 63 | | [Switch](https://github.com/mertenats/Itead_Sonoff/tree/master/Sonoff_TH) | An alternative firmware for the **Sonoff TH** switches, including the **MQTT Discovery** functionality | 64 | | [Sensor](/ha_mqtt_sensor_dht22) | A simple example to measure the **temperature** and the **humidity** (DHT22 sensor)| 65 | | [Sensor](/ha_mqtt_sensor_photocell) | A simple example to measure the **brightness** (photocell)| 66 | | [Binary Sensor](/ha_mqtt_binary_sensor_pir) | A simple example to detect **motions** (PIR motion sensor)| 67 | | [Binary Sensor](/ha_mqtt_binary_sensor_door) | A simple example to monitor the **state** of a **window/door** | 68 | | [Binary Sensor](/ha_mqtt_multisensor) | A full example describing how to monitor your **environment** with different sensors (SHT3X, DHT22, TEMT6000, etc.)| 69 | | [Binary Sensor](/ha_mqtt_binary_sensor_ble_scanner)| An example describing how to trigger an action when a specific **BLE device** is detected (ESP32)| 70 | | [Binary Sensor](/ha_mqtt_binary_sensor_nfc_scanner)| An example describing how to trigger an action when a specific **NFC tag** is detected| 71 | 72 | ### Configuration examples for Home Assistant 73 | This section contains a few configuration examples dedicated to Home Assistant. 74 | 75 | | Title / link | Description | 76 | |-----------------------------------------------|-----------------------------------------------------------------------| 77 | | [Alarm Clock](/ha_config_alarm_clock) | An example describing how to create an **alarm clock** with the components provided by HA | 78 | | [openhome](/openhome) | A school project based on Home Assistant and using only **open source** HW and SW | 79 | | [Zigate & ZigBee devices](/ha_config_zigate) | An example describing how to add and control **ZigBee** devices paired to a **Zigate** | 80 | 81 | [![OpenHome with Home Assistant and MQTT](openhome/images/Youtube.png)](https://www.youtube.com/watch?v=Vh-vzFPCF2U "OpenHome with Home Assistant and MQTT") 82 | 83 | ## Miscelleneous 84 | 85 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 86 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 87 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 88 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 89 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 90 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 91 | SOFTWARE. 92 | 93 | *If you like the content of this repo, please add a star! Thank you!* 94 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/Alarm_clock.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_config_alarm_clock/Alarm_clock.png -------------------------------------------------------------------------------- /ha_config_alarm_clock/README.md: -------------------------------------------------------------------------------- 1 | # Configuration - Alarm Clock - Home Assistant 2 | A simple configuration example to create an alarm clock and trigger an automation, which turns on the light and switches on a stereo. This example was tested on [Home Assistant](https://home-assistant.io) 0.64.1 and uses the Philips [Hue](https://home-assistant.io/components/light.hue/) component and an [Onkyo](https://home-assistant.io/components/media_player.onkyo/) media player. 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | homeassistant: 8 | # Customization file 9 | customize: !include customize.yaml 10 | 11 | hue: 12 | bridges: 13 | - host: 192.168.1.130 14 | 15 | recorder: 16 | include: 17 | entities: 18 | - input_number.alarm_clock_hours 19 | - input_number.alarm_clock_minutes 20 | - input_boolean.alarm_clock_status 21 | 22 | sensor: !include sensors.yaml 23 | input_number: !include input_numbers.yaml 24 | input_boolean: !include input_booleans.yaml 25 | media_player: !include media_players.yaml 26 | group: !include groups.yaml 27 | automation: !include automations.yaml 28 | ``` 29 | 30 | customize.yaml : 31 | ```yaml 32 | input_number.alarm_clock_hours: 33 | friendly_name: 'Heure' 34 | icon: mdi:timer 35 | input_number.alarm_clock_minutes: 36 | friendly_name: 'Minute' 37 | icon: mdi:timer 38 | input_boolean.alarm_clock_status: 39 | friendly_name: 'Etat' 40 | icon: mdi:calendar 41 | sensor.alarm_clock_hours: 42 | hidden: true 43 | sensor.alarm_clock_minutes: 44 | hidden: true 45 | sensor.alarm_clock_time: 46 | friendly_name: 'Heure du réveil' 47 | icon: mdi:alarm 48 | ``` 49 | 50 | sensors.yaml : 51 | ```yaml 52 | - platform: template 53 | sensors: 54 | alarm_clock_hours: 55 | value_template: "{{ states('input_number.alarm_clock_hours') | round(0) }}" 56 | alarm_clock_minutes: 57 | value_template: "{{ states('input_number.alarm_clock_minutes') | round(0) }}" 58 | alarm_clock_time: 59 | value_template: "{% if states.sensor.alarm_clock_hours.state | length == 1 -%}0{%- endif -%}{{ states.sensor.alarm_clock_hours.state }}:{% if states.sensor.alarm_clock_minutes.state | length == 1 -%}0{%- endif -%}{{ states.sensor.alarm_clock_minutes.state }}" 60 | - platform: time_date 61 | display_options: 62 | - 'time' 63 | ``` 64 | 65 | input_numbers.yaml : 66 | ```yaml 67 | alarm_clock_hours: 68 | min: 0 69 | max: 23 70 | step: 1 71 | mode: slider 72 | alarm_clock_minutes: 73 | min: 0 74 | max: 55 75 | step: 5 76 | mode: slider 77 | ``` 78 | 79 | input_booleans.yaml : 80 | ```yaml 81 | alarm_clock_status: 82 | ``` 83 | 84 | media_players.yaml : 85 | ```yaml 86 | - platform: onkyo 87 | host: 192.168.1.133 88 | name: 'Stereo' 89 | ``` 90 | 91 | groups.yaml : 92 | ```yaml 93 | default_view: 94 | view: yes 95 | entities: 96 | - group.alarm_clock 97 | 98 | alarm_clock: 99 | name: 'Réveil' 100 | entities: 101 | - sensor.alarm_clock_time 102 | - input_number.alarm_clock_hours 103 | - input_number.alarm_clock_minutes 104 | - input_boolean.alarm_clock_status 105 | ``` 106 | 107 | automations.yaml : 108 | ```yaml 109 | - alias: 'Turn on the alarm clock' 110 | trigger: 111 | platform: template 112 | value_template: '{{ states.sensor.time.state == states.sensor.alarm_clock_time.state }}' 113 | condition: 114 | condition: and 115 | conditions: 116 | - condition: state 117 | entity_id: input_boolean.alarm_clock_status 118 | state: 'on' 119 | - condition: time 120 | weekday: 121 | - mon 122 | - tue 123 | - wed 124 | - thu 125 | - fri 126 | action: 127 | - service: media_player.turn_on 128 | data: 129 | entity_id: media_player.stereo 130 | - service: media_player.volume_set 131 | data: 132 | entity_id: media_player.stereo 133 | volume_level: 0.07 134 | - service: media_player.select_source 135 | data: 136 | entity_id: media_player.stereo 137 | source: dab 138 | - service: light.turn_on 139 | data: 140 | entity_id: light.bedside 141 | brightness: 255 142 | transition: 900 143 | - delay: 144 | minutes: 15 145 | - service: light.turn_on 146 | data: 147 | entity_id: light.ceiling 148 | brightness: 255 149 | - service: light.turn_off 150 | data: 151 | entity_id: light.bedside 152 | ``` 153 | 154 | ## Preview 155 | ![Alarm Clock](Alarm_clock.png) 156 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/automations.yaml: -------------------------------------------------------------------------------- 1 | - alias: 'Turn on the alarm clock' 2 | trigger: 3 | platform: template 4 | value_template: '{{ states.sensor.time.state == states.sensor.alarm_clock_time.state }}' 5 | condition: 6 | condition: and 7 | conditions: 8 | - condition: state 9 | entity_id: input_boolean.alarm_clock_status 10 | state: 'on' 11 | - condition: time 12 | weekday: 13 | - mon 14 | - tue 15 | - wed 16 | - thu 17 | - fri 18 | action: 19 | - service: media_player.turn_on 20 | data: 21 | entity_id: media_player.stereo 22 | - service: media_player.volume_set 23 | data: 24 | entity_id: media_player.stereo 25 | volume_level: 0.07 26 | - service: media_player.select_source 27 | data: 28 | entity_id: media_player.stereo 29 | source: dab 30 | - service: light.turn_on 31 | data: 32 | entity_id: light.bedside 33 | brightness: 255 34 | transition: 900 35 | - delay: 36 | minutes: 15 37 | - service: light.turn_on 38 | data: 39 | entity_id: light.ceiling 40 | brightness: 255 41 | - service: light.turn_off 42 | data: 43 | entity_id: light.bedside 44 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/configuration.yaml: -------------------------------------------------------------------------------- 1 | homeassistant: 2 | # Customization file 3 | customize: !include customize.yaml 4 | 5 | hue: 6 | bridges: 7 | - host: 192.168.1.130 8 | 9 | recorder: 10 | include: 11 | entities: 12 | - input_number.alarm_clock_hours 13 | - input_number.alarm_clock_minutes 14 | - input_boolean.alarm_clock_status 15 | 16 | sensor: !include sensors.yaml 17 | input_number: !include input_numbers.yaml 18 | input_boolean: !include input_booleans.yaml 19 | media_player: !include media_players.yaml 20 | group: !include groups.yaml 21 | automation: !include automations.yaml 22 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/customize.yaml: -------------------------------------------------------------------------------- 1 | input_number.alarm_clock_hours: 2 | friendly_name: 'Heure' 3 | icon: mdi:timer 4 | input_number.alarm_clock_minutes: 5 | friendly_name: 'Minute' 6 | icon: mdi:timer 7 | input_boolean.alarm_clock_status: 8 | friendly_name: 'Status' 9 | icon: mdi:calendar 10 | sensor.alarm_clock_hours: 11 | hidden: true 12 | sensor.alarm_clock_minutes: 13 | hidden: true 14 | sensor.alarm_clock_time: 15 | friendly_name: 'Réveil' 16 | icon: mdi:alarm 17 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/groups.yaml: -------------------------------------------------------------------------------- 1 | default_view: 2 | view: yes 3 | entities: 4 | - group.alarm_clock 5 | 6 | alarm_clock: 7 | name: 'Réveil' 8 | entities: 9 | - sensor.alarm_clock_time 10 | - input_number.alarm_clock_hours 11 | - input_number.alarm_clock_minutes 12 | - input_boolean.alarm_clock_status 13 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/input_booleans.yaml: -------------------------------------------------------------------------------- 1 | alarm_clock_status: 2 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/input_numbers.yaml: -------------------------------------------------------------------------------- 1 | alarm_clock_hours: 2 | min: 0 3 | max: 23 4 | step: 1 5 | mode: slider 6 | alarm_clock_minutes: 7 | min: 0 8 | max: 55 9 | step: 5 10 | mode: slider 11 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/media_players.yaml: -------------------------------------------------------------------------------- 1 | - platform: onkyo 2 | host: 192.168.1.133 3 | name: 'Stereo' 4 | -------------------------------------------------------------------------------- /ha_config_alarm_clock/configuration/sensors.yaml: -------------------------------------------------------------------------------- 1 | - platform: template 2 | sensors: 3 | alarm_clock_hours: 4 | value_template: "{{ states('input_number.alarm_clock_hours') | round(0) }}" 5 | alarm_clock_minutes: 6 | value_template: "{{ states('input_number.alarm_clock_minutes') | round(0) }}" 7 | alarm_clock_time: 8 | value_template: "{% if states.sensor.alarm_clock_hours.state | length == 1 -%}0{%- endif -%}{{ states.sensor.alarm_clock_hours.state }}:{% if states.sensor.alarm_clock_minutes.state | length == 1 -%}0{%- endif -%}{{ states.sensor.alarm_clock_minutes.state }}" 9 | - platform: time_date 10 | display_options: 11 | - 'time' 12 | -------------------------------------------------------------------------------- /ha_config_zigate/README.md: -------------------------------------------------------------------------------- 1 | # Configuration - Zigate and ZigBee devices - Home Assistant 2 | A simple configuration example to add and control ZigBee devices paired to a [Zigate](https://zigate.fr), an open source ZigBee concentrator. 3 | 4 | ## Requirements 5 | ### Software 6 | Using the Zigate with Home Assistant requires to install `pyzigate` ([GitHub](https://github.com/elric91/ZiGate)) and copy the `homeassistant_zigate` component within the `custom_components` in Home Assistant's configuration folder ([GitHub](https://github.com/elric91/homeassistant_zigate)). 7 | 8 | ### Hardware 9 | - 1x [Zigate](https://zigate.fr) 10 | - 2x Philips white bulbs 11 | - 1x Xiaomi Aqara switch 12 | - 1x Xiaomi Aqara door sensor 13 | - 1x Xiaomi Aqara temperature/humidity/pressure sensor 14 | 15 | ## Configuration 16 | configuration.yaml : 17 | ```yaml 18 | homeassistant: 19 | 20 | ... 21 | 22 | switch: !include switches.yaml 23 | light: !include lights.yaml 24 | sensor: !include sensors.yaml 25 | automation: !include automations.yaml 26 | ``` 27 | 28 | Configuration for the Xiaomi Aqara door sensor : 29 | 30 | switches.yaml : 31 | ```yaml 32 | - platform: zigate 33 | name: 'Door' 34 | address: XXXX01 35 | default_state: 'state' 36 | inverted: 'yes' 37 | ``` 38 | 39 | Configuration for the two white Philips Hue bulbs : 40 | 41 | lights.yaml : 42 | ```yaml 43 | - platform: zigate 44 | name: 'Bedside' 45 | address: XXXX0b 46 | light_type: 'white' 47 | default_state: 'event' 48 | - platform: zigate 49 | name: 'Ceiling' 50 | address: XXXX0b 51 | light_type: 'white' 52 | default_state: 'event' 53 | ``` 54 | **Note** : Philips uses the `0b`cluster for their bulbs! 55 | 56 | Configuration for the Xiaomi Aqara temperature/humidity/pressure sensor and switch : 57 | 58 | sensors.yaml : 59 | ```yaml 60 | - platform: zigate 61 | name: 'Ceiling Switch' 62 | address: XXXX01 63 | default_state: 'state' 64 | - platform: zigate 65 | name: 'Temperature' 66 | address: XXXX01 67 | default_state: temperature 68 | default_unit: '°C' 69 | - platform: zigate 70 | name: 'Humidity' 71 | address: XXXX01 72 | default_state: humidity 73 | default_unit: '%' 74 | - platform: zigate 75 | name: 'Pressure' 76 | address: XXXX01 77 | default_state: pressure 78 | default_unit: 'mb' 79 | ``` 80 | 81 | Automation example to handle a single/double click on the Xiaomi Aqara switch : 82 | 83 | automations.yaml : 84 | ```yaml 85 | - alias: 'Ceiling Switch - Single Click' 86 | hide_entity: True 87 | trigger: 88 | entity_id: sensor.ceiling_switch 89 | platform: state 90 | to: 'off-release' 91 | action: 92 | service: light.toggle 93 | data: 94 | entity_id: light.ceiling 95 | - alias: 'Ceiling Switch - Double Click' 96 | hide_entity: True 97 | trigger: 98 | entity_id: sensor.ceiling_switch 99 | platform: state 100 | to: 'multi_2' 101 | action: 102 | service: light.toggle 103 | data: 104 | entity_id: light.bedside 105 | ``` 106 | 107 | ## References 108 | - [Instructions pour les ampoules Philips Hue](http://zigate.fr/837-2/) 109 | - [Configuration examples](https://github.com/elric91/homeassistant_zigate/wiki/Configuration-examples) 110 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_ble_scanner/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Binary Sensor - Bluetooth LE Device Tracker - Home Assistant 2 | A simple example describing how to track a Bluetooth Low Energy device with an ESP32, the MQTT protocol and Home Assistant. Please note that the targeted device can't have a changing BLE address (normally called random instead of public address). 3 | 4 | ![ESP32](esp32.jpg) 5 | 6 | ## Configuration 7 | To configure this sketch, you have to rename the header file `example.config.h` in `config.h`, provide the Bluetooth device(s) to track and add your Wi-Fi and MQTT credentials in the `SOFTWARE SECTION`. 8 | 9 | ### Bluetooth Device(s) 10 | ``` 11 | #define NB_OF_BLE_TRACKED_DEVICES 1 12 | BLETrackedDevice BLETrackedDevices[NB_OF_BLE_TRACKED_DEVICES] = { 13 | {"11:22:33:44:55:66", false, 0, false, {0}} 14 | }; 15 | 16 | // Location of the BLE scanner 17 | #define LOCATION "bedroom" 18 | ``` 19 | or with multiple devices 20 | ``` 21 | #define NB_OF_BLE_TRACKED_DEVICES 3 22 | BLETrackedDevice BLETrackedDevices[NB_OF_BLE_TRACKED_DEVICES] = { 23 | {"11:22:33:44:55:66", false, 0, false, {0}}, 24 | {"11:22:33:44:55:66", false, 0, false, {0}}, 25 | {"11:22:33:44:55:66", false, 0, false, {0}} 26 | }; 27 | 28 | // Location of the BLE scanner 29 | #define LOCATION "bedroom" 30 | ``` 31 | 32 | ### Credentials 33 | ``` 34 | // Wi-Fi credentials 35 | #define WIFI_SSID "" 36 | #define WIFI_PASSWORD "" 37 | 38 | // MQTT 39 | #define MQTT_USERNAME "" 40 | #define MQTT_PASSWORD "" 41 | #define MQTT_SERVER "" 42 | #define MQTT_SERVER_PORT 1883 43 | ``` 44 | 45 | ### Home Assistant 46 | To add the occupancy sensor to Home Assistant, please edit and add this snippet into your configuration. Make sure to replace `` and `` with the values defined in `config.h`. 47 | 48 | ```yaml 49 | # Example configuration.yaml entry 50 | binary_sensor: 51 | - platform: mqtt 52 | name: 'Occupancy' 53 | state_topic: '/sensor///state' 54 | availability_topic: ' THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 62 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 63 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 64 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 65 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 66 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 67 | SOFTWARE. 68 | 69 | *If you like the content of this repo, please add a star! Thank you!* 70 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_ble_scanner/esp32.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_binary_sensor_ble_scanner/esp32.jpg -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_ble_scanner/example.config.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////// 2 | // CONFIGURATION - SOFTWARE 3 | /////////////////////////////////////////////////////////////////////////// 4 | #define NB_OF_BLE_TRACKED_DEVICES 1 5 | BLETrackedDevice BLETrackedDevices[NB_OF_BLE_TRACKED_DEVICES] = { 6 | {"11:22:33:44:55:66", false, 0, false, {0}} 7 | }; 8 | 9 | #define BLE_SCANNING_PERIOD 5 10 | #define MAX_NON_ADV_PERIOD 10000 11 | 12 | // Location of the BLE scanner 13 | #define LOCATION "bedroom" 14 | 15 | // Debug output 16 | //#define DEBUG_SERIAL 17 | 18 | // Wi-Fi credentials 19 | #define WIFI_SSID "" 20 | #define WIFI_PASSWORD "" 21 | 22 | // Over-the-Air update 23 | // Not implemented yet 24 | //#define OTA 25 | //#define OTA_HOSTNAME "" // hostname esp8266-[ChipID] by default 26 | //#define OTA_PASSWORD "" // no password by default 27 | //#define OTA_PORT 8266 // port 8266 by default 28 | 29 | // MQTT 30 | #define MQTT_USERNAME "" 31 | #define MQTT_PASSWORD "" 32 | #define MQTT_SERVER "" 33 | #define MQTT_SERVER_PORT 1883 34 | 35 | #define MQTT_CONNECTION_TIMEOUT 5000 // [ms] 36 | 37 | // MQTT availability: available/unavailable 38 | #define MQTT_AVAILABILITY_TOPIC_TEMPLATE "%s/availability" 39 | // MQTT binary sensor: /sensor// 40 | #define MQTT_SENSOR_TOPIC_TEMPLATE "%s/sensor/%s/%s/state" 41 | 42 | #define MQTT_PAYLOAD_ON "ON" 43 | #define MQTT_PAYLOAD_OFF "OFF" 44 | 45 | #define MQTT_PAYLOAD_AVAILABLE "online" 46 | #define MQTT_PAYLOAD_UNAVAILABLE "offline" 47 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_ble_scanner/ha_mqtt_binary_sensor_ble_scanner.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Binary Sensor - Bluetooth LE Device Tracker - Home Assistant 3 | 4 | Libraries: 5 | - PubSubClient: https://github.com/knolleary/pubsubclient 6 | - ESP32 BLE: https://github.com/nkolban/ESP32_BLE_Arduino 7 | 8 | Sources: 9 | - https://github.com/nkolban/ESP32_BLE_Arduino/blob/master/examples/BLE_scan/BLE_scan.ino 10 | - https://www.youtube.com/watch?v=KNoFdKgvskU 11 | 12 | Samuel M. - v1.0 - 01.2018 13 | If you like this example, please add a star! Thank you! 14 | https://github.com/mertenats/open-home-automation 15 | */ 16 | 17 | typedef struct { 18 | String address; 19 | bool isDiscovered; 20 | long lastDiscovery; 21 | bool toNotify; 22 | char mqttTopic[48]; 23 | } BLETrackedDevice; 24 | 25 | #include "config.h" 26 | #include 27 | #include 28 | #include // https://github.com/knolleary/pubsubclient 29 | 30 | #if defined(DEBUG_SERIAL) 31 | #define DEBUG_PRINT(x) Serial.print(x) 32 | #define DEBUG_PRINTLN(x) Serial.println(x) 33 | #else 34 | #define DEBUG_PRINT(x) 35 | #define DEBUG_PRINTLN(x) 36 | #endif 37 | 38 | BLEScan* pBLEScan; 39 | WiFiClient wifiClient; 40 | PubSubClient mqttClient(wifiClient); 41 | 42 | /////////////////////////////////////////////////////////////////////////// 43 | // BLUETOOTH 44 | /////////////////////////////////////////////////////////////////////////// 45 | class MyAdvertisedDeviceCallbacks: 46 | public BLEAdvertisedDeviceCallbacks { 47 | void onResult(BLEAdvertisedDevice advertisedDevice) { 48 | for (uint8_t i = 0; i < NB_OF_BLE_TRACKED_DEVICES; i++) { 49 | if (strcmp(advertisedDevice.getAddress().toString().c_str(), BLETrackedDevices[i].address.c_str()) == 0) { 50 | if (!BLETrackedDevices[i].isDiscovered) { 51 | BLETrackedDevices[i].isDiscovered = true; 52 | BLETrackedDevices[i].lastDiscovery = millis(); 53 | BLETrackedDevices[i].toNotify = true; 54 | 55 | DEBUG_PRINT(F("INFO: Tracked device newly discovered, Address: ")); 56 | DEBUG_PRINT(advertisedDevice.getAddress().toString().c_str()); 57 | DEBUG_PRINT(F(", RSSI: ")); 58 | DEBUG_PRINTLN(advertisedDevice.getRSSI()); 59 | } else { 60 | BLETrackedDevices[i].lastDiscovery = millis(); 61 | DEBUG_PRINT(F("INFO: Tracked device discovered, Address: ")); 62 | DEBUG_PRINT(advertisedDevice.getAddress().toString().c_str()); 63 | DEBUG_PRINT(F(", RSSI: ")); 64 | DEBUG_PRINTLN(advertisedDevice.getRSSI()); 65 | } 66 | } else { 67 | DEBUG_PRINT(F("INFO: Device discovered, Address: ")); 68 | DEBUG_PRINT(advertisedDevice.getAddress().toString().c_str()); 69 | DEBUG_PRINT(F(", RSSI: ")); 70 | DEBUG_PRINTLN(advertisedDevice.getRSSI()); 71 | } 72 | } 73 | } 74 | }; 75 | 76 | /////////////////////////////////////////////////////////////////////////// 77 | // MQTT 78 | /////////////////////////////////////////////////////////////////////////// 79 | volatile unsigned long lastMQTTConnection = 0; 80 | char MQTT_CLIENT_ID[7] = {0}; 81 | char MQTT_AVAILABILITY_TOPIC[sizeof(MQTT_CLIENT_ID) + sizeof(MQTT_AVAILABILITY_TOPIC_TEMPLATE) - 2] = {0}; 82 | /* 83 | Function called to publish to a MQTT topic with the given payload 84 | */ 85 | void publishToMQTT(char* p_topic, char* p_payload) { 86 | if (mqttClient.publish(p_topic, p_payload, true)) { 87 | DEBUG_PRINT(F("INFO: MQTT message published successfully, topic: ")); 88 | DEBUG_PRINT(p_topic); 89 | DEBUG_PRINT(F(", payload: ")); 90 | DEBUG_PRINTLN(p_payload); 91 | } else { 92 | DEBUG_PRINTLN(F("ERROR: MQTT message not published, either connection lost, or message too large. Topic: ")); 93 | DEBUG_PRINT(p_topic); 94 | DEBUG_PRINT(F(" , payload: ")); 95 | DEBUG_PRINTLN(p_payload); 96 | } 97 | } 98 | /* 99 | Function called to connect/reconnect to the MQTT broker 100 | */ 101 | void connectToMQTT() { 102 | if (!mqttClient.connected()) { 103 | if (lastMQTTConnection < millis()) { 104 | if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD, MQTT_AVAILABILITY_TOPIC, 0, 1, MQTT_PAYLOAD_UNAVAILABLE)) { 105 | DEBUG_PRINTLN(F("INFO: The client is successfully connected to the MQTT broker")); 106 | publishToMQTT(MQTT_AVAILABILITY_TOPIC, MQTT_PAYLOAD_AVAILABLE); 107 | } else { 108 | DEBUG_PRINTLN(F("ERROR: The connection to the MQTT broker failed")); 109 | DEBUG_PRINT(F("INFO: MQTT username: ")); 110 | DEBUG_PRINTLN(MQTT_USERNAME); 111 | DEBUG_PRINT(F("INFO: MQTT password: ")); 112 | DEBUG_PRINTLN(MQTT_PASSWORD); 113 | DEBUG_PRINT(F("INFO: MQTT broker: ")); 114 | DEBUG_PRINTLN(MQTT_SERVER); 115 | } 116 | lastMQTTConnection = millis() + MQTT_CONNECTION_TIMEOUT; 117 | } 118 | } 119 | } 120 | 121 | /////////////////////////////////////////////////////////////////////////// 122 | // SETUP() & LOOP() 123 | /////////////////////////////////////////////////////////////////////////// 124 | void setup() { 125 | #if defined(DEBUG_SERIAL) 126 | Serial.begin(115200); 127 | #endif 128 | 129 | BLEDevice::init(""); 130 | pBLEScan = BLEDevice::getScan(); 131 | pBLEScan->setAdvertisedDeviceCallbacks(new MyAdvertisedDeviceCallbacks()); 132 | pBLEScan->setActiveScan(false); 133 | 134 | mqttClient.setServer(MQTT_SERVER, MQTT_SERVER_PORT); 135 | 136 | sprintf(MQTT_CLIENT_ID, "%06X", ESP.getEfuseMac()); 137 | sprintf(MQTT_AVAILABILITY_TOPIC, MQTT_AVAILABILITY_TOPIC_TEMPLATE, MQTT_CLIENT_ID); 138 | 139 | DEBUG_PRINT(F("INFO: MQTT availability topic: ")); 140 | DEBUG_PRINTLN(MQTT_AVAILABILITY_TOPIC); 141 | 142 | char mqttTopic[sizeof(MQTT_CLIENT_ID) + sizeof(MQTT_SENSOR_TOPIC_TEMPLATE) + sizeof(LOCATION) + 12 - 4] = {0}; 143 | for (uint8_t i = 0; i < NB_OF_BLE_TRACKED_DEVICES; i++) { 144 | char tmp_ble_address[13] = {0}; 145 | String tmp_string_ble_address = BLETrackedDevices[i].address; 146 | tmp_string_ble_address.replace(":", ""); 147 | tmp_string_ble_address.toCharArray(tmp_ble_address, sizeof(tmp_ble_address)); 148 | sprintf(mqttTopic, MQTT_SENSOR_TOPIC_TEMPLATE, MQTT_CLIENT_ID, LOCATION, tmp_ble_address); 149 | memcpy(BLETrackedDevices[i].mqttTopic, mqttTopic, sizeof(mqttTopic) + 1); 150 | DEBUG_PRINT(F("INFO: MQTT sensor topic: ")); 151 | DEBUG_PRINTLN(BLETrackedDevices[i].mqttTopic); 152 | } 153 | 154 | } 155 | 156 | void loop() { 157 | pBLEScan->start(BLE_SCANNING_PERIOD); 158 | 159 | static boolean enableWifi = false; 160 | for (uint8_t i = 0; i < NB_OF_BLE_TRACKED_DEVICES; i++) { 161 | if (BLETrackedDevices[i].toNotify) { 162 | enableWifi = true; 163 | } else if (BLETrackedDevices[i].isDiscovered == true && BLETrackedDevices[i].lastDiscovery + MAX_NON_ADV_PERIOD < millis()) { 164 | BLETrackedDevices[i].isDiscovered = false; 165 | BLETrackedDevices[i].toNotify = true; 166 | enableWifi = true; 167 | } 168 | } 169 | 170 | if (enableWifi) { 171 | enableWifi = false; 172 | 173 | DEBUG_PRINT(F("INFO: WiFi connecting to: ")); 174 | DEBUG_PRINTLN(WIFI_SSID); 175 | delay(10); 176 | WiFi.mode(WIFI_STA); 177 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 178 | randomSeed(micros()); 179 | 180 | while (WiFi.status() != WL_CONNECTED) { 181 | DEBUG_PRINT(F(".")); 182 | delay(500); 183 | } 184 | DEBUG_PRINTLN(); 185 | DEBUG_PRINTLN(WiFi.localIP()); 186 | 187 | while (!mqttClient.connected()) { 188 | connectToMQTT(); 189 | } 190 | 191 | for (uint8_t i = 0; i < NB_OF_BLE_TRACKED_DEVICES; i++) { 192 | if (BLETrackedDevices[i].toNotify) { 193 | if (BLETrackedDevices[i].isDiscovered) { 194 | publishToMQTT(BLETrackedDevices[i].mqttTopic, MQTT_PAYLOAD_ON); 195 | } else { 196 | publishToMQTT(BLETrackedDevices[i].mqttTopic, MQTT_PAYLOAD_OFF); 197 | } 198 | BLETrackedDevices[i].toNotify = false; 199 | } 200 | } 201 | 202 | mqttClient.disconnect(); 203 | WiFi.mode(WIFI_OFF); 204 | } 205 | } 206 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_ble_scanner/occupancy.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_binary_sensor_ble_scanner/occupancy.png -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_door/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Binary Sensor - Door - Home Assistant 2 | A simple example to monitor the state of a door with a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | binary_sensor: 8 | platform: mqtt 9 | name: 'Door' 10 | state_topic: 'CBF777/binary_sensor/door/state' 11 | sensor_class: opening 12 | ``` 13 | 14 | ## Schematic 15 | Door sensor 16 | - Door sensor leg 1 - D1 17 | - Door sensor leg 2 - GND 18 | 19 | Button 20 | - Switch leg 1 - VCC 21 | - Switch leg 2 - D2 - Resistor 10K Ohms - GND 22 | 23 | ## Wi-Fi and MQTT Configuration 24 | ![Steps](Steps.png) 25 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_door/Steps.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_binary_sensor_door/Steps.png -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_door/ha_mqtt_binary_sensor_door.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Binary Sensor - Door sensor for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/binary_sensor.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient: https://github.com/knolleary/pubsubclient 8 | - WiFiManager: https://github.com/tzapu/WiFiManager 9 | 10 | Sources : 11 | - File > Examples > ES8266WiFi > WiFiClient 12 | - File > Examples > PubSubClient > mqtt_auth 13 | 14 | Steps: 15 | - Upload the firmware 16 | - Connect to the new Wi-Fi AP and memorize its name 17 | - Choose your network and enter your MQTT username, password, broker 18 | IP address and broker port 19 | - Update your configuration in Home Assistant 20 | 21 | Configuration (Home Assistant) : 22 | binary_sensor: 23 | platform: mqtt 24 | name: 'Door' 25 | state_topic: 'CBF777/binary_sensor/door/state' 26 | sensor_class: opening 27 | 28 | Samuel M. - v1.0 - 11.2016 29 | If you like this example, please add a star! Thank you! 30 | https://github.com/mertenats/open-home-automation 31 | */ 32 | 33 | #include // https://github.com/esp8266/Arduino 34 | #include // https://github.com/tzapu/WiFiManager 35 | #include // https://github.com/knolleary/pubsubclient/releases/tag/v2.6 36 | #include 37 | #include 38 | #include 39 | 40 | #define DEBUG // enable debugging 41 | #define STRUCT_CHAR_ARRAY_SIZE 24 // size of the arrays for MQTT username, password, etc. 42 | 43 | // macros for debugging 44 | #ifdef DEBUG 45 | #define DEBUG_PRINT(x) Serial.print(x) 46 | #define DEBUG_PRINTLN(x) Serial.println(x) 47 | #else 48 | #define DEBUG_PRINT(x) 49 | #define DEBUG_PRINTLN(x) 50 | #endif 51 | 52 | // Pins used by the door sensor and the push button 53 | const PROGMEM uint8_t DOOR_SENSOR_PIN = D1; 54 | const PROGMEM uint8_t BUTTON_PIN = D2; 55 | const PROGMEM uint8_t BUILTINLED_PIN = BUILTIN_LED; 56 | 57 | // MQTT ID and topics 58 | char MQTT_CLIENT_ID[7] = {0}; 59 | char MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC[STRUCT_CHAR_ARRAY_SIZE] = {0}; 60 | const char* MQTT_ON_PAYLOAD = "ON"; 61 | const char* MQTT_OFF_PAYLOAD = "OFF"; 62 | 63 | // MQTT settings 64 | typedef struct { 65 | char mqttUser[STRUCT_CHAR_ARRAY_SIZE] = {0}; 66 | char mqttPassword[STRUCT_CHAR_ARRAY_SIZE] = {0}; 67 | char mqttServer[STRUCT_CHAR_ARRAY_SIZE] = {0}; 68 | char mqttPort[5] = {0}; 69 | } Settings; 70 | 71 | uint8_t doorState = LOW; 72 | uint8_t currentDoorState = doorState; 73 | uint8_t buttonState = LOW; 74 | uint8_t currentButtonState = buttonState; 75 | long buttonStartPressed = 0; 76 | long buttonDurationPressed = 0; 77 | 78 | enum CMD { 79 | CMD_NOT_DEFINED, 80 | CMD_DOOR_STATE_CHANGED, 81 | CMD_BUTTON_STATE_CHANGED, 82 | }; 83 | volatile uint8_t cmd = CMD_NOT_DEFINED; 84 | 85 | Settings settings; 86 | Ticker ticker; 87 | WiFiClient wifiClient; 88 | PubSubClient mqttClient(wifiClient); 89 | 90 | 91 | /////////////////////////////////////////////////////////////////////////// 92 | // MQTT 93 | /////////////////////////////////////////////////////////////////////////// 94 | 95 | /* 96 | Function called to publish the state of the door sensor 97 | */ 98 | void publishDoorState() { 99 | if (doorState == HIGH) { 100 | if (mqttClient.publish(MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC, MQTT_ON_PAYLOAD, true)) { 101 | DEBUG_PRINT(F("INFO: MQTT message publish succeeded. Topic: ")); 102 | DEBUG_PRINT(MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC); 103 | DEBUG_PRINT(F(". Payload: ")); 104 | DEBUG_PRINTLN(MQTT_ON_PAYLOAD); 105 | } else { 106 | DEBUG_PRINTLN(F("ERROR: MQTT message publish failed, either connection lost, or message too large")); 107 | } 108 | } else { 109 | if (mqttClient.publish(MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC, MQTT_OFF_PAYLOAD, true)) { 110 | DEBUG_PRINT(F("INFO: MQTT message publish succeeded. Topic: ")); 111 | DEBUG_PRINT(MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC); 112 | DEBUG_PRINT(F(". Payload: ")); 113 | DEBUG_PRINTLN(MQTT_OFF_PAYLOAD); 114 | } else { 115 | DEBUG_PRINTLN(F("ERROR: MQTT message publish failed, either connection lost, or message too large")); 116 | } 117 | } 118 | } 119 | 120 | /* 121 | Function called to connect/reconnect to the MQTT broker 122 | */ 123 | void reconnect() { 124 | uint8_t i = 0; 125 | while (!mqttClient.connected()) { 126 | if (mqttClient.connect(MQTT_CLIENT_ID, settings.mqttUser, settings.mqttPassword)) { 127 | DEBUG_PRINTLN(F("INFO: The client is successfully connected to the MQTT broker")); 128 | } else { 129 | DEBUG_PRINTLN(F("ERROR: The connection to the MQTT broker failed")); 130 | DEBUG_PRINT(F("Username: ")); 131 | DEBUG_PRINTLN(settings.mqttUser); 132 | DEBUG_PRINT(F("Password: ")); 133 | DEBUG_PRINTLN(settings.mqttPassword); 134 | DEBUG_PRINT(F("Broker: ")); 135 | DEBUG_PRINTLN(settings.mqttServer); 136 | delay(1000); 137 | if (i == 3) { 138 | reset(); 139 | } 140 | i++; 141 | } 142 | } 143 | } 144 | 145 | /////////////////////////////////////////////////////////////////////////// 146 | // WiFiManager 147 | /////////////////////////////////////////////////////////////////////////// 148 | /* 149 | Function called to toggle the state of the LED 150 | */ 151 | void tick() { 152 | digitalWrite(BUILTIN_LED, !digitalRead(BUILTIN_LED)); 153 | } 154 | 155 | // flag for saving data 156 | bool shouldSaveConfig = false; 157 | 158 | // callback notifying us of the need to save config 159 | void saveConfigCallback () { 160 | shouldSaveConfig = true; 161 | } 162 | 163 | void configModeCallback (WiFiManager *myWiFiManager) { 164 | ticker.attach(0.2, tick); 165 | } 166 | 167 | /////////////////////////////////////////////////////////////////////////// 168 | // ISR 169 | /////////////////////////////////////////////////////////////////////////// 170 | /* 171 | Function called when the door is opened/closed 172 | */ 173 | void doorStateChangedISR() { 174 | cmd = CMD_DOOR_STATE_CHANGED; 175 | } 176 | 177 | /* 178 | Function called when the button is pressed/released 179 | */ 180 | void buttonStateChangedISR() { 181 | cmd = CMD_BUTTON_STATE_CHANGED; 182 | } 183 | 184 | /////////////////////////////////////////////////////////////////////////// 185 | // ESP 186 | /////////////////////////////////////////////////////////////////////////// 187 | /* 188 | Function called to restart the switch 189 | */ 190 | void restart() { 191 | DEBUG_PRINTLN(F("INFO: Restart...")); 192 | ESP.reset(); 193 | delay(1000); 194 | } 195 | 196 | /* 197 | Function called to reset the configuration of the switch 198 | */ 199 | void reset() { 200 | DEBUG_PRINTLN(F("INFO: Reset...")); 201 | WiFi.disconnect(); 202 | delay(1000); 203 | ESP.reset(); 204 | delay(1000); 205 | } 206 | 207 | /////////////////////////////////////////////////////////////////////////// 208 | // Setup() and loop() 209 | /////////////////////////////////////////////////////////////////////////// 210 | void setup() { 211 | #ifdef DEBUG 212 | Serial.begin(115200); 213 | #endif 214 | pinMode(DOOR_SENSOR_PIN, INPUT_PULLUP); 215 | pinMode(BUTTON_PIN, INPUT); 216 | pinMode(BUILTIN_LED, OUTPUT); 217 | 218 | attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR_PIN), doorStateChangedISR, CHANGE); 219 | attachInterrupt(digitalPinToInterrupt(BUTTON_PIN), buttonStateChangedISR, CHANGE); 220 | 221 | ticker.attach(0.6, tick); 222 | 223 | sprintf(MQTT_CLIENT_ID, "%06X", ESP.getChipId()); 224 | DEBUG_PRINT(F("INFO: MQTT client ID/Hostname: ")); 225 | DEBUG_PRINTLN(MQTT_CLIENT_ID); 226 | 227 | sprintf(MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC, "%06X/binary_sensor/door/state", ESP.getChipId()); 228 | DEBUG_PRINT(F("INFO: MQTT command topic: ")); 229 | DEBUG_PRINTLN(MQTT_BINARY_SENSOR_DOOR_STATE_TOPIC); 230 | 231 | // load custom params 232 | EEPROM.begin(512); 233 | EEPROM.get(0, settings); 234 | EEPROM.end(); 235 | 236 | WiFiManagerParameter custom_mqtt_user("mqtt-user", "MQTT User", settings.mqttUser, STRUCT_CHAR_ARRAY_SIZE); 237 | WiFiManagerParameter custom_mqtt_password("mqtt-password", "MQTT Password", settings.mqttPassword, STRUCT_CHAR_ARRAY_SIZE, "type = \"password\""); 238 | WiFiManagerParameter custom_mqtt_server("mqtt-server", "MQTT Broker IP", settings.mqttServer, STRUCT_CHAR_ARRAY_SIZE); 239 | WiFiManagerParameter custom_mqtt_port("mqtt-port", "MQTT Broker Port", settings.mqttPort, 5); 240 | 241 | WiFiManager wifiManager; 242 | 243 | wifiManager.addParameter(&custom_mqtt_user); 244 | wifiManager.addParameter(&custom_mqtt_password); 245 | wifiManager.addParameter(&custom_mqtt_server); 246 | wifiManager.addParameter(&custom_mqtt_port); 247 | 248 | wifiManager.setAPCallback(configModeCallback); 249 | wifiManager.setConfigPortalTimeout(180); 250 | // set config save notify callback 251 | wifiManager.setSaveConfigCallback(saveConfigCallback); 252 | 253 | if (!wifiManager.autoConnect(MQTT_CLIENT_ID)) { 254 | ESP.reset(); 255 | delay(1000); 256 | } 257 | 258 | if (shouldSaveConfig) { 259 | strcpy(settings.mqttServer, custom_mqtt_server.getValue()); 260 | strcpy(settings.mqttPort, custom_mqtt_port.getValue()); 261 | strcpy(settings.mqttUser, custom_mqtt_user.getValue()); 262 | strcpy(settings.mqttPassword, custom_mqtt_password.getValue()); 263 | 264 | EEPROM.begin(512); 265 | EEPROM.put(0, settings); 266 | EEPROM.end(); 267 | } 268 | 269 | // configure MQTT 270 | mqttClient.setServer(settings.mqttServer, atoi(settings.mqttPort)); 271 | 272 | // connect to the MQTT broker 273 | reconnect(); 274 | 275 | ArduinoOTA.setHostname(MQTT_CLIENT_ID); 276 | ArduinoOTA.begin(); 277 | 278 | ticker.detach(); 279 | 280 | doorState = digitalRead(DOOR_SENSOR_PIN); 281 | buttonState = digitalRead(BUTTON_PIN); 282 | digitalWrite(BUILTIN_LED, HIGH); 283 | 284 | publishDoorState(); 285 | } 286 | 287 | void loop() { 288 | ArduinoOTA.handle(); 289 | 290 | yield(); 291 | 292 | // keep the MQTT client connected to the broker 293 | if (!mqttClient.connected()) { 294 | reconnect(); 295 | } 296 | mqttClient.loop(); 297 | 298 | yield(); 299 | 300 | switch (cmd) { 301 | case CMD_NOT_DEFINED: 302 | // do nothing ... 303 | break; 304 | case CMD_DOOR_STATE_CHANGED: 305 | currentDoorState = digitalRead(DOOR_SENSOR_PIN); 306 | if (doorState != currentDoorState) { 307 | if (currentDoorState == HIGH) { 308 | DEBUG_PRINTLN(F("INFO: Door opened")); 309 | } else { 310 | DEBUG_PRINTLN(F("INFO: Door closed")); 311 | } 312 | doorState = currentDoorState; 313 | } 314 | publishDoorState(); 315 | cmd = CMD_NOT_DEFINED; 316 | break; 317 | case CMD_BUTTON_STATE_CHANGED: 318 | currentButtonState = digitalRead(BUTTON_PIN); 319 | if (buttonState != currentButtonState) { 320 | // tests if the button is released or pressed 321 | if (buttonState == HIGH && currentButtonState == LOW) { 322 | buttonDurationPressed = millis() - buttonStartPressed; 323 | if (buttonDurationPressed < 500) { 324 | // do nothing 325 | DEBUG_PRINTLN(F("INFO: Single press")); 326 | } else if (buttonDurationPressed < 3000) { 327 | DEBUG_PRINTLN(F("INFO: Restarting...")); 328 | restart(); 329 | } else { 330 | DEBUG_PRINTLN(F("INFO: Reseting...")); 331 | reset(); 332 | } 333 | } else if (buttonState == LOW && currentButtonState == HIGH) { 334 | buttonStartPressed = millis(); 335 | } 336 | buttonState = currentButtonState; 337 | } 338 | cmd = CMD_NOT_DEFINED; 339 | break; 340 | } 341 | } 342 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_nfc_scanner/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Binary Sensor - NFC Tags Scanner - Home Assistant 2 | A simple example describing how to scan NFC tags with an ESP8266 and send the results through MQTT to Home Assistant. 3 | 4 | ![NFC](nfc_scanner.jpg) 5 | 6 | ## Schematic 7 | Requirements : 8 | - PN532 NFC RFID (Elechouse module v3) 9 | - ESP8266 (NodeMCU v1.0) 10 | 11 | | NFC reader | NodeMCU / ESP8266 | 12 | |------------|--------------------| 13 | | SS (CS) | D2 (GPIO4) | 14 | | SCK | D5 (GPIO14) | 15 | | MISO | D6 (GPIO12) | 16 | | MOSI | D7 (GPIO13) | 17 | | VCC | VCC (3V3) | 18 | | GND | GND | 19 | 20 | ## Configuration 21 | To configure this sketch, you have to rename the header file `example.config.h` in `config.h`, provide the NFC tag's UID to track, its desired name (for example `MifareTag`) and add your Wi-Fi and MQTT credentials in the `SOFTWARE SECTION`. 22 | 23 | ### NFC Tags 24 | ``` 25 | #define NB_OF_NFC_TRACKED_TAGS 1 26 | NFCTag NFCTags[NB_OF_NFC_TRACKED_TAGS] = { 27 | {{0x11, 0x22, 0x33, 0x44, 0x0, 0x0, 0x0}, "MifareTag", false, 0, false, {0}} 28 | }; 29 | 30 | // Location of the NFC scanner 31 | #define LOCATION "office" 32 | ``` 33 | or with multiple tags 34 | ``` 35 | #define NB_OF_NFC_TRACKED_TAGS 2 36 | NFCTag NFCTags[NB_OF_NFC_TRACKED_TAGS] = { 37 | {{0x11, 0x22, 0x33, 0x44, 0x0, 0x0, 0x0}, "MifareTag", false, 0, false, {0}}, 38 | {{0x12, 0x23, 0x34, 0x45, 0x0, 0x0, 0x0}, "MifareCard", false, 0, false, {0}}, 39 | }; 40 | ``` 41 | 42 | ### Credentials 43 | ``` 44 | // Wi-Fi credentials 45 | #define WIFI_SSID "" 46 | #define WIFI_PASSWORD "" 47 | 48 | // MQTT 49 | #define MQTT_USERNAME "" 50 | #define MQTT_PASSWORD "" 51 | #define MQTT_SERVER "" 52 | #define MQTT_SERVER_PORT 1883 53 | ``` 54 | 55 | ### Home Assistant 56 | To retrieve and use the results obtained with the NFC scanner into Home Assistant, please edit and add this snippet into your configuration. Make sure to replace `` and `` with the values defined in `config.h`. 57 | 58 | ```yaml 59 | # Example configuration.yaml entry 60 | binary_sensor: 61 | - platform: mqtt 62 | name: 'NFC Tag' 63 | state_topic: '/sensor///state' 64 | availability_topic: '/availability' 65 | - platform: mqtt 66 | name: 'NFC Card' 67 | state_topic: '/sensor///state' 68 | availability_topic: '/availability' 69 | ``` 70 | 71 | ![HA](ha.png) 72 | 73 | ## Licence 74 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 75 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 76 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 77 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 78 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 79 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 80 | SOFTWARE. 81 | 82 | *If you like the content of this repo, please add a star! Thank you!* 83 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_nfc_scanner/example.config.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////// 2 | // CONFIGURATION - SOFTWARE 3 | /////////////////////////////////////////////////////////////////////////// 4 | #define NB_OF_NFC_TRACKED_TAGS 2 5 | NFCTag NFCTags[NB_OF_NFC_TRACKED_TAGS] = { 6 | {{0x11, 0x22, 0x33, 0x44, 0x0, 0x0, 0x0}, "MifareTag", false, 0, false, {0}}, 7 | {{0x12, 0x23, 0x34, 0x45, 0x0, 0x0, 0x0}, "MifareCard", false, 0, false, {0}}, 8 | }; 9 | 10 | // send OFF payload after x ms 11 | #define MAX_NON_DISCOVERED_PERIOD 1000 12 | 13 | // Location of the BLE scanner 14 | #define LOCATION "office" 15 | 16 | // Debug output 17 | #define DEBUG_SERIAL 18 | 19 | // Wi-Fi credentials 20 | #define WIFI_SSID "" 21 | #define WIFI_PASSWORD "" 22 | 23 | // MQTT 24 | #define MQTT_USERNAME "" 25 | #define MQTT_PASSWORD "" 26 | #define MQTT_SERVER "" 27 | #define MQTT_SERVER_PORT 1883 28 | 29 | #define MQTT_CONNECTION_TIMEOUT 5000 // [ms] 30 | 31 | // MQTT availability: available/unavailable 32 | #define MQTT_AVAILABILITY_TOPIC_TEMPLATE "%s/availability" 33 | // MQTT binary sensor: /sensor// 34 | #define MQTT_SENSOR_TOPIC_TEMPLATE "%s/sensor/%s/%s/state" 35 | 36 | #define MQTT_PAYLOAD_ON "ON" 37 | #define MQTT_PAYLOAD_OFF "OFF" 38 | 39 | #define MQTT_PAYLOAD_AVAILABLE "online" 40 | #define MQTT_PAYLOAD_UNAVAILABLE "offline" 41 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_nfc_scanner/ha.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_binary_sensor_nfc_scanner/ha.png -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_nfc_scanner/ha_mqtt_binary_sensor_nfc_scanner.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Binary Sensor - NFC Tags Scanner - Home Assistant 3 | 4 | Libraries: 5 | - PubSubClient: https://github.com/knolleary/pubsubclient 6 | - PN532: https://github.com/Seeed-Studio/PN532 7 | 8 | Sources: 9 | - Examples > PN532 > readMifare 10 | 11 | Samuel M. - v1.0 - 02.2018 12 | If you like this example, please add a star! Thank you! 13 | https://github.com/mertenats/open-home-automation 14 | */ 15 | 16 | typedef struct { 17 | uint8_t uid[7]; 18 | String tagName; 19 | bool isDiscovered; 20 | long lastDiscovery; 21 | bool toNotify; 22 | char mqttTopic[48]; 23 | } NFCTag; 24 | 25 | #include "config.h" 26 | #include 27 | #include 28 | #include 29 | #include "PN532.h" // https://github.com/Seeed-Studio/PN532 30 | #include // https://github.com/knolleary/pubsubclient 31 | 32 | #if defined(DEBUG_SERIAL) 33 | #define DEBUG_PRINT(x) Serial.print(x) 34 | #define DEBUG_PRINTLN(x) Serial.println(x) 35 | #else 36 | #define DEBUG_PRINT(x) 37 | #define DEBUG_PRINTLN(x) 38 | #endif 39 | 40 | WiFiClient wifiClient; 41 | PubSubClient mqttClient(wifiClient); 42 | PN532_SPI pn532spi(SPI, 4); 43 | PN532 nfc(pn532spi); 44 | 45 | /////////////////////////////////////////////////////////////////////////// 46 | // NFC 47 | /////////////////////////////////////////////////////////////////////////// 48 | void readNFCTag() { 49 | uint8_t uid[] = { 0, 0, 0, 0, 0, 0, 0 }; // Buffer to store the returned UID 50 | uint8_t uidLength; 51 | 52 | if (nfc.readPassiveTargetID(PN532_MIFARE_ISO14443A, uid, &uidLength)) { 53 | for (uint8_t i = 0; i < NB_OF_NFC_TRACKED_TAGS; i++) { 54 | if (strcmp((char *)uid, (char *)NFCTags[i].uid) == 0) { 55 | if (!NFCTags[i].isDiscovered) { 56 | NFCTags[i].isDiscovered = true; 57 | NFCTags[i].toNotify = true; 58 | } 59 | NFCTags[i].lastDiscovery = millis(); 60 | break; 61 | } 62 | } 63 | } 64 | 65 | for (uint8_t i = 0; i < NB_OF_NFC_TRACKED_TAGS; i++) { 66 | if (NFCTags[i].isDiscovered == true && NFCTags[i].lastDiscovery + MAX_NON_DISCOVERED_PERIOD < millis()) { 67 | NFCTags[i].isDiscovered = false; 68 | NFCTags[i].toNotify = true; 69 | } 70 | } 71 | } 72 | 73 | /////////////////////////////////////////////////////////////////////////// 74 | // WiFi 75 | /////////////////////////////////////////////////////////////////////////// 76 | /* 77 | Function called to handle WiFi events 78 | */ 79 | void handleWiFiEvent(WiFiEvent_t event) { 80 | switch (event) { 81 | case WIFI_EVENT_STAMODE_GOT_IP: 82 | DEBUG_PRINTLN(F("INFO: Connection successful to the Wi-Fi AP")); 83 | DEBUG_PRINT(F("INFO: IP address: ")); 84 | DEBUG_PRINTLN(WiFi.localIP()); 85 | break; 86 | case WIFI_EVENT_STAMODE_DISCONNECTED: 87 | DEBUG_PRINTLN(F("ERROR: Connection lost from the Wi-Fi AP")); 88 | /* 89 | TODO: Doing something smarter than rebooting the device 90 | */ 91 | delay(5000); 92 | ESP.restart(); 93 | break; 94 | default: 95 | DEBUG_PRINT(F("INFO: WiFi event: ")); 96 | DEBUG_PRINTLN(event); 97 | break; 98 | } 99 | } 100 | 101 | /* 102 | Function called to setup the connection to the WiFi AP 103 | */ 104 | void setupWiFi() { 105 | DEBUG_PRINT(F("INFO: WiFi connecting to: ")); 106 | DEBUG_PRINTLN(WIFI_SSID); 107 | 108 | delay(10); 109 | 110 | WiFi.mode(WIFI_STA); 111 | WiFi.onEvent(handleWiFiEvent); 112 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 113 | 114 | randomSeed(micros()); 115 | } 116 | /////////////////////////////////////////////////////////////////////////// 117 | // MQTT 118 | /////////////////////////////////////////////////////////////////////////// 119 | volatile unsigned long lastMQTTConnection = 0; 120 | char MQTT_CLIENT_ID[7] = {0}; 121 | char MQTT_AVAILABILITY_TOPIC[sizeof(MQTT_CLIENT_ID) + sizeof(MQTT_AVAILABILITY_TOPIC_TEMPLATE) - 2] = {0}; 122 | /* 123 | Function called to publish to a MQTT topic with the given payload 124 | */ 125 | void publishToMQTT(char* p_topic, char* p_payload) { 126 | if (mqttClient.publish(p_topic, p_payload, true)) { 127 | DEBUG_PRINT(F("INFO: MQTT message published successfully, topic: ")); 128 | DEBUG_PRINT(p_topic); 129 | DEBUG_PRINT(F(", payload: ")); 130 | DEBUG_PRINTLN(p_payload); 131 | } else { 132 | DEBUG_PRINTLN(F("ERROR: MQTT message not published, either connection lost, or message too large. Topic: ")); 133 | DEBUG_PRINT(p_topic); 134 | DEBUG_PRINT(F(" , payload: ")); 135 | DEBUG_PRINTLN(p_payload); 136 | } 137 | } 138 | /* 139 | Function called to connect/reconnect to the MQTT broker 140 | */ 141 | void connectToMQTT() { 142 | if (!mqttClient.connected()) { 143 | if (lastMQTTConnection < millis()) { 144 | if (mqttClient.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD, MQTT_AVAILABILITY_TOPIC, 0, 1, MQTT_PAYLOAD_UNAVAILABLE)) { 145 | DEBUG_PRINTLN(F("INFO: The client is successfully connected to the MQTT broker")); 146 | publishToMQTT(MQTT_AVAILABILITY_TOPIC, MQTT_PAYLOAD_AVAILABLE); 147 | } else { 148 | DEBUG_PRINTLN(F("ERROR: The connection to the MQTT broker failed")); 149 | DEBUG_PRINT(F("INFO: MQTT username: ")); 150 | DEBUG_PRINTLN(MQTT_USERNAME); 151 | DEBUG_PRINT(F("INFO: MQTT password: ")); 152 | DEBUG_PRINTLN(MQTT_PASSWORD); 153 | DEBUG_PRINT(F("INFO: MQTT broker: ")); 154 | DEBUG_PRINTLN(MQTT_SERVER); 155 | } 156 | lastMQTTConnection = millis() + MQTT_CONNECTION_TIMEOUT; 157 | } 158 | } 159 | } 160 | 161 | /////////////////////////////////////////////////////////////////////////// 162 | // SETUP() & LOOP() 163 | /////////////////////////////////////////////////////////////////////////// 164 | void setup() { 165 | #if defined(DEBUG_SERIAL) 166 | Serial.begin(115200); 167 | #endif 168 | 169 | setupWiFi(); 170 | 171 | nfc.begin(); 172 | 173 | uint32_t nfcReaderFirmwareVersion = nfc.getFirmwareVersion(); 174 | if (!nfcReaderFirmwareVersion) { 175 | DEBUG_PRINTLN(F("ERROR: Didn't find PN53x board")); 176 | while (1); // halt 177 | } 178 | 179 | // configure board to read RFID tags 180 | nfc.SAMConfig(); 181 | 182 | sprintf(MQTT_CLIENT_ID, "%06X", ESP.getChipId()); 183 | sprintf(MQTT_AVAILABILITY_TOPIC, MQTT_AVAILABILITY_TOPIC_TEMPLATE, MQTT_CLIENT_ID); 184 | 185 | DEBUG_PRINT(F("INFO: MQTT availability topic: ")); 186 | DEBUG_PRINTLN(MQTT_AVAILABILITY_TOPIC); 187 | 188 | char mqttTopic[sizeof(MQTT_CLIENT_ID) + sizeof(MQTT_SENSOR_TOPIC_TEMPLATE) + sizeof(LOCATION) + 12 - 4] = {0}; 189 | for (uint8_t i = 0; i < NB_OF_NFC_TRACKED_TAGS; i++) { 190 | char tmpTagName[sizeof(NFCTags[i].tagName)] = {0}; 191 | NFCTags[i].tagName.toCharArray(tmpTagName, sizeof(tmpTagName)); 192 | sprintf(mqttTopic, MQTT_SENSOR_TOPIC_TEMPLATE, MQTT_CLIENT_ID, LOCATION, tmpTagName); 193 | memcpy(NFCTags[i].mqttTopic, mqttTopic, sizeof(mqttTopic) + 1); 194 | DEBUG_PRINT(F("INFO: MQTT sensor topic: ")); 195 | DEBUG_PRINTLN(NFCTags[i].mqttTopic); 196 | } 197 | 198 | mqttClient.setServer(MQTT_SERVER, MQTT_SERVER_PORT); 199 | connectToMQTT(); 200 | } 201 | 202 | void loop() { 203 | connectToMQTT(); 204 | mqttClient.loop(); 205 | 206 | yield(); 207 | 208 | readNFCTag(); 209 | 210 | yield(); 211 | 212 | for (uint8_t i = 0; i < NB_OF_NFC_TRACKED_TAGS; i++) { 213 | if (NFCTags[i].toNotify) { 214 | if (NFCTags[i].isDiscovered) { 215 | publishToMQTT(NFCTags[i].mqttTopic, MQTT_PAYLOAD_ON); 216 | } else { 217 | publishToMQTT(NFCTags[i].mqttTopic, MQTT_PAYLOAD_OFF); 218 | } 219 | NFCTags[i].toNotify = false; 220 | } 221 | } 222 | 223 | yield(); 224 | } 225 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_nfc_scanner/nfc_scanner.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_binary_sensor_nfc_scanner/nfc_scanner.jpg -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_pir/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Binary Sensor - Motion - Home Assistant 2 | A simple example to use a PIR motion sensor connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | binary_sensor: 8 | platform: mqtt 9 | state_topic: 'office/motion/status' 10 | name: 'Motion' 11 | sensor_class: motion 12 | ``` 13 | 14 | ## Schematic 15 | - PIR leg 1 - VCC 16 | - PIR leg 2 - D1/GPIO5 17 | - PIR leg 3 - GND 18 | 19 | ![Schematic](Schematic.png) 20 | -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_pir/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_binary_sensor_pir/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_binary_sensor_pir/ha_mqtt_binary_sensor_pir.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Binary Sensor - Motion (PIR) for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/binary_sensor.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | 9 | Sources : 10 | - File > Examples > ES8266WiFi > WiFiClient 11 | - File > Examples > PubSubClient > mqtt_auth 12 | - File > Examples > PubSubClient > mqtt_esp8266 13 | - https://learn.adafruit.com/pir-passive-infrared-proximity-motion-sensor/using-a-pir 14 | 15 | Schematic : 16 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_binary_sensor_pir/Schematic.png 17 | - PIR leg 1 - VCC 18 | - PIR leg 2 - D1/GPIO5 19 | - PIR leg 3 - GND 20 | 21 | Configuration (HA) : 22 | binary_sensor: 23 | platform: mqtt 24 | state_topic: 'office/motion/status' 25 | name: 'Motion' 26 | sensor_class: motion 27 | 28 | TODO : 29 | - Use the interrupts instead of constinously polling the sensor 30 | 31 | Samuel M. - v1.1 - 08.2016 32 | If you like this example, please add a star! Thank you! 33 | https://github.com/mertenats/open-home-automation 34 | */ 35 | 36 | #include 37 | #include 38 | 39 | #define MQTT_VERSION MQTT_VERSION_3_1_1 40 | 41 | // Wifi: SSID and password 42 | const PROGMEM char* WIFI_SSID = "[Redacted]"; 43 | const PROGMEM char* WIFI_PASSWORD = "[Redacted]"; 44 | 45 | // MQTT: ID, server IP, port, username and password 46 | const PROGMEM char* MQTT_CLIENT_ID = "office_motion"; 47 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 48 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 49 | const PROGMEM char* MQTT_USER = "[Redacted]"; 50 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 51 | 52 | // MQTT: topic 53 | const PROGMEM char* MQTT_MOTION_STATUS_TOPIC = "office/motion/status"; 54 | 55 | // default payload 56 | const PROGMEM char* MOTION_ON = "ON"; 57 | const PROGMEM char* MOTION_OFF = "OFF"; 58 | 59 | // PIR : D1/GPIO5 60 | const PROGMEM uint8_t PIR_PIN = 5; 61 | uint8_t m_pir_state = LOW; // no motion detected 62 | uint8_t m_pir_value = 0; 63 | 64 | WiFiClient wifiClient; 65 | PubSubClient client(wifiClient); 66 | 67 | // function called to publish the state of the pir sensor 68 | void publishPirSensorState() { 69 | if (m_pir_state) { 70 | client.publish(MQTT_MOTION_STATUS_TOPIC, MOTION_OFF, true); 71 | } else { 72 | client.publish(MQTT_MOTION_STATUS_TOPIC, MOTION_ON, true); 73 | } 74 | } 75 | 76 | // function called when a MQTT message arrived 77 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 78 | } 79 | 80 | void reconnect() { 81 | // Loop until we're reconnected 82 | while (!client.connected()) { 83 | Serial.println("INFO: Attempting MQTT connection..."); 84 | // Attempt to connect 85 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 86 | Serial.println("INFO: connected"); 87 | } else { 88 | Serial.print("ERROR: failed, rc="); 89 | Serial.print(client.state()); 90 | Serial.println("DEBUG: try again in 5 seconds"); 91 | // Wait 5 seconds before retrying 92 | delay(5000); 93 | } 94 | } 95 | } 96 | 97 | void setup() { 98 | // init the serial 99 | Serial.begin(115200); 100 | 101 | // init the WiFi connection 102 | Serial.println(); 103 | Serial.println(); 104 | Serial.print("INFO: Connecting to "); 105 | Serial.println(WIFI_SSID); 106 | WiFi.mode(WIFI_STA); 107 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 108 | 109 | while (WiFi.status() != WL_CONNECTED) { 110 | delay(500); 111 | Serial.print("."); 112 | } 113 | 114 | Serial.println(""); 115 | Serial.println("INFO: WiFi connected"); 116 | Serial.println("INFO: IP address: "); 117 | Serial.println(WiFi.localIP()); 118 | 119 | // init the MQTT connection 120 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 121 | client.setCallback(callback); 122 | } 123 | 124 | void loop() { 125 | if (!client.connected()) { 126 | reconnect(); 127 | } 128 | client.loop(); 129 | 130 | // read the PIR sensor 131 | m_pir_value = digitalRead(PIR_PIN); 132 | if (m_pir_value == HIGH) { 133 | if (m_pir_state == LOW) { 134 | // a motion is detected 135 | Serial.println("INFO: Motion detected"); 136 | publishPirSensorState(); 137 | m_pir_state = HIGH; 138 | } 139 | } else { 140 | if (m_pir_state == HIGH) { 141 | publishPirSensorState(); 142 | Serial.println("INFO: Motion ended"); 143 | m_pir_state = LOW; 144 | } 145 | } 146 | } 147 | -------------------------------------------------------------------------------- /ha_mqtt_light/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Light - Home Assistant 2 | A simple example to control a led connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | light: 8 | platform: mqtt 9 | name: 'Office light' 10 | state_topic: 'office/light1/status' 11 | command_topic: 'office/light1/switch' 12 | optimistic: false 13 | ``` 14 | 15 | ## Schematic 16 | - GND - LED - Resistor 220 Ohms - D1/GPIO5 17 | 18 | ![Schematic](Schematic.png) 19 | -------------------------------------------------------------------------------- /ha_mqtt_light/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_light/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_light/ha_mqtt_light.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Light for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/light.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | 9 | Sources : 10 | - File > Examples > ES8266WiFi > WiFiClient 11 | - File > Examples > PubSubClient > mqtt_auth 12 | - File > Examples > PubSubClient > mqtt_esp8266 13 | 14 | Schematic : 15 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_light/Schematic.png 16 | - GND - LED - Resistor 220 Ohms - D1/GPIO5 17 | 18 | Configuration (HA) : 19 | light: 20 | platform: mqtt 21 | name: Office light' 22 | state_topic: 'office/light1/status' 23 | command_topic: 'office/light1/switch' 24 | optimistic: false 25 | 26 | Samuel M. - v1.1 - 08.2016 27 | If you like this example, please add a star! Thank you! 28 | https://github.com/mertenats/open-home-automation 29 | */ 30 | 31 | #include 32 | #include 33 | 34 | #define MQTT_VERSION MQTT_VERSION_3_1_1 35 | 36 | // Wifi: SSID and password 37 | const char* WIFI_SSID = "[Redacted]"; 38 | const char* WIFI_PASSWORD = "[Redacted]"; 39 | 40 | // MQTT: ID, server IP, port, username and password 41 | const PROGMEM char* MQTT_CLIENT_ID = "office_light1"; 42 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 43 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 44 | const PROGMEM char* MQTT_USER = "[Redacted]"; 45 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 46 | 47 | // MQTT: topics 48 | const char* MQTT_LIGHT_STATE_TOPIC = "office/light1/status"; 49 | const char* MQTT_LIGHT_COMMAND_TOPIC = "office/light1/switch"; 50 | 51 | // payloads by default (on/off) 52 | const char* LIGHT_ON = "ON"; 53 | const char* LIGHT_OFF = "OFF"; 54 | 55 | const PROGMEM uint8_t LED_PIN = 5; 56 | boolean m_light_state = false; // light is turned off by default 57 | 58 | WiFiClient wifiClient; 59 | PubSubClient client(wifiClient); 60 | 61 | // function called to publish the state of the light (on/off) 62 | void publishLightState() { 63 | if (m_light_state) { 64 | client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true); 65 | } else { 66 | client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true); 67 | } 68 | } 69 | 70 | // function called to turn on/off the light 71 | void setLightState() { 72 | if (m_light_state) { 73 | digitalWrite(LED_PIN, HIGH); 74 | Serial.println("INFO: Turn light on..."); 75 | } else { 76 | digitalWrite(LED_PIN, LOW); 77 | Serial.println("INFO: Turn light off..."); 78 | } 79 | } 80 | 81 | // function called when a MQTT message arrived 82 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 83 | // concat the payload into a string 84 | String payload; 85 | for (uint8_t i = 0; i < p_length; i++) { 86 | payload.concat((char)p_payload[i]); 87 | } 88 | 89 | // handle message topic 90 | if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) { 91 | // test if the payload is equal to "ON" or "OFF" 92 | if (payload.equals(String(LIGHT_ON))) { 93 | if (m_light_state != true) { 94 | m_light_state = true; 95 | setLightState(); 96 | publishLightState(); 97 | } 98 | } else if (payload.equals(String(LIGHT_OFF))) { 99 | if (m_light_state != false) { 100 | m_light_state = false; 101 | setLightState(); 102 | publishLightState(); 103 | } 104 | } 105 | } 106 | } 107 | 108 | void reconnect() { 109 | // Loop until we're reconnected 110 | while (!client.connected()) { 111 | Serial.println("INFO: Attempting MQTT connection..."); 112 | // Attempt to connect 113 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 114 | Serial.println("INFO: connected"); 115 | // Once connected, publish an announcement... 116 | publishLightState(); 117 | // ... and resubscribe 118 | client.subscribe(MQTT_LIGHT_COMMAND_TOPIC); 119 | } else { 120 | Serial.print("ERROR: failed, rc="); 121 | Serial.print(client.state()); 122 | Serial.println("DEBUG: try again in 5 seconds"); 123 | // Wait 5 seconds before retrying 124 | delay(5000); 125 | } 126 | } 127 | } 128 | 129 | void setup() { 130 | // init the serial 131 | Serial.begin(115200); 132 | 133 | // init the led 134 | pinMode(LED_PIN, OUTPUT); 135 | analogWriteRange(255); 136 | setLightState(); 137 | 138 | // init the WiFi connection 139 | Serial.println(); 140 | Serial.println(); 141 | Serial.print("INFO: Connecting to "); 142 | WiFi.mode(WIFI_STA); 143 | Serial.println(WIFI_SSID); 144 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 145 | 146 | while (WiFi.status() != WL_CONNECTED) { 147 | delay(500); 148 | Serial.print("."); 149 | } 150 | 151 | Serial.println(""); 152 | Serial.println("INFO: WiFi connected"); 153 | Serial.print("INFO: IP address: "); 154 | Serial.println(WiFi.localIP()); 155 | 156 | // init the MQTT connection 157 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 158 | client.setCallback(callback); 159 | } 160 | 161 | void loop() { 162 | if (!client.connected()) { 163 | reconnect(); 164 | } 165 | client.loop(); 166 | } 167 | -------------------------------------------------------------------------------- /ha_mqtt_light_arilux/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Samuel Mertenat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ha_mqtt_light_arilux/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Light - Arilux - Home Assistant 2 | This sketch is an alternative firmware for Arilux LED controllers, based on the [WS2812FX](https://github.com/kitesurfer1404/WS2812FX) library and is compatible with `Home Assistant` through the `MQTT` protocol. 3 | 4 | ## Configuration 5 | To configure this sketch, you have to rename the header file `example.config.h` in `config.h`. Then, it is possible to modify the `name` and the `location` of the device or edit your Wi-Fi and MQTT credentials. Note that the device `name` and `location` are used to create the MQTT topics. 6 | 7 | ### Device location and name 8 | ``` 9 | #define DEVICE_LOCATION "bedroom" 10 | #define DEVICE_NAME "arilux" // also used as MQTT ID 11 | ``` 12 | 13 | ### Credentials 14 | Wi-Fi : 15 | 16 | ``` 17 | #define WIFI_SSID "" 18 | #define WIFI_PASSWORD "" 19 | ``` 20 | MQTT : 21 | 22 | ``` 23 | #define MQTT_USERNAME "" 24 | #define MQTT_PASSWORD "" 25 | #define MQTT_SERVER "" 26 | #define MQTT_SERVER_PORT 1883 27 | ``` 28 | 29 | ### Home Assistant 30 | To integrate the light in Home Assistant, please edit and add this snippet into your configuration. 31 | 32 | ```yaml 33 | # Example configuration.yml entry 34 | light: 35 | - platform: mqtt 36 | schema: json 37 | state_topic: 'bedroom/arilux/state' 38 | command_topic: 'bedroom/arilux/set' 39 | brightness: true 40 | rgb: true 41 | white_value: true 42 | effect: true 43 | effect_list: 44 | - 'Static' 45 | - 'Blink' 46 | - 'Breath' 47 | - 'Random Color' 48 | - 'Rainbow' 49 | - 'Fade' 50 | - 'Strobe' 51 | - 'Strobe Rainbow' 52 | - 'Multi Strobe' 53 | - 'Blink Rainbow' 54 | - 'Comet' 55 | - 'Fire Flicker' 56 | - 'Halloween' 57 | ``` 58 | 59 | ## Flash the firmware and control 60 | More information available [here](https://github.com/mertenats/Arilux_AL-LC0X). 61 | 62 | Example of a returned state : 63 | ``` 64 | { 65 | "state" : "ON", 66 | "brightness" : 255, 67 | "color" : { 68 | "r" : 0, 69 | "g" : 250, 70 | "b" : 0 71 | }, 72 | "white_value" : 0, 73 | "effect" : "Static" 74 | } 75 | ``` 76 | 77 | ## Licence 78 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 79 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 80 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 81 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 82 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 83 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 84 | SOFTWARE. 85 | 86 | *If you like the content of this repo, please add a star! Thank you!* 87 | -------------------------------------------------------------------------------- /ha_mqtt_light_arilux/example.config.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////////////////////////// 2 | // WIFI 3 | /////////////////////////////////////////////////////////////////////////////////////////////// 4 | 5 | #define WIFI_SSID "" 6 | #define WIFI_PASSWORD "" 7 | 8 | 9 | /////////////////////////////////////////////////////////////////////////////////////////////// 10 | // DEVICE 11 | /////////////////////////////////////////////////////////////////////////////////////////////// 12 | 13 | #define DEVICE_LOCATION "bedroom" 14 | #define DEVICE_NAME "arilux" // also used as MQTT ID 15 | 16 | 17 | /////////////////////////////////////////////////////////////////////////////////////////////// 18 | // MQTT 19 | /////////////////////////////////////////////////////////////////////////////////////////////// 20 | 21 | #define MQTT_USERNAME "" 22 | #define MQTT_PASSWORD "" 23 | #define MQTT_SERVER "" 24 | #define MQTT_SERVER_PORT 1883 25 | 26 | // MQTT topics 27 | // - status state 28 | // < DEVICE_LOCATION >/< DEVICE_NAME >/state 29 | // - command 30 | // < DEVICE_LOCATION >/< DEVICE_NAME >/set 31 | // ... 32 | #define MQTT_AVAILABILITY_TOPIC DEVICE_LOCATION "/" DEVICE_NAME 33 | #define MQTT_STATE_TOPIC DEVICE_LOCATION "/" DEVICE_NAME "/state" 34 | #define MQTT_CMD_TOPIC DEVICE_LOCATION "/" DEVICE_NAME "/set" 35 | 36 | #define MQTT_STATE_ON_PAYLOAD "ON" 37 | #define MQTT_STATE_OFF_PAYLOAD "OFF" 38 | 39 | #define MQTT_AVAILABLE_PAYLOAD "online" 40 | #define MQTT_NOT_AVAILABLE_PAYLOAD "offline" 41 | 42 | 43 | /////////////////////////////////////////////////////////////////////////////////////////////// 44 | // ARILUX 45 | /////////////////////////////////////////////////////////////////////////////////////////////// 46 | 47 | #define RED_PIN 5 48 | #define GREEN_PIN 14 49 | #define BLUE_PIN 12 50 | #define WHITE_PIN 13 51 | 52 | #define PWM_MAX 255 53 | #define PWM_MIN 0 54 | #define PWM_FREQUENCY 500 55 | -------------------------------------------------------------------------------- /ha_mqtt_light_arilux/ha_mqtt_light_arilux.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Light for Home-Assistant - Arilux (ESP8266) 3 | 4 | Libraries : 5 | - ESP8266 Core : https://github.com/esp8266/Arduino 6 | - PubSubClient : https://github.com/knolleary/pubsubclient 7 | - WS2812FX : https://github.com/kitesurfer1404/WS2812FX 8 | - ArduinoJson : https://github.com/bblanchon/ArduinoJson 9 | 10 | Configuration for Home Assistant : 11 | light: 12 | - platform: mqtt 13 | schema: json 14 | state_topic: 'bedroom/arilux/state' 15 | command_topic: 'bedroom/arilux/set' 16 | brightness: true 17 | rgb: true 18 | white_value: true 19 | effect: true 20 | effect_list: 21 | - 'Static' 22 | - 'Blink' 23 | - 'Breath' 24 | - 'Random Color' 25 | - 'Rainbow' 26 | - 'Fade' 27 | - 'Strobe' 28 | - 'Strobe Rainbow' 29 | - 'Multi Strobe' 30 | - 'Blink Rainbow' 31 | - 'Comet' 32 | - 'Fire Flicker' 33 | - 'Halloween' 34 | 35 | Samuel M. - v1.0 - 01.2019 36 | If you like this example, please add a star! Thank you! 37 | https://github.com/mertenats/open-home-automation 38 | */ 39 | 40 | #include 41 | #include // https://github.com/knolleary/pubsubclient 42 | #include // https://github.com/bblanchon/ArduinoJson 43 | #include // https://github.com/kitesurfer1404/WS2812FX 44 | 45 | #include "config.h" 46 | 47 | struct RGBW { 48 | uint8_t red; 49 | uint8_t green; 50 | uint8_t blue; 51 | uint8_t white; 52 | bool isWhiteSelected; 53 | uint8_t brightness; 54 | }; 55 | 56 | WiFiClient wifiClient; 57 | PubSubClient mqttClient(wifiClient); 58 | WS2812FX ws2812fx = WS2812FX(1, NULL, NEO_RGBW); 59 | RGBW rgbw = {PWM_MIN,PWM_MIN,PWM_MIN,PWM_MIN,false,PWM_MAX}; 60 | 61 | long lastReconnectAttempt = 0; 62 | bool newStateToPublish = false; 63 | 64 | /////////////////////////////////////////////////////////////////////////////////////////////// 65 | // LIGHT 66 | /////////////////////////////////////////////////////////////////////////////////////////////// 67 | uint8_t getRedValueFromRGB(uint32_t p_color) {return p_color >> 16;} 68 | uint8_t getGreenValueFromRGB(uint32_t p_color) {return p_color >> 8;} 69 | uint8_t getBlueValueFromRGB(uint32_t p_color) {return p_color;} 70 | 71 | void customShow(void) { 72 | // get the current color 73 | uint32 rgb = ws2812fx.getPixelColor(0); 74 | 75 | // retrieve the value for each channel 76 | rgbw.red = getRedValueFromRGB(rgb); 77 | rgbw.green = getGreenValueFromRGB(rgb); 78 | rgbw.blue = getBlueValueFromRGB(rgb); 79 | 80 | // set each channel with the new value 81 | analogWrite(RED_PIN, map(rgbw.red, PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness)); 82 | analogWrite(GREEN_PIN, map(rgbw.green, PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness)); 83 | analogWrite(BLUE_PIN, map(rgbw.blue, PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness)); 84 | analogWrite(WHITE_PIN, map(rgbw.white, PWM_MIN, PWM_MAX, PWM_MIN, rgbw.brightness)); 85 | } 86 | 87 | void setupLight(void) { 88 | // set the pins as output 89 | pinMode(RED_PIN, OUTPUT); 90 | pinMode(GREEN_PIN, OUTPUT); 91 | pinMode(BLUE_PIN, OUTPUT); 92 | pinMode(WHITE_PIN, OUTPUT); 93 | 94 | analogWriteFreq(PWM_FREQUENCY); 95 | analogWriteRange(PWM_MAX); 96 | 97 | ws2812fx.init(); 98 | ws2812fx.setColor(GREEN); 99 | ws2812fx.stop(); 100 | ws2812fx.setCustomShow(customShow); 101 | } 102 | 103 | 104 | /////////////////////////////////////////////////////////////////////////////////////////////// 105 | // MQTT 106 | /////////////////////////////////////////////////////////////////////////////////////////////// 107 | 108 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 109 | String topic(p_topic); 110 | 111 | if (topic.equals(MQTT_CMD_TOPIC)) { 112 | DynamicJsonBuffer dynamicJsonBuffer; 113 | JsonObject& root = dynamicJsonBuffer.parseObject(p_payload); 114 | 115 | // check if the payload contains a new state 116 | if (root.containsKey("state")) { 117 | if (strcmp(root["state"], MQTT_STATE_ON_PAYLOAD) == 0) { 118 | if (ws2812fx.isRunning() == false) { 119 | if (rgbw.isWhiteSelected == true) { 120 | rgbw.white = PWM_MAX; 121 | } 122 | 123 | ws2812fx.start(); 124 | newStateToPublish = true; 125 | } 126 | } else if (strcmp(root["state"], MQTT_STATE_OFF_PAYLOAD) == 0) { 127 | if (ws2812fx.isRunning() == true) { 128 | if (rgbw.isWhiteSelected == true) { 129 | rgbw.white = PWM_MIN; 130 | } 131 | 132 | ws2812fx.stop(); 133 | newStateToPublish = true; 134 | } 135 | } 136 | } 137 | 138 | // check if the payload contains a new color value 139 | if (root.containsKey("color")) { 140 | uint8_t red = root["color"]["r"]; 141 | uint8_t green = root["color"]["g"]; 142 | uint8_t blue = root["color"]["b"]; 143 | 144 | if ((red >= PWM_MIN || red <= PWM_MAX) && (green >= PWM_MIN || green <= PWM_MAX) && (blue >= PWM_MIN || blue <= PWM_MAX)) { 145 | rgbw.white = PWM_MIN; 146 | rgbw.isWhiteSelected = false; 147 | ws2812fx.setMode(FX_MODE_STATIC); 148 | ws2812fx.setColor(red, green, blue); 149 | newStateToPublish = true; 150 | } 151 | } 152 | 153 | // check if the payload contains a new brightness value 154 | if (root.containsKey("brightness")) { 155 | uint8_t brightness = root["brightness"]; 156 | 157 | if (brightness >= PWM_MIN || brightness <= PWM_MAX) { 158 | rgbw.brightness = brightness; 159 | newStateToPublish = true; 160 | } 161 | } 162 | 163 | // check if the payload contains a new white value 164 | if (root.containsKey("white_value")) { 165 | uint8_t white_value = root["white_value"]; 166 | 167 | if (white_value >= PWM_MIN || white_value <= PWM_MAX) { 168 | rgbw.white = PWM_MAX; 169 | rgbw.brightness = white_value; 170 | rgbw.isWhiteSelected = true; 171 | ws2812fx.setMode(FX_MODE_STATIC); 172 | ws2812fx.setColor(0, 0, 0); 173 | newStateToPublish = true; 174 | } 175 | } 176 | 177 | // check if the payload contains a new effect value 178 | if (root.containsKey("effect")) { 179 | const char* effect = root["effect"]; 180 | 181 | // TODO check if current effect is different 182 | rgbw.white = PWM_MIN; 183 | rgbw.isWhiteSelected = false; 184 | newStateToPublish = true; 185 | 186 | if (strcmp_P(effect, (const char*)name_0) == 0) { 187 | ws2812fx.setMode(FX_MODE_STATIC); 188 | } else if (strcmp_P(effect, (const char*)name_1) == 0) { 189 | ws2812fx.setMode(FX_MODE_BLINK); 190 | } else if (strcmp_P(effect, (const char*)name_2) == 0) { 191 | ws2812fx.setMode(FX_MODE_BREATH); 192 | } else if (strcmp_P(effect, (const char*)name_8) == 0) { 193 | ws2812fx.setMode(FX_MODE_RANDOM_COLOR); 194 | } else if (strcmp_P(effect, (const char*)name_11) == 0) { 195 | ws2812fx.setMode(FX_MODE_RAINBOW); 196 | } else if (strcmp_P(effect, (const char*)name_15) == 0) { 197 | ws2812fx.setMode(FX_MODE_FADE); 198 | } else if (strcmp_P(effect, (const char*)name_26) == 0) { 199 | ws2812fx.setMode(FX_MODE_STROBE); 200 | } else if (strcmp_P(effect, (const char*)name_27) == 0) { 201 | ws2812fx.setMode(FX_MODE_STROBE_RAINBOW); 202 | } else if (strcmp_P(effect, (const char*)name_28) == 0) { 203 | ws2812fx.setMode(FX_MODE_MULTI_STROBE); 204 | } else if (strcmp_P(effect, (const char*)name_29) == 0) { 205 | ws2812fx.setMode(FX_MODE_BLINK_RAINBOW); 206 | } else if (strcmp_P(effect, (const char*)name_44) == 0) { 207 | ws2812fx.setMode(FX_MODE_COMET); 208 | } else if (strcmp_P(effect, (const char*)name_48) == 0) { 209 | ws2812fx.setMode(FX_MODE_FIRE_FLICKER); 210 | } else if (strcmp_P(effect, (const char*)name_52) == 0) { 211 | ws2812fx.setMode(FX_MODE_HALLOWEEN); 212 | } else { 213 | ws2812fx.setMode(FX_MODE_BLINK); 214 | } 215 | } 216 | } 217 | } 218 | 219 | void sendState(void) { 220 | DynamicJsonBuffer dynamicJsonBuffer; 221 | JsonObject& root = dynamicJsonBuffer.createObject(); 222 | root["state"] = ws2812fx.isRunning() ? MQTT_STATE_ON_PAYLOAD : MQTT_STATE_OFF_PAYLOAD; 223 | root["brightness"] = rgbw.brightness; 224 | JsonObject& color = root.createNestedObject("color"); 225 | color["r"] = rgbw.red; 226 | color["g"] = rgbw.green; 227 | color["b"] = rgbw.blue; 228 | root["white_value"] = rgbw.white == 0 ? 0 : rgbw.brightness; 229 | root["effect"] = ws2812fx.getModeName(ws2812fx.getMode());//"Static"; 230 | 231 | char tmp[128] = {0}; 232 | root.printTo(tmp); 233 | mqttClient.publish(MQTT_STATE_TOPIC, tmp); 234 | } 235 | 236 | bool reconnect() { 237 | if (mqttClient.connect(DEVICE_NAME, MQTT_USERNAME, MQTT_PASSWORD, MQTT_AVAILABILITY_TOPIC, 0, 1, MQTT_NOT_AVAILABLE_PAYLOAD)) { 238 | mqttClient.subscribe(MQTT_CMD_TOPIC); 239 | mqttClient.publish(MQTT_AVAILABILITY_TOPIC, MQTT_AVAILABLE_PAYLOAD); 240 | 241 | sendState(); 242 | } 243 | return mqttClient.connected(); 244 | } 245 | 246 | void setupMQTT(void) { 247 | mqttClient.setServer(MQTT_SERVER, MQTT_SERVER_PORT); 248 | mqttClient.setCallback(callback); 249 | } 250 | 251 | /////////////////////////////////////////////////////////////////////////////////////////////// 252 | // WIFI 253 | /////////////////////////////////////////////////////////////////////////////////////////////// 254 | 255 | void setupWiFi(void) { 256 | WiFi.mode(WIFI_STA); 257 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 258 | 259 | while (WiFi.status() != WL_CONNECTED) { 260 | delay(500); 261 | } 262 | } 263 | 264 | /////////////////////////////////////////////////////////////////////////////////////////////// 265 | // SETUP and LOOP 266 | /////////////////////////////////////////////////////////////////////////////////////////////// 267 | 268 | void setup() { 269 | setupWiFi(); 270 | 271 | setupMQTT(); 272 | 273 | setupLight(); 274 | 275 | ArduinoOTA.begin(); 276 | } 277 | 278 | 279 | void loop() { 280 | if (!mqttClient.connected()) { 281 | long now = millis(); 282 | if (now - lastReconnectAttempt > 5000) { 283 | lastReconnectAttempt = now; 284 | if (reconnect()) 285 | lastReconnectAttempt = 0; 286 | } 287 | } else { 288 | mqttClient.loop(); 289 | } 290 | 291 | ws2812fx.service(); 292 | 293 | yield(); 294 | 295 | if (newStateToPublish) { 296 | newStateToPublish = false; 297 | sendState(); 298 | } 299 | 300 | yield(); 301 | 302 | ArduinoOTA.handle(); 303 | } 304 | -------------------------------------------------------------------------------- /ha_mqtt_light_with_WiFiManager_mDNS_and_OTA/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Light with WiFiManager, mDNS and OTA - Home Assistant 2 | A simple example to control the built-in led connected to a NodeMCU board (ESP8266). 3 | 4 | ## Advanced features 5 | - WiFiManager: To list the available Wifi AP and to connect to one of them. 6 | - mDNS: To look for the IP address and the port of the local MQTT broker. 7 | - OTA: To update the firmware over-the-air. 8 | 9 | ## Configuration 10 | ### MQTT broker server 11 | Steps: 12 | - sudo apt-get install avahi-deamon (installed by default) 13 | - sudo nano /etc/avahi/services/mqtt.service 14 | - Copy/paste the following lines: 15 | ```xml 16 | 17 | 18 | 19 | %h 20 | 21 | _mqtt._tcp 22 | 1883 23 | 24 | 25 | ``` 26 | - sudo service avahi-daemon restart 27 | 28 | ### Home-Assistant 29 | Warning: 'F90D5F' corresponds to the chip ID of my ESP8266. 30 | Your chip ID is visible in the logs and corresponds to the name of the initial AP. 31 | 32 | configuration.yaml : 33 | ```yaml 34 | light: 35 | platform: mqtt 36 | name: 'Office light' 37 | state_topic: '9A6C95/light' 38 | command_topic: '9A6C95/light/switch' 39 | optimistic: false 40 | ``` 41 | 42 | ## Steps 43 | 1. Select the Wifi AP provided by the ESP8266. A window is open, 44 | 2. Select "Configure WiFi", 45 | 3. Choose your Wifi AP in the list and enter your password, 46 | 4. Enter the MQTT username and password. Press "save", 47 | 5. Configure Home-Assitant. 48 | 49 | ![Schematic](Schematic.jpg) 50 | 51 | -------------------------------------------------------------------------------- /ha_mqtt_light_with_WiFiManager_mDNS_and_OTA/Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_light_with_WiFiManager_mDNS_and_OTA/Schematic.jpg -------------------------------------------------------------------------------- /ha_mqtt_light_with_WiFiManager_mDNS_and_OTA/ha_mqtt_light_with_WiFiManager_mDNS_and_OTA.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Light for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/switch.mqtt/ 4 | 5 | Features: 6 | - WiFiManager 7 | - mDNS 8 | - OTA 9 | 10 | Libraries: 11 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 12 | - WiFiManager: https://github.com/tzapu/WiFiManager 13 | - ESP8266mDNS: https://github.com/esp8266/Arduino/tree/master/libraries/ESP8266mDNS 14 | - ArduinoJson: https://github.com/bblanchon/ArduinoJson 15 | 16 | Sources: 17 | - File > Examples > WiFiManager > AutoConnectWithFSParameters 18 | - File > Examples > ArduinoOTA > BasicOTA 19 | 20 | Configuration (HA): 21 | Warning: 'F90D5F' corresponds to the chip ID of my ESP 22 | Your chip ID is visible in the logs and the initial WIFI AP has the same name 23 | light: 24 | platform: mqtt 25 | name: 'Office light' 26 | state_topic: 'F90D5F/light' 27 | command_topic: 'F90D5F/light/switch' 28 | optimistic: false 29 | 30 | Samuel M. - v1.0 - 08.2016 31 | If you like this example, please add a star! Thank you! 32 | https://github.com/mertenats/open-home-automation 33 | */ 34 | 35 | #include 36 | #include 37 | 38 | /* 39 | WiFiManager 40 | Doc: https://github.com/tzapu/WiFiManager 41 | Moves the ESP8266 into AP mode and spins up a DNS and WebServer, IP 192.168.4.1 42 | Scans the available AP, asks the password for the wished AP and tries to connect to it 43 | Custom parameters: 44 | - MQTT username 45 | - MQTT password 46 | How-to: 47 | - Define #WIFI_MANAGER, or 48 | - Set manually the variables, lines 72-75 49 | */ 50 | #define WIFI_MANAGER 51 | 52 | #ifdef WIFI_MANAGER 53 | #include 54 | #include 55 | #include 56 | #include 57 | #include 58 | 59 | // Wifi AP: SSID: chip ID, passowrd: WIFI_PASSWORD 60 | const char WIFI_PASSWORD[] = "password"; 61 | char MQTT_USERNAME[10] = {0}; 62 | char MQTT_PASSWORD[10] = {0}; 63 | 64 | // flag for saving data 65 | bool m_shouldSaveConfig = false; 66 | 67 | void saveConfigCallback () { 68 | Serial.println(F("INFO: Should save config")); 69 | m_shouldSaveConfig = true; 70 | } 71 | #else 72 | const PROGMEM char* WIFI_SSID = "[Redacted]"; 73 | const PROGMEM char* WIFI_PASSWORD = "[Redacted]"; 74 | const PROGMEM char* MQTT_USERNAME = "[Redacted]"; 75 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 76 | #endif 77 | 78 | /* 79 | DNS-SD - http://www.dns-sd.org 80 | Soft: Avahi (Linux) or Bonjour (OS X/Windows) 81 | Doc: http://linux.die.net/man/5/avahi.service 82 | Create a service on your machine, which hosts the MQTT broker 83 | On Linux: 84 | - sudo apt-get install avahi-deamon (installed by default) 85 | - sudo nano /etc/avahi/services/mqtt.service 86 | - Copy/paste the following lines: 87 | 88 | 89 | 90 | %h 91 | 92 | _mqtt._tcp 93 | 1883 94 | 95 | 96 | - sudo service avahi-daemon restart 97 | How-to: 98 | - Define #MDNS_SD, or 99 | - Set manually the variables, lines 106-107 100 | */ 101 | #define MDNS_SD 102 | 103 | #ifdef MDNS_SD 104 | #include 105 | #else 106 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 107 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 108 | #endif 109 | 110 | /* 111 | OTA 112 | Password: "1234" (line 341) 113 | */ 114 | 115 | #define OTA 116 | #ifdef OTA 117 | #include 118 | #include 119 | #include 120 | #endif 121 | 122 | // MQTT 123 | #define MQTT_VERSION MQTT_VERSION_3_1_1 124 | char MQTT_CLIENT_ID[6] = {0}; 125 | 126 | // topics: status: /light 127 | // command: /light/switch 128 | char MQTT_LIGHT_STATUS_TOPIC[13] = {0}; 129 | char MQTT_LIGHT_COMMAND_TOPIC[20] = {0}; 130 | 131 | // default payload 132 | const char* LIGHT_ON = "ON"; 133 | const char* LIGHT_OFF = "OFF"; 134 | 135 | // light is turned off by default 136 | boolean m_light_state = false; 137 | 138 | WiFiClient wifiClient; 139 | PubSubClient client(wifiClient); 140 | 141 | // function called to publish the state of the light (on/off) 142 | void publishLightState() { 143 | if (m_light_state) { 144 | client.publish(MQTT_LIGHT_STATUS_TOPIC, LIGHT_ON, true); 145 | } else { 146 | client.publish(MQTT_LIGHT_STATUS_TOPIC, LIGHT_OFF, true); 147 | } 148 | } 149 | 150 | // function called to turn on/off the light 151 | void setLightState() { 152 | if (m_light_state) { 153 | digitalWrite(BUILTIN_LED, LOW); 154 | Serial.println(F("INFO: Light switched on...")); 155 | } else { 156 | digitalWrite(BUILTIN_LED, HIGH); 157 | Serial.println(F("INFO: Light switched off...")); 158 | } 159 | } 160 | 161 | // function called when a MQTT message arrived 162 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 163 | // concat the payload into a string 164 | String payload; 165 | for (uint8_t i = 0; i < p_length; i++) { 166 | payload.concat((char)p_payload[i]); 167 | } 168 | 169 | // handle message topic 170 | if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) { 171 | // test if the payload is equal to "ON" or "OFF" 172 | if (payload.equals(String(LIGHT_ON))) { 173 | if (m_light_state != true) { 174 | m_light_state = true; 175 | setLightState(); 176 | publishLightState(); 177 | } 178 | } else if (payload.equals(String(LIGHT_OFF))) { 179 | if (m_light_state != false) { 180 | m_light_state = false; 181 | setLightState(); 182 | publishLightState(); 183 | } 184 | } 185 | } 186 | } 187 | 188 | void reconnect() { 189 | while (!client.connected()) { 190 | if (client.connect(MQTT_CLIENT_ID, MQTT_USERNAME, MQTT_PASSWORD)) { 191 | Serial.println(F("INFO: Successfully connected to the MQTT broker")); 192 | publishLightState(); 193 | client.subscribe(MQTT_LIGHT_COMMAND_TOPIC); 194 | } else { 195 | Serial.print(F("ERROR: Failed to connect to the MQTT broker")); 196 | delay(5000); 197 | } 198 | } 199 | } 200 | 201 | 202 | void setup() { 203 | Serial.begin(115200); 204 | 205 | // init the built-in led 206 | pinMode(BUILTIN_LED, OUTPUT); 207 | setLightState(); 208 | 209 | // get the chip ID and concat this ID with the MQTT topics 210 | sprintf(MQTT_CLIENT_ID, "%06X", ESP.getChipId()); 211 | sprintf(MQTT_LIGHT_STATUS_TOPIC, "%s%s", MQTT_CLIENT_ID, "/light"); 212 | sprintf(MQTT_LIGHT_COMMAND_TOPIC, "%s%s", MQTT_CLIENT_ID, "/light/switch"); 213 | 214 | Serial.print(F("MQTT id:\t\t ")); 215 | Serial.println(MQTT_CLIENT_ID); 216 | 217 | Serial.print(F("MQTT status topic:\t ")); 218 | Serial.println(MQTT_LIGHT_STATUS_TOPIC); 219 | 220 | Serial.print(F("MQTT command topic:\t ")); 221 | Serial.println(MQTT_LIGHT_COMMAND_TOPIC); 222 | 223 | #ifdef WIFI_MANAGER 224 | // clean FS, for testing 225 | SPIFFS.format(); 226 | 227 | // read configuration from FS json 228 | Serial.println(F("INFO: mounting FS...")); 229 | 230 | if (SPIFFS.begin()) { 231 | Serial.println(F("INFO: mounted file system")); 232 | if (SPIFFS.exists("/config.json")) { 233 | Serial.println(F("INFO: reading config file")); 234 | File configFile = SPIFFS.open("/config.json", "r"); 235 | if (configFile) { 236 | Serial.println(F("INFO: opened config file")); 237 | size_t size = configFile.size(); 238 | // Allocate a buffer to store contents of the file. 239 | std::unique_ptr buf(new char[size]); 240 | 241 | configFile.readBytes(buf.get(), size); 242 | DynamicJsonBuffer jsonBuffer; 243 | JsonObject& json = jsonBuffer.parseObject(buf.get()); 244 | json.printTo(Serial); 245 | if (json.success()) { 246 | Serial.println(F("\nINFO: parsed json")); 247 | strcpy(MQTT_USERNAME, json["mqtt_username"]); 248 | strcpy(MQTT_PASSWORD, json["mqtt_password"]); 249 | } else { 250 | Serial.println(F("ERROR: failed to load json config")); 251 | } 252 | } 253 | } 254 | } else { 255 | Serial.println(F("ERROR: failed to mount FS")); 256 | } 257 | 258 | WiFiManagerParameter custom_mqtt_username("mqtt_username", "MQTT username", MQTT_USERNAME, 15); 259 | WiFiManagerParameter custom_mqtt_password("mqtt_password", "MQTT password", MQTT_PASSWORD, 15, "type=\"password\""); 260 | 261 | // WiFiManager, local intialization 262 | WiFiManager wifiManager; 263 | 264 | // set config save notify callback 265 | wifiManager.setSaveConfigCallback(saveConfigCallback); 266 | 267 | // add all the parameters 268 | wifiManager.addParameter(&custom_mqtt_username); 269 | wifiManager.addParameter(&custom_mqtt_password); 270 | 271 | // reset settings, for testing 272 | wifiManager.resetSettings(); 273 | 274 | // disable the debug output 275 | wifiManager.setDebugOutput(false); 276 | 277 | // fetches ssid and pass and tries to connect 278 | // if it does not connect it starts an access point with the specified name 279 | if (!wifiManager.autoConnect(MQTT_CLIENT_ID, WIFI_PASSWORD)) { 280 | Serial.println(F("Error: Failed to connect and hit timeout")); 281 | delay(3000); 282 | ESP.reset(); 283 | delay(5000); 284 | } 285 | 286 | // if you get here you have connected to the WiFi 287 | Serial.println(F("INFO: Successfully connected to the Wifi AP")); 288 | 289 | // read updated parameters 290 | strcpy(MQTT_USERNAME, custom_mqtt_username.getValue()); 291 | strcpy(MQTT_PASSWORD, custom_mqtt_password.getValue()); 292 | 293 | // save the custom parameters to FS 294 | if (m_shouldSaveConfig) { 295 | Serial.println(F("INFO: saving config")); 296 | DynamicJsonBuffer jsonBuffer; 297 | JsonObject& json = jsonBuffer.createObject(); 298 | json["mqtt_username"] = MQTT_USERNAME; 299 | json["mqtt_password"] = MQTT_PASSWORD; 300 | 301 | File configFile = SPIFFS.open("/config.json", "w"); 302 | if (!configFile) { 303 | Serial.println(F("ERROR: failed to open config file for writing")); 304 | } 305 | json.printTo(Serial); 306 | json.printTo(configFile); 307 | Serial.println(); 308 | configFile.close(); 309 | } 310 | 311 | Serial.print(F("INFO: MQTT username: ")); 312 | Serial.println(MQTT_USERNAME); 313 | 314 | Serial.print(F("INFO: MQTT password: ")); 315 | Serial.println(MQTT_PASSWORD); 316 | 317 | Serial.print(F("INFO: Local IP address: ")); 318 | Serial.println(WiFi.localIP()); 319 | #else 320 | WiFi.hostname(MQTT_CLIENT_ID); 321 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 322 | while (WiFi.status() != WL_CONNECTED) { 323 | delay(250); 324 | } 325 | Serial.println(F("INFO: Successfully connected to the Wifi AP")); 326 | Serial.print(F("INFO: Local IP address: ")); 327 | Serial.println(WiFi.localIP()); 328 | #endif 329 | 330 | delay(500); 331 | 332 | #ifdef OTA 333 | // set port to 8266 334 | //ArduinoOTA.setPort(8266); 335 | 336 | // set hostname 337 | sprintf(MQTT_CLIENT_ID, "%06X", ESP.getChipId()); 338 | ArduinoOTA.setHostname(MQTT_CLIENT_ID); 339 | 340 | // set a password 341 | ArduinoOTA.setPassword((const char *)"1234"); 342 | 343 | ArduinoOTA.onStart([]() { 344 | Serial.println(F("INFO: Start OTA")); 345 | }); 346 | ArduinoOTA.onEnd([]() { 347 | Serial.println(F("INFO: End OTA")); 348 | ESP.reset(); 349 | }); 350 | ArduinoOTA.onProgress([](unsigned int progress, unsigned int total) { 351 | Serial.printf("INFO: Progress: %u%%\r", (progress / (total / 100))); 352 | }); 353 | ArduinoOTA.onError([](ota_error_t error) { 354 | Serial.printf("Error[%u]: ", error); 355 | if (error == OTA_AUTH_ERROR) Serial.println(F("ERROR: OTA auth Failed")); 356 | else if (error == OTA_BEGIN_ERROR) Serial.println(F("ERROR: OTA begin Failed")); 357 | else if (error == OTA_CONNECT_ERROR) Serial.println(F("ERROR: OTA connect Failed")); 358 | else if (error == OTA_RECEIVE_ERROR) Serial.println(F("ERROR: OTA receive Failed")); 359 | else if (error == OTA_END_ERROR) Serial.println(F("ERROR: OTA end Failed")); 360 | }); 361 | ArduinoOTA.begin(); 362 | #endif 363 | 364 | delay(500); 365 | 366 | #ifdef MDNS_SD 367 | if (!MDNS.begin(MQTT_CLIENT_ID)) { 368 | Serial.println(F("ERROR: Setting up MDNS responder!")); 369 | } 370 | Serial.println(F("INFO: mDNS responder started")); 371 | Serial.println(F("INFO: Sending mDNS query")); 372 | int n = MDNS.queryService("mqtt", "tcp"); // Send out query for the MQTT service 373 | Serial.println(F("INFO: mDNS query done")); 374 | if (n == 0) { 375 | Serial.println(F("ERROR: No services found")); 376 | } else if (n > 1) { 377 | Serial.println(F("ERROR: Multiple services found, remove the unnecessary mDNS services")); 378 | } else { 379 | Serial.print(F("INFO: MQTT broker IP address: ")); 380 | Serial.print(MDNS.IP(0)); 381 | Serial.print(F(":")); 382 | Serial.println(MDNS.port(0)); 383 | client.setServer(MDNS.IP(0), int(MDNS.port(0))); 384 | } 385 | #else 386 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 387 | #endif 388 | 389 | client.setCallback(callback); 390 | } 391 | 392 | void loop() { 393 | // put your main code here, to run repeatedly 394 | 395 | // MQTT 396 | if (!client.connected()) { 397 | reconnect(); 398 | } 399 | client.loop(); 400 | 401 | ArduinoOTA.handle(); 402 | } 403 | -------------------------------------------------------------------------------- /ha_mqtt_light_with_brightness/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Light with brightness support - Home Assistant 2 | A simple example to control a led connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | light: 8 | - platform: mqtt 9 | name: 'Office light' 10 | state_topic: 'office/light' 11 | command_topic: 'office/light/switch' 12 | brightness_state_topic: 'office/light/brightness' 13 | brightness_command_topic: 'office/light/brightness/set' 14 | optimistic: false 15 | ``` 16 | 17 | ## Schematic 18 | - GND - Resistor 220 Ohms - LED leg 1 19 | - D1/GPIO5 - LED leg 2 (longuest one) 20 | 21 | ![Schematic](Schematic.png) 22 | -------------------------------------------------------------------------------- /ha_mqtt_light_with_brightness/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_light_with_brightness/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_light_with_brightness/ha_mqtt_light_with_brightness.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Light (with brightness) for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/light.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | 9 | Schematic : 10 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_rgb_light/Schematic.png 11 | - GND - Resistor 220 Ohms - LED leg 1 12 | - D1/GPIO5 - LED leg 2 (longuest one) 13 | 14 | Configuration (HA) : 15 | light: 16 | platform: mqtt 17 | name: 'Office light' 18 | state_topic: 'office/light' 19 | command_topic: 'office/light/switch' 20 | brightness_state_topic: 'office/light/brightness' 21 | brightness_command_topic: 'office/light/brightness/set' 22 | optimistic: false 23 | 24 | Samuel M. - v1.0 - 08.2016 25 | If you like this example, please add a star! Thank you! 26 | https://github.com/mertenats/open-home-automation 27 | */ 28 | 29 | #include 30 | #include 31 | 32 | #define MQTT_VERSION MQTT_VERSION_3_1_1 33 | 34 | // Wifi: SSID and password 35 | const char* WIFI_SSID = "[Redacted]"; 36 | const char* WIFI_PASSWORD = "[Redacted]"; 37 | 38 | // MQTT: ID, server IP, port, username and password 39 | const PROGMEM char* MQTT_CLIENT_ID = "office_light"; 40 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 41 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 42 | const PROGMEM char* MQTT_USER = "[Redacted]"; 43 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 44 | 45 | // MQTT: topics 46 | // state 47 | const PROGMEM char* MQTT_LIGHT_STATE_TOPIC = "office/light"; 48 | const PROGMEM char* MQTT_LIGHT_COMMAND_TOPIC = "office/light/switch"; 49 | 50 | // brightness 51 | const PROGMEM char* MQTT_LIGHT_BRIGHTNESS_STATE_TOPIC = "office/light/brightness"; 52 | const PROGMEM char* MQTT_LIGHT_BRIGHTNESS_COMMAND_TOPIC = "office/light/brightness/set"; 53 | 54 | // payloads by default (on/off) 55 | const PROGMEM char* LIGHT_ON = "ON"; 56 | const PROGMEM char* LIGHT_OFF = "OFF"; 57 | 58 | // variables used to store the statea and the brightness of the light 59 | boolean m_light_state = false; 60 | uint8_t m_light_brightness = 255; 61 | 62 | // pin used for the led (PWM) 63 | const PROGMEM uint8_t LIGHT_PIN = 4; 64 | 65 | // buffer used to send/receive data with MQTT 66 | const uint8_t MSG_BUFFER_SIZE = 20; 67 | char m_msg_buffer[MSG_BUFFER_SIZE]; 68 | 69 | WiFiClient wifiClient; 70 | PubSubClient client(wifiClient); 71 | 72 | // function called to adapt the brightness and the state of the led 73 | void setLightState() { 74 | if (m_light_state) { 75 | analogWrite(LIGHT_PIN, m_light_brightness); 76 | Serial.print("INFO: Brightness: "); 77 | Serial.println(m_light_brightness); 78 | } else { 79 | analogWrite(LIGHT_PIN, 0); 80 | Serial.println("INFO: Turn light off"); 81 | } 82 | } 83 | 84 | // function called to publish the state of the led (on/off) 85 | void publishLightState() { 86 | if (m_light_state) { 87 | client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true); 88 | } else { 89 | client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true); 90 | } 91 | } 92 | 93 | // function called to publish the brightness of the led 94 | void publishLightBrightness() { 95 | snprintf(m_msg_buffer, MSG_BUFFER_SIZE, "%d", m_light_brightness); 96 | client.publish(MQTT_LIGHT_BRIGHTNESS_STATE_TOPIC, m_msg_buffer, true); 97 | } 98 | 99 | 100 | // function called when a MQTT message arrived 101 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 102 | // concat the payload into a string 103 | String payload; 104 | for (uint8_t i = 0; i < p_length; i++) { 105 | payload.concat((char)p_payload[i]); 106 | } 107 | // handle message topic 108 | if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) { 109 | // test if the payload is equal to "ON" or "OFF" 110 | if (payload.equals(String(LIGHT_ON))) { 111 | if (m_light_state != true) { 112 | m_light_state = true; 113 | setLightState(); 114 | publishLightState(); 115 | } 116 | } else if (payload.equals(String(LIGHT_OFF))) { 117 | if (m_light_state != false) { 118 | m_light_state = false; 119 | setLightState(); 120 | publishLightState(); 121 | } 122 | } 123 | } else if (String(MQTT_LIGHT_BRIGHTNESS_COMMAND_TOPIC).equals(p_topic)) { 124 | uint8_t brightness = payload.toInt(); 125 | if (brightness < 0 || brightness > 255) { 126 | // do nothing... 127 | return; 128 | } else { 129 | m_light_brightness = brightness; 130 | setLightState(); 131 | publishLightBrightness(); 132 | } 133 | } 134 | } 135 | 136 | void reconnect() { 137 | // Loop until we're reconnected 138 | while (!client.connected()) { 139 | Serial.println("INFO: Attempting MQTT connection..."); 140 | // Attempt to connect 141 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 142 | Serial.println("\nINFO: connected"); 143 | 144 | // Once connected, publish an announcement... 145 | // publish the initial values 146 | publishLightState(); 147 | publishLightBrightness(); 148 | 149 | // ... and resubscribe 150 | client.subscribe(MQTT_LIGHT_COMMAND_TOPIC); 151 | client.subscribe(MQTT_LIGHT_BRIGHTNESS_COMMAND_TOPIC); 152 | } else { 153 | Serial.print("ERROR: failed, rc="); 154 | Serial.print(client.state()); 155 | Serial.println("DEBUG: try again in 5 seconds"); 156 | // Wait 5 seconds before retrying 157 | delay(5000); 158 | } 159 | } 160 | } 161 | 162 | void setup() { 163 | // init the serial 164 | Serial.begin(115200); 165 | 166 | // init the led 167 | pinMode(LIGHT_PIN, OUTPUT); 168 | analogWriteRange(255); 169 | setLightState(); 170 | 171 | // init the WiFi connection 172 | Serial.println(); 173 | Serial.println(); 174 | Serial.print("INFO: Connecting to "); 175 | WiFi.mode(WIFI_STA); 176 | Serial.println(WIFI_SSID); 177 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 178 | 179 | while (WiFi.status() != WL_CONNECTED) { 180 | delay(500); 181 | Serial.print("."); 182 | } 183 | 184 | Serial.println(""); 185 | Serial.println("INFO: WiFi connected"); 186 | Serial.print("INFO: IP address: "); 187 | Serial.println(WiFi.localIP()); 188 | 189 | // init the MQTT connection 190 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 191 | client.setCallback(callback); 192 | } 193 | 194 | void loop() { 195 | if (!client.connected()) { 196 | reconnect(); 197 | } 198 | client.loop(); 199 | } 200 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/Configuration/example.binary_sensor.yaml: -------------------------------------------------------------------------------- 1 | # Example configuration.yaml entry 2 | binary_sensor: 3 | - platform: mqtt 4 | name: 'Motion' 5 | state_topic: '/sensor/motion' 6 | availability_topic: '/status' 7 | payload_available: 'online' 8 | payload_not_available: 'offline' 9 | device_class: motion 10 | - platform: mqtt 11 | name: 'Door' 12 | state_topic: '/sensor/door' 13 | availability_topic: '/status' 14 | payload_available: 'online' 15 | payload_not_available: 'offline' 16 | device_class: opening 17 | - platform: mqtt 18 | name: 'Button' 19 | state_topic: '/sensor/button' 20 | availability_topic: '/status' 21 | payload_available: 'online' 22 | payload_not_available: 'offline' 23 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/Configuration/example.group.yaml: -------------------------------------------------------------------------------- 1 | group: 2 | multisensor: 3 | name: 'Multisensor' 4 | entities: 5 | - sensor.temperature 6 | - sensor.humidity 7 | - sensor.luminosity 8 | - binary_sensor.motion 9 | - binary_sensor.door 10 | - binary_sensor.button 11 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/Configuration/example.sensor.yaml: -------------------------------------------------------------------------------- 1 | # Example configuration.yml entry 2 | sensor: 3 | - platform: mqtt 4 | name: 'Temperature' 5 | state_topic: '/sensor/temperature' 6 | unit_of_measurement: '°C' 7 | availability_topic: '/status' 8 | payload_available: 'online' 9 | payload_not_available: 'offline' 10 | - platform: mqtt 11 | name: 'Humidity' 12 | state_topic: '/sensor/humidity' 13 | unit_of_measurement: '%' 14 | availability_topic: '/status' 15 | payload_available: 'online' 16 | payload_not_available: 'offline' 17 | - platform: mqtt 18 | name: 'Luminosity' 19 | state_topic: '/sensor/lux' 20 | unit_of_measurement: 'lux' 21 | availability_topic: '/status' 22 | payload_available: 'online' 23 | payload_not_available: 'offline' 24 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/Images/Schematic.jpg: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_multisensor/Images/Schematic.jpg -------------------------------------------------------------------------------- /ha_mqtt_multisensor/LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2017 Samuel Mertenat 4 | 5 | Permission is hereby granted, free of charge, to any person obtaining a copy 6 | of this software and associated documentation files (the "Software"), to deal 7 | in the Software without restriction, including without limitation the rights 8 | to use, copy, modify, merge, publish, distribute, sublicense, and/or sell 9 | copies of the Software, and to permit persons to whom the Software is 10 | furnished to do so, subject to the following conditions: 11 | 12 | The above copyright notice and this permission notice shall be included in all 13 | copies or substantial portions of the Software. 14 | 15 | THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 16 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 17 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 18 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 19 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 20 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 21 | SOFTWARE. 22 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/MultiSensor.cpp: -------------------------------------------------------------------------------- 1 | #include "Arduino.h" 2 | #include "MultiSensor.h" 3 | 4 | #if defined(DHT_SENSOR) 5 | // https://github.com/adafruit/Adafruit_Sensor 6 | // https://github.com/adafruit/DHT-sensor-library 7 | #include "DHT.h" 8 | #define DHTTYPE DHT22 9 | DHT dht(DHT_PIN, DHTTYPE); 10 | #endif 11 | 12 | #if defined(SHT_SENSOR) 13 | // https://github.com/Sensirion/arduino-sht 14 | #include 15 | #include "SHTSensor.h" 16 | SHTSensor sht; 17 | #endif 18 | 19 | volatile uint8_t evt = NO_SENSOR_EVT; 20 | 21 | /////////////////////////////////////////////////////////////////////////// 22 | // ISRs 23 | /////////////////////////////////////////////////////////////////////////// 24 | 25 | #if defined(DOOR_SENSOR) 26 | void doorSensorISR(void) { 27 | evt = DOOR_SENSOR_EVT; 28 | } 29 | #endif 30 | 31 | #if defined(MOTION_SENSOR) 32 | void motionSensorISR(void) { 33 | evt = MOTION_SENSOR_EVT; 34 | } 35 | #endif 36 | 37 | #if defined(BUTTON_SENSOR) 38 | void buttonSensorISR(void) { 39 | static unsigned long lastButtonSensorInterrupt = 0; 40 | unsigned long currentButtonSensorInterrupt = millis(); 41 | if (currentButtonSensorInterrupt - lastButtonSensorInterrupt > 500) 42 | evt = BUTTON_SENSOR_EVT; 43 | lastButtonSensorInterrupt = currentButtonSensorInterrupt; 44 | } 45 | #endif 46 | 47 | 48 | /////////////////////////////////////////////////////////////////////////// 49 | // Constructor, init(), handleEvt() & loop() 50 | /////////////////////////////////////////////////////////////////////////// 51 | MultiSensor::MultiSensor(void) {} 52 | 53 | void MultiSensor::init(void) { 54 | #if defined(DOOR_SENSOR) 55 | pinMode(DOOR_SENSOR, INPUT_PULLUP); 56 | attachInterrupt(digitalPinToInterrupt(DOOR_SENSOR), doorSensorISR, CHANGE); 57 | this->_doorState = this->_readDoorState(); 58 | #endif 59 | #if defined(MOTION_SENSOR) 60 | pinMode(MOTION_SENSOR_PIN, INPUT_PULLUP); 61 | attachInterrupt(digitalPinToInterrupt(MOTION_SENSOR_PIN), motionSensorISR, CHANGE); 62 | this->_motionState = digitalRead(MOTION_SENSOR_PIN); 63 | #endif 64 | #if defined(LDR_SENSOR) 65 | pinMode(LDR_PIN, INPUT); 66 | this->_ldrValue = analogRead(LDR_PIN); 67 | #endif 68 | #if defined(DHT_SENSOR) 69 | dht.begin(); 70 | delay(2000); 71 | this->_readDHTTemperature(); 72 | this->_readDHTHumidity(); 73 | #endif 74 | #if defined(SHT_SENSOR) 75 | Wire.begin(SHT_SCL_PIN, SHT_SDA_PIN); 76 | sht.init(); 77 | sht.setAccuracy(SHTSensor::SHT_ACCURACY_MEDIUM); 78 | this->_readSHTTemperature(); 79 | this->_readSHTHumidity(); 80 | #endif 81 | #if defined(BUTTON_SENSOR) 82 | pinMode(BUTTON_SENSOR, INPUT); 83 | attachInterrupt(digitalPinToInterrupt(BUTTON_SENSOR), buttonSensorISR, CHANGE); 84 | #endif 85 | } 86 | 87 | void MultiSensor::handleEvt(void) { 88 | switch(evt) { 89 | case NO_SENSOR_EVT: 90 | break; 91 | #if defined(DOOR_SENSOR) 92 | case DOOR_SENSOR_EVT: 93 | if (this->_readDoorState() != this->_doorState) { 94 | this->_doorState = !this->_doorState; 95 | this->_callback(DOOR_SENSOR_EVT); 96 | } 97 | evt = NO_SENSOR_EVT; 98 | break; 99 | #endif 100 | #if defined(MOTION_SENSOR) 101 | case MOTION_SENSOR_EVT: 102 | if (digitalRead(MOTION_SENSOR_PIN) != this->_motionState) { 103 | this->_motionState = !this->_motionState; 104 | this->_callback(MOTION_SENSOR_EVT); 105 | } 106 | evt = NO_SENSOR_EVT; 107 | break; 108 | #endif 109 | #if defined(BUTTON_SENSOR) 110 | case BUTTON_SENSOR_EVT: 111 | this->_buttonState = !this->_buttonState; 112 | this->_callback(BUTTON_SENSOR_EVT); 113 | evt = NO_SENSOR_EVT; 114 | break; 115 | #endif 116 | #if defined(LDR_SENSOR) 117 | case LDR_SENSOR_EVT: 118 | this->_callback(LDR_SENSOR_EVT); 119 | evt = NO_SENSOR_EVT; 120 | break; 121 | #endif 122 | #if defined(DHT_SENSOR) 123 | case DHT_TEMPERATURE_SENSOR_EVT: 124 | this->_callback(DHT_TEMPERATURE_SENSOR_EVT); 125 | evt = NO_SENSOR_EVT; 126 | break; 127 | case DHT_HUMIDITY_SENSOR_EVT: 128 | this->_callback(DHT_HUMIDITY_SENSOR_EVT); 129 | evt = NO_SENSOR_EVT; 130 | break; 131 | #endif 132 | #if defined(SHT_SENSOR) 133 | case SHT_TEMPERATURE_SENSOR_EVT: 134 | this->_callback(SHT_TEMPERATURE_SENSOR_EVT); 135 | evt = NO_SENSOR_EVT; 136 | break; 137 | case SHT_HUMIDITY_SENSOR_EVT: 138 | this->_callback(SHT_HUMIDITY_SENSOR_EVT); 139 | evt = NO_SENSOR_EVT; 140 | break; 141 | #endif 142 | } 143 | } 144 | 145 | void MultiSensor::loop(void) { 146 | this->handleEvt(); 147 | 148 | #if defined(LDR_SENSOR) 149 | static unsigned long lastLdrSensorMeasure = 0; 150 | if (lastLdrSensorMeasure + LDR_MEASURE_INTERVAL <= millis()) { 151 | lastLdrSensorMeasure = millis(); 152 | uint16_t currentLdrValue = analogRead(LDR_PIN); 153 | if (currentLdrValue <= this->_ldrValue - LDR_OFFSET_VALUE || currentLdrValue >= this->_ldrValue + LDR_OFFSET_VALUE) { 154 | this->_ldrValue = currentLdrValue; 155 | evt = LDR_SENSOR_EVT; 156 | return; 157 | } 158 | } 159 | #endif 160 | 161 | #if defined(DHT_SENSOR) 162 | static unsigned long lastDHTTemperatureSensorMeasure = 0; 163 | if (lastDHTTemperatureSensorMeasure + DHT_MEASURE_INTERVAL <= millis()) { 164 | lastDHTTemperatureSensorMeasure = millis(); 165 | float currentDHTTemperature = this->_readDHTTemperature(); 166 | if (currentDHTTemperature <= this->_DHTTemperature - DHT_TEMPERATURE_OFFSET_VALUE || currentDHTTemperature >= this->_DHTTemperature + DHT_TEMPERATURE_OFFSET_VALUE) { 167 | this->_DHTTemperature = currentDHTTemperature; 168 | evt = DHT_TEMPERATURE_SENSOR_EVT; 169 | return; 170 | } 171 | } 172 | 173 | static unsigned long lastDHTHumiditySensorMeasure = 0; 174 | if (lastDHTHumiditySensorMeasure + DHT_MEASURE_INTERVAL <= millis()) { 175 | lastDHTHumiditySensorMeasure = millis(); 176 | float currentDHTHumidity = this->_readDHTHumidity(); 177 | if (currentDHTHumidity <= this->_DHTHumidity - DHT_HUMIDITY_OFFSET_VALUE || currentDHTHumidity >= this->_DHTHumidity + DHT_HUMIDITY_OFFSET_VALUE) { 178 | this->_DHTHumidity = currentDHTHumidity; 179 | evt = DHT_HUMIDITY_SENSOR_EVT; 180 | return; 181 | } 182 | } 183 | #endif 184 | #if defined(SHT_SENSOR) 185 | static unsigned long lastSHTTemperatureSensorMeasure = 0; 186 | if (lastSHTTemperatureSensorMeasure + SHT_MEASURE_INTERVAL <= millis()) { 187 | lastSHTTemperatureSensorMeasure = millis(); 188 | float currentSHTTemperature = this->_readSHTTemperature(); 189 | if (currentSHTTemperature <= this->_SHTTemperature - SHT_TEMPERATURE_OFFSET_VALUE || currentSHTTemperature >= this->_SHTTemperature + SHT_TEMPERATURE_OFFSET_VALUE) { 190 | this->_SHTTemperature = currentSHTTemperature; 191 | evt = SHT_TEMPERATURE_SENSOR_EVT; 192 | return; 193 | } 194 | } 195 | 196 | static unsigned long lastSHTHumiditySensorMeasure = 0; 197 | if (lastSHTHumiditySensorMeasure + SHT_MEASURE_INTERVAL <= millis()) { 198 | lastSHTHumiditySensorMeasure = millis(); 199 | float currentSHTHumidity = this->_readSHTHumidity(); 200 | if (currentSHTHumidity <= this->_SHTHumidity - SHT_HUMIDITY_OFFSET_VALUE || currentSHTHumidity >= this->_SHTHumidity + SHT_HUMIDITY_OFFSET_VALUE) { 201 | this->_SHTHumidity = currentSHTHumidity; 202 | evt = SHT_HUMIDITY_SENSOR_EVT; 203 | return; 204 | } 205 | } 206 | #endif 207 | } 208 | 209 | 210 | /////////////////////////////////////////////////////////////////////////// 211 | // setCallback() 212 | /////////////////////////////////////////////////////////////////////////// 213 | void MultiSensor::setCallback(void (*callback)(uint8_t)) { 214 | this->_callback = callback; 215 | } 216 | 217 | 218 | /////////////////////////////////////////////////////////////////////////// 219 | // Getters 220 | /////////////////////////////////////////////////////////////////////////// 221 | #if defined(DOOR_SENSOR) 222 | bool MultiSensor::_readDoorState(void) { 223 | return digitalRead(DOOR_SENSOR); 224 | } 225 | 226 | bool MultiSensor::getDoorState(void) { 227 | return this->_doorState; 228 | } 229 | #endif 230 | 231 | #if defined(MOTION_SENSOR) 232 | bool MultiSensor::getMotionState(void) { 233 | return this->_motionState; 234 | } 235 | #endif 236 | 237 | #if defined(LDR_SENSOR) 238 | uint16_t MultiSensor::getLux(void) { 239 | // http://forum.arduino.cc/index.php?topic=37555.0 240 | // https://forum.arduino.cc/index.php?topic=185158.0 241 | float volts = this->_ldrValue * REFERENCE_VOLTAGE / ADC_PRECISION; 242 | float amps = volts / LDR_RESISTOR_VALUE; 243 | float lux = amps * 1000000 * 2.0; 244 | return uint16_t(lux); 245 | } 246 | #endif 247 | 248 | 249 | #if defined(DHT_SENSOR) 250 | float MultiSensor::_readDHTTemperature(void) { 251 | float temperature = dht.readTemperature(); 252 | 253 | if (isnan(temperature)) { 254 | return this->_DHTTemperature; 255 | } 256 | return temperature; 257 | } 258 | 259 | float MultiSensor::_readDHTHumidity(void) { 260 | float humidity = dht.readHumidity(); 261 | 262 | if (isnan(humidity)) { 263 | return this->_DHTHumidity; 264 | } 265 | return humidity; 266 | } 267 | 268 | float MultiSensor::getDHTTemperature(void) { 269 | return this->_DHTTemperature; 270 | } 271 | 272 | float MultiSensor::getDHTHumidity(void) { 273 | return this->_DHTHumidity; 274 | } 275 | #endif 276 | 277 | 278 | #if defined(SHT_SENSOR) 279 | float MultiSensor::_readSHTTemperature(void) { 280 | float temperature = sht.getTemperature(); 281 | 282 | if (isnan(temperature)) { 283 | return this->_SHTTemperature; 284 | } 285 | return temperature; 286 | } 287 | 288 | float MultiSensor::_readSHTHumidity(void) { 289 | float humidity = sht.getHumidity(); 290 | 291 | if (isnan(humidity)) { 292 | return this->_SHTHumidity; 293 | } 294 | return humidity; 295 | } 296 | 297 | float MultiSensor::getSHTTemperature(void) { 298 | return this->_SHTTemperature; 299 | } 300 | 301 | float MultiSensor::getSHTHumidity(void) { 302 | return this->_SHTHumidity; 303 | } 304 | #endif 305 | 306 | 307 | #if defined(BUTTON_SENSOR) 308 | bool MultiSensor::getButtonState(void) { 309 | return this->_buttonState; 310 | } 311 | #endif 312 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/MultiSensor.h: -------------------------------------------------------------------------------- 1 | #ifndef MultiSensor_h 2 | #define MultiSensor_h 3 | 4 | #include "Arduino.h" 5 | #include "config.h" 6 | 7 | #define NO_SENSOR_EVT 0 8 | #if defined(DOOR_SENSOR) 9 | #define DOOR_SENSOR_EVT 1 10 | #endif 11 | #if defined(MOTION_SENSOR) 12 | #define MOTION_SENSOR_EVT 2 13 | #endif 14 | #if defined(LDR_SENSOR) 15 | #define LDR_SENSOR_EVT 3 16 | #endif 17 | #if defined(DHT_SENSOR) 18 | #define DHT_TEMPERATURE_SENSOR_EVT 4 19 | #define DHT_HUMIDITY_SENSOR_EVT 5 20 | #endif 21 | #if defined(SHT_SENSOR) 22 | #define SHT_TEMPERATURE_SENSOR_EVT 6 23 | #define SHT_HUMIDITY_SENSOR_EVT 7 24 | #endif 25 | #if defined(BUTTON_SENSOR) 26 | #define BUTTON_SENSOR_EVT 8 27 | #endif 28 | 29 | class MultiSensor { 30 | public: 31 | MultiSensor(void); 32 | void init(void); 33 | void loop(void); 34 | void setCallback(void (*callback)(uint8_t)); 35 | 36 | #if defined(DOOR_SENSOR) 37 | bool getDoorState(void); 38 | #endif 39 | #if defined(MOTION_SENSOR) 40 | bool getMotionState(void); 41 | #endif 42 | #if defined(LDR_SENSOR) 43 | uint16_t getLux(void); 44 | #endif 45 | #if defined(DHT_SENSOR) 46 | float getDHTTemperature(void); 47 | float getDHTHumidity(void); 48 | #endif 49 | #if defined(SHT_SENSOR) 50 | float getSHTTemperature(void); 51 | float getSHTHumidity(void); 52 | #endif 53 | #if defined(BUTTON_SENSOR) 54 | bool getButtonState(void); 55 | #endif 56 | private: 57 | void (*_callback)(uint8_t); 58 | void handleEvt(void); 59 | #if defined(DOOR_SENSOR) 60 | bool _readDoorState(void); 61 | bool _doorState = false; 62 | #endif 63 | #if defined(MOTION_SENSOR) 64 | bool _motionState = false; 65 | #endif 66 | #if defined(LDR_SENSOR) 67 | uint16_t _ldrValue = 0; 68 | #endif 69 | #if defined(DHT_SENSOR) 70 | float _readDHTTemperature(void); 71 | float _readDHTHumidity(void); 72 | float _DHTTemperature = 0; 73 | float _DHTHumidity = 0; 74 | #endif 75 | #if defined(SHT_SENSOR) 76 | float _readSHTTemperature(void); 77 | float _readSHTHumidity(void); 78 | float _SHTTemperature = 0; 79 | float _SHTHumidity = 0; 80 | #endif 81 | #if defined(BUTTON_SENSOR) 82 | bool _buttonState = false; 83 | #endif 84 | }; 85 | #endif 86 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/README.md: -------------------------------------------------------------------------------- 1 | # MQTT - MultiSensor - Home Assistant 2 | A full example describing how to monitor your environment with an ESP8266, the MQTT protocol and Home Assistant. 3 | 4 | ## Features 5 | - Temperature (DHT22, SHT3X) 6 | - Humidity (DHT22, SHT3X) 7 | - Luminosity (Photoresistor, TEMT6000) 8 | - Motion (AM312, RCWL 0516) 9 | - Door/Window state ON/OFF 10 | - Button state ON/OFF 11 | 12 | ## Schematic 13 | ### DHT22 sensor 14 | Temperature and Humidity sensor. Schematic available [here](https://github.com/mertenats/Open-Home-Automation/tree/master/ha_mqtt_sensor_dht22). 15 | 16 | - DHT22 leg 1 - VCC 17 | - DHT22 leg 2 - D2 - Resistor 4.7K Ohms - GND 18 | - DHT22 leg 4 - GND 19 | 20 | ### SHT3X sensor 21 | Temperature and Humidity sensor. 22 | 23 | - SHT3X VCC - VCC 24 | - SHT3X GND - GND 25 | - SHT3X SCL - D2 26 | - SHT3X SDA - D3 27 | 28 | ### Photoresistor 29 | Luminosity sensor. Schematic available [here](https://github.com/mertenats/Open-Home-Automation/tree/master/ha_mqtt_sensor_photocell). 30 | 31 | - Photocell leg 1 - VCC 32 | - Photocell leg 2 - A0 - Resistor 10K Ohms - GND 33 | 34 | ### TEMT6000 35 | Luminosity sensor. 36 | 37 | - TEMT6000 VCC - VCC 38 | - TEMT6000 GND - GND 39 | - TEMT6000 OUT - A0 40 | 41 | ### AM312 sensor 42 | Motion sensor. Schematic available [here](https://github.com/mertenats/Open-Home-Automation/tree/master/ha_mqtt_binary_sensor_pir). 43 | 44 | - PIR leg 1 - VCC 45 | - PIR leg 2 - D7 46 | - PIR leg 3 - GND 47 | 48 | ### RCWL 0516 sensor 49 | Motion sensor. 50 | 51 | - RCWL 0516 3v3 - VCC 52 | - RCWL 0516 GND - GND 53 | - RCWL 0516 OUT - D7 54 | 55 | ### Magnet 56 | Door/Window state sensor. Schematic available [here](https://github.com/mertenats/Open-Home-Automation/tree/master/ha_mqtt_binary_sensor_door). 57 | 58 | - Door sensor leg 1 - D3 59 | - Door sensor leg 2 - GND 60 | 61 | ### Button 62 | Button ON/OFF. Schematic available [here](https://github.com/mertenats/Open-Home-Automation/tree/master/ha_mqtt_switch). 63 | 64 | - Switch leg 1 - VCC 65 | - Switch leg 2 - D1 - Resistor 10K Ohms - GND 66 | 67 | ![Schematic](Images/Schematic.jpg) 68 | 69 | ## Configuration 70 | To configure this sketch, you have to rename the header file `example.config.h` in `config.h`. Then, it is possible to enable/disable sensors in the `HARDWARE SECTION` or edit your Wi-Fi and MQTT credentials in the `SOFTWARE SECTION`. 71 | 72 | ### Sensors 73 | ``` 74 | // Door sensor 75 | #define DOOR_SENSOR D3 76 | 77 | // Motion sensor 78 | #define MOTION_SENSOR D7 79 | 80 | // Photoresistor sensor 81 | #define LDR_SENSOR A0 82 | 83 | // Temperature and humidity sensor (DHT22) 84 | #define DHT_SENSOR D2 85 | 86 | // Button 87 | #define BUTTON_SENSOR D1 88 | ``` 89 | 90 | ### Credentials 91 | ``` 92 | // Wi-Fi credentials 93 | #define WIFI_SSID "" 94 | #define WIFI_PASSWORD "" 95 | 96 | // MQTT 97 | #define MQTT_USERNAME "" 98 | #define MQTT_PASSWORD "" 99 | #define MQTT_SERVER "" 100 | #define MQTT_SERVER_PORT 1883 101 | ``` 102 | 103 | ### Home Assistant 104 | To add the motion sensor, the door/window state sensor and the button to Home Assistant, please edit and add this snippet into your configuration. 105 | 106 | ```yaml 107 | # Example configuration.yaml entry 108 | binary_sensor: 109 | - platform: mqtt 110 | name: 'Motion' 111 | state_topic: '/sensor/motion' 112 | availability_topic: '/status' 113 | payload_available: 'online' 114 | payload_not_available: 'offline' 115 | device_class: motion 116 | - platform: mqtt 117 | name: 'Door' 118 | state_topic: '/sensor/door' 119 | availability_topic: '/status' 120 | payload_available: 'online' 121 | payload_not_available: 'offline' 122 | device_class: opening 123 | - platform: mqtt 124 | name: 'Button' 125 | state_topic: '/sensor/button' 126 | availability_topic: '/status' 127 | payload_available: 'online' 128 | payload_not_available: 'offline' 129 | ``` 130 | 131 | To add the temperature and humidity sensor and the luminosity sensor, please edit and add this snippet into your configuration. 132 | 133 | ```yaml 134 | # Example configuration.yml entry 135 | sensor: 136 | - platform: mqtt 137 | name: 'Temperature' 138 | state_topic: '/sensor/temperature' 139 | unit_of_measurement: '°C' 140 | availability_topic: '/status' 141 | payload_available: 'online' 142 | payload_not_available: 'offline' 143 | - platform: mqtt 144 | name: 'Humidity' 145 | state_topic: '/sensor/humidity' 146 | unit_of_measurement: '%' 147 | availability_topic: '/status' 148 | payload_available: 'online' 149 | payload_not_available: 'offline' 150 | - platform: mqtt 151 | name: 'Luminosity' 152 | state_topic: '/sensor/lux' 153 | unit_of_measurement: 'lux' 154 | availability_topic: '/status' 155 | payload_available: 'online' 156 | payload_not_available: 'offline' 157 | ``` 158 | 159 | ## Licence 160 | > THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 161 | IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 162 | FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 163 | AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 164 | LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, 165 | OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE 166 | SOFTWARE. 167 | 168 | *If you like the content of this repo, please add a star! Thank you!* 169 | -------------------------------------------------------------------------------- /ha_mqtt_multisensor/example.config .h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////// 2 | // CONFIGURATION - HARDWARE 3 | /////////////////////////////////////////////////////////////////////////// 4 | // Door sensor 5 | #define DOOR_SENSOR D3 6 | #if defined(DOOR_SENSOR) 7 | #define DOOR_SENSOR_NAME "door" // used for the MQTT topic 8 | #endif 9 | 10 | // Motion sensor 11 | // - AM312 12 | // - RCWL 0516 13 | #define MOTION_SENSOR 14 | #if defined(MOTION_SENSOR) 15 | #define MOTION_SENSOR_NAME "motion" 16 | #define MOTION_SENSOR_PIN D7 17 | #endif 18 | 19 | // Ambient light sensor 20 | // - Photoresistor 21 | // - TEMT6000 sensor 22 | // Do not add a 10 kOhms resistor if you're using the TEMT6000 23 | // sensor (already present on the PCB) 24 | //#define LDR_SENSOR 25 | #define LDR_SENSOR 26 | #if defined(LDR_SENSOR) 27 | #define LDR_SENSOR_NAME "lux" 28 | #define LDR_OFFSET_VALUE 25 29 | #define LDR_MEASURE_INTERVAL 15000 // [ms] 30 | #define REFERENCE_VOLTAGE 3.3 // [v] 31 | #define ADC_PRECISION 1024.0 // 10 bits 32 | #define LDR_RESISTOR_VALUE 10000.0 // [Ohms] 33 | #define LDR_PIN A0 34 | #endif 35 | 36 | // Temperature and humidity sensor (DHT22) 37 | //#define DHT_SENSOR 38 | #if defined(DHT_SENSOR) 39 | #define DHT_TEMPERATURE_SENSOR_NAME "temperature" 40 | #define DHT_HUMIDITY_SENSOR_NAME "humidity" 41 | #define DHT_TEMPERATURE_OFFSET_VALUE 0.2 // [°C] 42 | #define DHT_HUMIDITY_OFFSET_VALUE 0.5 // [%] 43 | #define DHT_MEASURE_INTERVAL 30000 // [ms] 44 | #define DHT_PIN D2 45 | #endif 46 | 47 | // Temperature and humidity sensor (Sensirion SHT3X) 48 | #define SHT_SENSOR 49 | #if defined(SHT_SENSOR) 50 | #define SHT_TEMPERATURE_SENSOR_NAME "temperature" 51 | #define SHT_HUMIDITY_SENSOR_NAME "humidity" 52 | #define SHT_TEMPERATURE_OFFSET_VALUE 0.2 // [°C] 53 | #define SHT_HUMIDITY_OFFSET_VALUE 0.5 // [%] 54 | #define SHT_MEASURE_INTERVAL 30000 // [ms] 55 | #define SHT_SDA_PIN D3 56 | #define SHT_SCL_PIN D2 57 | #endif 58 | 59 | // Button 60 | #define BUTTON_SENSOR D1 61 | #if defined(BUTTON_SENSOR) 62 | #define BUTTON_SENSOR_NAME "button" 63 | #endif 64 | 65 | 66 | /////////////////////////////////////////////////////////////////////////// 67 | // CONFIGURATION - SOFTWARE 68 | /////////////////////////////////////////////////////////////////////////// 69 | // Debug output 70 | #define DEBUG_SERIAL 71 | 72 | // Wi-Fi credentials 73 | #define WIFI_SSID "" 74 | #define WIFI_PASSWORD "" 75 | 76 | // Over-the-Air update 77 | #define OTA 78 | #define OTA_HOSTNAME "MultiSensor" // hostname esp8266-[ChipID] by default 79 | //#define OTA_PASSWORD "password" // no password by default 80 | //#define OTA_PORT 8266 // port 8266 by default 81 | 82 | // MQTT 83 | #define MQTT_USERNAME "" 84 | #define MQTT_PASSWORD "" 85 | #define MQTT_SERVER "" 86 | #define MQTT_SERVER_PORT 1883 87 | 88 | #define MQTT_CONNECTION_TIMEOUT 5000 // [ms] 89 | 90 | #define MQTT_AVAILABILITY_TOPIC_TEMPLATE "%s/status" // MQTT availability: online/offline 91 | #define MQTT_SENSOR_TOPIC_TEMPLATE "%s/sensor/%s" 92 | 93 | #define MQTT_PAYLOAD_ON "ON" 94 | #define MQTT_PAYLOAD_OFF "OFF" 95 | -------------------------------------------------------------------------------- /ha_mqtt_rgb_light/README.md: -------------------------------------------------------------------------------- 1 | # MQTT RGB Light - Home Assistant 2 | A simple example to control a RGB led connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | light: 8 | platform: mqtt 9 | name: 'Office RGB light' 10 | state_topic: 'office/rgb1/light/status' 11 | command_topic: 'office/rgb1/light/switch' 12 | brightness_state_topic: 'office/rgb1/brightness/status' 13 | brightness_command_topic: 'office/rgb1/brightness/set' 14 | rgb_state_topic: 'office/rgb1/rgb/status' 15 | rgb_command_topic: 'office/rgb1/rgb/set' 16 | brightness_scale: 100 17 | optimistic: false 18 | ``` 19 | 20 | ## Schematic 21 | - LED leg 1 - Resistor 270 Ohms - D1/GPIO5 22 | - LED leg 2 (longuest leg) - GND 23 | - LED leg 3 - Resistor 270 Ohms - D2/GPIO4 24 | - LED leg 4 - Resistor 270 Ohms - D3/GPIO0 25 | 26 | ![Schematic](Schematic.png) 27 | 28 | ## Demo 29 | [![Home-Assistant + MQTT + RGB light](screenshot.png)](https://www.youtube.com/watch?v=7rMpCZ9I2BU "Home-Assistant + MQTT + RGB light") 30 | -------------------------------------------------------------------------------- /ha_mqtt_rgb_light/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_rgb_light/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_rgb_light/ha_mqtt_rgb_light.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT RGB Light for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/light.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | 9 | Sources : 10 | - File > Examples > ES8266WiFi > WiFiClient 11 | - File > Examples > PubSubClient > mqtt_auth 12 | - File > Examples > PubSubClient > mqtt_esp8266 13 | - http://forum.arduino.cc/index.php?topic=272862.0 14 | 15 | Schematic : 16 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_rgb_light/Schematic.png 17 | - LED leg 1 - Resistor 270 Ohms - D1/GPIO5 18 | - LED leg 2 (longuest leg) - GND 19 | - LED leg 3 - Resistor 270 Ohms - D2/GPIO4 20 | - LED leg 4 - Resistor 270 Ohms - D3/GPIO0 21 | 22 | Configuration (HA) : 23 | light: 24 | platform: mqtt 25 | name: 'Office RGB light' 26 | state_topic: 'office/rgb1/light/status' 27 | command_topic: 'office/rgb1/light/switch' 28 | brightness_state_topic: 'office/rgb1/brightness/status' 29 | brightness_command_topic: 'office/rgb1/brightness/set' 30 | rgb_state_topic: 'office/rgb1/rgb/status' 31 | rgb_command_topic: 'office/rgb1/rgb/set' 32 | brightness_scale: 100 33 | optimistic: false 34 | 35 | Samuel M. - v1.1 - 08.2016 36 | If you like this example, please add a star! Thank you! 37 | https://github.com/mertenats/open-home-automation 38 | */ 39 | 40 | #include 41 | #include 42 | 43 | #define MQTT_VERSION MQTT_VERSION_3_1_1 44 | 45 | // Wifi: SSID and password 46 | const char* WIFI_SSID = "[Redacted]"; 47 | const char* WIFI_PASSWORD = "[Redacted]"; 48 | 49 | // MQTT: ID, server IP, port, username and password 50 | const PROGMEM char* MQTT_CLIENT_ID = "office_rgb_light"; 51 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 52 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 53 | const PROGMEM char* MQTT_USER = "[Redacted]"; 54 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 55 | 56 | // MQTT: topics 57 | // state 58 | const PROGMEM char* MQTT_LIGHT_STATE_TOPIC = "office/rgb1/light/status"; 59 | const PROGMEM char* MQTT_LIGHT_COMMAND_TOPIC = "office/rgb1/light/switch"; 60 | 61 | // brightness 62 | const PROGMEM char* MQTT_LIGHT_BRIGHTNESS_STATE_TOPIC = "office/rgb1/brightness/status"; 63 | const PROGMEM char* MQTT_LIGHT_BRIGHTNESS_COMMAND_TOPIC = "office/rgb1/brightness/set"; 64 | 65 | // colors (rgb) 66 | const PROGMEM char* MQTT_LIGHT_RGB_STATE_TOPIC = "office/rgb1/rgb/status"; 67 | const PROGMEM char* MQTT_LIGHT_RGB_COMMAND_TOPIC = "office/rgb1/rgb/set"; 68 | 69 | // payloads by default (on/off) 70 | const PROGMEM char* LIGHT_ON = "ON"; 71 | const PROGMEM char* LIGHT_OFF = "OFF"; 72 | 73 | // variables used to store the state, the brightness and the color of the light 74 | boolean m_rgb_state = false; 75 | uint8_t m_rgb_brightness = 100; 76 | uint8_t m_rgb_red = 255; 77 | uint8_t m_rgb_green = 255; 78 | uint8_t m_rgb_blue = 255; 79 | 80 | // pins used for the rgb led (PWM) 81 | const PROGMEM uint8_t RGB_LIGHT_RED_PIN = 5; 82 | const PROGMEM uint8_t RGB_LIGHT_GREEN_PIN = 0; 83 | const PROGMEM uint8_t RGB_LIGHT_BLUE_PIN = 4; 84 | 85 | // buffer used to send/receive data with MQTT 86 | const uint8_t MSG_BUFFER_SIZE = 20; 87 | char m_msg_buffer[MSG_BUFFER_SIZE]; 88 | 89 | WiFiClient wifiClient; 90 | PubSubClient client(wifiClient); 91 | 92 | // function called to adapt the brightness and the color of the led 93 | void setColor(uint8_t p_red, uint8_t p_green, uint8_t p_blue) { 94 | // convert the brightness in % (0-100%) into a digital value (0-255) 95 | uint8_t brightness = map(m_rgb_brightness, 0, 100, 0, 255); 96 | 97 | analogWrite(RGB_LIGHT_RED_PIN, map(p_red, 0, 255, 0, brightness)); 98 | analogWrite(RGB_LIGHT_GREEN_PIN, map(p_green, 0, 255, 0, brightness)); 99 | analogWrite(RGB_LIGHT_BLUE_PIN, map(p_blue, 0, 255, 0, brightness)); 100 | } 101 | 102 | // function called to publish the state of the led (on/off) 103 | void publishRGBState() { 104 | if (m_rgb_state) { 105 | client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_ON, true); 106 | } else { 107 | client.publish(MQTT_LIGHT_STATE_TOPIC, LIGHT_OFF, true); 108 | } 109 | } 110 | 111 | // function called to publish the brightness of the led (0-100) 112 | void publishRGBBrightness() { 113 | snprintf(m_msg_buffer, MSG_BUFFER_SIZE, "%d", m_rgb_brightness); 114 | client.publish(MQTT_LIGHT_BRIGHTNESS_STATE_TOPIC, m_msg_buffer, true); 115 | } 116 | 117 | // function called to publish the colors of the led (xx(x),xx(x),xx(x)) 118 | void publishRGBColor() { 119 | snprintf(m_msg_buffer, MSG_BUFFER_SIZE, "%d,%d,%d", m_rgb_red, m_rgb_green, m_rgb_blue); 120 | client.publish(MQTT_LIGHT_RGB_STATE_TOPIC, m_msg_buffer, true); 121 | } 122 | 123 | // function called when a MQTT message arrived 124 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 125 | // concat the payload into a string 126 | String payload; 127 | for (uint8_t i = 0; i < p_length; i++) { 128 | payload.concat((char)p_payload[i]); 129 | } 130 | // handle message topic 131 | if (String(MQTT_LIGHT_COMMAND_TOPIC).equals(p_topic)) { 132 | // test if the payload is equal to "ON" or "OFF" 133 | if (payload.equals(String(LIGHT_ON))) { 134 | if (m_rgb_state != true) { 135 | m_rgb_state = true; 136 | setColor(m_rgb_red, m_rgb_green, m_rgb_blue); 137 | publishRGBState(); 138 | } 139 | } else if (payload.equals(String(LIGHT_OFF))) { 140 | if (m_rgb_state != false) { 141 | m_rgb_state = false; 142 | setColor(0, 0, 0); 143 | publishRGBState(); 144 | } 145 | } 146 | } else if (String(MQTT_LIGHT_BRIGHTNESS_COMMAND_TOPIC).equals(p_topic)) { 147 | uint8_t brightness = payload.toInt(); 148 | if (brightness < 0 || brightness > 100) { 149 | // do nothing... 150 | return; 151 | } else { 152 | m_rgb_brightness = brightness; 153 | setColor(m_rgb_red, m_rgb_green, m_rgb_blue); 154 | publishRGBBrightness(); 155 | } 156 | } else if (String(MQTT_LIGHT_RGB_COMMAND_TOPIC).equals(p_topic)) { 157 | // get the position of the first and second commas 158 | uint8_t firstIndex = payload.indexOf(','); 159 | uint8_t lastIndex = payload.lastIndexOf(','); 160 | 161 | uint8_t rgb_red = payload.substring(0, firstIndex).toInt(); 162 | if (rgb_red < 0 || rgb_red > 255) { 163 | return; 164 | } else { 165 | m_rgb_red = rgb_red; 166 | } 167 | 168 | uint8_t rgb_green = payload.substring(firstIndex + 1, lastIndex).toInt(); 169 | if (rgb_green < 0 || rgb_green > 255) { 170 | return; 171 | } else { 172 | m_rgb_green = rgb_green; 173 | } 174 | 175 | uint8_t rgb_blue = payload.substring(lastIndex + 1).toInt(); 176 | if (rgb_blue < 0 || rgb_blue > 255) { 177 | return; 178 | } else { 179 | m_rgb_blue = rgb_blue; 180 | } 181 | 182 | setColor(m_rgb_red, m_rgb_green, m_rgb_blue); 183 | publishRGBColor(); 184 | } 185 | } 186 | 187 | void reconnect() { 188 | // Loop until we're reconnected 189 | while (!client.connected()) { 190 | Serial.println("INFO: Attempting MQTT connection..."); 191 | // Attempt to connect 192 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 193 | Serial.println("INFO: connected"); 194 | 195 | // Once connected, publish an announcement... 196 | // publish the initial values 197 | publishRGBState(); 198 | publishRGBBrightness(); 199 | publishRGBColor(); 200 | 201 | // ... and resubscribe 202 | client.subscribe(MQTT_LIGHT_COMMAND_TOPIC); 203 | client.subscribe(MQTT_LIGHT_BRIGHTNESS_COMMAND_TOPIC); 204 | client.subscribe(MQTT_LIGHT_RGB_COMMAND_TOPIC); 205 | } else { 206 | Serial.print("ERROR: failed, rc="); 207 | Serial.print(client.state()); 208 | Serial.println("DEBUG: try again in 5 seconds"); 209 | // Wait 5 seconds before retrying 210 | delay(5000); 211 | } 212 | } 213 | } 214 | 215 | void setup() { 216 | // init the serial 217 | Serial.begin(115200); 218 | 219 | // init the RGB led 220 | pinMode(RGB_LIGHT_BLUE_PIN, OUTPUT); 221 | pinMode(RGB_LIGHT_RED_PIN, OUTPUT); 222 | pinMode(RGB_LIGHT_GREEN_PIN, OUTPUT); 223 | analogWriteRange(255); 224 | setColor(0, 0, 0); 225 | 226 | // init the WiFi connection 227 | Serial.println(); 228 | Serial.println(); 229 | Serial.print("INFO: Connecting to "); 230 | WiFi.mode(WIFI_STA); 231 | Serial.println(WIFI_SSID); 232 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 233 | 234 | while (WiFi.status() != WL_CONNECTED) { 235 | delay(500); 236 | Serial.print("."); 237 | } 238 | 239 | Serial.println(""); 240 | Serial.println("INFO: WiFi connected"); 241 | Serial.print("INFO: IP address: "); 242 | Serial.println(WiFi.localIP()); 243 | 244 | // init the MQTT connection 245 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 246 | client.setCallback(callback); 247 | } 248 | 249 | void loop() { 250 | if (!client.connected()) { 251 | reconnect(); 252 | } 253 | client.loop(); 254 | } 255 | -------------------------------------------------------------------------------- /ha_mqtt_rgb_light/screenshot.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_rgb_light/screenshot.png -------------------------------------------------------------------------------- /ha_mqtt_rgbw_light_with_discovery/README.md: -------------------------------------------------------------------------------- 1 | # MQTT JSON Light - Home Assistant 2 | A simple example to control a RGB led and a white led connected to a NodeMCU board (ESP8266). 3 | 4 | ## Features 5 | - MQTT discovery 6 | - MQTT JSON Light 7 | - State 8 | - RGB 9 | - White 10 | - Brightness 11 | - Color temperature 12 | - Effect 13 | - Rainbow 14 | 15 | ## How to 16 | 1. Rename `config.example.h`to `config.h` 17 | 2. Define your WiFi SSID and password 18 | 3. Define your MQTT settings 19 | 4. Install the external libraries (PubSubClient, ArduinoJson) 20 | 4. Define `MQTT_MAX_PACKET_SIZE` to `256`in `Arduino/libraries/pubsubclient/src/PubSubClient.h` 21 | -------------------------------------------------------------------------------- /ha_mqtt_rgbw_light_with_discovery/config.example.h: -------------------------------------------------------------------------------- 1 | /////////////////////////////////////////////////////////////////////////// 2 | // RGB PINS 3 | /////////////////////////////////////////////////////////////////////////// 4 | #define RED_PIN D1 5 | #define GREEN_PIN D2 6 | #define BLUE_PIN D3 7 | #define WHITE_PIN D4 8 | 9 | /////////////////////////////////////////////////////////////////////////// 10 | // MISC 11 | /////////////////////////////////////////////////////////////////////////// 12 | #define FRIENDLY_NAME "MQTT RGBW Light" 13 | 14 | /////////////////////////////////////////////////////////////////////////// 15 | // WiFi 16 | /////////////////////////////////////////////////////////////////////////// 17 | #define WIFI_SSID "" 18 | #define WIFI_PASSWORD "" 19 | 20 | /////////////////////////////////////////////////////////////////////////// 21 | // MQTT 22 | /////////////////////////////////////////////////////////////////////////// 23 | #define MQTT_USERNAME "" 24 | #define MQTT_PASSWORD "" 25 | #define MQTT_SERVER "" 26 | #define MQTT_SERVER_PORT 1883 27 | 28 | #define MQTT_HOME_ASSISTANT_SUPPORT 29 | 30 | #if defined(MQTT_HOME_ASSISTANT_SUPPORT) 31 | // template: /light//config, status, state or set 32 | #define MQTT_CONFIG_TOPIC_TEMPLATE "%s/light/%s/config" 33 | #else 34 | 35 | #endif 36 | 37 | #define MQTT_STATE_TOPIC_TEMPLATE "%s/rgbw/state" 38 | #define MQTT_COMMAND_TOPIC_TEMPLATE "%s/rgbw/set" 39 | #define MQTT_STATUS_TOPIC_TEMPLATE "%s/rgbw/status" // MQTT connection: alive/dead 40 | 41 | #define MQTT_HOME_ASSISTANT_DISCOVERY_PREFIX "homeassistant" 42 | #define MQTT_STATE_ON_PAYLOAD "ON" 43 | #define MQTT_STATE_OFF_PAYLOAD "OFF" 44 | 45 | #define MQTT_CONNECTION_TIMEOUT 5000 46 | 47 | /////////////////////////////////////////////////////////////////////////// 48 | // DEBUG 49 | /////////////////////////////////////////////////////////////////////////// 50 | //#define DEBUG_TELNET 51 | //#define DEBUG_SERIAL 52 | 53 | /////////////////////////////////////////////////////////////////////////// 54 | // OTA 55 | /////////////////////////////////////////////////////////////////////////// 56 | #define OTA 57 | //#define OTA_HOSTNAME "hostname" // hostname esp8266-[ChipID] by default 58 | //#define OTA_PASSWORD "password" // no password by default 59 | //#define OTA_PORT 8266 // port 8266 by default 60 | -------------------------------------------------------------------------------- /ha_mqtt_rgbw_light_with_discovery/ha_mqtt_rgbw_light_with_discovery.cpp: -------------------------------------------------------------------------------- 1 | #include "ha_mqtt_rgbw_light_with_discovery.h" 2 | 3 | volatile uint8_t effect = EFFECT_NOT_DEFINED; 4 | 5 | /////////////////////////////////////////////////////////////////////////// 6 | // CONSTRUCTOR, INIT() AND LOOP() 7 | /////////////////////////////////////////////////////////////////////////// 8 | AIRGBWBulb::AIRGBWBulb(void) { 9 | analogWriteRange(255); 10 | 11 | pinMode(RED_PIN, OUTPUT); 12 | pinMode(GREEN_PIN, OUTPUT); 13 | pinMode(BLUE_PIN, OUTPUT); 14 | pinMode(WHITE_PIN, OUTPUT); 15 | } 16 | 17 | void AIRGBWBulb::init(void) { 18 | m_state = false; 19 | m_brightness = 255; 20 | m_color.red = 0; 21 | m_color.green = 0; 22 | m_color.blue = 0; 23 | m_color.white = 255; 24 | } 25 | 26 | void AIRGBWBulb::loop(void) { 27 | // TODO: handles effects 28 | switch(effect) { 29 | case EFFECT_NOT_DEFINED: 30 | break; 31 | case EFFECT_RAMBOW: 32 | static unsigned char count = 0; 33 | static unsigned long last = millis(); 34 | if (millis() - last > EFFECT_RAINBOW_DELAY) { 35 | last = millis(); 36 | rainbowEffect(count++); 37 | } 38 | break; 39 | } 40 | } 41 | 42 | /////////////////////////////////////////////////////////////////////////// 43 | // STATE 44 | /////////////////////////////////////////////////////////////////////////// 45 | bool AIRGBWBulb::getState(void) { 46 | return m_state; 47 | } 48 | 49 | bool AIRGBWBulb::setState(bool p_state) { 50 | // checks if the given state is different from the actual state 51 | if (p_state == m_state) 52 | return false; 53 | 54 | if (p_state) { 55 | m_state = true; 56 | setColor(); 57 | } else { 58 | m_state = false; 59 | analogWrite(RED_PIN, 0); 60 | analogWrite(GREEN_PIN, 0); 61 | analogWrite(BLUE_PIN, 0); 62 | analogWrite(WHITE_PIN, 0); 63 | } 64 | 65 | return true; 66 | } 67 | 68 | /////////////////////////////////////////////////////////////////////////// 69 | // BRIGHTNESS 70 | /////////////////////////////////////////////////////////////////////////// 71 | uint8_t AIRGBWBulb::getBrightness(void) { 72 | return m_brightness; 73 | } 74 | 75 | bool AIRGBWBulb::setBrightness(uint8_t p_brightness) { 76 | // checks if the value is smaller, bigger or equal to the actual brightness value 77 | if (p_brightness < 0 || p_brightness > 255 || p_brightness == m_brightness) 78 | return false; 79 | 80 | // saves the new brightness value 81 | m_brightness = p_brightness; 82 | 83 | if (m_color.white != 0) 84 | m_color.white = p_brightness; 85 | 86 | return setColor(); 87 | } 88 | 89 | /////////////////////////////////////////////////////////////////////////// 90 | // RGB COLOR 91 | /////////////////////////////////////////////////////////////////////////// 92 | Color AIRGBWBulb::getColor(void) { 93 | return m_color; 94 | } 95 | 96 | bool AIRGBWBulb::setColor(uint8_t p_red, uint8_t p_green, uint8_t p_blue) { 97 | if ((p_red < 0 || p_red > 255) || (p_green < 0 || p_green > 255) || (p_blue < 0 || p_blue > 255)) 98 | return false; 99 | 100 | // saves the new values 101 | m_color.red = p_red; 102 | m_color.green = p_green; 103 | m_color.blue = p_blue; 104 | 105 | // switches off the white leds 106 | m_color.white = 0; 107 | 108 | return setColor(); 109 | } 110 | 111 | bool AIRGBWBulb::setColor() { 112 | // sets the new color 113 | analogWrite(RED_PIN, map(m_color.red, 0, 255, 0, m_brightness)); 114 | analogWrite(GREEN_PIN, map(m_color.green, 0, 255, 0, m_brightness)); 115 | analogWrite(BLUE_PIN, map(m_color.blue, 0, 255, 0, m_brightness)); 116 | analogWrite(WHITE_PIN, m_color.white); 117 | 118 | return true; 119 | } 120 | 121 | /////////////////////////////////////////////////////////////////////////// 122 | // WHITE COLOR 123 | /////////////////////////////////////////////////////////////////////////// 124 | bool AIRGBWBulb::setWhite(uint8_t p_white) { 125 | // checks if the value is smaller, bigger or equal to the actual white value 126 | if (p_white < 0 || p_white > 255 || p_white == m_color.white) 127 | return false; 128 | 129 | // saves the new white value 130 | m_color.white = p_white; 131 | m_brightness = p_white; 132 | 133 | // switch off the RGB leds 134 | m_color.red = 0; 135 | m_color.green = 0; 136 | m_color.blue = 0; 137 | 138 | // adjusts the white value 139 | analogWrite(RED_PIN, m_color.red); 140 | analogWrite(GREEN_PIN, m_color.green); 141 | analogWrite(BLUE_PIN, m_color.blue); 142 | analogWrite(WHITE_PIN, m_color.white); 143 | 144 | return true; 145 | } 146 | 147 | /////////////////////////////////////////////////////////////////////////// 148 | // COLOR TEMPERATURE 149 | /////////////////////////////////////////////////////////////////////////// 150 | uint16_t AIRGBWBulb::getColorTemperature(void) { 151 | return m_colorTemperature; 152 | } 153 | 154 | bool AIRGBWBulb::setColorTemperature(uint16_t p_colorTemperature) { 155 | // checks if the value is equal to the actual color temperature 156 | if (p_colorTemperature < COLOR_TEMP_HA_MIN_IN_MIRED || p_colorTemperature == m_colorTemperature || p_colorTemperature > COLOR_TEMP_HA_MAX_IN_MIRED) 157 | return false; 158 | 159 | // switches off the white leds 160 | m_color.white = 0; 161 | 162 | // saves the new colour temperature 163 | m_colorTemperature = p_colorTemperature; 164 | 165 | // https://fr.wikipedia.org/wiki/Mired 166 | // http://www.tannerhelland.com/4435/convert-temperature-rgb-algorithm-code/ 167 | // M = 1000000 / T <> T [kelvin] = 1000000 / M [mired] 168 | int tmpKelvin = 1000000 / m_colorTemperature; 169 | 170 | if (tmpKelvin < 1000) { 171 | tmpKelvin = 1000; 172 | } else if (tmpKelvin > 40000) { 173 | tmpKelvin = 40000; 174 | } 175 | 176 | //int tmpKelvin = map(p_colorTemperature, COLOR_TEMP_HA_MIN_IN_MIRED, COLOR_TEMP_HA_MAX_IN_MIRED, COLOR_TEMP_MAX_IN_KELVIN, COLOR_TEMP_MIN_IN_KELVIN); 177 | tmpKelvin = tmpKelvin / 100; 178 | 179 | // computes red 180 | if (tmpKelvin <= 66) { 181 | m_color.red = 255; 182 | } else { 183 | float red = tmpKelvin - 60; 184 | red = 329.698727446 * pow(red, -0.1332047592); 185 | if (red < 0) { 186 | m_color.red = 0; 187 | } else if (red > 255) { 188 | m_color.red = 255; 189 | } else { 190 | m_color.red = red; 191 | } 192 | } 193 | 194 | // computes green 195 | if (tmpKelvin <= 66) { 196 | float green = tmpKelvin; 197 | green = 99.4708025861 * log(green) - 161.1195681661; 198 | if (green < 0) { 199 | m_color.green = 0; 200 | } else if (green > 255) { 201 | m_color.green = 255; 202 | } else { 203 | m_color.green = green; 204 | } 205 | } else { 206 | float green = tmpKelvin - 60; 207 | green = 288.1221695283 * pow(green, -0.0755148492); 208 | if (green < 0) { 209 | m_color.green = 0; 210 | } else if (green > 255) { 211 | m_color.green = 255; 212 | } else { 213 | m_color.green = green; 214 | } 215 | } 216 | 217 | // computes blue 218 | if (tmpKelvin <= 66) { 219 | m_color.blue = 255; 220 | } else { 221 | if (tmpKelvin <= 19) { 222 | m_color.blue = 0; 223 | } else { 224 | float blue = tmpKelvin - 10; 225 | blue = 138.5177312231 * log(blue) - 305.0447927307; 226 | if (blue < 0) { 227 | m_color.blue = 0; 228 | } else if (blue > 255) { 229 | m_color.blue = 255; 230 | } else { 231 | m_color.blue = blue; 232 | } 233 | } 234 | } 235 | 236 | return setColor(); 237 | } 238 | 239 | /////////////////////////////////////////////////////////////////////////// 240 | // EFFECTS 241 | /////////////////////////////////////////////////////////////////////////// 242 | bool AIRGBWBulb::setEffect(const char* p_effect) { 243 | if (strcmp(p_effect, EFFECT_NOT_DEFINED_NAME) == 0) { 244 | effect = EFFECT_NOT_DEFINED; 245 | return true; 246 | } else if (strcmp(p_effect, EFFECT_RAMBOW_NAME) == 0) { 247 | effect = EFFECT_RAMBOW; 248 | return true; 249 | } 250 | 251 | return false; 252 | } 253 | 254 | // https://github.com/xoseperez/my9291/blob/master/examples/esp8285/esp8285_rainbow.cpp 255 | void AIRGBWBulb::rainbowEffect(uint8_t p_index) { 256 | if (p_index < 85) { 257 | setColor(p_index * 3, 255 - p_index * 3, 0); 258 | } else if (p_index < 170) { 259 | p_index -= 85; 260 | setColor(255 - p_index * 3, 0, p_index * 3); 261 | } else { 262 | p_index -= 170; 263 | setColor(0, p_index * 3, 255 - p_index * 3); 264 | } 265 | } 266 | -------------------------------------------------------------------------------- /ha_mqtt_rgbw_light_with_discovery/ha_mqtt_rgbw_light_with_discovery.h: -------------------------------------------------------------------------------- 1 | #pragma once 2 | #ifndef _RGBW_ 3 | #define _RGBW_ 4 | 5 | #include // https://github.com/esp8266/Arduino 6 | #include "config.h" 7 | 8 | #define COLOR_TEMP_HA_MIN_IN_MIRED 154 // Home Assistant minimum color temperature 9 | #define COLOR_TEMP_HA_MAX_IN_MIRED 500 // Home Assistant maximum color temperature 10 | #define COLOR_TEMP_MIN_IN_KELVIN 1000 // minimum color temperature 11 | #define COLOR_TEMP_MAX_IN_KELVIN 15000 // maximum color temperature 12 | 13 | typedef struct Color { 14 | uint8_t red; 15 | uint8_t green; 16 | uint8_t blue; 17 | uint8_t white; 18 | }; 19 | 20 | enum CMD { 21 | CMD_NOT_DEFINED, 22 | CMD_STATE_CHANGED, 23 | }; 24 | 25 | #define EFFECT_NOT_DEFINED_NAME "None" 26 | #define EFFECT_RAMBOW_NAME "Rainbow" 27 | #define EFFECT_RAINBOW_DELAY 10 28 | 29 | #define EFFECT_LIST EFFECT_RAMBOW_NAME 30 | 31 | enum EFFECT { 32 | EFFECT_NOT_DEFINED, 33 | EFFECT_RAMBOW, 34 | }; 35 | 36 | class AIRGBWBulb { 37 | public: 38 | AIRGBWBulb(void); 39 | 40 | void init(void); 41 | void loop(void); 42 | 43 | bool getState(void); 44 | bool setState(bool p_state); 45 | 46 | uint8_t getBrightness(void); 47 | bool setBrightness(uint8_t p_brightness); 48 | 49 | Color getColor(void); 50 | bool setColor(uint8_t p_red, uint8_t p_green, uint8_t p_blue); 51 | 52 | bool setWhite(uint8_t p_white); 53 | 54 | uint16_t getColorTemperature(void); 55 | bool setColorTemperature(uint16_t p_colorTemperature); 56 | 57 | bool setEffect(const char* p_effect); 58 | 59 | private: 60 | bool m_state; 61 | uint8_t m_brightness; 62 | Color m_color; 63 | uint16_t m_colorTemperature; 64 | 65 | bool setColor(); 66 | 67 | void rainbowEffect(uint8_t p_index); 68 | 69 | }; 70 | 71 | #endif 72 | -------------------------------------------------------------------------------- /ha_mqtt_sensor_dht22/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Sensor - Temperature and Humidity - Home Assistant 2 | A simple example to get temperature and humidity every ten minutes from a DHT22 sensor connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | sensor 1: 8 | platform: mqtt 9 | state_topic: 'office/sensor1' 10 | name: 'Temperature' 11 | unit_of_measurement: '°C' 12 | value_template: '{{ value_json.temperature }}' 13 | 14 | sensor 2: 15 | platform: mqtt 16 | state_topic: 'office/sensor1' 17 | name: 'Humidity' 18 | unit_of_measurement: '%' 19 | value_template: '{{ value_json.humidity }}' 20 | ``` 21 | 22 | ## Schematic 23 | - DHT22 leg 1 - VCC 24 | - DHT22 leg 2 - D1/GPIO5 - Resistor 4.7K Ohms - GND 25 | - DHT22 leg 4 - GND 26 | - D0/GPIO16 - RST (wake-up purpose) 27 | 28 | ![Schematic](Schematic.png) 29 | -------------------------------------------------------------------------------- /ha_mqtt_sensor_dht22/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_sensor_dht22/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_sensor_dht22/ha_mqtt_sensor_dht22.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Sensor - Temperature and Humidity (DHT22) for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/sensor.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | - DHT : https://github.com/adafruit/DHT-sensor-library 9 | - ArduinoJson : https://github.com/bblanchon/ArduinoJson 10 | 11 | Sources : 12 | - File > Examples > ES8266WiFi > WiFiClient 13 | - File > Examples > PubSubClient > mqtt_auth 14 | - File > Examples > PubSubClient > mqtt_esp8266 15 | - File > Examples > DHT sensor library > DHTtester 16 | - File > Examples > ArduinoJson > JsonGeneratorExample 17 | - http://www.jerome-bernard.com/blog/2015/10/04/wifi-temperature-sensor-with-nodemcu-esp8266/ 18 | 19 | Schematic : 20 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_sensor_dht22/Schematic.png 21 | - DHT22 leg 1 - VCC 22 | - DHT22 leg 2 - D1/GPIO5 - Resistor 4.7K Ohms - GND 23 | - DHT22 leg 4 - GND 24 | - D0/GPIO16 - RST (wake-up purpose) 25 | 26 | Configuration (HA) : 27 | sensor 1: 28 | platform: mqtt 29 | state_topic: 'office/sensor1' 30 | name: 'Temperature' 31 | unit_of_measurement: '°C' 32 | value_template: '{{ value_json.temperature }}' 33 | 34 | sensor 2: 35 | platform: mqtt 36 | state_topic: 'office/sensor1' 37 | name: 'Humidity' 38 | unit_of_measurement: '%' 39 | value_template: '{{ value_json.humidity }}' 40 | 41 | Samuel M. - v1.1 - 08.2016 42 | If you like this example, please add a star! Thank you! 43 | https://github.com/mertenats/open-home-automation 44 | */ 45 | 46 | #include 47 | #include 48 | #include "DHT.h" 49 | #include 50 | 51 | #define MQTT_VERSION MQTT_VERSION_3_1_1 52 | 53 | // Wifi: SSID and password 54 | const char* WIFI_SSID = "[Redacted]"; 55 | const char* WIFI_PASSWORD = "[Redacted]"; 56 | 57 | // MQTT: ID, server IP, port, username and password 58 | const PROGMEM char* MQTT_CLIENT_ID = "office_dht22"; 59 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 60 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 61 | const PROGMEM char* MQTT_USER = "[Redacted]"; 62 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 63 | 64 | // MQTT: topic 65 | const PROGMEM char* MQTT_SENSOR_TOPIC = "office/sensor1"; 66 | 67 | // sleeping time 68 | const PROGMEM uint16_t SLEEPING_TIME_IN_SECONDS = 600; // 10 minutes x 60 seconds 69 | 70 | // DHT - D1/GPIO5 71 | #define DHTPIN 5 72 | #define DHTTYPE DHT22 73 | 74 | DHT dht(DHTPIN, DHTTYPE); 75 | WiFiClient wifiClient; 76 | PubSubClient client(wifiClient); 77 | 78 | // function called to publish the temperature and the humidity 79 | void publishData(float p_temperature, float p_humidity) { 80 | // create a JSON object 81 | // doc : https://github.com/bblanchon/ArduinoJson/wiki/API%20Reference 82 | StaticJsonBuffer<200> jsonBuffer; 83 | JsonObject& root = jsonBuffer.createObject(); 84 | // INFO: the data must be converted into a string; a problem occurs when using floats... 85 | root["temperature"] = (String)p_temperature; 86 | root["humidity"] = (String)p_humidity; 87 | root.prettyPrintTo(Serial); 88 | Serial.println(""); 89 | /* 90 | { 91 | "temperature": "23.20" , 92 | "humidity": "43.70" 93 | } 94 | */ 95 | char data[200]; 96 | root.printTo(data, root.measureLength() + 1); 97 | client.publish(MQTT_SENSOR_TOPIC, data, true); 98 | yield(); 99 | } 100 | 101 | // function called when a MQTT message arrived 102 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 103 | } 104 | 105 | void reconnect() { 106 | // Loop until we're reconnected 107 | while (!client.connected()) { 108 | Serial.println("INFO: Attempting MQTT connection..."); 109 | // Attempt to connect 110 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 111 | Serial.println("INFO: connected"); 112 | } else { 113 | Serial.print("ERROR: failed, rc="); 114 | Serial.print(client.state()); 115 | Serial.println("DEBUG: try again in 5 seconds"); 116 | // Wait 5 seconds before retrying 117 | delay(5000); 118 | } 119 | } 120 | } 121 | 122 | void setup() { 123 | // init the serial 124 | Serial.begin(115200); 125 | 126 | dht.begin(); 127 | 128 | // init the WiFi connection 129 | Serial.println(); 130 | Serial.println(); 131 | Serial.print("INFO: Connecting to "); 132 | WiFi.mode(WIFI_STA); 133 | Serial.println(WIFI_SSID); 134 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 135 | 136 | while (WiFi.status() != WL_CONNECTED) { 137 | delay(500); 138 | Serial.print("."); 139 | } 140 | 141 | Serial.println(""); 142 | Serial.println("INFO: WiFi connected"); 143 | Serial.println("INFO: IP address: "); 144 | Serial.println(WiFi.localIP()); 145 | 146 | // init the MQTT connection 147 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 148 | client.setCallback(callback); 149 | } 150 | 151 | void loop() { 152 | if (!client.connected()) { 153 | reconnect(); 154 | } 155 | client.loop(); 156 | 157 | // Reading temperature or humidity takes about 250 milliseconds! 158 | // Sensor readings may also be up to 2 seconds 'old' (its a very slow sensor) 159 | float h = dht.readHumidity(); 160 | // Read temperature as Celsius (the default) 161 | float t = dht.readTemperature(); 162 | 163 | if (isnan(h) || isnan(t)) { 164 | Serial.println("ERROR: Failed to read from DHT sensor!"); 165 | return; 166 | } else { 167 | //Serial.println(h); 168 | //Serial.println(t); 169 | publishData(t, h); 170 | } 171 | 172 | Serial.println("INFO: Closing the MQTT connection"); 173 | client.disconnect(); 174 | 175 | Serial.println("INFO: Closing the Wifi connection"); 176 | WiFi.disconnect(); 177 | 178 | ESP.deepSleep(SLEEPING_TIME_IN_SECONDS * 1000000, WAKE_RF_DEFAULT); 179 | delay(500); // wait for deep sleep to happen 180 | } 181 | -------------------------------------------------------------------------------- /ha_mqtt_sensor_photocell/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Sensor - Brightness - Home Assistant 2 | A simple example to get the brightness (0 - 100%) of the room every ten minutes from a photocell connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | sensor 1: 8 | platform: mqtt 9 | state_topic: 'office/sensor1' 10 | name: 'Brightness' 11 | unit_of_measurement: '%' 12 | value_template: '{{ value_json.brightness }}' 13 | ``` 14 | 15 | ## Schematic 16 | - Photocell leg 1 - VCC 17 | - Photocell leg 2 - A0 - Resistor 10K Ohms - GND 18 | - D0/GPIO16 - RST (wake-up purpose) 19 | 20 | ![Schematic](Schematic.png) -------------------------------------------------------------------------------- /ha_mqtt_sensor_photocell/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_sensor_photocell/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_sensor_photocell/ha_mqtt_sensor_photocell.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Sensor - Brightness (photocell) for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/sensor.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | - ArduinoJson : https://github.com/bblanchon/ArduinoJson 9 | 10 | Sources : 11 | - File > Examples > ES8266WiFi > WiFiClient 12 | - File > Examples > PubSubClient > mqtt_auth 13 | - File > Examples > PubSubClient > mqtt_esp8266 14 | - File > Examples > ArduinoJson > JsonGeneratorExample 15 | 16 | Schematic : 17 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_sensor_photocell/Schematic.png 18 | - Photocell leg 1 - VCC 19 | - Photocell leg 2 - A0 - Resistor 10K Ohms - GND 20 | - D0/GPIO16 - RST (wake-up purpose) 21 | 22 | Configuration (HA) : 23 | sensor 1: 24 | platform: mqtt 25 | state_topic: 'office/sensor1' 26 | name: 'Brightness' 27 | unit_of_measurement: '%' 28 | value_template: '{{ value_json.brightness }}' 29 | 30 | Samuel M. - v1.1 - 08.2016 31 | If you like this example, please add a star! Thank you! 32 | https://github.com/mertenats/open-home-automation 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #define MQTT_VERSION MQTT_VERSION_3_1_1 40 | 41 | // Wifi: SSID and password 42 | const PROGMEM char* WIFI_SSID = "[Redacted]"; 43 | const PROGMEM char* WIFI_PASSWORD = "[Redacted]"; 44 | 45 | // MQTT: ID, server IP, port, username and password 46 | const PROGMEM char* MQTT_CLIENT_ID = "office_brightness"; 47 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 48 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 49 | const PROGMEM char* MQTT_USER = "[Redacted]"; 50 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 51 | 52 | // MQTT: topic 53 | const PROGMEM char* MQTT_SENSOR_TOPIC = "office/sensor1"; 54 | 55 | // sleeping time 56 | const PROGMEM uint16_t SLEEPING_TIME_IN_SECONDS = 600; // 10 minutes x 60 seconds 57 | 58 | // Photocell: A0 59 | const PROGMEM uint8_t PHOTOCELL_PIN = 0; 60 | 61 | WiFiClient wifiClient; 62 | PubSubClient client(wifiClient); 63 | 64 | // function called to publish the temperature and the humidity 65 | void publishData(int p_analogRead) { 66 | // convert 0-1024 into a percentage 67 | uint8_t brightness = map(p_analogRead, 0, 1024, 0, 100); 68 | 69 | // create a JSON object 70 | // doc : https://github.com/bblanchon/ArduinoJson/wiki/API%20Reference 71 | StaticJsonBuffer<200> jsonBuffer; 72 | JsonObject& root = jsonBuffer.createObject(); 73 | root["brightness"] = (String)brightness; 74 | root.prettyPrintTo(Serial); 75 | Serial.println(""); 76 | /* 77 | { 78 | "brightness": "75" 79 | } 80 | */ 81 | char data[200]; 82 | root.printTo(data, root.measureLength() + 1); 83 | client.publish(MQTT_SENSOR_TOPIC, data); 84 | } 85 | 86 | // function called when a MQTT message arrived 87 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 88 | } 89 | 90 | void reconnect() { 91 | // Loop until we're reconnected 92 | while (!client.connected()) { 93 | Serial.print("INFO: Attempting MQTT connection..."); 94 | // Attempt to connect 95 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 96 | Serial.println("INFO: connected"); 97 | } else { 98 | Serial.print("ERROR: failed, rc="); 99 | Serial.print(client.state()); 100 | Serial.println("DEBUG: try again in 5 seconds"); 101 | // Wait 5 seconds before retrying 102 | delay(5000); 103 | } 104 | } 105 | } 106 | 107 | void setup() { 108 | // init the serial 109 | Serial.begin(115200); 110 | 111 | // init the WiFi connection 112 | Serial.println(); 113 | Serial.println(); 114 | Serial.print("INFO: Connecting to "); 115 | WiFi.mode(WIFI_STA); 116 | Serial.println(WIFI_SSID); 117 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 118 | 119 | while (WiFi.status() != WL_CONNECTED) { 120 | delay(500); 121 | Serial.print("."); 122 | } 123 | 124 | Serial.println(""); 125 | Serial.println("INFO: WiFi connected"); 126 | Serial.println("INFO: IP address: "); 127 | Serial.println(WiFi.localIP()); 128 | 129 | // init the MQTT connection 130 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 131 | client.setCallback(callback); 132 | } 133 | 134 | void loop() { 135 | if (!client.connected()) { 136 | reconnect(); 137 | } 138 | client.loop(); 139 | 140 | // read the value of the photocell 141 | uint16_t photocell = analogRead(PHOTOCELL_PIN); 142 | 143 | if (photocell < 0 || photocell > 1024) { 144 | Serial.println("ERROR: Failed to read from the photocell!"); 145 | return; 146 | } else { 147 | publishData(photocell); 148 | } 149 | 150 | Serial.println("INFO: Closing the MQTT connection"); 151 | client.disconnect(); 152 | 153 | Serial.println("INFO: Closing the Wifi connection"); 154 | WiFi.disconnect(); 155 | 156 | ESP.deepSleep(SLEEPING_TIME_IN_SECONDS * 1000000, WAKE_RF_DEFAULT); 157 | delay(500); // wait for deep sleep to happen 158 | } 159 | -------------------------------------------------------------------------------- /ha_mqtt_switch/README.md: -------------------------------------------------------------------------------- 1 | # MQTT Switch - Home Assistant 2 | A simple example to control a switch connected to a NodeMCU board (ESP8266). 3 | 4 | ## Configuration 5 | configuration.yaml : 6 | ```yaml 7 | switch: 8 | platform: mqtt 9 | name: 'Office Switch' 10 | state_topic: 'office/switch1/status' 11 | command_topic: 'office/switch1/set' 12 | retain: true 13 | optimistic: false 14 | ``` 15 | 16 | ## Schematic 17 | - Switch leg 1 - VCC 18 | - Switch leg 2 - D1/GPIO5 - Resistor 10K Ohms - GND 19 | 20 | ![Schematic](Schematic.png) 21 | -------------------------------------------------------------------------------- /ha_mqtt_switch/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/ha_mqtt_switch/Schematic.png -------------------------------------------------------------------------------- /ha_mqtt_switch/ha_mqtt_switch.ino: -------------------------------------------------------------------------------- 1 | /* 2 | MQTT Switch for Home-Assistant - NodeMCU (ESP8266) 3 | https://home-assistant.io/components/switch.mqtt/ 4 | 5 | Libraries : 6 | - ESP8266 core for Arduino : https://github.com/esp8266/Arduino 7 | - PubSubClient : https://github.com/knolleary/pubsubclient 8 | - OneButton : https://github.com/mathertel/OneButton 9 | 10 | Sources : 11 | - File > Examples > ES8266WiFi > WiFiClient 12 | - File > Examples > PubSubClient > mqtt_auth 13 | - File > Examples > PubSubClient > mqtt_esp8266 14 | - OneButton : http://www.mathertel.de/Arduino/OneButtonLibrary.aspx 15 | 16 | Schematic : 17 | - https://github.com/mertenats/open-home-automation/blob/master/ha_mqtt_switch/Schematic.png 18 | - Switch leg 1 - VCC 19 | - Switch leg 2 - D1/GPIO5 - Resistor 10K Ohms - GND 20 | 21 | Configuration (HA) : 22 | switch: 23 | platform: mqtt 24 | name: 'Office Switch' 25 | state_topic: 'office/switch1/status' 26 | command_topic: 'office/switch1/set' 27 | retain: true 28 | optimistic: false 29 | 30 | Samuel M. - v1.1 - 08.2016 31 | If you like this example, please add a star! Thank you! 32 | https://github.com/mertenats/open-home-automation 33 | */ 34 | 35 | #include 36 | #include 37 | #include 38 | 39 | #define MQTT_VERSION MQTT_VERSION_3_1_1 40 | 41 | // Wifi: SSID and password 42 | const char* WIFI_SSID = "[Redacted]"; 43 | const char* WIFI_PASSWORD = "[Redacted]"; 44 | 45 | // MQTT: ID, server IP, port, username and password 46 | const PROGMEM char* MQTT_CLIENT_ID = "office_switch1"; 47 | const PROGMEM char* MQTT_SERVER_IP = "[Redacted]"; 48 | const PROGMEM uint16_t MQTT_SERVER_PORT = 1883; 49 | const PROGMEM char* MQTT_USER = "[Redacted]"; 50 | const PROGMEM char* MQTT_PASSWORD = "[Redacted]"; 51 | 52 | // MQTT: topics 53 | const PROGMEM char* MQTT_SWITCH_STATUS_TOPIC = "office/switch1/status"; 54 | const PROGMEM char* MQTT_SWITCH_COMMAND_TOPIC = "office/switch1/set"; 55 | 56 | // default payload 57 | const PROGMEM char* SWITCH_ON = "ON"; 58 | const PROGMEM char* SWITCH_OFF = "OFF"; 59 | 60 | // store the state of the switch 61 | boolean m_switch_state = false; 62 | 63 | // D1/GPIO5 64 | const PROGMEM uint8_t BUTTON_PIN = 5; 65 | 66 | WiFiClient wifiClient; 67 | PubSubClient client(wifiClient); 68 | OneButton button(BUTTON_PIN, false); // false : active HIGH 69 | 70 | // function called on button press 71 | // toggle the state of the switch 72 | void click() { 73 | if (m_switch_state) { 74 | m_switch_state = false; 75 | } else { 76 | m_switch_state = true; 77 | } 78 | publishSwitchState(); 79 | } 80 | 81 | // function called to publish the state of the switch (on/off) 82 | void publishSwitchState() { 83 | if (m_switch_state) { 84 | client.publish(MQTT_SWITCH_STATUS_TOPIC, SWITCH_ON, true); 85 | } else { 86 | client.publish(MQTT_SWITCH_STATUS_TOPIC, SWITCH_OFF, true); 87 | } 88 | } 89 | 90 | // function called when a MQTT message arrived 91 | void callback(char* p_topic, byte* p_payload, unsigned int p_length) { 92 | // concat the payload into a string 93 | String payload; 94 | for (uint8_t i = 0; i < p_length; i++) { 95 | payload.concat((char)p_payload[i]); 96 | } 97 | // handle message topic 98 | if (String(MQTT_SWITCH_COMMAND_TOPIC).equals(p_topic)) { 99 | // test if the payload is equal to "ON" or "OFF" 100 | if (payload.equals(String(SWITCH_ON))) { 101 | if (m_switch_state != true) { 102 | m_switch_state = true; 103 | publishSwitchState(); 104 | } 105 | } else if (payload.equals(String(SWITCH_OFF))) { 106 | if (m_switch_state != false) { 107 | m_switch_state = false; 108 | publishSwitchState(); 109 | } 110 | } 111 | } 112 | } 113 | 114 | void reconnect() { 115 | // Loop until we're reconnected 116 | while (!client.connected()) { 117 | Serial.println("INFO: Attempting MQTT connection..."); 118 | // Attempt to connect 119 | if (client.connect(MQTT_CLIENT_ID, MQTT_USER, MQTT_PASSWORD)) { 120 | Serial.println("INFO: connected"); 121 | 122 | // Once connected, publish an announcement... 123 | // publish the initial values 124 | publishSwitchState(); 125 | 126 | // ... and resubscribe 127 | client.subscribe(MQTT_SWITCH_COMMAND_TOPIC); 128 | } else { 129 | Serial.print("ERROR: failed, rc="); 130 | Serial.print(client.state()); 131 | Serial.println("DEBUG: try again in 5 seconds"); 132 | // Wait 5 seconds before retrying 133 | delay(5000); 134 | } 135 | } 136 | } 137 | 138 | void setup() { 139 | // init the serial 140 | Serial.begin(115200); 141 | 142 | // link the click function to be called on a single click event. 143 | button.attachClick(click); 144 | 145 | // init the WiFi connection 146 | Serial.println(); 147 | Serial.println(); 148 | Serial.print("INFO: Connecting to "); 149 | WiFi.mode(WIFI_STA); 150 | Serial.println(WIFI_SSID); 151 | WiFi.begin(WIFI_SSID, WIFI_PASSWORD); 152 | 153 | while (WiFi.status() != WL_CONNECTED) { 154 | delay(500); 155 | Serial.print("."); 156 | } 157 | 158 | Serial.println(""); 159 | Serial.println("INFO: WiFi connected"); 160 | Serial.println("INFO: IP address: "); 161 | Serial.println(WiFi.localIP()); 162 | 163 | // init the MQTT connection 164 | client.setServer(MQTT_SERVER_IP, MQTT_SERVER_PORT); 165 | client.setCallback(callback); 166 | } 167 | 168 | void loop() { 169 | // keep watching the push button: 170 | button.tick(); 171 | delay(10); 172 | 173 | if (!client.connected()) { 174 | reconnect(); 175 | } 176 | client.loop(); 177 | } 178 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation.yaml: -------------------------------------------------------------------------------- 1 | - !include automation/automation_1a.yaml 2 | - !include automation/automation_1b.yaml 3 | - !include automation/automation_1c.yaml 4 | - !include automation/automation_1d.yaml 5 | 6 | - !include automation/automation_2a.yaml 7 | - !include automation/automation_2b.yaml 8 | 9 | - !include automation/automation_3a.yaml 10 | - !include automation/automation_3b.yaml 11 | - !include automation/automation_3c.yaml 12 | 13 | - !include automation/automation_4a.yaml 14 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_1a.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 1 on motion (1a)' 2 | trigger: 3 | platform: state 4 | entity_id: binary_sensor.motion 5 | from: 'off' 6 | to: 'on' 7 | condition: 8 | condition: and 9 | conditions: 10 | - condition: state 11 | entity_id: group.all_devices 12 | state: 'not_home' 13 | - condition: state 14 | entity_id: 'sun.sun' 15 | state: 'below_horizon' 16 | action: 17 | - service: light.turn_on 18 | entity_id: light.lamp_1 19 | - delay: 20 | minutes: 3 21 | - service: light.turn_off 22 | entity_id: light.lamp_1 23 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_1b.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 1 & 2 on motion (1b)' 2 | trigger: 3 | platform: state 4 | entity_id: binary_sensor.motion 5 | from: 'off' 6 | to: 'on' 7 | condition: 8 | condition: and 9 | conditions: 10 | - condition: state 11 | entity_id: group.all_devices 12 | state: 'home' 13 | - condition: state 14 | entity_id: 'sun.sun' 15 | state: 'below_horizon' 16 | action: 17 | - service: light.turn_on 18 | entity_id: 19 | - light.lamp_1 20 | - light.lamp_2 21 | - delay: 22 | minutes: 3 23 | - service: light.turn_off 24 | entity_id: 25 | - light.lamp_1 26 | - light.lamp_2 27 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_1c.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 1, 2 & 4 on arrival of an inhabitantn (1c)' 2 | trigger: 3 | platform: state 4 | entity_id: device_tracker.samuel_phone 5 | from: 'not_home' 6 | to: 'home' 7 | condition: 8 | condition: and 9 | conditions: 10 | - condition: time 11 | before: '22:30:00' 12 | - condition: state 13 | entity_id: sun.sun 14 | state: 'below_horizon' 15 | action: 16 | - service: light.turn_on 17 | entity_id: 18 | - light.lamp_1 19 | - light.lamp_2 20 | - light.lamp_4 21 | - delay: 22 | minutes: 3 23 | - service: light.turn_off 24 | entity_id: 25 | - light.lamp_1 26 | - light.lamp_2 27 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_1d.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 1, 2, 5 & 6 on arrival of an inhabitantn (1d)' 2 | trigger: 3 | platform: state 4 | entity_id: device_tracker.samuel_phone 5 | from: 'not_home' 6 | to: 'home' 7 | condition: 8 | condition: and 9 | conditions: 10 | - condition: time 11 | after: '22:30:00' 12 | - condition: state 13 | entity_id: sun.sun 14 | state: 'below_horizon' 15 | action: 16 | - service: light.turn_on 17 | entity_id: 18 | - light.lamp_1 19 | - light.lamp_2 20 | - light.lamp_5 21 | - light.lamp_6 22 | - delay: 23 | minutes: 3 24 | - service: light.turn_off 25 | entity_id: 26 | - light.lamp_1 27 | - light.lamp_2 28 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_2a.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch off the lamp 4 when the TV is turned on (2a)' 2 | trigger: 3 | platform: state 4 | entity_id: binary_sensor.tv 5 | from: 'off' 6 | to: 'on' 7 | condition: 8 | condition: state 9 | entity_id: sun.sun 10 | state: 'below_horizon' 11 | action: 12 | - service: light.turn_off 13 | entity_id: light.lamp_4 14 | - service: light.turn_on 15 | data: 16 | entity_id: light.lamp_3 17 | brightness: 128 18 | rgb_color: [0, 255, 0] 19 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_2b.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 4 when the TV is turned off (2b)' 2 | trigger: 3 | platform: state 4 | entity_id: binary_sensor.tv 5 | from: 'on' 6 | to: 'off' 7 | condition: 8 | condition: state 9 | entity_id: sun.sun 10 | state: 'below_horizon' 11 | action: 12 | service: light.turn_on 13 | data: 14 | entity_id: light.lamp_3 15 | brightness: 192 16 | rgb_color: [255, 255, 255] 17 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_3a.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 5 progressively (3a)' 2 | trigger: 3 | platform: template 4 | value_template: '{{ now.time().strftime("%-H") == states.sensor.alarm_clock_hour.state and now.time().strftime("%-M") == states.sensor.alarm_clock_minute.state }}' 5 | condition: 6 | condition: and 7 | conditions: 8 | - condition: state 9 | entity_id: input_boolean.alarm_clock_status 10 | state: 'on' 11 | - condition: time 12 | weekday: 13 | - mon 14 | - tue 15 | - wed 16 | - thu 17 | - fri 18 | action: 19 | # minute 0 to 1 20 | - service: light.turn_on 21 | data: 22 | entity_id: light.lamp_5 23 | brightness: 45 24 | rgb_color: [255, 0, 0] # red 25 | - delay: 26 | minutes: 1 27 | # minute 1 to 2 28 | - service: light.turn_on 29 | data: 30 | entity_id: light.lamp_5 31 | brightness: 60 32 | rgb_color: [255, 51, 51] 33 | - delay: 34 | minutes: 1 35 | # minute 2 to 3 36 | - service: light.turn_on 37 | data: 38 | entity_id: light.lamp_5 39 | brightness: 75 40 | rgb_color: [255, 102, 102] 41 | - delay: 42 | minutes: 1 43 | # minute 3 to 4 44 | - service: light.turn_on 45 | data: 46 | entity_id: light.lamp_5 47 | brightness: 90 48 | rgb_color: [255, 128, 0] 49 | - delay: 50 | minutes: 1 51 | # minute 4 to 5 52 | - service: light.turn_on 53 | data: 54 | entity_id: light.lamp_5 55 | brightness: 105 56 | rgb_color: [255, 153, 51] 57 | - delay: 58 | minutes: 1 59 | # minute 5 to 6 60 | - service: light.turn_on 61 | data: 62 | entity_id: light.lamp_5 63 | brightness: 120 64 | rgb_color: [255, 178, 102] 65 | - delay: 66 | minutes: 1 67 | # minute 6 to 7 68 | - service: light.turn_on 69 | data: 70 | entity_id: light.lamp_5 71 | brightness: 135 72 | rgb_color: [255, 204, 153] 73 | - delay: 74 | minutes: 1 75 | # minute 7 to 8 76 | - service: light.turn_on 77 | data: 78 | entity_id: light.lamp_5 79 | brightness: 150 80 | rgb_color: [255, 229, 204] 81 | - delay: 82 | minutes: 1 83 | # minute 8 to 9 84 | - service: light.turn_on 85 | data: 86 | entity_id: light.lamp_5 87 | brightness: 165 88 | rgb_color: [255, 255, 204] 89 | - delay: 90 | minutes: 1 91 | # minute 9 to 10 92 | - service: light.turn_on 93 | data: 94 | entity_id: light.lamp_5 95 | brightness: 180 96 | rgb_color: [255, 255, 153] 97 | - delay: 98 | minutes: 1 99 | # minute 10 to 11 100 | - service: light.turn_on 101 | data: 102 | entity_id: light.lamp_5 103 | brightness: 195 104 | rgb_color: [255, 255, 102] 105 | - delay: 106 | minutes: 1 107 | # minute 11 to 12 108 | - service: light.turn_on 109 | data: 110 | entity_id: light.lamp_5 111 | brightness: 210 112 | rgb_color: [255, 255, 51] 113 | - delay: 114 | minutes: 1 115 | # minute 12 to 13 116 | - service: light.turn_on 117 | data: 118 | entity_id: light.lamp_5 119 | brightness: 225 120 | rgb_color: [255, 255, 0] 121 | - delay: 122 | minutes: 1 123 | # minute 13 to 14 124 | - service: light.turn_on 125 | data: 126 | entity_id: light.lamp_5 127 | brightness: 240 128 | rgb_color: [255, 255, 255] 129 | - delay: 130 | minutes: 1 131 | # minute 14 to 15 132 | - service: light.turn_on 133 | data: 134 | entity_id: light.lamp_5 135 | brightness: 255 136 | rgb_color: [255, 255, 255] 137 | - delay: 138 | minutes: 1 139 | - service: light.turn_on 140 | entity_id: light.lamp_6 141 | - service: light.turn_off 142 | entity_id: light.lamp_5 143 | # https://home-assistant.io/cookbook/notify_if_over_threshold/ 144 | - service: notify.notify 145 | data_template: 146 | message: > 147 | Hi Sam ! It's time to wake up ! It's {{ states.sensor.forecastio_temperature.state | round(0) }} degrees Celcius outside and the maximum temperature will be {{ states.sensor.forecastio_daily_high_temperature.state | round(0) }}. There's a {{ states.sensor.forecastio_precip_probability.state | round(0) }}% chance of rain today. 148 | {% if states('sensor.forecastio_precip_probability') | int > 50 %} 149 | Don't forget to bring your favorite umbrella! Have a nice (and rainy) day ! 150 | {% else %} 151 | Have a nice day! 152 | {% endif %} 153 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_3b.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch off the lamp 5 progressively (3b)' 2 | trigger: 3 | platform: state 4 | entity_id: binary_sensor.occupancy 5 | from: 'off' 6 | to: 'on' 7 | condition: 8 | condition: time 9 | after: '20:00:00' 10 | before: '07:00:00' 11 | action: 12 | - service: light.turn_off 13 | # minute 0 to 1 14 | - service: light.turn_on 15 | data: 16 | entity_id: light.lamp_5 17 | brightness: 255 18 | rgb_color: [255, 255, 255] 19 | - delay: 20 | minutes: 1 21 | # minute 1 to 2 22 | - service: light.turn_on 23 | data: 24 | entity_id: light.lamp_5 25 | brightness: 240 26 | rgb_color: [255, 255, 255] 27 | - delay: 28 | minutes: 1 29 | # minute 2 to 3 30 | - service: light.turn_on 31 | data: 32 | entity_id: light.lamp_5 33 | brightness: 225 34 | rgb_color: [255, 255, 0] 35 | - delay: 36 | minutes: 1 37 | # minute 3 to 4 38 | - service: light.turn_on 39 | data: 40 | entity_id: light.lamp_5 41 | brightness: 210 42 | rgb_color: [255, 255, 51] 43 | - delay: 44 | minutes: 1 45 | # minute 4 to 5 46 | - service: light.turn_on 47 | data: 48 | entity_id: light.lamp_5 49 | brightness: 195 50 | rgb_color: [255, 255, 102] 51 | - delay: 52 | minutes: 1 53 | # minute 5 to 6 54 | - service: light.turn_on 55 | data: 56 | entity_id: light.lamp_5 57 | brightness: 180 58 | rgb_color: [255, 255, 153] 59 | - delay: 60 | minutes: 1 61 | # minute 6 to 7 62 | - service: light.turn_on 63 | data: 64 | entity_id: light.lamp_5 65 | brightness: 165 66 | rgb_color: [255, 255, 204] 67 | - delay: 68 | minutes: 1 69 | # minute 7 to 8 70 | - service: light.turn_on 71 | data: 72 | entity_id: light.lamp_5 73 | brightness: 150 74 | rgb_color: [255, 229, 204] 75 | - delay: 76 | minutes: 1 77 | # minute 8 to 9 78 | - service: light.turn_on 79 | data: 80 | entity_id: light.lamp_5 81 | brightness: 135 82 | rgb_color: [255, 204, 153] 83 | - delay: 84 | minutes: 1 85 | # minute 9 to 10 86 | - service: light.turn_on 87 | data: 88 | entity_id: light.lamp_5 89 | brightness: 120 90 | rgb_color: [255, 178, 102] 91 | - delay: 92 | minutes: 1 93 | # minute 10 to 11 94 | - service: light.turn_on 95 | data: 96 | entity_id: light.lamp_5 97 | brightness: 105 98 | rgb_color: [255, 153, 51] 99 | - delay: 100 | minutes: 1 101 | # minute 11 to 12 102 | - service: light.turn_on 103 | data: 104 | entity_id: light.lamp_5 105 | brightness: 90 106 | rgb_color: [255, 128, 0] 107 | - delay: 108 | minutes: 1 109 | # minute 12 to 13 110 | - service: light.turn_on 111 | data: 112 | entity_id: light.lamp_5 113 | brightness: 75 114 | rgb_color: [255, 102, 102] 115 | - delay: 116 | minutes: 1 117 | # minute 13 to 14 118 | - service: light.turn_on 119 | data: 120 | entity_id: light.lamp_5 121 | brightness: 60 122 | rgb_color: [255, 51, 51] 123 | - delay: 124 | minutes: 1 125 | # minute 14 to 15 126 | - service: light.turn_on 127 | data: 128 | entity_id: light.lamp_5 129 | brightness: 45 130 | rgb_color: [255, 0, 0] # red 131 | - delay: 132 | minutes: 1 133 | - service: light.turn_off 134 | # set the light 5 into its initial state (withe, brightness 100%) 135 | - service: mqtt.publish 136 | data: 137 | topic: 'bedroom/light1/color/set' 138 | payload: '255,255,255' 139 | - service: mqtt.publish 140 | data: 141 | topic: 'bedroom/light1/brightness/set' 142 | payload: '255' 143 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_3c.yaml: -------------------------------------------------------------------------------- 1 | alias: 'Switch on the lamp 5 when the person get out of its bed (3c)' 2 | trigger: 3 | platform: state 4 | entity_id: binary_sensor.occupancy 5 | from: 'on' 6 | to: 'off' 7 | condition: 8 | condition: time 9 | after: '20:00:00' 10 | before: '07:00:00' 11 | action: 12 | service: light.turn_on 13 | data: 14 | entity_id: light.lamp_5 15 | brightness: 64 16 | rgb_color: [255, 255, 255] 17 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/automation/automation_4a.yaml: -------------------------------------------------------------------------------- 1 | alias: Simulate presence (4a)' 2 | trigger: 3 | - platform: state 4 | entity_id: group.all_devices 5 | from: 'home' 6 | to: 'not_home' 7 | - platform: sun 8 | event: sunset 9 | - platform: event 10 | event_type: event_simulate_presence 11 | condition: 12 | condition: and 13 | conditions: 14 | - condition: state 15 | entity_id: 'sun.sun' 16 | state: 'below_horizon' 17 | - condition: time 18 | before: '23:01:00' 19 | - condition: state 20 | entity_id: group.all_devices 21 | state: 'not_home' 22 | action: 23 | # https://home-assistant.io/cookbook/perform_actions_based_on_input_select/ 24 | # https://home-assistant.io/getting-started/scripts/ 25 | - service: light.turn_on 26 | data_template: 27 | entity_id: > 28 | light.lamp_{{ (range(1, 6) | random) }} 29 | # wait some seconds (will be in reality in minutes) 30 | - delay: '00:{{ (range(2, 10) | random) }}:00' 31 | # turn off all devices 32 | - service: light.turn_off 33 | # wait a little bit before turning on another lamp 34 | - delay: '00:00:{{ (range(1, 5) | random) }}' 35 | # generate an event to call again this automation rule 36 | - event: event_simulate_presence 37 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/binary_sensors.yaml: -------------------------------------------------------------------------------- 1 | - platform: mqtt 2 | name: 'Motion' 3 | state_topic: 'entrance/door/motion/status' 4 | sensor_class: motion 5 | - platform: mqtt 6 | name: 'Occupancy' 7 | state_topic: 'bedroom/bed/occupancy/status' 8 | sensor_class: occupancy 9 | - platform: mqtt 10 | name: 'TV' 11 | state_topic: 'livingroom/tv/status' 12 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/configuration.yaml: -------------------------------------------------------------------------------- 1 | homeassistant: 2 | # Name of the location where Home Assistant is running 3 | name: Home 4 | # Location required to calculate the time the sun rises and sets 5 | latitude: [REDACTED] 6 | longitude: [REDACTED] 7 | # Impacts weather/sunrise data 8 | elevation: [REDACTED] 9 | # metric for Metric, imperial for Imperial 10 | unit_system: metric 11 | # Pick yours from here: http://en.wikipedia.org/wiki/List_of_tz_database_time_zones 12 | time_zone: Europe/Zurich 13 | customize: !include customize.yaml 14 | 15 | # Show links to resources in log and frontend 16 | # introduction: 17 | 18 | # Enables the frontend 19 | frontend: 20 | 21 | http: 22 | api_password: '[REDACTED]' 23 | ssl_certificate: '/etc/letsencrypt/live/[REDACTED]/fullchain.pem' 24 | ssl_key: '/etc/letsencrypt/live/[REDACTED]/privkey.pem' 25 | 26 | # Checks for available updates 27 | updater: 28 | 29 | # Discover some devices automatically 30 | discovery: 31 | 32 | # Allows you to issue voice commands from the frontend in enabled browsers 33 | conversation: 34 | 35 | # Enables support for tracking state changes over time. 36 | history: 37 | 38 | # View all events in a logbook 39 | logbook: 40 | 41 | # Track the sun 42 | sun: 43 | 44 | 45 | mqtt: 46 | broker: 'localhost' #127.0.0.1 47 | port: 8883 #1883 48 | client_id: 'ha' 49 | username: 'ha' 50 | password: '[REDACTED]' 51 | certificate: '/etc/mosquitto/certs/ca.crt' 52 | discovery: true # optional 53 | discovery_prefix: homeassistant # optional 54 | 55 | light: !include lights.yaml 56 | sensor: !include sensors.yaml 57 | binary_sensor: !include binary_sensors.yaml 58 | group: !include groups.yaml 59 | automation: !include automation.yaml 60 | input_number: !include input_sliders.yaml 61 | 62 | input_boolean: 63 | alarm_clock_status: 64 | initial: on 65 | 66 | notify: 67 | platform: telegram 68 | api_key: [REDACTED] 69 | chat_id: [REDACTED] 70 | 71 | device_tracker: 72 | platform: owntracks 73 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/customize.yaml: -------------------------------------------------------------------------------- 1 | # lights 2 | light.lamp_1: 3 | friendly_name: 'Exterior Lamp' 4 | light.lamp_2: 5 | friendly_name: 'Interior Lamp' 6 | light.lamp_3: 7 | friendly_name: 'Cosy Lamp' 8 | light.lamp_4: 9 | friendly_name: 'Ceiling Lamp' 10 | light.lamp_5: 11 | friendly_name: 'Bedside Lamp' 12 | light.lamp_6: 13 | friendly_name: 'Principal Lamp' 14 | 15 | # binary sensors 16 | # icon: https://materialdesignicons.com 17 | binary_sensor.occupancy: 18 | friendly_name: 'Bed Occupancy' 19 | icon: mdi:hotel 20 | binary_sensor.tv: 21 | friendly_name: 'Television' 22 | device_tracker.samuel_phone: 23 | friendly_name: 'Samuel' 24 | 25 | sun.sun: 26 | hidden: true 27 | 28 | # Forecast.io 29 | sensor.forecastio_cloud_coverage: 30 | hidden: true 31 | sensor.forecastio_daily_high_temperature: 32 | hidden: true 33 | sensor.forecastio_daily_max_precip_intensity: 34 | hidden: true 35 | sensor.forecastio_humidity: 36 | friendly_name: 'Humidity' 37 | icon: mdi:weather-rainy 38 | sensor.forecastio_precip_probability: 39 | hidden: true 40 | sensor.forecastio_pressure: 41 | friendly_name: 'Pressure' 42 | icon: mdi:nature 43 | sensor.forecastio_temperature: 44 | friendly_name: 'Temperature' 45 | icon: mdi:thermometer 46 | sensor.forecastio_wind_speed: 47 | hidden: true 48 | 49 | # alarm clock 50 | input_slider.alarm_clock_hour: 51 | friendly_name: 'Hour' 52 | icon: mdi:timer 53 | input_slider.alarm_clock_minute: 54 | friendly_name: 'Minute' 55 | icon: mdi:timer 56 | input_boolean.alarm_clock_status: 57 | friendly_name: 'Alarm Clock Status (Week only)' 58 | icon: mdi:alarm-check 59 | sensor.alarm_clock_hour: 60 | hidden: true 61 | sensor.alarm_clock_minute: 62 | hidden: true 63 | sensor.alarm_clock_time: 64 | friendly_name: 'Alarm Clock Setting' 65 | icon: mdi:alarm 66 | 67 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/groups.yaml: -------------------------------------------------------------------------------- 1 | default_view: 2 | view: yes 3 | entities: 4 | - group.weather 5 | - group.occupancy 6 | - group.entrance 7 | - group.livingroom 8 | - group.bedroom 9 | - group.alarm_clock 10 | 11 | weather: 12 | name: 'Weather' 13 | entities: 14 | - sensor.forecastio_temperature 15 | - sensor.forecastio_humidity 16 | - sensor.forecastio_pressure 17 | 18 | occupancy: 19 | name: 'Occupancy' 20 | entities: 21 | - device_tracker.samuel_phone 22 | 23 | entrance: 24 | name: 'Entrance' 25 | entities: 26 | - binary_sensor.motion 27 | - light.lamp_1 28 | - light.lamp_2 29 | 30 | livingroom: 31 | name: 'Living room' 32 | entities: 33 | - binary_sensor.tv 34 | - light.lamp_3 35 | - light.lamp_4 36 | 37 | bedroom: 38 | name: 'Bedroom' 39 | entities: 40 | - binary_sensor.occupancy 41 | - light.lamp_5 42 | - light.lamp_6 43 | 44 | alarm_clock: 45 | name: 'Alarm Clock' 46 | entities: 47 | - sensor.alarm_clock_time 48 | - input_slider.alarm_clock_hour 49 | - input_slider.alarm_clock_minute 50 | - input_boolean.alarm_clock_status 51 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/input_numbers.yaml: -------------------------------------------------------------------------------- 1 | alarm_clock_hour: 2 | min: 0 3 | max: 23 4 | step: 1 5 | mode: slider 6 | 7 | alarm_clock_minute: 8 | min: 0 9 | max: 55 10 | step: 5 11 | mode: slider 12 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/known_devices.yaml: -------------------------------------------------------------------------------- 1 | 2 | samuel_phone: 3 | name: Samuel 4 | mac: 5 | picture: 6 | track: yes 7 | hide_if_away: no 8 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/lights.yaml: -------------------------------------------------------------------------------- 1 | # lamp 1 2 | - platform: mqtt 3 | name: 'Lamp 1' 4 | state_topic: 'entrance/light1/status' 5 | command_topic: 'entrance/light1/switch' 6 | optimistic: false 7 | # lamp 2 8 | - platform: mqtt 9 | name: 'Lamp 2' 10 | state_topic: 'entrance/light2/status' 11 | command_topic: 'entrance/light2/switch' 12 | optimistic: false 13 | # lamp 3 (RGB) 14 | - platform: mqtt 15 | name: 'Lamp 3' 16 | state_topic: 'livingroom/light1/status' 17 | command_topic: 'livingroom/light1/switch' 18 | brightness_state_topic: 'livingroom/light1/brightness/status' 19 | brightness_command_topic: 'livingroom/light1/brightness/set' 20 | rgb_state_topic: 'livingroom/light1/color/status' 21 | rgb_command_topic: 'livingroom/light1/color/set' 22 | optimistic: false 23 | # lamp 4 24 | - platform: mqtt 25 | name: 'Lamp 4' 26 | state_topic: 'livingroom/light2/status' 27 | command_topic: 'livingroom/light2/switch' 28 | optimistic: false 29 | # lamp 5 (RGB) 30 | - platform: mqtt 31 | name: 'Lamp 5' 32 | state_topic: 'bedroom/light1/status' 33 | command_topic: 'bedroom/light1/switch' 34 | brightness_state_topic: 'bedroom/light1/brightness/status' 35 | brightness_command_topic: 'bedroom/light1/brightness/set' 36 | rgb_state_topic: 'bedroom/light1/color/status' 37 | rgb_command_topic: 'bedroom/light1/color/set' 38 | optimistic: false 39 | # lamp 6 40 | - platform: mqtt 41 | name: 'Lamp 6' 42 | state_topic: 'bedroom/light2/status' 43 | command_topic: 'bedroom/light2/switch' 44 | optimistic: false 45 | -------------------------------------------------------------------------------- /openhome/configuration/home_assistant/sensors.yaml: -------------------------------------------------------------------------------- 1 | - platform: forecast 2 | api_key: [Redacted] 3 | monitored_conditions: 4 | - precip_probability 5 | - temperature 6 | - wind_speed 7 | - cloud_cover 8 | - humidity 9 | - pressure 10 | - temperature_max 11 | - precip_intensity_max 12 | 13 | - platform: template 14 | sensors: 15 | alarm_clock_hour: 16 | value_template: '{{ states("input_number.alarm_clock_hour") | round(0) }}' 17 | alarm_clock_minute: 18 | value_template: '{{ states("input_number.alarm_clock_minute") | round(0) }}' 19 | alarm_clock_time: 20 | value_template: '{{ states("sensor.alarm_clock_hour") }}:{% if states("sensor.alarm_clock_minute")|length == 1 %}0{% endif %}{{ states("sensor.alarm_clock_minute") }}' 21 | -------------------------------------------------------------------------------- /openhome/configuration/mosquitto/aclfile: -------------------------------------------------------------------------------- 1 | user ha 2 | topic write entrance/light1/switch 3 | topic write entrance/light2/switch 4 | 5 | topic write livingroom/light1/switch 6 | topic write livingroom/light1/brightness/set 7 | topic write livingroom/light1/color/set 8 | topic write livingroom/light2/switch 9 | 10 | topic write bedroom/light1/switch 11 | topic write bedroom/light1/brightness/set 12 | topic write bedroom/light1/color/set 13 | topic write bedroom/light2/switch 14 | 15 | topic read entrance/light1/status 16 | topic read entrance/light2/status 17 | topic read entrance/door/motion/status 18 | topic read owntracks/samuel/phone 19 | topic read owntracks/samuel/phone/event 20 | 21 | topic read livingroom/light1/status 22 | topic read livingroom/light1/brightness/status 23 | topic read livingroom/light1/color/status 24 | topic read livingroom/light2/status 25 | topic read livingroom/tv/status 26 | 27 | topic read bedroom/light1/status 28 | topic read bedroom/light1/brightness/status 29 | topic read bedroom/light1/color/status 30 | topic read bedroom/light2/status 31 | topic read bedroom/bed/occupancy/status 32 | 33 | 34 | user entrance 35 | topic write entrance/light1/status 36 | topic write entrance/light2/status 37 | topic write entrance/door/motion/status 38 | 39 | topic read entrance/light1/switch 40 | topic read entrance/light2/switch 41 | 42 | 43 | user livingroom 44 | topic write livingroom/light1/status 45 | topic write livingroom/light1/brightness/status 46 | topic write livingroom/light1/color/status 47 | topic write livingroom/light2/status 48 | topic write livingroom/tv/status 49 | 50 | topic read livingroom/light1/switch 51 | topic read livingroom/light1/brightness/set 52 | topic read livingroom/light1/color/set 53 | topic read livingroom/light2/switch 54 | 55 | 56 | user bedroom 57 | topic write bedroom/light1/status 58 | topic write bedroom/light1/brightness/status 59 | topic write bedroom/light1/color/status 60 | topic write bedroom/light2/status 61 | topic write bedroom/bed/occupancy/status 62 | 63 | topic read bedroom/light1/switch 64 | topic read bedroom/light1/brightness/set 65 | topic read bedroom/light1/color/set 66 | topic read bedroom/light2/switch 67 | 68 | 69 | user samuel 70 | topic write owntracks/samuel/phone 71 | topic write owntracks/samuel/phone/event 72 | -------------------------------------------------------------------------------- /openhome/configuration/mosquitto/mosquitto.conf: -------------------------------------------------------------------------------- 1 | # ----------------------------------------------------------------- 2 | # Certificate based SSL/TLS support 3 | # ----------------------------------------------------------------- 4 | # The following options can be used to enable SSL/TLS support for 5 | # this listener. Note that the recommended port for MQTT over TLS 6 | # is 8883, but this must be set manually. 7 | # 8 | # See also the mosquitto-tls man page. 9 | #listener 1883 10 | listener 8883 11 | 12 | # At least one of cafile or capath must be defined. They both 13 | # define methods of accessing the PEM encoded Certificate 14 | # Authority certificates that have signed your server certificate 15 | # and that you wish to trust. 16 | # cafile defines the path to a file containing the CA certificates. 17 | # capath defines a directory that will be searched for files 18 | # containing the CA certificates. For capath to work correctly, the 19 | # certificate files must have ".crt" as the file ending and you must run 20 | # "c_rehash " each time you add/remove a certificate. 21 | #cafile 22 | #capath 23 | cafile /etc/mosquitto/certs/ca.crt 24 | 25 | # Path to the PEM encoded server certificate. 26 | #certfile 27 | certfile /etc/mosquitto/certs/raspberrypi.crt 28 | 29 | # Path to the PEM encoded keyfile. 30 | #keyfile 31 | keyfile /etc/mosquitto/certs/raspberrypi.key 32 | 33 | # ================================================================= 34 | # Security 35 | # ================================================================= 36 | 37 | # Boolean value that determines whether clients that connect 38 | # without providing a username are allowed to connect. If set to 39 | # false then a password file should be created (see the 40 | # password_file option) to control authenticated client access. 41 | # Defaults to true. 42 | allow_anonymous false 43 | 44 | # ----------------------------------------------------------------- 45 | # Default authentication and topic access control 46 | # ----------------------------------------------------------------- 47 | 48 | # Control access to the broker using a password file. This file can be 49 | # generated using the mosquitto_passwd utility. If TLS support is not compiled 50 | # into mosquitto (it is recommended that TLS support should be included) then 51 | # plain text passwords are used, in which case the file should be a text file 52 | # with lines in the format: 53 | # username:password 54 | # The password (and colon) may be omitted if desired, although this 55 | # offers very little in the way of security. 56 | # 57 | # See the TLS client require_certificate and use_identity_as_username options 58 | # for alternative authentication options. 59 | password_file /etc/mosquitto/conf.d/pwfile 60 | 61 | # Control access to topics on the broker using an access control list 62 | # file. If this parameter is defined then only the topics listed will 63 | # have access. 64 | # If the first character of a line of the ACL file is a # it is treated as a 65 | # comment. 66 | # Topic access is added with lines of the format: 67 | # 68 | # topic [read|write|readwrite] 69 | # 70 | # The access type is controlled using "read", "write" or "readwrite". This 71 | # parameter is optional (unless contains a space character) - if not 72 | # given then the access is read/write. can contain the + or # 73 | # wildcards as in subscriptions. 74 | # 75 | # The first set of topics are applied to anonymous clients, assuming 76 | # allow_anonymous is true. User specific topic ACLs are added after a 77 | # user line as follows: 78 | # 79 | # user 80 | # 81 | # The username referred to here is the same as in password_file. It is 82 | # not the clientid. 83 | # 84 | # 85 | # If is also possible to define ACLs based on pattern substitution within the 86 | # topic. The patterns available for substition are: 87 | # 88 | # %c to match the client id of the client 89 | # %u to match the username of the client 90 | # 91 | # The substitution pattern must be the only text for that level of hierarchy. 92 | # 93 | # The form is the same as for the topic keyword, but using pattern as the 94 | # keyword. 95 | # Pattern ACLs apply to all users even if the "user" keyword has previously 96 | # been given. 97 | # 98 | # If using bridges with usernames and ACLs, connection messages can be allowed 99 | # with the following pattern: 100 | # pattern write $SYS/broker/connection/%c/state 101 | # 102 | # pattern [read|write|readwrite] 103 | # 104 | # Example: 105 | # 106 | # pattern write sensor/%u/data 107 | # 108 | acl_file /etc/mosquitto/conf.d/aclfile 109 | -------------------------------------------------------------------------------- /openhome/configuration/mosquitto/pwfile: -------------------------------------------------------------------------------- 1 | samuel:$6$HagYska+ZBtV0a2a$RA0pgSHa5g6/NoZqbE5N0UwnV++vmxkgbz5gRd+9J4Vh03PEXqi8XpqnMM9iFJ6QVzH/893VE5E1cI6SVGpung== 2 | ha:$6$kvipp6VVJOrqYesh$NOji6P9/91OroPkJdjLcwGo115b0JWuFcC6NoFlVVf+Fd7p07XrAdpDtstOMtDly9acPE3NqrHLSV8/RHwswLw== 3 | entrance:$6$hxoat1lWtyYxbwwA$DnikUcSz/aIZh12zz0GM0blj2G2EXcv67K4qylmrKCofmahgCQRp7HzkEeqiWsAobu8xic9lynZPOUigDIUtAQ== 4 | livingroom:$6$L6286ehtOInn7J/b$Mxeng6igWWzt7Wb6Y+fo58Yukz09O90Kvu5AwsysNycJIj8ETLV66OGNLkQ8e105D10mR4nMz+DeP8fgPL5jHA== 5 | bedroom:$6$CBpKfzH+97D9j5fM$9zUS/WH/HZBL9WYTUA8XKVkoDnP6q4ObxOILvyPiWiHVFlq03/oNt+TCo1KS62+amN/l5AhJOpSaUY2yi3BedA== 6 | -------------------------------------------------------------------------------- /openhome/images/Architecture_MQTT.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/images/Architecture_MQTT.png -------------------------------------------------------------------------------- /openhome/images/Architecture_Network.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/images/Architecture_Network.png -------------------------------------------------------------------------------- /openhome/images/Features.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/images/Features.png -------------------------------------------------------------------------------- /openhome/images/Home.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/images/Home.png -------------------------------------------------------------------------------- /openhome/images/Owntracks.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/images/Owntracks.png -------------------------------------------------------------------------------- /openhome/images/Youtube.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/images/Youtube.png -------------------------------------------------------------------------------- /openhome/sketches/Bedroom/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/sketches/Bedroom/Schematic.png -------------------------------------------------------------------------------- /openhome/sketches/Entrance/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/sketches/Entrance/Schematic.png -------------------------------------------------------------------------------- /openhome/sketches/Livingroom/Schematic.png: -------------------------------------------------------------------------------- https://raw.githubusercontent.com/SamZorSec/Open-Home-Automation/a751db9c6a02a49610a81d03776399390dfbee9b/openhome/sketches/Livingroom/Schematic.png --------------------------------------------------------------------------------