Skip to content
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
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -158,4 +158,5 @@ cython_debug/
# option (not recommended) you can uncomment the following to ignore the entire idea folder.
.idea/
urequests.py
src/test/
src/test/
config.py
28 changes: 17 additions & 11 deletions src/api.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,18 @@ class ApiInterface:
"accept": "application/json"
}

__BASE_URL = "http://185.185.71.49:8000"
__HEALTH_URL = __BASE_URL + "/health"
__DEVICE_URL = __BASE_URL + "/device"
__NEXT_DEVICE_URL = __DEVICE_URL + "/next"
__PREVIOUS_DEVICE_URL = __DEVICE_URL + "/previous"
__PLAY_URL = __BASE_URL + "/play"
def __init__(self, base_url: str):
if "https" in base_url:
raise ValueError("Base URL must not contain https://")
if "http://" not in base_url:
base_url = "http://" + base_url

self.__base_url = base_url
self.__health_url = base_url + "/health"
self.__play_url = base_url + "/play"
self.__device_url = base_url + "/device"
self.__next_device_url = self.__device_url + "/next"
self.__previous_device_url = self.__device_url + "/previous"

def request(self, method: str, url: str, data=None, params=None) -> urequests.Response:
if data is None:
Expand Down Expand Up @@ -41,18 +47,18 @@ def request(self, method: str, url: str, data=None, params=None) -> urequests.Re

def check_health(self) -> bool:
try:
return self.request("GET", self.__HEALTH_URL).status_code == 200
return self.request("GET", self.__health_url).status_code == 200
except:
return False

def get_current_device(self, reset: bool = False) -> dict:
return self.request("GET", self.__DEVICE_URL, params={"reset": reset}).json()
return self.request("GET", self.__device_url, params={"reset": reset}).json()

def next_device(self) -> dict:
return self.request("POST", self.__NEXT_DEVICE_URL).json()
return self.request("POST", self.__next_device_url).json()

def previous_device(self) -> dict:
return self.request("POST", self.__PREVIOUS_DEVICE_URL).json()
return self.request("POST", self.__previous_device_url).json()

def play(self, track: str) -> dict:
return self.request("POST", self.__PLAY_URL, {"id": track}).json()
return self.request("POST", self.__play_url, {"id": track}).json()
35 changes: 35 additions & 0 deletions src/config.py.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,35 @@
class Track:
def __init__(self, id: str, name: str):
self.id = id
self.name = name


class Config:
TRACKS = {
4117885779: Track(id="3uMUdlo47oEes3kgL4T4EC", name="Nonstop"),
4233351011: Track(id="5UW6yvwo3nVA609NgprdhK", name="Supermarket")
}

class Wifi:
SSID = "WIFI_SSID"
PASSWORD = "WIFI_PASSWORD"

class Buttons:
LEFT_PIN = 12
RIGHT_PIN = 13

class Display:
SDA_PIN = 0
SCL_PIN = 1

BUZZER_PIN = 11

class RFID:
SDA_PIN = 15
SCK_PIN = 18
MOSI_PIN = 19
MISO_PIN = 16
RST_PIN = 14
READ_DELAY = 2

API_BASE_URL = "http://apiurl.com"
128 changes: 70 additions & 58 deletions src/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -6,28 +6,31 @@
from buttons import ButtonsInterface
from buzzer import BuzzerInterface
from rfid import RFIDInterface


class Track:
def __init__(self, id: str, name: str):
self.id = id
self.name = name
from config import Config


class App:
def __init__(self):
self.__display = DisplayInterface(sda_pin=0, scl_pin=1)
self.__api = ApiInterface()
self.__buttons = ButtonsInterface(left_button_pin=12, right_button_pin=13)
self.__buzzer = BuzzerInterface(pin=11)
self.__rfid = RFIDInterface(sda_pin=15, sck_pin=18, mosi_pin=19, miso_pin=16, rst_pin=14)
self.__last_rfid_successful_read_time = 0
self.__rfid_read_delay = 2
self.__display = DisplayInterface(
sda_pin=Config.Display.SDA_PIN,
scl_pin=Config.Display.SCL_PIN
)
self.__buttons = ButtonsInterface(
left_button_pin=Config.Buttons.LEFT_PIN,
right_button_pin=Config.Buttons.RIGHT_PIN
)
self.__rfid = RFIDInterface(
sda_pin=Config.RFID.SDA_PIN,
sck_pin=Config.RFID.SCK_PIN,
mosi_pin=Config.RFID.MOSI_PIN,
miso_pin=Config.RFID.MISO_PIN,
rst_pin=Config.RFID.RST_PIN
)
self.__buzzer = BuzzerInterface(pin=Config.BUZZER_PIN)
self.__api = ApiInterface(base_url=Config.API_BASE_URL)

self.__tracks = {
4117885779: Track(id="3uMUdlo47oEes3kgL4T4EC", name="Nonstop"),
4233351011: Track(id="5UW6yvwo3nVA609NgprdhK", name="Supermarket")
}
self.__last_rfid_successful_read_time = 0
self.__rfid_read_delay = Config.RFID.READ_DELAY

def run(self) -> None:
self.__display.print_centered(f"{chr(Symbols.NOTE.index)} Music Box {chr(Symbols.NOTE.index)}", line=1)
Expand All @@ -36,49 +39,18 @@ def run(self) -> None:
self.__connect_to_wifi()
if not self.__check_api_health():
return

self.__display.print("Devices:", line=1, clear_full=True)
self.__display_current_device()

while True:
if self.__buttons.was_left_button_pressed():
self.__display.print("Loading...", line=2, clear_line=True)
current_device_data = self.__api.previous_device()
self.__change_device(current_device_data)
self.__buttons.reset()

if self.__buttons.was_right_button_pressed():
self.__display.print("Loading...", line=2, clear_line=True)
current_device_data = self.__api.next_device()
self.__change_device(current_device_data)
self.__buttons.reset()

if time.time() - self.__last_rfid_successful_read_time > self.__rfid_read_delay:
card_id = self.__rfid.read_card_id()

if not card_id:
continue

self.__display.print("Reading card...", line=2, clear_line=True)

if card_id not in self.__tracks:
self.__display.print(f"{chr(Symbols.CROSS.index)} Unknown card", line=2, clear_line=True)
self.__buzzer.play_failure()
time.sleep(1)
self.__display_current_device()
continue

track = self.__tracks[card_id]
self.__api.play(track.id)
self.__display.print(f"{chr(Symbols.NOTE.index)} {track.name}", line=2, clear_line=True)
self.__buzzer.play_success()
time.sleep(1)
self.__display_current_device()

self.__last_rfid_successful_read_time = time.time()
self.__check_buttons_press()
self.__check_rfid_read()

def __connect_to_wifi(self) -> None:
self.__display.print_centered("WiFi", line=2)

wlan.connect()
wlan.connect(Config.Wifi.SSID, Config.Wifi.PASSWORD)

self.__display.print_centered(f"{chr(Symbols.TICK.index)} WiFi ", line=2)
self.__buzzer.play_success()
Expand All @@ -96,20 +68,60 @@ def __check_api_health(self) -> bool:
return True

def __display_current_device(self) -> None:
self.__display.clear()
self.__display.print("Devices:", line=1)

self.__display.print("Loading...", line=2, clear_line=True)
current_device_data = self.__api.get_current_device(reset=True)
self.__change_device(current_device_data)
self.__display_device(current_device_data)

def __change_device(self, device_data: dict) -> None:
def __display_device(self, device_data: dict) -> None:
if device_data == {}:
self.__display.print("No devices", line=2)
return

text = f"{device_data['index'] + 1}/{device_data['total']} {device_data['device']['name']}"
self.__display.print(text, line=2)

def __check_buttons_press(self) -> None:
was_left_button_pressed = self.__buttons.was_left_button_pressed()
was_right_button_pressed = self.__buttons.was_right_button_pressed()

if not any((was_left_button_pressed, was_right_button_pressed)):
return

self.__display.print("Loading...", line=2, clear_line=True)

if was_left_button_pressed:
current_device_data = self.__api.previous_device()
elif was_right_button_pressed:
current_device_data = self.__api.next_device()

self.__display_device(current_device_data)
self.__buttons.reset()

def __check_rfid_read(self) -> None:
if time.time() - self.__last_rfid_successful_read_time <= self.__rfid_read_delay:
return

card_id = self.__rfid.read_card_id()

if not card_id:
return

self.__display.print("Reading card...", line=2, clear_line=True)

if card_id not in Config.TRACKS:
self.__display.print(f"{chr(Symbols.CROSS.index)} Unknown card", line=2, clear_line=True)
self.__buzzer.play_failure()
else:
track = Config.TRACKS[card_id]
self.__api.play(track.id)
self.__display.print(f"{chr(Symbols.NOTE.index)} {track.name}", line=2, clear_line=True)
self.__buzzer.play_success()

time.sleep(1)
self.__display_current_device()

self.__last_rfid_successful_read_time = time.time()


if __name__ == "__main__":
app = App()
Expand Down
4 changes: 2 additions & 2 deletions src/wlan.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,10 +2,10 @@
import time


def connect():
def connect(ssid: str, password: str) -> None:
wlan = network.WLAN(network.STA_IF)
wlan.active(True)
wlan.connect("Tima", "00000000")
wlan.connect(ssid, password)

wait = 10
while wait > 0:
Expand Down