You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Python(兼容Jython)跨设备JS脚本基线对比工具优化问询

脚本对比工具优化方案(适配Python 2.7/Jython)

一、对比流程优化

  • 增强ndiff输出解析:基于difflib.ndiff的输出,自定义逻辑将差异映射为新增、删除、修改三类明确类型,而非仅标记行号:
    • 以+开头的行标记为新增行
    • 以-开头的行标记为删除行
    • 成对出现的-和+行标记为修改行(明确原行与修改后行的对应关系)
  • 脚本预处理:对比前统一格式化JS脚本(正则去除多余空格/换行、统一缩进),避免格式差异被误判为逻辑变更;对基准脚本和设备脚本做相同标准化处理。
  • 按模块拆分对比:若JS脚本有明确的函数/模块划分,先拆分后逐块对比,输出时标注具体函数名,更精准定位变更位置。

二、审计输出丰富化

  • 结构化报告内容:每台设备的审计报告包含以下部分:
    • 设备基础信息:设备ID、部署地点、IP地址
    • 差异统计:新增行数、删除行数、修改行数
    • 详细差异清单:按变更类型分组展示,示例:
      设备ID: D1001 | 地点: 北京机房
      差异统计: 新增2行,删除1行,修改1行
      
      详细差异:
      1. 修改行
         基准脚本: function sendData() {
         设备脚本: function sendUpdatedData() {
      2. 删除行
         基准脚本: console.log("Debug mode enabled");
      3. 新增行
         设备脚本: var timestamp = new Date().getTime();
         设备脚本: payload.timestamp = timestamp;
      
  • 双格式输出:同时生成易读的纯文本报告(用于邮件)和JSON格式数据(方便后续自动化处理)。

三、自动化流程实现

  • 批量设备处理:编写循环逻辑批量拉取所有设备的运行脚本,用Jython线程池实现简单并发,提升处理效率。
  • 自动告警邮件:用Python 2.7标准库smtplib+email构建邮件,将审计报告作为正文;主题明确标记异常设备,比如[脚本告警] 设备D1001脚本与基准不符。
  • 异常过滤规则:配置忽略注释行变更、设置变更行数阈值,仅当差异达到阈值时发送邮件,减少误报。

四、Jython与Ignition适配注意事项

  • 严格遵循Python 2.7语法:用print语句而非函数、xrange替代range,统一UTF-8编码避免中文乱码。
  • 利用Ignition内置API:调用system.device.listDevices()批量获取设备信息,借助Ignition日志系统记录审计过程。
  • 依赖轻量化:仅使用Python标准库,避免引入第三方库(Jython对第三方库支持有限)。

核心代码片段

import difflib
import smtplib
from email.mime.text import MIMEText

def compare_scripts(base_script, device_script):
    # 预处理:统一格式并过滤空行
    base_lines = [line.strip() for line in base_script.splitlines() if line.strip()]
    device_lines = [line.strip() for line in device_script.splitlines() if line.strip()]
    
    diff = difflib.ndiff(base_lines, device_lines)
    diff_result = []
    current_change = {}
    
    for line in diff:
        if line.startswith('- '):
            current_change['base'] = line[2:]
        elif line.startswith('+ '):
            if 'base' in current_change:
                # 标记修改行
                diff_result.append({
                    'type': 'modified',
                    'base_line': current_change['base'],
                    'device_line': line[2:]
                })
                current_change = {}
            else:
                # 标记新增行
                diff_result.append({
                    'type': 'added',
                    'device_line': line[2:]
                })
        elif line.startswith('? '):
            continue
        else:
            if current_change:
                # 标记删除行
                diff_result.append({
                    'type': 'removed',
                    'base_line': current_change['base']
                })
                current_change = {}
    # 处理剩余的删除行
    if current_change:
        diff_result.append({
            'type': 'removed',
            'base_line': current_change['base']
        })
    return diff_result

def generate_report(device_info, diffs):
    report = f"设备ID: {device_info['id']} | 地点: {device_info['location']}\n"
    stats = {'added': 0, 'removed': 0, 'modified': 0}
    for d in diffs:
        stats[d['type']] += 1
    report += f"差异统计: 新增{stats['added']}行,删除{stats['removed']}行,修改{stats['modified']}行\n\n"
    report += "详细差异:\n"
    for idx, d in enumerate(diffs, 1):
        if d['type'] == 'modified':
            report += f"{idx}. 修改行\n"
            report += f"   基准脚本: {d['base_line']}\n"
            report += f"   设备脚本: {d['device_line']}\n"
        elif d['type'] == 'removed':
            report += f"{idx}. 删除行\n"
            report += f"   基准脚本: {d['base_line']}\n"
        else:
            report += f"{idx}. 新增行\n"
            report += f"   设备脚本: {d['device_line']}\n"
    return report

def send_alert_email(report, to_email):
    msg = MIMEText(report, 'plain', 'utf-8')
    msg['Subject'] = '[脚本异常告警] 设备脚本与基准存在差异'
    msg['From'] = 'scada-audit@yourcompany.com'
    msg['To'] = to_email
    
    smtp_server = 'smtp.yourcompany.com'
    smtp_port = 25
    try:
        server = smtplib.SMTP(smtp_server, smtp_port)
        server.sendmail(msg['From'], msg['To'].split(','), msg.as_string())
        server.quit()
    except Exception as e:
        print(f"邮件发送失败: {str(e)}")

内容的提问来源于stack exchange,提问作者CKemp

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.06.29 06:55:04