Skip to content

Commit

Permalink
Updates from testing on device
Browse files Browse the repository at this point in the history
  • Loading branch information
alistairjcbrown committed Jul 15, 2024
1 parent 6f19a28 commit bdfb8eb
Show file tree
Hide file tree
Showing 17 changed files with 275 additions and 49 deletions.
1 change: 1 addition & 0 deletions access-front-door/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3
20 changes: 14 additions & 6 deletions access-front-door/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -9,22 +9,30 @@ This is the code required for opening the front door latch.
pip install esptool

# Find the serial port of the connected ESP32
esptool.py flash_id
esptool.py flash_id

# Wipe the chip
esptool.py --port [serial_port] erase_flash
esptool.py --port [serial_port] erase_flash

# Download the latest firmware from https://micropython.org/download/ESP32_GENERIC/
# Install th firmware
# Install the firmware
esptool.py --chip esp32 --port [serial_port] --baud 460800 write_flash -z 0x1000 [path_to_downloaded_bin_file]
```


## Setting up environment variables

1. Copy or rename `access-front-door/src/env.example.py` to `access-front-door/src/env.py`
2. Set `WIFI_SSID` and `WIFI_PASSWORD` to your wifi ssid and password
3. Update any other variables
1. Clone this repository
```sh
git clone git@github.com:FarsetLabs/gate-network.git
cd gate-network
```
1. Create the environment file
```sh
cp ./access-front-door/src/env.example.py ./access-front-door/src/env.py
```
1. Set `WIFI_SSID` and `WIFI_PASSWORD` to your wifi ssid and password
1. Update any other variables


## Micropython type hints in VSCode
Expand Down
12 changes: 12 additions & 0 deletions access-front-door/flash.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
# bin/bash
if [[ -z "$1" ]]; then
echo "usage: $0 [device_id]"
mpremote devs
exit 1;
fi

mpremote connect id:$1 reset
cd ./src
echo "Copying files to device $1 ..."
mpremote connect id:$1 cp -r ./* :
echo "You can now disconnect your device"
21 changes: 18 additions & 3 deletions access-front-door/run.sh
Original file line number Diff line number Diff line change
@@ -1,10 +1,25 @@
# bin/bash
if [[ -z "$1" ]]; then
echo "usage: $0 [device_id]"
echo "usage: $0 [device_id] [flash]"
mpremote devs
exit 1;
fi

echo "Resetting device $1 ..."
mpremote connect id:$1 reset
mpremote connect id:$1 cp -r src/* :
mpremote connect id:$1 run ./src/main.py

echo "Copying files to device $1 ..."
cd ./src
mpremote connect id:$1 cp -r lib/* :
mpremote connect id:$1 cp ./hub.py :
mpremote connect id:$1 cp ./wifi.py :
mpremote connect id:$1 cp ./env.py :

if [[ -z "$2" ]]; then
echo "Running main.py remotely ..."
mpremote connect id:$1 run ./main.py
else
echo "Copying main.py into place ..."
mpremote connect id:$1 cp ./main.py :
echo "Device has been updated"
fi
2 changes: 1 addition & 1 deletion access-front-door/src/env.example.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,5 @@
WIFI_SSID = ""
WIFI_PASSWORD = ""
SHARED_PASSWORD = "access-front-door-psk"
HOSTNAME = "access-front-door"
HUB_IP_ADDRESS = ""
DEFAULT_UNLOCK_DURATION = 10
22 changes: 22 additions & 0 deletions access-front-door/src/hub.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,22 @@
import urequests


class Hub():
def __init__(self, env):
self.env = env

def register_device(self, id):
url = 'http://{}/register'.format(self.env.HUB_IP_ADDRESS)
data = {'id': id, 'psk': self.env.SHARED_PASSWORD}
encoded_data = '&'.join(["{}={}".format(k, v) for k, v in data.items()])
response = urequests.post(url, data=encoded_data, headers={'Content-Type': 'application/x-www-form-urlencoded'})
response.close()
return response.status_code

def perform_action(self, id, affect, params):
url = 'http://{}/action'.format(self.env.HUB_IP_ADDRESS)
data = {'id': id, 'psk': self.env.SHARED_PASSWORD, affect: affect, params: params}
encoded_data = '&'.join(["{}={}".format(k, v) for k, v in data.items()])
response = urequests.post(url, data=encoded_data, headers={'Content-Type': 'application/x-www-form-urlencoded'})
response.close()
return response.status_code
54 changes: 15 additions & 39 deletions access-front-door/src/main.py
Original file line number Diff line number Diff line change
@@ -1,46 +1,12 @@
import network
import uasyncio as asyncio
import utime as time
from machine import PWM, Pin
from phew import server
from phew.server import Request

import env


class Wifi():
def __init__(self):
self.wifi = network.WLAN(network.STA_IF)

async def connect(self, timeout_ms=60*1000):
if self.is_connected():
return True

# Connect to WiFi
self.wifi.active(True)
self.wifi.connect(env.WIFI_SSID, env.WIFI_PASSWORD)
try:
await asyncio.wait_for_ms(self.wait_for_connected(), timeout_ms)
return True
except asyncio.TimeoutError:
self.wifi.disconnect()
self.wifi.active(False)
return False

def ip(self):
return self.wifi.ifconfig()[0]

def is_connected(self):
return self.wifi.isconnected()

async def wait_for_connected(self, connection_state=True):
while self.is_connected() is not connection_state:
await asyncio.sleep_ms(500)

async def stay_connected(self):
while True:
await self.connect()
await asyncio.sleep_ms(500)
from hub import Hub
from wifi import Wifi


class DoorServer():
Expand Down Expand Up @@ -68,7 +34,9 @@ async def index(self, request: Request):
if params.get('psk') != env.SHARED_PASSWORD:
return

duration = self.parse_duration(params.get("duration"))
# Reparse any params which were passed from the initial sender
proxied_params = server._parse_query_string(params.get("params"))
duration = self.parse_duration(proxied_params.get("duration"))
unlock_duration = max(min(duration, 30), 1)

self.unlock()
Expand Down Expand Up @@ -99,18 +67,26 @@ def unlock(self):
self.pwm.duty(1023)

def run(self):
self.server.run()
self.server.run(port = 8080)


async def main():
door = DoorServer()
door.lock()

wifi = Wifi()
wifi = Wifi(env)
while not await wifi.connect():
print('Connecting...')
print('Connected:', wifi.ip())

print("Registering with the hub ...")
hub = Hub(env)
status_code = hub.register_device('access-front-door')
if status_code == 200:
print('Device registered successfully')
else:
print('Error registering device:', status_code)

door.run()


Expand Down
38 changes: 38 additions & 0 deletions access-front-door/src/wifi.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,38 @@
import network
import uasyncio as asyncio


class Wifi():
def __init__(self, env):
self.env = env
self.wifi = network.WLAN(network.STA_IF)

async def connect(self, timeout_ms=60*1000):
if self.is_connected():
return True

# Connect to WiFi
self.wifi.active(True)
self.wifi.connect(self.env.WIFI_SSID, self.env.WIFI_PASSWORD)
try:
await asyncio.wait_for_ms(self.wait_for_connected(), timeout_ms)
return True
except asyncio.TimeoutError:
self.wifi.disconnect()
self.wifi.active(False)
return False

def ip(self):
return self.wifi.ifconfig()[0]

def is_connected(self):
return self.wifi.isconnected()

async def wait_for_connected(self, connection_state=True):
while self.is_connected() is not connection_state:
await asyncio.sleep_ms(500)

async def stay_connected(self):
while True:
await self.connect()
await asyncio.sleep_ms(500)
1 change: 1 addition & 0 deletions button-door/.python-version
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
3
1 change: 1 addition & 0 deletions button-door/README.md
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
esptool.py --chip esp32 --port /dev/cu.usbserial-21527DFA12 --baud 115200 write_flash -z 0x1000 /Users/alistairbrown/Downloads/ESP32_GENERIC-20240602-v1.23.0.bin
24 changes: 24 additions & 0 deletions button-door/run.sh
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
# bin/bash
if [[ -z "$1" ]]; then
echo "usage: $0 [device_id] [flash]"
mpremote devs
exit 1;
fi

echo "Resetting device $1 ..."
mpremote connect id:$1 reset

echo "Copying files to device $1 ..."
cd ./src
mpremote connect id:$1 cp ./hub.py :
mpremote connect id:$1 cp ./wifi.py :
mpremote connect id:$1 cp ./env.py :

if [[ -z "$2" ]]; then
echo "Running main.py remotely ..."
mpremote connect id:$1 run ./main.py
else
echo "Copying main.py into place ..."
mpremote connect id:$1 cp ./main.py :
echo "Device has been updated"
fi
4 changes: 4 additions & 0 deletions button-door/src/env.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,4 @@
WIFI_SSID = "farset-guest"
WIFI_PASSWORD = "donationswelcome"
SHARED_PASSWORD = "psk-button-door"
HUB_IP_ADDRESS = "192.168.1.244"
24 changes: 24 additions & 0 deletions button-door/src/hub.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
import urequests


class Hub():
def __init__(self, env):
self.env = env

def register_device(self, id):
url = 'http://{}/register'.format(self.env.HUB_IP_ADDRESS)
data = {'id': id, 'psk': self.env.SHARED_PASSWORD}
encoded_data = '&'.join(["{}={}".format(k, v) for k, v in data.items()])
response = urequests.post(url, data=encoded_data, headers={'Content-Type': 'application/x-www-form-urlencoded'})
response.close()
return response.status_code

def perform_action(self, id, affect, params):
url = 'http://{}/action'.format(self.env.HUB_IP_ADDRESS)
print(">> url", url)
data = {'id': id, 'psk': self.env.SHARED_PASSWORD, 'affect': affect, 'params': params}
print(">> data", data)
encoded_data = '&'.join(["{}={}".format(k, v) for k, v in data.items()])
response = urequests.post(url, data=encoded_data, headers={'Content-Type': 'application/x-www-form-urlencoded'})
response.close()
return response.status_code
60 changes: 60 additions & 0 deletions button-door/src/main.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,60 @@
import uasyncio as asyncio
import utime as time
from machine import Pin

import env
from hub import Hub
from wifi import Wifi

device_id = 'button-door'

class Button():
def __init__(self, hub):
self.last_tick_time = None
self.hub = hub

def on_press(self):
status_code = self.hub.perform_action(device_id, 'access-front-door', 'duration%3D2')
if status_code == 200:
print('Action sent successfully')
else:
print('Error sending action:', status_code)


def tick(self, pin):
self.last_tick_time = time.ticks_ms()

def check_tick(self):
current_time = time.ticks_ms()
if self.last_tick_time and current_time - self.last_tick_time > 500:
self.last_tick_time = None
self.on_press()

async def run(self):
button = Pin(39, Pin.IN)
button.irq(trigger=Pin.IRQ_FALLING, handler=self.tick)
while True:
self.check_tick()
await asyncio.sleep_ms(10)


async def main():
hub = Hub(env)
button = Button(hub)

wifi = Wifi(env)
while not await wifi.connect():
print('Connecting...')
print('Connected:', wifi.ip())

print("Registering with the hub ...")
status_code = hub.register_device(device_id)
if status_code == 200:
print('Device registered successfully')
else:
print('Error registering device:', status_code)

await button.run()

if __name__ == '__main__':
asyncio.run(main())
Loading

0 comments on commit bdfb8eb

Please sign in to comment.