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可用于构建统一规范、功能强大的综合能源管理服务平台。MyEMS由资深专业团队开发维护系统代码基于MIT开源软件许可协议发布。
## MyEMS架构 ## 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组件(社区版) ## MyEMS组件(社区版)
@ -63,123 +67,129 @@ MyEMS项目由下列组件构成:
[安装 web UI](./web/README.md) [安装 web UI](./web/README.md)
## 功能版本对比 ## 功能版本对比
| 功能 |社区版(MyEMS) |企业版(AlbertEOS)| | 功能 |社区版 |企业版 | 说明 |
| :--- | :----: | :----: | | :--- | :----: | :----: | :----: |
| 开源 | ✔️ | ❌ | | 开源 | ✔️ | ❌ | |
| 定价模式 | 免费 | 按项目付费 | | 价格 | 免费 | 收费 | 标准组件授权费;定制组件开发费; |
| 更换品牌名称与标志LOGO | ✔️ | ✔️ | | 更换品牌名称与标志LOGO | ✔️ | ✔️ | |
| Modbus TCP 协议 | ✔️ | ✔️ | | Modbus TCP 协议 | ✔️ | ✔️ | 采集数据 |
| BACnet/IP 协议 | ✔️ | ✔️ | | BACnet/IP 协议 | ✔️ | ✔️ | 采集数据 |
| MQTT 协议发布数据 | ✔️ | ✔️ | | MQTT 协议发布 | ✔️ | ✔️ | 发布最新采集到的数据 |
| 数据点数 | 无限制 |无限制 | | 数据点数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 计量表数 | 无限制 |无限制 | | 计量表数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 设备数 | 无限制 |无限制 | | 空间数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| 用能单位数 | 无限制 |无限制 | | 设备数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| Docker容器化部署 | ✔️ | ✔️ | | 租户数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| Kubernetes部署 | ✔️ | ✔️ | | 门店数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| MySQL | ✔️ | ✔️ | | 车间数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| MariaDB | ✔️ | ✔️ | | 组合设备数量 | 无限制 |无限制 | 仅受硬件性能限制 |
| SingleStore | ✔️ | ✔️ | | Docker容器化部署 | ✔️ | ✔️ | |
| AWS 云部署 | ✔️ | ✔️ | | Kubernetes部署 | ✔️ | ✔️ | |
| AZure 云部署 | ✔️ | ✔️ | | MySQL | ✔️ | ✔️ | |
| 阿里云部署 | ✔️ | ✔️ | | MariaDB | ✔️ | ✔️ | |
| 私有云部署 | ✔️ | ✔️ | | SingleStore | ✔️ | ✔️ | |
| 总览页 | ✔️ | ✔️ | | AWS 云部署 | ✔️ | ✔️ | |
| 数据比较分析(同比、环比、自由比) | ✔️ | ✔️ | | AZure 云部署 | ✔️ | ✔️ | |
| 数据分析结果导出到Excel | ✔️ | ✔️ | | 阿里云部署 | ✔️ | ✔️ | |
| 空间数据/能耗分类分析 | ✔️ | ✔️ | | 私有云部署 | ✔️ | ✔️ | |
| 空间数据/能耗分项分析 | ✔️ | ✔️ | | 总览页 | ✔️ | ✔️ | |
| 空间数据/成本分析 | ✔️ | ✔️ | | 数据比较分析 | ✔️ | ✔️ | 同比、环比、自由比、不比 |
| 空间数据/产出分析 | ✔️ | ✔️ | | Excel 导出 | ✔️ | ✔️ | 表格、曲线图、柱状图、饼状图 |
| 空间数据/收入分析 | ✔️ | ✔️ | | 计量表数据/能耗分析 | ✔️ | ✔️ | |
| 空间数据/效率分析 | ✔️ | ✔️ | | 计量表数据/成本分析 | ✔️ | ✔️ | |
| 空间数据/负荷分析 | ✔️ | ✔️ | | 计量表数据/趋势分析 | ✔️ | ✔️ | |
| 空间数据/统计分析 | ✔️ | ✔️ | | 计量表数据/实时分析 | ✔️ | ✔️ | |
| 空间数据/节能分析 | ❌ | ✔️ | | 计量表数据/总分表平衡分析 | ✔️ | ✔️ | |
| 设备数据/能耗分类分析 | ✔️ | ✔️ | | 计量表数据/离线表能耗分析 | ✔️ | ✔️ | |
| 设备数据/能耗分项分析 | ✔️ | ✔️ | | 计量表数据/离线表成本分析 | ✔️ | ✔️ | |
| 设备数据/成本分析 | ✔️ | ✔️ | | 计量表数据/虚拟表能耗分析 | ✔️ | ✔️ | |
| 设备数据/产出分析 | ✔️ | ✔️ | | 计量表数据/虚拟表成本分析 | ✔️ | ✔️ | |
| 设备数据/收入分析 | ✔️ | ✔️ | | 计量表数据/计量表台账 | ✔️ | ✔️ | |
| 设备数据/效率分析 | ✔️ | ✔️ | | 空间数据/能耗分类分析 | ✔️ | ✔️ | |
| 设备数据/负荷分析 | ✔️ | ✔️ | | 空间数据/能耗分项分析 | ✔️ | ✔️ | |
| 设备数据/统计分析 | ✔️ | ✔️ | | 空间数据/成本分析 | ✔️ | ✔️ | |
| 设备数据/节能分析 | ❌ | ✔️ | | 空间数据/产出分析 | ✔️ | ✔️ | |
| 设备数据/设备台账 | ✔️ | ✔️ | | 空间数据/收入分析 | ✔️ | ✔️ | |
| 计量表数据/能耗分析 | ✔️ | ✔️ | | 空间数据/效率分析 | ✔️ | ✔️ | |
| 计量表数据/成本分析 | ✔️ | ✔️ | | 空间数据/负荷分析 | ✔️ | ✔️ | |
| 计量表数据/趋势分析 | ✔️ | ✔️ | | 空间数据/统计分析 | ✔️ | ✔️ | |
| 计量表数据/实时分析 | ✔️ | ✔️ | | 空间数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 计量表数据/总分表平衡分析 | ✔️ | ✔️ | | 设备数据/能耗分类分析 | ✔️ | ✔️ | |
| 计量表数据/离线表能耗分析 | ✔️ | ✔️ | | 设备数据/能耗分项分析 | ✔️ | ✔️ | |
| 计量表数据/离线表成本分析 | ✔️ | ✔️ | | 设备数据/成本分析 | ✔️ | ✔️ | |
| 计量表数据/虚拟表能耗分析 | ✔️ | ✔️ | | 设备数据/产出分析 | ✔️ | ✔️ | |
| 计量表数据/虚拟表成本分析 | ✔️ | ✔️ | | 设备数据/收入分析 | ✔️ | ✔️ | |
| 计量表数据/计量表台账 | ✔️ | ✔️ | | 设备数据/效率分析 | ✔️ | ✔️ | |
| 租户数据/能耗分类分析 | ✔️ | ✔️ | | 设备数据/负荷分析 | ✔️ | ✔️ | |
| 租户数据/能耗分项分析 | ✔️ | ✔️ | | 设备数据/统计分析 | ✔️ | ✔️ | |
| 租户数据/成本分析 | ✔️ | ✔️ | | 设备数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 租户数据/负荷分析 | ✔️ | ✔️ | | 设备数据/设备台账 | ✔️ | ✔️ | |
| 租户数据/统计分析 | ✔️ | ✔️ | | 租户数据/能耗分类分析 | ✔️ | ✔️ | |
| 租户数据/节能分析 | ❌ | ✔️ | | 租户数据/能耗分项分析 | ✔️ | ✔️ | |
| 租户数据/租户账单 | ✔️ | ✔️ | | 租户数据/成本分析 | ✔️ | ✔️ | |
| 门店数据/能耗分类分析 | ✔️ | ✔️ | | 租户数据/负荷分析 | ✔️ | ✔️ | |
| 门店数据/能耗分项分析 | ✔️ | ✔️ | | 租户数据/统计分析 | ✔️ | ✔️ | |
| 门店数据/成本分析 | ✔️ | ✔️ | | 租户数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 门店数据/负荷分析 | ✔️ | ✔️ | | 租户数据/租户账单 | ✔️ | ✔️ | |
| 门店数据/统计分析 | ✔️ | ✔️ | | 门店数据/能耗分类分析 | ✔️ | ✔️ | |
| 门店数据/节能分析 | ❌ | ✔️ | | 门店数据/能耗分项分析 | ✔️ | ✔️ | |
| 车间数据/能耗分类分析 | ✔️ | ✔️ | | 门店数据/成本分析 | ✔️ | ✔️ | |
| 车间数据/能耗分项分析 | ✔️ | ✔️ | | 门店数据/负荷分析 | ✔️ | ✔️ | |
| 车间数据/成本分析 | ✔️ | ✔️ | | 门店数据/统计分析 | ✔️ | ✔️ | |
| 车间数据/负荷分析 | ✔️ | ✔️ | | 门店数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 车间数据/统计分析 | ✔️ | ✔️ | | 车间数据/能耗分类分析 | ✔️ | ✔️ | |
| 车间数据/节能分析 | ❌ | ✔️ | | 车间数据/能耗分项分析 | ✔️ | ✔️ | |
| 组合设备数据/成本分析 | ✔️ | ✔️ | | 车间数据/成本分析 | ✔️ | ✔️ | |
| 组合设备数据/产出分析 | ✔️ | ✔️ | | 车间数据/负荷分析 | ✔️ | ✔️ | |
| 组合设备数据/收入分析 | ✔️ | ✔️ | | 车间数据/统计分析 | ✔️ | ✔️ | |
| 组合设备数据/效率分析 | ✔️ | ✔️ | | 车间数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| 组合设备数据/负荷分析 | ✔️ | ✔️ | | 组合设备数据/成本分析 | ✔️ | ✔️ | |
| 组合设备数据/统计分析 | ✔️ | ✔️ | | 组合设备数据/产出分析 | ✔️ | ✔️ | |
| 组合设备数据/节能分析 | ❌ | ✔️ | | 组合设备数据/收入分析 | ✔️ | ✔️ | |
| 能流图分析 | ✔️ | ✔️ | | 组合设备数据/效率分析 | ✔️ | ✔️ | |
| 配电系统分析 | ✔️ | ✔️ | | 组合设备数据/负荷分析 | ✔️ | ✔️ | |
| REST API | ✔️ | ✔️ | | 组合设备数据/统计分析 | ✔️ | ✔️ | |
| Web UI | ✔️ | ✔️ | | 组合设备数据/节能分析 | ❌ | ✔️ | 需要能耗预测组件许可 |
| Admin UI | ✔️ | ✔️ | | 能流图分析 | ✔️ | ✔️ | |
| MQTT 协议订阅数据 | ❌ | ✔️ | | 配电系统分析 | ✔️ | ✔️ | |
| Modbus RTU 协议 | ❌ | ✔️ | | REST API | ✔️ | ✔️ | |
| OPC UA 协议 | ❌ | ✔️ | | Web UI | ✔️ | ✔️ | |
| OPC DA 协议 | ❌ | ✔️ | | Admin UI | ✔️ | ✔️ | |
| Siemens S7 协议 | ❌ | ✔️ | | MQTT 协议订阅数据 | ❌ | ✔️ | 需要标准组件许可 |
| IEC 104 协议 | ❌ | ✔️ | | Modbus RTU 协议 | ❌ | ✔️ | 需要标准组件许可 |
| Johnson Controls Metasys | ✔️ | ✔️ | | OPC UA 协议 | ❌ | ✔️ | 需要标准组件许可 |
| Honeywell EBI | ✔️ | ✔️ | | OPC DA 协议 | ❌ | ✔️ | 需要标准组件许可 |
| SIEMENS Desigo CC | ❌ | ✔️ | | Siemens S7 协议 | ❌ | ✔️ | 需要标准组件许可 |
| QWeather API | ❌ | ✔️ | | IEC 104 协议 | ❌ | ✔️ | 需要标准组件许可 |
| FDD 能效故障诊断系统 | ❌ | ✔️ | | Johnson Controls Metasys API | ✔️ | ✔️ | 需要标准组件许可 |
| 高级报表系统 | ❌ | ✔️ | | Honeywell EBI | ✔️ | ✔️ | |
| 组态图形绘制工具 | ❌ | ✔️ | | SIEMENS Desigo CC | ❌ | ✔️ | 需要标准组件许可 |
| 设备远程控制 | ❌ | ✔️ | | QWeather API | ❌ | ✔️ | 需要标准组件许可 |
| BACnet Server | ❌ | ✔️ | | FDD 能效故障诊断系统 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| Modbus TCP Server(Slave) | ❌ | ✔️ | | 高级报表系统 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| OPC UA Server | ❌ | ✔️ | | 组态图形绘制工具 | ❌ | ✔️ | 需要标准组件许可 |
| iOS APP | ❌ | ✔️ | | 设备远程控制 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| Android APP | ❌ | ✔️ | | BACnet Server | ❌ | ✔️ | 需要标准组件许可 |
| 微信小程序 | ❌ | ✔️ | | Modbus TCP Server(Slave) | ❌ | ✔️ | 需要标准组件许可 |
| 支付宝小程序 | ❌ | ✔️ | | OPC UA Server | ❌ | ✔️ | 需要标准组件许可 |
| 工控机硬件网关(数据采集和远程控制) | ❌ | ✔️ | | iOS APP | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| LoRa无线数传电台模块(数据采集和远程控制)| ❌ | ✔️ | | Android APP | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 重点用能单位能耗在线监测系统上传省级平台通信协议| ❌ | ✔️ | | 微信小程序 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 第三方系统集成服务 | ❌ | ✔️ | | 支付宝小程序 | ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 在线社区技术支持 | ✔️ | ✔️ | | 工控机硬件网关(数据采集和远程控制) | ❌ | ✔️ | MyEMS认证工控机硬件 |
| 邮件技术支持 | ✔️ | ✔️ | | LoRa无线数传电台模块(数据采集和远程控制)| ❌ | ✔️ | MyEMS认证LoRa硬件设备 |
| 电话技术支持服务 | ❌ | ✔️ | | 重点用能单位能耗在线监测系统上传省级平台通信协议| ❌ | ✔️ | 需要标准组件许可或定制开发 |
| 微信技术支持服务 | ❌ | ✔️ | | 第三方系统集成服务 | ❌ | ✔️ | 定制开发 |
| 远程桌面技术支持服务 | ❌ | ✔️ | | 线上软件使用培训 | ✔️ | ✔️ | 免费 |
| 现场技术支持服务 | ❌ | ✔️ | | 线下软件使用培训 | ❌ | ✔️ | |
| 投标技术支持服务 | ❌ | ✔️ | | 在线社区技术支持 | ✔️ | ✔️ | 免费 |
| 二次开发技术支持服务 | ❌ | ✔️ | | 邮件技术支持 | ✔️ | ✔️ | 免费 |
| 电话技术支持服务 | ❌ | ✔️ | |
| 微信技术支持服务 | ❌ | ✔️ | |
| 远程桌面技术支持服务 | ❌ | ✔️ | |
| 投标技术支持服务 | ❌ | ✔️ | |
| 二次开发技术支持服务 | ❌ | ✔️ | |
| 现场技术支持服务 | ❌ | ✔️ | |
## MyEMS截图 ## MyEMS截图
![MyEMS Space EnergyCategory1](/docs/images/myems-space-energycategory1.gif) ![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 wird von einem erfahrenen Entwicklungsteam entwickelt und gewartet, und der Quellcode des Systems wird unter MIT-Lizenz veröffentlicht.
## MyEMS Architektur ## 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) ## MyEMS Komponenten (GCommunity Edition)
@ -66,125 +70,131 @@ Dieses Projekt besteht aus folgenden Komponenten:
## Editionen vergleichen ## Editionen vergleichen
| Eigenschaften |Community Edition (MyEMS) |Enterprise Edition (AlbertEOS)| | Eigenschaften | Gemeinschaftsausgabe | Enterprise Edition | Erläuterung |
| :--- | :----: | :----: | | :--- | :----: | :----: | :----: |
| Open Source | ✔️ | ❌ | | Open Source | ✔️ | ❌ | |
| Pricing | Free | Pay for Projects | | Pricing | Free | Pay for Projects | |
| Change Name and Logo | ✔️ | ✔️ | | Change Name and Logo | ✔️ | ✔️ | |
| Modbus TCP | ✔️ | ✔️ | | Modbus TCP | ✔️ | ✔️ | |
| BACnet/IP | ✔️ | ✔️ | | BACnet/IP | ✔️ | ✔️ | |
| MQTT Publisher | ✔️ | ✔️ | | MQTT Publisher | ✔️ | ✔️ | |
| Data Points Number | Unlimited |Unlimited | | Data Points Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Meters Number | Unlimited |Unlimited | | Meters Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Equipments Number | Unlimited |Unlimited | | Spaces Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Spaces Number | Unlimited |Unlimited | | Equipments Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Docker | ✔️ | ✔️ | | Tenants Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| Kubernetes | ✔️ | ✔️ | | Stores Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| MySQL | ✔️ | ✔️ | | Shopfloors Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| MariaDB | ✔️ | ✔️ | | Combined Equipments Number | Unbegrenzt | Unbegrenzt | Nur durch die Hardwareleistung begrenzt |
| SingleStore | ✔️ | ✔️ | | Docker | ✔️ | ✔️ | |
| AWS Cloud | ✔️ | ✔️ | | Kubernetes | ✔️ | ✔️ | |
| AZure Cloud | ✔️ | ✔️ | | MySQL | ✔️ | ✔️ | |
| Alibaba Cloud | ✔️ | ✔️ | | MariaDB | ✔️ | ✔️ | |
| Private Cloud | ✔️ | ✔️ | | SingleStore | ✔️ | ✔️ | |
| Data ComparisonYear-on-Year、Month-on-Month、Any-on-Any | ✔️ | ✔️ | | AWS Cloud | ✔️ | ✔️ | |
| Export result to Excel | ✔️ | ✔️ | | AZure Cloud | ✔️ | ✔️ | |
| Space/Energy Category Data | ✔️ | ✔️ | | Alibaba Cloud | ✔️ | ✔️ | |
| Space/Energy Item Data | ✔️ | ✔️ | | Private Cloud | ✔️ | ✔️ | |
| Space/Cost Data | ✔️ | ✔️ | | Data Comparison | ✔️ | ✔️ | Jahr für Jahr, Monat für Monat, Freier Vergleich, Kein Vergleich |
| Space/Output Data | ✔️ | ✔️ | | Excel Exporter | ✔️ | ✔️ | Tabellen, Liniendiagramme, Säulendiagramme, Kreisdiagramme |
| Space/Income Data | ✔️ | ✔️ | | Meter/Energy Data | ✔️ | ✔️ | |
| Space/Efficiency Data | ✔️ | ✔️ | | Meter/Cost Data | ✔️ | ✔️ | |
| Space/Load Data | ✔️ | ✔️ | | Meter/Trend Data | ✔️ | ✔️ | |
| Space/Statistics | ✔️ | ✔️ | | Meter/Realtime Data | ✔️ | ✔️ | |
| Space/Saving Data | ❌ | ✔️ | | Meter/Master Meter Submeters Balance | ✔️ | ✔️ | |
| Equipment/Energy Category Data | ✔️ | ✔️ | | Meter/Offline Meter Energy Data | ✔️ | ✔️ | |
| Equipment/Energy Item Data | ✔️ | ✔️ | | Meter/Offline Meter Cost Data | ✔️ | ✔️ | |
| Equipment/Cost Data | ✔️ | ✔️ | | Meter/Virtual Meter Energy Data | ✔️ | ✔️ | |
| Equipment/Output Data | ✔️ | ✔️ | | Meter/Virtual Meter Cost Data | ✔️ | ✔️ | |
| Equipment/Income Data | ✔️ | ✔️ | | Meter/Meter Tracking | ✔️ | ✔️ | |
| Equipment/Efficiency Data | ✔️ | ✔️ | | Space/Energy Category Data | ✔️ | ✔️ | |
| Equipment/Load Data | ✔️ | ✔️ | | Space/Energy Item Data | ✔️ | ✔️ | |
| Equipment/Statistics | ✔️ | ✔️ | | Space/Cost Data | ✔️ | ✔️ | |
| Equipment/Saving Data | ❌ | ✔️ | | Space/Output Data | ✔️ | ✔️ | |
| Equipment/Equipment Tracking | ✔️ | ✔️ | | Space/Income Data | ✔️ | ✔️ | |
| Meter/Energy Data | ✔️ | ✔️ | | Space/Efficiency Data | ✔️ | ✔️ | |
| Meter/Cost Data | ✔️ | ✔️ | | Space/Load Data | ✔️ | ✔️ | |
| Meter/Trend Data | ✔️ | ✔️ | | Space/Statistics | ✔️ | ✔️ | |
| Meter/Realtime Data | ✔️ | ✔️ | | Space/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Meter/Master Meter Submeters Balance | ✔️ | ✔️ | | Equipment/Energy Category Data | ✔️ | ✔️ | |
| Meter/Offline Meter Energy Data | ✔️ | ✔️ | | Equipment/Energy Item Data | ✔️ | ✔️ | |
| Meter/Offline Meter Cost Data | ✔️ | ✔️ | | Equipment/Cost Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Energy Data | ✔️ | ✔️ | | Equipment/Output Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Cost Data | ✔️ | ✔️ | | Equipment/Income Data | ✔️ | ✔️ | |
| Meter/Meter Tracking | ✔️ | ✔️ | | Equipment/Efficiency Data | ✔️ | ✔️ | |
| Tenant/Energy Category Data | ✔️ | ✔️ | | Equipment/Load Data | ✔️ | ✔️ | |
| Tenant/Energy Item Data | ✔️ | ✔️ | | Equipment/Statistics | ✔️ | ✔️ | |
| Tenant/Cost Data | ✔️ | ✔️ | | Equipment/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Tenant/Load Data | ✔️ | ✔️ | | Equipment/Equipment Tracking | ✔️ | ✔️ | |
| Tenant/Statistics | ✔️ | ✔️ | | Tenant/Energy Category Data | ✔️ | ✔️ | |
| Tenant/Saving Data | ❌ | ✔️ | | Tenant/Energy Item Data | ✔️ | ✔️ | |
| Tenant/Tenant Bill | ✔️ | ✔️ | | Tenant/Cost Data | ✔️ | ✔️ | |
| Store/Energy Category Data | ✔️ | ✔️ | | Tenant/Load Data | ✔️ | ✔️ | |
| Store/Energy Item Data | ✔️ | ✔️ | | Tenant/Statistics | ✔️ | ✔️ | |
| Store/Cost Data | ✔️ | ✔️ | | Tenant/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Store/Load Data | ✔️ | ✔️ | | Tenant/Tenant Bill | ✔️ | ✔️ | |
| Store/Statistics | ✔️ | ✔️ | | Store/Energy Category Data | ✔️ | ✔️ | |
| Store/Saving Data | ❌ | ✔️ | | Store/Energy Item Data | ✔️ | ✔️ | |
| Shopfloor/Energy Category Data | ✔️ | ✔️ | | Store/Cost Data | ✔️ | ✔️ | |
| Shopfloor/Energy Item Data | ✔️ | ✔️ | | Store/Load Data | ✔️ | ✔️ | |
| Shopfloor/Cost Data | ✔️ | ✔️ | | Store/Statistics | ✔️ | ✔️ | |
| Shopfloor/Load Data | ✔️ | ✔️ | | Store/Saving Data | ❌ | ✔️ | |
| Shopfloor/Statistics | ✔️ | ✔️ | | Shopfloor/Energy Category Data | ✔️ | ✔️ | |
| Shopfloor/Saving Data | ❌ | ✔️ | | Shopfloor/Energy Item Data | ✔️ | ✔️ | |
| Combined Equipment/Energy Category Data | ✔️ | ✔️ | | Shopfloor/Cost Data | ✔️ | ✔️ | |
| Combined Equipment/Energy Item Data | ✔️ | ✔️ | | Shopfloor/Load Data | ✔️ | ✔️ | |
| Combined Equipment/Cost Data | ✔️ | ✔️ | | Shopfloor/Statistics | ✔️ | ✔️ | |
| Combined Equipment/Output Data | ✔️ | ✔️ | | Shopfloor/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Combined Equipment/Income Data | ✔️ | ✔️ | | Combined Equipment/Energy Category Data | ✔️ | ✔️ | |
| Combined Equipment/Efficiency Data | ✔️ | ✔️ | | Combined Equipment/Energy Item Data | ✔️ | ✔️ | |
| Combined Equipment/Load Data | ✔️ | ✔️ | | Combined Equipment/Cost Data | ✔️ | ✔️ | |
| Combined Equipment/Statistics | ✔️ | ✔️ | | Combined Equipment/Output Data | ✔️ | ✔️ | |
| Combined Equipment/Saving Data | ❌ | ✔️ | | Combined Equipment/Income Data | ✔️ | ✔️ | |
| Energy Dashboard | ✔️ | ✔️ | | Combined Equipment/Efficiency Data | ✔️ | ✔️ | |
| Energy Flow Diagram | ✔️ | ✔️ | | Combined Equipment/Load Data | ✔️ | ✔️ | |
| Distribution System | ✔️ | ✔️ | | Combined Equipment/Statistics | ✔️ | ✔️ | |
| REST API | ✔️ | ✔️ | | Combined Equipment/Saving Data | ❌ | ✔️ | Erfordert eine Komponente zur Vorhersage des Energieverbrauchs |
| Web UI | ✔️ | ✔️ | | Energy Dashboard | ✔️ | ✔️ | |
| Admin UI | ✔️ | ✔️ | | Energy Flow Diagram | ✔️ | ✔️ | |
| MQTT Subscriber | ❌ | ✔️ | | Distribution System | ✔️ | ✔️ | |
| Modbus RTU | ❌ | ✔️ | | REST API | ✔️ | ✔️ | |
| OPC UA | ❌ | ✔️ | | Web UI | ✔️ | ✔️ | |
| OPC DA | ❌ | ✔️ | | Admin UI | ✔️ | ✔️ | |
| Siemens S7 | ❌ | ✔️ | | MQTT Subscriber | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| IEC 104 | ❌ | ✔️ | | Modbus RTU | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Johnson Controls Metasys | ✔️ | ✔️ | | OPC UA | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Honeywell EBI | ✔️ | ✔️ | | OPC DA | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| SIEMENS Desigo CC | ❌ | ✔️ | | Siemens S7 | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| QWeather API | ❌ | ✔️ | | IEC 104 | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| FDD Rule Engine | ❌ | ✔️ | | Johnson Controls Metasys API | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Advanced Reporting Engine | ❌ | ✔️ | | Honeywell EBI | ✔️ | ✔️ | |
| Graphics Drawing Tool | ❌ | ✔️ | | SIEMENS Desigo CC | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Equipments Remote Control | ❌ | ✔️ | | QWeather API | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| BACnet Server | ❌ | ✔️ | | FDD Rule Engine | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Modbus TCP Server(Slave) | ❌ | ✔️ | | Advanced Reporting Engine | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| OPC UA Server | ❌ | ✔️ | | Graphics Drawing Tool | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| iOS APP | ❌ | ✔️ | | Equipments Remote Control | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| Android APP | ❌ | ✔️ | | BACnet Server | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| WeChat Mini Program | ❌ | ✔️ | | Modbus TCP Server(Slave) | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| Alipay Mini Program | ❌ | ✔️ | | OPC UA Server | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz |
| IPC Hardware Gateway (Data Acquisition and Remote Control| ❌ | ✔️ | | iOS APP | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| LoRa Radio Module (Data Acquisition and Remote Control| ❌ | ✔️ | | Android APP | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit| ❌ | ✔️ | | WeChat Mini Program | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| 3rd Party Systems Integration Service | ❌ | ✔️ | | Alipay Mini Program | ❌ | ✔️ | Erfordert eine Standardkomponentenlizenz oder eine benutzerdefinierte Entwicklung |
| Online Community Customer Support| ✔️ | ✔️ | | IPC Hardware Gateway (Data Acquisition and Remote Control| ❌| ✔️ | MyEMS-zertifizierte industrielle Computerhardware |
| Email Customer Support | ✔️ | ✔️ | | LoRa Radio Module (Data Acquisition and Remote Control | ❌| ✔️ | MyEMS-zertifiziertes LoRa-Hardwaregerät |
| Telephone Customer Support | ❌ | ✔️ | | Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit | ❌ | ✔️ | |
| WeChat Customer Support | ❌ | ✔️ | | 3rd Party Systems Integration Service | ❌ | ✔️ | Kundenspezifische Entwicklung |
| Remote Desktop Customer Support | ❌ | ✔️ | | Online software training | ✔️ | ✔️ | Kostenlos |
| Onsite Customer Support | ❌ | ✔️ | | Face to face software training | ❌ | ✔️ | |
| Bidding Support Service | ❌ | ✔️ | | Online Community Customer Support| ✔️ | ✔️ | Kostenlos |
| Customize Support Service | ❌ | ✔️ | | 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 ## 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 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
![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) ## MyEMS Components (Community Edition)
@ -66,125 +70,131 @@ This project is compose of following components:
## Compare Editions ## Compare Editions
| Features |Communit Edition (MyEMS) |Enterprise Edition (AlbertEOS)| | Features | Community Edition | Enterprise Edition | Explanation |
| :--- | :----: | :----: | | :--- | :----: | :----: | :----: |
| Open Source | ✔️ | ❌ | | Open Source | ✔️ | ❌ | |
| Pricing | Free | Pay for Projects | | Pricing | Free | Pay for Projects | |
| Change Name and Logo | ✔️ | ✔️ | | Change Name and Logo | ✔️ | ✔️ | |
| Modbus TCP | ✔️ | ✔️ | | Modbus TCP | ✔️ | ✔️ | |
| BACnet/IP | ✔️ | ✔️ | | BACnet/IP | ✔️ | ✔️ | |
| MQTT Publisher | ✔️ | ✔️ | | MQTT Publisher | ✔️ | ✔️ | |
| Data Points Number | Unlimited |Unlimited | | Data Points Number | Unlimited | Unlimited | Limited only by hardware performance |
| Meters Number | Unlimited |Unlimited | | Meters Number | Unlimited | Unlimited | Limited only by hardware performance |
| Equipments Number | Unlimited |Unlimited | | Spaces Number | Unlimited | Unlimited | Limited only by hardware performance |
| Spaces Number | Unlimited |Unlimited | | Equipments Number | Unlimited | Unlimited | Limited only by hardware performance |
| Docker | ✔️ | ✔️ | | Tenants Number | Unlimited | Unlimited | Limited only by hardware performance |
| Kubernetes | ✔️ | ✔️ | | Stores Number | Unlimited | Unlimited | Limited only by hardware performance |
| MySQL | ✔️ | ✔️ | | Shopfloors Number | Unlimited | Unlimited | Limited only by hardware performance |
| MariaDB | ✔️ | ✔️ | | Combined Equipments Number | Unlimited | Unlimited | Limited only by hardware performance |
| SingleStore | ✔️ | ✔️ | | Docker | ✔️ | ✔️ | |
| AWS Cloud | ✔️ | ✔️ | | Kubernetes | ✔️ | ✔️ | |
| AZure Cloud | ✔️ | ✔️ | | MySQL | ✔️ | ✔️ | |
| Alibaba Cloud | ✔️ | ✔️ | | MariaDB | ✔️ | ✔️ | |
| Private Cloud | ✔️ | ✔️ | | SingleStore | ✔️ | ✔️ | |
| Data ComparisonYear-on-Year、Month-on-Month、Any-on-Any| ✔️ | ✔️ | | AWS Cloud | ✔️ | ✔️ | |
| Export result to Excel | ✔️ | ✔️ | | AZure Cloud | ✔️ | ✔️ | |
| Space/Energy Category Data | ✔️ | ✔️ | | Alibaba Cloud | ✔️ | ✔️ | |
| Space/Energy Item Data | ✔️ | ✔️ | | Private Cloud | ✔️ | ✔️ | |
| Space/Cost Data | ✔️ | ✔️ | | Data Comparison | ✔️ | ✔️ | Year-on-Year, Month-on-Month, Free Comparison, None Comparison |
| Space/Output Data | ✔️ | ✔️ | | Excel Exporter | ✔️ | ✔️ | Tables, Line Charts, Column Charts, Pie Charts |
| Space/Income Data | ✔️ | ✔️ | | Meter/Energy Data | ✔️ | ✔️ | |
| Space/Efficiency Data | ✔️ | ✔️ | | Meter/Cost Data | ✔️ | ✔️ | |
| Space/Load Data | ✔️ | ✔️ | | Meter/Trend Data | ✔️ | ✔️ | |
| Space/Statistics | ✔️ | ✔️ | | Meter/Realtime Data | ✔️ | ✔️ | |
| Space/Saving Data | ❌ | ✔️ | | Meter/Master Meter Submeters Balance | ✔️ | ✔️ | |
| Equipment/Energy Category Data | ✔️ | ✔️ | | Meter/Offline Meter Energy Data | ✔️ | ✔️ | |
| Equipment/Energy Item Data | ✔️ | ✔️ | | Meter/Offline Meter Cost Data | ✔️ | ✔️ | |
| Equipment/Cost Data | ✔️ | ✔️ | | Meter/Virtual Meter Energy Data | ✔️ | ✔️ | |
| Equipment/Output Data | ✔️ | ✔️ | | Meter/Virtual Meter Cost Data | ✔️ | ✔️ | |
| Equipment/Income Data | ✔️ | ✔️ | | Meter/Meter Tracking | ✔️ | ✔️ | |
| Equipment/Efficiency Data | ✔️ | ✔️ | | Space/Energy Category Data | ✔️ | ✔️ | |
| Equipment/Load Data | ✔️ | ✔️ | | Space/Energy Item Data | ✔️ | ✔️ | |
| Equipment/Statistics | ✔️ | ✔️ | | Space/Cost Data | ✔️ | ✔️ | |
| Equipment/Saving Data | ❌ | ✔️ | | Space/Output Data | ✔️ | ✔️ | |
| Equipment/Equipment Tracking | ✔️ | ✔️ | | Space/Income Data | ✔️ | ✔️ | |
| Meter/Energy Data | ✔️ | ✔️ | | Space/Efficiency Data | ✔️ | ✔️ | |
| Meter/Cost Data | ✔️ | ✔️ | | Space/Load Data | ✔️ | ✔️ | |
| Meter/Trend Data | ✔️ | ✔️ | | Space/Statistics | ✔️ | ✔️ | |
| Meter/Realtime Data | ✔️ | ✔️ | | Space/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Meter/Master Meter Submeters Balance | ✔️ | ✔️ | | Equipment/Energy Category Data | ✔️ | ✔️ | |
| Meter/Offline Meter Energy Data | ✔️ | ✔️ | | Equipment/Energy Item Data | ✔️ | ✔️ | |
| Meter/Offline Meter Cost Data | ✔️ | ✔️ | | Equipment/Cost Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Energy Data | ✔️ | ✔️ | | Equipment/Output Data | ✔️ | ✔️ | |
| Meter/Virtual Meter Cost Data | ✔️ | ✔️ | | Equipment/Income Data | ✔️ | ✔️ | |
| Meter/Meter Tracking | ✔️ | ✔️ | | Equipment/Efficiency Data | ✔️ | ✔️ | |
| Tenant/Energy Category Data | ✔️ | ✔️ | | Equipment/Load Data | ✔️ | ✔️ | |
| Tenant/Energy Item Data | ✔️ | ✔️ | | Equipment/Statistics | ✔️ | ✔️ | |
| Tenant/Cost Data | ✔️ | ✔️ | | Equipment/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Tenant/Load Data | ✔️ | ✔️ | | Equipment/Equipment Tracking | ✔️ | ✔️ | |
| Tenant/Statistics | ✔️ | ✔️ | | Tenant/Energy Category Data | ✔️ | ✔️ | |
| Tenant/Saving Data | ❌ | ✔️ | | Tenant/Energy Item Data | ✔️ | ✔️ | |
| Tenant/Tenant Bill | ✔️ | ✔️ | | Tenant/Cost Data | ✔️ | ✔️ | |
| Store/Energy Category Data | ✔️ | ✔️ | | Tenant/Load Data | ✔️ | ✔️ | |
| Store/Energy Item Data | ✔️ | ✔️ | | Tenant/Statistics | ✔️ | ✔️ | |
| Store/Cost Data | ✔️ | ✔️ | | Tenant/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Store/Load Data | ✔️ | ✔️ | | Tenant/Tenant Bill | ✔️ | ✔️ | |
| Store/Statistics | ✔️ | ✔️ | | Store/Energy Category Data | ✔️ | ✔️ | |
| Store/Saving Data | ❌ | ✔️ | | Store/Energy Item Data | ✔️ | ✔️ | |
| Shopfloor/Energy Category Data | ✔️ | ✔️ | | Store/Cost Data | ✔️ | ✔️ | |
| Shopfloor/Energy Item Data | ✔️ | ✔️ | | Store/Load Data | ✔️ | ✔️ | |
| Shopfloor/Cost Data | ✔️ | ✔️ | | Store/Statistics | ✔️ | ✔️ | |
| Shopfloor/Load Data | ✔️ | ✔️ | | Store/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Shopfloor/Statistics | ✔️ | ✔️ | | Shopfloor/Energy Category Data | ✔️ | ✔️ | |
| Shopfloor/Saving Data | ❌ | ✔️ | | Shopfloor/Energy Item Data | ✔️ | ✔️ | |
| Combined Equipment/Energy Category Data | ✔️ | ✔️ | | Shopfloor/Cost Data | ✔️ | ✔️ | |
| Combined Equipment/Energy Item Data | ✔️ | ✔️ | | Shopfloor/Load Data | ✔️ | ✔️ | |
| Combined Equipment/Cost Data | ✔️ | ✔️ | | Shopfloor/Statistics | ✔️ | ✔️ | |
| Combined Equipment/Output Data | ✔️ | ✔️ | | Shopfloor/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Combined Equipment/Income Data | ✔️ | ✔️ | | Combined Equipment/Energy Category Data | ✔️ | ✔️ | |
| Combined Equipment/Efficiency Data | ✔️ | ✔️ | | Combined Equipment/Energy Item Data | ✔️ | ✔️ | |
| Combined Equipment/Load Data | ✔️ | ✔️ | | Combined Equipment/Cost Data | ✔️ | ✔️ | |
| Combined Equipment/Statistics | ✔️ | ✔️ | | Combined Equipment/Output Data | ✔️ | ✔️ | |
| Combined Equipment/Saving Data | ❌ | ✔️ | | Combined Equipment/Income Data | ✔️ | ✔️ | |
| Energy Dashboard | ✔️ | ✔️ | | Combined Equipment/Efficiency Data | ✔️ | ✔️ | |
| Energy Flow Diagram | ✔️ | ✔️ | | Combined Equipment/Load Data | ✔️ | ✔️ | |
| Distribution System | ✔️ | ✔️ | | Combined Equipment/Statistics | ✔️ | ✔️ | |
| REST API | ✔️ | ✔️ | | Combined Equipment/Saving Data | ❌ | ✔️ | Requires Energy consumption prediction component |
| Web UI | ✔️ | ✔️ | | Energy Dashboard | ✔️ | ✔️ | |
| Admin UI | ✔️ | ✔️ | | Energy Flow Diagram | ✔️ | ✔️ | |
| MQTT Subscriber | ❌ | ✔️ | | Distribution System | ✔️ | ✔️ | |
| Modbus RTU | ❌ | ✔️ | | REST API | ✔️ | ✔️ | |
| OPC UA | ❌ | ✔️ | | Web UI | ✔️ | ✔️ | |
| OPC DA | ❌ | ✔️ | | Admin UI | ✔️ | ✔️ | |
| Siemens S7 | ❌ | ✔️ | | MQTT Subscriber | ❌ | ✔️ | Requires standard component license |
| IEC 104 | ❌ | ✔️ | | Modbus RTU | ❌ | ✔️ | Requires standard component license |
| Johnson Controls Metasys | ✔️ | ✔️ | | OPC UA | ❌ | ✔️ | Requires standard component license |
| Honeywell EBI | ✔️ | ✔️ | | OPC DA | ❌ | ✔️ | Requires standard component license |
| SIEMENS Desigo CC | ❌ | ✔️ | | Siemens S7 | ❌ | ✔️ | Requires standard component license |
| QWeather API | ❌ | ✔️ | | IEC 104 | ❌ | ✔️ | Requires standard component license |
| FDD Rule Engine | ❌ | ✔️ | | Johnson Controls Metasys API | ❌ | ✔️ | Requires standard component license |
| Advanced Reporting Engine | ❌ | ✔️ | | Honeywell EBI | ✔️ | ✔️ | |
| Graphics Drawing Tool | ❌ | ✔️ | | SIEMENS Desigo CC | ❌ | ✔️ | Requires standard component license |
| Equipments Remote Control | ❌ | ✔️ | | QWeather API | ❌ | ✔️ | Requires standard component license |
| BACnet Server | ❌ | ✔️ | | FDD Rule Engine | ❌ | ✔️ | Requires standard component license or custom development |
| Modbus TCP Server(Slave) | ❌ | ✔️ | | Advanced Reporting Engine | ❌ | ✔️ | Requires standard component license or custom development |
| OPC UA Server | ❌ | ✔️ | | Graphics Drawing Tool | ❌ | ✔️ | |
| iOS APP | ❌ | ✔️ | | Equipments Remote Control | ❌ | ✔️ | Requires standard component license or custom development |
| Android APP | ❌ | ✔️ | | BACnet Server | ❌ | ✔️ | |
| WeChat Mini Program | ❌ | ✔️ | | Modbus TCP Server(Slave) | ❌ | ✔️ | |
| Alipay Mini Program | ❌ | ✔️ | | OPC UA Server | ❌ | ✔️ | |
| IPC Hardware Gateway (Data Acquisition and Remote Control| ❌ | ✔️ | | iOS APP | ❌ | ✔️ | Requires standard component license or custom development |
| LoRa Radio Module (Data Acquisition and Remote Control| ❌ | ✔️ | | Android APP | ❌ | ✔️ | Requires standard component license or custom development |
| Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit| ❌ | ✔️ | | WeChat Mini Program | ❌ | ✔️ | Requires standard component license or custom development |
| 3rd Party Systems Integration Service | ❌ | ✔️ | | Alipay Mini Program | ❌ | ✔️ | Requires standard component license or custom development |
| Online Community Customer Support| ✔️ | ✔️ | | IPC Hardware Gateway (Data Acquisition and Remote Control| ❌ | ✔️ | MyEMS certified industrial computer hardware |
| Email Customer Support | ✔️ | ✔️ | | LoRa Radio Module (Data Acquisition and Remote Control| ❌ | ✔️ | MyEMS certified LoRa hardware device |
| Telephone Customer Support | ❌ | ✔️ | | Protocol for Uploading to Provincial Platform of On-line monitoring system for Key Energy-Consuming Unit | ❌ | ✔️ | Requires standard component license or custom development |
| WeChat Customer Support | ❌ | ✔️ | | 3rd Party Systems Integration Service | ❌ | ✔️ | Custom development |
| Remote Desktop Customer Support | ❌ | ✔️ | | Online software training | ✔️ | ✔️ | Free |
| Onsite Customer Support | ❌ | ✔️ | | Face to face software training | ❌ | ✔️ | |
| Bidding Support Service | ❌ | ✔️ | | Online Community Customer Support| ✔️ | ✔️ | Free |
| Customize Support Service | ❌ | ✔️ | | 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 Screenshot
![MyEMS Space EnergyCategory1](/docs/images/myems-space-energycategory1.gif) ![MyEMS Space EnergyCategory1](/docs/images/myems-space-energycategory1.gif)

View File

@ -1,3 +1,4 @@
Architecture 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList 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'] times = reporting_period_data['timestamps']
has_detail_data_flag = True has_detail_data_flag = True
ca_len = len(report['reporting_period']['names']) 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'])
current_end_row_number = (current_row_number + 1) + ca_len * 6 + len(times[0]) + 3 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 \ if "timestamps" not in reporting_period_data.keys() or \
reporting_period_data['timestamps'] is None or \ reporting_period_data['timestamps'] is None or \
len(reporting_period_data['timestamps']) == 0: len(reporting_period_data['timestamps']) == 0:
@ -491,6 +493,7 @@ def generate_excel(report,
line.dLbls.showPercent = False line.dLbls.showPercent = False
chart_col = 'B' chart_col = 'B'
chart_cell = chart_col + str(current_row_number + 1 + 6 * i) chart_cell = chart_col + str(current_row_number + 1 + 6 * i)
table_start_draw_flag = current_row_number
ws.add_chart(line, chart_cell) ws.add_chart(line, chart_cell)
row = str(max_row + 1) row = str(max_row + 1)
@ -645,7 +648,188 @@ def generate_excel(report,
current_row_number += 5 current_row_number += 5
current_row_number += 1 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) 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] every_day_sum += reporting_period_data['values'][i][every_day_index]
return every_day_sum 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList from openpyxl.chart.label import DataLabelList
import openpyxl.utils.cell as format_cell
#################################################################################################################### ####################################################################################################################
# PROCEDURES # PROCEDURES
@ -512,11 +514,11 @@ def generate_excel(report,
reporting_period_data = report['reporting_period'] reporting_period_data = report['reporting_period']
times = reporting_period_data['timestamps'] times = reporting_period_data['timestamps']
ca_len = len(report['reporting_period']['names']) 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)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据' 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 current_row_number = table_start_row_number
time = times[0] time = times[0]
@ -691,8 +693,214 @@ def generate_excel(report,
if ca_len % 2 == 1: if ca_len % 2 == 1:
current_row_number += 5 current_row_number += 5
current_row_number += 1 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)
return 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList 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: if has_values_data and has_timestamps_data:
ca_len = len(reporting_period_data['names']) ca_len = len(reporting_period_data['names'])
time = reporting_period_data['timestamps'][0] 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)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据' ws['B' + str(current_row_number)] = name + ' 详细数据'
@ -345,7 +346,7 @@ def generate_excel(report,
chart_start_row_number = current_row_number 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 table_start_row_number = current_row_number
ws.row_dimensions[current_row_number].height = 60 ws.row_dimensions[current_row_number].height = 60
@ -539,7 +540,188 @@ def generate_excel(report,
current_row_number += 5 current_row_number += 5
current_row_number += 1 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)
@ -553,3 +735,28 @@ def group_by_category(category_list):
category_dict[value] = list() category_dict[value] = list()
category_dict[value].append(i) category_dict[value].append(i)
return category_dict 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList 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'] times = reporting_period_data['timestamps']
has_detail_data_flag = True has_detail_data_flag = True
ca_len = len(report['reporting_period']['names']) 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 current_end_row_number = current_row_number
if "timestamps" not in reporting_period_data.keys() or \ if "timestamps" not in reporting_period_data.keys() or \
reporting_period_data['timestamps'] is None or \ reporting_period_data['timestamps'] is None or \
@ -420,6 +422,7 @@ def generate_excel(report,
line.dLbls.showPercent = False line.dLbls.showPercent = False
chart_col = 'B' chart_col = 'B'
chart_cell = chart_col + str(current_row_number + 1 + 6 * i) chart_cell = chart_col + str(current_row_number + 1 + 6 * i)
table_start_draw_flag = current_row_number
ws.add_chart(line, chart_cell) ws.add_chart(line, chart_cell)
row = str(max_row + 1) row = str(max_row + 1)
@ -480,7 +483,7 @@ def generate_excel(report,
if has_child_flag: if has_child_flag:
child = report['child_space'] 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)].font = title_font
ws['B' + str(current_row_number)] = name + ' 子空间数据' ws['B' + str(current_row_number)] = name + ' 子空间数据'
@ -578,7 +581,187 @@ def generate_excel(report,
current_row_number += 1 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) 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] every_day_sum += reporting_period_data['values'][i][every_day_index]
return every_day_sum 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList 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) ca_len = len(category)
times = reporting_period_data['timestamps'] times = reporting_period_data['timestamps']
time = times[0] 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)].font = title_font
ws['B' + str(current_row_number)] = name + '详细数据' ws['B' + str(current_row_number)] = name + '详细数据'
current_row_number += 1 current_row_number += 1
chart_start_number = current_row_number chart_start_number = current_row_number
current_row_number += real_timestamps_len * 7 + 1
if has_sub_averages_data_flag: if has_sub_averages_data_flag:
current_row_number = (current_row_number + ca_len * 6) 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 line.dLbls.showVal = True
ws.add_chart(line, "B" + str(current_chart_row_number)) ws.add_chart(line, "B" + str(current_chart_row_number))
current_chart_row_number += 6 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)
return 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList 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: if has_values_data and has_timestamps_data:
ca_len = len(reporting_period_data['names']) ca_len = len(reporting_period_data['names'])
time = reporting_period_data['timestamps'][0] 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)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据' ws['B' + str(current_row_number)] = name + ' 详细数据'
@ -284,7 +285,7 @@ def generate_excel(report,
chart_start_row_number = current_row_number 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 table_start_row_number = current_row_number
ws.row_dimensions[current_row_number].height = 60 ws.row_dimensions[current_row_number].height = 60
@ -475,11 +476,214 @@ def generate_excel(report,
current_row_number += 5 current_row_number += 5
current_row_number += 1 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)
return 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.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
from openpyxl.chart.label import DataLabelList 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: if has_values_saving_data and has_timestamps_data:
ca_len = len(reporting_period_data['names']) ca_len = len(reporting_period_data['names'])
time = reporting_period_data['timestamps'][0] 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)].font = title_font
ws['B' + str(current_row_number)] = name + ' 详细数据' ws['B' + str(current_row_number)] = name + ' 详细数据'
@ -486,7 +487,7 @@ def generate_excel(report,
chart_start_row_number = current_row_number 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 table_start_row_number = current_row_number
ws.row_dimensions[current_row_number].height = 60 ws.row_dimensions[current_row_number].height = 60
@ -683,7 +684,188 @@ def generate_excel(report,
current_row_number += 5 current_row_number += 5
current_row_number += 1 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)
@ -698,3 +880,27 @@ def sum_list(lists):
return total 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.styles import PatternFill, Border, Side, Alignment, Font
from openpyxl.drawing.image import Image from openpyxl.drawing.image import Image
from openpyxl import Workbook from openpyxl import Workbook
import openpyxl.utils.cell as format_cell
#################################################################################################################### ####################################################################################################################
@ -175,8 +176,6 @@ def generate_excel(report,
if has_energy_data_flag: if has_energy_data_flag:
ws['B6'].font = title_font ws['B6'].font = title_font
ws['B6'] = name + ' 统计分析' ws['B6'] = name + ' 统计分析'
# ws['D6'].font = title_font
# ws['D6'] = '面积' +report['space']['area']
category = reporting_period_data['names'] category = reporting_period_data['names']
@ -441,8 +440,9 @@ def generate_excel(report,
names = reporting_period_data['names'] names = reporting_period_data['names']
ca_len = len(names) ca_len = len(names)
time_len = len(timestamps) time_len = len(timestamps)
real_timestamps_len = timestamps_data_not_equal_0(report['parameters']['timestamps'])
# title # 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 analysis_end_row_number = 12 + 3 * ca_len
detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1 detailed_start_row_number = analysis_end_row_number + line_charts_row_number + 1
@ -525,8 +525,214 @@ def generate_excel(report,
ser.marker.symbol = "diamond" ser.marker.symbol = "diamond"
ser.marker.size = 5 ser.marker.size = 5
ws.add_chart(line, 'B' + str(analysis_end_row_number + 6 * i)) 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' filename = str(uuid.uuid4()) + '.xlsx'
wb.save(filename) wb.save(filename)
return 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