Modul für Omada SDN Controller

Begonnen von MatthiasL, 30 September 2022, 15:43:08

Vorheriges Thema - Nächstes Thema

MatthiasL

Hallo Zusammen,
ich bin gerade dabei, bzw. besser gesagt versuche, ein Modul zu entwickeln, welches die Omada SDN API von TP-Link ansprechen kann.
Primärziel ist es, POE per FHEM zu schalten.
Ich habe hierzu mal ganz dreißt, dass 74_Unifi.pm Modul kopiert und etwas angepasst.
Was bereits funktioniert ist das Auslesen einiger Information nach erfolgreichem login.

Da ich selber aber echt kein Perl Profi bin, würde ich mich sehr über Unterstützung freuen.
Vielleicht findet sich ja jemand, der das möglicherweise auch im Einsatz hat und helfen kann und will?

Die API ist recht gut dokumentiert - Siehe Anhang

Hier mal ein aktuelles Listing, was so bisher geht.

Internals:
   Cookies    TPEAP_SESSIONID=XXXXXXXXXXXXXXXXXXXXXXX; rememberMe=deleteMe
   DEF        10.0.0.250 8043 crypt:XXXXXXXXXXXXXXXXXXXXXXXcrypt:XXXXXXXXXXXXXXXXXXXXXXX
   FUUID      XXXXXXXXXXXXXXXXXXXXXXX
   NAME       Omada
   NOTIFYDEV  global
   NR         67
   NTFY_ORDER 50-Omada
   OMADACID   XXXXXXXXXXXXXXXXXXXXXXX
   OMADACURL  https://10.0.0.250:8043/XXXXXXXXXXXXXXXXXXXXXXX/api/v2/
   OMADACVERSION 5.5.6
   STATE      connected
   TOKEN      XXXXXXXXXXXXXXXXXXXXXXX
   TYPE       Omada
   VERSION    0.1.1
   eventCount 8
   HTTPCookieHash:
     TPEAP_SESSIONID;:
       Name       TPEAP_SESSIONID
       Options    Path=/XXXXXXXXXXXXXXXXXXXXXXX; Max-Age=1296000; Expires=Sat, 15-Oct-2022 09:26:13 GMT; Secure; HttpOnly
       Path       
       Value      XXXXXXXXXXXXXXXXXXXXXXX
     rememberMe;:
       Name       rememberMe
       Options    Path=/; Max-Age=0; Expires=Thu, 29-Sep-2022 09:26:14 GMT
       Path       
       Value      deleteMe
   Omada:
   READINGS:
     2022-09-30 11:26:45   LoggedInUser    Albert Einstein
     2022-09-30 11:26:45   site_0_ID       XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:26:45   site_0_name     Einstein
     2022-09-30 11:26:13   state           connected
     2022-09-30 11:26:44   wlan_0_ID       XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:26:44   wlan_0_name     Default
     2022-09-30 11:26:44   wlan_1_ID       XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:26:44   wlan_1_name     Night
     2022-09-30 11:26:44   wlan_2_ID       XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:26:44   wlan_2_name     Outdoor
     2022-09-30 11:22:20   wlanssid_0_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_0_name Garten
     2022-09-30 11:22:20   wlanssid_1_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_1_name WLAN-Einstein
     2022-09-30 11:22:20   wlanssid_2_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_2_name WLAN-EinsteinKids
     2022-09-30 11:22:20   wlanssid_3_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_3_name WLAN-EinsteinPrint
     2022-09-30 11:22:20   wlanssid_4_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_4_name WLAN-EinsteinOffice
     2022-09-30 11:22:20   wlanssid_5_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_5_name WLAN-Einstein
     2022-09-30 11:22:20   wlanssid_6_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_6_name WLAN-EinsteinKids
     2022-09-30 11:22:20   wlanssid_7_ID   XXXXXXXXXXXXXXXXXXXXXXX
     2022-09-30 11:22:20   wlanssid_7_name WLAN-EinsteinPrint
   accespoints:
   alerts_unarchived:
   helper:
     password   crypt:XXXXXXXXXXXXXXXXXXXXXXX
     username   crypt:XXXXXXXXXXXXXXXXXXXXXXX
   httpParams:
     header     
     ignoreredirects 1
     loglevel   5
     method     POST
     noshutdown 0
     timeout    5
     hash:
     sslargs:
       SSL_verify_mode 0
   omada:
     CONNECTED  connected
     eventPeriod 24
     interval   30
     updateStartTime 1664530004.94297
     url        https://10.0.0.250:8043
     customClientReadings:
       attr_value .:^accesspoint|^essid|^hostname|^last_seen|^snr|^uptime|^omadacId|^controllerVer
       parts:
         0000000_part:
           ReadingRegEx ^accesspoint|^essid|^hostname|^last_seen|^snr|^uptime|^omadacId|^controllerVer
           nameRegEx  .
   sites:
     XXXXXXXXXXXXXXXXXXXXXXX:
       alertNum   0
       id         XXXXXXXXXXXXXXXXXXXXXXX
       lanDeviceConnectedNum 4
       lanDeviceDisconnectedNum 0
       lanGuestNum 0
       lanUserNum 5
       name       Einstein
       region     Germany
       wlanDeviceConnectedNum 1
       wlanDeviceDisconnectedNum 1
       wlanDeviceIsolatedNum 0
       wlanGuestNum 0
       wlanUserNum 9
   updateDispatch:
     Omada_GetCurrentAccount_Send:
       CODE(0x55a8ceb63718)
       Omada_GetCurrentAccount_Receive
       CODE(0x55a8ceb63760)
     Omada_GetWlanSsid_Send:
       CODE(0x55a8ceb638c8)
       Omada_GetWlanSsid_Receive
       CODE(0x55a8ceb63910)
     Omada_ProcessUpdate:
       CODE(0x55a8ceb63958)
       
   wlan:
     XXXXXXXXXXXXXXXXXXXXXXX:
       id         XXXXXXXXXXXXXXXXXXXXXXX
       name       Default
       site       XXXXXXXXXXXXXXXXXXXXXXX
     XXXXXXXXXXXXXXXXXXXXXXX:
       clonedWlanId XXXXXXXXXXXXXXXXXXXXXXX
       id         XXXXXXXXXXXXXXXXXXXXXXX
       name       Night
       site       XXXXXXXXXXXXXXXXXXXXXXX
     XXXXXXXXXXXXXXXXXXXXXXX:
       clonedWlanId XXXXXXXXXXXXXXXXXXXXXXX
       id         XXXXXXXXXXXXXXXXXXXXXXX
       name       Outdoor
       site       XXXXXXXXXXXXXXXXXXXXXXX
Attributes:
   room       Omada
   verbose    5

Und nein... ich heiße nicht Albert Einstein und die IDs sind durch XXXX... geschwärzt.

MatthiasL

Habe es nun letztlich mit HTTPMOD gelöst.
Ist zwar ein bisschen unschön, aber funktioniert.

Bei Interesse - einfach melden.

Supadone

Servus

Ich nutze auch Omada, bei Perl bin ich aber leider komplett raus. Könntest du bitte dein HTTPMOD Device posten?

Danke und Grüße

Andy

MatthiasL

Servus Andy,
Ich hab mehrere Devices angelegt, weil man sonst Millionen an Readings hat.
Kann ich aber gerne morgen mal teilen, wie ich es gelöst habe.
Welche Controller Version hast du?

Supadone

Das wär super :)

Ich habe den OC200 2.0 mit 5.5.7

MatthiasL

Alles klar, das sollte dann so auch gehen.
Ich nutze bei mir den Linux Software Controller. Mal sehen...
IP und Port muss natürlich angepasst werden.
Habe zu allererst einen HTTPMOD:

define Omada HTTPMOD https://ip:port/api/info 3200

Mit folgenden Attributen:

   enableControlSet 1
   enableCookies 1
   getHeader1 Content-Type: application/json
   handleRedirects 0
   reading100JSON result_supportApp
   reading100Name result_supportApp
   reading101JSON result_omadacId
   reading101Name result_omadacId
   reading102JSON result_controllerVer
   reading102Name result_controllerVer
   reading103JSON result_configured
   reading103Name result_configured
   reading104JSON errorCode
   reading104Name errorCode
   reading105JSON msg
   reading105Name msg
   reading106JSON result_apiVer
   reading106Name result_apiVer
   reading107JSON result_type
   reading107Name result_type
   requestHeader1 Content-Type: application/json
   room       Omada
   sslArgs    SSL_VERIFY_NONE
   stateFormat result_controllerVer

Wichtig ist hier das Reading: result_omadacId
Dieses wird später für die Anmeldung benötigt.
Irreführend ist die API Version. Das Reading wird wahrscheinlich auch ,,3" ausspucken. Version 3 funktioniert bei mir aber nicht.

Sollten hier schon erfolgreiche Readings erscheinen können wir weiter machen.
Ansonsten mal dringend nachsehen, ob bei der der Login über HTTPS an ist.
HTTP sollte aber auch gehen.

Supadone

#6
Super, hat geklappt. :)
Mit dem einzigen Unterschied dass im def bei einem Hardwarecontroller kein Port angegeben werden muss.

2022-10-13 10:21:46 errorCode 0
setstate Omada 5.5.7
setstate Omada 2022-10-13 10:29:42 errorCode 0
setstate Omada 2022-10-13 10:29:42 msg Success.
setstate Omada 2022-10-13 10:29:42 result_apiVer 3
setstate Omada 2022-10-13 10:29:42 result_configured 1
setstate Omada 2022-10-13 10:29:42 result_controllerVer 5.5.7
setstate Omada 2022-10-13 10:29:42 result_omadacId XXXXXXXXXXXXX
setstate Omada 2022-10-13 10:29:42 result_supportApp 1
setstate Omada 2022-10-13 10:29:42 result_type 10

MatthiasL

Alles klar, dann ist der Rest eigentlich recht einfach.
Laut Omada SDN Doku sollte man sich einen eigenen Admin Benutzer für die API anlegen (habe ich aber nicht gemacht)

define OmadaSites HTTPMOD https://ip:port/%%omadacId%%/api/v%%apiVer%%/sites/default?currentPage=1&currentPageSize=1000 3600
mit den Attributen:

   enableControlSet 1
   enableCookies 1
   getHeader1 Content-Type: application/json
   getHeader2 Csrf-Token: $sid
   handleRedirects 0
   reAuthAlways 1
   reading100JSON result_name
   reading100Name result_name
   reading101JSON result_primary
   reading101Name result_primary
   reading102JSON result_scenario
   reading102Name result_scenario
   reading103JSON result_id
   reading103Name result_id
   reading104JSON result_timeZone
   reading104Name result_timeZone
   reading105JSON result_region
   reading105Name result_region
   reading106JSON msg
   reading106Name msg
   reading107JSON errorCode
   reading107Name errorCode
   reading108JSON result_omadacId
   reading108Name result_omadacId
   replacement01Mode expression
   replacement01Regex %%omadacId%%
   replacement01Value ReadingsVal("Omada", "result_omadacId", "")
   replacement02Mode text
   replacement02Regex %%apiVer%%
   replacement02Value 2
   requestHeader1 Content-Type: application/json
   requestHeader2 Csrf-Token: $sid
   room       Omada
   sid01Data  {"username":"APINUTZERNAME","password":"APINUTZERPASSWORT"}
   sid01Header Content-Type: application/json
   sid01IdJSON result_token
   sid01URL   https://ip:port/%%omadacId%%/api/v%%apiVer%%/login
   sslArgs    SSL_VERIFY_NONE
   stateFormat msg result_name
   verbose    0

reAuthAlways kann natürlich auch durch tolle Funktionen ersetzt werden... Wäre da offen für Input, wie man das schöner löst.
reAuthJSON / reAuthRegex

sid01Data kann natürlich auch noch versteckt werden.

Durch die replacement... Atrribute werden die erforderlichen Readings des der vorigen HTTPMODS schön weiter verwendet.

Nun hat man eigentlich schon fast alles was man braucht.
Um zum Beispiel an die grobe POE Auslastung zu kommen (geht auch genauer über die Insight API)
https://ip:port/%%omadacId%%/api/v%%apiVer%%/sites/%%siteId%%/dashboard/poeUtilization 60
Hier habe ich dann ExtractAllJSON verwendet um an alle Readings zu kommen.
Attribute:

   enableControlSet 1
   enableCookies 1
   event-on-update-reading .*
   getHeader1 Content-Type: application/json
   getHeader2 Csrf-Token: $sid
   handleRedirects 0
   reAuthAlways 1
   extractAllJSON 2
   replacement01Mode expression
   replacement01Regex %%omadacId%%
   replacement01Value ReadingsVal("Omada", "result_omadacId", "")
   replacement02Mode text
   replacement02Regex %%apiVer%%
   replacement02Value 2
   replacement03Mode expression
   replacement03Regex %%siteId%%
   replacement03Value ReadingsVal("OmadaSites", "result_id", "")
   requestHeader1 Content-Type: application/json
   requestHeader2 Csrf-Token: $sid
   room       Omada
   sid01Data  {"username":"APINUTZERNAME","password":"APINUTZERPASSWORT"}
   sid01Header Content-Type: application/json
   sid01IdJSON result_token
   sid01URL   https://ip:port/%%omadacId%%/api/v%%apiVer%%/login
   sslArgs    SSL_VERIFY_NONE

Die API hatte ich ja schon angehängt, da ist dann alles weitere erklärt..

Supadone

Sorry das ich mich jetzt erst melde, bin erst heute dazugekommen...

Funktioniert bisher super :)
Hast du zufällig noch eine fertige def um einen reconnect eines clients durchzuführen? Das ist eigentlich das einzige was ich aktuell brauchen würde.
Hab mir die API schon angesehen, aber dafür brauche ich ja ein POST statt ein GET, das habe ich bisher noch nicht hinbekommen...

Grüße

Andy

MatthiasL

#9
Zum Beispiel - ist zwar ein Patch sollte aber als Post genau so gehen.

attr OmadaSettingLanProfiles set01Data {\
    "id": "%%AZdataid%%",\
    "site": "63593f6d9a4a5d07fb951330",\
    "name": "%%AZdataname%%",\
    "poe": "$val",\
    "nativeNetworkId": "63593f6e9a4a5d07fb951341",\
    "tagNetworkIds": [\
        "63593f6e9a4a5d07fb951342",\
        "63593f6e9a4a5d07fb951343",\
        "63593f6e9a4a5d07fb951344",\
        "63593f6e9a4a5d07fb951345",\
        "63593f6e9a4a5d07fb951347",\
        "63593f6e9a4a5d07fb951348",\
        "63701dfa61aee228a8a675e9",\
        "6371f11061aee228a8a6951e"\
    ],\
    "untagNetworkIds": [],\
    "dot1x": 1,\
    "portIsolationEnable": false,\
    "lldpMedEnable": true,\
    "bandWidthCtrlType": 0,\
    "spanningTreeEnable": false,\
    "loopbackDetectEnable": false\
}
attr OmadaSettingLanProfiles set01Hint 0,1,2
attr OmadaSettingLanProfiles set01Max 2
attr OmadaSettingLanProfiles set01Method PATCH
attr OmadaSettingLanProfiles set01Min 0
attr OmadaSettingLanProfiles set01Name AZ_POE
attr OmadaSettingLanProfiles set01URL https://ip:port/%%omadacId%%/api/v%%apiVer%%/sites/%%siteId%%/setting/lan/profiles/%%AZdataid%%

KOAL

Zitat von: MatthiasL am 12 Oktober 2022, 13:01:06
Alles klar, das sollte dann so auch gehen.
Ich nutze bei mir den Linux Software Controller. Mal sehen...
IP und Port muss natürlich angepasst werden.
Habe zu allererst einen HTTPMOD:

define Omada HTTPMOD https://ip:port/api/info 3200

Mit folgenden Attributen:

   enableControlSet 1
   enableCookies 1
   getHeader1 Content-Type: application/json
   handleRedirects 0
   reading100JSON result_supportApp
   reading100Name result_supportApp
   reading101JSON result_omadacId
   reading101Name result_omadacId
   reading102JSON result_controllerVer
   reading102Name result_controllerVer
   reading103JSON result_configured
   reading103Name result_configured
   reading104JSON errorCode
   reading104Name errorCode
   reading105JSON msg
   reading105Name msg
   reading106JSON result_apiVer
   reading106Name result_apiVer
   reading107JSON result_type
   reading107Name result_type
   requestHeader1 Content-Type: application/json
   room       Omada
   sslArgs    SSL_VERIFY_NONE
   stateFormat result_controllerVer

Wichtig ist hier das Reading: result_omadacId
Dieses wird später für die Anmeldung benötigt.
Irreführend ist die API Version. Das Reading wird wahrscheinlich auch ,,3" ausspucken. Version 3 funktioniert bei mir aber nicht.

Sollten hier schon erfolgreiche Readings erscheinen können wir weiter machen.
Ansonsten mal dringend nachsehen, ob bei der der Login über HTTPS an ist.
HTTP sollte aber auch gehen.


HI, danke für das teilen der Infos.
Das hab ich noch geschafft, aber alles weitere was du an Code geteilt hast geht bei mir nicht. :(
Der Link "https://meine IP + PORT/%%omadacId%%/api/v%%apiVer%%/sites/default?currentPage=1&currentPageSize=1000 3600" geht nicht da kommt Error 400.
Kannst du das für Dumme ganz einfach erklären bitte. :) 

Ich möchte gerne den Zustand der AP's sehen, das Gästeweife ein/aus schalten, Clients anzeigen die verbunden/nicht verbunden sind.
Das wäre mega toll.


Danke
LG
KOAL
1X DEBAIN 11 ESXI VM, Openvpn-Server, FHEM, DHCP, HM-LAN W, USB-Enocean, Smartvisu V3.X
1X UBUNU 20.X LTS ESXI VM, AUTO-SERVER, Openvpn-Backup Server
1X UBUNU 20.X LTS ESXI VM, MAILSERVER, CLOUD
1X Lockerstor 4, NAS + APC CS650
1X WIN-10 ESXI VM, BLUEIRIS CAM Server

MatthiasL

Hast du auch die entsprechenden Attribute gesetzt?

enableControlSet 1
   enableCookies 1
   event-on-update-reading .*
   getHeader1 Content-Type: application/json
   getHeader2 Csrf-Token: $sid
   handleRedirects 0
   reAuthAlways 1
   extractAllJSON 2
   replacement01Mode expression
   replacement01Regex %%omadacId%%
   replacement01Value ReadingsVal("Omada", "result_omadacId", "")
   replacement02Mode text
   replacement02Regex %%apiVer%%
   replacement02Value 2
   replacement03Mode expression
   replacement03Regex %%siteId%%
   replacement03Value ReadingsVal("OmadaSites", "result_id", "")
   requestHeader1 Content-Type: application/json
   requestHeader2 Csrf-Token: $sid
   room       Omada
   sid01Data  {"username":"APINUTZERNAME","password":"APINUTZERPASSWORT"}
   sid01Header Content-Type: application/json
   sid01IdJSON result_token
   sid01URL   https://ip:port/%%omadacId%%/api/v%%apiVer%%/login
   sslArgs    SSL_VERIFY_NONE


Wie heißt dein erstes Device?
Bei den Replacements (replacementXXValue...) muss der Name passen.
Hoffe das hilft weiter.

MatthiasL

Zitat von: Supadone am 26 November 2022, 17:44:23
Sorry das ich mich jetzt erst melde, bin erst heute dazugekommen...

Funktioniert bisher super :)
Hast du zufällig noch eine fertige def um einen reconnect eines clients durchzuführen? Das ist eigentlich das einzige was ich aktuell brauchen würde.
Hab mir die API schon angesehen, aber dafür brauche ich ja ein POST statt ein GET, das habe ich bisher noch nicht hinbekommen...

Grüße

Andy

So gehts:
Mit set NAME reconnectClient 00-00-00-00-00 (Device MAC)

set01Header01 Content-Type: application/x-www-form-urlencoded
   set01Header02 Csrf-Token: $sid
   set01Method POST
   set01Name  reconnectClient
   set01TextArg 1
   set01URL   https://ip:port/%%omadacId%%/api/v2/sites/%%siteId%%/cmd/clients/$val/reconnect

KOAL

HI,

also ich hab ein Device "Omada_PAPA" angelegt. Bild OMADA_1
Dann hab ich noch das Device "OmadaSites_PAPA" angelegt, und hier steck ich. Bid: OMADA_2, OMADA_3

Das was ich gelb mariert habe, da bin ich mir nicht sicher ob ich das mit meinen Daten befüllen muss oder ob das vom ersten Device kommt?
Bei username und pasword hab ich die Logindaten vom Controller Administrator eingetragen.

Danke für die Hilfe.



LG
KOAL
1X DEBAIN 11 ESXI VM, Openvpn-Server, FHEM, DHCP, HM-LAN W, USB-Enocean, Smartvisu V3.X
1X UBUNU 20.X LTS ESXI VM, AUTO-SERVER, Openvpn-Backup Server
1X UBUNU 20.X LTS ESXI VM, MAILSERVER, CLOUD
1X Lockerstor 4, NAS + APC CS650
1X WIN-10 ESXI VM, BLUEIRIS CAM Server

MatthiasL

IP:Port bitte immer durch echt Werte ersetzen.
Und Replacement02Value ApiVer 2! Nicht 3!