mirror of
https://github.com/CharaChorder/DeviceManager.git
synced 2026-01-10 03:52:57 +00:00
serial pairing
This commit is contained in:
@@ -5,7 +5,7 @@
|
|||||||
"scripts": {
|
"scripts": {
|
||||||
"dev": "vite dev",
|
"dev": "vite dev",
|
||||||
"build": "vite build",
|
"build": "vite build",
|
||||||
"deploy": "npm run build && gh-pages -d build",
|
"deploy": "npm run build && gh-pages -d build -t true",
|
||||||
"preview": "vite preview",
|
"preview": "vite preview",
|
||||||
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
"check": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json",
|
||||||
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./jsconfig.json --watch",
|
||||||
|
|||||||
@@ -1,4 +1,5 @@
|
|||||||
import {writable} from "svelte/store"
|
import {writable} from "svelte/store"
|
||||||
|
import {CharaDevice} from "$lib/serial/device.js"
|
||||||
|
|
||||||
/** @type {import('svelte/store').Writable<import('./device.js').CharaDevice>} */
|
/** @type {import('svelte/store').Writable<import('./device.js').CharaDevice>} */
|
||||||
export const serialPort = writable()
|
export const serialPort = writable()
|
||||||
@@ -11,3 +12,21 @@ export const chords = writable([])
|
|||||||
|
|
||||||
/** @type {import('svelte/store').Writable<boolean>} */
|
/** @type {import('svelte/store').Writable<boolean>} */
|
||||||
export const syncing = writable(false)
|
export const syncing = writable(false)
|
||||||
|
|
||||||
|
/** @type {CharaDevice} */
|
||||||
|
let device // @hmr:keep
|
||||||
|
|
||||||
|
export async function initSerial() {
|
||||||
|
syncing.set(true)
|
||||||
|
device ??= new CharaDevice()
|
||||||
|
serialPort.set(device)
|
||||||
|
|
||||||
|
const chordCount = await device.getChordCount()
|
||||||
|
const chordInfo = []
|
||||||
|
for (let i = 0; i < chordCount; i++) {
|
||||||
|
chordInfo.push(await device.getChord(i))
|
||||||
|
}
|
||||||
|
chordInfo.sort(({phrase: a}, {phrase: b}) => a.localeCompare(b))
|
||||||
|
chords.set(chordInfo)
|
||||||
|
syncing.set(false)
|
||||||
|
}
|
||||||
|
|||||||
@@ -2,6 +2,15 @@ import {LineBreakTransformer} from "$lib/serial/line-break-transformer.js"
|
|||||||
import {serialLog} from "$lib/serial/connection.js"
|
import {serialLog} from "$lib/serial/connection.js"
|
||||||
import {ACTION_MAP} from "$lib/serial/webserial/constants/action-map.js"
|
import {ACTION_MAP} from "$lib/serial/webserial/constants/action-map.js"
|
||||||
|
|
||||||
|
export const VENDOR_ID = 0x239a
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @returns {Promise<boolean>}
|
||||||
|
*/
|
||||||
|
export async function hasSerialPermission() {
|
||||||
|
return navigator.serial.getPorts().then(it => it.length > 0)
|
||||||
|
}
|
||||||
|
|
||||||
export class CharaDevice {
|
export class CharaDevice {
|
||||||
/** @type {Promise<SerialPort>} */
|
/** @type {Promise<SerialPort>} */
|
||||||
#port
|
#port
|
||||||
@@ -26,7 +35,9 @@ export class CharaDevice {
|
|||||||
*/
|
*/
|
||||||
constructor(baudRate = 115200) {
|
constructor(baudRate = 115200) {
|
||||||
this.#port = navigator.serial.getPorts().then(async ports => {
|
this.#port = navigator.serial.getPorts().then(async ports => {
|
||||||
const port = ports.find(it => it.getInfo().usbVendorId === 0x239a)
|
const port =
|
||||||
|
ports.find(it => it.getInfo().usbVendorId === VENDOR_ID) ??
|
||||||
|
(await navigator.serial.requestPort({filters: [{usbVendorId: VENDOR_ID}]}))
|
||||||
await port.open({baudRate})
|
await port.open({baudRate})
|
||||||
const info = port.getInfo()
|
const info = port.getInfo()
|
||||||
serialLog.update(it => {
|
serialLog.update(it => {
|
||||||
|
|||||||
@@ -4,11 +4,8 @@
|
|||||||
import {onMount} from "svelte"
|
import {onMount} from "svelte"
|
||||||
import {applyTheme, argbFromHex, themeFromSourceColor} from "@material/material-color-utilities"
|
import {applyTheme, argbFromHex, themeFromSourceColor} from "@material/material-color-utilities"
|
||||||
import Navigation from "$lib/components/Navigation.svelte"
|
import Navigation from "$lib/components/Navigation.svelte"
|
||||||
import {chords, serialPort, syncing} from "$lib/serial/connection.js"
|
import {hasSerialPermission} from "$lib/serial/device.js"
|
||||||
import {CharaDevice} from "$lib/serial/device.js"
|
import {initSerial} from "$lib/serial/connection.js"
|
||||||
|
|
||||||
/** @type {import('$lib/serial/device.js').CharaDevice} */
|
|
||||||
let device // @hmr:keep
|
|
||||||
|
|
||||||
onMount(async () => {
|
onMount(async () => {
|
||||||
const theme = themeFromSourceColor(argbFromHex("#6D81C7"), [
|
const theme = themeFromSourceColor(argbFromHex("#6D81C7"), [
|
||||||
@@ -17,18 +14,7 @@
|
|||||||
const dark = true // window.matchMedia("(prefers-color-scheme: dark)").matches
|
const dark = true // window.matchMedia("(prefers-color-scheme: dark)").matches
|
||||||
applyTheme(theme, {target: document.body, dark})
|
applyTheme(theme, {target: document.body, dark})
|
||||||
|
|
||||||
syncing.set(true)
|
if (await hasSerialPermission()) await initSerial()
|
||||||
device ??= new CharaDevice()
|
|
||||||
serialPort.set(device)
|
|
||||||
|
|
||||||
const chordCount = await device.getChordCount()
|
|
||||||
const chordInfo = []
|
|
||||||
for (let i = 0; i < chordCount; i++) {
|
|
||||||
chordInfo.push(await device.getChord(i))
|
|
||||||
}
|
|
||||||
chordInfo.sort(({phrase: a}, {phrase: b}) => a.localeCompare(b))
|
|
||||||
chords.set(chordInfo)
|
|
||||||
syncing.set(false)
|
|
||||||
})
|
})
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
|
|||||||
@@ -1,6 +1,7 @@
|
|||||||
<script>
|
<script>
|
||||||
import {serialPort} from "$lib/serial/connection.js"
|
import {initSerial, serialPort} from "$lib/serial/connection.js"
|
||||||
import Terminal from "$lib/components/Terminal.svelte"
|
import Terminal from "$lib/components/Terminal.svelte"
|
||||||
|
import {browser} from "$app/environment"
|
||||||
</script>
|
</script>
|
||||||
|
|
||||||
<svelte:head>
|
<svelte:head>
|
||||||
@@ -11,15 +12,15 @@
|
|||||||
|
|
||||||
<div class="device-grid">
|
<div class="device-grid">
|
||||||
<div class="row">
|
<div class="row">
|
||||||
<button class="secondary">
|
{#if $serialPort === undefined}
|
||||||
{#if $serialPort}
|
<button class="secondary" disabled={browser && !("serial" in navigator)} on:click={initSerial}>
|
||||||
<span class="icon">usb_off</span> Disconnect
|
<span class="icon">usb</span>Pair
|
||||||
{:else}
|
|
||||||
<span class="icon">usb</span> Connect
|
|
||||||
{/if}
|
|
||||||
</button>
|
</button>
|
||||||
<button title="Reboot" class="icon">restart_alt</button>
|
{/if}
|
||||||
<button class="icon" title="Reboot to bootloader">rule_settings</button>
|
<button title="Reboot" class="icon" disabled={$serialPort === undefined}>restart_alt</button>
|
||||||
|
<button title="Reboot to bootloader" class="icon" disabled={$serialPort === undefined}
|
||||||
|
>rule_settings</button
|
||||||
|
>
|
||||||
</div>
|
</div>
|
||||||
<div class="terminal">
|
<div class="terminal">
|
||||||
<Terminal />
|
<Terminal />
|
||||||
|
|||||||
Reference in New Issue
Block a user