294 lines
13 KiB
XML
294 lines
13 KiB
XML
<?xml version="1.0" encoding="utf-8"?>
|
|
<feed xmlns="http://www.w3.org/2005/Atom">
|
|
|
|
<title><![CDATA[Category: Micropython | Home Assistant]]></title>
|
|
<link href="https://home-assistant.io/blog/categories/micropython/atom.xml" rel="self"/>
|
|
<link href="https://home-assistant.io/"/>
|
|
<updated>2017-07-20T15:38:20+00:00</updated>
|
|
<id>https://home-assistant.io/</id>
|
|
<author>
|
|
<name><![CDATA[Home Assistant]]></name>
|
|
|
|
</author>
|
|
<generator uri="http://octopress.org/">Octopress</generator>
|
|
|
|
|
|
<entry>
|
|
<title type="html"><![CDATA[Grazer Linuxtage 2017: Python Everywhere]]></title>
|
|
<link href="https://home-assistant.io/blog/2017/05/07/grazer-linuxtage-2017-talk-python-everywhere/"/>
|
|
<updated>2017-05-07T02:00:00+00:00</updated>
|
|
<id>https://home-assistant.io/blog/2017/05/07/grazer-linuxtage-2017-talk-python-everywhere</id>
|
|
<content type="html"><![CDATA[I like Python. It's a clean easy to read, easy to learn language. Yet when you use it for some time you still find more features to improve your coding. What I probably like most about Python is the community and the great libraries that already exist. Often solving a problem means including a pre-existing library and writing some glue code. That makes it quick to get things up and running.
|
|
|
|
I just gave a talk on how you can run Python to automate your home (yes with Home-Assistant) but also with [MicroPython]. Micropython allows you to run Python on your DIY sensors and switches around your home. Python everywhere - even on the chips that give Home-Assistant the data to be awesome.
|
|
|
|
<div class='videoWrapper'>
|
|
<iframe width="560" height="315" src="https://www.youtube.com/embed/KNFZSSCPUyM" frameborder="0" allowfullscreen></iframe>
|
|
</div>
|
|
|
|
[MicroPython]: https://micropython.org
|
|
]]></content>
|
|
</entry>
|
|
|
|
<entry>
|
|
<title type="html"><![CDATA[ESP8266 and MicroPython - Part 2]]></title>
|
|
<link href="https://home-assistant.io/blog/2016/08/31/esp8266-and-micropython-part2/"/>
|
|
<updated>2016-08-31T04:17:25+00:00</updated>
|
|
<id>https://home-assistant.io/blog/2016/08/31/esp8266-and-micropython-part2</id>
|
|
<content type="html">< was pretty lame, right? Instead of getting information out of Home Assistant we are going a step forward and create our own sensor which is sending details about its state to a Home Assistant instance.
|
|
|
|
<!--more-->
|
|
|
|
Beside [HTTP POST](https://en.wikipedia.org/wiki/POST_(HTTP)) requests, MQTT is the quickest way (from the author's point of view) to publish information with DIY devices.
|
|
|
|
You have to make a decision: Do you want to pull or to [poll](https://en.wikipedia.org/wiki/Polling_(computer_science)) the information for the sensor? For slowly changing values like temperature it's perfectly fine to wait a couple of seconds to retrieve the value. If it's a motion detector the state change should be available instantly in Home Assistant or it could be missed. This means the sensor must take initiative and send the data to Home Assistant.
|
|
|
|
An example for pulling is [aREST](/components/sensor.arest/). This is a great way to work with the ESP8266 based units and the Ardunio IDE.
|
|
|
|
### <a class='title-link' name='mqtt' href='#mqtt'></a> MQTT
|
|
|
|
You can find a simple examples for publishing and subscribing with MQTT in the [MicroPython](https://github.com/micropython/micropython-lib) library overview in the section for [umqtt](https://github.com/micropython/micropython-lib/tree/master/umqtt.simple).
|
|
|
|
The example below is adopted from the work of [@davea](https://github.com/davea) as we don't want to re-invent the wheel. The configuration feature is crafty and simplyfies the code with the usage of a file called `/config.json` which stores the configuration details. The ESP8266 device will send the value of a pin every 5 seconds.
|
|
|
|
|
|
```python
|
|
import machine
|
|
import time
|
|
import ubinascii
|
|
import webrepl
|
|
|
|
from umqtt.simple import MQTTClient
|
|
|
|
# These defaults are overwritten with the contents of /config.json by load_config()
|
|
CONFIG = {
|
|
"broker": "192.168.1.19",
|
|
"sensor_pin": 0,
|
|
"client_id": b"esp8266_" + ubinascii.hexlify(machine.unique_id()),
|
|
"topic": b"home",
|
|
}
|
|
|
|
client = None
|
|
sensor_pin = None
|
|
|
|
def setup_pins():
|
|
global sensor_pin
|
|
sensor_pin = machine.ADC(CONFIG['sensor_pin'])
|
|
|
|
def load_config():
|
|
import ujson as json
|
|
try:
|
|
with open("/config.json") as f:
|
|
config = json.loads(f.read())
|
|
except (OSError, ValueError):
|
|
print("Couldn't load /config.json")
|
|
save_config()
|
|
else:
|
|
CONFIG.update(config)
|
|
print("Loaded config from /config.json")
|
|
|
|
def save_config():
|
|
import ujson as json
|
|
try:
|
|
with open("/config.json", "w") as f:
|
|
f.write(json.dumps(CONFIG))
|
|
except OSError:
|
|
print("Couldn't save /config.json")
|
|
|
|
def main():
|
|
client = MQTTClient(CONFIG['client_id'], CONFIG['broker'])
|
|
client.connect()
|
|
print("Connected to {}".format(CONFIG['broker']))
|
|
while True:
|
|
data = sensor_pin.read()
|
|
client.publish('{}/{}'.format(CONFIG['topic'],
|
|
CONFIG['client_id']),
|
|
bytes(str(data), 'utf-8'))
|
|
print('Sensor state: {}'.format(data))
|
|
time.sleep(5)
|
|
|
|
if __name__ == '__main__':
|
|
load_config()
|
|
setup_pins()
|
|
main()
|
|
```
|
|
|
|
Subscribe to the topic `home/#` or create a [MQTT sensor](/components/sensor.mqtt/) to check if the sensor values are published.
|
|
|
|
```bash
|
|
$ mosquitto_sub -h 192.168.1.19 -v -t "home/#"
|
|
```
|
|
|
|
```yaml
|
|
sensor:
|
|
- platform: mqtt
|
|
state_topic: "home/esp8266_[last part of the MAC address]"
|
|
name: "MicroPython"
|
|
```
|
|
|
|
[@davea](https://github.com/davea) created [sonoff-mqtt](https://github.com/davea/sonoff-mqtt). This code will work on ESP8622 based devices too and shows how to use a button to control a relay.
|
|
|
|
]]></content>
|
|
</entry>
|
|
|
|
<entry>
|
|
<title type="html"><![CDATA[ESP8266 and MicroPython - Part 1]]></title>
|
|
<link href="https://home-assistant.io/blog/2016/07/28/esp8266-and-micropython-part1/"/>
|
|
<updated>2016-07-28T04:00:00+00:00</updated>
|
|
<id>https://home-assistant.io/blog/2016/07/28/esp8266-and-micropython-part1</id>
|
|
<content type="html">< covers a lot of ground. This post is providing only a little summary which should get you started.
|
|
|
|
Until a couple of weeks ago, the pre-built MicroPython binary for the ESP8266 was only available to backers of the Kickstarter campaign. This has changed now and it is available to the public for [download](https://micropython.org/download/#esp8266).
|
|
|
|
<!--more-->
|
|
|
|
The easiest way is to use [esptool.py](https://github.com/themadinventor/esptool) for firmware handling tasks. First erase the flash:
|
|
|
|
```bash
|
|
$ sudo python esptool.py --port /dev/ttyUSB0 erase_flash
|
|
esptool.py v1.0.2-dev
|
|
Connecting...
|
|
Erasing flash (this may take a while)...
|
|
```
|
|
|
|
and then load the firmware. You may adjust the file name of the firmware binary.
|
|
|
|
```bash
|
|
$ sudo python esptool.py --port /dev/ttyUSB0 --baud 460800 write_flash --flash_size=8m 0 esp8266-2016-07-10-v1.8.2.bin
|
|
esptool.py v1.2-dev
|
|
Connecting...
|
|
Running Cesanta flasher stub...
|
|
Flash params set to 0x0020
|
|
Writing 540672 @ 0x0... 540672 (100 %)
|
|
Wrote 540672 bytes at 0x0 in 13.1 seconds (330.8 kbit/s)...
|
|
Leaving...
|
|
```
|
|
|
|
Now reset the device. You should then be able to use the [REPL (Read Evaluate Print Loop)](http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/repl.html#getting-a-micropython-repl-prompt). On Linux there is `minicom` or `picocom`, on a Mac you can use `screen` (eg. `screen /dev/tty.SLAB_USBtoUART 115200`), and on Windows there is Putty to open a serial connection and get the REPL prompt.
|
|
|
|
The [WebREPL](http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/repl.html#webrepl-a-prompt-over-wifi) work over a wireless connection and allows easy access to a prompt in your browser. An instance of the WebREPL client is hosted at [http://micropython.org/webrepl](http://micropython.org/webrepl). Alternatively, you can create a local clone of their [GitHub repository](https://github.com/micropython/webrepl). This is neccessary if your want to use the command-line tool `webrepl_cli.py` which is mentionend later in this post.
|
|
|
|
```bash
|
|
$ sudo minicom -D /dev/ttyUSB0
|
|
#4 ets_task(4020e374, 29, 3fff70e8, 10)
|
|
WebREPL daemon started on ws://192.168.4.1:8266
|
|
Started webrepl in setup mode
|
|
could not open file 'main.py' for reading
|
|
|
|
#5 ets_task(4010035c, 3, 3fff6360, 4)
|
|
MicroPython v1.8.2-9-g805c2b9 on 2016-07-10; ESP module with ESP8266
|
|
Type "help()" for more information.
|
|
>>>
|
|
```
|
|
|
|
<p class='note'>
|
|
The public build of the firmware may be different than the firmware distributed to the backers of the Kickstarter campaign. Especially in regard of the [available modules](http://docs.micropython.org/en/latest/esp8266/py-modindex.html), turned on debug messages, and alike. Also, the WebREPL may not be started by default.
|
|
</p>
|
|
|
|
Connect a LED to pin 5 (or another pin of your choosing) to check if the ESP8266 is working as expected.
|
|
|
|
```python
|
|
>>> import machine
|
|
>>> pin = machine.Pin(5, machine.Pin.OUT)
|
|
>>> pin.high()
|
|
```
|
|
|
|
You can toogle the LED by changing its state with `pin.high()` and `pin.low()`.
|
|
|
|
Various ESP8266 development board are shipped with an onboard photocell or a light dependent resistors (LDR) connected to the analog pin of your ESP8266 check if you are able to obtain a value.
|
|
|
|
```python
|
|
>>> import machine
|
|
>>> brightness = machine.ADC(0)
|
|
>>> brightness.read()
|
|
```
|
|
|
|
Make sure that you are familiar with REPL and WebREPL because this will be needed soon. Keep in mind the password for the WebREPL access.
|
|
|
|
Read the [instructions](http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/network_basics.html) about how to setup your wireless connection. Basically you need to upload a `boot.py` file to the microcontroller and this file is taking care of the connection setup. Below you find a sample which is more or less the same as shown in the [documentation](http://docs.micropython.org/en/latest/esp8266/esp8266/tutorial/network_basics.html#configuration-of-the-wifi).
|
|
|
|
```python
|
|
def do_connect():
|
|
import network
|
|
|
|
SSID = 'SSID'
|
|
PASSWORD = 'PASSWORD'
|
|
|
|
sta_if = network.WLAN(network.STA_IF)
|
|
ap_if = network.WLAN(network.AP_IF)
|
|
if ap_if.active():
|
|
ap_if.active(False)
|
|
if not sta_if.isconnected():
|
|
print('connecting to network...')
|
|
sta_if.active(True)
|
|
sta_if.connect(SSID, PASSWORD)
|
|
while not sta_if.isconnected():
|
|
pass
|
|
print('Network configuration:', sta_if.ifconfig())
|
|
```
|
|
|
|
Upload this file with `webrepl_cli.py` or the WebREPL:
|
|
|
|
```bash
|
|
$ python webrepl_cli.py boot.py 192.168.4.1:/boot.py
|
|
```
|
|
|
|
If you reboot, you should see your current IP address in the terminal.
|
|
|
|
```bash
|
|
>>> Network configuration: ('192.168.0.10', '255.255.255.0', '192.168.0.1', '192.168.0.1')
|
|
```
|
|
|
|
First let's create a little consumer for Home Assistant sensor's state. The code to place in `main.py` is a mixture of code from above and the [RESTful API](/developers/rest_api/) of Home Assistant. If the temperature in the kitchen is higher than 20 °C then the LED connected to pin 5 is switched on.
|
|
|
|
<p class='note'>
|
|
If a module is missing then you need to download it from the [MicroPython Library overview](https://github.com/micropython/micropython-lib) and upload it to the ESP8266 with `webrepl_cli.py` manually.
|
|
</p>
|
|
|
|
```python
|
|
# Sample code to request the state of a Home Assistant entity.
|
|
|
|
API_PASSWORD = 'YOUR_PASSWORD'
|
|
URL = 'http://192.168.0.5:8123/api/states/'
|
|
ENTITY = 'sensor.kitchen_temperature'
|
|
TIMEOUT = 30
|
|
PIN = 5
|
|
|
|
def get_data():
|
|
import urequests
|
|
url = '{}{}'.format(URL, ENTITY)
|
|
headers = {'x-ha-access': API_PASSWORD,
|
|
'content-type': 'application/json'}
|
|
resp = urequests.get(URL, headers=headers)
|
|
return resp.json()['state']
|
|
|
|
def main():
|
|
import machine
|
|
import time
|
|
|
|
pin = machine.Pin(PIN, machine.Pin.OUT)
|
|
while True:
|
|
try:
|
|
if int(get_data()) >= 20:
|
|
pin.high()
|
|
else:
|
|
pin.low()
|
|
except TypeError:
|
|
pass
|
|
time.sleep(TIMEOUT)
|
|
|
|
if __name__ == '__main__':
|
|
print('Get the state of {}'.format(ENTITY))
|
|
main()
|
|
```
|
|
|
|
Upload `main.py` the same way as `boot.py`. After a reboot (`>>> import machine` and `>>> machine.reboot()`) or power-cycling your physical notifier is ready.
|
|
|
|
If you run into trouble, press "Ctrl+c" in the REPL to stop the execution of the code, enter `>>> import webrepl` and `>>> webrepl.start()`, and upload your fixed file.
|
|
|
|
]]></content>
|
|
</entry>
|
|
|
|
</feed>
|