Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Limit setzen über API klappt nicht mehr seit 0.8.70 #1415

Closed
1 task
Ollipop030 opened this issue Feb 8, 2024 · 10 comments
Closed
1 task

Limit setzen über API klappt nicht mehr seit 0.8.70 #1415

Ollipop030 opened this issue Feb 8, 2024 · 10 comments
Assignees
Labels
bug Something isn't working fixed dev fixed

Comments

@Ollipop030
Copy link

Ollipop030 commented Feb 8, 2024

Platform

ESP32

Assembly

I did the assebly by myself

nRF24L01+ Module

nRF24L01+ plus

Antenna

external antenna

Power Stabilization

Elko (~100uF)

Connection picture

  • I will attach/upload an Image of my wiring

Version

0.8.76

Github Hash

7c532ca

Build & Flash Method

AhoyDTU Webinstaller

Setup

none

Debug Serial Log output

none

Error description

Seit der Ahoy Version 0.8.70 klappt das Limit senden über die API nicht mehr, wenn in Ahoy ein Passwort vergeben ist. Wenn das Passwort gelöscht wird klappt es wieder. http://AhoyIP/api/ ist aber erreichbar, ob mit oder ohne Passwort.

Das Limit setze ich hiermit:
https://github.com/reserve85/HoymilesZeroExport

Gibt auch dort ein Issue: reserve85/HoymilesZeroExport#132

@Ollipop030 Ollipop030 added the bug Something isn't working label Feb 8, 2024
@Ollipop030 Ollipop030 changed the title [Bug] Limit setzen über API klappt nicht mehr seit 0.8.70 Feb 8, 2024
lumapu added a commit that referenced this issue Feb 8, 2024
* merge PR: BugFix: ACK #1414
* fix suspicious if condition #1416
* prepared API token for access, not functional #1415
@MetaChuh
Copy link

ich hab's auch mit v0.8.77 noch nicht geschafft 🫤

auch curl --header "Content-Type:application/json" --user "user:password" --request POST --data '{"id": 4, "cmd": "limit_nonpersistent_relative", "val": 50}' "http://dtu_ip/api/ctrl"

liefert nur {"success":false,"error":"nicht angemeldet, Kommando nicht möglich!"}

die älteren versionen funktionieren auch bei mir wie gewohnt.

@lumapu
Copy link
Owner

lumapu commented Feb 10, 2024

ich bin dabei und habe auch schon eine bessere Version parat. Aktuell habe ich nur das Problem, das der ESP durch API Anfragen neu startet. Ich weiß noch nicht warum und was der Auslöser ist, das wollte ich heute noch herausfinden.
In der aktuellen Version hatte ich auch nicht erwartet, dass die API requests besser gehen, ich habe nur schon die Verbesserung vorbereitet.

@lumapu lumapu added the fixed dev fixed label Feb 10, 2024
@lumapu
Copy link
Owner

lumapu commented Feb 10, 2024

ab Version 0.8.78 muss man sich erst authentifizieren, bevor man über die API was verändern darf.

Das Passwort muss nur einmalig in Klartext übertragen werden. Nach 20 Minuten erlischt ein generierter Token, sofern in der Zwischenzeit nicht ein weiteres Kommando gesendet wurde. Jedes Kommando setzt das Timeout der 20 Minuten wieder zurück. Zur weiteren Absicherung wird die IP-Adresse der API ausgewertet. Das heißt, wenn im Netzwerk der Token mitgelesen werden sollte, kann trotzdem nicht auf die API zugegriffen werden, da beim Authenifizieren die IP-Adresse im ESP gespeichert wird.

Jede Authentifizierung führt zu einem neuen Token. Theoretisch wäre auch ein zugriff von zwei versch. Clients möglich, diese müssten sich aber für jedes Kommando neu authentifizieren. Dafür müsste jedes mal das Passwort im Klartext übertragen werden was nicht zu empfehlen ist.

Ich bin sehr gespannt, wie ihr meine Umsetzung findet und wie ihr damit zurecht kommt. 😊

Python Test Script (Limit auf 100% setzen) Die IP-Adresse muss geändert werden. Passwort ist hier `admin`. Man kann den Token beliebig oft wiederverwenden - man muss nur innerhalb des Timeouts von 20 Minuten bleiben.
import requests
import json

url = 'http://192.168.0.81/api/ctrl'

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '1000', 'id': 0}
x = requests.post(url, json = myobj)
print(x.text)

myobj = {'cmd': 'auth', 'val': 'admin'}
x = requests.post(url, json = myobj)
print(x.text)
y = json.loads(x.text)

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '1000', 'id': 0, 'token': y["token"]}
x = requests.post(url, json = myobj)
print(x.text)

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '1000', 'id': 0, 'token': y["token"]}
x = requests.post(url, json = myobj)
print(x.text)
Python Test Script - Output
{"success":false,"error":"not logged in, command not possible!"}
{"success":true,"token":"I6NWJ91ITOU39CTW"}
{"success":true,"id":0}
{"success":true,"id":0}

lumapu added a commit that referenced this issue Feb 11, 2024
* finalized API token access #1415
@MetaChuh
Copy link

fragen:

  1. warum ab jetzt 1000 für 100%
    statt wie früher 100 für 100% ?

    grund der frage:
    jedes api nutzende projekt muss dann beide routinen beinhalten (x1 / x10) und wissen, welche ahoy dtu version gerade läuft.
    viel zusätzlicher case/if/else code in allen steuerungs projekten.
    die 100 für 100% beizubehalten, macht einbauen von auth rückwärtskompatibel mit älteren versionen, da auth und token in älteren versionen ignoriert wird (gleiche api ansteuerung sind dann, bereits getestet, für alle versionen möglich)

  2. ginge in zukunft als single line alternative {'cmd': 'limit_nonpersistent_relative', 'val': '1000', 'id': 0, 'auth': "password"}
    (one pass auth und cmd) ?

    gründe der frage:
    a) um kein 20 minuten tracking, für die gültigkeit des tokens zu speichern, wird nahezu jeder in seiner steuerung, einfach aus jedem befehl, eine doppelbefehl abfolge (auth und danach limit_nonpersistent_relative) machen.
    dadurch wird jedes mal ein neuer token erstellt und im esp mit referenz zur ip zwischengespeichert.
    muss wie reserve85 noch testen, ob dies die ahoydtu bei normaler bis erhöhter befehlsrate zum abstürzen bringt.

    b) eine möglichkeit eines einzeilers, hilft sämtlichen projekten, die derzeit nur ein single pass template für ahoy und opendtu api befehlsaufrufe haben.

thx

@reserve85
Copy link

reserve85 commented Feb 11, 2024

@lumapu : hier bin ich grad beim implementieren drübergestolpert: bei mir geht das mit jedem "ausgedachten" Token, dann kommt immer successful = true zurück und das Limit wird eingestellt. Auch ohne abgerufenem token.

edit: irgendwie komisch, ich kann es nicht mehr nachstellen. Es war aber definitiv so, da ich mich wunderte wieso es funktioniert obwohl ich den Token noch gar nicht implementiert hatte...

reserve85 added a commit to reserve85/HoymilesZeroExport that referenced this issue Feb 11, 2024
## V1.73
### script
* Support of AHOY-DTU Authentication, #132 and lumapu/ahoy#1415
### Config
* added `AHOY_PASSWORD =` to `AHOY_DTU`
lumapu added a commit that referenced this issue Feb 12, 2024
* optimize API authentication, Error-Codes #1415
* breaking change: authentication API command changed #1415
* breaking change: limit has to be send als `float`, `0.0 .. 100.0` #1415
* updated documentation #1415
* fix don't send control command twice #1426
@lumapu
Copy link
Owner

lumapu commented Feb 12, 2024

Danke für euer Feedback. Folgendes habe ich angepasst:

  • die Authentifizierung ist jetzt eingebettet in das erste Komando, oder optional auch extra
  • die Fehler werden jetzt in Form von Codes zurückgegeben (identisch für alle Sprachen), siehe Fehlerliste weiter unten
  • das relative Limit benötigt jetzt einen Floatwert, zwischen 0.0 und 100.0
Python Test Script (Limit auf 100% setzen) Die IP-Adresse muss geändert werden. Passwort ist hier `admin`. Man kann den Token beliebig oft wiederverwenden - man muss nur innerhalb des Timeouts von 20 Minuten bleiben. Zuerst eine Anfrage, die mit gesetztem Passwort fehlschlägt. Dann kommt eine Anfrage mit eingebetteter Authentifizierung. Die nächsten beiden Anfragen nutzen den zurückgegebenen Token. Die letzten Beiden Zeilen zeigen eine Option, die Authentifizierung gesondert zu machen.
import requests
import json

url = 'http://192.168.0.81/api/ctrl'

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '100.0', 'id': 0}
x = requests.post(url, json = myobj)
print(x.text)

myobj = {'auth': 'admin', 'cmd': 'limit_nonpersistent_relative', 'val': '1000', 'id': 0}
x = requests.post(url, json = myobj)
print(x.text)
y = json.loads(x.text)

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '100.0', 'id': 0, 'token': y["token"]}
x = requests.post(url, json = myobj)
print(x.text)

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '99.9', 'id': 0, 'token': y["token"]}
x = requests.post(url, json = myobj)
print(x.text)

myobj = {'auth': 'admin'}
x = requests.post(url, json = myobj)
print(x.text)
y = json.loads(x.text)

myobj = {'cmd': 'limit_nonpersistent_relative', 'val': '99.8', 'id': 0, 'token': y["token"]}
x = requests.post(url, json = myobj)
print(x.text)
Python Test Script - Output
{"success":false,"error":"ERR_PROTECTED"}
{"success":true,"token":"5OH37BUUQP1SWOT3","id":0}
{"success":true,"id":0}
{"success":true,"id":0}
{"success":true,"token":"U8BFVP2UYKDO6N8X"}
{"success":true,"id":0}

edit: mögliche Fehler:

ERR_AUTH
ERR_INDEX
ERR_UNKNOWN_CMD
ERR_LIMIT_NOT_ACCEPT
ERR_PROTECTED

@MetaChuh
Copy link

MetaChuh commented Feb 12, 2024

thx, bereits geflasht und wir beginnen zu testen 👍

  • limit_nonpersistent_relative/absolute 100.0 %/w float wert, statt integer 100%/w * 10 = 1000:
    funktioniert, kann man imho so lassen 👍

    zwecks vollständigkeit, eine irrelevante, gefundene einschränkung bei den tests:
    ahoy web interface und api liefern integer statt float werte zurück.
    inverter wird jedoch korrekt auf float (zb. 50.5%) gestellt.
    (für mich egal, da die integer auflösung in watt oder prozent ausreicht)

  • single pass auth & command:
    funktioniert perfekt 👍
    sowohl single pass auth und dual pass auth mit token fehlerfrei.

  • power_limit_read 3-100 statt 65535 nach limit_nonpersistent_relative oder limit_nonpersistent_absolute befehl:
    irrelevant für dieses issue, wird in #1427 behandelt

thx & greetings 👍🙏

@MetaChuh
Copy link

@Ollipop030

wie sieht's bei dir aus ?
auch alles ok und schließbar, bezüglich dieses ahoy issues ?

ps, weil cross projects:
bei hoymileszeroexport fehlt imho "nur noch" revert vom "ahoy_factor" 10er multiplikator als critical task.

(die non localized error message auswertung bei auth fehlern ist optional, solange man die englische ahoy firmware verwendet.
ansonsten ist die bisherige auth routine, seit hoymileszeroexport 1.73 weiterhin kompatibel mit ahoydtu v0.8.80)

@reserve85
Copy link

reserve85 commented Feb 13, 2024

ne passt noch nicht von der DTU (ich konnte nur in der Pause schnell schauen, werde das nachher implementieren), wenn das Passwort im AHOY vergeben wird und die DTU neu gestartet wird, dann akzeptiert die DTU auch ohne auth das Kommando.
command (leeres Token):
command

result (successful):
result

wurde ein mal ein Token abgerufen, dann gehen die cmd-befehle auf error. (wie gewünscht)

@lumapu kannst du das nachstellen?

reserve85 added a commit to reserve85/HoymilesZeroExport that referenced this issue Feb 13, 2024
## V1.75
### script
* refactoring, all DTU commands moved into DTU class
* support newest version of openDTU (API changed, see https://github.com/tbnobody/OpenDTU/releases/tag/v24.2.12)
* set min Version of openDTU to v24.2.12
* support newest version of AhoyDTU (Authentication, removed Factor, see lumapu/ahoy#1415)
* set min Version of AhoyDTU to 0.8.80
### Config
* renamed `AHOY_PASSWORD =` to `AHOY_PASS` (like openDTU)
@lumapu
Copy link
Owner

lumapu commented Feb 13, 2024

@reserve85 tatsächlich, leerer Token geht bei mir auch, echt komisch. Utnersuche ich gleich.

lumapu added a commit that referenced this issue Feb 13, 2024
* fixed authentication with empty token #1415
* added new setting for future function to send log via MqTT
* combined firmware and hardware version to JSON topics (MqTT) #1212
@lumapu lumapu closed this as completed Feb 17, 2024
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
bug Something isn't working fixed dev fixed
Projects
None yet
Development

No branches or pull requests

4 participants