Skip to content

Commit

Permalink
Add basic infrastructure for WLED support in FCS
Browse files Browse the repository at this point in the history
Includes field states as a proof of concept but will clean this up later
  • Loading branch information
jfabellera committed Sep 11, 2024
1 parent 8c82f35 commit f656353
Show file tree
Hide file tree
Showing 7 changed files with 277 additions and 16 deletions.
93 changes: 86 additions & 7 deletions back-end/realtime/package-lock.json

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

4 changes: 3 additions & 1 deletion back-end/realtime/package.json
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,7 @@
"@types/passport-jwt": "^3.0.9",
"@types/passport-local": "^1.0.35",
"@types/uuid": "^9.0.4",
"@types/ws": "^8.5.12",
"@vercel/ncc": "^0.36.1",
"typescript": "^5.1.6"
},
Expand All @@ -34,7 +35,8 @@
"passport-jwt": "^4.0.1",
"passport-local": "^1.0.0",
"socket.io": "^4.7.1",
"winston": "^3.10.0"
"winston": "^3.10.0",
"ws": "^8.18.0"
},
"optionalDependencies": {
"bufferutil": "^4.0.7",
Expand Down
20 changes: 19 additions & 1 deletion back-end/realtime/src/rooms/FCS.ts
Original file line number Diff line number Diff line change
Expand Up @@ -9,14 +9,27 @@ import {
} from "@toa-lib/models";
import Room from "./Room.js";
import Match from "./Match.js";
import { WebSocket } from 'ws';
import { buildWledInitializationPacket, buildWledSetColorPacket } from "../util/WLEDHelper.js";

export default class FCS extends Room {
private readonly latestFcsStatus: FieldControlUpdatePacket = { hubs: {} };
private readonly latestFcsStatus: FieldControlUpdatePacket = { hubs: {}, wleds: {} };
private fcsPackets: FcsPackets = getFcsPackets(defaultFieldOptions);
private wledSockets: Record<string, WebSocket> = {};

public constructor(server: Server, matchRoom: Match) {
super(server, "fcs");

// Connect to wled websocket servers if there are wleds
Object.entries(this.fcsPackets.init.wleds).forEach((wled) => {
this.wledSockets[wled[0]] = new WebSocket(wled[1].address);

// Send initialization packet
this.wledSockets[wled[0]].onopen = () => {
this.wledSockets[wled[0]].send(buildWledInitializationPacket(wled[1]));
}
});

matchRoom.localEmitter.on(MatchSocketEvent.TELEOPERATED, () => {
this.broadcastFcsUpdate(this.fcsPackets.matchStart);
});
Expand Down Expand Up @@ -51,6 +64,11 @@ export default class FCS extends Room {
private broadcastFcsUpdate(update: FieldControlUpdatePacket): void {
this.broadcast().emit("fcs:update", update);

// Handle wleds
Object.entries(update.wleds).forEach((wled) => {
this.wledSockets[wled[0]].send(buildWledSetColorPacket(wled[1]));
});

// Update this.latestFcsStatus AFTER sending out the new update
for (const hubNumber in update.hubs) {
const hubFromThisUpdate = update.hubs[hubNumber];
Expand Down
29 changes: 29 additions & 0 deletions back-end/realtime/src/util/WLEDHelper.ts
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
import { WledInitParameters, WledUpdateParameters } from "@toa-lib/models";

export const buildWledInitializationPacket = (packet: WledInitParameters): string => {
const wledJson = {
transition: 0,
bri: 255,
frz: false,
fx: 0,
seg: packet.segments
}

return JSON.stringify(wledJson);
}

export const buildWledSetColorPacket = (packet: WledUpdateParameters): string => {
const wledJson = {
seg: packet.targetSegments?.map((segment) => ({
id: segment,
on: true,
frz: false,
fx: 0,
col: [
packet.color
]
}))
}

return JSON.stringify(wledJson);
}
70 changes: 69 additions & 1 deletion front-end/src/seasons/fgc-2024/field-control.tsx
Original file line number Diff line number Diff line change
@@ -1,4 +1,4 @@
import { FeedingTheFuture } from '@toa-lib/models';
import { FeedingTheFuture, FieldControlUpdatePacket } from '@toa-lib/models';
import { FieldControlCallbacks } from '..';
import { useSocket } from 'src/api/use-socket';

Expand All @@ -16,18 +16,86 @@ export const useFieldControl =
};

const prepareField = () => {
socket?.emit('fcs:update', {
hubs: {},
wleds: {
center: {
color: 'ffff00',
targetSegments: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
red: {
color: 'ffff00',
targetSegments: [0, 1, 2, 3, 4, 5]
},
blue: {
color: 'ffff00',
targetSegments: [0, 1, 2, 3, 4, 5]
}
}
} satisfies FieldControlUpdatePacket);
console.log('prepareField');
};

const startField = () => {
socket?.emit('fcs:update', {
hubs: {},
wleds: {
center: {
color: '000000',
targetSegments: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
red: {
color: '000000',
targetSegments: [0, 1, 2, 3, 4, 5]
},
blue: {
color: '000000',
targetSegments: [0, 1, 2, 3, 4, 5]
}
}
} satisfies FieldControlUpdatePacket);
console.log('startField');
};

const abortField = () => {
socket?.emit('fcs:update', {
hubs: {},
wleds: {
center: {
color: 'ff0000',
targetSegments: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
red: {
color: 'ff0000',
targetSegments: [0, 1, 2, 3, 4, 5]
},
blue: {
color: 'ff0000',
targetSegments: [0, 1, 2, 3, 4, 5]
}
}
} satisfies FieldControlUpdatePacket);
console.log('abortField');
};

const clearField = () => {
socket?.emit('fcs:update', {
hubs: {},
wleds: {
center: {
color: '00ff00',
targetSegments: [0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10, 11, 12]
},
red: {
color: '00ff00',
targetSegments: [0, 1, 2, 3, 4, 5]
},
blue: {
color: '00ff00',
targetSegments: [0, 1, 2, 3, 4, 5]
}
}
} satisfies FieldControlUpdatePacket);
console.log('clearField');
};

Expand Down
Loading

0 comments on commit f656353

Please sign in to comment.