seahaven-door-unlock-api/lambda/blf-sync/slot-contract.ts
Adam Moussa c23f990c6f
feat(phones): add T57W door-unlock-with-sp template (#87)
* feat(phones): add T57W door-unlock-with-sp template

* feat: add firmware dir and add latest 3cx supported yealink firmware
2026-09-03 22:56:04 +00:00

93 lines
2.5 KiB
TypeScript

export type TemplateId =
| "t54w-door-unlock"
| "t54w-door-unlock-with-sp"
| "t57w-door-unlock-with-sp"
| "t58w-door-unlock";
export interface SharedParkingSlot {
readonly blfNo: number;
readonly value: string;
}
export interface SlotContract {
readonly reserved: readonly number[];
readonly sharedParking: readonly SharedParkingSlot[];
readonly ownLine: number;
readonly managedStart: number;
readonly managedEnd: number;
}
export const SLOT_CONTRACT: Record<TemplateId, SlotContract> = {
"t54w-door-unlock": {
reserved: [2],
sharedParking: [],
ownLine: 1,
managedStart: 3,
managedEnd: 12,
},
"t54w-door-unlock-with-sp": {
reserved: [2],
sharedParking: [
{ blfNo: 3, value: "SP1" },
{ blfNo: 4, value: "SP2" },
{ blfNo: 5, value: "SP3" },
],
ownLine: 1,
managedStart: 6,
managedEnd: 15,
},
"t57w-door-unlock-with-sp": {
reserved: [2],
sharedParking: [
{ blfNo: 3, value: "SP1" },
{ blfNo: 4, value: "SP2" },
{ blfNo: 5, value: "SP3" },
],
ownLine: 1,
managedStart: 6,
managedEnd: 15,
},
"t58w-door-unlock": {
reserved: [2, 3, 4],
sharedParking: [],
ownLine: 1,
managedStart: 5,
managedEnd: 14,
},
};
const TEMPLATE_MATCHERS: { id: TemplateId; needle: string }[] = [
{ id: "t57w-door-unlock-with-sp", needle: "yealinkT57W-door-unlock-with-sp" },
{ id: "t54w-door-unlock-with-sp", needle: "yealinkT54W-door-unlock-with-sp" },
{ id: "t54w-door-unlock", needle: "yealinkT54W-door-unlock" },
{ id: "t58w-door-unlock", needle: "yealinkT58W-door-unlock" },
];
export function resolveTemplateId(...candidates: Array<string | undefined | null>): TemplateId | undefined {
const haystack = candidates.filter(Boolean).join(" ");
if (!haystack) {
return undefined;
}
for (const matcher of TEMPLATE_MATCHERS) {
if (haystack.includes(matcher.needle)) {
return matcher.id;
}
}
return undefined;
}
export function isManagedSlot(contract: SlotContract, blfNo: number): boolean {
return blfNo >= contract.managedStart && blfNo <= contract.managedEnd;
}
export function isReservedSlot(contract: SlotContract, blfNo: number): boolean {
return contract.reserved.includes(blfNo);
}
export function isSharedParkingSlot(contract: SlotContract, blfNo: number): boolean {
return contract.sharedParking.some((slot) => slot.blfNo === blfNo);
}
export function managedSlotCount(contract: SlotContract): number {
return contract.managedEnd - contract.managedStart + 1;
}