Перейти к содержимому

Расширение списка поддерживаемых устройств

Для того, чтобы система могла отображать детали оборудования, которого нет в списке поддерживаемых типов устройств, можно добавить новый тип оборудования по инструкции ниже.

Для работы с оборудованием у вас должен быть модуль устройств.

В модуле устройств есть директория device_config, её структура выглядит так:

Окно терминала
$ tree device_config/
device_config/
├── base_device_strategy.py
├── base.py
├── device_type_collection.py
├── expect_util.py
├── __init__.py
├── pon
│   ├── epon
│   │   ├── bdcom_p3310c.py
│   │   ├── epon_bdcom_expect.py
│   │   ├── epon_bdcom_fora.py
│   │   └── __init__.py
│   ├── gpon
│   │   ├── __init__.py
│   │   ├── olt_ztec320.py
│   │   ├── onu_fd511g
│   │   │   └── __init__.py
│   │   ├── onu_zte_f601
│   │   │   ├── __init__.py
│   │   │   ├── zte_f601_bridge_config.py
│   │   │   └── zte_f601_static.py
│   │   ├── onu_zte_f601_v2
│   │   │   ├── __init__.py
│   │   │   ├── zte_f601_bridge_config.py
│   │   │   └── zte_f601_static.py
│   │   ├── onu_zte_f660
│   │   │   ├── __init__.py
│   │   │   ├── zte_f660_dynamic_bridge_config.py
│   │   │   ├── zte_f660_router_config.py
│   │   │   └── zte_f660_static_bridge_config.py
│   │   ├── onu_zte_f660_v2
│   │   │   ├── __init__.py
│   │   │   ├── zte_f660_dynamic_bridge_config.py
│   │   │   ├── zte_f660_router_config.py
│   │   │   ├── zte_f660_static_bridge_config.py
│   │   │   └── zte_f660_vlan_dynamic_bridge_config.py
│   │   ├── zte_onu.py
│   │   └── zte_utils.py
│   ├── __init__.py
│   ├── pon_device_strategy.py
│   └── utils.py
└── switch
├── dlink
│   ├── dgs_1100_06me.py
│   ├── dgs_1100_10me.py
│   ├── dgs_3120_24sc.py
│   ├── dgs_3627g.py
│   ├── dlink_DGS1100_reboot.exp
│   └── __init__.py
├── eltex
│   ├── general.py
│   ├── __init__.py
│   └── mes5324a.py
├── huawei
│   ├── __init__.py
│   └── s2300.py
├── __init__.py
└── switch_device_strategy.py

Система может работать с 2мя типами устройств, с PON и Ethernet коммутаторами. Соответственно нас интересуют 2 модуля: pon и switch.

Для добавления новой реализации типа устройства нужно добавить подмодуль в одну из этих директорий.

Например, попробуем добавить новую реализацию коммутатора. В директории switch создадим файл new_switch.py. Наследуемся от интерфейса SwitchDeviceStrategy, и реализуем абстрактные методы родительского интерфейса.

from djing2.lib import safe_int
from devices.device_config.base_device_strategy import SNMPWorker
from devices.device_config.switch.switch_device_strategy import (
SwitchDeviceStrategy, PortType,
SwitchDeviceStrategyContext
)
from devices.device_config.base import (
Vlans, Vlan
)
# Уницальный номер типа устройства. Используется
# для хранения и понимания выбранного типа устройства с его логикой реализации.
# Можно не бояться добавить дубль, т.к. при старте система покажет ошибку, если встретятся
# 2 реализации с одинаковыми номерами.
DEVICE_UNIQUE_CODE = 18
class NewCustomSwitch(SwitchDeviceStrategy):
# Количество портов коммутатора
ports_len: int
# Можно подключать порты к учётным записям абонентов
has_attachable_to_customer = True
# Уникальный, в пределах типов устройств, короткий код устройства
tech_code = 'my_dev'
# Человекопонятное, короткое описание устройства
description = 'My custom switch device'
# Используется ли порт при авторизации с помощью option82
is_use_device_port = True
def get_ports(self) -> tuple[PortType, ...]:
# Попробуем получить список портов с помощью snmp:
# Можно, так же, вернуть и генератор.
# Это пример взятый из реализации для Dlink DGS.
dev = self.model_instance
with SNMPWorker(hostname=dev.ip_address, community=str(dev.man_passw)) as snmp:
ifs_ids = snmp.get_list(".1.3.6.1.2.1.10.7.2.1.1")
for num, if_id in enumerate(ifs_ids, 1):
if num > self.ports_len:
return
status = snmp.get_item(".1.3.6.1.2.1.2.2.1.7.%d" % snmp_num)
yield PortType(
num=safe_int(if_id),
name=snmp.get_item(".1.3.6.1.2.1.31.1.1.1.18.%d" % snmp_num),
status=status,
mac=snmp.get_item(".1.3.6.1.2.1.2.2.1.6.%d" % snmp_num),
speed=snmp.get_item(".1.3.6.1.2.1.2.2.1.5.%d" % snmp_num),
uptime=safe_int(snmp.get_item(".1.3.6.1.2.1.2.2.1.9.%d" % snmp_num)),
)
def read_all_vlan_info(self) -> Vlans:
# Возвращаем все вланы, которые есть на коммутаторе.
# Замените на имеющую смысл реализацию:)
# Возвращаем что-то итерируемое, генератор, список, кортеж...
return (
Vlan(vid=1, title='default', native=True, is_management=False),
Vlan(vid=2, title='management', native=False, is_management=True),
...
)
# И так далее, реализуйте все абстрактные методы.
# Можно посмотреть их в интерфейсе от которого наследуемся.
# В конце нужно зарегистрировать нашу реализацию в системе:
SwitchDeviceStrategyContext.add_device_type(DEVICE_UNIQUE_CODE, NewCustomSwitch)

Так же, чтоб код инициализировался, нужно передать сюда нить управления, для этого импортируйте модуль в файле __init__.py который должен лежать там же где вы создали вашу реализацию. Допишите в конце:

__init__.py
from .dlink import *
from .eltex import *
from .huawei import *
# Добавте импорт вашей реализации в конце
from .new_switch import NewCustomSwitch

В директории pon есть 2 субмодуля epon и gpon. В зависимости от типа вашего PON оборудования вы добавляете реализацию в соответствующий субмодуль.

Создайте в директории, например, epon, реализацию для OLT по аналогии с Ethernet коммутатором:

device_config/pon/epon/my_olt_device.py
from dataclasses import dataclass
from typing import Generator
from devices.device_config.pon.pon_device_strategy import (
PonOltDeviceStrategy,
PonOLTDeviceStrategyContext,
FiberDataClass, ONUdevPort
)
# Описание выше, по аналогии с коммутатором.
DEVICE_UNIQUE_CODE = 19
class MyCustomOLT(PonOltDeviceStrategy):
# Уникальный, в пределах типов устройств, короткий код устройства
tech_code = 'my_olt_dev'
# Человекопонятное, короткое описание устройства
description = 'My custom switch device'
# Количество pon портов
ports_len = 4
def scan_onu_list(self) -> Generator[ONUdevPort, None, None]:
# Собираем информацию о подключенных к pon портам onu,
# и возвращаем генератор.
...
def get_fibers(self) -> tuple[FiberDataClass, ...]:
# Собираем информацию о pon портах на olt
...
def get_device_name(self) -> str:
# Имя устройства
...
# И так далее, реализуйте все абстрактные методы.
# Можно посмотреть их в интерфейсе от которого наследуемся.
# И, как и с коммутатором, нужно зарегистрировать нашу реализацию в системе:
PonOLTDeviceStrategyContext.add_device_type(DEVICE_UNIQUE_CODE, MyCustomOLT)

И, так же как и с коммутатором, нужно передать нить управления для иницииализации кода новой реализации. Добавим импорт в __init__.py

device_config/pon/epon/__init__.py
from .bdcom_p3310c import BDCOM_P3310C
from .epon_bdcom_fora import EPON_BDCOM_FORA
# Добавте импорт вашей реализации в конце
from .my_olt_device import MyCustomOLT