Merge remote-tracking branch 'upstream/develop' into develop

pull/34/head
Caozhenhui 2021-04-14 16:13:19 +08:00
commit 4bd67a6bee
14 changed files with 2063 additions and 378 deletions

246
README.md
View File

@ -17,7 +17,11 @@
MyEMS是行业领先的开源能源管理系统利用云计算、物联网、大数据、人工智能等信息化技术构建而成。MyEMS可用于构建统一规范、功能强大的综合能源管理服务平台。MyEMS由资深专业团队开发维护系统代码基于MIT开源软件许可协议发布。
## MyEMS架构
![MyEMS Architecture](/docs/images/architecture.png)
![MyEMS Architecture Function View](/docs/images/architecture-function-view.png)
![MyEMS Architecture Site View](/docs/images/architecture-site-view.png)
## MyEMS组件(社区版)
@ -63,123 +67,129 @@ MyEMS项目由下列组件构成:
[安装 web UI](./web/README.md)
## 功能版本对比
| 功能 |社区版(MyEMS) |企业版(AlbertEOS)|
| :--- | :----: | :----: |
| 开源 | ✔️ | ❌ |
| 定价模式 | 免费 | 按项目付费 |
| 更换品牌名称与标志LOGO | ✔️ | ✔️ |
| Modbus TCP 协议 | ✔️ | ✔️ |
| BACnet/IP 协议 | ✔️ | ✔️ |
| MQTT 协议发布数据 | ✔️ | ✔️ |
| 数据点数 | 无限制 |无限制 |
| 计量表数 | 无限制 |无限制 |
| 设备数 | 无限制 |无限制 |
| 用能单位数 | 无限制 |无限制 |
| Docker容器化部署 | ✔️ | ✔️ |
| Kubernetes部署 | ✔️ | ✔️ |
| MySQL | ✔️ | ✔️ |
| MariaDB | ✔️ | ✔️ |
| SingleStore | ✔️ | ✔️ |
| AWS 云部署 | ✔️ | ✔️ |
| AZure 云部署 | ✔️ | ✔️ |
| 阿里云部署 | ✔️ | ✔️ |
| 私有云部署 | ✔️ | ✔️ |
| 总览页 | ✔️ | ✔️ |
| 数据比较分析(同比、环比、自由比) | ✔️ | ✔️ |
| 数据分析结果导出到Excel | ✔️ | ✔️ |
| 空间数据/能耗分类分析 | ✔️ | ✔️ |
| 空间数据/能耗分项分析 | ✔️ | ✔️ |
| 空间数据/成本分析 | ✔️ | ✔️ |
| 空间数据/产出分析 | ✔️ | ✔️ |
| 空间数据/收入分析 | ✔️ | ✔️ |
| 空间数据/效率分析 | ✔️ | ✔️ |
| 空间数据/负荷分析 | ✔️ | ✔️ |
| 空间数据/统计分析 | ✔️ | ✔️ |
| 空间数据/节能分析 | ❌ | ✔️ |
| 设备数据/能耗分类分析 | ✔️ | ✔️ |
| 设备数据/能耗分项分析 | ✔️ | ✔️ |
| 设备数据/成本分析 | ✔️ | ✔️ |
| 设备数据/产出分析 | ✔️ | ✔️ |
| 设备数据/收入分析 | ✔️ | ✔️ |
| 设备数据/效率分析 | ✔️ | ✔️ |
| 设备数据/负荷分析 | ✔️ | ✔️ |
| 设备数据/统计分析 | ✔️ | ✔️ |
| 设备数据/节能分析 | ❌ | ✔️ |
| 设备数据/设备台账 | ✔️ | ✔️ |
| 计量表数据/能耗分析 | ✔️ | ✔️ |
| 计量表数据/成本分析 | ✔️ | ✔️ |
| 计量表数据/趋势分析 | ✔️ | ✔️ |
| 计量表数据/实时分析 | ✔️ | ✔️ |
| 计量表数据/总分表平衡分析 | ✔️ | ✔️ |
| 计量表数据/离线表能耗分析 | ✔️ | ✔️ |
| 计量表数据/离线表成本分析 | ✔️ | ✔️ |
| 计量表数据/虚拟表能耗分析 | ✔️ | ✔️ |
| 计量表数据/虚拟表成本分析 | ✔️ | ✔️ |
| 计量表数据/计量表台账 | ✔️ | ✔️ |
| 租户数据/能耗分类分析 | ✔️ | ✔️ |
| 租户数据/能耗分项分析 | ✔️ | ✔️ |
| 租户数据/成本分析 | ✔️ | ✔️ |
| 租户数据/负荷分析 | ✔️ | ✔️ |
| 租户数据/统计分析 | ✔️ | ✔️ |
| 租户数据/节能分析 | ❌ | ✔️ |
| 租户数据/租户账单 | ✔️ | ✔️ |
| 门店数据/能耗分类分析 | ✔️ | ✔️ |
| 门店数据/能耗分项分析 | ✔️ | ✔️ |
| 门店数据/成本分析 | ✔️ | ✔️ |
| 门店数据/负荷分析 | ✔️ | ✔️ |
| 门店数据/统计分析 | ✔️ | ✔️ |
| 门店数据/节能分析 | ❌ | ✔️ |
| 车间数据/能耗分类分析 | ✔️ | ✔️ |
| 车间数据/能耗分项分析 | ✔️ | ✔️ |
| 车间数据/成本分析 | ✔️ | ✔️ |
| 车间数据/负荷分析 | ✔️ | ✔️ |
| 车间数据/统计分析 | ✔️ | ✔️ |
| 车间数据/节能分析 | ❌ | ✔️ |
| 组合设备数据/成本分析 | ✔️ | ✔️ |
| 组合设备数据/产出分析 | ✔️ | ✔️ |
| 组合设备数据/收入分析 | ✔️ | ✔️ |
| 组合设备数据/效率分析 | ✔️ | ✔️ |
| 组合设备数据/负荷分析 | ✔️ | ✔️ |
| 组合设备数据/统计分析 | ✔️ | ✔️ |
| 组合设备数据/节能分析 | ❌ | ✔️ |
| 能流图分析 | ✔️ | ✔️ |
| 配电系统分析 | ✔️ | ✔️ |
| REST API | ✔️ | ✔️ |
| Web UI | ✔️ | ✔️ |
| Admin UI | ✔️ | ✔️ |
| MQTT 协议订阅数据 | ❌ | ✔️ |
| Modbus RTU 协议 | ❌ | ✔️ |
| OPC UA 协议 | ❌ | ✔️ |
| OPC DA 协议 | ❌ | ✔️ |
| Siemens S7 协议 | ❌ | ✔️ |
| IEC 104 协议 | ❌ | ✔️ |
| Johnson Controls Metasys | ✔️ | ✔️ |
| Honeywell EBI | ✔️ | ✔️ |
| SIEMENS Desigo CC | ❌ | ✔️ |
| QWeather API | ❌ | ✔️ |
| FDD 能效故障诊断系统 | ❌ | ✔️ |
| 高级报表系统 | ❌ | ✔️ |
| 组态图形绘制工具 | ❌ | ✔️ |
| 设备远程控制 | ❌ | ✔️ |
| BACnet Server | ❌ | ✔️ |
| Modbus TCP Server(Slave) | ❌ | ✔️ |
| OPC UA Server | ❌ | ✔️ |
| iOS APP | ❌ | ✔️ |
| Android APP | ❌ | ✔️ |
| 微信小程序 | ❌ | ✔️ |
| 支付宝小程序 | ❌ | ✔️ |
| 工控机硬件网关(数据采集和远程控制) | ❌ | ✔️ |
| LoRa无线数传电台模块(数据采集和远程控制)| ❌ | ✔️ |
| 重点用能单位能耗在线监测系统上传省级平台通信协议| ❌ | ✔️ |
| 第三方系统集成服务 | ❌ | ✔️ |
| 在线社区技术支持 | ✔️ | ✔️ |
| 邮件技术支持 | ✔️ | ✔️ |
| 电话技术支持服务 | ❌ | ✔️ |
| 微信技术支持服务 | ❌ | ✔️ |
| 远程桌面技术支持服务 | ❌ | ✔️ |
| 现场技术支持服务 | ❌ | ✔️ |
| 投标技术支持服务 | ❌ | ✔️ |
| 二次开发技术支持服务 | ❌ | ✔️ |
| 功能 |社区版 |企业版 | 说明 |
| :--- | :----: | :----: | :----: |
| 开源 | ✔️ | ❌ | |
| 价格 | 免费 | 收费 | 标准组件授权费;定制组件开发费; |
| 更换品牌名称与标志LOGO | ✔️ | ✔️ | |
| Modbus TCP 协议 | ✔️ | ✔️ | 采集数据 |
| BACnet/IP 协议 | ✔️ | ✔️ | 采集数据 |
| MQTT 协议发布 | ✔️ | ✔️ | 发布最新采集到的数据 |
| 数据点数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 计量表数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 空间数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 设备数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 租户数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 门店数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 车间数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 组合设备数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| Docker容器化部署 | ✔️ | ✔️ | |
| Kubernetes部署 | ✔️ | ✔️ | |
| MySQL | ✔️ | ✔️ | |
| MariaDB | ✔️ | ✔️ | |
| SingleStore | ✔️ | ✔️ | |
| AWS 云部署 | ✔️ | ✔️ | |
| AZure 云部署 | ✔️ | ✔️ | |
| 阿里云部署 | ✔️ | ✔️ | |
| 私有云部署 | ✔️ | ✔️ | |
| 总览页 | ✔️ | ✔️ | |
| 数据比较分析 | ✔️ | ✔️ | 同比、环比、自由比、不比 |
| Excel 导出 | ✔️ | ✔️ | 表格、曲线图、柱状图、饼状图 |
| 计量表数据/能耗分析 | ✔️ | ✔️ | |
| 计量表数据/成本分析 | ✔️ | ✔️ | |
| 计量表数据/趋势分析 | ✔️ | ✔️ | |
| 计量表数据/实时分析 | ✔️ | ✔️ | |
| 计量表数据/总分表平衡分析 | ✔️ | ✔️ | |
| 计量表数据/离线表能耗分析 | ✔️ | ✔️ | |
| 计量表数据/离线表成本分析 | ✔️ | ✔️ | |
| 计量表数据/虚拟表能耗分析 | ✔️ | ✔️ | |
| 计量表数据/虚拟表成本分析 | ✔️ | ✔️ | |
| 计量表数据/计量表台账 | ✔️ | ✔️ | |
| 空间数据/能耗分类分析 | ✔️ | ✔️ | |
| 空间数据/能耗分项分析 | ✔️ | ✔️ | |
| 空间数据/成本分析 | ✔️ | ✔️ | |
| 空间数据/产出分析 | ✔️ | ✔️ | |
| 空间数据/收入分析 | ✔️ | ✔️ | |
| 空间数据/效率分析 | ✔️ | ✔️ | |
| 空间数据/负荷分析 | ✔️ | ✔️ | |
| 空间数据/统计分析 | ✔️ | ✔️ | |
| 空间数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 设备数据/能耗分类分析 | ✔️ | ✔️ | |
| 设备数据/能耗分项分析 | ✔️ | ✔️ | |
| 设备数据/成本分析 | ✔️ | ✔️ | |
| 设备数据/产出分析 | ✔️ | ✔️ | |
| 设备数据/收入分析 | ✔️ | ✔️ | |
| 设备数据/效率分析 | ✔️ | ✔️ | |
| 设备数据/负荷分析 | ✔️ | ✔️ | |
| 设备数据/统计分析 | ✔️ | ✔️ | |
| 设备数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 设备数据/设备台账 | ✔️ | ✔️ | |
| 租户数据/能耗分类分析 | ✔️ | ✔️ | |
| 租户数据/能耗分项分析 | ✔️ | ✔️ | |
| 租户数据/成本分析 | ✔️ | ✔️ | |
| 租户数据/负荷分析 | ✔️ | ✔️ | |
| 租户数据/统计分析 | ✔️ | ✔️ | |
| 租户数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 租户数据/租户账单 | ✔️ | ✔️ | |
| 门店数据/能耗分类分析 | ✔️ | ✔️ | |
| 门店数据/能耗分项分析 | ✔️ | ✔️ | |
| 门店数据/成本分析 | ✔️ | ✔️ | |
| 门店数据/负荷分析 | ✔️ | ✔️ | |
| 门店数据/统计分析 | ✔️ | ✔️ | |
| 门店数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 车间数据/能耗分类分析 | ✔️ | ✔️ | |
| 车间数据/能耗分项分析 | ✔️ | ✔️ | |
| 车间数据/成本分析 | ✔️ | ✔️ | |
| 车间数据/负荷分析 | ✔️ | ✔️ | |
| 车间数据/统计分析 | ✔️ | ✔️ | |
| 车间数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 组合设备数据/成本分析 | ✔️ | ✔️ | |
| 组合设备数据/产出分析 | ✔️ | ✔️ | |
| 组合设备数据/收入分析 | ✔️ | ✔️ | |
| 组合设备数据/效率分析 | ✔️ | ✔️ | |
| 组合设备数据/负荷分析 | ✔️ | ✔️ | |
| 组合设备数据/统计分析 | ✔️ | ✔️ | |
| 组合设备数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 能流图分析 | ✔️ | ✔️ | |
| 配电系统分析 | ✔️ | ✔️ | |
| REST API | ✔️ | ✔️ | |
| Web UI | ✔️ | ✔️ | |
| Admin UI | ✔️ | ✔️ | |
| MQTT 协议订阅数据 | ❌ | ✔️ | 需要标准组件许可 |
| Modbus RTU 协议 | ❌ | ✔️ | 需要标准组件许可 |
| OPC UA 协议 | ❌ | ✔️ | 需要标准组件许可 |
| OPC DA 协议 | ❌ | ✔️ | 需要标准组件许可 |
| Siemens S7 协议 | ❌ | ✔️ | 需要标准组件许可 |
| IEC 104 协议 | ❌ | ✔️ | 需要标准组件许可 |
| Johnson Controls Metasys API | ✔️ | ✔️ | 需要标准组件许可 |
| Honeywell EBI | ✔️ | ✔️ | |
| SIEMENS Desigo CC | ❌ | ✔️ | 需要标准组件许可 |
| QWeather API | ❌ | ✔️ | 需要标准组件许可 |
| FDD 能效故障诊断系统 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 高级报表系统 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 组态图形绘制工具 | ❌ | ✔️ | 需要标准组件许可 |
| 设备远程控制 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| BACnet Server | ❌ | ✔️ | 需要标准组件许可 |
| Modbus TCP Server(Slave) | ❌ | ✔️ | 需要标准组件许可 |
| OPC UA Server | ❌ | ✔️ | 需要标准组件许可 |
| iOS APP | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| Android APP | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 微信小程序 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 支付宝小程序 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 工控机硬件网关(数据采集和远程控制) | ❌ | ✔️ | MyEMS认证工控机硬件 |
| LoRa无线数传电台模块(数据采集和远程控制)| ❌ | ✔️ | MyEMS认证LoRa硬件设备 |
| 重点用能单位能耗在线监测系统上传省级平台通信协议| ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 第三方系统集成服务 | ❌ | ✔️ | 定制开发 |
| 线上软件使用培训 | ✔️ | ✔️ | 免费 |
| 线下软件使用培训 | ❌ | ✔️ | |
| 在线社区技术支持 | ✔️ | ✔️ | 免费 |
| 邮件技术支持 | ✔️ | ✔️ | 免费 |
| 电话技术支持服务 | ❌ | ✔️ | |
| 微信技术支持服务 | ❌ | ✔️ | |
| 远程桌面技术支持服务 | ❌ | ✔️ | |
| 投标技术支持服务 | ❌ | ✔️ | |
| 二次开发技术支持服务 | ❌ | ✔️ | |
| 现场技术支持服务 | ❌ | ✔️ | |
## MyEMS截图
![MyEMS Space EnergyCategory1](/docs/images/myems-space-energycategory1.gif)

View File

@ -17,7 +17,11 @@ MyEMS ist ein branchenführendes Open-Source-Energiemanagementsystem, das auf Cl
MyEMS wird von einem erfahrenen Entwicklungsteam entwickelt und gewartet, und der Quellcode des Systems wird unter MIT-Lizenz veröffentlicht.
## MyEMS Architektur
![MyEMS Architecture](/docs/images/architecture.png)
![MyEMS Architecture Function View](/docs/images/architecture-function-view.png)
![MyEMS Architecture Site View](/docs/images/architecture-site-view.png)
## MyEMS Komponenten (GCommunity Edition)
@ -66,125 +70,131 @@ Dieses Projekt besteht aus folgenden Komponenten:
## Editionen vergleichen
| Eigenschaften |Community Edition (MyEMS) |Enterprise Edition (AlbertEOS)|
| :--- | :----: | :----: |
| Open Source | ✔️ | ❌ |
| Pricing | Free | Pay for Projects |
| Change Name and Logo | ✔️ | ✔️ |
| Modbus TCP | ✔️ | ✔️ |
| BACnet/IP | ✔️ | ✔️ |
| MQTT Publisher | ✔️ | ✔️ |
| Data Points Number | Unlimited |Unlimited |
| Meters Number | Unlimited |Unlimited |
| Equipments Number | Unlimited |Unlimited |
| Spaces Number | Unlimited |Unlimited |
| Docker | ✔️ | ✔️ |
| Kubernetes | ✔️ | ✔️ |
| MySQL | ✔️ | ✔️ |
| MariaDB | ✔️ | ✔️ |
| SingleStore | ✔️ | ✔️ |
| AWS Cloud | ✔️ | ✔️ |
| AZure Cloud | ✔️ | ✔️ |
| Alibaba Cloud | ✔️ | ✔️ |
| Private Cloud | ✔️ | ✔️ |
| Data ComparisonYear-on-Year、Month-on-Month、Any-on-Any | ✔️ | ✔️ |
| Export result to Excel | ✔️ | ✔️ |
| Space/Energy Category Data | ✔️ | ✔️ |
| Space/Energy Item Data | ✔️ | ✔️ |
| Space/Cost Data | ✔️ | ✔️ |
| Space/Output Data | ✔️ | ✔️ |
| Space/Income Data | ✔️ | ✔️ |
| Space/Efficiency Data | ✔️ | ✔️ |
| Space/Load Data | ✔️ | ✔️ |
| Space/Statistics | ✔️ | ✔️ |
| Space/Saving Data | ❌ | ✔️ |
| Equipment/Energy Category Data | ✔️ | ✔️ |
| Equipment/Energy Item Data | ✔️ | ✔️ |
| Equipment/Cost Data | ✔️ | ✔️ |
| Equipment/Output Data | ✔️ | ✔️ |
| Equipment/Income Data | ✔️ | ✔️ |
| Equipment/Efficiency Data | ✔️ | ✔️ |
| Equipment/Load Data | ✔️ | ✔️ |
| Equipment/Statistics | ✔️ | ✔️ |
| Equipment/Saving Data | ❌ | ✔️ |
| Equipment/Equipment Tracking | ✔️ | ✔️ |
| Meter/Energy Data | ✔️ | ✔️ |
| Meter/Cost Data | ✔️ | ✔️ |
| Meter/Trend Data | ✔️ | ✔️ |
| Meter/Realtime Data | ✔️ | ✔️ |
| Meter/Master Meter Submeters Balance | ✔️ | ✔️ |
| Meter/Offline Meter Energy Data | ✔️ | ✔️ |
| Meter/Offline Meter Cost Data | ✔️ | ✔️ |
| Meter/Virtual Meter Energy Data | ✔️ | ✔️ |
| Meter/Virtual Meter Cost Data | ✔️ | ✔️ |
| Meter/Meter Tracking | ✔️ | ✔️ |
| Tenant/Energy Category Data | ✔️ | ✔️ |
| Tenant/Energy Item Data | ✔️ | ✔️ |
| Tenant/Cost Data | ✔️ | ✔️ |
| Tenant/Load Data | ✔️ | ✔️ |
| Tenant/Statistics | ✔️ | ✔️ |
| Tenant/Saving Data | ❌ | ✔️ |
| Tenant/Tenant Bill | ✔️ | ✔️ |
| Store/Energy Category Data | ✔️ | ✔️ |
| Store/Energy Item Data | ✔️ | ✔️ |
| Store/Cost Data | ✔️ | ✔️ |
| Store/Load Data | ✔️ | ✔️ |
| Store/Statistics | ✔️ | ✔️ |
| Store/Saving Data | ❌ | ✔️ |
| Shopfloor/Energy Category Data | ✔️ | ✔️ |
| Shopfloor/Energy Item Data | ✔️ | ✔️ |
| Shopfloor/Cost Data | ✔️ | ✔️ |
| Shopfloor/Load Data | ✔️ | ✔️ |
| Shopfloor/Statistics | ✔️ | ✔️ |
| Shopfloor/Saving Data | ❌ | ✔️ |
| Combined Equipment/Energy Category Data | ✔️ | ✔️ |
| Combined Equipment/Energy Item Data | ✔️ | ✔️ |
| Combined Equipment/Cost Data | ✔️ | ✔️ |
| Combined Equipment/Output Data | ✔️ | ✔️ |
| Combined Equipment/Income Data | ✔️ | ✔️ |
| Combined Equipment/Efficiency Data | ✔️ | ✔️ |
| Combined Equipment/Load Data | ✔️ | ✔️ |
| Combined Equipment/Statistics | ✔️ | ✔️ |
| Combined Equipment/Saving Data | ❌ | ✔️ |
| Energy Dashboard | ✔️ | ✔️ |
| Energy Flow Diagram | ✔️ | ✔️ |
| Distribution System | ✔️ | ✔️ |
| REST API | ✔️ | ✔️ |
| Web UI | ✔️ | ✔️ |
| Admin UI | ✔️ | ✔️ |
| MQTT Subscriber | ❌ | ✔️ |
| Modbus RTU | ❌ | ✔️ |
| OPC UA | ❌ | ✔️ |
| OPC DA | ❌ | ✔️ |
| Siemens S7 | ❌ | ✔️ |
| IEC 104 | ❌ | ✔️ |
| Johnson Controls Metasys | ✔️ | ✔️ |
| Honeywell EBI | ✔️ | ✔️ |
| SIEMENS Desigo CC | ❌ | ✔️ |
| QWeather API | ❌ | ✔️ |
| FDD Rule Engine | ❌ | ✔️ |
| Advanced Reporting Engine | ❌ | ✔️ |
| Graphics Drawing Tool | ❌ | ✔️ |
| Equipments Remote Control | ❌ | ✔️ |
| BACnet Server | ❌ | ✔️ |
| Modbus TCP Server(Slave) | ❌ | ✔️ |
| OPC UA Server | ❌ | ✔️ |
| iOS APP | ❌ | ✔️ |
| Android APP | ❌ | ✔️ |
| WeChat Mini Program | ❌ | ✔️ |
| Alipay Mini Program | ❌ | ✔️ |
| IPC Hardware Gateway (Data Acquisition and Remote Control| ❌ | ✔️ |
| LoRa Radio Module (Data Acquisition and Remote Control| ❌ | ✔️ |
| Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit| ❌ | ✔️ |
| 3rd Party Systems Integration Service | ❌ | ✔️ |
| Online Community Customer Support| ✔️ | ✔️ |
| Email Customer Support | ✔️ | ✔️ |
| Telephone Customer Support | ❌ | ✔️ |
| WeChat Customer Support | ❌ | ✔️ |
| Remote Desktop Customer Support | ❌ | ✔️ |
| Onsite Customer Support | ❌ | ✔️ |
| Bidding Support Service | ❌ | ✔️ |
| Customize Support Service | ❌ | ✔️ |
| Eigenschaften | Gemeinschaftsausgabe | Enterprise Edition | Erläuterung |
| :--- | :----: | :----: | :----: |
| Open Source | ✔️ | ❌ | |
| Pricing | Free | Pay for Projects | |
| Change Name and Logo | ✔️ | ✔️ | |
| Modbus TCP | ✔️ | ✔️ | |
| BACnet/IP | ✔️ | ✔️ | |
| MQTT Publisher | ✔️ | ✔️ | |
| Data Points Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Meters Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Spaces Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Equipments Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Tenants Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Stores Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Shopfloors Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Combined Equipments Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Docker | ✔️ | ✔️ | |
| Kubernetes | ✔️ | ✔️ | |
| MySQL | ✔️ | ✔️ | |
| MariaDB | ✔️ | ✔️ | |
| SingleStore | ✔️ | ✔️ | |
| AWS Cloud | ✔️ | ✔️ | |
| AZure Cloud | ✔️ | ✔️ | |
| Alibaba Cloud | ✔️ | ✔️ | |
| Private Cloud | ✔️ | ✔️ | |
| Data Comparison | ✔️ | ✔️ | Jahr für Jahr, Monat für Monat, Freier Vergleich, Kein Vergleich |
| Excel Exporter | ✔️ | ✔️ | Tabellen, Liniendiagramme, Säulendiagramme, Kreisdiagramme |
| Meter/Energy Data | ✔️ | ✔️ | |
| Meter/Cost Data | ✔️ | ✔️ | |
| Meter/Trend Data | ✔️ | ✔️ | |
| Meter/Realtime Data | ✔️ | ✔️ | |
| Meter/Master Meter Submeters Balance | ✔️ | ✔️ | |
| Meter/Offline Meter Energy Data | ✔️ | ✔️ | |
| Meter/Offline Meter Cost Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Energy Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Cost Data | ✔️ | ✔️ | |
| Meter/Meter Tracking | ✔️ | ✔️ | |
| Space/Energy Category Data | ✔️ | ✔️ | |
| Space/Energy Item Data | ✔️ | ✔️ | |
| Space/Cost Data | ✔️ | ✔️ | |
| Space/Output Data | ✔️ | ✔️ | |
| Space/Income Data | ✔️ | ✔️ | |
| Space/Efficiency Data | ✔️ | ✔️ | |
| Space/Load Data | ✔️ | ✔️ | |
| Space/Statistics | ✔️ | ✔️ | |
| Space/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Equipment/Energy Category Data | ✔️ | ✔️ | |
| Equipment/Energy Item Data | ✔️ | ✔️ | |
| Equipment/Cost Data | ✔️ | ✔️ | |
| Equipment/Output Data | ✔️ | ✔️ | |
| Equipment/Income Data | ✔️ | ✔️ | |
| Equipment/Efficiency Data | ✔️ | ✔️ | |
| Equipment/Load Data | ✔️ | ✔️ | |
| Equipment/Statistics | ✔️ | ✔️ | |
| Equipment/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Equipment/Equipment Tracking | ✔️ | ✔️ | |
| Tenant/Energy Category Data | ✔️ | ✔️ | |
| Tenant/Energy Item Data | ✔️ | ✔️ | |
| Tenant/Cost Data | ✔️ | ✔️ | |
| Tenant/Load Data | ✔️ | ✔️ | |
| Tenant/Statistics | ✔️ | ✔️ | |
| Tenant/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Tenant/Tenant Bill | ✔️ | ✔️ | |
| Store/Energy Category Data | ✔️ | ✔️ | |
| Store/Energy Item Data | ✔️ | ✔️ | |
| Store/Cost Data | ✔️ | ✔️ | |
| Store/Load Data | ✔️ | ✔️ | |
| Store/Statistics | ✔️ | ✔️ | |
| Store/Saving Data | ❌ | ✔️ | |
| Shopfloor/Energy Category Data | ✔️ | ✔️ | |
| Shopfloor/Energy Item Data | ✔️ | ✔️ | |
| Shopfloor/Cost Data | ✔️ | ✔️ | |
| Shopfloor/Load Data | ✔️ | ✔️ | |
| Shopfloor/Statistics | ✔️ | ✔️ | |
| Shopfloor/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Combined Equipment/Energy Category Data | ✔️ | ✔️ | |
| Combined Equipment/Energy Item Data | ✔️ | ✔️ | |
| Combined Equipment/Cost Data | ✔️ | ✔️ | |
| Combined Equipment/Output Data | ✔️ | ✔️ | |
| Combined Equipment/Income Data | ✔️ | ✔️ | |
| Combined Equipment/Efficiency Data | ✔️ | ✔️ | |
| Combined Equipment/Load Data | ✔️ | ✔️ | |
| Combined Equipment/Statistics | ✔️ | ✔️ | |
| Combined Equipment/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Energy Dashboard | ✔️ | ✔️ | |
| Energy Flow Diagram | ✔️ | ✔️ | |
| Distribution System | ✔️ | ✔️ | |
| REST API | ✔️ | ✔️ | |
| Web UI | ✔️ | ✔️ | |
| Admin UI | ✔️ | ✔️ | |
| MQTT Subscriber | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Modbus RTU | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| OPC UA | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| OPC DA | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Siemens S7 | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| IEC 104 | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Johnson Controls Metasys API | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Honeywell EBI | ✔️ | ✔️ | |
| SIEMENS Desigo CC | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| QWeather API | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| FDD Rule Engine | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Advanced Reporting Engine | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| Graphics Drawing Tool | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Equipments Remote Control | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| BACnet Server | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Modbus TCP Server(Slave) | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| OPC UA Server | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| iOS APP | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| Android APP | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| WeChat Mini Program | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| Alipay Mini Program | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| IPC Hardware Gateway (Data Acquisition and Remote Control| ❌| ✔️ | MyEMS-zertifizierte industrielle Computerhardware |
| LoRa Radio Module (Data Acquisition and Remote Control | ❌| ✔️ | MyEMS-zertifiziertes LoRa-Hardwaregerät |
| Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit | ❌ | ✔️ | |
| 3rd Party Systems Integration Service | ❌ | ✔️ | Kundenspezifische Entwicklung |
| Online software training | ✔️ | ✔️ | Kostenlos |
| Face to face software training | ❌ | ✔️ | |
| Online Community Customer Support| ✔️ | ✔️ | Kostenlos |
| Email Customer Support | ✔️ | ✔️ | Kostenlos |
| Telephone Customer Support | ❌ | ✔️ | |
| WeChat Customer Support | ❌ | ✔️ | |
| Remote Desktop Customer Support | ❌ | ✔️ | |
| Onsite Customer Support | ❌ | ✔️ | |
| Bidding Support Service | ❌ | ✔️ | |
| Customize Support Service | ❌ | ✔️ | |
## MyEMS Bildschirmfoto

View File

@ -17,7 +17,11 @@
MyEMS is being developed and maintained by an experienced development team, and the system's source code is published under MIT license.
## MyEMS Architecture
![MyEMS Architecture](/docs/images/architecture.png)
![MyEMS Architecture Function View](/docs/images/architecture-function-view.png)
![MyEMS Architecture Site View](/docs/images/architecture-site-view.png)
## MyEMS Components (Community Edition)
@ -66,125 +70,131 @@ This project is compose of following components:
## Compare Editions
| Features |Communit Edition (MyEMS) |Enterprise Edition (AlbertEOS)|
| :--- | :----: | :----: |
| Open Source | ✔️ | ❌ |
| Pricing | Free | Pay for Projects |
| Change Name and Logo | ✔️ | ✔️ |
| Modbus TCP | ✔️ | ✔️ |
| BACnet/IP | ✔️ | ✔️ |
| MQTT Publisher | ✔️ | ✔️ |
| Data Points Number | Unlimited |Unlimited |
| Meters Number | Unlimited |Unlimited |
| Equipments Number | Unlimited |Unlimited |
| Spaces Number | Unlimited |Unlimited |
| Docker | ✔️ | ✔️ |
| Kubernetes | ✔️ | ✔️ |
| MySQL | ✔️ | ✔️ |
| MariaDB | ✔️ | ✔️ |
| SingleStore | ✔️ | ✔️ |
| AWS Cloud | ✔️ | ✔️ |
| AZure Cloud | ✔️ | ✔️ |
| Alibaba Cloud | ✔️ | ✔️ |
| Private Cloud | ✔️ | ✔️ |
| Data ComparisonYear-on-Year、Month-on-Month、Any-on-Any| ✔️ | ✔️ |
| Export result to Excel | ✔️ | ✔️ |
| Space/Energy Category Data | ✔️ | ✔️ |
| Space/Energy Item Data | ✔️ | ✔️ |
| Space/Cost Data | ✔️ | ✔️ |
| Space/Output Data | ✔️ | ✔️ |
| Space/Income Data | ✔️ | ✔️ |
| Space/Efficiency Data | ✔️ | ✔️ |
| Space/Load Data | ✔️ | ✔️ |
| Space/Statistics | ✔️ | ✔️ |
| Space/Saving Data | ❌ | ✔️ |
| Equipment/Energy Category Data | ✔️ | ✔️ |
| Equipment/Energy Item Data | ✔️ | ✔️ |
| Equipment/Cost Data | ✔️ | ✔️ |
| Equipment/Output Data | ✔️ | ✔️ |
| Equipment/Income Data | ✔️ | ✔️ |
| Equipment/Efficiency Data | ✔️ | ✔️ |
| Equipment/Load Data | ✔️ | ✔️ |
| Equipment/Statistics | ✔️ | ✔️ |
| Equipment/Saving Data | ❌ | ✔️ |
| Equipment/Equipment Tracking | ✔️ | ✔️ |
| Meter/Energy Data | ✔️ | ✔️ |
| Meter/Cost Data | ✔️ | ✔️ |
| Meter/Trend Data | ✔️ | ✔️ |
| Meter/Realtime Data | ✔️ | ✔️ |
| Meter/Master Meter Submeters Balance | ✔️ | ✔️ |
| Meter/Offline Meter Energy Data | ✔️ | ✔️ |
| Meter/Offline Meter Cost Data | ✔️ | ✔️ |
| Meter/Virtual Meter Energy Data | ✔️ | ✔️ |
| Meter/Virtual Meter Cost Data | ✔️ | ✔️ |
| Meter/Meter Tracking | ✔️ | ✔️ |
| Tenant/Energy Category Data | ✔️ | ✔️ |
| Tenant/Energy Item Data | ✔️ | ✔️ |
| Tenant/Cost Data | ✔️ | ✔️ |
| Tenant/Load Data | ✔️ | ✔️ |
| Tenant/Statistics | ✔️ | ✔️ |
| Tenant/Saving Data | ❌ | ✔️ |
| Tenant/Tenant Bill | ✔️ | ✔️ |
| Store/Energy Category Data | ✔️ | ✔️ |
| Store/Energy Item Data | ✔️ | ✔️ |
| Store/Cost Data | ✔️ | ✔️ |
| Store/Load Data | ✔️ | ✔️ |
| Store/Statistics | ✔️ | ✔️ |
| Store/Saving Data | ❌ | ✔️ |
| Shopfloor/Energy Category Data | ✔️ | ✔️ |
| Shopfloor/Energy Item Data | ✔️ | ✔️ |
| Shopfloor/Cost Data | ✔️ | ✔️ |
| Shopfloor/Load Data | ✔️ | ✔️ |
| Shopfloor/Statistics | ✔️ | ✔️ |
| Shopfloor/Saving Data | ❌ | ✔️ |
| Combined Equipment/Energy Category Data | ✔️ | ✔️ |
| Combined Equipment/Energy Item Data | ✔️ | ✔️ |
| Combined Equipment/Cost Data | ✔️ | ✔️ |
| Combined Equipment/Output Data | ✔️ | ✔️ |
| Combined Equipment/Income Data | ✔️ | ✔️ |
| Combined Equipment/Efficiency Data | ✔️ | ✔️ |
| Combined Equipment/Load Data | ✔️ | ✔️ |
| Combined Equipment/Statistics | ✔️ | ✔️ |
| Combined Equipment/Saving Data | ❌ | ✔️ |
| Energy Dashboard | ✔️ | ✔️ |
| Energy Flow Diagram | ✔️ | ✔️ |
| Distribution System | ✔️ | ✔️ |
| REST API | ✔️ | ✔️ |
| Web UI | ✔️ | ✔️ |
| Admin UI | ✔️ | ✔️ |
| MQTT Subscriber | ❌ | ✔️ |
| Modbus RTU | ❌ | ✔️ |
| OPC UA | ❌ | ✔️ |
| OPC DA | ❌ | ✔️ |
| Siemens S7 | ❌ | ✔️ |
| IEC 104 | ❌ | ✔️ |
| Johnson Controls Metasys | ✔️ | ✔️ |
| Honeywell EBI | ✔️ | ✔️ |
| SIEMENS Desigo CC | ❌ | ✔️ |
| QWeather API | ❌ | ✔️ |
| FDD Rule Engine | ❌ | ✔️ |
| Advanced Reporting Engine | ❌ | ✔️ |
| Graphics Drawing Tool | ❌ | ✔️ |
| Equipments Remote Control | ❌ | ✔️ |
| BACnet Server | ❌ | ✔️ |
| Modbus TCP Server(Slave) | ❌ | ✔️ |
| OPC UA Server | ❌ | ✔️ |
| iOS APP | ❌ | ✔️ |
| Android APP | ❌ | ✔️ |
| WeChat Mini Program | ❌ | ✔️ |
| Alipay Mini Program | ❌ | ✔️ |
| IPC Hardware Gateway (Data Acquisition and Remote Control| ❌ | ✔️ |
| LoRa Radio Module (Data Acquisition and Remote Control| ❌ | ✔️ |
| Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit| ❌ | ✔️ |
| 3rd Party Systems Integration Service | ❌ | ✔️ |
| Online Community Customer Support| ✔️ | ✔️ |
| Email Customer Support | ✔️ | ✔️ |
| Telephone Customer Support | ❌ | ✔️ |
| WeChat Customer Support | ❌ | ✔️ |
| Remote Desktop Customer Support | ❌ | ✔️ |
| Onsite Customer Support | ❌ | ✔️ |
| Bidding Support Service | ❌ | ✔️ |
| Customize Support Service | ❌ | ✔️ |
| Features | Community Edition | Enterprise Edition | Explanation |
| :--- | :----: | :----: | :----: |
| Open Source | ✔️ | ❌ | |
| Pricing | Free | Pay for Projects | |
| Change Name and Logo | ✔️ | ✔️ | |
| Modbus TCP | ✔️ | ✔️ | |
| BACnet/IP | ✔️ | ✔️ | |
| MQTT Publisher | ✔️ | ✔️ | |
| Data Points Number | Unlimited | Unlimited | Limited only by hardware performance |
| Meters Number | Unlimited | Unlimited | Limited only by hardware performance |
| Spaces Number | Unlimited | Unlimited | Limited only by hardware performance |
| Equipments Number | Unlimited | Unlimited | Limited only by hardware performance |
| Tenants Number | Unlimited | Unlimited | Limited only by hardware performance |
| Stores Number | Unlimited | Unlimited | Limited only by hardware performance |
| Shopfloors Number | Unlimited | Unlimited | Limited only by hardware performance |
| Combined Equipments Number | Unlimited | Unlimited | Limited only by hardware performance |
| Docker | ✔️ | ✔️ | |
| Kubernetes | ✔️ | ✔️ | |
| MySQL | ✔️ | ✔️ | |
| MariaDB | ✔️ | ✔️ | |
| SingleStore | ✔️ | ✔️ | |
| AWS Cloud | ✔️ | ✔️ | |
| AZure Cloud | ✔️ | ✔️ | |
| Alibaba Cloud | ✔️ | ✔️ | |
| Private Cloud | ✔️ | ✔️ | |
| Data Comparison | ✔️ | ✔️ | Year-on-Year, Month-on-Month, Free Comparison, None Comparison |
| Excel Exporter | ✔️ | ✔️ | Tables, Line Charts, Column Charts, Pie Charts |
| Meter/Energy Data | ✔️ | ✔️ | |
| Meter/Cost Data | ✔️ | ✔️ | |
| Meter/Trend Data | ✔️ | ✔️ | |
| Meter/Realtime Data | ✔️ | ✔️ | |
| Meter/Master Meter Submeters Balance | ✔️ | ✔️ | |
| Meter/Offline Meter Energy Data | ✔️ | ✔️ | |
| Meter/Offline Meter Cost Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Energy Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Cost Data | ✔️ | ✔️ | |
| Meter/Meter Tracking | ✔️ | ✔️ | |
| Space/Energy Category Data | ✔️ | ✔️ | |
| Space/Energy Item Data | ✔️ | ✔️ | |
| Space/Cost Data | ✔️ | ✔️ | |
| Space/Output Data | ✔️ | ✔️ | |
| Space/Income Data | ✔️ | ✔️ | |
| Space/Efficiency Data | ✔️ | ✔️ | |
| Space/Load Data | ✔️ | ✔️ | |
| Space/Statistics | ✔️ | ✔️ | |
| Space/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Equipment/Energy Category Data | ✔️ | ✔️ | |
| Equipment/Energy Item Data | ✔️ | ✔️ | |
| Equipment/Cost Data | ✔️ | ✔️ | |
| Equipment/Output Data | ✔️ | ✔️ | |
| Equipment/Income Data | ✔️ | ✔️ | |
| Equipment/Efficiency Data | ✔️ | ✔️ | |
| Equipment/Load Data | ✔️ | ✔️ | |
| Equipment/Statistics | ✔️ | ✔️ | |
| Equipment/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Equipment/Equipment Tracking | ✔️ | ✔️ | |
| Tenant/Energy Category Data | ✔️ | ✔️ | |
| Tenant/Energy Item Data | ✔️ | ✔️ | |
| Tenant/Cost Data | ✔️ | ✔️ | |
| Tenant/Load Data | ✔️ | ✔️ | |
| Tenant/Statistics | ✔️ | ✔️ | |
| Tenant/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Tenant/Tenant Bill | ✔️ | ✔️ | |
| Store/Energy Category Data | ✔️ | ✔️ | |
| Store/Energy Item Data | ✔️ | ✔️ | |
| Store/Cost Data | ✔️ | ✔️ | |
| Store/Load Data | ✔️ | ✔️ | |
| Store/Statistics | ✔️ | ✔️ | |
| Store/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Shopfloor/Energy Category Data | ✔️ | ✔️ | |
| Shopfloor/Energy Item Data | ✔️ | ✔️ | |
| Shopfloor/Cost Data | ✔️ | ✔️ | |
| Shopfloor/Load Data | ✔️ | ✔️ | |
| Shopfloor/Statistics | ✔️ | ✔️ | |
| Shopfloor/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Combined Equipment/Energy Category Data | ✔️ | ✔️ | |
| Combined Equipment/Energy Item Data | ✔️ | ✔️ | |
| Combined Equipment/Cost Data | ✔️ | ✔️ | |
| Combined Equipment/Output Data | ✔️ | ✔️ | |
| Combined Equipment/Income Data | ✔️ | ✔️ | |
| Combined Equipment/Efficiency Data | ✔️ | ✔️ | |
| Combined Equipment/Load Data | ✔️ | ✔️ | |
| Combined Equipment/Statistics | ✔️ | ✔️ | |
| Combined Equipment/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Energy Dashboard | ✔️ | ✔️ | |
| Energy Flow Diagram | ✔️ | ✔️ | |
| Distribution System | ✔️ | ✔️ | |
| REST API | ✔️ | ✔️ | |
| Web UI | ✔️ | ✔️ | |
| Admin UI | ✔️ | ✔️ | |
| MQTT Subscriber | ❌ | ✔️ | Requires standard component license |
| Modbus RTU | ❌ | ✔️ | Requires standard component license |
| OPC UA | ❌ | ✔️ | Requires standard component license |
| OPC DA | ❌ | ✔️ | Requires standard component license |
| Siemens S7 | ❌ | ✔️ | Requires standard component license |
| IEC 104 | ❌ | ✔️ | Requires standard component license |
| Johnson Controls Metasys API | ❌ | ✔️ | Requires standard component license |
| Honeywell EBI | ✔️ | ✔️ | |
| SIEMENS Desigo CC | ❌ | ✔️ | Requires standard component license |
| QWeather API | ❌ | ✔️ | Requires standard component license |
| FDD Rule Engine | ❌ | ✔️ | Requires standard component license or custom development |
| Advanced Reporting Engine | ❌ | ✔️ | Requires standard component license or custom development |
| Graphics Drawing Tool | ❌ | ✔️ | |
| Equipments Remote Control | ❌ | ✔️ | Requires standard component license or custom development |
| BACnet Server | ❌ | ✔️ | |
| Modbus TCP Server(Slave) | ❌ | ✔️ | |
| OPC UA Server | ❌ | ✔️ | |
| iOS APP | ❌ | ✔️ | Requires standard component license or custom development |
| Android APP | ❌ | ✔️ | Requires standard component license or custom development |
| WeChat Mini Program | ❌ | ✔️ | Requires standard component license or custom development |
| Alipay Mini Program | ❌ | ✔️ | Requires standard component license or custom development |
| IPC Hardware Gateway (Data Acquisition and Remote Control| ❌ | ✔️ | MyEMS certified industrial computer hardware |
| LoRa Radio Module (Data Acquisition and Remote Control| ❌ | ✔️ | MyEMS certified LoRa hardware device |
| Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit | ❌ | ✔️ | Requires standard component license or custom development |
| 3rd Party Systems Integration Service | ❌ | ✔️ | Custom development |
| Online software training | ✔️ | ✔️ | Free |
| Face to face software training | ❌ | ✔️ | |
| Online Community Customer Support| ✔️ | ✔️ | Free |
| Email Customer Support | ✔️ | ✔️ | Free |
| Telephone Customer Support | ❌ | ✔️ | |
| WeChat Customer Support | ❌ | ✔️ | |
| Remote Desktop Customer Support | ❌ | ✔️ | |
| Onsite Customer Support | ❌ | ✔️ | |
| Bidding Support Service | ❌ | ✔️ | |
| Customize Support Service | ❌ | ✔️ | |
## MyEMS Screenshot
![MyEMS Space EnergyCategory1](/docs/images/myems-space-energycategory1.gif)

View File

@ -1,3 +1,4 @@
Architecture
==============
.. image:: images/architecture.png
.. image:: images/architecture-site-view.png
.. image:: images/architecture-function-view.png

Binary file not shown.

After

Width:  |  Height:  |  Size: 41 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 111 KiB

View File

@ -11,6 +11,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -417,8 +418,9 @@ def generate_excel(report,
times = reporting_period_data['timestamps']
has_detail_data_flag = True
ca_len = len(report['reporting_period']['names'])
table_row = (current_row_number + 1) + ca_len * 6
current_end_row_number = (current_row_number + 1) + ca_len * 6 + len(times[0]) + 3
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
table_row = (current_row_number + 1) + ca_len * 6 + real_timestamps_len * 7
current_end_row_number = (current_row_number + 1) + ca_len * 6 + len(times[0]) + 3 + real_timestamps_len * 7
if "timestamps" not in reporting_period_data.keys() or \
reporting_period_data['timestamps'] is None or \
len(reporting_period_data['timestamps']) == 0:
@ -491,6 +493,7 @@ def generate_excel(report,
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(current_row_number + 1 + 6 * i)
table_start_draw_flag = current_row_number
ws.add_chart(line, chart_cell)
row = str(max_row + 1)
@ -645,7 +648,188 @@ def generate_excel(report,
current_row_number += 5
current_row_number += 1
##########################################
current_sheet_parameters_row_number = table_start_draw_flag + ca_len * 6 + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
@ -658,3 +842,28 @@ def reporting_period_values_every_day_sum(reporting_period_data, every_day_index
every_day_sum += reporting_period_data['values'][i][every_day_index]
return every_day_sum
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -11,6 +11,8 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
# PROCEDURES
@ -512,11 +514,11 @@ def generate_excel(report,
reporting_period_data = report['reporting_period']
times = reporting_period_data['timestamps']
ca_len = len(report['reporting_period']['names'])
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
ws['B' + str(current_row_number)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据'
table_start_row_number = (current_row_number + 1) + ca_len * 6
table_start_row_number = (current_row_number + 2) + ca_len * 6 + real_timestamps_len * 7
current_row_number = table_start_row_number
time = times[0]
@ -691,8 +693,214 @@ def generate_excel(report,
if ca_len % 2 == 1:
current_row_number += 5
current_row_number += 1
##########################################
current_sheet_parameters_row_number = table_start_draw_flag + ca_len * 6 + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -11,6 +11,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -337,7 +338,7 @@ def generate_excel(report,
if has_values_data and has_timestamps_data:
ca_len = len(reporting_period_data['names'])
time = reporting_period_data['timestamps'][0]
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
ws['B' + str(current_row_number)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据'
@ -345,7 +346,7 @@ def generate_excel(report,
chart_start_row_number = current_row_number
current_row_number += ca_len * 6
current_row_number += ca_len * 6 + real_timestamps_len * 7 + 1
table_start_row_number = current_row_number
ws.row_dimensions[current_row_number].height = 60
@ -539,7 +540,188 @@ def generate_excel(report,
current_row_number += 5
current_row_number += 1
##########################################
current_sheet_parameters_row_number = chart_start_row_number + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
@ -553,3 +735,28 @@ def group_by_category(category_list):
category_dict[value] = list()
category_dict[value].append(i)
return category_dict
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -12,6 +12,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -344,7 +345,8 @@ def generate_excel(report,
times = reporting_period_data['timestamps']
has_detail_data_flag = True
ca_len = len(report['reporting_period']['names'])
table_row = (current_row_number + 1) + ca_len * 6
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
table_row = (current_row_number + 1) + ca_len * 6 + real_timestamps_len * 7
current_end_row_number = current_row_number
if "timestamps" not in reporting_period_data.keys() or \
reporting_period_data['timestamps'] is None or \
@ -420,6 +422,7 @@ def generate_excel(report,
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(current_row_number + 1 + 6 * i)
table_start_draw_flag = current_row_number
ws.add_chart(line, chart_cell)
row = str(max_row + 1)
@ -480,7 +483,7 @@ def generate_excel(report,
if has_child_flag:
child = report['child_space']
current_row_number = int(row) + 1
ws['B' + str(current_row_number)].font = title_font
ws['B' + str(current_row_number)] = name + ' 子空间数据'
@ -578,7 +581,187 @@ def generate_excel(report,
current_row_number += 1
#############################################
current_sheet_parameters_row_number = table_start_draw_flag + ca_len * 6 + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
@ -591,3 +774,28 @@ def reporting_period_values_every_day_sum(reporting_period_data, every_day_index
every_day_sum += reporting_period_data['values'][i][every_day_index]
return every_day_sum
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -11,6 +11,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -369,13 +370,13 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
ca_len = len(category)
times = reporting_period_data['timestamps']
time = times[0]
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
ws['B' + str(current_row_number)].font = title_font
ws['B' + str(current_row_number)] = name + '详细数据'
current_row_number += 1
chart_start_number = current_row_number
current_row_number += real_timestamps_len * 7 + 1
if has_sub_averages_data_flag:
current_row_number = (current_row_number + ca_len * 6)
@ -487,9 +488,214 @@ def generate_excel(report, name, reporting_start_datetime_local, reporting_end_d
line.dLbls.showVal = True
ws.add_chart(line, "B" + str(current_chart_row_number))
current_chart_row_number += 6
current_chart_col_number += 1
##########################################
current_sheet_parameters_row_number = current_chart_row_number + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -11,6 +11,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -276,7 +277,7 @@ def generate_excel(report,
if has_values_data and has_timestamps_data:
ca_len = len(reporting_period_data['names'])
time = reporting_period_data['timestamps'][0]
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
ws['B' + str(current_row_number)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据'
@ -284,7 +285,7 @@ def generate_excel(report,
chart_start_row_number = current_row_number
current_row_number += ca_len * 6
current_row_number += ca_len * 6 + real_timestamps_len * 7 + 1
table_start_row_number = current_row_number
ws.row_dimensions[current_row_number].height = 60
@ -475,11 +476,214 @@ def generate_excel(report,
current_row_number += 5
current_row_number += 1
##########################################
current_sheet_parameters_row_number = chart_start_row_number + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -11,6 +11,7 @@ from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -478,7 +479,7 @@ def generate_excel(report,
if has_values_saving_data and has_timestamps_data:
ca_len = len(reporting_period_data['names'])
time = reporting_period_data['timestamps'][0]
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
ws['B' + str(current_row_number)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据'
@ -486,7 +487,7 @@ def generate_excel(report,
chart_start_row_number = current_row_number
current_row_number += ca_len * 6
current_row_number += ca_len * 6 + real_timestamps_len * 7 + 1
table_start_row_number = current_row_number
ws.row_dimensions[current_row_number].height = 60
@ -683,7 +684,188 @@ def generate_excel(report,
current_row_number += 5
current_row_number += 1
##########################################
current_sheet_parameters_row_number = chart_start_row_number + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
@ -698,3 +880,27 @@ def sum_list(lists):
return total
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number

View File

@ -9,6 +9,7 @@ from openpyxl.chart.label import DataLabelList
from openpyxl.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image
from openpyxl import Workbook
import openpyxl.utils.cell as format_cell
####################################################################################################################
@ -175,8 +176,6 @@ def generate_excel(report,
if has_energy_data_flag:
ws['B6'].font = title_font
ws['B6'] = name + ' 统计分析'
# ws['D6'].font = title_font
# ws['D6'] = '面积' +report['space']['area']
category = reporting_period_data['names']
@ -441,11 +440,12 @@ def generate_excel(report,
names = reporting_period_data['names']
ca_len = len(names)
time_len = len(timestamps)
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
# title
line_charts_row_number = 6 * ca_len
line_charts_row_number = 6 * ca_len + real_timestamps_len * 7
analysis_end_row_number = 12 + 3 * ca_len
detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1
ws['B' + str(detailed_start_row_number)].font = title_font
ws['B' + str(detailed_start_row_number)] = name + ' 详细数据'
# table_title
@ -525,8 +525,214 @@ def generate_excel(report,
ser.marker.symbol = "diamond"
ser.marker.size = 5
ws.add_chart(line, 'B' + str(analysis_end_row_number + 6 * i))
##########################################
current_sheet_parameters_row_number = analysis_end_row_number + ca_len * 6 + 1
has_parameters_names_and_timestamps_and_values_data = True
if 'parameters' not in report.keys() or \
report['parameters'] is None or \
'names' not in report['parameters'].keys() or \
report['parameters']['names'] is None or \
len(report['parameters']['names']) == 0 or \
'timestamps' not in report['parameters'].keys() or \
report['parameters']['timestamps'] is None or \
len(report['parameters']['timestamps']) == 0 or \
'values' not in report['parameters'].keys() or \
report['parameters']['values'] is None or \
len(report['parameters']['values']) == 0 or \
timestamps_data_all_equal_0(report['parameters']['timestamps']):
has_parameters_names_and_timestamps_and_values_data = False
if has_parameters_names_and_timestamps_and_values_data:
###############################
# new worksheet
###############################
parameters_data = report['parameters']
parameters_names_len = len(parameters_data['names'])
parameters_ws = wb.create_sheet('相关参数')
parameters_timestamps_data_max_len = \
get_parameters_timestamps_lists_max_len(list(parameters_data['timestamps']))
# Row height
parameters_ws.row_dimensions[1].height = 102
for i in range(2, 7 + 1):
parameters_ws.row_dimensions[i].height = 42
for i in range(8, parameters_timestamps_data_max_len + 10):
parameters_ws.row_dimensions[i].height = 60
# Col width
parameters_ws.column_dimensions['A'].width = 1.5
parameters_ws.column_dimensions['B'].width = 25.0
for i in range(3, 12 + parameters_names_len * 3):
parameters_ws.column_dimensions[format_cell.get_column_letter(i)].width = 15.0
# Img
img = Image("excelexporters/myems.png")
img.width = img.width * 0.85
img.height = img.height * 0.85
# img = Image("myems.png")
parameters_ws.add_image(img, 'B1')
# Title
parameters_ws.row_dimensions[3].height = 60
parameters_ws['B3'].font = name_font
parameters_ws['B3'].alignment = b_r_alignment
parameters_ws['B3'] = 'Name:'
parameters_ws['C3'].border = b_border
parameters_ws['C3'].alignment = b_c_alignment
parameters_ws['C3'].font = name_font
parameters_ws['C3'] = name
parameters_ws['D3'].font = name_font
parameters_ws['D3'].alignment = b_r_alignment
parameters_ws['D3'] = 'Period:'
parameters_ws['E3'].border = b_border
parameters_ws['E3'].alignment = b_c_alignment
parameters_ws['E3'].font = name_font
parameters_ws['E3'] = period_type
parameters_ws['F3'].font = name_font
parameters_ws['F3'].alignment = b_r_alignment
parameters_ws['F3'] = 'Date:'
parameters_ws['G3'].border = b_border
parameters_ws['G3'].alignment = b_c_alignment
parameters_ws['G3'].font = name_font
parameters_ws['G3'] = reporting_start_datetime_local + "__" + reporting_end_datetime_local
parameters_ws.merge_cells("G3:H3")
parameters_ws_current_row_number = 6
parameters_ws['B' + str(parameters_ws_current_row_number)].font = title_font
parameters_ws['B' + str(parameters_ws_current_row_number)] = name + ' 相关参数'
parameters_ws_current_row_number += 1
parameters_table_start_row_number = parameters_ws_current_row_number
parameters_ws.row_dimensions[parameters_ws_current_row_number].height = 80
parameters_ws_current_row_number += 1
table_current_col_number = 'B'
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[table_current_col_number + str(parameters_ws_current_row_number - 1)].border = f_border
col = chr(ord(table_current_col_number) + 1)
parameters_ws[col + str(parameters_ws_current_row_number - 1)].fill = table_fill
parameters_ws[col + str(parameters_ws_current_row_number - 1)].border = f_border
parameters_ws[col + str(parameters_ws_current_row_number - 1)].font = name_font
parameters_ws[col + str(parameters_ws_current_row_number - 1)].alignment = c_c_alignment
parameters_ws[col + str(parameters_ws_current_row_number - 1)] = parameters_data['names'][i]
table_current_row_number = parameters_ws_current_row_number
for j, value in enumerate(list(parameters_data['timestamps'][i])):
col = table_current_col_number
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = value
col = chr(ord(col) + 1)
parameters_ws[col + str(table_current_row_number)].border = f_border
parameters_ws[col + str(table_current_row_number)].font = title_font
parameters_ws[col + str(table_current_row_number)].alignment = c_c_alignment
parameters_ws[col + str(table_current_row_number)] = round(parameters_data['values'][i][j], 2)
table_current_row_number += 1
table_current_col_number = chr(ord(table_current_col_number) + 3)
########################################################
# parameters chart and parameters table
########################################################
ws['B' + str(current_sheet_parameters_row_number)].font = title_font
ws['B' + str(current_sheet_parameters_row_number)] = name + ' 相关参数'
current_sheet_parameters_row_number += 1
chart_start_row_number = current_sheet_parameters_row_number
col_index = 0
for i in range(0, parameters_names_len):
if len(parameters_data['timestamps'][i]) == 0:
continue
line = LineChart()
data_col = 3 + col_index * 3
labels_col = 2 + col_index * 3
col_index += 1
line.title = '相关参数 - ' + \
parameters_ws.cell(row=parameters_table_start_row_number, column=data_col).value
labels = Reference(parameters_ws, min_col=labels_col, min_row=parameters_table_start_row_number + 1,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line_data = Reference(parameters_ws, min_col=data_col, min_row=parameters_table_start_row_number,
max_row=(len(parameters_data['timestamps'][i]) + parameters_table_start_row_number))
line.add_data(line_data, titles_from_data=True)
line.set_categories(labels)
line_data = line.series[0]
line_data.marker.symbol = "circle"
line_data.smooth = True
line.x_axis.crosses = 'min'
line.height = 8.25
line.width = 24
line.dLbls = DataLabelList()
line.dLbls.dLblPos = 't'
line.dLbls.showVal = False
line.dLbls.showPercent = False
chart_col = 'B'
chart_cell = chart_col + str(chart_start_row_number)
chart_start_row_number += 6
ws.add_chart(line, chart_cell)
current_sheet_parameters_row_number = chart_start_row_number
current_sheet_parameters_row_number += 1
##########################################
filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename)
return filename
def timestamps_data_all_equal_0(lists):
for i, value in enumerate(list(lists)):
if len(value) > 0:
return False
return True
def get_parameters_timestamps_lists_max_len(parameters_timestamps_lists):
max_len = 0
for i, value in enumerate(list(parameters_timestamps_lists)):
if len(value) > max_len:
max_len = len(value)
return max_len
def timestamps_data_not_equal_0(lists):
number = 0
for i, value in enumerate(list(lists)):
if len(value) > 0:
number += 1
return number