Каталог Поиск 0 Сравнить 0 Закладки 0 Корзина Войти
Каталог
105082, Москва, ул. Фридриха Энгельса, 75с21, БЦ Бауманский ИТКОЛ
Пн - Пт: с 09-00 до 18-00 Сб: с 10-00 до 18-00 Вс: выходной
Страницы: 1 2 След.
RSS
как экспортировать карту топологии unifi, UniFi Protect
 
как экспортировать карту топологии unifi
 
Я нашёл способ хотя бы сохранить это в формате JSON :-) должно быть возможно преобразовать эту структуру в диаграмму plantuml. http://<unif-hostname>:<unifi-ui-port>/v2/api/site/default/topology
 
+1
 
Печать в PDF сработала у меня, потом обрезал PDF, чтобы убрать меню сбоку.
 
Просто нажмите ctrl+p и выберите печать в .pdf. Так вы получите экспорт высокого разрешения с возможностью масштабирования.
 
Продолжая вышесказанное, я написал простой и грубый скрипт на TypeScript, который конвертирует json, сохранённый в файле 'network_topology.json', в черновой SVG. Запускаю этот файл с помощью BunJS (самая быстрая замена nodejs): bun index.ts  
У меня работает. У вас могут быть свои результаты. Удачи!

import * as fs from 'fs';
import * as https from 'https';
import * as zlib from 'zlib';

interface Edge {
 downlinkMac: string;
 uplinkMac: string;
 type: string;
 rateMbps?: number;
 channel?: number;
 essid?: string;
 experienceScore?: number;
 protocol?: string;
 radioBand?: string;
}

interface Vertex {
 mac: string;
 name: string;
 type: string;
 model?: string;
 state?: number;
 wifiRadios?: Array<{
   channel: number;
   protocol: string;
   radioBand: string;
 }>;
}

interface TopologyData {
 edges: Edge[];
 vertices: Vertex[];
}

function generatePlantUML(data: TopologyData): string {
 let uml = '@startuml\n\n';
 uml += 'skinparam componentStyle uml2\n\n';

 // Создаём карту для хранения уникальных идентификаторов для каждого устройства
 const deviceMap = new Map<string, string>();

 // Добавляем устройства (вершины)
 data.vertices.forEach((vertex, index) => {
   const id = `device${index}`;
   deviceMap.set(vertex.mac, id);

   let deviceType = 'component';
   if (vertex.type === 'DEVICE') {
     deviceType = 'rectangle';
   } else if (vertex.type === 'CLIENT') {
     deviceType = 'node';
   }

   uml += `${deviceType} "${vertex.name}" as ${id}\n`;
 });

 uml += '\n';

 // Добавляем соединения (ребра)
 data.edges.forEach((edge) => {
   const downlinkId = deviceMap.get(edge.downlinkMac);
   const uplinkId = deviceMap.get(edge.uplinkMac);

   if (downlinkId && uplinkId) {
     let connectionLabel = edge.type;
     if (edge.rateMbps) {
       connectionLabel += ` ${edge.rateMbps}Mbps`;
     }
     if (edge.channel) {
       connectionLabel += ` Ch${edge.channel}`;
     }
     if (edge.protocol) {
       connectionLabel += ` ${edge.protocol}`;
     }

     uml += `${uplinkId} -- ${downlinkId} : "${connectionLabel}"\n`;
   }
 });

 uml += '\n@enduml';
 return uml;
}

function encode64(data: Buffer): string {
 let r = "";
 for (let i = 0; i < data.length; i += 3) {
   if (i + 2 === data.length) {
     r += append3bytes(data[i], data[i + 1], 0);
   } else if (i + 1 === data.length) {
     r += append3bytes(data[i], 0, 0);
   } else {
     r += append3bytes(data[i], data[i + 1], data[i + 2]);
   }
 }
 return r;
}

function append3bytes(b1: number, b2: number, b3: number): string {
 const c1 = b1 >> 2;
 const c2 = ((b1 & 0x3) << 4) | (b2 >> 4);
 const c3 = ((b2 & 0xF) << 2) | (b3 >> 6);
 const c4 = b3 & 0x3F;
 return encode6bit(c1 & 0x3F) +
   encode6bit(c2 & 0x3F) +
   encode6bit(c3 & 0x3F) +
   encode6bit(c4 & 0x3F);
}

function encode6bit(b: number): string {
 if (b < 10) {
   return String.fromCharCode(48 + b);
 }
 b -= 10;
 if (b < 26) {
   return String.fromCharCode(65 + b);
 }
 b -= 26;
 if (b < 26) {
   return String.fromCharCode(97 + b);
 }
 b -= 26;
 if (b === 0) {
   return '-';
 }
 if (b === 1) {
   return '_';
 }
 return '?';
}

function encodePlantUML(puml: string): string {
 const utf8Encoded = Buffer.from(puml, 'utf-8');
 const deflated = zlib.deflateRawSync(utf8Encoded, { level: 9 });
 return encode64(deflated);
}

function fetchSVG(encodedUML: string): Promise<string> {
 return new Promise((resolve, reject) => {
   const options = {
     hostname: 'www.plantuml.com',
     path: `/plantuml/svg/${encodedUML}`,
     method: 'GET',
   };

   const req = https.request(options, (res) => {
     let data = '';
     res.on('data', (chunk) => {
       data += chunk;
     });
     res.on('end', () => {
       if (res.statusCode === 200) {
         resolve(data);
       } else {
         reject(new Error(`HTTP Status Code: ${res.statusCode}, Body: ${data}`));
       }
     });
   });

   req.on('error', (error) => {
     reject(error);
   });

   req.end();
 });
}

async function main() {
 try {
   // Читаем и парсим JSON-данные
   const jsonData = fs.readFileSync('network_topology.json', 'utf-8');
   const topologyData: TopologyData = JSON.parse(jsonData);

   // Генерируем диаграмму PlantUML
   const plantUMLCode = generatePlantUML(topologyData);

   // Кодируем PlantUML для URL
   const encodedUML = encodePlantUML(plantUMLCode);

   // Запрашиваем SVG с сервера PlantUML
   const svgContent = await fetchSVG(encodedUML);

   // Записываем SVG в файл
   fs.writeFileSync('network_topology.svg', svgContent);

   console.log('SVG диаграмма успешно сгенерирована!');
 } catch (error) {
   console.error('Произошла ошибка:', error);
   if (error instanceof Error) {
     console.error('Сообщение об ошибке:', error.message);
   }
 }
}

main();
 
Пожалуйста, добавьте это.
 
нужна была эта опция
 
плюс один
 
Плюс один.
 
Плюс один!
 
@mobiletechltd Наверное, столько же лет уйдёт, чтобы топология стала стабильной и точной для всех.
 
Unifi, всё ещё жду. Сколько же это будет продолжаться — годы?
 
Мне пришлось сделать это для нашего CEO, а если бы была такая кнопка, это сэкономило бы кучу времени. Сеть большая, так что скриншот даже в 4K получился бесполезным.
 
Согласен. Экспорт топологии с cloud key должен был быть изначально включён в комплект. Зачем тогда эта функция, если с ней практически ничего нельзя сделать? Давайте, UI, мы все знаем, что ваши стандарты лучше, чем у конкурентов, так что давайте продолжать поднимать планку. Этот запрос на улучшение вполне разумен, так что надеемся, вы согласитесь и внедрите его без задержек.
 
@edwardvn, если ты хорошо разбираешься в html, можешь открыть инспектор в браузере и скопировать html для топологии.
 
Согласен, пожалуйста, сделайте так, чтобы это работало в интерфейсе!
 
Это было бы очень полезно. У меня в сети 19 коммутаторов и более 80 точек доступа, и мне действительно нужно передать топологию IT-консультанту, который для нас что-то делает. Скриншотов явно недостаточно.
 
Эта функция была бы полезной.
 
Для тех случаев, когда ваша топология действительно точная, а это случается не так уж часто. :)
Страницы: 1 2 След.
Читают тему (гостей: 1)