# Radio Dashboard ```typescript /** * Radio monitoring dashboard * * Each radio client is represented by a dot on the screen. * Once a client is registered, it will stay at the same pixel location * forever. * * Radio clients can simply send a number (between 0..255) on group 4. * They must transmit the serial number using ``radio.setTransmitSerialNumber(true)`` * * The received number is used to set the LED brightness for that client. * * If the radio packet is not received for 10sec, the LED starts blinking. */ const deadPing = 20000; const lostPing = 10000; interface Client { // client serial id id: number; // sprite on screen sprite: game.LedSprite; // last ping received ping: number; } const clients: Client[] = []; /* lazy allocate sprite */ function getClient(id: number): Client { // needs an id to track radio client identity if (!id) return undefined; // look for cache clients for (const client of clients) if (client.id == id) return client; const n = clients.length; if (n == 24) // out of pixels return undefined; const client: Client = { id: id, sprite: game.createSprite(n % 5, n / 5), ping: input.runningTime() } clients.push(client); return client; } // store data received by clients radio.onReceivedNumber(function (receivedNumber) { const serialNumber = radio.receivedPacket(RadioPacketProperty.SerialNumber) const client = getClient(serialNumber); if (!client) return; client.ping = input.runningTime() client.sprite.setBrightness(Math.max(1, receivedNumber & 0xff)); }) // monitor the sprites and start blinking when no packet is received basic.forever(() => { const now = input.runningTime() for (const client of clients) { // lost signal starts blinking const lastPing = now - client.ping; if (lastPing > deadPing) { client.sprite.setBlink(0) client.sprite.setBrightness(0) } else if (lastPing > lostPing) client.sprite.setBlink(500); else client.sprite.setBlink(0); } basic.pause(500) }) // setup the radio and start! radio.setGroup(4) game.addScore(1) ``` ```package radio ```