用 Codex 或 Claude 帮你安装 复制这段 Prompt,粘贴到 Codex、Claude 或其他助手里,让它检查 Skill 页面并帮你完成安装。
直接命令不会经过审查 Prompt;运行前请先检查来源。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill energy-monitoring命令会保持在同一行。复制前请横向滚动并检查完整内容。
想先保存到本地?可下载 SkillsMP 当前能够提供的文件。
Concevoir et maintenir un watchdog auto-correcteur pour services HTTP — checks de santé, auto-restart, état persistant, rapports et pièges bash.
Serveur de messagerie sécurisé auto-hébergé (Signal-like) avec Flask + WebSocket + AES-256-GCM + pont EVA
ADAM-SENTINEL — Veilleur technologique 24h/24h. Scanne 10 domaines, cree des rapports, met a jour les skills, alerte sur les CVE et breaking changes.
基于 SOC 职业分类
正在显示 SKILL.md
| name | energy-monitoring |
| description | Collecter des données énergétiques et calculer des KPIs. |
| version | 1.0.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| platforms | ["linux","macos","windows"] |
| metadata | {"EVA":{"tags":["energy","iso-50001","power-metering","modbus","grafana","influxdb","enpi","industrial-automation"],"related_skills":["plc-connectivity","industrial-edge","industrial-analytics-grafana","oee-performance"]}} |
La gestion énergétique industrielle consiste à mesurer, surveiller et optimiser la consommation d'énergie (électricité, gaz, eau, air comprimé, vapeur) d'un site de production. La norme ISO 50001 fournit le cadre méthodologique pour un Système de Management de l'Énergie (SMÉ) structuré.
Cette compétence guide l'agent EVA pour :
À utiliser lorsque l'utilisateur demande :
Ne pas utiliser pour :
pid-tuning-control ou hvac-industrial-ventilation).electrical-schematics-eplan).Les compteurs Schneider PowerLogic PM5xxx exposent leurs mesures via des registres Modbus Holding Registers. Voici un script de collecte robuste :
from pymodbus.client import ModbusTcpClient
from pymodbus.payload import BinaryPayloadDecoder
from pymodbus.constants import Endian
import time
import json
# Configuration du compteur
METER_IP = "192.168.1.50"
METER_PORT = 502
UNIT_ID = 1
# Registres Schneider PM5xxx (Holding Registers)
REGISTERS = {
"voltage_L1_N": {"address": 3027, "count": 2, "unit": "V"},
"voltage_L2_N": {"address": 3029, "count": 2, "unit": "V"},
"voltage_L3_N": {"address": 3031, "count": 2, "unit": "V"},
"current_L1": {"address": 2999, "count": 2, "unit": "A"},
"current_L2": {"address": 3001, "count": 2, "unit": "A"},
"current_L3": {"address": 3003, "count": , : },
: {: , : , : },
: {: , : , : },
: {: , : , : },
: {: , : , : },
: {: , : , : },
}
():
result = client.read_holding_registers(address, count, slave=unit_id)
result.isError():
decoder = BinaryPayloadDecoder.fromRegisters(
result.registers, byteorder=Endian.BIG, wordorder=Endian.BIG
)
(decoder.decode_32bit_float(), )
():
client = ModbusTcpClient(ip, port=port, timeout=)
client.connect():
ConnectionError()
:
data = {: time.strftime(, time.gmtime())}
name, reg REGISTERS.items():
value = read_float32(client, reg[], reg[], unit_id)
data[name] = {: value, : reg[]}
data
:
client.close()
__name__ == :
reading = collect_meter_data()
(json.dumps(reading, indent=, ensure_ascii=))
Les EnPI permettent de normaliser la consommation par rapport à un facteur de production (tonnes, pièces, heures de marche) :
import pandas as pd
def calculate_enpi(energy_data: pd.DataFrame, production_column: str,
energy_column: str = "kwh") -> pd.DataFrame:
"""Calcule l'indicateur de performance énergétique (EnPI) et la ligne de base.
Args:
energy_data: DataFrame contenant les colonnes de temps, énergie et production.
production_column: Nom de la colonne de production (ex: 'tonnes', 'pieces').
energy_column: Nom de la colonne d'énergie consommée en kWh.
Returns:
pd.DataFrame: DataFrame enrichi avec les colonnes EnPI et ligne de base.
"""
df = energy_data.copy()
# Calcul de l'EnPI brut : kWh par unité de production
df["enpi"] = df[energy_column] / df[production_column].replace(0, float("nan"))
# Ligne de base énergétique (régression linéaire simple)
valid = df.dropna(subset=["enpi"])
if len(valid) >= 2:
coeffs = pd.np.polyfit(valid[production_column], valid[energy_column], 1)
df["baseline_kwh"] = coeffs[0] * df[production_column] + coeffs[1]
df["savings_kwh"] = df["baseline_kwh"] - df[energy_column]
df["savings_pct"] = (df["savings_kwh"] / df["baseline_kwh"]) * 100
else:
df["baseline_kwh"] = df[energy_column]
df["savings_kwh"] = 0.0
df["savings_pct"] = 0.0
return df
L'algorithme CUSUM (Cumulative Sum) détecte les changements progressifs de moyenne dans une série temporelle de consommation :
import numpy as np
def cusum_detection(values: np.ndarray, threshold: float = 5.0,
drift: float = 1.0) -> dict:
"""Applique l'algorithme CUSUM pour détecter les dérives de consommation.
Args:
values: Série de mesures de consommation.
threshold: Seuil de déclenchement d'alerte (sensibilité).
drift: Tolérance de dérive acceptable autour de la moyenne.
Returns:
dict: Résultat contenant les indices de dérive détectés et les cumuls.
"""
mean_val = np.mean(values)
cumsum_pos = np.zeros(len(values))
cumsum_neg = np.zeros(len(values))
alarms_high = []
alarms_low = []
for i in range(1, len(values)):
deviation = values[i] - mean_val
cumsum_pos[i] = max(0, cumsum_pos[i - 1] + deviation - drift)
cumsum_neg[i] = max(0, cumsum_neg[i - 1] - deviation - drift)
if cumsum_pos[i] > threshold:
alarms_high.append(i)
cumsum_pos[i] = 0 # Réinitialisation après alarme
if cumsum_neg[i] > threshold:
alarms_low.append(i)
cumsum_neg[i] = 0
return {
"mean_baseline": float(mean_val),
"high_drift_indices": alarms_high,
"low_drift_indices": alarms_low,
"cumsum_positive": cumsum_pos.tolist(),
"cumsum_negative": cumsum_neg.tolist(),
}
[Compteur PM5xxx] ──Modbus TCP──▶ [Script Python / Telegraf]
[Compteur PAC3200] ──Modbus TCP──▶ [sur passerelle Edge IOT2050]
[Compteur Janitza] ──Modbus TCP──▶ │
▼
[InfluxDB 2.x]
(Bucket: energy)
(Retention: 1 an)
│
▼
[Grafana Dashboard]
- Courbe de charge 24h
- EnPI temps réel
- Alertes CUSUM
- Répartition par atelier
from(bucket: "energy")
|> range(start: -24h)
|> filter(fn: (r) => r._measurement == "power_meter")
|> filter(fn: (r) => r._field == "active_power")
|> aggregateWindow(every: 1h, fn: mean, createEmpty: false)
|> yield(name: "hourly_avg_power")
Ordonnancement des octets (Byte Order) incorrect lors de la lecture Modbus :
1.5e+38 ou NaN).BB, BL, LB, LL).Compteur d'énergie totale qui redémarre à zéro après une coupure :
total_energy) se réinitialise lors d'un redémarrage du compteur, entraînant un pic négatif dans les calculs de consommation horaire.Facteur de puissance (cos φ) mal interprété :
active_power en kW) pour les calculs d'EnPI et surveiller séparément le facteur de puissance pour la compensation réactive.