Tap the card on the charger and the number fills itself in

The enrolment the Anker app does, done here: 0108 a2=7 opens the reader,
0908 brings back the UID. The frames this sends are byte-for-byte the
ones the app was captured sending — checksum included — which is what the
new test asserts.

Adding and removing now write the charger as well as the account: the
device write is the app's own message, the account write is the inferred
one that carries the name, and either may fail without the other.

Co-Authored-By: Claude Opus 5 <noreply@anthropic.com>
This commit is contained in:
tajniak81
2026-09-03 13:45:00 +02:00
co-authored by Claude Opus 5
parent 4c73d4ac05
commit 7176867eb3
13 changed files with 473 additions and 19 deletions
@@ -636,6 +636,18 @@ func (s *Server) handleAnkerCardDelete(w http.ResponseWriter, r *http.Request) {
})
}
// POST /api/integrations/anker-solix/chargers/{sn}/rfid-cards/scan — open the
// charger's card reader and answer with the card someone taps on it. Takes as
// long as the window does, about twenty seconds, and answers either way: a
// window that closed with nothing tapped is an answer, not a timeout.
func (s *Server) handleAnkerCardScan(w http.ResponseWriter, r *http.Request) {
who, sn, cfg, ok := s.ankerCardGate(w, r)
if !ok {
return
}
s.ankerCardWrite(w, r, who, cfg, "rfid-card-scan", sn, map[string]any{"sn": sn})
}
// ankerCardGate is everything both writes need before they may run: a caller, a
// serial, an integration that is on and has credentials, and a rate limit. A
// gate that is off answers 409 rather than the reads' 200-with-a-reason: a write
+2
View File
@@ -53,6 +53,7 @@
// GET /api/integrations/anker-solix/chargers
// GET /api/integrations/anker-solix/chargers/{sn}/details
// POST /api/integrations/anker-solix/chargers/{sn}/rfid-cards
// POST /api/integrations/anker-solix/chargers/{sn}/rfid-cards/scan
// DELETE /api/integrations/anker-solix/chargers/{sn}/rfid-cards/{number}
// GET /api/integrations/greencell PUT /api/integrations/greencell
// POST /api/integrations/greencell/health
@@ -444,6 +445,7 @@ func (s *Server) Handler() http.Handler {
mux.HandleFunc("GET /api/integrations/anker-solix/chargers", s.handleAnkerChargers)
mux.HandleFunc("GET /api/integrations/anker-solix/chargers/{sn}/details", s.handleAnkerChargerDetails)
mux.HandleFunc("POST /api/integrations/anker-solix/chargers/{sn}/rfid-cards", s.handleAnkerCardSave)
mux.HandleFunc("POST /api/integrations/anker-solix/chargers/{sn}/rfid-cards/scan", s.handleAnkerCardScan)
mux.HandleFunc("DELETE /api/integrations/anker-solix/chargers/{sn}/rfid-cards/{number}", s.handleAnkerCardDelete)
mux.HandleFunc("GET /api/integrations/greencell", s.handleGetGreencell)
mux.HandleFunc("PUT /api/integrations/greencell", s.handlePutGreencell)