- initialize tcp communication with brew app - WIP value editor sync Signed-off-by: pakintada@gmail.com <Pakin>
243 lines
6.6 KiB
Svelte
243 lines
6.6 KiB
Svelte
<script lang="ts">
|
|
import * as Tabs from '$lib/components/ui/tabs/index';
|
|
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 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 {
|
|
latestRecipeToppingData,
|
|
materialFromMachineQuery,
|
|
materialFromServerQuery
|
|
} from '$lib/core/stores/recipeStore';
|
|
import { generateIcing } from '$lib/helpers/icingGen';
|
|
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 {
|
|
recipeData,
|
|
onPendingChange,
|
|
refPage
|
|
}: { recipeData: any; onPendingChange: any; refPage: string } = $props();
|
|
|
|
let menuName: string = $state('');
|
|
|
|
let materialSnapshot: any = $state();
|
|
let machineInfoSnapshot: any = $state();
|
|
|
|
let recipeListMatState: RecipelistMaterial[] = $state([]);
|
|
let recipeListOriginal: RecipelistMaterial[] = $state([]);
|
|
|
|
let toppingSlotState: any = $state([]);
|
|
|
|
const recipeDetailDispatch = createEventDispatcher();
|
|
|
|
function remappingToColumn(data: any[]): RecipelistMaterial[] {
|
|
let ret: RecipelistMaterial[] = [];
|
|
// expect recipelist
|
|
if (materialSnapshot) {
|
|
let d_cnt = 0;
|
|
for (let rpl of data) {
|
|
let mat = materialSnapshot.filter(
|
|
(x: any) => x['id'].toString() === rpl['materialPathId'].toString()
|
|
)[0];
|
|
|
|
// console.log('mat filter get', Object(mat), Object.keys(mat));
|
|
|
|
let name = mat ? mat['materialOtherName'] : rpl['materialPathId'];
|
|
|
|
if (rpl['materialPathId'] === 0) {
|
|
name = '-';
|
|
}
|
|
|
|
// let gen_id = generateRowId();
|
|
|
|
// console.log(`generated for ${rpl['materialPathId']} = ${gen_id}`);
|
|
|
|
ret.push({
|
|
id: d_cnt,
|
|
material_id: `${name} (${rpl['materialPathId']})`,
|
|
is_use: rpl['isUse'],
|
|
values: {
|
|
string_param: rpl['StringParam'],
|
|
mix_order: rpl['MixOrder'],
|
|
stir_time: rpl['stirTime'],
|
|
feed: {
|
|
pattern: rpl['FeedPattern'],
|
|
parameter: rpl['FeedParameter']
|
|
},
|
|
powder: {
|
|
gram: rpl['powderGram'],
|
|
time: rpl['powderTime']
|
|
},
|
|
syrup: {
|
|
gram: rpl['syrupGram'],
|
|
time: rpl['syrupTime']
|
|
},
|
|
water: {
|
|
cold: rpl['waterCold'],
|
|
yield: rpl['waterYield']
|
|
}
|
|
}
|
|
});
|
|
d_cnt++;
|
|
}
|
|
}
|
|
|
|
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) {
|
|
recipeListOriginal = original;
|
|
}
|
|
|
|
if (original !== recipeListMatState) {
|
|
await onPendingChange({
|
|
target: 'recipeList',
|
|
value: original
|
|
});
|
|
}
|
|
}
|
|
|
|
onMount(() => {
|
|
machineInfoSnapshot = get(machineInfoStore);
|
|
|
|
if (recipeData) {
|
|
menuName =
|
|
recipeData['name'] ?? (recipeData['otherName'] ? recipeData['otherName'] : 'Not set');
|
|
|
|
if (refPage == 'overview') {
|
|
materialSnapshot = get(materialFromServerQuery);
|
|
} else if (refPage == 'brew') {
|
|
materialSnapshot = get(materialFromMachineQuery);
|
|
}
|
|
|
|
recipeListMatState = remappingToColumn(recipeData['recipes']);
|
|
toppingSlotState = recipeData['ToppingSet'];
|
|
|
|
latestRecipeToppingData.set(toppingSlotState);
|
|
|
|
// save old value\
|
|
}
|
|
});
|
|
</script>
|
|
|
|
<!-- show info -->
|
|
<!-- latest edit date -->
|
|
<!-- Menu Status -->
|
|
|
|
<div class="-mb-4 flex w-full flex-col gap-6">
|
|
<Tabs.Root value="info">
|
|
<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>
|
|
<Card.Header>
|
|
<Card.Title>Info</Card.Title>
|
|
<Card.Description>Info about this menu</Card.Description>
|
|
</Card.Header>
|
|
|
|
<Card.Content class="grid gap-6">
|
|
<div class="grid grid-flow-row gap-3">
|
|
<Label for="tabs-menu-name">Name</Label>
|
|
<Input id="tabs-menu-name" value={recipeData['name'] ?? ''} />
|
|
<Label for="tabs-menu-other-name">Other Name</Label>
|
|
<Input id="tabs-menu-other-name" value={recipeData['otherName'] ?? ''} />
|
|
</div>
|
|
|
|
<div class="grid gap-3"></div>
|
|
</Card.Content>
|
|
</Card.Root>
|
|
</Tabs.Content>
|
|
|
|
<Tabs.Content value="details">
|
|
<RecipelistTable data={recipeListMatState} {columns} onStateChange={checkChanges} />
|
|
</Tabs.Content>
|
|
</Tabs.Root>
|
|
</div>
|