Skip to content

Development version is now master branch #1

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 6 commits into from
Mar 29, 2018
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -99,3 +99,5 @@ ENV/

# mypy
.mypy_cache/
/.project
/.pydevproject
4 changes: 2 additions & 2 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -37,7 +37,7 @@ Its main drawback is code size. Run as frozen bytecode it uses about 50% of the
RAM on the ESP8266. On ESP32 it runs as a standard Python module with 64K of
RAM free.

It is documented [here](./mqtt_as/README.md).
It is documented [here](./README_mqtt_as.md).

## 2. MQTT for generic MicroPython targets

Expand All @@ -49,4 +49,4 @@ five GPIO pins accessible via the `machine` library should suffice.

The driver is non-blocking and is designed for applications using uasyncio.

It is documented [here](./NO_NET.md).
It is documented [here](./remote_mqtt/NO_NET.md).
70 changes: 45 additions & 25 deletions mqtt_as/README.md → README_mqtt_as.md
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,7 @@ but duplication can occur. Level 2 avoids duplication; it is unsuported by the
official driver and by this module. Duplicates can readily be handled at the
application level.

###### [Main README](../README.md)
###### [Main README](./README.md)

## 1.1 Rationale

Expand Down Expand Up @@ -73,19 +73,26 @@ experience. Feedback on this issue would be very welcome.

The module is too large to compile on the ESP8266 and should be precompiled or
preferably frozen as bytecode.
To save about 150-250 Bytes on the ESP8266 there is a minimal version `mqtt_as_minimal.py`
that works exactly like the full version but has all code not related to ESP8266 removed
as well as some functions that are not commonly used.

## 1.5 ESP32 issues

This platform has issues. During WiFi and broker connection and reconnection it
has proved necessary to issue `utime.sleep_ms(20)`. After sending data to the
socket a delay of 20ms also proved necessary to prevent a timeout occurring
while waiting for a response (without the delay, the incoming data is never
recognised). These delays block the scheduler.
When using the official port of the ESP32 this platform has issues.
During WiFi and broker connection and reconnection it has proved necessary
to issue `utime.sleep_ms(20)`. After sending data to the socket a delay
of 20ms also proved necessary to prevent a timeout occurring while waiting
for a response (without the delay, the incoming data is never recognised).
These delays block the scheduler.

It recovers from outages but this hasn't been tested as thoroughly as on the
ESP8266. The board must be power cycled between runs of an application. Issues
have been raised.

The [loboris fork](https://github.com/loboris/MicroPython_ESP32_psRAM_LoBo)
does not suffer from these problems.

Currently (5th Sept 2017) DNS lookups don't work (`usocket.getaddrinfo()`).
Hence broker addresses must be numeric IP's.

Expand All @@ -96,26 +103,36 @@ The module works without recourse to cross compilation or frozen bytecode.
## 2.1 Program files

1. `mqtt_as.py` The main module.
2. `config.py` Stores cross-project settings.
3. `clean.py` Test/demo program using MQTT Clean Session.
4. `unclean.py` Test/demo program with MQTT Clean Session `False`.
5. `range.py` For WiFi range testing.
6. `pubtest` Bash script illustrating publication with Mosquitto.
7. `main.py` Example for auto-starting an application.
8. `ssl.py` Failed attempt to run with SSL. See note above (1.3).
2. `mqtt_as_minimal.py` The main module cut down for the ESP8266 to save RAM
3. `config.py` Stores cross-project settings.
4. `tests` Folder containing test files for mqtt_as
1. `clean.py` Test/demo program using MQTT Clean Session.
2. `unclean.py` Test/demo program with MQTT Clean Session `False`.
3. `range.py` For WiFi range testing.
4. `pubtest` Bash script illustrating publication with Mosquitto.
5. `main.py` Example for auto-starting an application.
6. `ssl.py` Failed attempt to run with SSL. See note above (1.3).
5. `remote_mqtt` Folder containing all files of mqtt for platforms without WIFI and tests
6. `sonoff` Folder containing test files for sonoff devices


## 2.2 Installation

The only dependency is uasyncio from the [MicroPython library](https://github.com/micropython/micropython-lib).
Ensure this is installed on the device.

The module is too large to compile on the ESP8266. It must either be cross
compiled or (preferably) built as frozen bytecode: copy `mqtt_as.py` to
`esp8266/modules` in the source tree, build and deploy. Copy `config.py` to the
filesystem for convenience.
compiled or (preferably) built as frozen bytecode: copy the repo to
`esp8266/modules` in the source tree, build and deploy. If your firmware
gets too big, remove all unnecessary files of just copy the ones you need.
Minimal requirements:
- directory `micropython_mqtt_as` with these files in it:
- `__init__.py` to make it a package
- `mqtt_as.py` or `mqtt_as_minimal.py`
- `config.py` for convenience, optional

On the ESP32 simply copy the Python source to the filesystem (items 1 and 2
above as a minimum).

On the ESP32 simply copy the above listed directory structure to the filesystem.

## 2.3 Example Usage

Expand All @@ -128,8 +145,8 @@ the network if it has to reconnect). The ESP32 behaves differently and requires
WiFi config data. Edit `config.py` to suit.

```python
from mqtt_as import MQTTClient
from config import config
from micropython_mqtt_as.mqtt_as import MQTTClient
from micropython_mqtt_as.config import config
import uasyncio as asyncio

SERVER = '192.168.0.9' # Change to suit e.g. 'iot.eclipse.org'
Expand All @@ -155,7 +172,7 @@ config['connect_coro'] = conn_han
config['server'] = SERVER

MQTTClient.DEBUG = True # Optional: print diagnostic messages
client = MQTTClient(config)
client = MQTTClient(**config)
loop = asyncio.get_event_loop()
try:
loop.run_until_complete(main(client))
Expand All @@ -176,9 +193,12 @@ this.

## 3.1 Constructor

This takes a dictionary as argument. The default is `mqtt_as.config`. Normally
an application imports this and modifies selected entries as required. Entries
are:
This takes all keywords found in the dictionary in `config.py` as argument.
As a convenience you can also use this dictionary by importing it and changing
the values. You then call the constructor by `MQTTClient(**config)`, this
automatically matches the contents of the dict to the keywords of the constructor.

Entries of config dictionary are:

**WiFi Parameters**

Expand Down Expand Up @@ -322,7 +342,7 @@ connectivity has been lost if no messages have been received in that period.
The module attempts to keep the connection open by issuing an MQTT ping upto
four times during the keepalive interval. (It pings if the last response from
the broker was over 1/4 of the keepalive period). More frequent pings may be
desirable to educe latency in subscribe-only applications. This may be achieved
desirable to reduce latency in subscribe-only applications. This may be achieved
using the `ping_interval` configuration option.

If the broker times out it will issue the "last will" publication (if any).
Expand Down
Empty file added __init__.py
Empty file.
29 changes: 29 additions & 0 deletions config.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
from sys import platform

# Include any cross-project settings.

config = {
'client_id': hexlify(unique_id()),
'server': None,
'port': 0,
'user': '',
'password': '',
'keepalive': 60,
'ping_interval': 0,
'ssl': False,
'ssl_params': {},
'response_time': 10,
'clean_init': True,
'clean': True,
'max_repubs': 4,
'will': None,
'subs_cb': lambda *_: None,
'wifi_coro': eliza,
'connect_coro': eliza,
'ssid': None,
'wifi_pw': None,
}

if platform == 'esp32':
config['ssid'] = 'my SSID' # EDIT if you're using ESP32
config['wifi_pw'] = 'my WiFi password'
Loading