MoreRSS

site iconSunZhongWei | 孙仲维 修改

博客名「大象笔记」,全干程序员一名,曾在金山,DNSPod,腾讯云,常驻烟台。
请复制 RSS 到你的阅读器,或快速订阅到 :

Inoreader Feedly Follow Feedbin Local Reader

SunZhongWei | 孙仲维 的 RSS 预览

MES 物料流转时间报表及超时预警

2026-05-14 10:22:32

依旧是内部 MES 系统的二次开发,这次要添加的是一个 MES 物料流转时间报表及超时预警功能。

即,两个站点之间的流转时间统计分析。客户对工艺流程的两个指定站点的流转时间有要求。需要拉报表出来。支持导出 Excel。这个不是一个简单的报表,而是包含了设置管理功能,例如,指定某个产品的某两个站点之间的流转时间不能超过多少小时。其次才是不同设置规则对应的统计表格功能。

预警消息

可以考虑用企业微信机器人消息的方式进行预警。
同时,在 MES 系统里也可以有一个预警消息的展示界面,显示所有当前处于预警状态的批次信息,方便生产人员查看和跟进处理。

群消息推送功能参考:
https://open.work.weixin.qq.com/help2/pc/14931

已添加的 Webhook 地址示例:
https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx

推送企业微信消息的功能,最好封装成函数,同时增加一个无需登录就能调用的测试 API,方便判断推送功能是否正常。

短期内推送过多企业微信消息,会触发企业微信接口的报错:{“errcode”:45009,“errmsg”:“api freq out of limit, hint: [xxx], from ip: xxx, more info at https://open.work.weixin.qq.com/devtool/query?e=45009”} 需要规避。

收集预警信息与发送微信预警消息逻辑分离

一个长假期回来,岂不是所有的批次都会报预警?如果有消息收敛机制,就不需要考虑这个问题了。
前提是,需要把收集预警信息与发送微信预警消息逻辑分离,做成两个独立的定时任务。如果不分离,就不方便做推送消息汇总。

  • 收集预警信息定时任务,每小时执行一次
  • 发送企业微信预警消息,每 15 分钟执行一次。未来也方便支持其他的功能的预警消息

消息收敛机制,新建一个定时任务,判断预警历史中没有处理的预警记录。每次生成一条企业微信推送消息汇总,将所有未处理的预警记录的批次号和预警类型进行汇总,生成一条企业微信消息进行推送。处理完成后,把对应的预警历史状态标记为推送成功。

数据库分离

由于是二次开发,而且拿不到原 MES 的代码,所以原 Oracle 的数据库我只开了一个只读的账号,不进行任何的写入和修改操作。新功能的数据都是放到新建的 MySQL 数据库中。这样,预警规则,及预警历史记录都存储到 MySQL 数据库中;流转时间报表则是通过同时查询 Oracle 和 MySQL 实现。

GPT 5.4 很强

实现这个功能大部分时间是在梳理需求,和调整交互体验。用 GPT 5.4 实现的第一版近乎完美,只是有一些逻辑上的缺陷。但是,参考王建硕大佬视频里的说法,未来将不是软件 bug,而是需求梳理的问题,就是没有跟 AI 交代清楚细节,导致 AI 没有完全理解你的需求和意图。确实是这样。

但是,要把一个需求事无巨细的交代清楚,也是一件需要耐心的事情,或者是能积累好日常的规范,不至于重复的细节还需要再说明一遍。例如:

  • 使用 golang sync/atomic 规避上一个计划任务没执行完,又开始执行下一个
  • 消息推送要考虑频率过高,造成的消息打扰,及三方推送接口频率限制
  • 生成的代码需要加注释,及单元测试
  • 界面需要考虑小屏幕笔记本的使用体验

不过以后 github copilot 换成 AI credit 计费之后,怕是不能这样奢侈地使用 GPT 5.4 了,何况是提掏腰包买会员。

一些感想

不知不觉这个总耗时不超过 3 周的 MES 系统,从完全不了解 300 多张数据表功能,到已经二次开发上线了 10 多项功能。我感觉已经很效率了。但是从日志看,每天的使用者也就是两个相关人员。

虽然交互上我觉得很满意了,但是因为用的人少,我又收获不到什么成就感。加之,开发这样的内部系统总归会被算作是成本,费力不讨好。领导毕竟都是冷血的动物(听闻嵌入式开发同事被生产部门推到其他部门,因为成本 hold 不住),这无可厚非,得多考虑能形成营收的功能,而不是满足于忙碌的状态。

内网 ubuntu 24.04 dial tcp: lookup qyapi.weixin.qq.com on 127.0.0.53:53: server misbehaving

2026-05-14 09:07:12

在公司内网部署了一套 ubuntu 24.04 Desktop 作为一个内部 MES 小服务器。但是在 golang 服务中调用企业微信机器人消息接口时报错:

Post “https://qyapi.weixin.qq.com/cgi-bin/webhook/send?key=xxx”: dial tcp: lookup qyapi.weixin.qq.com on 127.0.0.53:53: server misbehaving

我印象中,还是第一次遇到这个问题。用了这么多云服务器都是 ubuntu server,以及 windows WSL 里安装的 ubuntu,好像这个错误是第一次见。

本地 DNS 缓存服务

systemctl status systemd-resolved

看来一下,这个服务是正常运行的。

但是,

cat /etc/systemd/resolved.conf

配置文件里 DNS 一行是空的。改成 114.114.114.114 之后,重启服务:

sudo systemctl restart systemd-resolved

然后再次在 golang 接口中测试企业微信消息推送就正常了。

为何 golang 会出现这个问题

我印象中安装这个系统时,应该用过浏览器访问网站是正常的。为何在 golang 中就失败了呢?

使用纯 Go 的 DNS 解析器,它严格遵循 /etc/resolv.conf 中列出的 第一个 nameserver(这里是 127.0.0.53),如果该服务器返回错误(如 server misbehaving)或不响应,Go 解析器不会自动尝试其他 nameserver,直接报错。

我看了一下 /etc/resolv.conf, 确实里面只有一行记录:

nameserver 127.0.0.53

但是,为何修改了 /etc/systemd/resolved.conf 就能解决 golang 的问题呢?

还有第二个问题,如何通过 Linux debug 工具或者 golang 日志来打印出这个完整的 DNS 解析过程呢?这样就能更直观地看到解析过程。

未完待续!

学习王建硕大佬的 SKILL.md

2026-05-12 15:36:32

最近发现大佬王建硕的微信公众号又开始写文章,最近几篇都是关于 AI 的。这篇《SKILL.md 相当于 index.html》非常适合我这种菜鸟,文章链接:

https://mp.weixin.qq.com/s/psu7fLuqdDiiwHZ71I9DGQ

我大概看了一下第二个和第三个项目

  1. 一个是多机位摄像机的,代码在:https://github.com/jianshuo/multicam-skill
  2. 一个是翻译视频的 skill:https://github.com/jianshuo/translate-video
  3. 一个是微信公众号发布助手:https://github.com/jianshuo/jianshuo-wechat-mp-publish

我比较吃惊的是 Mac 上的自动化 shell 脚本还能这样写,大概率也是 AI 写的,确实超出人类的 shell 极限。

看看实际的 skill.md 比去了解科幻的项目要有意义多了。

自动化公众号的风险

我在 github 网页里问 copilot 这样自动化微信公众号文章的发布过程是否会导致封号。

其认为不至于,因为登录授权这些流程并没有自动化,只是把打开网页,复制黏贴部分自动化了。而且也不是单设备多账号的操作。问题不大。也是,之前有点多虑了。

MES Hold 信息报表开发的相关概念,预 Hold、在制 Hold、解 Hold

2026-05-08 14:01:07

这周收到一个半导体产线 MES 系统的二次开发需求,即,增加一个 Hold 信息报表,展示预 Hold、在制 Hold、解 Hold 信息,信息展示包括时间、人、Hold 原因、解 Hold 解释、Hold 状态、类型等。

我大概理解是什么是 Hold 状态,但是这个预 Hold 又是什么呢?我查了一下。

Hold 状态

在 MES(制造执行系统)里,Hold 通常翻译为 “冻结”、“锁定”或“留置”,我们这里叫“在制 Hold”。可以理解为:给一个批次或单个产品贴上“暂停流转”的标签。即,把产品挡在当前工序,阻止其继续生产、检验或发货。核心目的:在不确定产品状态时,防止不良品继续生产、减少损失,并争取决策时间。

举个例子,在我们的系统中,当某个工序站点的良率低于设定的阈值 98% 时,系统会自动生成一条 Event 事件,类型为 Hold,原因类型为 “出站良率低于设定值”。这个时候,这个批次就进入了 Hold 状态,无法继续流转到下一个工序站点,直到这个 Hold 状态被解除。

Hold 的典型应用场景

  • 质量异常:过程参数超差、SPC 报警、QC 抽样发现不良趋势。
  • 设备问题:设备故障可能已影响该批次产品质量。
  • 材料疑虑:怀疑原料用错或有效成分过期。
  • 等待检验:生产完成但检验结果未出(先 Hold 住,合格再放行)。
  • 人为触发的待判定:操作员或主管发现螺丝松动、外观异常等,主动冻结。
  • 系统规则触发:系统自动判断某物料已过期,直接置为 Hold。

预 Hold 状态

即,Pre Hold, 翻译为预冻结 / 预留置。在数据库中的状态字段可能是 Hold_P 之类的缩写。是在正式 Hold 之前的一种过渡性、预警性状态。它的核心作用是:在最终判定质量异常之前,先把物料“软锁定”起来,避免它继续流转,同时等待进一步检验或评审。可以把 Pre-Hold 理解为一种 “软冻结”(Soft Lock),而正式的 Hold 是 “硬冻结”(Hard Lock)。

我疑惑的点是,在我们的 MES 系统中,近 2000 个 Hold 状态,但是只有 2 个 Pre Hold 状态。而且看起来是第一次部署验收系统时的测试数据。感觉是使用人员对 Pre Hold 的概念没有理解正确。上面提到的系统自动将良率低于设定值的批次置为 Hold 状态,从概念上看应该是先置为 Pre Hold 状态,等待人工评审后再置为正式的 Hold 状态。我昨天特意问了一下产线人员,他们说直接设置为 Hold 状态,没有问题。我这里存疑。

这里有个对比表格,非常直观:

MES 系统 Pre Hold 与 Hold 状态的区别

实际应用示例,场景:汽车零部件压铸工序

  • 设备每生产 10 个产品,自动抽检 1 个测量尺寸。
  • 测到某个尺寸接近上公差(99% 规格限)→ MES 自动对该批次(如最近生产的 50 个)打 Pre-Hold。
  • 同时在车间大屏和质检员手机上推送消息:“#2310 批次尺寸偏上限,请复测”。
  • 质检员 10 分钟内复测 5 个产品,数据均合格 → 一键释放 Pre-Hold,批次继续流转。
  • 如果复测发现 2 个超差 → 点击“转为 Hold”,QA 启动不合格品处理流程。
  • 没有 Pre-Hold 的情况:系统直接打正式 Hold → 必须走评审会议、填写处置单,浪费时间。有了 Pre-Hold,大部分虚惊一场的情况可以快速恢复。

解 Hold

即,Release Hold, 放行。QA 或主管对 Hold 批次做评审,有几种处理方式:

  • Release(放行):判定合格,恢复流转。
  • Scrap(报废):判定报废,冻结后转入报废流程。
  • Rework(返工):需进行返工,先生成返工单,再解除 Hold。

对应的批次事件状态,即 Release 状态。

一些奇怪的流转记录

因为要实现这个 Hold 信息报表的前端展示,我担心数据并非跟我想象的一致,即,一条 Hold / Pre Hold 对应一条 Release 记录。如果不是一一对应的关系,我就无法通过 table 的一行来同时展示 Hold 和 Release 的信息了。所以,我特意查询了一下数据库,发现有一些奇怪的流转记录:

  • 某个 lot 批次站点,出现了 3 轮 Hold / Release 的反复记录。即,Hold → Release → Hold → Release → Hold → Release。
  • 另一个 lot 批次站点,出现了 Hold → Hold → Release。看起来是第一条 Hold 是系统自动标记的,然后操作员在解除 Hold 时,误操作又点击了 Hold 按钮,导致又多了一条 Hold 记录。
  • 还有的时两轮 Hold / Release 反复记录
  • 系统 Hold 时,只自动标注了原因类型,例如良率低于设定值,但没有标注事件说明。即,具体不良的原因。而是在 Release 的时候,才在事件说明里标注了具体的原因,例如,来料不良。可以理解为第一次 Hold 为系统自动判断,没有标记原因;而 Release 时是人工评审的结果,所以才标注了具体的原因。

总体看上去,Hold 相关的功能,目前的使用人员还没有一套规范,导致数据看起来很奇怪。估计这也是找我开发这个 Hold 信息报表的原因吧。

枯燥的生活需要多一些夸奖

2026-05-07 10:53:28

昨晚写代码到 22 点,本来想看会网飞讲 Spotify 的神剧《串流先锋 The Playlist》放松一下。突然接到一个客户的新开发需求。客户大哥说他文字表述不清楚,非要跟我视频,然后我就看他在办公室的大屏幕上手写计算公式,然后一点点说明计算逻辑。

突然感觉回到了大学课堂看天书般的数学课板书。不过好在遇到过好几个类似的需求,我大概也能猜出计算逻辑。所以,简单确认几个问题,就互道晚安。但是,大哥说了一句话,让我很暖心:

你是我遇到的技术人员中服务最好的!

我心想这可不是吗,哪个程序员会大晚上 10 点还笑嘻嘻地听客户讲需求。而且属于临时加需求,分文不多收。如果换了其他人早咆哮了吧。我甚至晚上 11 点参加过类似的多方需求讨论会,还帮客户的外包开发团队讲解计算公式。客户感动地要在我所在城市开分公司,让我跟着他干,但是我感觉并不是适合,就回绝了。但是总体感觉上,这些老板挺好相处的。特别是,他们能看到你的付出,也会直接肯定你的价值。

我很喜欢这样的合作。即便不收费,我也愿意去维护这些程序。但是,这些老板通常比较大方,会主动发红包。

而反观公司内部的系统开发,真是一眼难尽,昨天一上午灰头土脸地解决了两个不同项目的 5 个问题。一句感谢都没有。现在还面临被裁员,shit。这些事也不能强求,我尽量做好分内的事情。

不过,生活中多夸夸别人,确实是一个好习惯,得多加练习。

基于 AI 二次开发内部 MES 系统的一些个人经验

2026-04-28 13:09:47

昨天用 GPT 5.4 实现了一个内部 MES 的同类型设备的产出及良率的统计报表功能。因为这个 MES 系统是外购的,二次开发没有源代码的情况下,只能直接读数据库。在 349 张表的情况下,靠人工分析非常浪费时间,所以我找到相关的表之后,把表结构导出为文档,放到了 golang struct 的注释中,然后让 AI 去实现这个统计功能。这个过程中,总结了一些经验技巧:

名词命名规范

没有命名规范,就很难定位具体的表存储。也没法规范 AI 的输出代码规范。包括英文的,也包括中文的。暂时我放到了代码项目文档里面,例如新建一个“命名规范.md”的文件,方便在团队中共享,或者仅仅是个人独立开发给 AI 看的:

命名规范

这里把一些常用的名称规范列出来,方便统一称谓,以及 AI 代码生成时的名称规范。

## 命名列表
- 关于 “MD” 的含义:最常见是 “MD = Master Data”,即“主数据”;也可能有场景把 MD 理解为 “Metadata(元数据)”,但在企业 MES 命名约定中通常指主数据(产品主档)
- 设备:MD_EQUIPMENT,EQUIPMENT 缩写为 EQP
- 良率:Yield,缩写为 YLD
- 批次:Lot,即 LOT
- ...

后续看看怎么放到 instruction 或者 skill 中。一个苏州来的 mes 销售公司来公司推销 mes 时,也特别说明了这一点,做 mes 系统首先要统一命名规范。

一行代码不写是不可能的

例如,一些统计,某些字段可能是空的,由于使用者没有填写,所以不能作为统计依据。而 AI 可能会忽略这些逻辑。而大量表存在冗余字段,也许存在别的表中,这就会导致统计逻辑取错表。

有些字段的原始命名存在歧义,很容易取错字段。修复只需要修改一个变量名单词,而要给 ai 描述清楚,则需要点功夫。就像我很难理解在扣子里添加待办日程,非得跟 ai 聊天,然后响应半分钟才能添加上。那我手动五秒钟不就加上了吗😳

所以,要警惕那些说靠 AI 完全实现开发一个完整项目的言论。毕竟新项目可以这么搞,但是历史项目不现实。

BUG

昨天快速上线了一版预览版本,今天上午就收到了 BUG 反馈。。。我觉得挺好的,总比憋一周才上线要好,半天上线收集反馈再迭代就好。