行业背景:这个问题现在为什么被反复问到
这两年,野外采集类项目被反复问到同一个问题:在没有稳定市电的地方,网关到底怎么供电、怎么省电,还能不能保证数据不丢。光伏板加蓄电池看起来是最直接的答案,但设备真正装到杆上之后,难点往往不是「能不能发一次」,而是「能不能一直发」。
太阳能补能受安装朝向、遮挡、季节和连续弱光影响,同一套配置在晴天富余,在连阴天就捉襟见肘。负载侧同样不是一个恒定值:采样只在毫安级,射频发射的瞬时峰值要高出一个量级,休眠唤醒、链路重连、历史补传又各自带着额外开销。只按平均功耗估算容量,很容易在第一次低温、第一次长时间弱信号里掉电重启。
更麻烦的是,现场对系统其实有三个彼此独立的要求——采样周期要稳、数据允许延迟但必须完整、维护频次要低。把「设备在线」当成唯一指标,会让一个频繁重启、缓存反复清零的站点看起来一切正常,数据缺口要到事后对账才暴露。所以这里要回答的是:在有限储能之下,采样节奏、通信策略、维护方式和异常恢复怎样一起排布,才能让这三个要求同时成立。
痛点:现场到底卡在哪几步
第一处卡点在算容量之前:负载其实没被量清。现场通常只掌握采样模块的静态电流和电池标称容量,而真正决定撑不撑得过去的,是另一组数——射频发射的瞬时峰值、弱信号下的连续重连、补传时长时间占用通信、低温时可放出的容量。按平均功率推出来的日耗电,在晴天里看着有余量;可凌晨电压最低、气温也最低时恰好来一次重连加补传,电压就掉到保护阈值以下,前面缓存的进度一起归零。
第二处是补能的季节波动。朝向、遮挡、积灰和日照角度都会让实际补能比估算低一截,而连续弱光天恰恰是数据最容易积压的时候。按平均日照配储能,还是按最不利时段配,是两个完全不同的结论;方案里只写一种,另一种边界就等于没交代。
第三处是休眠与唤醒的口径对不齐。休眠时长、唤醒后的冷启动、外设上电顺序如果没有统一,就会出现「以为睡了其实没睡实」和「醒了太久」两种偏差;阈值卡在临界点上时,设备还会在节能与正常之间来回切换,状态被切成许多短段,能耗反而高于不省电。重试也是同理:没有上限和退避的链路,会把本该留给定时上报的能量提前花掉。
最后一处最隐蔽,是断电后本地数据怎么处理。缓存按固定容量滚动写入时,写满即覆盖最旧的一条,而覆盖是静默的,没有告警也没有计数。所以「设备在线、心跳正常」和「本轮数据完整」并不是同一个结论:链路恢复只证明通信通了,证明不了断网期间的数据还在。排障要采的证据也就那么几样——重启次数与时刻、各状态持续时间、储能电压变化、待传积压条数、最旧一条待传记录的年龄。少了最后一项,分不清是新数据在堆积还是旧数据卡住了;少了状态持续时间,也看不出到底卡在采集、发送还是休眠。
方案:可落地的结构与取舍
供电链路要按顺序交代清楚:光伏板补能,经充电管理进入蓄电池,再由变换级供给网关与传感器。每一级都有转换损耗,标称容量也不等于低温下能放出的容量,所以核算时要把损耗和温度边界分开写,不能把电池标称值当成可用能量;补能一侧同样要给两组结论——按平均日照算有多少余量,按最不利时段算还差多少。
工作状态不能只有开与关。至少区分正常采集、批量上传、节能待机、低电保护与恢复五种,每种都要有明确的进入、退出阈值,并留出滞回区间。电压卡在临界点时若没有滞回,设备会在两种状态之间反复切换,唤醒与重连的开销叠起来,能耗反而比不省电更高。
采样与上传应当分开定策略。逐条上报延迟低,但唤醒次数多,每次唤醒的固定开销逐条累加;批量上传把若干次采样合并成一次发送,射频占用集中,代价是对瞬时供电和链路质量的要求更高。常见的折中是按周期批量上传,事件告警独立走优先通道,且这条通道只在供电与网络都允许时才生效,不被当成无条件例外。
重试必须有退避上限和单周期预算:间隔逐次拉长并设最大值,一个周期内允许几次重试、总共能占多少时间也要限定,超了就等下一周期,不提前花掉留给定时上报的能量。
持久化放在最后写,却最容易被略过:数据先落本地再发送,发送成功不等于服务端已经落库,只有收到确认才回收。低电保护期间保留必要采样与诊断,非必要通信降频;缓存写满时的取舍必须可观测,覆盖了哪条、最旧一条积压多久,都要留下记录,否则事后无法解释缺口。
| 状态 | 进入条件 | 允许动作 | 明确禁止 |
|---|---|---|---|
| 正常采集 | 储能高于恢复阈值 | 采集、即时发送 | 长时间占用射频 |
| 批量上传 | 到上报周期且链路可用 | 限时补传历史 | 无上限重连 |
| 节能待机 | 储能持续下降 | 降频采样、仅存本地 | 新增非必要唤醒 |
| 低电保护 | 电压低于保护阈值 | 停通信、保留时钟与关键采样 | 清理未确认缓存 |
| 恢复 | 电压回到滞回上沿 | 先补传、后恢复周期 | 一次性全量重发 |
配套还要一张数据分级表:哪些指标允许降采样、哪些业务记录不允许丢,谁有权改这一栏。
技术实现:字段、接口与数据口径
这一节只解决一件事:把前面定下来的策略,变成别人能照着实现、也能对着复算的口径。顺序是先统一能量,再统一数据。
能量账本只用 Wh。每个状态的功率要实测,乘以该状态的日累计时长再相加,不能拿一个平均功率乘二十四小时。两个常见错法:一是把电池标称 Ah 直接当能量——Ah 乘电压才是 Wh,同样标称容量在不同化学体系下能放出的能量差得很远;二是把不同电压侧的数据混着加——组件输出、电池端、负载端各在自己的电压侧,各段功率必须换算到 Wh 之后再累加。转换效率只在对应那一段扣一次,充电、变换、待机各自扣完再相加,重复扣会把余量算小,漏扣会把余量算大。
符号口径统一成:日负载能量等于各状态功率与时长的乘积之和,功率用毫瓦、时长用小时,结果除以一千得 Wh;补能一侧不给单点值,只按「平均有效辐照」和「最不利连续弱光」各给一个区间。
数据侧定七个字段:设备标识、启动标识、序号、采样时间、接收时间、载荷、确认游标。启动标识是必需的——设备重启后序号通常从零重新计数,只靠设备标识加序号会和重启前的旧记录撞号。采样时间取设备时钟,接收时间取服务端时刻,两者永远分开存;时钟校准前后都要保留原始的采样先后顺序,不能拿接收时间冒充采样时间。
写入流程固定四步:采样后先落本地,再批量发送,服务端持久化成功之后才回确认,设备收到确认才按游标回收。发送成功不等于已经落库,中间任何一步崩掉,这批记录都必须能在下次开机后原样重新出现。
去重靠稳定标识做幂等,服务端按标识 upsert,重复补传只落一条。确认游标只能沿没有缺口的前缀推进:序号出现空洞时游标停在空洞之前,空洞单独记录并上报,不能为了让游标好看就跳过去——跳过的那一段,事后没有人能把缺口解释清楚。
补传要带预算:每批条数上限、每个周期可占的时长或能量上限,以及新数据与历史积压的调度顺序。常见做法是给新数据留保底额度、剩余能量再补给历史,否则积压越堆越多,新数据也跟着延迟。缓存写满时的覆盖必须可观测:覆盖了哪一条、最旧一条待传记录放了多久,都要留下计数与记录,否则缺口无法审计。
下面这段只演示本地去重与连续确认游标的判定,不涉及真实硬件、网络与能耗测量,数值都是构造出来的。
# 本地去重与连续确认游标模拟(不涉及真实硬件、网络与能耗测量)
def record_key(device_id, boot_id, seq):
# 稳定记录标识:设备 + 本次启动 + 序号,重启后不会与旧记录撞号
return f"{device_id}/{boot_id}/{seq}"
# 收到的一批记录:(boot_id, seq, sampled_at)
batch = [
("b1", 1, "12:00:00"),
("b1", 2, "12:05:00"),
("b1", 4, "12:15:00"), # seq=3 在缓存覆盖时丢失
("b2", 5, "12:20:00"), # 重启后 boot_id 变了,seq 继续递增
("b1", 2, "12:05:00"), # 重复补传同一批
]
store = {}
for boot, seq, ts in batch:
store.setdefault(record_key("GW-A", boot, seq), ts) # 幂等:同一标识只落一条
# 连续确认游标:只沿无缺口的前缀推进,缺口之后的记录不能提前回收
cursor, gap = 0, None
while True:
if record_key("GW-A", "b1", cursor + 1) not in store:
gap = cursor + 1
break
cursor += 1
oldest = min(store.values())
print(f"去重后 {len(store)} 条,连续确认游标 {cursor},首个缺口 seq={gap},最旧记录 {oldest}")
# expect: 去重后 4 条,连续确认游标 2,首个缺口 seq=3,最旧记录 12:00:00
这段能跑出结论的地方只有两处:重复的那条没有让库里的条数变多,游标停在缺口之前而不是跟着最新的一条往前跑。真实能量账本与补传收敛要靠在台架和现场量出来的数据回填,代码里给不出来。
项目实践:一次真实落地怎么走
以下是一个假设站点的验证流程,不代表已完成的客户项目,也没有任何可引用的现场测量值。
场景按一类野外采集点设定:单杆安装,采样周期以分钟计,允许的上报延迟以十分钟计,需要覆盖的最长预期断网时段按天计,供电为小型光伏板加蓄电池。动手之前先要把几个输入确认清楚——当地最不利的连续弱光天数期望值、杆位的朝向与遮挡情况、负载清单与各状态的功率预算、允许的最长数据延迟、维护人员多久能到现场一次。这些值没确认之前,任何容量结论都只是占位。
第一步在台架上做,量的是各工作状态的实测功率:正常采集、射频发射峰值、批量上传、节能待机、低电保护各测一段,记下每次唤醒的固定开销与链路重连的额外开销。台架的好处是能反复触发,坏处是它不代表弱信号,所以第二步必须放到现场:设备装在真实杆位上,记录至少一个完整日照周期的补能曲线、弱信号下的重连次数与每次重连的持续时长。
第三步做故障注入,这一步最容易被省掉,也最不能省。测试矩阵至少覆盖六种情形:发送后、确认前的掉电;重启之后的序号接续;重复确认与重复补传;记录乱序到达;缓存正好写满的临界点;低电保护触发与电压回升后的恢复边界。
第四步收口。网络恢复之后,把设备侧已持久化的记录集合与服务端已持久化的记录集合按稳定标识做差集,只看三件事:有没有重复、有没有缺口、缺口的位置和持续时长能不能与注入的故障对上。看到界面重新在线不算验收通过——在线只证明链路通了,证明不了断网期间的数据都还在。
这一轮做完应当留下四样东西:各状态实测功率表、现场补能与弱信号记录、故障注入的逐项结果、仍未解决的风险清单。没测到的项保持「未测」,不要用估算值填进去,否则后面所有容量结论都建立在一个虚构的起点上。
价值总结:判断标准与复用边界
判断一套野外供电方案做没做完,四个判据就够。一是供需假设可追溯:负载是按状态实测累加还是拍的平均值,补能看到底给了哪几个区间、损耗扣在哪一级,每一项都能倒查到出处。二是异常状态可恢复:低电保护、断网、重启之后,设备能自己回到正常节奏,不等人到现场按一下。三是数据缺口可解释:真的少了数据,能回答缺了哪几条、为什么缺、覆盖发生在什么时候。四是维护决策有证据:该换电池、该加板子还是该调周期,结论背后有曲线有计数,不是凭感觉。
对应的交付物也是四样:能量预算表、状态转换表、缓存与确认约定、故障测试记录。凑齐这四样,方案才交得出去;只报一个在线率,说明不了最不利的那几天设备到底怎样。
边界要一并写明。这套思路适合允许一定上报延迟、能接受本地缓存的采集场景;需要秒级响应或持续大流量上传的业务不在此列——休眠与批量的前提在那里直接失效,容量和策略都得重新核算,不能把周期套过来用。
低功耗不是加一块板子就能解决的事。采样节奏、通信策略与供电能力必须一起约束:改其中一项,另外两项的账都要重算。设计的价值不在承诺能撑多少天,而在把假设写清楚、把边界画出来,让后来的人拿实测数据就能验它站不站得住。
