Skip to content
File

Blob: worker/src/shared/contracts/robot.ts

typescript73 lines
1import { z } from 'zod';
2import { nowPlayingSchema } from './track.ts';
3import { hardwareSchema } from './hardware.ts';
4 
5const count = z.number().int().nonnegative();
6export const rgbSchema = z.tuple([
7 z.number().int().min(0).max(255),
8 z.number().int().min(0).max(255),
9 z.number().int().min(0).max(255),
10]);
11export const spectrumStatsSchema = z.object({
12 source: z.string().max(32),
13 fftSize: count,
14 core: count,
15 sampleRate: count,
16 frames: count,
17 errors: count,
18 inputDropped: count,
19 outputDropped: count,
20 meanUs: count,
21 maxUs: count,
22 stackFree: count.optional(),
23});
24export const telemetrySchema = z.object({
25 event: z.literal('telemetry'),
26 firmware: z.string().max(32),
27 sequence: count,
28 uptimeMs: count,
29 positionMs: count,
30 durationMs: count.positive(),
31 playbackRevision: count.max(0xffff_ffff).optional(),
32 paused: z.boolean(),
33 rssi: z.number().int().min(-127).max(0).nullable(),
34 heap: count,
35 hardware: hardwareSchema.nullish(),
36 stackFree: count.optional(),
37 led: rgbSchema,
38 audioErrors: count,
39 dataErrors: count,
40 skippedFrames: count,
41 spectrum: spectrumStatsSchema.optional(),
42 music: z
43 .object({ cacheBytes: count, indexBytes: count, reads: count, maxReadUs: count })
44 .optional(),
45});
46export const ackSchema = z.object({
47 event: z.literal('ack'),
48 command_id: z.string().max(64),
49 result: z.number().int(),
50 led: rgbSchema,
51 paused: z.boolean(),
52});
53export const nowPlayingMessageSchema = z.object({
54 event: z.literal('nowPlaying'),
55 nowPlaying: nowPlayingSchema,
56});
57export const robotMessageSchema = z.discriminatedUnion('event', [
58 telemetrySchema,
59 ackSchema,
60 nowPlayingMessageSchema,
61]);
62export const commandSchema = z.union([
63 z.object({ led: rgbSchema }).strict(),
64 z.object({ action: z.enum(['play', 'pause', 'restart', 'next']) }).strict(),
65]);
66 
67export type RGB = z.infer<typeof rgbSchema>;
68export type SpectrumStats = z.infer<typeof spectrumStatsSchema>;
69export type Telemetry = z.infer<typeof telemetrySchema>;
70export type Ack = z.infer<typeof ackSchema>;
71export type Command = z.infer<typeof commandSchema>;
72export type RobotMessage = z.infer<typeof robotMessageSchema>;