Faceplates: USW Pro Max 24 PoE and 48 PoE #29
@@ -704,6 +704,16 @@ gandalf/
|
||||
4. Restart monitor: `systemctl restart gandalf-monitor`
|
||||
5. For SFP DOM / ethtool: ensure the host is SSH-accessible from the Pulse worker
|
||||
|
||||
### Faceplates included
|
||||
|
||||
UniFi gear drawn with live ports: UDM Pro (`UDMPRO`), USW Pro 24 PoE (`US24PRO`), USW Aggregation
|
||||
(`USL8A`), USW Flex (`USF5P`), USW Flex Mini (`USMINI`), USP PDU Pro (`USPPDUP`), UPS 2U Pro (`USPDA2B`),
|
||||
USW Pro Max 24 PoE (`USPM24P`, also `USPM24`) and USW Pro Max 48 PoE (`USPM48P`, also `USPM48`), plus the
|
||||
UniFi NVR Pro (`UNVRPRO`), which UniFi Network doesn't report and so is picked by Front drawing. The Pro
|
||||
Max switches also have Front drawing options, so a new switch draws correctly on the rack before it is
|
||||
adopted. If UniFi reports a Pro Max under a different model code, add it as another alias at the end of
|
||||
`static/faceplates.js`.
|
||||
|
||||
### Adding a New Device Faceplate
|
||||
|
||||
Find the UniFi model code on the device page, then add an entry to `FACEPLATES` in `static/faceplates.js`.
|
||||
|
||||
@@ -30,6 +30,8 @@ RACK_UNITS_MAX = 60
|
||||
CHASSIS = {
|
||||
'unvr-pro': 'UniFi NVR Pro (UNVR Pro)',
|
||||
'uacc-patch-24': 'UniFi Patch Panel Blank 24 (UACC-Rack-Panel-Patch-Blank-24)',
|
||||
'usw-pro-max-24-poe': 'UniFi Switch Pro Max 24 PoE (until UniFi reports it)',
|
||||
'usw-pro-max-48-poe': 'UniFi Switch Pro Max 48 PoE (until UniFi reports it)',
|
||||
'sliger-cx4712': 'Sliger CX4712 4U (10-bay)',
|
||||
'rosewill-rsv-l4500u': 'Rosewill RSV-L4500U 4U (15-bay)',
|
||||
'server-1u': 'Generic 1U server',
|
||||
|
||||
@@ -225,6 +225,12 @@ function fpQuadScreen(x, y, s) {
|
||||
</g>`;
|
||||
}
|
||||
|
||||
// The bar UniFi prints under a group of faster ports, with its speed ("2.5G", "10G")
|
||||
function fpSpeedBar(x0, x1, y, text) {
|
||||
return `<rect class="fp-speedbar" x="${x0}" y="${y - 3}" width="${x1 - x0}" height="3" rx="1.5"/>
|
||||
<text class="fp-label fp-label-sm" x="${(x0 + x1) / 2}" y="${y + 6}" text-anchor="middle">${text}</text>`;
|
||||
}
|
||||
|
||||
// The model name printed under a UniFi screen: centred on the screen, first word bold and
|
||||
// second word light ("USW Pro", "NVR Pro"), as on the real units. `bolt` adds the PoE mark.
|
||||
function fpModel(cx, y, bold, light = '', { size = 7.5, bolt = false } = {}) {
|
||||
@@ -350,6 +356,53 @@ const FACEPLATES = {
|
||||
},
|
||||
},
|
||||
|
||||
// USW Pro Max 24 PoE, laid out from the CC0 NetBox devicetype-library image
|
||||
// (ubiquiti-unifi-switch-pro-max-24-poe.front.png; jack centres measured from it):
|
||||
// one row of 24 RJ45 in three groups of 8 (17-24 are 2.5G), then 2 SFP+.
|
||||
USPM24P: {
|
||||
width: 1167, height: 117, frameClass: 'fp-scroll', scrollX: 560,
|
||||
label: 'USW Pro Max 24 PoE',
|
||||
legend: [...LEGEND_RJ45, ['white', '10G'], ['poe', 'PoE in use']],
|
||||
roles: { ...roleRange(1, 16, 'RJ45 1G'), ...roleRange(17, 24, 'RJ45 2.5G'), 25: 'SFP+', 26: 'SFP+' },
|
||||
ports: [
|
||||
...[118.5, 427, 734.5].flatMap((x0, g) => Array.from({ length: 8 }, (_, i) => {
|
||||
const x = x0 + i * 37.35;
|
||||
return { idx: g * 8 + i + 1, type: 'rj45', x, y: 74, scale: 1.1, label: [x, 100] };
|
||||
})),
|
||||
...[1030, 1071].map((x, i) => ({ idx: 25 + i, type: 'sfp', x, y: 62, w: 38, h: 27,
|
||||
led: [x + 19, 54], label: [x + 19, 100] })),
|
||||
],
|
||||
decor() {
|
||||
return `${fpVents([[97, 293], [301, 498], [506, 703], [710, 906], [914, 1110]], 9, 3)}
|
||||
${fpQuadScreen(14, 27, 60)}${fpModel(44, 103, 'USW', 'Pro Max', { bolt: true })}
|
||||
${[98, 407, 714].map(x => `<rect class="fp-block" x="${x}" y="53" width="303" height="36" rx="1"/>`).join('')}
|
||||
${fpSpeedBar(714, 1017, 107, '2.5G')}${fpSpeedBar(1030, 1109, 107, '10G')}
|
||||
${fpReset(1128, 101)}`;
|
||||
},
|
||||
},
|
||||
|
||||
// USW Pro Max 48 PoE, from ubiquiti-unifi-switch-pro-max-48-poe.front.png (CC0, NetBox):
|
||||
// two rows, odd ports on top, three groups of 16 (33-48 are 2.5G), then 4 SFP+ (49-52).
|
||||
USPM48P: {
|
||||
width: 1169, height: 114, frameClass: 'fp-scroll', scrollX: 560,
|
||||
label: 'USW Pro Max 48 PoE',
|
||||
legend: [...LEGEND_RJ45, ['white', '10G'], ['poe', 'PoE in use']],
|
||||
roles: { ...roleRange(1, 32, 'RJ45 1G'), ...roleRange(33, 48, 'RJ45 2.5G'), ...roleRange(49, 52, 'SFP+') },
|
||||
ports: [
|
||||
...rj45Pairs([122, 425.5, 731].flatMap(x0 => Array.from({ length: 8 }, (_, i) => x0 + i * 36.8)),
|
||||
{ top: 38, bottom: 68, topLabel: 15, bottomLabel: 97 }),
|
||||
...sfpPairs([1033, 1075], { first: 49, top: 23, bottom: 60, w: 37, h: 27, ledY: 56, ledGap: 9,
|
||||
topLabel: 15, bottomLabel: 97 }),
|
||||
],
|
||||
decor() {
|
||||
return `${fpVents([[97, 293], [301, 498], [506, 703], [710, 906], [914, 1110]], 7, 3)}
|
||||
${fpQuadScreen(14, 25, 60)}${fpModel(44, 101, 'USW', 'Pro Max', { bolt: true })}
|
||||
${[101, 405, 711].map(x => `<rect class="fp-block" x="${x}" y="19" width="298" height="70" rx="1"/>`).join('')}
|
||||
${fpSpeedBar(711, 1009, 104, '2.5G')}${fpSpeedBar(1033, 1112, 104, '10G')}
|
||||
${fpReset(1130, 99)}`;
|
||||
},
|
||||
},
|
||||
|
||||
// No quick start guide was available: layout from a reference image. LED colors
|
||||
// are taken from the SFP+ ports of the USW Pro 24 guide.
|
||||
USL8A: {
|
||||
@@ -585,3 +638,8 @@ function faceplateScrollLeft(model, frame) {
|
||||
const spec = FACEPLATES[model];
|
||||
return spec.scrollX ? (frame.scrollWidth / spec.width) * spec.scrollX : 0;
|
||||
}
|
||||
|
||||
// Same fronts under the other model codes UniFi uses for these switches (non-PoE variants
|
||||
// draw the same; PoE marks simply never show)
|
||||
FACEPLATES.USPM24 = FACEPLATES.USPM24P;
|
||||
FACEPLATES.USPM48 = FACEPLATES.USPM48P;
|
||||
|
||||
+6
-1
@@ -134,7 +134,12 @@ function genericServer(units, bays) {
|
||||
}
|
||||
|
||||
// Front drawings that are full faceplates in faceplates.js (same parts as the UniFi gear)
|
||||
const CHASSIS_FACEPLATES = { 'unvr-pro': 'UNVRPRO' };
|
||||
const CHASSIS_FACEPLATES = {
|
||||
'unvr-pro': 'UNVRPRO',
|
||||
// For a new switch before UniFi reports it (or under a model code not mapped yet)
|
||||
'usw-pro-max-24-poe': 'USPM24P',
|
||||
'usw-pro-max-48-poe': 'USPM48P',
|
||||
};
|
||||
|
||||
// The markup for one item's drawn front, or '' when the key is unknown
|
||||
function rackFrontSvg(key, ctx) {
|
||||
|
||||
@@ -1584,3 +1584,5 @@ body.fp-marks-off .fp-svg .fp-mark { display: none; }
|
||||
.rack-pp-bad .ua-mark { stroke: #e0312b; stroke-width: 3; }
|
||||
.rack-pp-doc .ua-mark { stroke: #4c5662; stroke-width: 2; }
|
||||
.rack-pp-port.rack-hl .ua-mark { fill: rgba(0,212,255,.25); stroke: #00b8e6; stroke-width: 3.5; }
|
||||
|
||||
.fp-speedbar { fill: #b3b5ba; }
|
||||
|
||||
@@ -368,4 +368,5 @@ class TestChassis:
|
||||
|
||||
def test_every_drawing_has_a_label(self):
|
||||
assert all(cs.CHASSIS.values())
|
||||
assert {'sliger-cx4712', 'rosewill-rsv-l4500u', 'unvr-pro', 'uacc-patch-24'} <= set(cs.CHASSIS)
|
||||
assert {'sliger-cx4712', 'rosewill-rsv-l4500u', 'unvr-pro', 'uacc-patch-24',
|
||||
'usw-pro-max-24-poe', 'usw-pro-max-48-poe'} <= set(cs.CHASSIS)
|
||||
|
||||
Reference in New Issue
Block a user