-
Notifications
You must be signed in to change notification settings - Fork 12
feat(peripheral-demo): add Edge App for peripheral integration #719
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Open
nicomiguelino
wants to merge
64
commits into
master
Choose a base branch
from
feat/peripheral-integration-poc
base: master
Could not load branches
Branch not found: {{ refName }}
Loading
Could not load tags
Nothing to show
Loading
Are you sure you want to change the base?
Some commits from the old base branch may be removed from the timeline,
and old review comments may become outdated.
+3,257
−3
Open
Changes from all commits
Commits
Show all changes
64 commits
Select commit
Hold shift + click to select a range
2b6f1a8
feat(edge-apps): add peripheral integration POC
nicomiguelino 21fcf10
chore(edge-apps): apply formatting fixes to peripheral integration POC
nicomiguelino 6d4ec84
chore(edge-apps): fix linting errors in edge-apps-library
nicomiguelino 170c717
chore: exclude peripheral-integration-poc from Prettier
nicomiguelino f65f9a8
refactor(edge-apps): update peripheral integration to use snapshot model
nicomiguelino a83ea72
docs(edge-apps): fix markdown table separator style in POC.md
nicomiguelino 1cf256b
Merge branch 'master' into feat/peripheral-integration-poc
nicomiguelino 97129fa
feat(edge-apps): add peripheral integration POC with watchState API
nicomiguelino 66f41d9
feat(edge-apps): scaffold peripheral-integration-demo Edge App
nicomiguelino 4d1a982
feat(edge-apps): wire peripheral temperature into demo app
nicomiguelino 8e585db
feat(edge-apps): wire card reader auth into peripheral-integration-demo
nicomiguelino f3c0f5b
feat(edge-apps): update peripheral protocol to edge_app_source_state
nicomiguelino 41a3df7
chore(edge-apps): retire peripheral-integration-poc
nicomiguelino 328f295
docs(peripheral-demo): update README with accurate API snippet and se…
nicomiguelino 87ce1ba
refactor(edge-apps): deliver full wire message in watchState callback
nicomiguelino 0e4ec87
feat(edge-apps): add edge_app_registration phase to peripheral integr…
nicomiguelino 2196671
chore(peripheral-demo): remove temporary role switch buttons
nicomiguelino 6f02124
refactor(edge-apps): move peripheral WS client into edge-apps-library
nicomiguelino be9ff8c
refactor(edge-apps): rename PeripheralReading to PeripheralState
nicomiguelino 429e24a
feat(edge-apps): update secure_card wire format to nested uid object
nicomiguelino 157b403
feat(peripheral-demo): reject stale card reads older than 1 minute
nicomiguelino e3c000d
feat(peripheral-demo): redesign public view to match Figma design
nicomiguelino bf58746
feat(peripheral-demo): redesign operator view to match Figma design
nicomiguelino 5f4288e
feat(peripheral-demo): redesign maintenance view to match Figma design
nicomiguelino 57f2a01
feat(peripheral-demo): redesign welcome overlay to match Figma design
nicomiguelino a08ccec
chore(peripheral-demo): remove emojis from safety carousel tips
nicomiguelino 73953f8
refactor(peripheral-demo): rename TS files to kebab-case and simplify…
nicomiguelino cdb290d
fix(peripheral-demo): prevent SVG icons from flashing large before CS…
nicomiguelino 5a1c6c4
fix(peripheral-demo): round temperature to nearest integer in public …
nicomiguelino 7e92ca2
fix(peripheral-demo): fix portrait layout by locking orientation and …
nicomiguelino ab7323a
fix(peripheral-demo): fix maintenance view not populating on card scan
nicomiguelino 9229487
fix(edge-apps): exclude fonts from asset inlining to avoid WAF false …
nicomiguelino d135e2d
feat(peripheral-demo): add categories to manifest files
nicomiguelino ce2c33f
fix(peripheral-demo): update layout and styling in index.html
514sid a5ad76f
fix(edge-apps): remove identification ACK dependency in peripheral cl…
nicomiguelino 585b8bf
fix(edge-apps): simplify peripheral init sequence per protocol correc…
nicomiguelino 1937989
refactor(edge-apps): align type names with Peri Protocol
nicomiguelino 6688369
docs(edge-apps): improve comments in peripheral client and types
nicomiguelino 3a846d2
chore: update Prettier ignore to exclude peripheral-integration-demo
nicomiguelino ed2941e
refactor(edge-apps-library): improve peripheral client robustness and…
nicomiguelino b58c98a
chore(peripheral-integration-demo): add app and instance IDs to manif…
nicomiguelino b46ab16
fix(edge-apps-library): remove downstream_node_event ACK handler
nicomiguelino 7665190
refactor(edge-apps): revert type renames to original names
nicomiguelino 6034f80
refactor(peripheral-integration-demo): replace Tailwind with plain CSS
nicomiguelino ab63f00
style(peripheral-integration-demo): adjust margins for date and time …
514sid ead28f5
fix(peripheral-integration): handle binary WebSocket messages and upd…
salmanfarisvp 13d8d46
fix ts lint
salmanfarisvp e7dd6b1
fix(peripheral-integration): prevent logout timer from restarting on …
salmanfarisvp eb682de
feat(peripheral-integration): restart timer when same card is scanned…
salmanfarisvp 20349db
fix ts lint
salmanfarisvp afef88e
Merge branch 'master' into feat/peripheral-integration-poc
nicomiguelino dd9d8d5
fix(peripheral-integration): sync dev server card UIDs with authentic…
nicomiguelino 4c642cd
fix(peripheral-integration): prevent UI flash when switching between …
salmanfarisvp b04313d
fix(peripheral-integration): add proper spacing for hardware name in …
salmanfarisvp c84b3ad
feat(peripheral-demo): add Sensor Data card to operator view
nicomiguelino ee6cce6
fix(peripheral-demo): display sensor values with 2 decimal places
nicomiguelino 6285ffa
refactor(peripheral-demo): widen sensor state setters to accept null
nicomiguelino 86e5699
refactor(peripheral-demo): batch sensor state updates into single not…
nicomiguelino 092e6fe
feat(peripheral-demo): add Raw Peripheral State card to maintenance view
nicomiguelino 83809de
Merge branch 'master' into feat/peripheral-integration-poc
nicomiguelino 5f5d9a1
Merge branch 'feat/peripheral-integration-poc' into ew-demo/additiona…
nicomiguelino 8445984
Merge branch 'master' into feat/peripheral-integration-poc
nicomiguelino d33ff6f
Merge branch 'feat/peripheral-integration-poc' into ew-demo/additiona…
nicomiguelino 39f51eb
Merge pull request #725 from Screenly/ew-demo/additional-sensor-data-…
salmanfarisvp File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Some comments aren't visible on the classic Files Changed page.
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.
Oops, something went wrong.
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
| @@ -0,0 +1,125 @@ | ||
| import { ulid } from 'ulid' | ||
|
|
||
| import type { PeripheralStateMessage } from '../types/index.js' | ||
|
|
||
| // WebSocket address of the hardware integration service on the Screenly player. | ||
| // Port 9010 is a fixed port defined in the player firmware for Edge App connections. | ||
| const PERIPHERAL_WS_URL = 'ws://127.0.0.1:9010' | ||
|
|
||
| const ETB = '\x17' | ||
|
|
||
| /** | ||
| * Serializes `payload` as JSON, appends the ETB delimiter, and sends it over | ||
| * the WebSocket connection to the hardware integration service. | ||
| * Throws if the connection is not open or if the underlying send fails. | ||
| */ | ||
| function sendMessage(ws: WebSocket, payload: unknown): void { | ||
| if (ws.readyState !== WebSocket.OPEN) { | ||
| throw new Error('Cannot send message: WebSocket is not open') | ||
| } | ||
| try { | ||
| ws.send(JSON.stringify(payload) + ETB) | ||
| } catch (err) { | ||
| throw new Error('Failed to send message', { cause: err }) | ||
| } | ||
| } | ||
|
|
||
| export interface PeripheralClient { | ||
| register: (edgeAppId: string) => void | ||
| watchState: (callback: (msg: PeripheralStateMessage) => void) => void | ||
| } | ||
|
|
||
| // eslint-disable-next-line max-lines-per-function | ||
| export function createPeripheralClient(): PeripheralClient { | ||
| let ws: WebSocket | null = null | ||
| const subscribers: Array<(msg: PeripheralStateMessage) => void> = [] | ||
| const readings: Record<string, unknown> = {} | ||
|
|
||
| /** | ||
| * Packages the latest cached sensor readings into a wire message and | ||
| * dispatches it to every callback registered via watchState(). | ||
| */ | ||
| function notifySubscribers() { | ||
| const msg: PeripheralStateMessage = { | ||
| request: { | ||
| id: ulid(), | ||
| edge_app_source_state: { | ||
| states: Object.values( | ||
| readings, | ||
| ) as PeripheralStateMessage['request']['edge_app_source_state']['states'], | ||
| }, | ||
| }, | ||
| } | ||
| subscribers.forEach((cb) => cb(msg)) | ||
| } | ||
|
|
||
| function connect() { | ||
| ws = new WebSocket(PERIPHERAL_WS_URL) | ||
|
|
||
| ws.onmessage = async (e: MessageEvent) => { | ||
| let text: string | ||
| if (e.data instanceof Blob) { | ||
| text = await e.data.text() | ||
| } else { | ||
| text = e.data as string | ||
| } | ||
|
|
||
| text = text.replace(ETB, '') | ||
| let msg: Record<string, unknown> | ||
| try { | ||
| msg = JSON.parse(text) as Record<string, unknown> | ||
| } catch (err) { | ||
| console.warn('Failed to parse peripheral message', err) | ||
| return | ||
| } | ||
nicomiguelino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
|
|
||
| const request = msg.request as Record<string, unknown> | undefined | ||
| if (request?.edge_app_source_state) { | ||
| const state = request.edge_app_source_state as { | ||
| states: Array<{ name: string }> | ||
| } | ||
| state.states.forEach((s) => { | ||
| readings[s.name] = s | ||
| }) | ||
| notifySubscribers() | ||
| sendMessage(ws!, { | ||
| response: { request_id: request.id, ok: 'edge_app_source_state' }, | ||
| }) | ||
| return | ||
| } | ||
| } | ||
|
|
||
| ws.onerror = () => console.warn('Peripheral WebSocket error') | ||
| ws.onclose = () => { | ||
| setTimeout(connect, 2000) | ||
| } | ||
| } | ||
|
|
||
| return { | ||
| register(edgeAppId: string) { | ||
| if (!ws) connect() | ||
| const sendRegistration = () => { | ||
| sendMessage(ws!, { | ||
| request: { | ||
| id: ulid(), | ||
| edge_app_registration: { | ||
| id: edgeAppId, | ||
| secret: '', | ||
| requested_source_channels: [], | ||
| }, | ||
| }, | ||
| }) | ||
| } | ||
| if (ws!.readyState === WebSocket.OPEN) { | ||
| sendRegistration() | ||
| } else { | ||
| ws!.addEventListener('open', sendRegistration, { once: true }) | ||
| } | ||
| }, | ||
|
|
||
| watchState(callback: (msg: PeripheralStateMessage) => void) { | ||
| if (!ws) connect() | ||
| subscribers.push(callback) | ||
nicomiguelino marked this conversation as resolved.
Show resolved
Hide resolved
|
||
| }, | ||
| } | ||
| } | ||
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Oops, something went wrong.
Oops, something went wrong.
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
Uh oh!
There was an error while loading. Please reload this page.