Summary
Network-controllable clock/timer displays (POE, WiFi, DotMatrix, TM1000/TM2000 time servers) by TimeMachines. Control uses a binary UDP/IP protocol on port 7372 supporting device discovery/query, up/down/countdown-to-date timers, dot-matrix text display, relay control, dimming, RGB color set, and multi-step stored timer programs. API designed for TM-Manager but usable by third-party control systems. Document basis: Locator Protocol API version 2.3 (July 2025).
Transport
protocols:
- udp
addressing:
port: 7372
auth:
type: none # inferred: no auth procedure in source
Traits
- queryable # inferred: device query (A1 04 B2) returns IP, MAC, firmware, display mode, timer value, device name
- levelable # inferred: dimmer set (B5) controls digit and indicator brightness 0-100
Actions
# All payloads are raw UDP byte sequences (hex), sent to port 7372.
# Most commands acknowledge with a single byte 'A' (0x41).
# Parameterized bytes shown as {var}.
- id: device_query
label: Device Query
kind: query
command: "A1 04 B2"
params: []
description: >-
3-byte query, unicast or broadcast to port 7372. Clocks respond with a
40-byte packet; TM1000A/TM2000A respond with 80 bytes. See Feedbacks.
- id: use_up_timer
label: Use UpTimer
kind: action
command: "A2 {display_mode}"
params:
- name: display_mode
type: integer
description: "0x00=MIN:SEC.Tenths, 0x01=HH:MM:SS"
description: "Command byte 0xA2. Puts clock into UpTimer mode. Ack: 'A'."
- id: up_timer_start_pause
label: UpTimer Start/Pause
kind: action
command: "A3 {action}"
params:
- name: action
type: integer
description: "0x00=Pause, 0x01=Count Up (added in API v1.1)"
description: "Command byte 0xA3. Toggles UpTimer running/paused. Ack: 'A'."
- id: up_timer_reset
label: UpTimer Reset
kind: action
command: "A4 {display_mode}"
params:
- name: display_mode
type: integer
description: "0x00=MIN:SEC.Tenths, 0x01=HH:MM:SS"
description: "Command byte 0xA4. Resets UpTimer to zero. Ack: 'A'."
- id: use_down_timer
label: Use DownTimer
kind: action
command: "A5 {display_mode} {start_hour} {start_minute} {start_second} {start_tenths} {alarm_enable} {alarm_duration_sec} {start_days_lsb} {start_days_msb}"
params:
- name: display_mode
type: integer
description: "0x00=MIN:SEC.Tenths, 0x01=HH:MM:SS; bit 7 (0x80) = bargraph display on matrix clock"
- name: start_hour
type: integer
description: Starting hour value for countdown
- name: start_minute
type: integer
description: Starting minute value for countdown
- name: start_second
type: integer
description: Starting second value for countdown
- name: start_tenths
type: integer
description: Starting tenths-of-second value for countdown
- name: alarm_enable
type: integer
description: "End-of-countdown alarm: 0=Disabled, 1=Enabled"
- name: alarm_duration_sec
type: integer
description: Alarm duration in seconds
- name: start_days_lsb
type: integer
required: false
description: "Starting days LSB (optional, zero if omitted)"
- name: start_days_msb
type: integer
required: false
description: "Starting days MSB (optional, zero if omitted)"
description: "Command byte 0xA5. Sets DownTimer mode with starting values. Ack: 'A'."
- id: down_timer_start_pause
label: DownTimer Start/Pause
kind: action
command: "A6 {action}"
params:
- name: action
type: integer
description: "0x00=Pause, 0x01=Count Up (added in API v1.1)"
description: "Command byte 0xA6. Toggles DownTimer running/paused. Ack: 'A'."
- id: down_timer_reset
label: DownTimer Reset
kind: action
command: "A7 {display_mode} {start_hour} {start_minute} {start_second} {start_tenths} {alarm_enable} {alarm_duration_sec} {start_days_lsb} {start_days_msb}"
params:
- name: display_mode
type: integer
description: "0x00=MIN:SEC.Tenths, 0x01=HH:MM:SS; bit 7 (0x80) = bargraph display on matrix clock"
- name: start_hour
type: integer
description: Starting hour value for countdown
- name: start_minute
type: integer
description: Starting minute value for countdown
- name: start_second
type: integer
description: Starting second value for countdown
- name: start_tenths
type: integer
description: Starting tenths-of-second value for countdown
- name: alarm_enable
type: integer
description: "0=Disabled, 1=Enabled"
- name: alarm_duration_sec
type: integer
description: Alarm duration in seconds
- name: start_days_lsb
type: integer
required: false
description: "Starting days LSB (optional, zero if omitted)"
- name: start_days_msb
type: integer
required: false
description: "Starting days MSB (optional, zero if omitted)"
description: "Command byte 0xA7. Resets DownTimer to starting value; must already be in DownTimer mode. Ack: 'A'."
- id: set_time_mode
label: Set Clock to Time Mode
kind: action
command: "A8 01"
params: []
description: "Command byte 0xA8, byte 1=0x01. Returns clock from Up/Down timer modes to regular time display. Ack: 'A'."
- id: set_dotmatrix_text_tm848
label: Set DotMatrix Text (TM848 POE dot matrix models)
kind: action
command: "A9 1B {scroll_just} {scroll_speed} {text} 00"
params:
- name: scroll_just
type: integer
description: "Bits 3:2 scroll direction (0=No Scroll, 1=Right to Left, 2=Bottom to Top); bits 1:0 justification (1=Left, 2=Center, 3=Right)"
- name: scroll_speed
type: integer
description: Scroll speed
- name: text
type: string
description: "Text starting at byte 4, null terminated, 250 chars maximum with null"
description: "Command byte 0xA9, byte 1=0x1B (ESC formatting character). Ack: 'A'."
- id: set_dotmatrix_text_2line
label: Set DotMatrix Text, 2 Line Clocks (POE 5.4 / WiFi 3.4 and greater)
kind: action
command: "A9 00 {text_attrs} {scroll_speed} {font} {color} {text} 00"
params:
- name: text_attrs
type: integer
description: "Bit 4 Blink (0=No Blink, 1=Blink); bits 3:2 scroll direction (0=No Scroll, 1=Right to Left, 2=Bottom to Top); bits 1:0 justification (1=Left, 2=Center, 3=Right)"
- name: scroll_speed
type: integer
description: "Scroll speed, typically 60-150"
- name: font
type: integer
description: "1=standard, 4=bold"
- name: color
type: integer
description: "0-9, uses color palette stored on clock"
- name: text
type: string
description: "Null terminated string; embed '\\n' for multiple lines"
description: "Command byte 0xA9, byte 1=display address 0x00. Ack: 'A'."
- id: static_text_off
label: Static Text Display Turn Off
kind: action
command: "BD 01"
params: []
description: "Command byte 0xBD, byte 1=0x01. Releases static text mode on 2nd line dot-matrix display, returns display to clock control. Ack: 'A'."
- id: set_up_timer_time_running
label: Set UpTimer Time While Running
kind: action
command: "AA {hours} {minutes} {seconds} {tenths} {hundredths} {days_lsb} {days_msb}"
params:
- name: hours
type: integer
description: New HOUR value
- name: minutes
type: integer
description: New MINUTE value
- name: seconds
type: integer
description: New SECOND value
- name: tenths
type: integer
description: New TENTHS of a second value
- name: hundredths
type: integer
description: New HUNDREDTHS of a second value
- name: days_lsb
type: integer
required: false
description: "New DAYS value LSB (optional, zero if not present)"
- name: days_msb
type: integer
required: false
description: "New DAYS value MSB (optional, zero if not present)"
description: "Command byte 0xAA. Instantaneously changes UpTimer time while running. Ack: 'A'."
- id: set_down_timer_time_running
label: Set DownTimer Time While Running
kind: action
command: "AB {hours} {minutes} {seconds} {tenths} {hundredths} {days_lsb} {days_msb}"
params:
- name: hours
type: integer
description: New HOUR value
- name: minutes
type: integer
description: New MINUTE value
- name: seconds
type: integer
description: New SECOND value
- name: tenths
type: integer
description: New TENTHS of a second value
- name: hundredths
type: integer
description: New HUNDREDTHS of a second value
- name: days_lsb
type: integer
required: false
description: "New DAYS value LSB (optional, zero if not present)"
- name: days_msb
type: integer
required: false
description: "New DAYS value MSB (optional, zero if not present)"
description: "Command byte 0xAB. Instantaneously changes DownTimer time while running. Ack: 'A'."
- id: countdown_to_date_reset
label: Countdown to Date Timer Reset
kind: action
command: "B9 {display_mode} {end_year_lsb} {end_year_msb} {end_month} {end_day} {end_hour} {end_minute} {end_second} {alarm_enable} {alarm_duration_sec}"
params:
- name: display_mode
type: integer
description: "0x00=(HR):MIN:SEC.Tenths, 0x01=(DAY):HH:MM:SS, 0x02=DD:HH:MM"
- name: end_year_lsb
type: integer
description: "Ending year for countdown (e.g. 2022), LSB"
- name: end_year_msb
type: integer
description: Ending year, MSB
- name: end_month
type: integer
description: Ending month
- name: end_day
type: integer
description: Ending day
- name: end_hour
type: integer
description: Ending hour
- name: end_minute
type: integer
description: Ending minute
- name: end_second
type: integer
description: Ending second
- name: alarm_enable
type: integer
description: "0=Disabled, 1=Enabled"
- name: alarm_duration_sec
type: integer
description: Alarm duration in seconds
description: "Command byte 0xB9. Resets countdown-to-date timer to starting value. Ack: 'A'."
- id: countdown_to_date_start_pause
label: Countdown to Date Start/Pause
kind: action
command: "BA {action}"
params:
- name: action
type: integer
description: "0x00=Pause, 0x01=Count Up"
description: "Command byte 0xBA. Toggles countdown-to-date timer running/paused. Ack: 'A'."
- id: get_program
label: Get Program from Clock
kind: query
command: "B2 {program_number}"
params:
- name: program_number
type: integer
description: "Program number 0-9"
description: "Command byte 0xB2. Clock returns requested program from flash memory. See Feedbacks: program_response."
- id: store_program
label: Store Program to Clock
kind: action
command: "B3 {program_number} {program_name_12_bytes} {program_data}"
params:
- name: program_number
type: integer
description: "Program number 0-9; overwrites existing program at that location"
- name: program_name_12_bytes
type: string
description: "Program name, must be exactly 12 bytes, null terminated"
- name: program_data
type: string
description: "10 copies of the 32-byte TIMER_PROGRAM structure (bytes 14-333 of the packet); unset bytes default 0x00"
description: "Command byte 0xB3. Stores a program to clock flash memory. Up to 10 programs. Ack: 'A'."
- id: get_active_program
label: Get Clock Active Program
kind: query
command: "AF"
params: []
description: "Command byte 0xAF. Clock sends back the program it is currently set to run. See Feedbacks: program_response."
- id: load_program_reset
label: Reset (Load and Prepare Program)
kind: action
command: "AC 4F {program_number} {program_name_12_bytes} {program_data}"
params:
- name: program_number
type: integer
description: "Program number 0-9"
- name: program_name_12_bytes
type: string
description: "Program name, must be exactly 12 bytes, null terminated"
- name: program_data
type: string
description: "10 copies of the TIMER_PROGRAM structure (bytes 15-334); unset bytes default 0x00"
description: "Command byte 0xAC. Gets clock out of time mode and ready to run a specific program. Byte 1=0x4F (sum of program size, program name length, and 3)."
- id: program_start_pause
label: Program Start/Pause
kind: action
command: "AE {action}"
params:
- name: action
type: integer
description: "0x00=Stop, 0x01=Start/Resume"
description: "Command byte 0xAE. Starts, pauses, and resumes the clock's current program."
- id: execute_stored_program
label: Execute Stored Program
kind: action
command: "B8 {program_number}"
params:
- name: program_number
type: integer
description: "Program number 0-9"
description: "Command byte 0xB8. Loads a stored timer program from flash and begins executing it. Same mechanism the alarm system uses to trigger a stored program at a given time."
- id: relay_close
label: Relay Close
kind: action
command: "B4 {duration_sec}"
params:
- name: duration_sec
type: integer
description: Number of seconds to close the relay
description: "Command byte 0xB4. Immediately closes the relay on the display for X seconds."
- id: relay_toggle
label: Relay Toggle
kind: action
command: "BC {state}"
params:
- name: state
type: integer
description: "0=open, 1=closed"
description: "Command byte 0xBC. Sets relay to open or closed indefinitely. State is not checked by other events that could change relay position (e.g. a timer-triggered closure overrides it)."
- id: set_revert_timeout
label: Revert to Time Timeout
kind: action
command: "BB {timeout_lsb} {timeout_msb}"
params:
- name: timeout_lsb
type: integer
description: "Timeout in minutes, LSB"
- name: timeout_msb
type: integer
description: "Timeout in minutes, MSB"
description: "Command byte 0xBB. Changes the timeout that reverts the clock from a non-running, unused timer back to time display. 0 disables the revert timer. Not saved to non-volatile memory; must be re-sent after power loss."
- id: dimmer_set
label: Dimmer Set
kind: action
command: "B5 {digit_brightness} {indicator_brightness}"
params:
- name: digit_brightness
type: integer
description: "Digit brightness 0-100"
- name: indicator_brightness
type: integer
description: "AM/PM/Colon dot brightness 0-100"
description: "Command byte 0xB5. Immediately changes display dimming. Not saved to non-volatile memory; only active until changed or reboot."
- id: timezone_variable_set
label: TimeZone Variable Set
kind: action
command: "BE {variable_index} {text} 00"
params:
- name: variable_index
type: integer
description: "Which string variable to set, 0-4 (up to 5 variables)"
- name: text
type: string
description: "Null terminated string stored for periodic display on second line (bytes 2-102)"
description: "Command byte 0xBE. For two-line TimeZone clocks, POE 5.4 and WiFi 3.4 and greater. Not stored during loss of power."
- id: color_set
label: Color Set
kind: action
command: "B6 {mmss_red} {mmss_green} {mmss_blue} {hh_red} {hh_green} {hh_blue}"
params:
- name: mmss_red
type: integer
description: "MM:SS digit red component 0-255"
- name: mmss_green
type: integer
description: "MM:SS digit green component 0-255"
- name: mmss_blue
type: integer
description: "MM:SS digit blue component 0-255"
- name: hh_red
type: integer
description: "HH digit red component 0-255"
- name: hh_green
type: integer
description: "HH digit green component 0-255"
- name: hh_blue
type: integer
description: "HH digit blue component 0-255"
description: "Command byte 0xB6. On RGB equipped displays, immediately changes displayed colors. Not saved to non-volatile memory; only active until changed or reboot."
# --- Timer Program Step Functions (TIMER_PROGRAM.command byte values, source 1.3.2) ---
# Each is byte 0 of a 32-byte TIMER_PROGRAM step inside the program blob sent
# by store_program / load_program_reset. Source lists each as a distinct row.
- id: timer_step_none
label: Timer Step - None
kind: action
command: "00"
params: []
description: "Step command 0x00. Zero to show no current function."
- id: timer_step_interval_countdown
label: Timer Step - Interval Countdown
kind: action
command: "01"
params: []
description: "Step command 0x01. Countdown between two set values with option to increment an interval."
- id: timer_step_interval_countup
label: Timer Step - Interval Countup
kind: action
command: "02"
params: []
description: "Step command 0x02. Countup between two set values with option to increment an interval."
- id: timer_step_countup_ddd_hhmmss
label: Timer Step - CountUp (DDD):HH:MM:SS
kind: action
command: "03"
params: []
description: "Step command 0x03. Countup with (DDD):HH:MM:SS format."
- id: timer_step_countup_hr_mmssts
label: Timer Step - CountUp (HR):MM:SS:TS
kind: action
command: "04"
params: []
description: "Step command 0x04. Countup with (HR):MM:SS:TS format."
- id: timer_step_countdown_day_hhmmss
label: Timer Step - CountDown (DAY):HH:MM:SS
kind: action
command: "05"
params: []
description: "Step command 0x05. Countdown with (DDD):HH:MM:SS format."
- id: timer_step_countdown_hr_mmssts
label: Timer Step - CountDown (HR):MM:SS:TS
kind: action
command: "06"
params: []
description: "Step command 0x06. Countdown with (HR):MM:SS:TS format."
- id: timer_step_goto_line
label: Timer Step - Goto Line
kind: action
command: "07"
params: []
description: "Step command 0x07. Repeat sequences, jump to a specific line (gotoLine 0-9) and choose how many times to repeat (repeatCountSet, 0=infinite)."
- id: timer_step_end_program
label: Timer Step - End Program
kind: action
command: "08"
params: []
description: "Step command 0x08. Ends the program. gotoLine bit 0 (0x01) resets program after finish; bit 1 (0x02) stops program after finish."
- id: timer_step_change_colors
label: Timer Step - Change Colors
kind: action
command: "09"
params: []
description: "Step command 0x09. For older devices, how the clock color is changed. Still supported but not needed from POE 5.4 / WiFi 3.4 forward (commands can change color inline)."
- id: timer_step_countup_dd_hhmm
label: Timer Step - CountUp DD:HH:MM
kind: action
command: "0A"
params: []
description: "Step command 0x0A. Countup with DD:HH:MM format."
- id: timer_step_countdown_dd_hhmm
label: Timer Step - CountDown DD:HH:MM
kind: action
command: "0B"
params: []
description: "Step command 0x0B. Countdown with DD:HH:MM format."
Feedbacks
- id: clock_query_response
type: binary
description: >-
40-byte response to device query (A1 04 B2) from POE/WiFi/DotMatrix clocks.
Byte 0 device type (0x01=POE, 0x02=WiFi, 0x03=DotMatrix); 1-4 client IP;
5-10 MAC; 11-12 firmware Major:Minor; 13-14 NTP sync count; 15-17 displayed
time/timer value HH MM SS; 18 tenths of second; 19 display mode (bits 2-0:
000=time 001=Up Timer 010=Down Timer 011=Interval Count Up 100=Interval
Count Down; bit5 0x20=1 D:H:M mode (bit7 cleared); bit6 0x40 start/stop
0=stopped 1=running; bit7 0x80 0=H:M:S 1=M:S:Tenths); 20 downtimer alarm
set (bits 0-6 alarm duration, bit7 alarm checked 0=unchecked 1=checked);
21 days displayed MSB; 22 digits value (0=4/6 digits, 1=(D):H:M:S,
2=(H):M:S.Tenths; top 3 bits are MSBs of day value); 23 WiFi signal
strength (0=wired, otherwise negative dBm); 24-39 device name null
terminated ASCII.
- id: tm1000_tm2000_query_response
type: binary
description: >-
80-byte response to device query (A1 04 B2) from TM1000A/TM2000A. Byte 0:
0x04=TM1000A, 0x05=TM2000A; 1-4 client IP; 5-10 MAC; 11-12 firmware
Major:Minor; 13 lock status (0=No Lock, 1=2D Lock, 2=3D Lock); 14-17 NTP
sync count 32-bit MSB to LSB; 18-20 current time H:M:S UTC; 21-45 location
(latitude, longitude, null terminated, 25 bytes); 46-79 time server name
null terminated.
- id: command_ack
type: enum
values: ["A"]
description: >-
Single character 'A' (0x41) acknowledgement sent back for most commands
when no data is being requested.
- id: program_response
type: binary
description: >-
Full program data returned by get_program (B2) and get_active_program
(AF). Per source 1.3.4/1.3.6 layout: program number, 12-byte null
terminated program name, then 10 copies of the 32-byte TIMER_PROGRAM
structure (command byte, 3 reserved bytes 0x00, incrementInterval,
gotoLine, repeatCountSet, repeatCountAct, startSeconds 4 bytes LSB,
stopSeconds 4 bytes LSB, relayTimeSec, digitColor, matrixAttrib, rsrvd3,
matrixStrig 12 bytes null terminated).
Variables
# UNRESOLVED: no persistent settable variables beyond the dimmer/color/revert
# timeout actions (all volatile, not stored in non-volatile memory).
Events
# UNRESOLVED: no unsolicited notification protocol documented; all responses
# are query-reply or command-ack.
Macros
- id: timer_program
label: Timer Program
description: >-
Multi-step program of up to 10 steps (last step always End Program), each
a 32-byte TIMER_PROGRAM structure whose first byte is a step function
opcode 0x00-0x0B (see timer_step_* actions). Store via store_program
(B3), load and prepare via load_program_reset (AC), execute via
execute_stored_program (B8), start/pause via program_start_pause (AE).
Source recommends using TM-Manager to create programs, then modifying
bytes for timing changes. Example invocation with Ncat:
ncat --udp 192.168.1.1 7372 < file.bin
Safety
confirmation_required_for: []
interlocks: []
# UNRESOLVED: no safety warnings, interlock procedures, or power-on sequencing
# requirements found in source.
Notes
- Binary UDP protocol — all commands are raw byte sequences, not ASCII text. 7372 is the standard port for communication with the clocks; device query also responds to broadcast on that port.
- Most commands acknowledge with single byte 'A' (0x41); Get Program/Get Active Program return full program data.
- Volatile settings (lost on power cycle): revert-to-time timeout (BB), dimmer set (B5), timezone variables (BE), color set (B6).
- Timer program structure is exactly 32 bytes per step; 3 bytes of padding follow the command byte before the union. Programs occupy 334 bytes (name + 10 steps).
- TIMER_PROGRAM.color union members (red1/grn1/blu1/red2/grn2/blu2/colorIndex1/colorIndex2) exist for Change Colors on older firmware; from POE 5.4 / WiFi 3.4 the color section is no longer needed but maintained for older clocks.
- Start/Pause second-byte semantics (A3/A6/BA) added in API v1.1 to prevent repeated packets negating previous packet's meaning; supported from WiFi clock 2.3, POE clock 4.5, DotMatrix 1.1.
- API v2.3 supports only models in the firmware table; see v1.1 of the source document for earlier models. Series letter (B vs C) determined by first letter of device serial number.
- TM-Manager / TM-Timer use this protocol to find and monitor clocks; a Wireshark capture of that software shows example data transfer.
- Source document: Locator Protocol API version 2.3, July 2025. Revision history: v1.0 Feb 2018 (initial); v1.1 Mar 2018 (start/pause byte semantics, TM2000A); v2.0 Mar 2021 (real-time timer reporting, relay/dimmer/RGB); v2.1 (countdown to date, 9-digit displays, relay toggle); v2.2 May 2023 (2-line dot matrix, bargraph bit); v2.3 July 2025 (timer program documentation).
Provenance
source_domains:
- timemachinescorp.com
source_urls:
- https://timemachinescorp.com/wp-content/uploads/TimeMachinesControlAPI.pdf
retrieved_at: 2026-09-02T17:16:47.152Z
last_checked_at: 2026-09-22T11:46:57.803Z
Verification Summary
verdict: verified
checked_at: 2026-09-22T11:46:57.803Z
matched_actions: 39
action_count: 39
confidence: medium
summary: "All 39 spec actions (28 wire commands + 11 timer step opcodes) match the refined source verbatim; transport port 7372 and UDP confirmed. (9 unresolved item(s) noted in Known Gaps.)"
Known Gaps
- "per-command firmware compatibility matrix beyond the section-level minimums stated in source"
- "no persistent settable variables beyond the dimmer/color/revert"
- "no unsolicited notification protocol documented; all responses"
- "no safety warnings, interlock procedures, or power-on sequencing"
- "error response behavior for invalid commands not documented"
- "maximum packet size / fragmentation handling not documented"
- "whether device sends unsolicited notification on timer completion or relay trigger"
- "byte offsets of TIMER_PROGRAM.color union within the 32-byte step not fully tabulated"
- "full per-command firmware compatibility matrix not stated"
From the AI4AV catalog (https://ai4av.net) · ODbL-1.0