Auteur Sujet: [Résolu] FTTH Sosh atténuation à -30dB  (Lu 1818 fois)

0 Membres et 1 Invité sur ce sujet

Kana-chan

  • Abonné Orange Fibre
  • *
  • Messages: 871
  • Antibes (06)
[Résolu] FTTH Sosh atténuation à -30dB
« Réponse #12 le: 12 août 2025 à 01:02:47 »
Félicitation !
Comme quoi, il ne faut rien lâcher pour se faire entendre !

simon

  • Abonné Orange Fibre
  • *
  • Messages: 1 761
[Résolu] FTTH Sosh atténuation à -30dB
« Réponse #13 le: 12 août 2025 à 08:03:05 »
Solide ton ONT :-)

Bien joué en tout cas. Tu m'as rendu curieux avec tes graphes, je vais mettre en place le script de scraping sous peu.

simon

  • Abonné Orange Fibre
  • *
  • Messages: 1 761
[Résolu] FTTH Sosh atténuation à -30dB
« Réponse #14 le: 13 août 2025 à 18:41:12 »
Pour info, sur l'interface web de mon HG8010H (fourni par Orange), j'ai dans la colonne "Reference Value" pour "RX Optical Power" une valeur de "-30 to -8 dBm".
Donc l'ONT semble pouvoir détecter un signal jusqu'à -30dBm. Au dessus de -8dBm, il serait probablement aveuglé.

Steph

  • Abonné K-Net
  • *
  • Messages: 8 500
  • La Balme de Sillingy 74
    • Uptime K-net
[Résolu] FTTH Sosh atténuation à -30dB
« Réponse #15 le: 13 août 2025 à 20:56:55 »
Pour la même ref, le mien,fourni par Covage, donne : -27 to -8 dBm

Manufacturer:Huawei Technologies Co., Ltd;
ProductClass:HG8010H;
SerialNumber:xxxxxxxxxxxxxx;
IP:xxxxxxxxx;
HWVer:AD5.A;
SWVer:V3R017C10S100;

simon

  • Abonné Orange Fibre
  • *
  • Messages: 1 761
[Résolu] FTTH Sosh atténuation à -30dB
« Réponse #16 le: 14 août 2025 à 10:32:02 »
L'ONT d'Orange a un firmware custom (marqué FT dans l'une des pages, d'ailleurs) et le hardware version n'a pas la même forme chez moi. Difficile de savoir si c'est lié à un hardware différent, simplement à un paramètre software ou si ton ONT tiendrait jusqu'à -30dBm...

simon

  • Abonné Orange Fibre
  • *
  • Messages: 1 761
[Résolu] FTTH Sosh atténuation à -30dB
« Réponse #17 le: 14 août 2025 à 18:11:43 »
Si ca intéresse quelqu'un, j'ai repris le script python et l'ai un peu amélioré pour gérer les exceptions et collecter plus de metrics (dont le statut d'enregistrement sur l'arbre):

#!/usr/bin/env python3
import socket
import requests
import base64
import time

## Default
#ont_host     = "192.168.100.1"
#ont_username = "root"
#ont_password = "adminHW"

## Orange custom
#ont_host     = "192.168.4.254"
#ont_username = "root"
#ont_password = "admin"

req_timeout_s   = 2

# User vars
ont_host        = "192.168.4.254"
ont_username    = "root"
ont_password    = "admin"
graphite_host   = "localhost"
graphite_port   = 2003
graphite_prefix = "ont0"

# precompute the password
ont_password = base64.b64encode(ont_password.encode())

# Python method to test if a string is a float
def isfloat(value):
  try:
    float(value)
    return True
  except ValueError:
    return False

# Build URL prefix
ont_urlprefix = "http://" + ont_host

carbon_socket = socket.socket(socket.AF_INET6, socket.SOCK_DGRAM)

# Start http session
ont_session = requests.Session()

starttime = time.monotonic()
session_active = False
print("running")

while True:
    graphite_data = []

    time.sleep(10.0 - ((time.monotonic() - starttime) % 10.0))
    starttime = time.monotonic()

    if session_active != True:
        # grab a session ID and authenticate to the ONT
        try:
            res = ont_session.post(ont_urlprefix + "/asp/GetRandCount.asp", timeout=req_timeout_s)
            res.close()
            if res.status_code != 200:
                raise Exception("non-200 status code")
        except Exception as e:
            print("failed to get session id: {:s}".format(str(e)))

            # try to login again on the next tick
            continue

        sid = res.text[-32:]

        headers = {"Cookie": "Cookie=body:Language:english:id=-1"}
        auth_data = {"UserName": ont_username, "PassWord": ont_password, "x.X_HW_Token": sid}
        try:
            res = ont_session.post(ont_urlprefix + "/login.cgi", headers=headers, data=auth_data, timeout=req_timeout_s)
            res.close()
            if res.status_code != 200:
                raise Exception("non-200 status code")
        except Exception as e:
            print("failed to execute login request: {:s}".format(str(e)))

            # try to login again on the next tick
            continue
 
        session_active = True

    # get optical transceiver stats
    try:
        res = ont_session.get(ont_urlprefix + "/html/amp/opticinfo/opticinfo.asp", timeout=req_timeout_s)
        res.close()
        if res.status_code != 200:
            raise Exception("non-200 status code")
        else:
            # mark the current time for metrics timestamping
            current_date = int(time.time())
           
            # parse the results
            for line in res.text.split("\n"):
              if line.startswith('var opticInfos = new Array'):
                opticInfos_split = line.split("\",\"")
                # ensure we have enough chunks to proceed
                if len(opticInfos_split) < 6:
                    break

                # tx power
                result_TxPower = opticInfos_split[1]
                if isfloat(result_TxPower):
                  graphite_data.append("{:s}.tx_power_dBm {:f} {:d}".format(graphite_prefix, float(result_TxPower), current_date))
           
                # rx power
                result_RxPower = opticInfos_split[2]
                if isfloat(result_RxPower):
                  graphite_data.append("{:s}.rx_power_dBm {:f} {:d}".format(graphite_prefix, float(result_RxPower), current_date))
           
                # voltage
                result_Voltage = opticInfos_split[3]
                if str(result_Voltage).isdigit():
                  graphite_data.append("{:s}.voltage_mV {:d} {:d}".format(graphite_prefix, int(result_Voltage), current_date))

                # bias current
                result_BiasCurrent = opticInfos_split[5]
                if str(result_BiasCurrent).isdigit():
                  graphite_data.append("{:s}.bias_current_mA {:d} {:d}".format(graphite_prefix, int(result_BiasCurrent), current_date))
           
           
                # temperature
                result_Temperature = opticInfos_split[4]
                if str(result_Temperature).isdigit():
                  graphite_data.append("{:s}.temperature_C {:d} {:d}".format(graphite_prefix, int(result_Temperature), current_date))
           
                break

    except Exception as e:
        print("failed to poll transceiver stats: {:s}".format(str(e)))

    # get device status
    try:
        res = ont_session.get(ont_urlprefix + "/html/ssmp/deviceinfo/deviceinfocut.asp", timeout=req_timeout_s)
        res.close()
        if res.status_code != 200:
            raise Exception("non-200 status code")
        else:
            # mark the current time right after reading the response
            current_date = int(time.time())

            lines_found = 0

            # parse results
            for line in res.text.split("\n"):
                if line.startswith('var ontInfos = new Array'):
                    lines_found += 1
                    ontInfos_split = line.split("\"")
                    # ensure we have enough chunks to proceed
                    if len(ontInfos_split) < 3:
                        continue

                    # ONT registration status
                    if len(ontInfos_split[5]) == 2 and ontInfos_split[5][0] == 'O' and ontInfos_split[5][1].isdigit():
                        graphite_data.append("{:s}.ont_registration_status {:d} {:d}".format(graphite_prefix, int(ontInfos_split[5][1]), current_date))

                    # ONT ID
                    if ontInfos_split[3].isdigit():
                        graphite_data.append("{:s}.ont_id {:d} {:d}".format(graphite_prefix, int(ontInfos_split[3]), current_date))

                elif line.startswith('var cpuUsed = '):
                    lines_found += 1
                    ontInfos_split = line.split("\'")
                    if len(ontInfos_split) != 3:
                        continue

                    # CPU used
                    if len(ontInfos_split[1]) >= 2 and ontInfos_split[1][-1] == '%' and ontInfos_split[1][0:-1].isdigit():
                        graphite_data.append("{:s}.cpu_used_pc {:d} {:d}".format(graphite_prefix, int(ontInfos_split[1][0:-1]), current_date))

                elif line.startswith('var memUsed = '):
                    lines_found += 1
                    ontInfos_split = line.split("\'")
                    if len(ontInfos_split) != 3:
                        continue

                    # memory used
                    if len(ontInfos_split[1]) >= 2 and ontInfos_split[1][-1] == '%' and ontInfos_split[1][0:-1].isdigit():
                        graphite_data.append("{:s}.memory_used_pc {:d} {:d}".format(graphite_prefix, int(ontInfos_split[1][0:-1]), current_date))

                if lines_found == 3:
                    break

    except Exception as e:
        print("failed to poll ONT status: {:s}".format(str(e)))

    # since the ONT replies with 200/OK to unauthenticated requests, treat the absence of
    # metrics as a signal to re-authenticate
    if len(graphite_data) == 0:
        print("no metrics, re-authenticating")
        session_active = False

        # logout
        try:
            ont_session.post(ont_urlprefix + "/logout.cgi?RequestFile=html/logout.html", timeout=req_timeout_s)
            res.close()
            if res.status_code != 200:
                raise Exception("non-200 status code")
        except Exception as e:
            print("failed to perform logout request: {:s}".format(str(e)))
        continue

    try:
        carbon_socket.sendto(("\n".join(graphite_data)).encode(), (graphite_host, graphite_port))
    except Exception as e:
        print("failed to push graphite metrics: {:s}".format(str(e)))

exit(2)

qui émet quelque chose comme cela toutes les 10s:
ont0.tx_power_dBm 2.060000 1755187721
ont0.rx_power_dBm -20.660000 1755187721
ont0.voltage_mV 3253 1755187721
ont0.bias_current_mA 7 1755187721
ont0.temperature_C 46 1755187721
ont0.ont_registration_status 5 1755187722
ont0.ont_id 106 1755187722
ont0.cpu_used_pc 14 1755187722
ont0.memory_used_pc 70 1755187722

Notez que j'émets en UDP et non en TCP comme le script original, donc il faudra probablement adapter si votre collecteur graphite n'écoute pas en UDP.

Python n'est pas mon language de prédilection, tapez pas trop fort si un PEP a été blessé lors de la rédaction de ce script :-)