Logo CRLF

En este apunte explico cómo controlar un puerto PoE en un switch TP-Link (TL-SG108PE) desde Home Assistant. Dado que estos pequeños conmutadores no soportan SNMP voy a usar curl para autenticarme, encender, apagar o consultar el estado de un puerto específico. El caso de uso es poder encender o apagar una cámara PoE ReoLink conectada a uno de los puertos desde Home Assistant.


Introducción

Como decía, se trata de un pequeño switch TL-SG108PE. Para los ejemplos siguientes, su nombre de host es sw-despacho-mesa.parchis.org. La secuencia de trabajo con él vía curl consiste en autenticarse primero y después pedir acciones como encender, apagar o consultar el estado de un puerto.

Esquema de conexión

Voy a utilizar autenticacion basada Cookie, en vez de basada en Sesión del Servidor. Uso un primer comando curl para autenticarme y salvo la cookie en un fichero, el segundo comando curl usará dicha cookie para trabajar de forma autenticada. Los comandos POST y GET que verás a continuación los descubrí conectándome desde el navegador y capturando el tráfico con Wireshark.

Autenticación: Este es el comando que nos autentica con el switch. Es necesario ejecutarlo antes y por cierto, si ya se encontrase autenticado, no pasa nada por ejecutarlo de nuevo.

pid=`echo $$`
curl -o /dev/null -s -c /tmp/cookies.$pid.txt -X POST "http://sw-despacho-mesa.parchis.org/logon.cgi" \
-H "Content-Type: application/x-www-form-urlencoded" \
--data-urlencode "username=<usuario>" \
--data-urlencode "password=<contraseña>" \
--data-urlencode "cpassword=" \
--data-urlencode "logon=Login"

Encender/Apagar el Puerto PoE: Estos son los dos comandos, la clave está en el valor de state. El primero enciende el puerto y el segundo lo apaga. La cámara se encenderá o apagará al recibir o dejar de recibir energía.

curl -o /dev/null -s -b /tmp/cookies.$pid.txt --basic --request GET "http://sw-despacho-mesa.parchis.org/port_setting.cgi?portid=1&state=1&speed=1&flowcontrol=0&apply=Apply"

curl -o /dev/null -s -b /tmp/cookies.$pid.txt --basic --request GET "http://sw-despacho-mesa.parchis.org/port_setting.cgi?portid=1&state=01&speed=1&flowcontrol=0&apply=Apply"

Obtener el estado de un puerto: Es posible interrogar al Switch para ver el estado de un puerto concreto. En el siguiente ejemplo averiguo el estado de todos los puertos y muestro el valor del primero (cambia el $1 por el puerto que te interese). Devolverá 1=encendido o 0=apagado.

curl -o /dev/null -s -b /tmp/cookies.$pid.txt --basic --request GET "http://sw-despacho-mesa.parchis.org/port_setting.cgi" | grep -oP 'state:\[\K[^\]]+' | awk -F, '{print $1}'

Home assistant

En el fichero /homeassistant/configuration.yaml incluyo lo siguiente:

command_line: !include command_line.yaml

Este es mi fichero command_line.yaml, recuerda cambiar USUARIO,CONTRASEÑA por los de tu switch.

# command_line.yaml
# Para ejecutar comandos externos

# Creo un objeto switch para poder conmutar ON/OFF el puerto del switch
#
- switch:
    name: ReoLink Despacho Sensor
    command_on: >
      pid=`echo $$` &&
      curl -o /dev/null -s -c /tmp/cookies.$pid.txt -X POST "http://sw-despacho-mesa.parchis.org/logon.cgi" -H "Content-Type: application/x-www-form-urlencoded" --data-urlencode "username=<USUARIO>" --data-urlencode "password=<CONTRASEÑA>" --data-urlencode "logon=Login" &&
      sleep 1 &&
      curl -o /dev/null -s -b /tmp/cookies.$pid.txt --basic --request GET "http://sw-despacho-mesa.parchis.org/port_setting.cgi?portid=1&state=1&speed=1&flowcontrol=0&apply=Apply" &&
      sleep 5
    command_off: >
      pid=`echo $$` &&
      curl -o /dev/null -s -c /tmp/cookies.$pid.txt -X POST "http://sw-despacho-mesa.parchis.org/logon.cgi" -H "Content-Type: application/x-www-form-urlencoded" --data-urlencode "username=<USUARIO>" --data-urlencode "password=<CONTRASEÑA>" --data-urlencode "logon=Login" &&
      sleep 1 &&
      curl -o /dev/null -s -b /tmp/cookies.$pid.txt --basic --request GET "http://sw-despacho-mesa.parchis.org/port_setting.cgi?portid=1&state=0&speed=1&flowcontrol=0&apply=Apply" &&
      sleep 5
    command_state: >
      ping -c 1 -W 2 camara-despacho.parchis.org | grep "1 packets received" | wc -l
    value_template: '{{ value == "1" }}'
    unique_id: cmd_line_reolink_despacho_sensor

# Creo un objeto binary_sensor para conocer es estado de la cámara
#
- binary_sensor:
    name: ReoLink Despacho Conectividad
    command: 'ping -c 1 -W 2 camara-despacho.parchis.org | grep "1 packets received" | wc -l'
    device_class: connectivity
    payload_on: 1
    payload_off: 0
    unique_id: cmd_line_reolink_despacho_conectividad

A continuación muestro el diagrama de secuencia.

Ejemplo de la secuencia de encendido

A partir de aquí ya puedes añadir las entidades al Dashboard que quieras y/o incluirlas en cualquier automatización para controlar el estado de la encendido o apagado de la cámara. Eso sí, dale tiempo a la ejecución, ten en cuenta que es asíncrono, encender la cámara tarda unos segundos y por lo tanto los cambios de estado tardarán en reflejarse.

Ejemplo de panel