Skip to content

Commit

Permalink
treadmill
Browse files Browse the repository at this point in the history
  • Loading branch information
AlanRosenthal committed Jul 16, 2024
1 parent 5aae44b commit 5e060a2
Show file tree
Hide file tree
Showing 4 changed files with 440 additions and 0 deletions.
3 changes: 3 additions & 0 deletions web/treadmill/treadmill.css
Original file line number Diff line number Diff line change
@@ -0,0 +1,3 @@
body {
font-family: monospace;
}
24 changes: 24 additions & 0 deletions web/treadmill/treadmill.html
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
<!DOCTYPE html>
<html>
<head>
<link rel="stylesheet" href="https://fonts.googleapis.com/icon?family=Material+Icons">
<link rel="stylesheet" href="treadmill.css">
<script src="https://cdn.jsdelivr.net/pyodide/v0.24.1/full/pyodide.js"></script>
<script type="module" src="../ui.js"></script>
<script type="module" src="treadmill.js"></script>
</style>
</style>
</head>
<body>
<script type="module">
import {LitElement, html} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js';
</script>

<bumble-controls id="bumble-controls"></bumble-controls><hr>
<textarea id="log-output" style="width: 100%;" rows="10" disabled></textarea><hr>
<scan-list id="scan-list"></scan-list>
<connection-info id="connection-info" style="display:none"></connection-info>
<security-request id="security-request" style="display:none"></security-request>
<treadmill-values id="treadmill-values"></treadmill-values>
</body>
</html>
241 changes: 241 additions & 0 deletions web/treadmill/treadmill.js
Original file line number Diff line number Diff line change
@@ -0,0 +1,241 @@
import {LitElement, html, css} from 'https://cdn.jsdelivr.net/gh/lit/dist@2/core/lit-core.min.js';
import {setupSimpleApp} from '../bumble.js';

class ScanList extends LitElement {
static properties = {
listItems: {state: true},
};

static styles = css`
table, th, td {
padding: 2px;
white-space: pre;
border: 1px solid black;
border-collapse: collapse;
}
`;

constructor() {
super();
this.listItems = [];
}

render() {
if (this.listItems.length === 0) {
return '';
}
return html`
<table>
<thead>
<tr>
<th>Address</th>
<th>Address Type</th>
<th>RSSI</th>
<th>Data</th>
<th>Connect</th>
</tr>
</thead>
<tbody>
${this.listItems.map(i => html`
<tr>
<td>${i['address']}</td>
<td>${i['address_type']}</td>
<td>${i['rssi']}</td>
<td>${i['data']}</td>
<td><button @click="${() => onConnectButton(i['address'])}">Connect</button></td>
</tr>
`)}
</tbody>
</table>
`;
}
}
customElements.define('scan-list', ScanList);


class ConnectionInfo extends LitElement {
static properties = {
handle: {state: true},
role_names: {state: true},
self_address: {state: true},
peer_address: {state: true},
is_encrypted: {state: true},
};

static styles = css`
div {
border: 1px solid black;
border-collapse: collapse;
}
`;

constructor() {
super();
this.handle = 0;
this.role = "UNKNOWN";
this.self_address = "00:00:00:00:00:00"
this.peer_address = "FF:FF:FF:FF:FF:FF"
this.is_encrypted = "No"
}

render() {
return html`
<div>
<b>Connection Info</b><br \>
Handle: ${this.handle}<br \>
Role: ${this.role}<br \>
Self Address: ${this.self_address}<br \>
Peer Address: ${this.peer_address}<br \>
Is Encrypted: ${this.is_encrypted}<br \>
</div>
`;
}
}
customElements.define('connection-info', ConnectionInfo);

class TreadmillValues extends LitElement {
static properties = {
listValues: {state: Array},
};

static styles = css`
table {
padding: 2px;
white-space: pre;
border: 1px solid black;
border-collapse: collapse;
}
`;

constructor() {
super();
this.listValues = [];
}

addValue(value) {
this.listValues = [value, ...this.listValues];
}

render() {
if (this.listValues.length === 0) {
return '';
}
return html`
<table>
<thead>
<tr>
<th>Time</th>
<th>Value</th>
</tr>
</thead>
<tbody>
${this.listValues.map(i => html`
<tr>
<td>${i['time']}</td>
<td>${i['value']}</td>
</tr>
`)}
</tbody>
</table>
`;
}
}
customElements.define('treadmill-values', TreadmillValues);

class SecurityRequest extends LitElement {
static properties = {
handle: {state: true},
role_names: {state: true},
self_address: {state: true},
peer_address: {state: true},
is_encrypted: {state: true},
};

static styles = css`
div {
border: 1px solid black;
border-collapse: collapse;
}
`;

constructor() {
super();
this.handle = 0;
this.role = "UNKNOWN";
this.self_address = "00:00:00:00:00:00"
this.peer_address = "FF:FF:FF:FF:FF:FF"
this.is_encrypted = "No"
}

render() {
return html`
<div>
<b>Pair?</b><br \>
<Button @click="${() => onPairButton(true)}">YES</Button>
<Button @click="${() => onPairButton(false)}">NO</Button>
</div>
`;
}
}
customElements.define('security-request', SecurityRequest);

const logOutput = document.querySelector('#log-output');
function logToOutput(message) {
console.log(message);
logOutput.value += message + '\n';
}

// Setup the UI
const scanList = document.querySelector('#scan-list');
const connectionInfo = document.querySelector('#connection-info');
const bumbleControls = document.querySelector('#bumble-controls');
const treadmillValues = document.querySelector('#treadmill-values');
const securityRequest = document.querySelector('#security-request');

// Setup the app
const app = await setupSimpleApp('treadmill.py', bumbleControls, logToOutput);
app.on('scanning_updates', onScanningUpdates);
app.on('hr_updates', onHrUpdates);
app.on('connection_updates', onConnectionUpdates)
app.on('on_security_request', onSecurityRequest)
logToOutput('Click the Bluetooth button to start');

function onScanningUpdates(scanResults) {
const items = scanResults.toJs({create_proxies : false}).map(entry => (
{ address: entry.address, address_type: entry.address_type, rssi: entry.rssi, data: entry.data }
));
scanResults.destroy();
scanList.listItems = items;
}

function onHrUpdates(hrResults) {
const items = hrResults.toJs({create_proxies : false})
treadmillValues.addValue({value: items.get('value'), time: items.get('time')})
hrResults.destroy();
}

function onConnectButton(address) {
app.do_connect(address)
}

function onSecurityRequest() {
securityRequest.style.display = 'block'
}

function onPairButton(value) {
app.do_security_request_response(value)
securityRequest.style.display = 'none'
}

function onConnectionUpdates(connection) {
const items = connection.toJs({create_proxies : false})
console.log(items)
connection.destroy();
scanList.style.display = 'none'
connectionInfo.style.display = 'block'
connectionInfo.handle = items.get('handle')
connectionInfo.role = items.get('role')
connectionInfo.self_address = items.get('self_address')
connectionInfo.peer_address = items.get('peer_address')
connectionInfo.is_encrypted = items.get('is_encrypted')
}
Loading

0 comments on commit 5e060a2

Please sign in to comment.