Summary

PiClock is a network-connected clock and tally display device. It connects to a tally server over TCP (default port 6254) and receives display commands including tally states, clock configurations, countdown timers, and GPIO controls. Authentication uses a SHA512 challenge-response mechanism.

Transport

protocols:
  - tcp
addressing:
  port: 6254  # default port; source states "default 6254"
auth:
  type: sha512_challenge  # CRYPT/AUTH challenge-response; shared secret required
  # UNRESOLVED: shared secret format/transfer method not described in source
message_encoding: utf-8
message_terminator: carriage_return  # 13 decimal / 0x0D
heartbeat_interval: 5  # seconds; server must transmit at least once every 5s

Traits

# PiClock is a display/tally device controlled by a tally server.
# No power, routing, or level commands present.
Traits: [server_driven]
# UNRESOLVED: additional traits (routable, levelable) not evidenced in source

Actions

# Server → PiClock commands.
# Region-prefix rule (source §"Region-Specific Commands"): any region command
# (SETSIZE, SETROW, SETTALLY, SETLABEL, SETCOUNTDOWN, SETLAYOUT, SETCLOCKS,
# SETLOCATION, SETFONTSIZEZONES) may be prefixed by a decimal region index,
# e.g. `0SETSIZE:rows:cols<CR>`. Absent prefix == region 0.
# All payloads terminated by carriage return (0x0D) - omitted from templates below.

- id: crypt
  label: CRYPT
  kind: action
  description: Authentication challenge from server to client
  command: "CRYPT:{random_string}"
  params:
    - name: random_string
      type: string
      description: Random string generated by server for challenge-response

- id: auth
  label: AUTH
  kind: action
  description: Client authentication response
  command: "AUTH:{sha512_digest}:{mac_addr}"
  params:
    - name: sha512_digest
      type: string
      description: SHA512 digest of UTF-8 concatenation of random_string + shared_secret
    - name: mac_addr
      type: string
      description: MAC address of PiClock host (hex, no colons)

- id: ping
  label: PING
  kind: action
  description: Heartbeat from server; client must respond with PONG
  command: "PING"
  params: []

- id: setgpo
  label: SETGPO
  kind: action
  description: Set General Purpose Output state
  command: "SETGPO:{index}:{value}"
  params:
    - name: index
      type: integer
      description: Zero-based GPO index (0-7). GPOs follow 8 GPIs, so GPO 0 sits on wiringPi pin 8
    - name: value
      type: boolean
      description: Turn GPO on (1) or off (0)

- id: setglobal
  label: SETGLOBAL
  kind: action
  description: Set global display flags
  command: "SETGLOBAL:{landscape}:{screensaver}"
  params:
    - name: landscape
      type: boolean
      description: "true = landscape (wider than tall), false = portrait"
    - name: screensaver
      type: boolean
      description: "true = enable screensaver (shrinks display 5% and moves slowly)"

- id: setprofile
  label: SETPROFILE
  kind: action
  description: Set profile name displayed alongside MAC address
  command: "SETPROFILE:{name}"
  params:
    - name: name
      type: string
      description: Profile name to display (cannot contain colon)

- id: setregioncount
  label: SETREGIONCOUNT
  kind: action
  description: Set number of display regions
  command: "SETREGIONCOUNT:{count}"
  params:
    - name: count
      type: integer
      description: Number of regions (default 1)

- id: storefont
  label: STOREFONT
  kind: action
  description: Store or update a font for later use
  command: "STOREFONT:{name}:{data}"
  params:
    - name: name
      type: string
      description: Font name identifier (must not contain ':')
    - name: data
      type: string
      description: Base64-encoded TTF or FreeType-supported font data

- id: clearfonts
  label: CLEARFONTS
  kind: action
  description: Clear all stored fonts
  command: "CLEARFONTS"
  params: []

- id: setfonts
  label: SETFONTS
  kind: action
  description: Select fonts for display elements
  command: "SETFONTS:{tally}:{tallyLabel}:{status}:{digital}:{date}:{hours}"
  params:
    - name: tally
      type: string
      description: Font for tally indicators (default Serif)
    - name: tallyLabel
      type: string
      description: Font for tally labels (default Serif)
    - name: status
      type: string
      description: Font for status displays (default Serif)
    - name: digital
      type: string
      description: Font for digital clock/countdowns (default Mono, must be monospaced)
    - name: date
      type: string
      description: Font for date (default Serif)
    - name: hours
      type: string
      description: Font for analogue clock hour numbers (default SansSerif)

- id: setsize
  label: SETSIZE
  kind: action
  description: Set tally grid dimensions for a region
  command: "SETSIZE:{rows}:{cols}"
  params:
    - name: rows
      type: integer
      description: Number of rows of tally indicators (default 0)
    - name: cols
      type: integer
      description: Default number of columns per row (default 0)

- id: setrow
  label: SETROW
  kind: action
  description: Override column count for a specific row
  command: "SETROW:{row}:{cols}"
  params:
    - name: row
      type: integer
      description: Row number (zero-indexed)
    - name: cols
      type: integer
      description: Column count for this row

- id: settally
  label: SETTALLY
  kind: action
  description: Set tally indicator state
  command: "SETTALLY:{row}:{col}:{fg_colour}:{bg_colour}:{text}"
  params:
    - name: row
      type: integer
      description: Row number (zero-indexed)
    - name: col
      type: integer
      description: Column number (zero-indexed)
    - name: fg_colour
      type: string
      description: Foreground/text colour (6-digit hex, optional leading #)
    - name: bg_colour
      type: string
      description: Background colour (6-digit hex, optional leading #)
    - name: text
      type: string
      description: Text to display (may contain colon; no args follow after this)

- id: setlabel
  label: SETLABEL
  kind: action
  description: Set label text above a tally indicator
  command: "SETLABEL:{row}:{col}:{label}"
  params:
    - name: row
      type: integer
      description: Row number (zero-indexed)
    - name: col
      type: integer
      description: Column number (zero-indexed)
    - name: label
      type: string
      description: Label text (may contain colon; no args follow after this)

- id: setcountdown
  label: SETCOUNTDOWN
  kind: action
  description: Configure countdown timer on an indicator
  command: "SETCOUNTDOWN:{row}:{col}:{fg_colour}:{bg_colour}:{target_secs}:{target_usecs}:{flash}:{label}"
  params:
    - name: row
      type: integer
      description: Row number (zero-indexed)
    - name: col
      type: integer
      description: Column number (zero-indexed)
    - name: fg_colour
      type: string
      description: Foreground/text colour (6-digit hex, optional leading #)
    - name: bg_colour
      type: string
      description: Background colour (6-digit hex, optional leading #)
    - name: target_secs
      type: integer
      description: Target time in seconds since Unix epoch (01/01/1970 UTC)
    - name: target_usecs
      type: integer
      description: Additional microseconds to add to target time
    - name: flash
      type: integer
      description: Flash frequency in Hz when countdown reaches this many seconds (empty = no flash)
    - name: label
      type: string
      description: Label text above countdown (may contain colon)

- id: setlayout
  label: SETLAYOUT
  kind: action
  description: Configure clock and display layout (legacy parameters; superseded by SETCLOCKS)
  command: "SETLAYOUT:{analogue_clock}:{analogue_clock_local}:{digital_clock_utc}:{digital_clock_local}:{date}:{date_local}:{blank}:{numbers_present}:{numbers_outside}:{seconds_sweep}:{image_clock_face}:{image_clock_hours}:{image_clock_minutes}:{image_clock_seconds}"
  params:
    - name: analogue_clock
      type: boolean
      description: Display analogue clock (default true, legacy)
    - name: analogue_clock_local
      type: boolean
      description: Analogue clock in local timezone (default true, legacy)
    - name: digital_clock_utc
      type: boolean
      description: Show digital clock in UTC (default false, legacy)
    - name: digital_clock_local
      type: boolean
      description: Show digital clock in local timezone (default true, legacy)
    - name: date
      type: boolean
      description: Display date (default true, legacy)
    - name: date_local
      type: boolean
      description: Date in local timezone (default true, legacy)
    - name: blank
      type: string
      description: Unused legacy field (ignored)
    - name: numbers_present
      type: boolean
      description: Show numbers on analogue clock (default true)
    - name: numbers_outside
      type: boolean
      description: Show numbers outside analogue clock (default true)
    - name: seconds_sweep
      type: boolean
      description: Continuously sweep seconds hand (default false)
    - name: image_clock_face
      type: string
      description: Image name for clock face (stored via STOREIMAGE)
    - name: image_clock_hours
      type: string
      description: Image or colour for hour hand
    - name: image_clock_minutes
      type: string
      description: Image or colour for minute hand
    - name: image_clock_seconds
      type: string
      description: Image or colour for seconds hand

- id: setclocks
  label: SETCLOCKS
  kind: action
  description: Configure clocks with timezones (supersedes first 6 SETLAYOUT params). Variable-length - additional digital clocks appended as tz:label pairs.
  command: "SETCLOCKS:{date_tz}:{analogue_tz}:{digital_clock_1_tz}:{digital_clock_1_label}:{digital_clock_2_tz}:{digital_clock_2_label}:..."
  params:
    - name: date_tz
      type: string
      description: Timezone for date display (empty = no date, LOCAL = local timezone)
    - name: analogue_tz
      type: string
      description: Timezone for analogue clock (empty = no analogue clock)
    - name: digital_clock_1_tz
      type: string
      description: Timezone for first digital clock
    - name: digital_clock_1_label
      type: string
      description: 3-character label for first digital clock
    - name: digital_clock_2_tz
      type: string
      description: Timezone for optional second digital clock
    - name: digital_clock_2_label
      type: string
      description: 3-character label for second digital clock
    # Additional digital clocks as pairs of tz/label...

- id: setlocation
  label: SETLOCATION
  kind: action
  description: Set region position and size (proportions of display, 0-1)
  command: "SETLOCATION:{x}:{y}:{width}:{height}"
  params:
    - name: x
      type: float
      description: Left edge coordinate (default 0)
    - name: y
      type: float
      description: Bottom edge coordinate (default 0)
    - name: width
      type: float
      description: Width of region (default 1)
    - name: height
      type: float
      description: Height of region (default 1)

- id: setfontsinezones
  label: SETFONTSIZEZONES
  kind: action
  description: Set font sizing zone names for tally indicators. Variable-length - one comma-separated zone-list per row.
  command: "SETFONTSIZEZONES:{row0}:{row1}:..."
  params:
    - name: row0
      type: string
      description: Comma-separated zone names for row 0
    - name: row1
      type: string
      description: Comma-separated zone names for row 1
    # Additional rows as needed...

- id: storeimage
  label: STOREIMAGE
  kind: action
  description: Store or update an image for display on tally indicators
  command: "STOREIMAGE:{name}:{image}"
  params:
    - name: name
      type: string
      description: Magic string triggering image display (must not start with # or contain ':')
    - name: image
      type: string
      description: Base64-encoded image data (JPEG, PNG, or ImageMagick-supported format)

- id: clearimages
  label: CLEARIMAGES
  kind: action
  description: Clear all stored images
  command: "CLEARIMAGES"
  params: []

Feedbacks

# PiClock → Server messages.

- id: auth_response
  label: AUTH
  kind: feedback
  description: Client authentication response after CRYPT challenge
  command: "AUTH:{sha512_digest}:{mac_addr}"
  params:
    - name: sha512_digest
      type: string
      description: SHA512 of random_string + shared_secret
    - name: mac_addr
      type: string
      description: Client MAC address (hex, no colons)

- id: pong
  label: PONG
  kind: feedback
  description: Response to PING heartbeat
  command: "PONG"
  params: []

- id: gpi
  label: GPI
  kind: feedback
  description: Unsolicited GPI state change notification (or on new connection)
  command: "GPI:{state}"
  params:
    - name: state
      type: integer
      description: 16-bit unsigned integer; bits 0-7 represent GPI states

- id: ack
  label: ACK
  kind: feedback
  description: Acknowledgement for understood command
  command: "ACK"
  params: []

- id: nack
  label: NACK
  kind: feedback
  description: Negative acknowledgement for unrecognized command
  command: "NACK"
  params: []

# UNRESOLVED: connection status notifications (disconnect reason, error states) not documented

Variables

# UNRESOLVED: PiClock does not appear to expose queryable parameters via this protocol.
# All state flows server→client; client only sends acknowledgements and state changes.

Events

# PiClock does not generate unsolicited events beyond GPI state changes.
# UNRESOLVED: any other event types (connection lost, profile change, etc.) not documented

Macros

# No explicit multi-step macros defined in source.
# UNRESOLVED: common sequences (e.g., initial setup, teardown) not documented

Safety

confirmation_required_for: []
interlocks: []
# UNRESOLVED: no safety warnings or interlock procedures in source

Notes

PiClock uses a server-driven display model. The device connects as a TCP client to the tally server (default port 6254). Authentication is mandatory using SHA512 challenge-response (CRYPT/AUTH). Once authenticated, the server must send a message at least every 5 seconds or the device assumes the connection is dead and disconnects.

Display is organized into regions, each of which can contain clocks (analogue, digital), tallies, countdowns, and custom images. Region 0 always shows connection status (MAC address, profile, connection/NTP status) at the bottom.

Message format: CMD:ARG1:ARG2:...:<CR> (UTF-8, carriage-return terminated, decimal 13). Extra arguments are ignored for forward compatibility. Argument types documented by source: string (inline UTF-8, no CR), int (decimal), bool (0/1), float (double precision), colour (6-digit hex RGB, optional leading #), b64 (base64 binary), tz (LOCAL or TZ database identifier).

Region prefix: every region-specific command (SETSIZE, SETROW, SETTALLY, SETLABEL, SETCOUNTDOWN, SETLAYOUT, SETCLOCKS, SETLOCATION, SETFONTSIZEZONES) may be prefixed by a decimal region index — e.g. 0SETSIZE:rows:cols<CR>. If no prefix is sent, the command is interpreted as SETREGIONCOUNT:1 followed by the command itself in Region 0.

GPIO: 8 GPIs (read as 16-bit value, bits 0–7 used; protocol reserves bits 8–15 for future growth) and 8 GPOs (indexed 0–7; GPO 0 sits on wiringPi pin 8). GPI state changes are sent unsolicited to the server, and also on new connection.

Testing: nc -k -l 6254 -C for basic protocol testing with netcat.


Upgrade summary: added `command:` field (verbatim payload templates) to all 22 actions + 5 feedbacks — was the B/C gap per implementability rule. Documented region-prefix convention, argument type table, GPO wiringPin offset, and 16-bit GPI field reservation in Notes. No IDs/shapes changed; all existing params preserved.

## Provenance

```yaml
source_domains:
  - github.com
source_urls:
  - https://github.com/simonhyde/PiClock/blob/master/TallyProtocol.md
retrieved_at: 2026-07-16T14:30:04.435Z
last_checked_at: 2026-07-22T01:10:17.559Z
```

## Verification Summary

```yaml
verdict: verified
checked_at: 2026-07-22T01:10:17.559Z
matched_actions: 21
action_count: 21
confidence: medium
summary: "All 21 spec actions matched source literals with correct parameter shapes; transport parameters fully verified; client-to-server feedback messages documented. (11 unresolved item(s) noted in Known Gaps.)"
```

## Known Gaps

```yaml
- "device hardware specifications (voltage, current, power) not stated in source"
- "shared secret format/transfer method not described in source"
- "additional traits (routable, levelable) not evidenced in source"
- "connection status notifications (disconnect reason, error states) not documented"
- "PiClock does not appear to expose queryable parameters via this protocol."
- "any other event types (connection lost, profile change, etc.) not documented"
- "common sequences (e.g., initial setup, teardown) not documented"
- "no safety warnings or interlock procedures in source"
- "firmware version compatibility not stated"
- "default baud rate / serial config not applicable (TCP-only device)"
- "power specifications not stated"
```

---
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0