Commit a5f0ce85 authored by 陈聪's avatar 陈聪

cc修改

parents
def cal_Phead(inletPressure_bar, outletPressure_bar, rho=1000, g=9.81): #Pressure:Pa;rho:kg/m^3;g:m/s^2
rho = rho
g = g
inletPressure_pa = inletPressure_bar * 100000
outletPressure_pa = outletPressure_bar * 100000
if rho * g == 0:
return "Error"
else:
H = (outletPressure_pa - inletPressure_pa) / (rho * g)
return H
# print(cal_Phead(2.5,2.4))
\ No newline at end of file
import apiUtils.api as cc
import paho.mqtt.client as mqtt
import json
import time
import Phead
import eef
import sys
urlMain = "http://gm.cloud.witium.com.cn/api"
# 根据当前的addr通道,自动读取对应设备的转速数据使用
RN_RM_1 = {"RN":"RN915455426295115778","RM":"RM915455426295115776"}
RN_RM_2 = {"RN":"RN915456080103223296","RM":"RM915456080069668864"}
RN_RM_3 = {"RN":"RN915456298278334464","RM":"RM915456298253168640"}
RN_RM_list = [RN_RM_1, RN_RM_2, RN_RM_3]
# 用于获取当前转速信息的传参
reducerNo = [RN_RM_list[1]["RN"]]
startTime = int(time.time())*1000 - 100000
endTime = startTime + 100000000
wcVarList = []
varList = [["actualSpd"]]
monitorNoList = [RN_RM_list[1]["RM"]]
# 如果获取的电机转速为0,则用固定值
actualSpd= 2400 # TODO
cc.setUrlMain(urlMain)
# 配置MQTT信息常量
CODEENV = "test"
OP_SN_TYPE = "WTG93RF"
OP_SN = "24010580W"
BROKER_IP = "222.71.96.91"
BROKER_PORT = 12883
USERNAME = "witcd"
PASSWORD = "Witium37774020"
# 构建主题
DATA_SOURCE_TOPIC = f"WT/{OP_SN_TYPE}/{OP_SN}/opData"
class MQTTForwarder:
def __init__(self, actualSpd, startTime, wcVarList, varList, RN_RM_list, endTime):
self.client = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
self.client.username_pw_set(USERNAME, PASSWORD)
self.client.on_connect = self.on_connect
self.client.on_message = self.on_message
self.client.on_disconnect = self.on_disconnect
self.received_data = None # 存储解析后的数据
self.actualSpd = actualSpd
self.startTime = startTime
self.wcVarList = wcVarList
self.varList = varList
self.RN_RM_list = RN_RM_list
self.endTime = endTime
def on_connect(self, client, userdata, flags, rc, properties=None):
if rc == 0:
print("成功连接到MQTT服务器")
client.subscribe(DATA_SOURCE_TOPIC) # 只订阅数据源主题
else:
print(f"连接失败,错误码: {rc}")
def on_message(self, client, userdata, msg):
print(f"收到消息 [{msg.topic}]: {msg.payload.decode()}")
if msg.topic == DATA_SOURCE_TOPIC:
try:
data = json.loads(msg.payload.decode())
print(type(data),data)
# 检查数据是否为列表,并提取第一个字典
if isinstance(data, list) and len(data) > 0:
received_data = data[0] # 取第一个字典
print("成功解析并存储数据")
# 从数据中提取 addr
if 'addr' in received_data:
addr = received_data['addr']
# 动态构建发布主题
PUBLISH_TOPIC = f"{DATA_SOURCE_TOPIC}/{addr}"
PUBLISH_TOPIC_cc = f"{DATA_SOURCE_TOPIC}"
# # 更新数据中的时间戳和地址
# received_data['ts'] = startTime
####################################### 涉及计算部分 cc修改 ##########################################
########################## 获取当前运行设备的转速 #################
print("addr:{}".format(received_data['addr']))
reducerNo = self.RN_RM_list[received_data["addr"] - 1]["RN"]
startTime = self.startTime
endTime = self.endTime
wcVarList =self.wcVarList
varList=self.varList
monitorNoList=[self.RN_RM_list[received_data["addr"] - 1]["RM"]]
res = cc.getHistoryDataWithWorkingConditionByMonitorList_route(
reducerNo = reducerNo,
startTime = startTime,
endTime = endTime,
wcVarList = wcVarList,
varList = varList ,
monitorNoList = monitorNoList)
acutalSpd_r = res["data"]["actualSpd_"+monitorNoList[0]]
if len(acutalSpd_r) == 0:
acutalSpd_r = self.actualSpd
else:
if actualSpd[0] == 0:
acutalSpd_r = self.actualSpd
else:
acutalSpd_r = actualSpd[-1] # 确保获取的转速是最新的
########################## 获取MQTT中的工况数据用于计算 #################
P_in = received_data["P_in"]
P_out = received_data["P_out"]
if P_in < 0 and P_out < 0:
P_in = 0
P_out = 0
else:
pass
########################## 更新扬程 #################
received_data["Phead"]= Phead.cal_Phead( inletPressure_bar= P_in, outletPressure_bar= P_out)
########################## 更新Umax #################
received_data["Umax"] = received_data["UA"]
########################## 更新能效比 #################
received_data["eef"] = eef.evaluate(H_real=received_data["Phead"], P0_real=received_data["Pmax"], N_real=acutalSpd_r)["ΔP0_%"]
if received_data["eef"] < 0:
received_data["eef"] = 0
elif received_data["eef"] > 100:
received_data["eef"] = 100
else:
pass
########################## 更新流量 #################
received_data["Flow"] = eef.estimate_flow(H_query=received_data["Phead"], N_query=acutalSpd_r)
########################## 更新频率 #################
received_data["actualSpd"] = acutalSpd_r / 60
########################## 更新负载 #################
received_data["Load_ratio"] = received_data["Pmax"] / 4.5 * 100
if received_data["Load_ratio"] < 0:
received_data["Load_ratio"] = 0
elif received_data["Load_ratio"] > 100:
received_data["Load_ratio"] = 100
else:
pass
# 发布到目标主题
received_data = [received_data]
payload = json.dumps(received_data)
result = client.publish(PUBLISH_TOPIC, payload)
result_cc = client.publish(PUBLISH_TOPIC_cc, payload)
if result.rc == mqtt.MQTT_ERR_SUCCESS:
print(f"数据已发布到 {PUBLISH_TOPIC}")
else:
print(f"发布失败,错误码: {result.rc}")
else:
print("数据格式错误:不是列表或列表为空")
except json.JSONDecodeError:
print("无法解析JSON数据")
except Exception as e:
print(f"处理消息时出错: {e}")
def on_disconnect(self, client, userdata, rc):
print(f"连接断开,5秒后重试 (code: {rc})")
time.sleep(5)
client.reconnect()
def start(self):
self.client.connect(BROKER_IP, BROKER_PORT, keepalive=60)
self.client.loop_start()
if __name__ == "__main__":
try:
forwarder = MQTTForwarder(actualSpd, startTime,wcVarList,varList,RN_RM_list,endTime)
forwarder.start()
# 等待连接建立
time.sleep(2)
# 每5秒检查并发布一次数据
while True:
time.sleep(5)
except KeyboardInterrupt:
print("\n程序终止")
except Exception as e:
print(f"致命错误: {str(e)}")
import numpy as np
def x():
return 1,2,3
y=x()[1]
print(y)
\ No newline at end of file
This diff is collapsed.
[0801/000125.601:ERROR:registration_protocol_win.cc(107)] CreateFile: 系统找不到指定的文件。 (0x2)
import pandas as pd, numpy as np
import sys
import datetime
import time
# ------------------------------------------------------------
# 1) 读取 CSV 并按 ±2 rpm 归并转速
speed_tol = 2
df = pd.read_csv("E:\File\DESK\陈聪文档\学习代码\wilo_fea_cal_transfer-main\wilo_fea_cal_transfer-main\wilo_pump.CSV")
df.rename(columns={"H\n(m)": "H",
"P0tot\n(kW)": "P0",
"Q\n(m3/h)": "Q",
"N\n(rpm)": "N"}, inplace=True)
uniq = np.sort(df["N"].unique())
clusters, cluster = [], [uniq[0]]
for n in uniq[1:]:
# 若与当前簇最后一个值差值 ≤ 容忍带 → 归同簇
if n - cluster[-1] <= speed_tol:
cluster.append(n)
else:
clusters.append(cluster) # 结束旧簇
cluster = [n] # 开始新簇
clusters.append(cluster) # 别忘了最后一个簇
# 建立 speed_map:把簇中的每个原始转速映射到簇内平均值
speed_map = {}
for c in clusters:
rep = int(round(np.mean(c))) # 代表转速
for n in c:
speed_map[int(n)] = rep # 注意 n 先转 int,避免 numpy.int64
df["N_grp"] = df["N"].map(speed_map)
# ------------------------------------------------------------
# 给定 H / N 估算 Q(流量)
def estimate_flow(H_query, N_query):
"""估算流量 Q(单位 m³/h),df 必须含 'Q', 'H', 'N_grp'"""
if "Q" not in df.columns:
raise ValueError("数据中不包含 'Q' 列")
speeds = np.sort(df["N_grp"].unique())
if N_query < speeds[0] or N_query > speeds[-1]:
raise ValueError("N 超出试验范围")
j = np.searchsorted(speeds, N_query)
N_lo, N_hi = speeds[max(j-1,0)], speeds[min(j,len(speeds)-1)]
def q_at(N_fix):
sub = df[df["N_grp"] == N_fix].sort_values("H")
return np.interp(H_query, sub["H"], sub["Q"],
left=sub["Q"].iloc[0], right=sub["Q"].iloc[-1])
Q_lo, Q_hi = q_at(N_lo), q_at(N_hi)
return Q_lo if N_lo == N_hi else np.interp(N_query, [N_lo, N_hi], [Q_lo, Q_hi])
# ------------------------------------------------------------
# 核心:给 H / N 求理想 P0tot
def ideal_p0(H, N):
speeds = np.sort(df["N_grp"].unique())
if N < speeds[0] or N > speeds[-1]:
raise ValueError("N 超出试验范围")
j = np.searchsorted(speeds, N)
N_lo, N_hi = speeds[max(j-1,0)], speeds[min(j,len(speeds)-1)]
def p0_at(N_fix):
sub = df[df["N_grp"]==N_fix].sort_values("H")
return np.interp(H, sub["H"], sub["P0"],
left=sub["P0"].iloc[0], right=sub["P0"].iloc[-1])
P_lo, P_hi = p0_at(N_lo), p0_at(N_hi)
return P_lo if N_lo==N_hi else np.interp(N, [N_lo,N_hi], [P_lo,P_hi])
# ------------------------------------------------------------
# 外部接口:输入实测 → 输出偏差
def evaluate(H_real, P0_real, N_real):
P_idl = ideal_p0(H_real, N_real)
return {
"H": H_real,
"N": N_real,
"P0_real": P0_real,
"P0_ideal": P_idl,
"ΔP0_kW": P0_real - P_idl,
"ΔP0_%": 100-((P0_real - P_idl) / P_idl * 100)
}
# -------------------- DEMO --------------------
# print(evaluate(50, 4.50, 2432))
# print(evaluate(2.4, 1.71, 2400))
# ➜ {'H': 50, 'N': 2992, 'P0_real': 4.5,
# 'P0_ideal': 4.232, 'ΔP0_kW': 0.268, 'ΔP0_%': 6.34}
# -------------------- 流量估算 --------------------
# print(f"估算流量 Q ≈ {estimate_flow(2.4, 2400):.2f} m³/h")
# **水泵特征计算与能耗分析工具**
**`02_feaCal.py`**
---
## **项目简介**
本工具用于读取威乐(WILO)水泵的现有特征数据(如流量、扬程等),并计算其能耗性能。核心脚本 `02_feaCal.py` 通过处理输入数据(如 `wilo_pump.CSV`),生成水泵的能耗和扬程分析结果。
---
## **功能特性**
1. **数据输入**
- 支持从 `CSV` 文件(如 `wilo_pump.CSV`)读取水泵特征参数。
- 可扩展其他数据源(如数据库、API)。
2. **核心计算**
- 根据流量(如 `m³/s``L/s`)、扬程等参数,计算水泵的能耗(功率)。
- 支持单位自动转换(如 `L/s ↔ m³/s`)。
3. **输出结果**
- 生成能耗报告或可视化图表(需结合其他工具如 `matplotlib`)。
4. **集成扩展**
-`apiUtils` 模块交互,支持数据远程传输(如 MQTT 或 HTTP)。
---
## **文件结构**
```plaintext
.
├── 02_feaCal.py # 主脚本:水泵特征与能耗计算
├── wilo_pump.CSV # 水泵特征数据源
├── apiUtils/ # 数据通信工具(如 MQTT/HTTP)
├── 01_wcTransfer.py # 辅助脚本(功能待明确)
├── Phead.py # 扬程计算相关(可能依赖)
└── __pycache__/ # Python 缓存目录
```
---
## **快速开始**
### **依赖安装**
```bash
pip install pandas numpy # 数据处理(如需 MQTT 则添加 paho-mqtt)
```
### **运行脚本**
```bash
python 02_feaCal.py
```
---
## **扩展开发**
- **自定义计算**:修改 `02_feaCal.py` 中的 `calculate_energy()` 方法。
- **集成 API**:通过 `apiUtils` 模块将结果发送至云端。
- **可视化**:结合 `matplotlib` 绘制能耗曲线图。
---
## **注意事项**
1. 文件状态说明:
- `M`:已修改(需提交)
- `U`:未跟踪(新文件)
- `IM`:忽略修改(如配置文件)
2. 确保 `wilo_pump.CSV` 的字段格式与脚本匹配。
---
**License**
MIT © 2025 上海辉度能力中心
\ No newline at end of file
"I0tot
(A)","I1tot
(A)","P0tot
(kW)","P1tot
(kW)","P2
(kW)","N
(rpm)","Q
(m3/h)","H
(m)"
2.94,2.73,1.680,1.624,1.501,3320,0.0,64.6
3.77,3.59,2.186,2.119,1.994,3320,3.5,64.0
5.07,5.18,3.101,3.014,2.873,3320,9.0,62.3
6.24,6.70,3.947,3.835,3.672,3320,14.5,58.3
6.93,7.61,4.429,4.301,4.119,3320,20.0,49.9
7.04,7.76,4.500,4.371,4.184,3320,23.7,41.2
6.92,7.62,4.423,4.297,4.116,3320,27.3,30.2
6.69,7.33,4.272,4.150,3.976,3320,31.0,16.8
6.49,7.06,4.130,4.012,3.830,3321,34.1,4.6
2.25,2.20,1.257,1.208,1.102,2988,0.0,52.4
2.87,2.86,1.627,1.572,1.459,2989,3.2,51.9
3.90,4.04,2.296,2.225,2.097,2989,8.1,50.5
4.78,5.15,2.914,2.828,2.684,2990,13.1,47.2
5.26,5.79,3.264,3.168,3.017,2991,18.0,40.5
5.33,5.88,3.315,3.217,3.065,2992,21.3,33.4
5.24,5.78,3.260,3.164,3.011,2992,24.6,24.5
5.08,5.58,3.152,3.059,2.906,2991,27.9,13.7
4.95,5.39,3.045,2.954,2.810,2990,30.7,3.7
1.74,1.78,0.913,0.871,0.782,2660,0.0,41.5
2.10,2.29,1.171,1.125,1.032,2661,2.8,41.1
3.03,3.22,1.649,1.586,1.482,2660,7.2,39.9
3.77,4.08,2.082,2.008,1.894,2660,11.6,37.3
4.10,4.57,2.324,2.245,2.123,2660,16.0,32.0
4.12,4.64,2.362,2.280,2.157,2660,19.0,26.4
4.07,4.57,2.326,2.244,2.122,2660,21.8,19.3
3.97,4.42,2.250,2.172,2.054,2661,24.8,10.8
3.83,4.27,2.168,2.097,1.981,2660,27.3,2.9
1.29,1.40,0.638,0.602,0.530,2326,0.0,31.7
1.57,1.79,0.810,0.770,0.695,2325,2.5,31.4
2.10,2.49,1.123,1.075,0.995,2326,6.3,30.4
2.58,3.14,1.415,1.357,1.270,2326,10.2,28.5
2.85,3.51,1.577,1.514,1.423,2325,14.0,24.4
2.89,3.56,1.600,1.536,1.445,2326,16.6,20.0
2.84,3.50,1.576,1.513,1.422,2328,19.1,14.6
2.74,3.40,1.529,1.467,1.378,2328,21.7,8.1
2.66,3.28,1.476,1.416,1.332,2325,23.9,2.1
0.93,1.08,0.430,0.397,0.340,1997,0.0,23.4
1.13,1.37,0.541,0.505,0.445,1999,2.1,23.1
1.46,1.87,0.737,0.696,0.634,1998,5.4,22.4
1.77,2.35,0.920,0.874,0.809,1998,8.7,21.1
1.96,2.62,1.025,0.974,0.907,1999,12.0,18.0
1.99,2.66,1.040,0.989,0.922,1999,14.2,14.8
1.97,2.62,1.025,0.974,0.908,1999,16.4,10.8
1.92,2.54,0.995,0.946,0.880,1999,18.6,6.0
1.84,2.46,0.965,0.915,0.852,1999,20.5,1.6
0.69,0.83,0.277,0.246,0.204,1663,0.0,16.2
0.77,1.00,0.337,0.306,0.262,1663,1.8,16.0
0.97,1.35,0.454,0.419,0.373,1667,4.5,15.6
1.16,1.68,0.561,0.523,0.475,1668,7.3,14.6
1.26,1.87,0.621,0.581,0.532,1668,10.0,12.5
1.27,1.89,0.630,0.589,0.540,1668,11.9,10.2
1.26,1.87,0.621,0.581,0.532,1668,13.7,7.4
1.24,1.81,0.604,0.564,0.515,1668,15.5,4.1
1.21,1.75,0.585,0.545,0.498,1668,17.1,1.0
0.51,0.61,0.168,0.142,0.110,1328,0.0,10.3
0.56,0.73,0.202,0.174,0.141,1330,1.4,10.1
0.66,0.94,0.261,0.230,0.198,1332,3.6,9.9
0.74,1.15,0.316,0.284,0.251,1334,5.8,9.3
0.83,1.27,0.347,0.314,0.280,1334,8.0,7.9
0.86,1.28,0.351,0.317,0.283,1333,9.5,6.4
0.84,1.26,0.345,0.312,0.278,1332,10.9,4.6
0.78,1.23,0.336,0.304,0.270,1332,12.4,2.5
0.78,1.19,0.327,0.295,0.261,1333,13.6,0.5
0.44,11.00,0.102,0.078,0.056,1000,0.0,5.8
0.45,0.52,0.114,0.089,0.067,1000,1.1,5.7
0.49,0.63,0.139,0.113,0.091,1000,2.7,5.5
0.52,0.74,0.162,0.134,0.112,1000,4.4,5.2
0.54,0.80,0.174,0.146,0.125,1000,6.0,4.4
0.54,0.81,0.176,0.148,0.126,1000,7.1,3.5
0.53,0.80,0.174,0.146,0.124,1000,8.2,2.5
0.53,0.78,0.169,0.142,0.120,1000,9.3,1.2
0.53,0.75,0.165,0.137,0.115,1000,10.3,0.1
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment