Skip to content

Commit

Permalink
Got websockets working
Browse files Browse the repository at this point in the history
although there is some instability on the MicroPython side
of things and I'm seeing non-reproducible crashes when using
websockets.
  • Loading branch information
dhylands committed May 23, 2018
1 parent 730639d commit 76c74be
Show file tree
Hide file tree
Showing 8 changed files with 434 additions and 264 deletions.
29 changes: 22 additions & 7 deletions README.md
Expand Up @@ -2,9 +2,10 @@

This is a MicroPython version of webthing-python.

This has been tested on an ESP-WROVER-KIT using the loboris version of ESP32 MicroPython.
The loboris port has a forked copy of https://github.com/jczic/MicroWebSrv and this requires
some further changes which can be found here:
This has been tested on an ESP-WROVER-KIT and a SparkFun ESP32 Thing using the
loboris version of ESP32 MicroPython.
The loboris port has a forked copy of https://github.com/jczic/MicroWebSrv and
this requires some further changes which can be found here:

https://github.com/dhylands/MicroPython_ESP32_psRAM_LoBo/tree/rest-improvements

Expand All @@ -16,13 +17,27 @@ the directions in the [README.md](https://github.com/dhylands/MicroPython_ESP32_
# Installing webthing-upy

I used version 0.0.12 of [rshell](https://github.com/dhylands/rshell) to copy the webthing-upy files to the board. The
ESP-WROVER-KIT board advertises 2 serial ports. Use the second port (typically /dev/ttyUSB1)
ESP-WROVER-KIT board advertises 2 serial ports. Use the second port (typically /dev/ttyUSB1). The SparkFun ESP32 Thing only advertises a single serial port.

Edit the config.py with an appropriate SSID and password. Edit main.py to be appropriate for the board you're using.

Sample main.py for the SparkFun ESP32 Thing:
```
import start
start.thing()
```
Sample main.py for the ESP-WROVER-KIT:
```
import start
start.rgb()
```
For debugging, remove main.py and enter commands at the REPL manually.

```
$ cd webthing-upy
$ rshell -a --buffer-size=30 --port=/dev/ttyUSB1
webthing-upy> rsync -v . /flash
webthing-upy> repl
>>> import start
>>> start.rgb()
>>> Control-D
```
Pressing Control-D will cause the board to soft reboot which will start executing main.py.
8 changes: 8 additions & 0 deletions config.py
@@ -0,0 +1,8 @@
# These should be edited to reflect your actual SSID and password

SSID = ''
PASSWORD = ''

if SSID == '':
print('Please edit config.py and set the SSID and password')
raise ValueError('SSID not set')
58 changes: 27 additions & 31 deletions connect.py
@@ -1,39 +1,35 @@
import machine
import network
import time
import config

def start_ftp():
print('Starting FTP...')
network.ftp.start()

station = network.WLAN(network.STA_IF)
if not station.active():
station.active(True)
if not station.isconnected():
print('Connecting....')
station.connect('SSID', 'password')
while not station.isconnected():
time.sleep(1)
print('.', end='')
print('ifconfig =', station.ifconfig())

print('Syncing to NTP...')
rtc = machine.RTC()
rtc.ntp_sync(server='pool.ntp.org')

print('Starting mDNS...')
mdns = network.mDNS()
_ = mdns.start("esp32-upy","MicroPython with mDNS")
_ = mdns.addService('_ftp', '_tcp', 21, "MicroPython", {"board": "ESP32", "service": "mPy FTP File transfer", "passive": "True"})
_ = mdns.addService('_telnet', '_tcp', 23, "MicroPython", {"board": "ESP32", "service": "mPy Telnet REPL"})
_ = mdns.addService('_http', '_tcp', 80, "MicroPython", {"board": "ESP32", "service": "mPy Web server"})
def start_ntp():
print('Syncing to NTP...')
rtc = machine.RTC()
rtc.ntp_sync(server='pool.ntp.org')

print('Starting FTP...')
network.ftp.start()

if not rtc.synced():
print(' waiting for time sync...', end='')
time.sleep(0.5)
while not rtc.synced():
print('.', end='')
if not rtc.synced():
print(' waiting for time sync...', end='')
time.sleep(0.5)
print('')
while not rtc.synced():
print('.', end='')
time.sleep(0.5)
print('')
print('Time:', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))

print('Time:', time.strftime('%Y-%m-%d %H:%M:%S', time.localtime()))
def connect_to_ap():
station = network.WLAN(network.STA_IF)
if not station.active():
station.active(True)
if not station.isconnected():
print('Connecting....')
station.connect(config.SSID, config.PASSWORD)
while not station.isconnected():
time.sleep(1)
print('.', end='')
print('')
print('ifconfig =', station.ifconfig())
67 changes: 39 additions & 28 deletions example/esp32_wrover_kit_rgb.py
Expand Up @@ -13,11 +13,19 @@ class RGBLed(Thing):
def __init__(self, rPin, gPin, bPin):
Thing.__init__(self,
'ESP32-RGB-LED',
'dimmableColorLight',
'onOffColorLight',
'RGB LED on ESP-Wrover-Kit')
self.red = machine.Pin(rPin, machine.Pin.OUT)
self.green = machine.Pin(gPin, machine.Pin.OUT)
self.blue = machine.Pin(bPin, machine.Pin.OUT)
self.pinRed = machine.Pin(rPin, machine.Pin.OUT)
self.pinGreen = machine.Pin(gPin, machine.Pin.OUT)
self.pinBlue = machine.Pin(bPin, machine.Pin.OUT)
self.pwmRed = machine.PWM(self.pinRed)
self.pwmGreen = machine.PWM(self.pinGreen)
self.pwmBlue = machine.PWM(self.pinBlue)
self.redLevel = 50
self.greenLevel = 50
self.blueLevel = 50
self.on = False
self.updateLeds()

self.add_property(
Property(self,
Expand All @@ -28,39 +36,42 @@ def __init__(self, rPin, gPin, bPin):
'description': 'Whether the LED is turned on',
}))
self.add_property(
Property(self,
'level',
Value(50, self.setRGBLevel),
metadata={
'type': 'number',
'description': 'The level of light from 0-100',
'minimum': 0,
'maximum': 100,
}))

self.add_property(
Property(self,
'color',
Value('#808080', self.setRGBColor),
metadata={
'type': 'string',
'description': 'The color of the LED',
}))
Property(self,
'color',
Value('#808080', self.setRGBColor),
metadata={
'type': 'string',
'description': 'The color of the LED',
}))

def setOnOff(self, onOff):
print('setOnOff: onOff =', onOff)

def setRGBLevel(self, level):
print('setsetRGBColorOnOff: level =', level)
print('setOnOff: onOff =', onOff)
self.on = onOff
self.updateLeds()

def setRGBColor(self, color):
print('setRGBColor: color =', color)
print('setRGBColor: color =', color)
self.redLevel = int(color[1:3], 16) / 256 * 100
self.greenLevel = int(color[3:5], 16) / 256 * 100
self.blueLevel = int(color[5:7], 16) / 256 * 100
self.updateLeds()

def updateLeds(self):
print('updateLeds: on =', self.on, 'r', self.redLevel, 'g', self.greenLevel, 'b', self.blueLevel)
if self.on:
self.pwmRed.duty(self.redLevel)
self.pwmGreen.duty(self.greenLevel)
self.pwmBlue.duty(self.blueLevel)
else:
self.pwmRed.duty(0)
self.pwmGreen.duty(0)
self.pwmBlue.duty(0)


def run_server():
log.info('run_server')

rgb = RGBLed(0, 4, 2)
rgb = RGBLed(0, 2, 4)

# If adding more than one thing here, be sure to set the `name`
# parameter to some string, which will be broadcast via mDNS.
Expand Down
111 changes: 111 additions & 0 deletions example/sparkfun_esp32_thing.py
@@ -0,0 +1,111 @@
from property import Property
from thing import Thing
from value import Value
from server import MultipleThings, WebThingServer
import logging
import time
import machine

log = logging.getLogger(__name__)

class Led(Thing):

def __init__(self, ledPin):
Thing.__init__(self,
'Blue LED',
'dimmableLight',
'Blue LED on SparkFun ESP32 Thing')
self.pinLed = machine.Pin(ledPin, machine.Pin.OUT)
self.pwmLed = machine.PWM(self.pinLed)
self.ledLevel = 50
self.on = False
self.updateLed()

self.add_property(
Property(self,
'on',
Value(self.on, self.setOnOff),
metadata={
'type': 'boolean',
'description': 'Whether the LED is turned on',
}))
self.add_property(
Property(self,
'level',
Value(self.ledLevel, self.setLevel),
metadata={
'type': 'number',
'description': 'The brightness of the LED',
}))

def setOnOff(self, onOff):
log.info('setOnOff: onOff = ' + str(onOff))
self.on = onOff
self.updateLed()

def setLevel(self, level):
log.info('setLevel: level = ' + str(level))
self.ledLevel = level
self.updateLed()

def updateLed(self):
log.debug('updateLed: on = ' + str(self.on) +
' level = ' + str(self.ledLevel))
if self.on:
self.pwmLed.duty(self.ledLevel)
else:
self.pwmLed.duty(0)

class Button(Thing):

def __init__(self, pin):
Thing.__init__(self,
'Button 0',
'binarySensor',
'Button 0 on SparkFun ESP32 Thing')
self.pin = machine.Pin(pin, machine.Pin.IN)

self.button = Value(False)
self.add_property(
Property(self,
'on',
self.button,
metadata={
'type': 'boolean',
'description': 'Button 0 pressed'
}))
self.prev_pressed = self.is_pressed()

def is_pressed(self):
return self.pin.value() == 0

def process(self):
pressed = self.is_pressed()
if pressed != self.prev_pressed:
self.prev_pressed = pressed
log.debug('pressed = ' + str(pressed))
self.button.notify_of_external_update(pressed)

def run_server():
log.info('run_server')

led = Led(5)
button = Button(0)

# If adding more than one thing here, be sure to set the `name`
# parameter to some string, which will be broadcast via mDNS.
# In the single thing case, the thing's name will be broadcast.
server = WebThingServer(MultipleThings([led, button],
'SparkFun-ESP32-Thing'),
port=80)
try:
log.info('starting the server')
server.start()
except KeyboardInterrupt:
log.info('stopping the server')
server.stop()
log.info('done')

while True:
time.sleep(0.1)
button.process()
19 changes: 9 additions & 10 deletions start.py
Expand Up @@ -8,18 +8,11 @@
sys.path.append('/flash/webthing')
sys.path.append('/flash/example')

# remove ourselves so that we can be re-imported
mod_name = __name__
g = globals()
if mod_name in g:
print('Deleting', mod_name, 'from globals')
del g[mod_name]
if mod_name in sys.modules:
print('Deleting', mod_name, 'from sys.modules')
del sys.modules[mod_name]

import connect

connect.connect_to_ap()
connect.start_ntp()

def rgb():
print('importing esp32_wrover_kit_rgb...')
import esp32_wrover_kit_rgb
Expand All @@ -37,3 +30,9 @@ def multi():
import multiple_things
print('Starting multiple_things server...')
multiple_things.run_server()

def thing():
print('importing sparkfun_esp32_thing...')
import sparkfun_esp32_thing
print('Starting sparkfun_esp32_thing server...')
sparkfun_esp32_thing.run_server()

0 comments on commit 76c74be

Please sign in to comment.