chronaxis.legacy.dbc_cycles
源码基线:8904c2f744951857659abd40aaa3535d57faf53c
1"""核验明确请求的DBC报文周期,不读文件、不解码报文或生成逐条诊断。23周期取同次已加载DBC的message.cycle_time(毫秒),精确换算一次供运行状态复用。4缺失或非法周期直接拒绝,不用快速发送周期、信号周期或实际差作替代。5"""67from decimal import Decimal8from math import isfinite910from .records import LegacyCANField11from ..timebase.conversion import require_int64_ns121314def require_cycle_fields(fields, channel=None):15 """核周期定位声明,不加载DBC。1617 参数: fields为无重复LegacyCANField tuple;channel为可选固定通道。18 返回: 原tuple。异常: TypeError/ValueError为类型、数量、重复或通道不符。19 """20 if (type(fields) is not tuple or len(fields)>409621 or any(type(field) is not LegacyCANField for field in fields)):22 raise TypeError('DBC周期字段需要有限LegacyCANField tuple')23 if len(set(fields)) != len(fields) or channel is not None and any(f.channel != channel for f in fields):24 raise ValueError('DBC周期字段不能重复且必须属于声明通道')25 return fields262728def cycle_time_ns(value):29 """将DBC报文毫秒周期转为正整数纳秒,拒绝有损舍入。3031 参数: value为message.cycle_time,允许原生int或有限float毫秒。32 返回: 正int64纳秒。异常: TypeError/ValueError/TimeOverflowError为缺失、类型、33 非正、非有限、不能精确到纳秒或越界;不为非法值选择默认周期。34 """35 if value is None:36 raise ValueError('所选DBC报文缺少cycle_time周期,请填写period或valid_for;DBC间隔消费者需改选固定间隔')37 if type(value) not in (int,float):38 raise TypeError('DBC报文周期需要数值毫秒,不能为bool或文本')39 if type(value) is float and not isfinite(value) or value <= 0:40 raise ValueError('DBC报文周期必须为有限正数')41 if type(value) is int:42 return require_int64_ns(value*1_000_000,'dbc.cycle_ns')43 # 用DBC公开十进制值转换,不引入二进制浮点乘法误差或静默截断。44 ns=Decimal(str(value))*1_000_00045 if ns != ns.to_integral_value():46 raise ValueError('DBC报文周期不能精确表示为整数纳秒')47 return require_int64_ns(int(ns),'dbc.cycle_ns')48