ソース情報
- リポジトリ
- JohnNuwan/EVA_CORE
- ソースの最終更新活動
- 2026年7月18日 08:30
- 検出された SKILL.md の言語
- フランス語
- スター
- 0
- フォーク
- 0
インストール方法
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
ソースファイルを確認
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
メニュー
デフォルトでは、最初にソースを確認する Prompt が選択されています。直接コマンドに切り替えるか、ローカルコピーをダウンロードすることもできます。
インストールを決める前に、SKILL.md と SkillsMP に表示されている付属ファイルをお読みください。
Codex または Claude でインストール この Prompt をコピーして Codex、Claude、または他のアシスタントに貼り付けると、Skill ページを確認してインストールできます。
直接コマンドでは確認用 Prompt が省略されます。実行前にソースを確認してください。
npx skills add https://github.com/JohnNuwan/EVA_CORE --skill siemens-auditコマンドは1行のまま表示されます。コピー前に横へスクロールして全体を確認してください。
ローカルで確認しますか?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 | siemens-audit |
| description | Extraire des données d'audit Siemens à partir de PDF. |
| version | 2.0.0 |
| author | EVA |
| license | Privée EVA St-Étienne |
| platforms | ["linux","macos","windows"] |
| metadata | {"EVA":{"tags":["industrial-automation","siemens","audit","pdf-parsing","data-extraction","python","pypdf","eph","external-exchanges","ids"],"related_skills":["industrial-documents","automation-linter","plc-diagnostic"]}} |
Cette compétence guide l'extraction structurée de données depuis des documents d'audit industriels Siemens (généralement au format PDF) vers un format texte standardisé. Elle cible spécifiquement deux sections critiques des rapports d'audit :
Ces documents d'audit sont produits par les outils Siemens (ex: SIMATIC IDS, Industrial Cyber Security Assessment) et servent à cartographier les flux de données et les communications entre systèmes d'automatisation.
Les fichiers PDF d'audit posent plusieurs défis d'extraction :
Pour surmonter ces limitations, cette compétence utilise la bibliothèque pypdf sous Python.
À utiliser lorsque l'utilisateur demande :
client_data/EPH/).plc-diagnostic).pypdfimport pypdf
import re
from pathlib import Path
def extract_text_from_pdf(pdf_path: str) -> str:
"""Extrait le texte brut de toutes les pages d'un fichier PDF.
Args:
pdf_path: Chemin absolu ou relatif vers le fichier PDF.
Returns:
str: Texte concaténé de toutes les pages, avec séparateurs de pages.
"""
reader = pypdf.PdfReader(pdf_path)
pages_text = []
for i, page in enumerate(reader.pages):
text = page.extract_text()
if text and text.strip():
# Nettoyage des espaces multiples
text = re.sub(r'\s+', ' ', text)
pages_text.append(f"--- PAGE {i+1} ---\n{text}")
return "\n".join(pages_text)
def extract_sections(text: str) -> dict:
"""Détecte et sépare les sections 1.5 et 2.5 du texte extrait.
Args:
text: Texte brut extrait du PDF.
Returns:
dict: Dictionnaire avec les clés 'section_1_5', 'section_2_5', 'other'.
"""
sections = {'section_1_5': '', 'section_2_5': '', 'other': ''}
# Patterns de détection des sections
patterns = {
'section_1_5': r'(?i)(?:section\s*1\.5|1\.5\s+EPH-EM|EPH[-\s]EM\s+Communications)',
'section_2_5': r'(?i)(?:section\s*2\.5|2\.5\s+External\s+Exchanges|External\s+Exchanges)',
}
# Logique de découpage par sections
# (implémentation adaptée au format réel des documents)
for key, pattern in patterns.items():
match = re.search(pattern, text)
if match:
start = match.start()
# Chercher la section suivante pour la fin
next_section = None
for other_key, other_pattern in patterns.items():
if other_key != key:
other_match = re.search(other_pattern, text[start + len(match.group()):])
if other_match:
next_section = start + len(match.group()) + other_match.start()
break
sections[key] = text[start:next_section] if next_section else text[start:]
sections
Cette section répertorie les échanges de signaux externes, en particulier de type « eph to / from eph ».
'eph to / from eph'.610C5_P_PCIP_BTL_2).E56_90_IDS851_An3_V00). Tronquer tout titre supplémentaire ou extension (.md, .pdf).FILENAME: [Nom propre nettoyé]
INSTANCE_SOURCE: [Titre exact du document]
- Instance_Target: [Vrai nom cible trouvé]
- Type: eph to / from eph
def extract_external_exchanges(text: str, filename: str) -> list[dict]:
"""Extrait les échanges externes (Section 2.5) du texte PDF.
Args:
text: Texte de la Section 2.5.
filename: Nom du fichier source nettoyé.
Returns:
list[dict]: Liste des échanges externes extraits.
"""
exchanges = []
lines = text.split('\n')
# Nettoyage du nom de fichier
clean_filename = re.sub(r'\s*[-–—].*$', '', filename)
clean_filename = re.sub(r'\.(pdf|md)$', '', clean_filename).strip()
# Recherche du titre du document (généralement en haut de section)
doc_title = ""
for line in lines[:20]:
if 'INSTANCE' in line.upper() or 'DOCUMENT' in line.upper():
doc_title = line.strip()
break
# Parsing du tableau des échanges
current_table = False
for i, line in enumerate(lines):
# Détection d'une ligne de tableau significative
if re.search(r'eph\s+to\s+/\s+from\s+eph', line, re.IGNORECASE):
# Extraction des instances
parts = line.split('|')
if len(parts) >= 2:
source = parts[0].strip()
target = parts[1].strip()
target.lower():
target = resolve_note(target, lines[i:i+])
target target.upper() != :
exchanges.append({
: clean_filename,
: doc_title clean_filename,
: target,
:
})
exchanges
() -> :
line context_lines:
= re.search(, line)
:
.group()
note_ref
Cette section détaille les communications internes entre les équipements EPH (Electrical Power & Hydraulic) et EM (Equipment Module).
664C6_E_B_INLET ou 664C6_E_B_Outlet).E56_90_IDSxxx_Anxx_Vxx). Supprimer tout texte après un tiret - et les extensions de fichier.*) dans la colonne « EMT » ET une valeur valide dans « Instance Tag ».EPH-EM.FILENAME: [Préfixe propre nettoyé]
INSTANCE_SOURCE: [Titre exact du document]
- Instance_Target: [Target Instance trouvé dans Instance Tag]
- Type: EPH-EM
FILENAME: E56_90_IDS851_An3_V00
INSTANCE_SOURCE: E56_90 - System Overview IDS851_An3_V00
- Instance_Target: 664C6_E_B_INLET
- Type: EPH-EM
FILENAME: E56_90_IDS851_An3_V00
INSTANCE_SOURCE: E56_90 - System Overview IDS851_An3_V00
- Instance_Target: 664C6_E_B_OUTLET
- Type: EPH-EM
Ignorer les notes en bas de tableau :
"See note below" comme cible d'instance dans le résultat final.[0-9A-Z_]+ après la note.Garder des extensions ou des titres dans FILENAME :
FILENAME: E56_90_IDS851_An3_V00 - MBR.pdf-, —, ou –. Supprimer .pdf, .md. Résultat attendu : FILENAME: E56_90_IDS851_An3_V00.Confusion entre le type d'échange :
Type: eph to / from ephType: EPH-EMOCR imparfaite sur les PDF scannés :
Erreur : Les PDF scannés (non natifs) produisent du texte avec des caractères mal reconnus, rendant les motifs regex inefficaces.
Correction : Vérifier la qualité du texte extrait. Si le texte contient trop d'artefacts, suggérer d'utiliser un OCR (Tesseract) en amont :
# Détection de qualité OCR
def is_text_quality_acceptable(text: str) -> bool:
"""Vérifie si le texte extrait est exploitable (>70% de mots valides)."""
words = text.split()
valid = sum(1 for w in words if re.match(r'^[A-Za-z0-9_\-\.]+$', w))
(words) > (valid / (words)) >
pypdf installée dans le .venv du projet.pdfplumber est installé pour les tableaux complexes avec cellules fusionnées..pdf, .md et des textes après tiret).* dans la colonne EMT.Tableaux avec cellules fusionnées :
Erreur : pypdf extrait les cellules fusionnées comme du texte plat, perdant la structure ligne/colonne.
Correction : Utiliser pdfplumber en complément pour les tableaux complexes :
pip install pdfplumber
import pdfplumber
with pdfplumber.open(pdf_path) as pdf:
for page in pdf.pages:
tables = page.extract_tables()
for table in tables:
for row in table:
print(row)