add network support
parent
0ba4b41917
commit
b3fd037cd9
122
esp32/main.py
122
esp32/main.py
|
@ -4,6 +4,10 @@ import machine
|
||||||
import hashlib
|
import hashlib
|
||||||
import os
|
import os
|
||||||
import asyncio
|
import asyncio
|
||||||
|
import network
|
||||||
|
import requests
|
||||||
|
import _thread
|
||||||
|
from umqtt.simple import MQTTClient
|
||||||
|
|
||||||
DEBUG = True
|
DEBUG = True
|
||||||
|
|
||||||
|
@ -45,6 +49,115 @@ class Keypad:
|
||||||
return data[:4]
|
return data[:4]
|
||||||
|
|
||||||
|
|
||||||
|
class Net:
|
||||||
|
def __init__(self):
|
||||||
|
self._connected = False
|
||||||
|
self._wlan = network.WLAN(network.STA_IF)
|
||||||
|
|
||||||
|
self._events = []
|
||||||
|
# keepalive is needed due to: https://github.com/eclipse/mosquitto/issues/2462
|
||||||
|
self._mqtt = MQTTClient("lock", "10.11.1.1", keepalive=5)
|
||||||
|
self._mqtt.set_callback(self._mqtt_cb)
|
||||||
|
|
||||||
|
async def loop(self):
|
||||||
|
self.start()
|
||||||
|
while True:
|
||||||
|
self.update()
|
||||||
|
await asyncio.sleep(0.5)
|
||||||
|
|
||||||
|
def _mqtt_cb(self, topic, msg):
|
||||||
|
if topic == b'locks/internal/command':
|
||||||
|
if msg == b'sync':
|
||||||
|
try:
|
||||||
|
print("starting sync")
|
||||||
|
# TODO: add auth support to http server
|
||||||
|
url = "http://10.11.1.1:8000/hashes/internal"
|
||||||
|
print(f"fetching: {url}")
|
||||||
|
rsp = requests.get(url)
|
||||||
|
print(f"sync code: {rsp.status_code}")
|
||||||
|
with open('hashes_new', 'wb') as f:
|
||||||
|
if 200 <= rsp.status_code < 300:
|
||||||
|
while True:
|
||||||
|
chunk = rsp.raw.read(512)
|
||||||
|
if not chunk:
|
||||||
|
break
|
||||||
|
f.write(chunk)
|
||||||
|
os.rename('hashes_new', 'hashes')
|
||||||
|
print("sync finished")
|
||||||
|
self.send_event("sync", 'success'.encode())
|
||||||
|
except Exception as e:
|
||||||
|
print(f"sync error: {e}")
|
||||||
|
self.send_event("sync", 'fail'.encode())
|
||||||
|
else:
|
||||||
|
print(f"uncrecognised command: {msg}")
|
||||||
|
|
||||||
|
|
||||||
|
def send_event(self, name, payload):
|
||||||
|
# TODO: limit number of events in queue
|
||||||
|
self._events.append((name, payload))
|
||||||
|
|
||||||
|
|
||||||
|
def _run_mqtt(self):
|
||||||
|
mqtt = self._mqtt
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
mqtt.connect()
|
||||||
|
mqtt.publish("locks/internal/mac", self._wlan.config('mac').hex())
|
||||||
|
mqtt.subscribe("locks/internal/command")
|
||||||
|
|
||||||
|
i = 0
|
||||||
|
while True:
|
||||||
|
try:
|
||||||
|
while True:
|
||||||
|
name, payload = self._events.pop()
|
||||||
|
print("sending event")
|
||||||
|
mqtt.sock.setblocking(True)
|
||||||
|
mqtt.publish(f"locks/internal/events/{name}", payload)
|
||||||
|
except IndexError:
|
||||||
|
pass
|
||||||
|
|
||||||
|
if i == 10:
|
||||||
|
i = 0
|
||||||
|
mqtt.ping()
|
||||||
|
else:
|
||||||
|
i += 1
|
||||||
|
|
||||||
|
mqtt.check_msg()
|
||||||
|
utime.sleep(0.25)
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"mqtt exception: {e}")
|
||||||
|
utime.sleep(6)
|
||||||
|
|
||||||
|
def start(self):
|
||||||
|
self._wlan.active(True)
|
||||||
|
# for net in self._wlan.scan():
|
||||||
|
# print(f'scan: {net}')
|
||||||
|
print("mac:", self._wlan.config('mac').hex())
|
||||||
|
|
||||||
|
_thread.start_new_thread(self._run_mqtt, ())
|
||||||
|
|
||||||
|
with open('wifi', 'r') as f:
|
||||||
|
ssid = f.readline().strip()
|
||||||
|
key = f.readline().strip()
|
||||||
|
|
||||||
|
if not self._wlan.isconnected():
|
||||||
|
print(f'connecting to network ssid={ssid!r}')
|
||||||
|
self._wlan.connect(ssid, key)
|
||||||
|
|
||||||
|
|
||||||
|
def update(self):
|
||||||
|
if self._wlan.isconnected():
|
||||||
|
if not self._connected:
|
||||||
|
print('network config:', self._wlan.ifconfig())
|
||||||
|
self._connected = True
|
||||||
|
else:
|
||||||
|
if self._connected:
|
||||||
|
print('disconnected')
|
||||||
|
self._connected = False
|
||||||
|
|
||||||
|
|
||||||
class Door:
|
class Door:
|
||||||
def __init__(self, pin):
|
def __init__(self, pin):
|
||||||
self._pin = pin
|
self._pin = pin
|
||||||
|
@ -64,7 +177,7 @@ def generate_hash(card_uid, pin):
|
||||||
return hash
|
return hash
|
||||||
|
|
||||||
|
|
||||||
async def handle_auth(nfc, keypad, door):
|
async def handle_auth(nfc, keypad, door, net):
|
||||||
while True:
|
while True:
|
||||||
card_uid = await nfc.wait_uid()
|
card_uid = await nfc.wait_uid()
|
||||||
print("Card UUID: " + ''.join('{:02x}'.format(x) for x in card_uid))
|
print("Card UUID: " + ''.join('{:02x}'.format(x) for x in card_uid))
|
||||||
|
@ -89,6 +202,8 @@ async def handle_auth(nfc, keypad, door):
|
||||||
hash_found = True
|
hash_found = True
|
||||||
break
|
break
|
||||||
|
|
||||||
|
net.send_event("hash", hash.encode())
|
||||||
|
|
||||||
try:
|
try:
|
||||||
if hash_found:
|
if hash_found:
|
||||||
print('Known hash, opening door')
|
print('Known hash, opening door')
|
||||||
|
@ -163,9 +278,12 @@ async def main():
|
||||||
door = Door(machine.Pin(2, machine.Pin.OUT))
|
door = Door(machine.Pin(2, machine.Pin.OUT))
|
||||||
door.lock()
|
door.lock()
|
||||||
|
|
||||||
|
net = Net()
|
||||||
|
|
||||||
await asyncio.gather(
|
await asyncio.gather(
|
||||||
handle_auth(nfc, keypad, door),
|
handle_auth(nfc, keypad, door, net),
|
||||||
nfc.loop(),
|
nfc.loop(),
|
||||||
|
net.loop()
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
|
|
Loading…
Reference in New Issue