-
Notifications
You must be signed in to change notification settings - Fork 2
Commit
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.
- Loading branch information
North101
committed
Jun 29, 2024
1 parent
2403cee
commit a3929dd
Showing
6 changed files
with
183 additions
and
69 deletions.
There are no files selected for viewing
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,4 @@ | ||
.venv/ | ||
.vscode/ | ||
|
||
access-front-door/src/env.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -1,3 +1,66 @@ | ||
# Access Front Door | ||
|
||
This is the code required for opening the front door latch. | ||
This is the code required for opening the front door latch. | ||
|
||
|
||
## 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 | ||
|
||
|
||
## Micropython type hints in VSCode | ||
|
||
### Install these extensions: | ||
* https://marketplace.visualstudio.com/items?itemName=ms-python.python | ||
* https://marketplace.visualstudio.com/items?itemName=ms-python.vscode-pylance | ||
|
||
|
||
### Setup virtualenv and install stubs | ||
```bash | ||
# setup virtualenv | ||
python3 -m venv .venv | ||
|
||
# activate virtualenv | ||
source ./.venv/bin/activate | ||
|
||
# install micropython stubs | ||
pip3 install -U micropython-esp32-stubs | ||
|
||
# install mpremote (optional, lets you connect via command line) | ||
pip3 install -U mpremote | ||
``` | ||
|
||
### Configure vscode | ||
`.vscode/settings.json` | ||
```json | ||
{ | ||
"python.languageServer": "Pylance", | ||
"python.analysis.typeCheckingMode": "basic", | ||
"python.analysis.diagnosticSeverityOverrides": { | ||
"reportMissingModuleSource": "none" | ||
}, | ||
// Replace <python_version> with whatever the folder name is in .venv/lib/ | ||
"python.analysis.typeshedPaths": [ | ||
".venv/lib/<python_version>/site-packages", | ||
], | ||
// Fixes imports | ||
"pylint.args": [ | ||
"--init-hook 'import sys; sys.path.append(\".\")'", | ||
], | ||
} | ||
``` | ||
|
||
|
||
### Copy code to device via command line (requires mpremote) | ||
```bash | ||
# make sure you are in the access-front-door directory | ||
cd access-front-door | ||
|
||
# list connected devices | ||
./run.sh | ||
|
||
# copy code and run main.py on device | ||
./run.sh [device_id] | ||
``` |
This file was deleted.
Oops, something went wrong.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,10 @@ | ||
# bin/bash | ||
if [[ -z "$1" ]]; then | ||
echo "usage: $0 [device_id]" | ||
mpremote devs | ||
exit 1; | ||
fi | ||
|
||
mpremote connect id:$1 reset | ||
mpremote connect id:$1 cp -r src/* : | ||
mpremote connect id:$1 run ./src/main.py |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,5 @@ | ||
WIFI_SSID = "" | ||
WIFI_PASSWORD = "" | ||
SHARED_PASSWORD = "access-front-door-psk" | ||
HOSTNAME = "access-front-door" | ||
DEFAULT_UNLOCK_DURATION = 10 |
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Original file line number | Diff line number | Diff line change |
---|---|---|
@@ -0,0 +1,100 @@ | ||
import socket | ||
import time | ||
|
||
import network | ||
from machine import PWM, Pin | ||
|
||
from . import env | ||
|
||
|
||
# Variables | ||
RESPONSE = "HTTP/1.1 200 OK\r\nContent-Length: 0\r\nConnection: close\r\n\r\n" | ||
|
||
|
||
class Door(): | ||
def __init__(self): | ||
self.pwm = PWM(Pin(23)) # Set up pin D23 to output | ||
self.led = Pin(2, Pin.OUT) # Pin 2 is the built-in LED | ||
self.setup_wifi() | ||
self.setup_socket() | ||
|
||
def setup_wifi(self): | ||
self.wifi = network.WLAN(network.STA_IF) | ||
self.wifi.active(True) | ||
time.sleep_us(100) | ||
self.wifi.config(dhcp_hostname=env.HOSTNAME) | ||
|
||
def connect_wifi(self): | ||
# Connect to WiFi | ||
self.wifi.connect(env.WIFI_SSID, env.WIFI_PASSWORD) | ||
while not self.wifi.isconnected(): | ||
pass | ||
|
||
def setup_socket(self): | ||
# Set up webserver | ||
self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM) | ||
self.socket.bind(('', 8080)) | ||
self.socket.listen(5) | ||
|
||
def get_parameters_from(self, request: bytes): | ||
parameters: dict[str, str] = {} | ||
request_str = request.decode('utf-8') | ||
params_index = request_str.find('Content-Length:') | ||
ampersand_split = request_str[params_index:].split("&") | ||
for element in ampersand_split: | ||
equal_split = element.split("=") | ||
parameters[equal_split[0]] = equal_split[1] | ||
|
||
return parameters | ||
|
||
def read_socket(self): | ||
conn: socket.socket = self.socket.accept()[0] | ||
request = conn.recv(1024) | ||
parameters = self.get_parameters_from(request) | ||
conn.send(RESPONSE) | ||
conn.close() | ||
|
||
return parameters | ||
|
||
def lock(self): | ||
self.led.off() | ||
self.pwm.duty(0) | ||
|
||
def unlock(self): | ||
# Output signal on pin to unlock and light up the internal light | ||
self.led.on() | ||
self.pwm.duty(1023) | ||
|
||
def run(self): | ||
while True: | ||
try: | ||
self.update() | ||
except Exception as e: | ||
print(e) | ||
|
||
def update(self): | ||
self.lock() | ||
|
||
if not self.wifi.isconnected(): | ||
self.connect_wifi() | ||
|
||
parameters = self.read_socket() | ||
|
||
# Bail if the request didn't come from a known source | ||
if parameters.get('psk') != env.SHARED_PASSWORD: | ||
return | ||
|
||
duration = parameters.get("duration") | ||
try: | ||
duration = int(duration) if duration is not None else env.DEFAULT_UNLOCK_DURATION | ||
except ValueError: | ||
return | ||
unlock_duration = max(min(duration, 30), 1) | ||
|
||
self.unlock() | ||
time.sleep(unlock_duration) | ||
|
||
|
||
if __name__ == '__main__': | ||
door = Door() | ||
door.run() |