Port NiimBlue label designer to Fichero D11s with local BLE protocol library

This commit is contained in:
Hamza
2026-03-01 22:47:16 +01:00
parent b1ff403594
commit 774b02bb99
102 changed files with 16333 additions and 951 deletions

148
web/src/stores.ts Normal file
View File

@@ -0,0 +1,148 @@
import { get, readable, writable } from "svelte/store";
import {
AppConfigSchema,
CsvParamsSchema,
UserFontSchema,
UserIconSchema,
type CsvParams,
type UserFont,
type UserIcon,
type AppConfig,
type AutomationProps,
type ConnectionState,
} from "$/types";
import {
RequestCommandId,
ResponseCommandId,
Utils,
instantiateClient,
type HeartbeatData,
type FicheroClient,
type PrinterInfo,
type PrinterModelMeta,
type RfidInfo,
} from "$/lib/fichero";
import { Toasts } from "$/utils/toasts";
import { tr } from "$/utils/i18n";
import { LocalStoragePersistence, writablePersisted } from "$/utils/persistence";
import { APP_CONFIG_DEFAULTS, CSV_DEFAULT, OBJECT_DEFAULTS_TEXT } from "$/defaults";
import z from "zod";
import { FileUtils } from "$/utils/file_utils";
export const fontCache = writable<string[]>([OBJECT_DEFAULTS_TEXT.fontFamily]);
export const appConfig = writablePersisted<AppConfig>("config", AppConfigSchema, APP_CONFIG_DEFAULTS);
export const userIcons = writablePersisted<UserIcon[]>("user_icons", z.array(UserIconSchema), []);
export const userFonts = writablePersisted<UserFont[]>("user_fonts", z.array(UserFontSchema), []);
export const loadedFonts = writable<FontFace[]>([]);
export const connectionState = writable<ConnectionState>("disconnected");
export const connectedPrinterName = writable<string>("");
export const printerClient = writable<FicheroClient>();
export const heartbeatData = writable<HeartbeatData>();
export const printerInfo = writable<PrinterInfo>();
export const rfidInfo = writable<RfidInfo | undefined>();
export const ribbonRfidInfo = writable<RfidInfo | undefined>();
export const printerMeta = writable<PrinterModelMeta | undefined>();
export const heartbeatFails = writable<number>(0);
export const csvData = writablePersisted<CsvParams>("csv_params", CsvParamsSchema, { data: CSV_DEFAULT });
userFonts.subscribe(FileUtils.loadFonts);
export const automation = readable<AutomationProps | undefined>(
(() => {
try {
return LocalStoragePersistence.loadAutomation() ?? undefined;
} catch (e) {
console.error(e);
}
return undefined;
})(),
);
export const refreshRfidInfo = () => {
const client = get(printerClient);
if (!client) {
return;
}
client.abstraction.rfidInfo().then(rfidInfo.set).catch(console.error);
client.abstraction
.rfidInfo2()
.then(ribbonRfidInfo.set)
.catch(() => {});
};
export const initClient = () => {
printerClient.update((prevClient: FicheroClient) => {
let newClient: FicheroClient = prevClient;
if (prevClient !== undefined) {
prevClient.disconnect();
}
newClient = instantiateClient();
const conf = get(appConfig);
if (conf.packetIntervalMs !== undefined) {
newClient.setPacketInterval(conf.packetIntervalMs);
}
newClient.on("packetsent", (e) => {
console.log(`>> ${Utils.bufToHex(e.packet.toBytes())} (${RequestCommandId[e.packet.command]})`);
});
newClient.on("packetreceived", (e) => {
console.log(`<< ${Utils.bufToHex(e.packet.toBytes())} (${ResponseCommandId[e.packet.command]})`);
});
newClient.on("connect", (e) => {
console.log("onConnect");
heartbeatFails.set(0);
connectionState.set("connected");
connectedPrinterName.set(e.info.deviceName ?? "unknown");
});
newClient.on("printerinfofetched", (e) => {
console.log("printerInfoFetched");
printerInfo.set(e.info);
printerMeta.set(newClient.getModelMetadata());
});
newClient.on("disconnect", () => {
console.log("onDisconnect");
connectionState.set("disconnected");
connectedPrinterName.set("");
printerInfo.set({});
printerMeta.set(undefined);
});
newClient.on("heartbeat", (e) => {
heartbeatFails.set(0);
heartbeatData.update((prev) => {
if (
prev?.paperRfidSuccess !== e.data?.paperRfidSuccess ||
prev?.ribbonRfidSuccess !== e.data?.ribbonRfidSuccess
) {
refreshRfidInfo();
}
return e.data;
});
});
newClient.on("heartbeatfailed", (e) => {
const maxFails = 5;
heartbeatFails.set(e.failedAttempts);
console.warn(`Heartbeat failed ${e.failedAttempts}/${maxFails}`);
if (e.failedAttempts >= maxFails) {
Toasts.error(get(tr)("connector.disconnect.heartbeat"));
newClient.disconnect();
}
});
return newClient;
});
};