PyPNM / Device / EventLog
Source Files
- HTML/script:
visual/PyPNM/Device/EventLog.html - JSON sample:
visual/PyPNM/Device/EventLog.json
Preview
Preview is best-effort. Some templates may rely on Postman-specific APIs that are not yet shimmed.
Visualizer HTML/script source
// Postman Visualizer: Device/EventLog
// Last Update: 2026-02-25 06:01:33 MST
// Postman Visualizer - DOCSIS Event Log (Dark Mode)
// Layout: Table first, then useful stats below.
// Input JSON shape:
// {
// "mac_address": "aabbccddeeff",
// "status": 0,
// "message": null,
// "logs": [ { docsDevEvFirstTime, docsDevEvLastTime, docsDevEvCounts, docsDevEvLevel, docsDevEvId, docsDevEvText }, ... ]
// }
const template = `
<style>
body {
font-family: Arial, sans-serif;
padding: 18px;
background-color: #0f1220;
color: #eaeaea;
}
.header {
background-color: #151a2e;
border: 1px solid rgba(255,255,255,0.08);
padding: 14px 14px 10px 14px;
border-radius: 10px;
margin-bottom: 14px;
box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
.title {
font-size: 16px;
font-weight: 700;
margin: 0 0 8px 0;
color: #9fb4ff;
}
.meta {
display: flex;
flex-wrap: wrap;
gap: 10px;
margin-bottom: 8px;
}
.pill {
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 999px;
padding: 6px 10px;
font-size: 12px;
color: #eaeaea;
}
.pill b { color: rgba(234,234,234,0.85); font-weight: 700; }
.sub {
margin: 0;
font-size: 12px;
color: rgba(234,234,234,0.85);
}
.deviceInfoTable { width: 100%; border-collapse: collapse; font-size: 12px; }
.deviceInfoTable th, .deviceInfoTable td { border-top: 1px solid rgba(255,255,255,0.08); padding: 8px 6px; text-align: left; white-space: nowrap; }
.deviceInfoTable th { color: #9fb4ff; font-weight: 700; border-top: none; }
.card {
background-color: #151a2e;
border: 1px solid rgba(255,255,255,0.08);
border-radius: 10px;
padding: 12px;
margin-top: 14px;
box-shadow: 0 2px 8px rgba(0,0,0,0.35);
}
.card h3 {
margin: 0 0 8px 0;
font-size: 13px;
color: #9fb4ff;
}
table {
width: 100%;
border-collapse: collapse;
font-size: 12px;
}
th, td {
border-bottom: 1px solid rgba(255,255,255,0.08);
padding: 8px 6px;
text-align: left;
vertical-align: top;
}
th { color: #9fb4ff; font-weight: 700; }
.lvl {
font-weight: 700;
border-radius: 999px;
padding: 2px 8px;
display: inline-block;
border: 1px solid rgba(255,255,255,0.10);
background: rgba(255,255,255,0.06);
}
.lvl6 { color: #ff6b6b; border-color: rgba(255,107,107,0.35); background: rgba(255,107,107,0.12); }
.lvl5 { color: #ffcc66; border-color: rgba(255,204,102,0.35); background: rgba(255,204,102,0.12); }
.lvl4 { color: #8fd3ff; border-color: rgba(143,211,255,0.35); background: rgba(143,211,255,0.12); }
.lvl3 { color: #b8ffb0; border-color: rgba(184,255,176,0.35); background: rgba(184,255,176,0.10); }
.lvlX { color: rgba(234,234,234,0.85); }
.mono { font-family: ui-monospace, SFMono-Regular, Menlo, Monaco, Consolas, "Liberation Mono", "Courier New", monospace; }
.muted { color: rgba(234,234,234,0.75); }
.kpi {
display: grid;
grid-template-columns: repeat(4, minmax(0, 1fr));
gap: 10px;
}
.kpiItem {
background: rgba(255,255,255,0.06);
border: 1px solid rgba(255,255,255,0.08);
border-radius: 10px;
padding: 10px;
}
.kpiItem .k {
font-size: 11px;
color: rgba(234,234,234,0.80);
margin-bottom: 4px;
}
.kpiItem .v {
font-size: 16px;
font-weight: 800;
color: #eaeaea;
}
.kpiItem .h {
margin-top: 4px;
font-size: 11px;
color: rgba(159,180,255,0.95);
}
.split {
display: grid;
grid-template-columns: 1fr 1fr;
gap: 12px;
}
.list {
margin: 0;
padding-left: 18px;
font-size: 12px;
color: rgba(234,234,234,0.90);
}
.note {
font-size: 11px;
color: rgba(234,234,234,0.78);
margin-top: 8px;
}
.textCell {
max-width: 860px;
white-space: nowrap;
overflow: hidden;
text-overflow: ellipsis;
}
.textCell span {
cursor: help;
}
.nowrap { white-space: nowrap; }
</style>
<div class="card">
<h3>Device Info</h3>
<table class="deviceInfoTable">
<thead><tr><th>MacAddress</th><th>Model</th><th>Vendor</th><th>SW Version</th><th>HW Version</th><th>Boot ROM</th></tr></thead>
<tbody><tr><td class="mono">{{deviceInfo.macAddress}}</td><td>{{deviceInfo.MODEL}}</td><td>{{deviceInfo.VENDOR}}</td><td class="mono">{{deviceInfo.SW_REV}}</td><td class="mono">{{deviceInfo.HW_REV}}</td><td class="mono">{{deviceInfo.BOOTR}}</td></tr></tbody>
</table>
</div>
<div class="header">
<div class="title">DOCSIS Event Log</div>
<div class="meta">
<div class="pill"><b>MAC</b> <span class="mono">{{mac}}</span></div>
<div class="pill"><b>Status</b> {{statusText}}</div>
<div class="pill"><b>Raw Entries</b> {{rawCount}}</div>
<div class="pill"><b>Unique Entries</b> {{uniqCount}}</div>
<div class="pill"><b>Time Span</b> {{timeSpan}}</div>
</div>
{{#if message}}
<p class="sub">{{message}}</p>
{{/if}}
</div>
<div class="card">
<h3>Event Table (Deduped, Sorted By Time Asc)</h3>
<div class="sub">Columns include extracted fields (when present) from the event text.</div>
<table>
<thead>
<tr>
<th class="nowrap">First Time</th>
<th class="nowrap">Last Time</th>
<th class="nowrap">Level</th>
<th class="nowrap">Event ID</th>
<th class="nowrap">Counts</th>
<th class="nowrap">Event Type</th>
<th class="nowrap">Chan ID</th>
<th class="nowrap">Profile</th>
<th class="nowrap">DSID</th>
<th class="nowrap">CMTS-MAC</th>
<th>Text</th>
</tr>
</thead>
<tbody>
{{#each rows}}
<tr>
<td class="nowrap muted">{{firstTime}}</td>
<td class="nowrap muted">{{lastTime}}</td>
<td class="nowrap"><span class="lvl {{lvlClass}}">L{{level}}</span></td>
<td class="nowrap mono">{{eventId}}</td>
<td class="nowrap">{{counts}}</td>
<td class="nowrap">{{eventType}}</td>
<td class="nowrap">{{chanId}}</td>
<td class="nowrap">{{profile}}</td>
<td class="nowrap">{{dsid}}</td>
<td class="nowrap mono">{{cmtsMac}}</td>
<td class="textCell">
<span title="{{fullText}}">{{textPreview}}</span>
</td>
</tr>
{{/each}}
</tbody>
</table>
<div class="note">
Note: duplicates are removed using a stable key built from (Event ID, Level, First/Last Time, Counts, Text).
</div>
</div>
<div class="card">
<h3>Useful Stats</h3>
<div class="kpi">
<div class="kpiItem">
<div class="k">Critical (L6)</div>
<div class="v">{{stats.level6}}</div>
<div class="h">Unique events at level 6</div>
</div>
<div class="kpiItem">
<div class="k">Warning (L5)</div>
<div class="v">{{stats.level5}}</div>
<div class="h">Unique events at level 5</div>
</div>
<div class="kpiItem">
<div class="k">Earliest</div>
<div class="v">{{stats.earliest}}</div>
<div class="h">First observable timestamp</div>
</div>
<div class="kpiItem">
<div class="k">Latest</div>
<div class="v">{{stats.latest}}</div>
<div class="h">Last observable timestamp</div>
</div>
</div>
<div style="height: 12px;"></div>
<div class="split">
<div class="kpiItem">
<div class="k">Top Event IDs By Total Counts</div>
<ol class="list">
{{#each stats.topEventIds}}
<li><span class="mono">{{id}}</span> — {{sumCounts}} counts ({{occurrences}} unique)</li>
{{/each}}
</ol>
</div>
<div class="kpiItem">
<div class="k">Level Distribution (Unique)</div>
<ul class="list">
<li><span class="lvl lvl6">L6</span> {{stats.level6}}</li>
<li><span class="lvl lvl5">L5</span> {{stats.level5}}</li>
<li><span class="lvl lvl4">L4</span> {{stats.level4}}</li>
<li><span class="lvl lvl3">L3</span> {{stats.level3}}</li>
<li><span class="lvl lvlX">Other</span> {{stats.levelOther}}</li>
</ul>
<div class="note">
“Unique” means after dedupe, one row per unique event key.
</div>
</div>
</div>
</div>
`;
function normalizeMac(mac) {
if (!mac || typeof mac !== 'string') return 'N/A';
const s = mac.trim();
if (s.includes(':')) return s.toLowerCase();
if (s.length !== 12) return s;
return s.toLowerCase().match(/.{1,2}/g).join(':');
}
function parseIsoTime(s) {
if (!s || typeof s !== 'string') return { ms: null, text: 'N/A' };
const ms = Date.parse(s);
if (!isFinite(ms)) return { ms: null, text: s };
return { ms, text: s };
}
function safeStr(v, fallback) {
if (v === undefined || v === null) return fallback;
return String(v);
}
function clipText(s, maxLen) {
if (!s || typeof s !== 'string') return '';
if (s.length <= maxLen) return s;
return s.slice(0, maxLen - 1) + '…';
}
function extractField(re, text) {
if (!text) return null;
const m = text.match(re);
if (!m) return null;
return m[1] !== undefined ? m[1] : null;
}
function levelClass(level) {
if (level === 6) return 'lvl6';
if (level === 5) return 'lvl5';
if (level === 4) return 'lvl4';
if (level === 3) return 'lvl3';
return 'lvlX';
}
function constructVisualizerPayload() {
const r = pm.response.json();
const device = (r.device && typeof r.device === "object") ? r.device : {};
const sys = (device.system_description && typeof device.system_description === "object") ? device.system_description : {};
const mac = normalizeMac(device.mac_address);
const status = (r.status !== undefined && r.status !== null) ? r.status : 'N/A';
const statusText = status === 0 ? 'Success' : String(status);
const message = r.message ? String(r.message) : '';
const logsRaw = Array.isArray(r.logs) ? r.logs : [];
const rawCount = logsRaw.length;
// Dedup: stable key from core fields
const seen = new Set();
const uniq = [];
for (let i = 0; i < logsRaw.length; i++) {
const e = logsRaw[i] || {};
const k = [
safeStr(e.docsDevEvId, ''),
safeStr(e.docsDevEvLevel, ''),
safeStr(e.docsDevEvFirstTime, ''),
safeStr(e.docsDevEvLastTime, ''),
safeStr(e.docsDevEvCounts, ''),
safeStr(e.docsDevEvText, '')
].join('|');
if (seen.has(k)) continue;
seen.add(k);
uniq.push(e);
}
// Normalize rows, parse times, and sort (FirstTime asc, then LastTime asc, then EventID)
const rowsNorm = uniq.map((e) => {
const ft = parseIsoTime(e.docsDevEvFirstTime);
const lt = parseIsoTime(e.docsDevEvLastTime);
const level = (typeof e.docsDevEvLevel === 'number') ? e.docsDevEvLevel : parseInt(e.docsDevEvLevel, 10);
const eventId = safeStr(e.docsDevEvId, 'N/A');
const counts = (typeof e.docsDevEvCounts === 'number') ? e.docsDevEvCounts : parseInt(e.docsDevEvCounts, 10);
const text = safeStr(e.docsDevEvText, '');
// Extract common fields from docsDevEvText (best-effort)
const eventType = extractField(/Event Type Code:\s*([0-9]+)\s*;/i, text) || 'N/A';
const chanId = extractField(/Chan ID:\s*([0-9]+)\s*;/i, text) || extractField(/US Chan ID:\s*([0-9]+)\s*;/i, text) || 'N/A';
const profile = extractField(/Profile ID:\s*([0-9]+)\s*;/i, text) || extractField(/New Profile:\s*([0-9]+)\s*;/i, text) || 'N/A';
const dsid = extractField(/DSID:\s*([0-9A-Za-z\/]+)\s*;/i, text) || 'N/A';
const cmtsMac = extractField(/CMTS-MAC=([0-9a-fA-F:]{17}|[0-9a-fA-F]{12})\s*;/, text) || 'N/A';
const cmtsMacNorm = (cmtsMac !== 'N/A') ? normalizeMac(cmtsMac) : 'N/A';
return {
firstMs: ft.ms,
lastMs: lt.ms,
firstTime: ft.text,
lastTime: lt.text,
level: isFinite(level) ? level : 'N/A',
lvlClass: levelClass(level),
eventId,
counts: isFinite(counts) ? counts : safeStr(e.docsDevEvCounts, 'N/A'),
eventType,
chanId,
profile,
dsid,
cmtsMac: cmtsMacNorm,
fullText: text,
textPreview: clipText(text, 120)
};
});
const timeSortKey = (ms) => (typeof ms === 'number' && isFinite(ms)) ? ms : Number.POSITIVE_INFINITY;
rowsNorm.sort((a, b) => {
const af = timeSortKey(a.firstMs);
const bf = timeSortKey(b.firstMs);
if (af !== bf) return af - bf;
const al = timeSortKey(a.lastMs);
const bl = timeSortKey(b.lastMs);
if (al !== bl) return al - bl;
if (a.eventId !== b.eventId) return String(a.eventId).localeCompare(String(b.eventId));
return 0;
});
// Stats: levels (unique rows)
const lvlCounts = { 3: 0, 4: 0, 5: 0, 6: 0, other: 0 };
let earliestMs = null;
let latestMs = null;
for (let i = 0; i < rowsNorm.length; i++) {
const r0 = rowsNorm[i];
const lvl = r0.level;
if (lvl === 6) lvlCounts[6] += 1;
else if (lvl === 5) lvlCounts[5] += 1;
else if (lvl === 4) lvlCounts[4] += 1;
else if (lvl === 3) lvlCounts[3] += 1;
else lvlCounts.other += 1;
const msCandidates = [r0.firstMs, r0.lastMs].filter((x) => typeof x === 'number' && isFinite(x));
for (let j = 0; j < msCandidates.length; j++) {
const ms = msCandidates[j];
if (earliestMs === null || ms < earliestMs) earliestMs = ms;
if (latestMs === null || ms > latestMs) latestMs = ms;
}
}
const fmtIso = (ms) => {
if (ms === null || !isFinite(ms)) return 'N/A';
try { return new Date(ms).toISOString(); } catch (_) { return 'N/A'; }
};
const timeSpan = (() => {
if (earliestMs === null || latestMs === null) return 'N/A';
const sec = Math.max(0, Math.floor((latestMs - earliestMs) / 1000));
const days = Math.floor(sec / 86400);
const hrs = Math.floor((sec % 86400) / 3600);
const mins = Math.floor((sec % 3600) / 60);
const s = sec % 60;
const parts = [];
if (days) parts.push(days + 'd');
if (days || hrs) parts.push(hrs + 'h');
if (days || hrs || mins) parts.push(mins + 'm');
parts.push(s + 's');
return parts.join(' ');
})();
// Top Event IDs by total counts (sum docsDevEvCounts)
const byId = {};
for (let i = 0; i < rowsNorm.length; i++) {
const ev = rowsNorm[i];
const id = String(ev.eventId);
const c = (typeof ev.counts === 'number' && isFinite(ev.counts)) ? ev.counts : parseInt(ev.counts, 10);
const add = isFinite(c) ? c : 0;
if (!byId[id]) byId[id] = { id, sumCounts: 0, occurrences: 0 };
byId[id].sumCounts += add;
byId[id].occurrences += 1;
}
const topEventIds = Object.keys(byId)
.map((k) => byId[k])
.sort((a, b) => (b.sumCounts - a.sumCounts) || (b.occurrences - a.occurrences) || a.id.localeCompare(b.id))
.slice(0, 8);
return {
mac,
statusText,
message,
rawCount,
uniqCount: rowsNorm.length,
timeSpan,
deviceInfo: {
macAddress: mac || 'N/A',
MODEL: sys.MODEL || 'N/A',
VENDOR: sys.VENDOR || 'N/A',
SW_REV: sys.SW_REV || 'N/A',
HW_REV: sys.HW_REV || 'N/A',
BOOTR: sys.BOOTR || 'N/A'
},
rows: rowsNorm.map((rw) => ({
firstTime: rw.firstTime,
lastTime: rw.lastTime,
level: rw.level,
lvlClass: rw.lvlClass,
eventId: rw.eventId,
counts: rw.counts,
eventType: rw.eventType,
chanId: rw.chanId,
profile: rw.profile,
dsid: rw.dsid,
cmtsMac: rw.cmtsMac,
fullText: rw.fullText,
textPreview: rw.textPreview
})),
stats: {
level6: lvlCounts[6],
level5: lvlCounts[5],
level4: lvlCounts[4],
level3: lvlCounts[3],
levelOther: lvlCounts.other,
earliest: fmtIso(earliestMs),
latest: fmtIso(latestMs),
topEventIds
}
};
}
pm.visualizer.set(template, constructVisualizerPayload());
Sample JSON payload
{
"system_description": {
"HW_REV": "1.0",
"VENDOR": "LANCity",
"BOOTR": "NONE",
"SW_REV": "1.0.0",
"MODEL": "LCPET-3"
},
"status": 0,
"message": null,
"device": {
"mac_address": "aabbccddeeff",
"system_description": {
"HW_REV": "1.0",
"VENDOR": "LANCity",
"BOOTR": "NONE",
"SW_REV": "1.0.0",
"MODEL": "LCPET-3"
}
},
"logs": [
{
"docsDevEvFirstTime": "2026-02-18T09:31:57",
"docsDevEvLastTime": "2026-02-18T09:31:57",
"docsDevEvCounts": 4,
"docsDevEvLevel": 3,
"docsDevEvId": 82000700,
"docsDevEvText": "Unicast Ranging Received Abort Response - initializing MAC;CM-MAC=aa:bb:cc:dd:ee:ff;CMTS-MAC=aa:bb:cc:dd:ee:ff;CM-QOS=1.1;CM-VER=4.0;"
},
{
"docsDevEvFirstTime": "2025-02-18T01:01:14",
"docsDevEvLastTime": "2025-02-18T01:01:14",
"docsDevEvCounts": 1,
"docsDevEvLevel": 5,
"docsDevEvId": 90000000,
"docsDevEvText": "MIMO Event MIMO: Stored MIMO=-1 post cfg file MIMO=-1;CM-MAC=aa:bb:cc:dd:ee:ff;CMTS-MAC=aa:bb:cc:dd:ee:ff;CM-QOS=1.1;CM-VER=4.0;"
},
{
"docsDevEvFirstTime": "2025-02-18T01:01:15",
"docsDevEvLastTime": "2025-02-18T01:01:15",
"docsDevEvCounts": 1,
"docsDevEvLevel": 5,
"docsDevEvId": 73050400,
"docsDevEvText": "REG-RSP-MP Mismatch Between Calculated Value for P1.6hi Compared to CCAP Provided Value;CM-MAC=aa:bb:cc:dd:ee:ff;CMTS-MAC=aa:bb:cc:dd:ee:ff;CM-QOS=1.1;CM-VER=4.0;"
},
{
"docsDevEvFirstTime": "2025-02-18T01:01:15",
"docsDevEvLastTime": "2025-02-18T01:01:15",
"docsDevEvCounts": 3,
"docsDevEvLevel": 5,
"docsDevEvId": 82001200,
"docsDevEvText": "RNG-RSP CCAP Commanded Power in Excess of 6 dB Below the Value Corresponding to the Top of the DRW;CM-MAC=aa:bb:cc:dd:ee:ff;CMTS-MAC=aa:bb:cc:dd:ee:ff;CM-QOS=1.1;CM-VER=4.0;"
},
{
"docsDevEvFirstTime": "2025-02-18T01:01:44",
"docsDevEvLastTime": "2025-02-18T01:01:49",
"docsDevEvCounts": 2,
"docsDevEvLevel": 6,
"docsDevEvId": 67061601,
"docsDevEvText": "US profile assignment change. US Chan ID: 42; Previous Profile: 12; New Profile: 6.;CM-MAC=aa:bb:cc:dd:ee:ff;CMTS-MAC=aa:bb:cc:dd:ee:ff;CM-QOS=1.1;CM-VER=4.0;"
},
{
"docsDevEvFirstTime": "2025-02-18T01:02:01",
"docsDevEvLastTime": "2025-02-18T01:02:01",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:02:01",
"docsDevEvLastTime": "2025-02-18T01:02:01",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:02:28",
"docsDevEvLastTime": "2025-02-18T01:02:28",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:02:28",
"docsDevEvLastTime": "2025-02-18T01:02:28",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:02:50",
"docsDevEvLastTime": "2025-02-18T01:02:50",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:02:50",
"docsDevEvLastTime": "2025-02-18T01:02:50",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:05",
"docsDevEvLastTime": "2025-02-18T01:03:05",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:05",
"docsDevEvLastTime": "2025-02-18T01:03:05",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:20",
"docsDevEvLastTime": "2025-02-18T01:03:20",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:20",
"docsDevEvLastTime": "2025-02-18T01:03:20",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:37",
"docsDevEvLastTime": "2025-02-18T01:03:37",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:37",
"docsDevEvLastTime": "2025-02-18T01:03:37",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:53",
"docsDevEvLastTime": "2025-02-18T01:03:53",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 69010100,
"docsDevEvText": "SW Download INIT - Via NMS"
},
{
"docsDevEvFirstTime": "2025-02-18T01:03:53",
"docsDevEvLastTime": "2025-02-18T01:03:53",
"docsDevEvCounts": 1,
"docsDevEvLevel": 4,
"docsDevEvId": 69020100,
"docsDevEvText": "Improper Code File Controls"
},
{
"docsDevEvFirstTime": "2025-02-18T01:06:59",
"docsDevEvLastTime": "2025-02-18T01:06:59",
"docsDevEvCounts": 1,
"docsDevEvLevel": 6,
"docsDevEvId": 67061601,
"docsDevEvText": "US profile assignment change. US Chan ID: 42; Previous Profile: 6; New Profile: 5.;CM-MAC=aa:bb:cc:dd:ee:ff;CMTS-MAC=aa:bb:cc:dd:ee:ff;CM-QOS=1.1;CM-VER=4.0;"
}
]
}