文档

通过电子表格为屏幕排程

场馆把排程保存在电子表格里:每行有屏幕代码、文件名、开始和结束。导入工作表后,screenRIG 对照你的屏幕和媒体检查每一行,按行和列指出每个问题,预览屏幕将遵循的日历,并全部应用或全部不应用。

从工作表到屏幕

  1. 从模板开始。将模板保存为 CSV 或 XLSX,或使用列相同的自有工作表。
  2. 每条排程填一行。写明屏幕(或文件夹、标签)、文件、开始和结束。
  3. 导入。将文件拖到仪表板排程标签页的导入对话框,或运行 screenrig schedule import FILE。
  4. 更正有错误的行。每个错误都指明行、列和代码。在对话框中编辑单元格,或编辑工作表后重新导入。
  5. 检查预览。列出工作表生成的层级、它更改或移除的层级,以及它涉及的屏幕的日历。
  6. 发布。所有行一起应用,或都不应用。

第 1 到 5 步不写入任何内容。屏幕需要时区(screen set-timezone)和默认播放列表(screen assign),行才能为其排程,且文件必须是已批准的图像或视频。

工作表

第一行为列名。之后每一行是一条排程。空行会被跳过。工作表是 CSV 文件(UTF-8,逗号或分号分隔)或 XLSX 工作簿,XLSX 工作簿读取其第一个工作表。

列也读作包含内容
targetscreen, screen code, code, room, room id, screen name, screen id该行排程的屏幕。必填
contentfile, file name, media, asset, playlist播放的内容。必填
startstart date, from, begin该行开始的时间
endend date, until, stop该行结束的时间
timezonetime zone, tz该行时间所用的时区
daysweekdays, day该行播放的星期
daily startwindow start, time from每个播放窗口开启的时刻
daily endwindow end, time to每个播放窗口关闭的时刻
priority0 到 100。高的优先于低的播放。默认 0
namelevel, label该行生成的层级的名称
displaydisplays, output该行播放所在的视频墙输出,如 1 或 1,2

表头匹配时忽略大小写、空格和标点。没有任何内容读取的列会被忽略,预览会列出它。一行需要 target、content,以及 start、end、days 或每日时间窗口中的至少一项。

Screen,File,Start,End,Timezone,Days,Daily start,Daily end,Priority,Name
LOBBY-01,welcome-spring.jpg,2026-11-05 18:00,2026-11-08 02:00,America/Los_Angeles,,,,0,
folder:Casino Floor,happy-hour.mp4,2026-11-05,2026-11-30,,Mon-Fri,16:00,19:00,5,Happy hour
tag:elevators,playlist:Holiday loop,2026-12-01 09:00,2026-12-26,,,,,0,
  • 第 2 行在代码为 LOBBY-01 的屏幕上播放 welcome-spring.jpg,从 11 月 5 日下午 6 点到 11 月 8 日凌晨 2 点,太平洋时间。
  • 第 3 行在文件夹 Casino Floor 及其内部文件夹的每个屏幕上播放 happy-hour.mp4,工作日下午 4 点到 7 点,从 11 月 5 日到 11 月 30 日结束。
  • 第 4 行在带标签 elevators 的每个屏幕上播放播放列表 Holiday loop,从 12 月 1 日上午 9 点到 12 月 25 日结束。

目标

目标可以是以下之一:

  • 屏幕。屏幕 id、屏幕任意字段的值(房间代码、门店编号)或屏幕名称。--code-field 或 code_field 将匹配限制在一个字段,如 code 或 room_id。
  • 文件夹。folder:NAME 或 folder:Parent/Child。覆盖该文件夹及其内部的每个文件夹。
  • 标签。tag:NAME 覆盖带该标签的每个屏幕。

一个单元格中的多个目标用 ; 或 | 分隔,如 LOBBY-01;LOBBY-02|tag:elevators。

内容

  • 文件。项目中某个媒体文件的名称,或转换后上传文件的原始文件名。文件全屏播放。首次提交使用某文件时,会创建单文件播放列表 Scheduled: FILE,之后的导入复用它。
  • 播放列表。playlist:NAME 或播放列表 id。该播放列表有已批准的版本,且不是模板。

时间

  • 日期和时间。读取 2026-11-05 18:00、2026-11-05T18:00、11/5/2026 6:00 PM 和电子表格日期单元格。带偏移量的时间(如 Z 或 +02:00)会被拒绝。
  • 每个屏幕自己的时钟。时间按该行涉及的屏幕的时钟读取,所以无论屏幕在哪里,18:00 都是下午 6 点。
  • 其他时区。timezone 单元格(或请求的 timezone)表示该行按该时区书写。当该行的所有屏幕共用一个时区时,时间会转换为屏幕的时区。覆盖多个时区屏幕的行会让 timezone 为空,并按每个屏幕自己的时钟读取。
  • 只有日期的结束时间在当天结束时关闭:2026-11-30 在 11 月 30 日结束时结束。只有日期的开始时间从午夜开始。
  • 没有结束时间会让该行一直播放,直到之后的导入将其移除。预览以 open_end 警告。
  • 星期。Mon-Fri、Mon,Wed,Fri、Sat,Sun、weekdays、weekends 或 daily。带 days 但没有每日时间窗口的行,在这些日子全天播放。
  • 每日时间窗口。daily start 和 daily end 给出每天的时段,如 16:00 和 19:00 或 4:00 PM 和 7:00 PM。两者都要填。结束时间等于或早于开始时间时跨越午夜,并归属于开始的那一天。没有 days 时,该窗口每天适用。

预览与错误

预览在写入任何内容之前检查每一行和每个单元格。有错误的行连同其单元格一起显示,每个错误指明列、代码和要更改的内容。

代码列含义与修复
requiredtarget, content, daily start, daily end单元格为空,或每日时间窗口的单元格只填了一个。请填写
unknown_screentarget没有屏幕具有该 id、字段值或名称。检查代码,或 code_field 指定的字段
ambiguous_screentarget该值匹配多个屏幕。请使用屏幕 id 或唯一的代码
unknown_foldertarget没有该名称的屏幕文件夹。检查拼写
ambiguous_foldertarget多个文件夹使用该名称。写出路径,例如 folder:Hotel/Casino Floor
unknown_tagtarget没有屏幕带有该标签。检查拼写
unknown_filecontent没有该名称的文件或播放列表。上传文件,或更正名称
ambiguous_filecontent多个文件使用该名称。重命名其一,或写 playlist:NAME
not_playablecontent文件不是图像或视频,媒体正在等待审核,或播放列表是模板或没有已批准的版本。批准它,或另选一个
invalid_timestart, end, daily start, daily end单元格不是日期和时间,或带有时区偏移量。写 2026-11-05 18:00
reversed_timesend结束时间不晚于开始时间。更正其中之一
past_endend结束时间已过。改到更晚,或移除该行
no_timingstart该行没有说明时间。请给出开始、结束、星期或每日时间窗口
invalid_valuedays, priority, display单元格不是星期列表(如 Mon-Fri)、0 到 100 的整数,或显示编号(如 1,2)
timezonetimezone时区未知,或目标包含多个时区的屏幕。请使用如 America/Los_Angeles 的时区,或留空
screen_not_readytarget屏幕没有时区或默认播放列表。运行 screen set-timezone 或 screen assign
overlappriority同一屏幕上两行在同一时间以相同优先级生效。给其中一行不同的优先级,或移动一个时间
limittarget某个屏幕的自有层级将超过 32 个,或组织的活动将超过 100 个(每个共享层级算一个)。合并行,或以文件夹或标签为目标

两个警告不会阻止导入。open_end 标记没有结束时间的行。outranked 标记在某屏幕上被共享层级(面向多个屏幕、文件夹或标签的行)覆盖播放的行。

没有行的工作表、不是 UTF-8 的文件、超过 5,000 行、超过 8 MiB 的文件,或会写入超过 400 个屏幕自有排程的提交,会被拒绝并说明原因。

层级

内容、时间、优先级、名称和显示一致的行合并为一个层级。目标不参与比较,所以十行在十个屏幕上于相同时间播放同一文件,只生成一个层级。

  • 一个屏幕会在该屏幕自己的排程中生成一个条目。
  • 多个屏幕、一个文件夹或一个标签生成一个共享层级,即针对该受众的活动。共享层级优先于屏幕的自有层级。

分组把场馆的 200 个屏幕变成一个活动,而不是 200 个条目,工作表中的一处更正只改变一个层级。name 列指定共享层级。没有时,它以导入、内容和目标命名,如 Spring promos: happy-hour.mp4 on Casino Floor。

再次导入

导入的 name 标识该导入,默认值为 import。以相同名称再次导入:

  • 更新它生成的层级,即使行的日期已更改;
  • 为新行添加层级;
  • 移除工作表中已不存在其行的层级;
  • 工作表相同时不改变任何内容。

导入生成的层级在其 id 中带有该导入(屏幕的条目以 imp_ 开头),活动带有 import 标记。你手动创建的层级不会被触碰。一张工作表使用一个名称,另一张使用不同的名称。

运行导入

控制台

打开项目的排程标签页并选择导入。拖入 CSV 或 XLSX 文件。对话框以表格显示各行,每个错误显示在其单元格旁,你可以就地编辑单元格。然后显示导入所改变屏幕的合成日历。发布即提交。

命令行

screenrig schedule template --output schedule.csv
screenrig schedule import schedule.csv --name "Spring promos" --timezone America/Los_Angeles
screenrig schedule import schedule.csv --name "Spring promos" --timezone America/Los_Angeles --commit

schedule import 只预览,不写入任何内容。当每一行都有效时,--commit 应用工作表。

选项含义
--name NAME导入名称,1 到 80 个字符。默认值为不带扩展名的文件名
--timezone ZONE行没有 timezone 时,时间所用的时区
--code-field FIELD只从此屏幕字段读取屏幕代码
--commit应用工作表
--format csv|xlsxschedule template:模板的格式
--output FILEschedule template:保存位置

命令对有效的工作表以 0 退出,行有错误时以 8 退出(不写入任何内容),预览之后项目已更改时以 5 退出(再次运行)。FILE 是 .csv、.xlsx 或 .json 文件,或用 - 表示标准输入。JSON 文件保存行对象数组,或 {"rows": [...]},以列名为键。

API

以 JSON 行发送工作表,或以 CSV 或 XLSX 请求体发送并用查询参数传设置。预览需要读权限。提交需要具有写权限的凭据,由能在仪表板中批准的人员授予。

curl -s https://api.screenrig.ai/api/schedule/imports/preview \
  --header "Authorization: Bearer $SCREENRIG_TOKEN" \
  --header "Content-Type: application/json" \
  --data '{
    "name": "Spring promos",
    "timezone": "America/Los_Angeles",
    "rows": [
      {"target": "LOBBY-01", "content": "welcome-spring.jpg", "start": "2026-11-05 18:00", "end": "2026-11-08 02:00"},
      {"target": "folder:Casino Floor", "content": "happy-hour.mp4", "start": "2026-11-05", "end": "2026-11-30",
       "days": "Mon-Fri", "daily_start": "16:00", "daily_end": "19:00", "priority": 5, "name": "Happy hour"}
    ]
  }'

同一张工作表作为文件:

curl -s "https://api.screenrig.ai/api/schedule/imports/preview?name=Spring%20promos&timezone=America/Los_Angeles" \
  --header "Authorization: Bearer $SCREENRIG_TOKEN" \
  --header "Content-Type: text/csv" \
  --data-binary @schedule.csv

应答(节选):

{
  "name": "Spring promos",
  "valid": false,
  "fingerprint": "FINGERPRINT",
  "columns": ["target", "content", "start", "end", "days", "daily_start", "daily_end", "priority", "name"],
  "summary": {"rows": 2, "rows_with_errors": 1, "levels": 1, "creates": 1, "updates": 0,
              "unchanged": 0, "removes": 0, "screens": 1, "playlists": 1},
  "rows": [
    {"row": 2, "status": "ok", "level": "LEVEL_KEY"},
    {"row": 3, "status": "error",
     "errors": [{"column": "content", "code": "unknown_file",
                 "message": "No file or playlist is named \"happy-hour.mp4\"."}]}
  ],
  "levels": [{"key": "LEVEL_KEY", "action": "create", "home": "screen", "screen_id": "scr_LOBBY",
              "content": {"kind": "file", "id": "med_WELCOME", "name": "welcome-spring.jpg"},
              "screens": 1, "priority": 0, "from": "2026-11-05T18:00", "until": "2026-11-08T02:00", "rows": [2]}],
  "removals": []
}

rows[].cells 按工作表给出的原样返回每行的单元格,客户端据此更正后再次发送这些行。没有任何行有错误时,valid 为 true。calendar 的结构与 GET /api/schedule/calendar 相同,显示导入在提交后屏幕会变成的样子。

提交发送同一张工作表及其预览的 fingerprint,作为 JSON 请求体的成员,或在发送文件时作为查询参数。发送 Idempotency-Key 可安全重试。

curl -s https://api.screenrig.ai/api/schedule/imports \
  --header "Authorization: Bearer $SCREENRIG_TOKEN" \
  --header "Idempotency-Key: spring-promos-1" \
  --header "Content-Type: application/json" \
  --data @commit.json

应答包含 preview 和 applied、已创建、已更新、未更改和已移除的计数,以及已写入的屏幕和已创建的播放列表。提交会被拒绝且不写入任何内容,原因为:

问题状态含义与修复
schedule_import_invalid422有行存在错误。更正后再次预览
schedule_import_stale409屏幕、媒体、播放列表或层级自预览后已更改,或各行的读取结果不同。再次预览,并使用新的指纹提交

GET /api/schedule/imports/template?format=csv 和 format=xlsx 返回模板。

限制

  • 每个工作表最多 5,000 行和 8 MiB。
  • 每个屏幕 32 个自有层级。一个组织在其所有项目中最多有 100 个活动,每个共享层级算一个。
  • 每次提交最多写入 400 个屏幕的自有排程。一个文件夹或标签行可覆盖任意数量的屏幕。
  • 导入名称为 1 到 80 个字符。