news 2026/9/29 4:35:32

DLMS/COSEM 蓝皮书解读(十):Schedule 类(class_id = 10)—— “什么时候、按什么周期”:Script table 的时间搭档

作者头像

张小明

前端开发工程师

1.2k 24
文章封面图
DLMS/COSEM 蓝皮书解读(十):Schedule 类(class_id = 10)—— “什么时候、按什么周期”:Script table 的时间搭档

DLMS/COSEM 蓝皮书解读(十):Schedule 类(class_id = 10)—— “什么时候、按什么周期”:Script table 的时间搭档

系列说明:本系列基于 DLMS UA《Blue Book(蓝皮书)第 16 版 · 第 2 部分 —— COSEM interface classes》,一个接口类一篇。第 9 篇讲了Script table(class_id = 9),它解决的是"到点了要执行哪些动作"(把一组SET/ACTION打包成脚本)。本篇的Schedule解决的是紧接着的下一个问题:这些脚本在"什么时候、按什么周期"执行。它和Script table是一对必须同时配置才成立的搭档。

上篇回顾:Script table把"做什么"外置成了数据 ——scripts里存着若干脚本,每个脚本是一串action_specification,由execute(data)触发。但它有一个致命的设计前提:它自己不会醒来。Script table没有"时间"属性,没有"周期"属性,也没有任何"到点自查"的逻辑。它只回答"做什么",把"何时做"整个留给了别人。本篇的Schedule就是来补这个洞的:它持有一张带时间的条目表,时间一到,就按script_logical_name+script_selector去把对应的脚本叫起来。

(版本说明:Schedule在本卷 raw 原文里只有version = 0一个版本,entry 结构为schedule_table_entry,故本篇不设版本对比章节。关于某些资料中出现的另一种 entry 形态,见 2.2 末尾的说明。)


0. 为什么必须要有 Schedule

把"表内自动化"拆成三要素,第 9 篇已经画过这张表,本篇把它补全:

要素由谁负责class_id
现在几点Clock8
在什么时候、按什么周期执行Schedule10
做什么Script table9
被操作的对象Register activation/Profile generic/Demand register…6 / 7 / 5

没有Schedule的话,"周期性动作"只剩三条路,每条都有硬伤:① 主站定时下发—— 22:00 切谷费率,主站要在 22:00:00 那一刻给全城 10 万块表各发一条SET,拥塞、离线表漏发、下发到一半断线全都无法收拾,而且那是主站的时钟,不是表的时钟;② 固件写死时段表—— 改一次峰谷时段就要改固件,在计量行业意味着重新送检;③ 厂商私有时间对象—— 各家一套格式,互操作性归零。

Schedule的答案和Script table一脉相承:把"什么时候"也外置成数据。一张entries表放在attribute里,表内固件只有一个通用引擎(比对时间 → 命中条目 → 调脚本),改时段 = 一次SET,不动固件,也不依赖主站在线。

蓝皮书原文(Schedule, Overview):
“This IC, together with the IC ‘Special days’, allows modelling time- and date-driven activities within a device.”

注意这一句把Schedule(10)和Special days table(11)绑在一起提到了:前者管"常规日程",后者管"对常规日程的例外覆盖"。这是本类的第一个关键点 —— 它从设计之初就不是孤立的一张表。

一句话定位:

Schedule=表内的 cron 表。它不管做什么(Script table的事),只管"什么时候、星期几、在哪个日期区间内"去叫那个脚本。

它和 Activity calendar / Single action schedule 怎么分工

三个类都能触发脚本,工程上最容易选错,判断标准很实用:"周期性 / 长期有效"用Schedule(switch_time可含通配符 +exec_weekdays+begin_date/end_date);"只干一次"用Single action schedule(22)(execution_time是精确的 time + date);"要按季节分层、随费率切换"用Activity calendar(20)(season_start→week_profile→day_profile层层嵌套)。三者可以共存于一台设备,但同一个动作不要配两处 —— 那是"费率被切两次"这类诡异故障的常见来源。


1. 类蓝图

Schedule 0...n class_id = 10, version = 0

基数0...n:一台设备可以有多个Schedule实例(费率切换一张、日冻结一张、负荷控制一张),也可以一个都没有。

属性静态/动态数据类型MinMaxDefShort name
logical_name(static)octet-stringx
entries(static)arrayx + 0x08
方法必选/可选(m/o)Short name
enable/disable (data)ox + 0x20
insert (data)ox + 0x28
delete (data)ox + 0x30

注 1:原文未给 Min / Max / Def 三列任何取值,故留空。两个属性全是 static—— static 表示"值不会由设备自发改变",不等于不可写;entries恰恰是主站改写最频繁的属性之一。
注 2:三个方法全部是o(optional)—— 一块表可以完全不实现任何Schedule方法,只把entries当可读写配置;调用前必须确认。另外 SN 寻址时属性结束在x + 0x08、方法从x + 0x20起步,中间0x10、0x18是空的,不能按 0x08 步长顺推。

只有 2 个属性,但全部复杂度都藏在entries这一个array里。


2. 属性逐条解读

2.1logical_name(static, octet-string)

“Identifies the ‘Schedule’ object instance.”

6 字节OBIS,Schedule常见取值形如0-0:11.0.0(示例值,非蓝皮书原文,实际以设备对象列表为准),A 组 = 0 属于"抽象/公用"对象。它自己不会被谁引用(Schedule是链条的发起端),但它引用的script_logical_name必须存在,否则命中条目后execute落空(见第 9 篇"软引用脱节")。

2.2entries(static, array)—— 本篇的全部内容

蓝皮书原文(Schedule, entries):
“Specifies the scripts to be executed at given times. There is only one script that can be executed per entry.”

“array schedule_table_entry”

两句话两层意思:entries是条目的数组;每个 entry 只能挂一个脚本(想要一个时刻做两件事?那就写两个 entry,或者把两件事合成一个脚本 —— 见示例 6)。

原文给出的structure定义,10 个字段,一个都不少:

schedule_table_entry ::= structure { index: long-unsigned, enable: boolean, script_logical_name: octet-string, script_selector: long-unsigned, switch_time: octet-string, validity_window: long-unsigned, exec_weekdays: bit-string, exec_specdays: bit-string, begin_date: octet-string, end_date: octet-string }
字段类型干什么用
indexlong-unsigned条目主键(不是数组下标!)。同时决定同一时刻的执行顺序
enableboolean本条目是否生效(enable/disable方法改的就是它)
script_logical_nameoctet-string目标Script table对象的OBIS
script_selectorlong-unsigned目标脚本的script_identifier(按编号匹配)
switch_timeoctet-string执行时刻,允许通配符→ 用来表达"重复"
validity_windowlong-unsigned掉电/时间跳变后补执行的容忍窗口,单位分钟
exec_weekdaysbit-string星期几生效(Mo…Su)
exec_specdaysbit-string关联Special days table的day_id
begin_dateoctet-string有效期起始日(允许通配符)
end_dateoctet-string有效期结束日(允许通配符)

“script_logical_name: defines the logical name of the ‘Script table’ object;”

“script_selector: defines the script_identifier of the script to be executed;”

与第 9 篇Activity calendar的day_profile_action引用方式完全一致(OBIS + 编号的软引用),改脚本不会触发任何一致性检查。

“switch_time accepts wildcards to define repetitive entries. The format of the octet-string follows the rules set in for time;”

switch_time支持通配符 —— 这是"周期性重复"的实现机制。按 4.6.1 的 time 编码它是 4 字节octet-string:hour | minute | second | hundredths,把某个字节写成通配符0xFF就等于"这一位任意":

switch_time(4 字节)触发效果
16 00 00 00每天 22:00:00.00 执行一次
16 FF 00 0022 点内的每一分钟都触发(22:00、22:01 … 22:59)
FF 00 00 00每小时的第 0 分触发(00:00、01:00 … 23:00)
FF FF FF FF全通配(工程上几乎不用,等于"一直触发")

“validity_window defines a period in minutes, in which an entry shall be processed after power fail. (time between defined switch_time and actual power_up) 0xFFFF: the script is processed any time;”

validity_window是全类最容易被误读的字段。它不是"动作持续多久",也不是"执行的宽限期",而是掉电恢复后判断"这条还补不补"的时间差上限:switch_time与实际上电时刻之间相差多少分钟之内,这条条目还算"欠账"、需要在恢复后补执行。注意单位是分钟,且0xFFFF是个特殊值 =任何时候都补(不管隔了多久)。

“exec_weekdays defines the days of the week on which the entry is valid;”

“exec_specdays perform the link to the IC ‘Special days table’, day_id;”

两个bit-string是并列的两套"日子"选择:exec_weekdays管星期(7 bit:Mo…Su),exec_specdays管特殊日(每 bit 对应Special days table的一个day_id)。两者是"或"的关系 —— 命中星期或命中特殊日,都触发。

“begin_date and end_date define the date period in which the entry is valid (wildcards are allowed). The format follows the rules set in for date.”

begin_date/end_date是 5 字节octet-string,按 date 编码:year_hi | year_lo | month | day_of_month | day_of_week。年份写0xFFFF就是"每年" —— 这正是"周期性"与"一次性"的分水岭:FF FF 04 01 FF→FF FF 09 1E FF是每年 4/1–9/30 的夏季日程(周期性);begin_date = end_date = 07 EA 09 1E FF(2026-09-30)则只在当天有效(一次性时间窗口,这种需求其实更适合Single action schedule)。

关于另一种 entry 形态(非本卷原文,仅供对照):在一些较新的资料 / 版本中,Schedule的 entry 被重构为schedule_entry,形如{index, enable, action_type, exec_time: array of date_time, script},即用一个action_type(enum)区分动作类型、用一个date_time数组承载多个执行时刻、并把script_logical_name/script_selector收进一个script子 structure。本文所依据的 raw 原文(Ed.16 Part 2, Schedule version = 0)并未包含该形态,action_type的枚举取值原文亦未提供—— 故本篇不对其展开规格。若你的设备对象列表里出现这种结构,请先核对所依据的蓝皮书版本与厂商文档,再决定解析方式。两者的语义对应关系可粗记为:exec_time(array)≈ 本文的switch_time+begin_date/end_date组合,script≈script_logical_name+script_selector。

2.3 原文给的那张示意表

raw 开头有一张Table — Schedule+Table — Special days table,是蓝皮书用来演示两者配合的(原表为节选排版,列位对齐按语义推断,仅作示意):

indexenableswitch_timevalidity_windowexec_weekdaysbegin_dateend_date
120Yes06:000xFFFFMo–Saxx-04-01xx-09-30
121Yes22:0015Mo–Frxx-04-01xx-09-30
122Yes12:000Suxx-04-01xx-09-30
200–202No06:30 / 21:30 / 11:00—Mo–Sa / Mo–Fr / Suxx-04-01xx-09-30

配套的Special days table:index 12 → xx-12-24 → S1(每年圣诞夜)、index 33 → xx-12-25 → S3、index 77 → 97-03-31 → S3(1997-03-31,一次性)。

一眼能看明白三件事:①xx= 年份通配符,所以"每年 4/1–9/30"是周期性的夏季日程,而97-03-31写了具体年份,是一次性的特殊日;② 120–122 与 200–202 是两套互为备份的日程(夏 / 冬),靠enable或enable/disable方法整段切换(见示例 5);③validity_window三档——0xFFFF(无条件补执行)、15(掉电后 15 分钟内才补)、0(永不补执行),必须按业务重要性分配。


3. 方法详解(三个,全是o)

3.1enable/disable (data)

data ::= structure { firstIndexA, lastIndexA, firstIndexB, lastIndexB: long-unsigned }

“Sets the disabled bit of range A entries to true and then enables the entries of range B.”

一次调用干两件事:先把区间 A 全部enable = false,再把区间 B 全部enable = true。设计意图非常明确 ——季节切换,一步完成"关旧日程、开新日程",不存在中间态。区间语义由两个端点的大小关系决定(原文逐条列出):

条件结果
firstIndexA/B < lastIndexA/B该区间的所有条目被 disable / enable
firstIndexA/B = lastIndexA/B只 disable / enable一个条目
firstIndexA/B > lastIndexA/B什么都不做
firstIndexA/B与lastIndexA/B> 9999该区间没有任何条目被 disable / enable

3.2insert (data)

“Inserts a new entry in the table. If the index of the entry exists already, the existing entry is overwritten by the new entry.”

“entry: schedule_table_entry / data ::= corresponding to entry”

data就是一个完整的schedule_table_entry。index相同时也不是报错,而是覆盖—— 这实际上把insert变成了"upsert":改配置无需先删后插,但写错index会静默覆盖掉一条正在用的日程。

3.3delete (data)

data ::= structure { firstIndex, lastIndex: long-unsigned }

“firstIndex < lastIndex: all entries of the range A/B are deleted,”
“firstIndex = lastIndex: one entry is deleted,”
“firstIndex > lastIndex: nothing deleted”

注意delete没有“> 9999视为空操作” 那一条(那是enable/disable独有的);删除按index区间匹配,不是数组位置 —— 删掉中间一条后,剩余条目的index不变。

3.4 两条"撞车"规则(原文 Remarks)

“If the same script should be executed several times at a specific time instance, then it is executed only once.”

“If different scripts should be executed at the same time instance, then the execution order is according to the ‘index’. The script with the lowest ‘index’ is executed first.”

  • 同一脚本在同一时刻被多条 entry 命中 → 只执行一次(天然去重);
  • 不同脚本在同一时刻 → 按index升序执行,小的先跑。

第 9 篇Script table里"同一时刻较小 index 者优先"的规则与此完全同源。


4. 【实战举例】

以下示例中的 OBIS、配置取值与报文字节均为帮助理解而构造,非蓝皮书原文,实际以设备对象列表与厂商文档为准。编码按 4.6.1 的 time / date 规则与 A-XDR 规则(structure=0x02、array=0x01、boolean=0x03、bit-string=0x04、octet-string=0x09、long-unsigned=0x12)构造。

示例 1:工作日 22:00 切谷费率(一条完整 entry 的 A-XDR)

承接第 9 篇示例 1 的脚本(Script table=0-0:10.0.0,script_identifier = 1):

Schedule logical_name = 0-0:11.0.0 (示例) entries[0] = { index = 120, # 主键(不是数组下标) enable = TRUE, script_logical_name = 0-0:10.0.0, # 指向 Script table script_selector = 1, # script_identifier = 1 switch_time = 22:00:00.00, validity_window = 15, # 掉电后 15 分钟内补执行 exec_weekdays = Mo–Fr, # 工作日 exec_specdays = (无), begin_date = xx-04-01, # 每年 4 月 1 日起 end_date = xx-09-30 # 每年 9 月 30 日止 }

SET该entries属性的 A-XDR(示例):

01 01 array(1) entries 02 0A structure(10) schedule_table_entry 12 00 78 long-unsigned 120 index 03 01 boolean TRUE enable 09 06 00 00 0A 00 00 FF octet-string(6) 0-0:10.0.0 script_logical_name 12 00 01 long-unsigned 1 script_selector 09 04 16 00 00 00 octet-string(4) 22:00:00.00 switch_time 12 00 0F long-unsigned 15 validity_window 04 07 7C bit-string(7) Mo–Fr exec_weekdays 04 09 00 00 bit-string(9) 无特殊日 exec_specdays 09 05 FF FF 04 01 FF octet-string(5) xx-04-01 begin_date 09 05 FF FF 09 1E FF octet-string(5) xx-09-30 end_date

exec_weekdays的 7 个 bit 按 Mo→Su 从高位排:Mo =0x40… Su =0x01,故 Mo–Fr =0x7C、Mo–Sa =0x7E、Su =0x01、Mo–Su =0x7F。exec_specdays的 bit 数必须与Special days table里day_id的取值范围长度一致(原文:the range of the day_id shall match the length of the bit-string exec_specdays);上表用 S1–S9,故取 9 bit、2 字节。

示例 2:周期性 vs 一次性 —— 两种日期写法

同一条"23:59 结算"的需求,两种配置语义完全不同(示例):

# A. 周期性:每年 9 月 30 日 23:59(2026 执行,2027 还会执行) switch_time = 17 3B 00 00 # 23:59:00.00 begin_date = FF FF 09 1E FF # 年份 0xFFFF = 每年 end_date = FF FF 09 1E FF # B. 一次性:只在 2026-09-30 执行一次,2027 年该条目已过期 switch_time = 17 3B 00 00 begin_date = 07 EA 09 1E 03 # 2026-09-30,周三(dow = 3) end_date = 07 EA 09 1E 03

若按新版形态(见 2.2 说明)写成exec_time: array of date_time,同一时刻的date_time(12 字节)编码为(示例):07 EA | 09 | 1E | 03 | 17 3B 00 00 | 01 E0 | 00—— 依次是 year0x07EA= 2026、month 9、dom 30、dow 3(周三)、time 23:59:00.00、UTC 偏差0x01E0= +480 min、clock_status0x00。对照本文 version = 0 的写法:date_time的前 5 字节就是 date、第 6–9 字节就是 time,后 3 字节是 UTC 偏差与clock_status(本类用不到)。本卷Schedule用拆开的switch_time(4 字节)+begin_date/end_date(5 字节),不要混用。

示例 3:validity_window—— 掉电恢复补不补

“After a power failure, the whole schedule is processed to execute all the necessary scripts that would get lost during a power failure.”

设switch_time = 22:00,表在 21:50 掉电、23:10 上电(相差 70 min):validity_window = 0xFFFF→无条件补执行(“the script is processed any time”);= 15→ 70 > 15,不补,这次费率切换丢失(若 22:05 就上电,5 ≤ 15 则补执行)。三条结论:① 费率切换类建议0xFFFF,漏一次就是一整天的费率错;② "抓冻结"类反而要小窗口(0也行),补一次capture可能抓到时间戳错位的记录;③ 单位是分钟,写 3600 以为毫秒/秒会得到荒谬巨大的窗口。

示例 4:周末 + 特殊日(两个 bit-string 的配合)

某地在 12 月 24 日执行特殊费率(不走常规周末日程),配置如下(示例):

Special days table (11):{ index = 12, specialday_date = FF FF 0C 18 FF, day_id = 1 } # xx-12-24 → S1 { index = 33, specialday_date = FF FF 0C 19 FF, day_id = 3 } # xx-12-25 → S3 Schedule (10):entry { index = 300, switch_time = 12:00, exec_weekdays = 04 07 01, # 7 bit,仅周日 exec_specdays = 04 09 80 00 } # 9 bit,S1 置位

12 月 24 日即使是周三,也因为命中exec_specdays的 S1 而触发——Special days table的 Overview 说得很直白:

蓝皮书原文(Special days table, Overview):
“On such dates, a special switching behaviour overrides the normal one.”

特殊日覆盖(override)常规日程—— 这是下篇(class_id = 11)的主线,本篇只需记住exec_specdays是这条覆盖关系的接口。

示例 5:夏 / 冬日程整段切换(enable/disable)

用示意表的两套条目(120–122 夏、200–202 冬),4 月 1 日切换:

ACTION (class_id = 10, logical_name = 0-0:11.0.0, method_index = 1) # enable/disable data ::= structure { firstIndexA = 200, lastIndexA = 202, # 关掉冬季(200 < 202 → 全区间) firstIndexB = 120, lastIndexB = 122 # 打开夏季 } → A-XDR(data 部分,示例):02 04 12 00 C8 12 00 CA 12 00 78 12 00 7A ↑0x00C8=200 ↑0x00CA=202 ↑0x0078=120 ↑0x007A=122

若只想动一条(临时禁用 121):firstIndexA = lastIndexA = 121,区间 B 写成"空操作" —— 例如firstIndexB = 10000, lastIndexB = 10000(两者均 > 9999 → 该区间不动作)。端点大小关系本身就是语义(<全区间 /=单条 />不做),写反了不报错,只会"安静地没生效"。

示例 6:同一时刻多条 entry 撞车(index 就是排序键)

entry { index = 120, switch_time = 22:00, script_selector = 1 } # 切谷费率 entry { index = 121, switch_time = 22:00, script_selector = 1 } # 同一脚本,写重了 entry { index = 122, switch_time = 22:00, script_selector = 2 } # 抓冻结

22:00 到来时:120 与 121 指向同一脚本→ 只执行一次;122 是不同脚本 → 排在后面。实际顺序"切谷费率 → 抓冻结"。想让某件事先发生,就给它更小的index。

示例 7:四种时间变更,各怎么处理

原文把时间变更分成四类,处理策略各不相同 —— 这是Schedule最硬核的一块:

变更类型触发方式Schedule 的处理
时间向前设置写Clock的timeattribute与掉电同等处理:所有被跳过的条目按validity_window决定是否补执行。很短的(manufacturer specific)向前调整可按"时间同步"处理
时间向后设置写Clock的timeattribute被回拨区间内的条目会重复执行
时间同步Clock的adjust_to_quarter方法算法 manufacturer specific,但必须保证不丢、不重复执行;validity_window不起作用
夏令时切换Clock的 DST 属性时钟拨快 → 落入该区间的脚本先执行(避免丢失);拨慢 → 落入该区间的脚本抑制重执行

“Time synchronization is used to correct small deviations between a master clock and the local clock. … It shall guarantee that no entry of the schedule gets lost, or is executed twice.”

给主站的最直接结论:主站校时不要动辄写Clock.time(那是"时间设置",会触发补执行/重执行连锁),小幅偏差应该用adjust_to_quarter这类同步方法。


5. 工程上容易踩的坑

  1. 把index当数组下标:index是条目的业务主键,insert/delete/enable/disable全部按index匹配;同时它还是排序键(同一时刻不同脚本按index升序执行,排反了冻结记录就会落在错误的费率上)。删掉中间一条后其余index不变,按下标推算必然错位。
  2. insert是 upsert:index已存在时静默覆盖(原文:“the existing entry is overwritten”)。批量下发日程前若没先读回entries比对,可能覆盖掉现场正在用的条目。
  3. validity_window理解错:它是"掉电/跳变后补执行的时间差上限",单位分钟,0xFFFF= 无条件补,0= 永不补。它不是"动作持续时长"。
  4. switch_time通配符乱填:想"每天 22:00"却写成16 FF 00 00(22 点内每分钟触发),费率脚本会被执行 60 次。通配符只用来表达"重复粒度",配完必须在实验表上跑一遍。
  5. 年份忘写通配符:begin_date写成07 EA ...(2026)却指望它年年生效 —— 到 2027 年这条条目整体失效,且没有任何告警。周期性日程的年份必须是FF FF。
  6. exec_specdays的 bit 数与day_id范围不匹配:原文要求两者长度一致(“the range of the day_id shall match the length of the bit-string exec_specdays”)。表里有 S1–S9(9 bit)而这里只写 7 bit,S8/S9 永远命中不了 —— 表现为"特殊日不生效",且很难查。
  7. 重复执行是允许的正常行为:时间向后设置会重跑、掉电会补跑。所以脚本动作必须幂等(用SET绝对值,不用"取反/累加"),这一点第 9 篇已经埋过伏笔。
  8. 三个方法都是o:不要假设insert/delete/enable/disable存在;不支持时退化为"整块SET重写entries",但要先读回原值再改,避免覆盖。另外主站校时别直接写Clock.time(那是"时间设置",会触发补执行/重执行连锁)。

6. 小结 & 下期预告

本篇要点:

  1. Schedule(class_id = 10, version = 0)是表内的 cron 表:Script table回答"做什么",它回答"什么时候、星期几、哪段日期内、按什么周期"去叫那个脚本;
  2. 只有 2 个属性 ——logical_name(static)、entries(static,array schedule_table_entry),10 字段的 entry:index/enable/script_logical_name/script_selector/switch_time/validity_window/exec_weekdays/exec_specdays/begin_date/end_date;
  3. 周期性重复靠通配符(switch_time的分/时字节写0xFF、日期年份写FF FF),一次性窗口则给begin_date/end_date写具体年份 —— 后者更适合交给Single action schedule(22);
  4. validity_window是掉电/时间跳变后的补执行窗口,单位分钟,0xFFFF= 无条件补,0= 永不补;
  5. 三个方法enable/disable(一次关 A 段、开 B 段,专为季节切换设计)、insert(upsert)、delete全是o(可选);同一脚本同一时刻只执行一次,不同脚本按index升序执行;
  6. 时间变更四类(向前设置 / 向后设置 / 同步 / 夏令时)处理策略不同 —— 主站校时优先用Clock的同步方法,别直接写time。

下一篇(第 11 篇):Special days table(class_id = 11)—— 本篇的exec_specdays只留了一个"接口",完整规则在那边。它用entries(array spec_day_entry,每个 entry 是index+specialday_date+day_id)定义节假日与例外日,让特殊日覆盖常规日程,是费率日历完整性的最后一块拼图。我们还会讲清day_id的取值范围如何与exec_specdays的 bit 长度对齐、通配符怎么表达"每年圣诞"这类重复节日,以及它与Activity calendar(20)里day_profile的优先级关系。


参考资料:DLMS UA《Blue Book Ed.16 Part 2 – COSEM interface classes》,Schedule (class_id = 10, version = 0) 章节(含 Overview、Table “Schedule”、Table “Special days table”、Attribute description、Method description、Remarks concerning inconsistencies、Recovery after power failure、Handling of time changes 各小节),以及 Special days table (class_id = 11) 章节中 Overview 与spec_day_entry的相关描述。文中 2 个属性的名称、static 标记、数据类型、Short name 偏移、3 个方法的名称与 m/o、Short name 偏移、以及全部英文引文均与原文一致;示例中的 OBIS(0-0:11.0.0/0-0:10.0.0)、配置取值与报文字节为帮助理解而构造(实际以设备对象列表与厂商文档为准)。2.2 末尾关于schedule_entry/exec_time/action_type的对照说明非本卷 raw 原文,仅为版本差异提示。

版权声明: 本文来自互联网用户投稿,该文观点仅代表作者本人,不代表本站立场。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如若内容造成侵权/违法违规/事实不符,请联系邮箱:809451989@qq.com进行投诉反馈,一经查实,立即删除!
网站建设 2026/9/29 4:35:12

芯参谋(23):并口/并行NOR_PPI_NOR_软件设计规范

并行NOR_PPI_NOR_软件设计规范 http://39.108.239.75:5001/share/DNylYp0iuzRP5QC http://39.108.239.75:5001/share/DNylYp0iuzRP5QC 并行 NOR Flash&#xff08;PPI NOR&#xff09;软件设计规范 编制日期 2026-09-24 &#xff5c; 版本号 Rev 1.5 面向 异步 SRAM 类并行…

作者头像 李华
网站建设 2026/9/29 4:34:34

AI前端美化规则 Taste Skill:用 SKILL.md 让 Cursor 告别塑料感界面

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 4:34:26

Win10安装JDK1.8完整教程:从下载到环境变量配置与排错

/* MD / 富文本中的 .toc(含博客园搬家等嵌套结构);.toc-box 在侧栏,不受影响 */#content_views .toc,/* 编辑器常在目录前后插入空 p(:empty 仍占 20px),一并去掉避免顶空隙 */#content_views.markdown_views > p:empty:has(+ .toc),#content_views.markdown_views …

作者头像 李华
网站建设 2026/9/29 4:29:15

同城电商系统:库存变更怎么同步到订单

同城电商系统库存变更若不同步到订单占用层&#xff0c;会出现「后台显示有货、实际已被未支付单占满」。宜库存 物理量 - 占用量&#xff1b;占用在下单创建&#xff0c;支付成功转实扣&#xff0c;超时释放。模型 sku_stock: on_hand sku_hold: sum(active holds) available…

作者头像 李华
网站建设 2026/9/29 4:25:46

hindsight浏览器历史取证实战:从SQLite碎片还原行为时间线

最近接了一个数据审计的活儿&#xff0c;客户拿了一台旧笔记本过来&#xff0c;说想搞清楚某天晚上这台设备到底访问了哪些网站、下载过什么文件、登录过哪些账号。设备早就关了机&#xff0c;现场也早就收拾干净了&#xff0c;唯一的线索就是浏览器里残留的那些数据库文件。这…

作者头像 李华