button states
This commit is contained in:
parent
66cd01b4a6
commit
16071f098a
@ -12,6 +12,11 @@ BUTTONS = [
|
|||||||
["SRC_DOWN", "PAUSE", "SRC_UP"]
|
["SRC_DOWN", "PAUSE", "SRC_UP"]
|
||||||
]
|
]
|
||||||
|
|
||||||
|
class ButtonEvent:
|
||||||
|
def __init__(self, btn, state=None):
|
||||||
|
self.button = btn
|
||||||
|
self.state = state
|
||||||
|
|
||||||
class ButtonDecoder:
|
class ButtonDecoder:
|
||||||
def __init__(self):
|
def __init__(self):
|
||||||
self.pi = pi()
|
self.pi = pi()
|
||||||
@ -29,14 +34,13 @@ class ButtonDecoder:
|
|||||||
def _process_line(self, line):
|
def _process_line(self, line):
|
||||||
if len(line) == 1:
|
if len(line) == 1:
|
||||||
if line[0] == 7:
|
if line[0] == 7:
|
||||||
self.queue.put_nowait("WHEEL_UP")
|
self.queue.put_nowait(ButtonEvent("WHEEL_UP"))
|
||||||
elif line[0] == 6:
|
elif line[0] == 6:
|
||||||
self.queue.put_nowait("WHEEL_DOWN")
|
self.queue.put_nowait(ButtonEvent("WHEEL_DOWN"))
|
||||||
elif len(line) == 3:
|
elif len(line) == 3:
|
||||||
btn_name = BUTTONS[line[0]][line[1]]
|
btn_name = BUTTONS[line[0]][line[1]]
|
||||||
action = line[2]
|
action = line[2]
|
||||||
if action == PRESSED:
|
self.queue.put_nowait(ButtonEvent(btn_name, action))
|
||||||
self.queue.put_nowait(btn_name)
|
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
buffer = b''
|
buffer = b''
|
||||||
|
@ -2,8 +2,7 @@
|
|||||||
# BUTTON MATRIX: OK, VOL_UP, VOL_DOWN, SRC_UP, SRC_DOWN, PAUSE, WHEEL_UP, WHEEL_DOWN
|
# BUTTON MATRIX: OK, VOL_UP, VOL_DOWN, SRC_UP, SRC_DOWN, PAUSE, WHEEL_UP, WHEEL_DOWN
|
||||||
# CD CHANGER: NEXT, PREV, FAST_FORW, PLAY, PAUSE, RESUME, STOP, FAST_BACK, CD_(1-6), STALK, RAND_ON, RAND_OFF
|
# CD CHANGER: NEXT, PREV, FAST_FORW, PLAY, PAUSE, RESUME, STOP, FAST_BACK, CD_(1-6), STALK, RAND_ON, RAND_OFF
|
||||||
# RADIO: VOL_UP, VOL_DOWN, PAUSE
|
# RADIO: VOL_UP, VOL_DOWN, PAUSE
|
||||||
# ANDROID AUTO: Play, Pause, Toggle play, Next track, Previous track, Home, Phone, Call end,
|
# ANDROID AUTO: ENTER, LEFT, RIGHT, UP, DOWN, BACK, HOME, PHONE, CALL_END, PLAY, PAUSE, PREV_TRACK, NEXT_TRACK, TOGGLE_PLAY, VOICE, WHEEL_LEFT, WHEEL_RIGHT
|
||||||
# Voice command, Left, Right, Up, Down, Scroll wheel, Back, Enter
|
|
||||||
|
|
||||||
def send_to_radio(btn):
|
def send_to_radio(btn):
|
||||||
tunerlist.send_button(btn)
|
tunerlist.send_button(btn)
|
||||||
@ -25,11 +24,14 @@ from buttondecoder import ButtonDecoder
|
|||||||
|
|
||||||
from json import dumps
|
from json import dumps
|
||||||
from fastapi import FastAPI, WebSocket, Request
|
from fastapi import FastAPI, WebSocket, Request
|
||||||
from fastapi.responses import PlainTextResponse, JSONResponse
|
from fastapi.responses import PlainTextResponse, JSONResponse, HTMLResponse
|
||||||
from asyncio import create_task, CancelledError, Queue
|
from fastapi.staticfiles import StaticFiles
|
||||||
|
from asyncio import create_task, CancelledError, Queue, sleep
|
||||||
from uvicorn import run
|
from uvicorn import run
|
||||||
|
import os
|
||||||
|
|
||||||
app = FastAPI()
|
app = FastAPI()
|
||||||
|
app.mount("/static", StaticFiles(directory="static"), name="static")
|
||||||
background_tasks = []
|
background_tasks = []
|
||||||
|
|
||||||
tunerlist = TunerList()
|
tunerlist = TunerList()
|
||||||
@ -99,6 +101,12 @@ async def shutdown_event():
|
|||||||
for task in background_tasks:
|
for task in background_tasks:
|
||||||
task.cancel()
|
task.cancel()
|
||||||
|
|
||||||
|
@app.get("/", response_class=HTMLResponse)
|
||||||
|
async def root():
|
||||||
|
html_file_path = os.path.join(os.getcwd(), "static", "index.html")
|
||||||
|
with open(html_file_path, "r") as file:
|
||||||
|
return file.read()
|
||||||
|
|
||||||
@app.websocket("/ws")
|
@app.websocket("/ws")
|
||||||
async def websocket_endpoint(websocket: WebSocket):
|
async def websocket_endpoint(websocket: WebSocket):
|
||||||
global state_to_send
|
global state_to_send
|
||||||
@ -120,5 +128,26 @@ async def emulated_button(request: Request):
|
|||||||
print("CD Changer button: ", btn)
|
print("CD Changer button: ", btn)
|
||||||
buttons.queue.put_nowait(btn)
|
buttons.queue.put_nowait(btn)
|
||||||
|
|
||||||
|
@app.get("/settext", response_class=JSONResponse)
|
||||||
|
async def set_text(request: Request):
|
||||||
|
text = request.query_params.get("txt")
|
||||||
|
tunerlist.set_text(text)
|
||||||
|
return dumps(state_to_send)
|
||||||
|
|
||||||
|
@app.get("/connect", response_class=PlainTextResponse)
|
||||||
|
async def connect_aa(request: Request):
|
||||||
|
ip = request.query_params.get("ip")
|
||||||
|
queue.put_nowait({"wireless_aa_ip": ip})
|
||||||
|
return ip
|
||||||
|
|
||||||
|
@app.get("/aabtn", response_class=PlainTextResponse)
|
||||||
|
async def aabtn(request: Request):
|
||||||
|
btn = request.query_params.get("btn")
|
||||||
|
queue.put_nowait({"button": {"btn": btn, "state": 0}})
|
||||||
|
await sleep(0.2)
|
||||||
|
queue.put_nowait({"button": {"btn": btn, "state": 1}})
|
||||||
|
return btn
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
run(app=app, host="0.0.0.0", port=5959, log_level="info")
|
run(app=app, host="0.0.0.0", port=5959, log_level="info")
|
||||||
|
60
tunerlistd/static/index.html
Normal file
60
tunerlistd/static/index.html
Normal file
@ -0,0 +1,60 @@
|
|||||||
|
<!DOCTYPE html>
|
||||||
|
<html lang="en">
|
||||||
|
<head>
|
||||||
|
<meta charset="UTF-8">
|
||||||
|
<title>AA Button Panel</title>
|
||||||
|
<style>
|
||||||
|
body {
|
||||||
|
font-family: Arial, sans-serif;
|
||||||
|
padding: 20px;
|
||||||
|
background-color: #f4f4f4;
|
||||||
|
}
|
||||||
|
.button-grid {
|
||||||
|
display: grid;
|
||||||
|
grid-template-columns: repeat(auto-fit, minmax(120px, 1fr));
|
||||||
|
gap: 10px;
|
||||||
|
}
|
||||||
|
button {
|
||||||
|
padding: 10px 20px;
|
||||||
|
font-size: 16px;
|
||||||
|
border: none;
|
||||||
|
background-color: #007bff;
|
||||||
|
color: white;
|
||||||
|
border-radius: 8px;
|
||||||
|
cursor: pointer;
|
||||||
|
transition: background-color 0.2s ease;
|
||||||
|
}
|
||||||
|
button:hover {
|
||||||
|
background-color: #0056b3;
|
||||||
|
}
|
||||||
|
</style>
|
||||||
|
</head>
|
||||||
|
<body>
|
||||||
|
|
||||||
|
<h1>Android Auto Button Panel</h1>
|
||||||
|
<div class="button-grid">
|
||||||
|
<!-- Buttons will be inserted here by JavaScript -->
|
||||||
|
</div>
|
||||||
|
|
||||||
|
<script>
|
||||||
|
const buttons = [
|
||||||
|
"ENTER", "LEFT", "RIGHT", "UP", "DOWN", "BACK", "HOME", "PHONE", "CALL_END",
|
||||||
|
"PLAY", "PAUSE", "PREV_TRACK", "NEXT_TRACK", "TOGGLE_PLAY", "VOICE", "WHEEL_LEFT", "WHEEL_RIGHT"
|
||||||
|
];
|
||||||
|
|
||||||
|
const container = document.querySelector('.button-grid');
|
||||||
|
|
||||||
|
buttons.forEach(btn => {
|
||||||
|
const button = document.createElement('button');
|
||||||
|
button.textContent = btn;
|
||||||
|
button.onclick = () => {
|
||||||
|
fetch(`http://192.168.1.50:5959/aabtn?btn=${btn}`)
|
||||||
|
.then(response => console.log(`Sent: ${btn}, Status: ${response.status}`))
|
||||||
|
.catch(error => console.error(`Error sending ${btn}:`, error));
|
||||||
|
};
|
||||||
|
container.appendChild(button);
|
||||||
|
});
|
||||||
|
</script>
|
||||||
|
|
||||||
|
</body>
|
||||||
|
</html>
|
@ -108,5 +108,8 @@ class TunerList:
|
|||||||
except CancelledError:
|
except CancelledError:
|
||||||
return
|
return
|
||||||
|
|
||||||
|
def set_text(self, text):
|
||||||
|
self.queue.put_nowait(TunerListState(text, self.preset))
|
||||||
|
|
||||||
async def run(self):
|
async def run(self):
|
||||||
self.future = await get_event_loop().run_in_executor(self.executor, self._run)
|
self.future = await get_event_loop().run_in_executor(self.executor, self._run)
|
Loading…
x
Reference in New Issue
Block a user