feat: add brew app connection
- initialize tcp communication with brew app - WIP value editor sync Signed-off-by: pakintada@gmail.com <Pakin>
This commit is contained in:
parent
08f7626dcb
commit
274025ed33
14 changed files with 431 additions and 69 deletions
|
|
@ -12,11 +12,15 @@
|
|||
import { handleIncomingMessages } from '$lib/core/handlers/messageHandler';
|
||||
import { auth as authStore } from '$lib/core/stores/auth';
|
||||
import { get } from 'svelte/store';
|
||||
import { AdbDaemonWebUsbDeviceManager } from '@yume-chan/adb-daemon-webusb';
|
||||
import {
|
||||
AdbDaemonWebUsbDevice,
|
||||
AdbDaemonWebUsbDeviceManager
|
||||
} from '@yume-chan/adb-daemon-webusb';
|
||||
import AdbWebCredentialStore from '@yume-chan/adb-credential-web';
|
||||
import { onMount } from 'svelte';
|
||||
import { deviceCredentialManager } from '$lib/core/adb/deviceCredManager';
|
||||
import { file } from 'zod/mini';
|
||||
import { addNotification } from '$lib/core/stores/noti';
|
||||
|
||||
let { enableComponent = true } = $props();
|
||||
|
||||
|
|
@ -161,6 +165,9 @@
|
|||
} else {
|
||||
console.log('push pull not ok', result);
|
||||
}
|
||||
|
||||
// clean file
|
||||
await adb.executeCmd('rm /sdcard/coffeevending/test.json');
|
||||
}
|
||||
} catch (error) {
|
||||
console.log('test push file failed', error);
|
||||
|
|
@ -205,6 +212,9 @@
|
|||
}
|
||||
|
||||
async function disconnectAdb() {
|
||||
// clean up no password flag
|
||||
// return to engine
|
||||
|
||||
await adb.disconnect();
|
||||
connectionButtonText = 'Connect';
|
||||
connectionButtonVariant = 'default';
|
||||
|
|
@ -313,6 +323,12 @@
|
|||
} catch (ignored) {}
|
||||
}
|
||||
|
||||
if (e instanceof AdbDaemonWebUsbDevice.DeviceBusyError) {
|
||||
addNotification(
|
||||
'ERR:Device is already in use by another program, please close the program and try again'
|
||||
);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
} catch (e: any) {
|
||||
|
|
|
|||
|
|
@ -3,9 +3,11 @@
|
|||
import * as Card from '$lib/components/ui/card/index';
|
||||
import Label from '$lib/components/ui/label/label.svelte';
|
||||
import Input from '$lib/components/ui/input/input.svelte';
|
||||
import { onDestroy, onMount } from 'svelte';
|
||||
import Button from '$lib/components/ui/button/button.svelte';
|
||||
import { createEventDispatcher, onDestroy, onMount } from 'svelte';
|
||||
import RecipelistTable from './recipelist-table.svelte';
|
||||
|
||||
import * as adb from '$lib/core/adb/adb';
|
||||
import { columns, type RecipelistMaterial } from './columns';
|
||||
import { get, readable, writable } from 'svelte/store';
|
||||
import {
|
||||
|
|
@ -17,6 +19,11 @@
|
|||
import { machineInfoStore } from '$lib/core/stores/machineInfoStore';
|
||||
import MachineInfo from '../machine-info.svelte';
|
||||
import { v4 as uuidv4 } from 'uuid';
|
||||
import { addNotification } from '$lib/core/stores/noti';
|
||||
import { env } from '$env/dynamic/public';
|
||||
import { sendCommand, sendReset } from '$lib/core/brew/command';
|
||||
import { isAdbWriterAvailable } from '$lib/core/stores/adbWriter';
|
||||
import { sendToAndroid } from '$lib/core/stores/adbWriter';
|
||||
|
||||
//
|
||||
let {
|
||||
|
|
@ -35,6 +42,8 @@
|
|||
|
||||
let toppingSlotState: any = $state([]);
|
||||
|
||||
const recipeDetailDispatch = createEventDispatcher();
|
||||
|
||||
function remappingToColumn(data: any[]): RecipelistMaterial[] {
|
||||
let ret: RecipelistMaterial[] = [];
|
||||
// expect recipelist
|
||||
|
|
@ -90,6 +99,62 @@
|
|||
return ret;
|
||||
}
|
||||
|
||||
async function getCurrentQueue() {
|
||||
let inst = adb.getAdbInstance();
|
||||
if (inst) {
|
||||
let current_brewing = await adb.pull(env.PUBLIC_BREW_CURRENT_RECIPE);
|
||||
// console.log(`current brewing queue: ${current_brewing}`);
|
||||
if (current_brewing === '') {
|
||||
current_brewing = '{}';
|
||||
}
|
||||
|
||||
return JSON.parse(current_brewing ?? '{}');
|
||||
}
|
||||
|
||||
return {
|
||||
error: 'instance lost'
|
||||
};
|
||||
}
|
||||
|
||||
async function resetAllPendingCmds() {
|
||||
// send reset to brew
|
||||
try {
|
||||
await sendReset();
|
||||
addNotification(`INFO:Reset completed!`);
|
||||
} catch (e) {
|
||||
addNotification(`ERR:${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
async function saveRecipe() {}
|
||||
|
||||
async function sendTriggerBrewNow() {
|
||||
// check queue ready
|
||||
// let currentBrewingQueue = await getCurrentQueue();
|
||||
// console.log('checking queue ... ', Object.keys(currentBrewingQueue).length);
|
||||
|
||||
await sendToAndroid({
|
||||
type: 'brew_prep',
|
||||
payload: {
|
||||
start: new Date().toLocaleTimeString()
|
||||
}
|
||||
});
|
||||
|
||||
// if (Object.keys(currentBrewingQueue).length != 0) {
|
||||
// addNotification('ERR:Brewing queue is full, please check machine or press `reset`');
|
||||
// return;
|
||||
// }
|
||||
|
||||
//
|
||||
let inst = adb.getAdbInstance();
|
||||
if (inst) {
|
||||
console.log('check adb writer', isAdbWriterAvailable());
|
||||
recipeDetailDispatch('brewNow');
|
||||
} else {
|
||||
console.log('result check fail');
|
||||
}
|
||||
}
|
||||
|
||||
async function checkChanges(original: any) {
|
||||
console.log('old', original, 'updated', recipeListMatState);
|
||||
if (recipeListOriginal.length == 0) {
|
||||
|
|
@ -133,10 +198,23 @@
|
|||
|
||||
<div class="-mb-4 flex w-full flex-col gap-6">
|
||||
<Tabs.Root value="info">
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value="info">Info</Tabs.Trigger>
|
||||
<Tabs.Trigger value="details">Details</Tabs.Trigger>
|
||||
</Tabs.List>
|
||||
<div class="flex flex-row justify-between">
|
||||
<Tabs.List>
|
||||
<Tabs.Trigger value="info">Info</Tabs.Trigger>
|
||||
<Tabs.Trigger value="details">Details</Tabs.Trigger>
|
||||
</Tabs.List>
|
||||
{#if refPage === 'brew'}
|
||||
<div>
|
||||
<Button type="button" variant="default" onclick={() => resetAllPendingCmds()}
|
||||
>Force Reset Brewing</Button
|
||||
>
|
||||
<Button type="button" variant="default" onclick={() => saveRecipe()}>Save</Button>
|
||||
<Button type="button" variant="default" onclick={async () => sendTriggerBrewNow()}
|
||||
>Test Brew</Button
|
||||
>
|
||||
</div>
|
||||
{/if}
|
||||
</div>
|
||||
|
||||
<Tabs.Content value="info">
|
||||
<Card.Root>
|
||||
|
|
|
|||
|
|
@ -198,6 +198,8 @@
|
|||
currentRef
|
||||
);
|
||||
|
||||
sheetOpenState = false;
|
||||
} else if (value_event_state === ValueEvent.NONE) {
|
||||
sheetOpenState = false;
|
||||
} else {
|
||||
// set noti
|
||||
|
|
@ -296,7 +298,7 @@
|
|||
|
||||
onMount(() => {
|
||||
sheetOpenState = false;
|
||||
console.log('sheet open? ', sheetOpenState);
|
||||
// console.log('sheet open? ', sheetOpenState);
|
||||
|
||||
let refFrom = get(referenceFromPage);
|
||||
categories = get(
|
||||
|
|
@ -317,16 +319,7 @@
|
|||
});
|
||||
</script>
|
||||
|
||||
<Sheet.Root
|
||||
bind:open={sheetOpenState}
|
||||
onOpenChange={(next) => {
|
||||
if (!next) {
|
||||
beforeClosing();
|
||||
} else {
|
||||
sheetOpenState = true;
|
||||
}
|
||||
}}
|
||||
>
|
||||
<Sheet.Root>
|
||||
<Sheet.Trigger>
|
||||
<Button
|
||||
variant="default"
|
||||
|
|
@ -616,12 +609,12 @@
|
|||
</ScrollArea>
|
||||
|
||||
<!-- final -->
|
||||
<Field.Field orientation="horizontal">
|
||||
<!-- <Field.Field orientation="horizontal">
|
||||
<Button type="button" onclick={() => saveEditingValue()}>Save</Button>
|
||||
<Button variant="outline" type="button" onclick={() => beforeClosing()}
|
||||
<Button variant="outline" type="button" onclick={() => (sheetOpenState = false)}
|
||||
>{warnUserNotSaveChange ? 'Discard Changes' : 'Cancel'}</Button
|
||||
>
|
||||
</Field.Field>
|
||||
</Field.Field> -->
|
||||
</Field.Group>
|
||||
</form>
|
||||
</div>
|
||||
|
|
|
|||
|
|
@ -77,7 +77,7 @@
|
|||
let key = kv[0];
|
||||
let value = kv[1] ?? '';
|
||||
|
||||
console.log('key', key, 'value', value);
|
||||
// console.log('key', key, 'value', value);
|
||||
currentStringParams[key] = value;
|
||||
}
|
||||
}
|
||||
|
|
@ -204,9 +204,9 @@
|
|||
console.log('detect mix order', mat_num);
|
||||
}
|
||||
|
||||
if (feed.parameter > 0 || feed.pattern > 0) {
|
||||
console.log('has feed fields', JSON.stringify(feed));
|
||||
}
|
||||
// if (feed.parameter > 0 || feed.pattern > 0) {
|
||||
// console.log('has feed fields', JSON.stringify(feed));
|
||||
// }
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -9,8 +9,9 @@
|
|||
import { MenuStatus, matchMenuStatus } from '$lib/core/types/menuStatus';
|
||||
|
||||
import * as adb from '$lib/core/adb/adb';
|
||||
|
||||
let open = $state(false);
|
||||
import { addNotification } from '$lib/core/stores/noti';
|
||||
import { sendToAndroid } from '$lib/core/stores/adbWriter';
|
||||
import { env } from '$env/dynamic/public';
|
||||
const isDesktop = new MediaQuery('(min-width: 768px)');
|
||||
|
||||
let currentData: any = $state();
|
||||
|
|
@ -27,6 +28,8 @@
|
|||
refPage: string;
|
||||
} = $props();
|
||||
|
||||
let ready_to_send_brew: any[] = $state([]);
|
||||
|
||||
async function onPendingChange(newChange: { target: string; value: any }) {
|
||||
console.log('detect pending change', matchMenuStatus(currentData.MenuStatus));
|
||||
hasPendingChange = true;
|
||||
|
|
@ -51,6 +54,9 @@
|
|||
console.log('pending change recipe list', newChange);
|
||||
}
|
||||
|
||||
ready_to_send_brew = [];
|
||||
ready_to_send_brew.push([env.PUBLIC_BREW_CURRENT_RECIPE, JSON.stringify(currentData)]);
|
||||
|
||||
// await adb.push('/sdcard/coffeevending/.curr.brewing.json', JSON.stringify(currentData));
|
||||
//
|
||||
//
|
||||
|
|
@ -59,6 +65,23 @@
|
|||
//
|
||||
}
|
||||
|
||||
async function sendBrewNow() {
|
||||
try {
|
||||
await sendToAndroid({
|
||||
type: 'brew',
|
||||
payload: {
|
||||
start: new Date().toLocaleTimeString(),
|
||||
// use this field for unchanged data
|
||||
target: ready_to_send_brew.length == 1 ? '-' : currentData.productCode,
|
||||
// use this field for new or modified data
|
||||
data: ready_to_send_brew.length == 1 ? ready_to_send_brew[0][1] : null
|
||||
}
|
||||
});
|
||||
} catch (e) {
|
||||
addNotification(`ERR:Failed to brewing\n${e}`);
|
||||
}
|
||||
}
|
||||
|
||||
onMount(() => {
|
||||
//
|
||||
if (refPage === 'brew') {
|
||||
|
|
@ -86,7 +109,7 @@
|
|||
</script>
|
||||
|
||||
{#if isDesktop.current}
|
||||
<Dialog.Root bind:open>
|
||||
<Dialog.Root>
|
||||
<Dialog.Trigger class="w-full text-start" onselect={(e) => e.preventDefault()}
|
||||
>View</Dialog.Trigger
|
||||
>
|
||||
|
|
@ -100,7 +123,12 @@
|
|||
</Dialog.Header>
|
||||
|
||||
<!-- render more -->
|
||||
<RecipeDetail recipeData={currentData} {onPendingChange} {refPage} />
|
||||
<RecipeDetail
|
||||
recipeData={currentData}
|
||||
{onPendingChange}
|
||||
{refPage}
|
||||
on:brewNow={async () => sendBrewNow()}
|
||||
/>
|
||||
</Dialog.Content>
|
||||
</Dialog.Root>
|
||||
{:else}
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue