搞了这么多年节能降碳信息化项目,我越来越觉得一个行业怪象很扎心:能源管理系统这个行当,真正烧钱的往往不是硬件设备,而是软件授权和定制开发。一块几万块的智能电表不算贵,但一套能把它用起来的软件平台,动辄十几二十万起,后续每改一个报表、加一个计量点都得单独报价。后来我在 GitHub 上顺手翻到一个叫 MyEMS 的开源能源管理系统,算是把这个困局撕开了一道口子——它几乎覆盖了企业能源管理的全部核心模块,而且代码完全开放。这篇文章就是一次比较完整的使用总结,从功能、部署、二次开发到避坑,把我实际跑过的东西都摊开讲。
MyEMS,全称 Modern Energy Management System,是目前少见的、持续更新且社区活跃的开源能源管理系统。它解决的正是那个老问题:企业想管好电、水、气、热,又不想被商业软件的高价定制绑死。我做过的几个项目,有的从零部署 MyEMS,有的是在它基础上做深度改造,整体印象是:这个系统不是拿来“看个 demo 就算完”的玩具,它是能接手真实生产环境的一整套基础设施。这篇分享适合谁看?想自建能管系统的工厂动力部门、做节能服务的工程公司、还有准备在能源管理方向做二次开发的研发团队,都可以从里面找到能直接抄作业的东西。
1. 为什么我盯上 MyEMS:能源管理系统的高价困局
1.1 传统方案,钱到底花在哪了
先把行业底摊开。传统能源管理系统供应商的报价套路很统一:软件平台按模块授权收钱,数据采集点数按点收费,报表和看板按页面定制收费,最后再加一笔实施服务费。一套中规中矩的能耗在线监测平台,覆盖几十个配电回路、几块水表气表,报价基本不会低于十万元。这还只是“能用”的状态,等你想把尖峰平谷计费、分项能耗、设备效率分析这些高级功能做进去,价格直接再翻一倍。
更难受的是闭源方案的隐藏成本。甲方想换个计量表品牌,供应商说“这个不在我们兼容列表里,要加开发费”;想导一份自定义格式的报表,供应商说“这个功能需要评估,最少两万”。数据权限、界面风格、告警规则,每一处微小调整都可能变成加价理由。我见过不少项目采购时候高高兴兴,验收之后天天跟供应商扯皮,核心就一个原因:系统是黑盒,你改不动,只能求着别人改。
1.2 MyEMS 的技术底子其实很主流
MyEMS 给我的第一印象就是技术栈不猎奇,全是大路货,这恰恰是企业项目最看重的。后端以 Python + Django REST Framework 为主,管理后台是 Angular 技术栈,数据库用 MySQL 或 MariaDB,部署方式是微服务加 Docker,采集层单独拆出来做成了 Modbus、BACnet、M-Bus 等独立服务。
这种选型的好处非常直观。第一,人才好找,会 Python 和 MySQL 的工程师满大街都是,不至于项目交接时找不到懂行的人。第二,语言生态成熟,Django 的项目结构、ORM、权限体系都很规范,二次开发上手快。第三,微服务和数据库分开设计,数据采集、清洗、聚合、API 服务各自独立,任何一个模块挂了不影响其他模块,这在真实生产环境里很重要——采集服务半夜卡死了,至少报表和历史数据还是好的。
我一开始也怀疑它是不是像很多开源项目一样,界面粗糙、文档稀碎。实际部署完用起来,发现它的管理后台包含了完整的空间管理、能源设备管理、计量器具管理、费率配置、告警规则配置这些模块,UI 虽然谈不上惊艳,但胜在功能密度高,该有的入口都有,比不少花大价钱定制的商业系统还要全。
1.3 开源不等于免费,但选它的逻辑是迁移自由
必须说句公道话:选 MyEMS 不等于零成本落地。服务器要钱,数据库要钱,如果采集点数多、需要技术支持的,一样要投入人力。但开源方案和商业方案的本质区别在于:钱花在哪。商业方案里你的钱换回来的是一个不断让你续费的黑盒授权;MyEMS 的钱花在服务器、实施和二次开发上,沉淀下来的是自己团队能掌握的技术资产。
换句话说,用 MyEMS 最爽的一点就是“退路”永远在自己手里。今天需求变了,加一块表、改一种计费方式、接一个新系统,都是自己可以动手解决的事情,不用再等供应商排期,也不用担心供应商跑路。尤其是做节能改造项目的工程公司,用开源底座一次性开发出标准化交付模板之后,每接一个新客户都是边际成本递减,这个商业逻辑比单纯省下一笔授权费重要得多。
2. 核心功能拆解:MyEMS 到底能干哪些活
2.1 数据采集:一通百通的协议网关
能源管理系统最底层也最要命的环节就是数据采集。MyEMS 的采集层,气味特别工程化。它把不同规约拆成了独立服务:Modbus TCP/RTU 服务、BACnet IP/MSTP 服务、M-Bus 服务、还有通用 MQTT 接入通道。这意味着什么呢?意味着常规的电表、水表、气表、冷热量表,基本都能覆盖。项目现场最怕的不是设备杂,而是协议闭源,MyEMS 走的是标准规约,主流表计厂商都会兼容这些协议,碰到位码特殊的奇葩表,至少你还有开放的代码可以去研究协议文档自己适配。
我特别喜欢它把采集和数据处理分开的设计。采集服务负责把现场寄存器的原始值读上来,比如电压、电流、功率、累计电量的整型原始值,然后由清洗和规范化服务去处理单位换算、倍率、字节序、数据有效性校验这些脏活。业内有句话叫“采集容易治理难”,MyEMS 的模块切分方式,让数据治理有了明确的抓手,也很容易在中间加自己的清洗逻辑。
2.2 计量计费:把电费单算得明明白白
能源管理的核心价值就是算明白“花了多少钱”。MyEMS 的计费模块不是简单地在电价表里填个单价,它能配置分时电价,尖峰平谷四段费率独立设置,还能把容量费、需量费、力率调整这些大工业电费里的复杂项目都纳进计算模型。配置界面里还可以按不同建筑、不同区域、不同成本中心设置差异化的费率方案,电费、水费、气费分得清清楚楚。
这一点对于做节能改造的同行来说价值巨大。很多商业软件把“计费”放在高配版本里,基础版只能看看曲线。而 MyEMS 把计费引擎直接开源出来,等于把一个通常要额外花大几万的功能模块,直接放进了基础能力里。我实际用它帮一个工厂做过月度电费核对,把尖峰平谷各时段的电量从系统导出,跟供电公司的电费单逐项对比,误差控制在个位数百分比以内,这已经完全是可用的水平。
2.3 分析看板:从数据到决策
数据光采上来不算完,得让管理层看得懂。MyEMS 的分析模块覆盖了几个高频场景:用能趋势的同比环比、分项用能占比、单位产量能耗、能源消耗对标定额、设备用能效率排名、成本中心用能分析。它带有比较成熟的图表看板和报表中心,不需要你自己写代码就能配置出一套能汇报的驾驶舱。
最让我觉得省心的是它的对标分析功能。你可以给每个车间设定一个单位能耗的定额值,系统自动把实际值和定额值放在同一张图上,超了立刻红色突出。在能源管理这个行当,“超标预警”和“节能潜力量化”是最容易被领导问起的两个问题,MyEMS 的定额对标能直接给出答案,这是很多定制项目里需要反复沟通才能做出来的功能。
2.4 告警与运维:从被动到主动
能源系统最尴尬的时刻是故障发生了还不知道,直到电费暴增或者某条产线跳闸才发现。MyEMS 提供阈值告警和故障检测诊断(FDD)两类能力。阈值告警很简单,设定上下限,超限就发消息;FDD 则高级一些,它基于规则引擎,能根据多个测量点的组合状态判断出“疑似设备故障”或者“不合理的运行状态”,比如冷冻水供水温度正常但回水温度异常、某些设备在非工作时段仍然高耗电这类问题,规则引擎都能捕获。
告警的推送通道也比较实用——微信、邮件、短信这类常规渠道都支持。我在项目里通常会让客户在微信企业号里建个群,把告警机器人拉进去,设备异常的第一时间,运行值班人员的手机就开始震动。这种“被动等待变成主动发现”的转变,救过我好几次,有一次就是因为夜里收到冷却塔异常启停的告警,避免了整个中央空调系统跳机。
2.5 双碳支撑与开放 API
最后说一个现在所有企业都绕不开的部分:碳排放管理。MyEMS 里面嵌入了碳排放的计算模块,可以按电、气、油、热等能源类型设置不同的排放因子,自动汇总出组织层面的碳排放量。虽然每个行业的碳核算标准还在不断演进,但系统把基础台账和计算逻辑摆在这里了,后续做碳盘查、碳信息披露的时候,至少有据可查。
开放 API 这一点,我更想多说两句。MyEMS 的 RESTful API 文档很完整,能源数据、设备数据、报警数据都可以通过 API 往外吐。我做过好几个对接项目:把 MyEMS 的数据推到企业的 MES 系统,把告警接入工单系统,把能耗数据同步到自建的数据中台。能用标准 API 解决的对接,基本不需要动后端代码。这也让它从一个单机系统变成了可以嵌入到企业数字化生态里的数据底座。
3. 从零到一:MyEMS 实际部署与操作实录
3.1 架构与部署清单,先看清楚要跑哪些服务
MyEMS 不是单一的程序,而是一套多服务的分布式架构,这一点新手最容易懵。部署之前先搭一张脑图:API 服务是主干,负责给前端页面提供数据;MySQL 是数据仓库,承载计量历史数据和配置数据;采集服务是触手,分别对接 Modbus、BACnet 等协议设备;整理服务负责把原始数据清洗成标准数据;聚合服务把细粒度数据汇总成小时、天、月级别的统计结果;报表服务按时生成 PDF 或 Excel 报表;消息服务处理告警推送。
刚接触的时候别慌,先用 Docker 或者 K8s 把所有服务编排起来,让它们各自跑在容器里。我目前在用的部署方式是这样一套清单:
- MySQL 8.0,单实例,数据挂载到宿主机制定的目录;
- API 跟前端页面跑在 Nginx 后面,API 走内网端口,前端走 80/443;
- myems-modbus、myems-bacnet 采集容器按现场设备的协议类型灵活扩容;
- 清洗、归一、聚合的容器按 Cron 周期调度执行;
- 报表容器每天凌晨定时跑一次;
- 告警规则引擎独立一两个实例,响应快一些。
这套架构跑在 8 核 16G 的云主机上毫无压力,处理上千个采集点没有问题。数据量不大的起步阶段,完全可以用一台 4 核 8G 的服务器承载全部服务,硬件门槛远没有想象那么高。
3.2 数据库初始化与后端配置
数据库初始化这一步很容易踩坑,因为 MyEMS 拆了很多个 SQL 脚本,每个服务对应一类表。正确做法是先建一个统一 MySQL 实例,然后按文档依次导入基础配置表、历史数据表、计量计费表、采集配置表和用户权限表。导入后马上检查两件事:一是数据库字符集必须统一,建议全部设置成 utf8mb4,否则中文字段会出现乱码;二是时区必须设置为中国时区,否则你看到的曲线高峰可能在半夜。
后端配置重点是 config.py 文件。这个文件里集中了数据库连接串、时区、运行端口、上传文件路径等核心参数,部署时几乎一定会动到。改完配置,记得重启 API 服务,然后用 curl 或者浏览器直接访问一次健康检查接口,确认返回 JSON 而不是 502,这就说明 API 层已经活了。
分享一个我犯过的错:第一次部署时我直接把 MySQL 的 root 密码写进了 config.py,运行是正常,但管理后台和 Web 端全都直连数据库。后来安全审计被卡住,才把所有连接改成专用数据库账号,权限按服务隔离。正确做法是给每个服务建单独账号,只授权它需要的库表权限,虽然前期麻烦一点,但后面安全审计会舒服很多。
3.3 前端部署与反向代理,做出能见人的界面
后端通了,再做前端。MyEMS 的 Web 管理后台和用户端页面都是 Angular 构建的静态资源,不需要单独跑一个后端进程,它们只需要 Nginx 托管静态文件,然后把 /api 路径反向代理到 API 服务即可。
有一个细节很多人第一次会忽略:Angular 应用默认使用 HTML5 history 路由模式,如果 Nginx 没做 try_files 配置,你刷新页面就会 404。必须把不存在文件路径的请求统一 rewrite 到 index.html。这个错误太典型了,我排查过两次,都是同一原因。正确 Nginx 配置长这样:
location / { try_files $uri $uri/ /index.html; } location /api { proxy_pass http://127.0.0.1:8000; proxy_set_header Host $host; proxy_set_header X-Real-IP $remote_addr; proxy_set_header X-Forwarded-For $proxy_add_x_forwarded_for; }另外强烈建议生产环境直接上 HTTPS。能源数据虽然不是高精尖机密,但涉及企业产线运行状态和电费成本,如果明文暴露在公网上,怎么想都不安心。提前把证书配置好,给 Nginx 加上 80->443 跳转,是成本极低又非常有必要的加固。
3.4 接入一个真实电表:Modbus 采集全流程
我在第一次接触 MyEMS 时,印象最深的还是“把一个真实电表的数据接进系统”这套流程。这里以一块提供 Modbus TCP 协议的智能电表为例,逐步拆开看。
第一步,在协议文档里查清电表参数:IP 地址、端口,默认通常是 502,还有寄存器地址表。以我常用的某国产品牌电表为例,累计有功电能的寄存器地址是 0x0000,数据类型是 32 位无符号整数,倍率是 1,单位是 kWh。这些信息必须从表计说明书里找,千万别凭经验用通用地址表盲试。
第二步,在 MyEMS 管理后台里创建一个数据源。选择 Modbus TCP 协议,填上电表 IP 和端口,选择一个 Modbus 从站地址(Slave ID)。这一步有个很容易踩的坑:很多电表默认从站地址是 1,但如果现场总线里已经有其他设备占用了 1 号地址,继续用 1 可能读不到数据。最好一开始就把每个从站的地址规划清楚,写进现场台账归档。
第三步,创建计量点。含义就是“我要读电表的哪个寄存器”。地址填 0,功能码选择“读保持寄存器(03)”,数据类型选择 32 位无符号,字节序选择“大端”,缩放系数填 1。对于累计电量,通常直接读原始值就行,但有些电表的高位和低位是分开存储的,这种需要把两个寄存器的值拼起来用,MyEMS 的采集配置里也有对应的组合方式。
第四步,把计量点绑到具体的能耗分类和设备上。在 MyEMS 的模型里,一个计量点必须先挂到一个能源计量表,再把表挂到空间节点下,最后指定它计量的是电还是水。如果不做这一步绑定,数据采集上来了也不会进入能耗分析报表。我见过不少同事卡在这里,采集日志里数据点明明有值,报表却是空的,原因就是漏了绑定环节。
做完这四步,启动 Modbus 采集容器,观察日志。第一次接入顺利读到了七八个点,说实话那一刻感觉挺解气的——几万块钱的定制系统的入门门槛,在这里只需要一个开源项目加一块几百块钱的电表。
3.5 二次开发和自定义报表的思路
如果用了一段时间,觉得默认页面不够用,MyEMS 的开放性就体现出来了。它前面是一个标准 RESTful API,后面是 MySQL 数据库,你做定制其实就是在“改前端 + 写后端”。
自定义报表我总结了三个路径,按成本从低到高排序。第一个路径是在管理后台自带的报表模块里配,适合做常规的日周月报表,把 Excel 模板配置好,系统定时推送。第二个路径是写一个独立的后端服务,直接从 MySQL 查聚合数据,生成自己的报表页面,适合做有特殊统计口径的报表。第三个路径是改前端代码,如果想做完全贴合企业内部风格的可视化大屏,就在 MyEMS Web 工程里新增页面,复用它的 API 认证和数据模型。
我最推荐的是第二种:既不动 MyEMS 核心代码,又能深度定制。因为能源管理系统改动频率最高的就是统计逻辑、分组维度、报表格式,而数据库表结构相对稳定。直接在外部写一个微服务,定时读 MyEMS 的聚合表,再写入自己的业务表,升级成本最低,未来 MyEMS 官方版本升级时也不至于冲突。
4. 常见问题与排查技巧实录
4.1 装了服务但收不到数据,先别急着怀疑软件
这是最最常见的现场问题。我的排查顺序永远是:链路、配置、软件三层排查。先确认电表所在网段和服务器能互通,用命令行直接 ping 电表 IP,再确认 502 端口有没有被防火墙挡掉。真实项目里,很多“采集不到”就是交换机 VLAN 没放通导致的。
链路通了还不来数据,就看采集日志。以 Modbus 服务为例,打开日志文件能看到每一次请求和超时记录。超时一般是对端 IP 不通或端口不对;返回异常码 02 是非法数据地址,说明你寄存器地址、功能码或数据类型填错了;异常码 03 是非法数据值,说明功能码不能用于该寄存器。这些错误码虽然看起来麻烦,其实比“静默失败”好得多,至少给了排查方向。等把字节序、缩放系数都看一遍,大概率能解决。我的经验是通信层占七成,配置占三成,真遇到代码 bug 的概率反而低。
4.2 API 或管理后台打不开
这个问题多数集中在启动阶段。API 起不来,先看日志里的 Python 异常栈,最常见是数据库连接不上。这时候第一步是进 MySQL 手动执行一条 select 1,确认库还活着;第二步检查 config.py 里的连接串端口、库名、账号密码有没有写错;第三步确认 MySQL 的 bind-address 是不是只监听了 127.0.0.1,如果 API 容器在另一个网络里,需要放开监听地址。
管理后台页面能打开但接口报 401,十有八九是 token 认证的问题。检查浏览器时间和服务器时间是否同步,JWT 对时间偏差非常敏感,时间差几分钟就会直接判定 token 失效。我在内网环境踩过这个坑,因为服务器 CMOS 电池没电了,时间和真实时间差了半个多小时,排查了整整一下午,最后同步了时间就一切正常。
4.3 报表数据不对或者更新慢
报表数据不对,优先检查聚合服务有没有跑。MyEMS 的报表不是一个实时查询,它依赖后台的聚合任务把小时级、天级数据提前算好存起来。如果聚合服务没启动,或者 Cron 表达式配错了,报表就会停留在上一次的数据。第一次部署时这些服务很容易被遗漏,我的建议是把所有定时任务单独列一张表,逐个验证日志里是否按时执行。
更新慢的问题九成在 SQL 效率上。历史数据表的数据量一旦超过百万行,没有索引的查询就会开始变慢。MyEMS 默认的表结构里有索引设计,但如果你的使用方式是绕过 API 直接查库,比如我用这种方式做自定义报表,就要注意查询条件必须带上时间范围,否则 MySQL 可能扫全表。给常用的时间字段和组合条件补上联合索引,查询速度能快一个数量级。
4.4 表数据量增长过快的优化
能源系统的历史数据增长是永不停止的,一台电表一天产生 1440 个分钟级数据,一千台电表一年就是几亿条记录。如果不提前做规划,MySQL 单表撑不住是迟早的事。
我在生产环境里常用的有三招。第一招是合理配置聚合粒度,分钟级原始数据只保留 30 天,之后只保留小时和天级聚合数据,磁盘占用立刻降下来。第二招是物理分区,按月份建分区,旧分区可以直接归档删除,查询新数据也不用扫旧的。第三招是定期清理,写一个存储过程,在月底自动删除超过保留策略的数据。
当然,也可以直接给采集层降低频率,有些非关键计量点没必要 1 分钟采集一次,改成 15 分钟一次,数据量直接减少到原来的一小半,精度完全够用在报告里。这三招配合起来,百万点级别的项目也压得住。
4.5 权限与多租户配置避坑
MyEMS 的权限设计里有菜单权限、数据权限和操作权限三个维度。很多初学者只配了菜单权限,以为用户进不了某个菜单就看不到数据,实际上如果数据权限没配好,用户只要拿到 API 地址,就能直接绕过页面把数据捞走。
我的建议是三层权限一起配。菜单权限决定“看到哪些功能”,数据权限决定“看到哪些空间”,操作权限决定“能不能增删改”。尤其对园区类项目,不同租户或不同部门只允许看自己那栋楼的数据,就一定要在数据权限里绑定到空间节点。我见过一个商业综合体项目,因为数据权限没隔离,A 商户登录后能看到整栋楼的能耗台账,客户差点投诉到质监部门。多花十分钟检查权限树,能省掉绝大部分客诉。
5. 跟高价定制做笔账:成本、风险与决策
5.1 一笔非常现实的成本对比
说了这么多,最后还是要落到“钱”上面。我以一个中等规模的工厂能源管理项目为模板,设定场景是:覆盖 200 个电表、50 个水表气表,需要尖峰平谷计费、能耗看板、告警推送、月报导出,做一次粗略的成本对比。
| 成本项 | 商业定制方案(估算) | MyEMS 方案(估算) |
|---|---|---|
| 软件授权 | 15-30 万元 | 0 元(开源许可证允许内部使用) |
| 服务器与数据库 | 3-5 万元 | 3-5 万元 |
| 现场采集实施 | 8-12 万元 | 8-12 万元 |
| 报表与界面定制 | 5-10 万元 | 部分包含在实施中,多余开发用人力成本替代 |
| 每年维保升级 | 2-5 万元/年 | 自己团队负责,主要成本是人力 |
同样是“能用、稳定、可运维”的交付物,商业方案总投入可能逼近五六十万,而 MyEMS 方案可以把采购成本压缩在十万上下,大头就是服务器和实施。当然,中间的人力投入一定存在,这我前面也说过。
5.2 开源方案的风险,也要做好对冲
不吹不黑,开源方案同样有风险。第一个风险是人才依赖:如果团队里没人懂 Python、MySQL,出问题了会很被动。对冲办法是我方在项目早期就派一两个人全程参与部署,把代码结构和部署文档吃透,从“用系统的人”转变成“系统的主人”。
第二个风险是 GPL 许可证的约束。MyEMS 采用 GNU GPL v3.0,如果你的使用场景是把系统打包后卖给第三方或者作为 SaaS 对外运营,必须仔细评估许可证的义务,必要时咨询法务。我的建议是:如果是企业自建私有化平台,内部使用,这类场景基本没有风险;如果做的是面向客户的系统集成业务,那就不要在未理解许可证的情况下直接闭源分发。
第三个风险是社区支持的不确定性。MyEMS 的社区比不过那些顶级国际项目,遇到冷门 bug 可能要自己啃。应对方式比较笨但有效:尽量不魔改核心代码,把所有定制都放在外部扩展里,这样官方每次更新都能平滑升级。我做过几个项目都秉持这个原则,后面升级基本没有阻碍。
5.3 哪种情况仍然建议商业方案
说了这么多优点,也得承认 MyEMS 不是银弹。如果你的项目属于下面这几类,建议还是认真考虑商业方案:一是对供应商服务响应有硬性合同要求的政企项目,出了问题需要有人背着 SLA 来兜底;二是项目规模大到几千个采集点、几十个并行服务集群,需要专业团队做高可用和性能调优的;三是甲方明确指定必须采购有软件著作权的商业产品,招投标文件里写死了证书要求。
我这里有一个真实教训。帮一个规模很大的园区做项目时,我一味强调开源的节约成本,结果甲方招标部门列出的资质清单里包含了软件著作权登记证书和软件产品检测报告,开源项目给不了,最后中途换成了商业平台。所以选型决策一定要让采购和法律部门提前介入,技术上的“强”不一定等于商务上的“合规”。
最后说点个人感受。我踩过不少开源的坑,也交过不少学费,但 MyEMS 是少数让我产生“这就是能源管理系统的样子”想法的项目。它不一定适合每一个项目,但它让技术团队第一次有了完全掌控能源数据的能力:数据是自己的,代码是自己的,算费逻辑能翻开看,告警规则能自己改——这种感觉,真不是几十万买一套黑盒系统能给的。如果让我重新选一次,我还是会先拿 MyEMS 做底座,再用外部服务扩展客户需要的那层业务,踏实。