Skip to content
4 changes: 3 additions & 1 deletion edge-apps/edge-apps-library/README.md
Original file line number Diff line number Diff line change
Expand Up @@ -59,7 +59,8 @@ signalReady()
### Metadata

- `getMetadata()` - Get all screen metadata
- `getScreenName()`, `getHostname()`, `getLocation()`, `getHardware()`, `getScreenlyVersion()`, `getTags()`, `hasTag(tag)`, `getFormattedCoordinates()`
- `getScreenName()`, `getHostname()`, `getLocation()`, `getScreenlyVersion()`, `getTags()`, `hasTag(tag)`, `getFormattedCoordinates()`
- `getHardware()` - Get hardware type as `Hardware` enum (`Anywhere`, `RaspberryPi`, or `ScreenlyPlayerMax`)

### Location & Localization

Expand Down Expand Up @@ -125,6 +126,7 @@ afterEach(() => {

```typescript
import type {
Hardware,
ScreenlyMetadata,
ScreenlySettings,
ScreenlyObject,
Expand Down
11 changes: 10 additions & 1 deletion edge-apps/edge-apps-library/src/types/index.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,20 @@
/**
* Hardware types for Screenly devices
*/
export enum Hardware {
Anywhere = 'Anywhere',
RaspberryPi = 'RaspberryPi',
ScreenlyPlayerMax = 'ScreenlyPlayerMax',
}

/**
* Screenly metadata provided by the Edge Apps runtime
*/
export interface ScreenlyMetadata {
/** GPS coordinates [latitude, longitude] */
coordinates: [number, number]
/** Hardware identifier */
hardware: string
hardware: string | undefined
/** Device hostname */
hostname: string
/** Physical location description */
Expand Down
50 changes: 46 additions & 4 deletions edge-apps/edge-apps-library/src/utils/metadata.test.ts
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@ import {
getTags,
hasTag,
} from './metadata'
import { Hardware } from '../types/index.js'
import { setupScreenlyMock, resetScreenlyMock } from '../test/mock'

describe('metadata utilities', () => {
Expand All @@ -18,7 +19,7 @@ describe('metadata utilities', () => {
coordinates: [37.3861, -122.0839],
hostname: 'test-host',
location: 'Test Location',
hardware: 'Raspberry Pi 4',
hardware: 'Raspberry Pi',
screenly_version: '1.2.3',
screen_name: 'Main Screen',
tags: ['lobby', 'reception', 'main'],
Expand All @@ -36,7 +37,7 @@ describe('metadata utilities', () => {
coordinates: [37.3861, -122.0839],
hostname: 'test-host',
location: 'Test Location',
hardware: 'Raspberry Pi 4',
hardware: 'Raspberry Pi',
screenly_version: '1.2.3',
screen_name: 'Main Screen',
tags: ['lobby', 'reception', 'main'],
Expand Down Expand Up @@ -70,8 +71,49 @@ describe('metadata utilities', () => {
})

describe('getHardware', () => {
test('should return hardware', () => {
expect(getHardware()).toBe('Raspberry Pi 4')
test('should return RaspberryPi enum value', () => {
expect(getHardware()).toBe(Hardware.RaspberryPi)
})

test('should return Anywhere enum value when hardware is undefined', () => {
setupScreenlyMock({
coordinates: [37.3861, -122.0839],
hostname: 'test-host',
location: 'Test Location',
hardware: undefined,
screenly_version: '1.2.3',
screen_name: 'Main Screen',
tags: [],
})
expect(getHardware()).toBe(Hardware.Anywhere)
})

test('should return ScreenlyPlayerMax enum value for Screenly Player Max hardware', () => {
setupScreenlyMock({
coordinates: [37.3861, -122.0839],
hostname: 'test-host',
location: 'Test Location',
hardware: 'Screenly Player Max',
screenly_version: '1.2.3',
screen_name: 'Main Screen',
tags: [],
})
expect(getHardware()).toBe(Hardware.ScreenlyPlayerMax)
})

test('should throw error for unknown hardware type', () => {
setupScreenlyMock({
coordinates: [37.3861, -122.0839],
hostname: 'test-host',
location: 'Test Location',
hardware: 'Unknown Hardware',
screenly_version: '1.2.3',
screen_name: 'Main Screen',
tags: [],
})
expect(() => getHardware()).toThrow(
'Unknown hardware type: Unknown Hardware',
)
})
})

Expand Down
21 changes: 18 additions & 3 deletions edge-apps/edge-apps-library/src/utils/metadata.ts
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
import type { ScreenlyMetadata } from '../types/index.js'
import { Hardware } from '../types/index.js'
import { formatCoordinates } from './locale.js'

/**
Expand Down Expand Up @@ -37,10 +38,24 @@ export function getLocation(): string {
}

/**
* Get the hardware identifier
* Get the hardware type
*/
export function getHardware(): string {
return screenly.metadata.hardware
export function getHardware(): Hardware {
const hardware = screenly.metadata.hardware

if (hardware === undefined) {
return Hardware.Anywhere
}

if (hardware === 'Raspberry Pi') {
return Hardware.RaspberryPi
}

if (hardware === 'Screenly Player Max') {
return Hardware.ScreenlyPlayerMax
}

throw new Error(`Unknown hardware type: ${hardware}`)
}

/**
Expand Down
5 changes: 3 additions & 2 deletions edge-apps/menu-board/src/main.ts
Original file line number Diff line number Diff line change
Expand Up @@ -3,6 +3,7 @@ import {
getSettingWithDefault,
signalReady,
} from '@screenly/edge-apps'
import { Hardware } from '@screenly/edge-apps'
import {
escapeHtml,
calculateItemsPerPage,
Expand Down Expand Up @@ -55,9 +56,9 @@ function renderPage(
fragment.appendChild(itemElement)
})

// Disable transitions if hardware is undefined (running in an Anywhere screen)
// Disable transitions if hardware is Anywhere screen
const hardware = getHardware()
if (!hardware) {
if (hardware === Hardware.Anywhere) {
menuGrid.innerHTML = ''
menuGrid.appendChild(fragment)
} else {
Expand Down