├── LICENSE ├── README.md ├── boot.py ├── config.py ├── main.py ├── upload.mpf └── upload.sh /LICENSE: -------------------------------------------------------------------------------- 1 | MIT License 2 | 3 | Copyright (c) 2018 Zack Lalanne 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. -------------------------------------------------------------------------------- /README.md: -------------------------------------------------------------------------------- 1 | # MicroPython MQTT Home Assistant Switch 2 | 3 | Quick demo of using an ESP8266 with Home Assistant as a switch 4 | communicating over MQTT. Developed using MicroPython. 5 | 6 | Read the full blog post [here](https://selfhostedhome.com/creating-a-diy-home-assistant-switch-using-micropython/). 7 | -------------------------------------------------------------------------------- /boot.py: -------------------------------------------------------------------------------- 1 | # This file is executed on every boot (including wake-boot from deepsleep) 2 | #import esp 3 | #esp.osdebug(None) 4 | import gc 5 | import webrepl 6 | import network 7 | from config import ESSID, PASSWORD 8 | 9 | webrepl.start() 10 | gc.collect() 11 | 12 | 13 | def connect(): 14 | sta_if = network.WLAN(network.STA_IF) 15 | if not sta_if.isconnected(): 16 | print('Connecting to network...') 17 | sta_if.active(True) 18 | sta_if.connect(ESSID, PASSWORD) 19 | while not sta_if.isconnected(): 20 | pass 21 | print('Network config:', sta_if.ifconfig()) 22 | 23 | connect() 24 | -------------------------------------------------------------------------------- /config.py: -------------------------------------------------------------------------------- 1 | ESSID = "" 2 | PASSWORD = "" 3 | SERVER = "192.168.1.9" 4 | 5 | COMMAND_TOPIC = "home/office/switch1/set" 6 | STATE_TOPIC = "home/office/switch1" 7 | AVAILABILITY_TOPIC = "home/office/switch1/available" 8 | -------------------------------------------------------------------------------- /main.py: -------------------------------------------------------------------------------- 1 | from umqtt.simple import MQTTClient 2 | import machine 3 | import utime 4 | import ubinascii 5 | 6 | from config import SERVER, COMMAND_TOPIC, STATE_TOPIC, AVAILABILITY_TOPIC 7 | 8 | LED = machine.Pin(2, machine.Pin.OUT, value=1) 9 | 10 | CLIENT = None 11 | CLIENT_ID = ubinascii.hexlify(machine.unique_id()) 12 | 13 | 14 | def new_msg(topic, msg): 15 | 16 | print("Received {}".format(msg)) 17 | 18 | if msg == b"on": 19 | LED.value(0) 20 | CLIENT.publish(STATE_TOPIC, "on") 21 | elif msg == b"off": 22 | LED.value(1) 23 | CLIENT.publish(STATE_TOPIC, "off") 24 | 25 | 26 | def main(): 27 | global CLIENT 28 | CLIENT = MQTTClient(CLIENT_ID, SERVER) 29 | CLIENT.set_callback(new_msg) 30 | CLIENT.connect() 31 | 32 | CLIENT.subscribe(COMMAND_TOPIC) 33 | 34 | # Publish as available once connected 35 | CLIENT.publish(AVAILABILITY_TOPIC, "online") 36 | 37 | print("Connected to {}, subscribed to {} topic".format(SERVER, COMMAND_TOPIC)) 38 | 39 | try: 40 | while 1: 41 | CLIENT.wait_msg() 42 | finally: 43 | CLIENT.publish(AVAILABILITY_TOPIC, "offline") 44 | CLIENT.disconnect() 45 | 46 | main() 47 | -------------------------------------------------------------------------------- /upload.mpf: -------------------------------------------------------------------------------- 1 | open ttyUSB0 2 | put boot.py 3 | put config.py 4 | put main.py 5 | ls 6 | -------------------------------------------------------------------------------- /upload.sh: -------------------------------------------------------------------------------- 1 | #!/usr/bin/env bash 2 | 3 | mpfshell -s upload.mpf 4 | --------------------------------------------------------------------------------