Supla+AI, rozpoznawanie tablic rejestracyjnych i kur na podwórku

[email protected]
Posts: 1584
Joined: Mon Feb 06, 2023 8:56 am
Has thanked: 18 times
Been thanked: 26 times

Post

Jestem ciekaw jak to zadziała wieczorem bo ta kamera to jest to samo co w ergo cam meter i to działa mega słabo jak się tylko warunki oświetleniowe zmieniają.

Sam pomysł super, ale żeby to działało stabilnie to trzeba dobrej kamery i dobrego kąta montażu
User avatar
Zibi_007
Posts: 3985
Joined: Tue Oct 31, 2023 10:06 pm
Has thanked: 10 times
Been thanked: 31 times

Post

[email protected] wrote: Sat Mar 14, 2026 8:57 pm Jestem ciekaw jak to zadziała wieczorem bo ta kamera to jest to samo co w ergo cam meter i to działa mega słabo jak się tylko warunki oświetleniowe zmieniają.

Sam pomysł super, ale żeby to działało stabilnie to trzeba dobrej kamery i dobrego kąta montażu
To jest taka właśnie kamerka. W nocy nie ma problemu, pod warunkiem, że na ten wjeżdżający samochód skierujesz reflektor 500W (albo odpowiednik w ledach) ;-)
Chciałem z niej zrobić kiedyś prosty monitoring. Zdjęcie i jego zapis po wykryciu ruchu (budka dla ptaków). Jakość tragedia, do tego problem z ostrością. Kupiłem na ali fotopułapkę w okazji z monetami za niecałe 50 zł. Nie spodziewałem się cudów, ale miło się zaskoczyłem. Jakość bije na głowę S3 i do tego jest podczerwień.

@Soyer - na początku pisałeś o rozpoznaniu tablicy, koloru i marki pojazdu.
Teraz o kolorze nic nie widzę. Nie sprawdziło się?
Image Wiesz, że Supla obsługuje Zigbee? Wstąp do Klubu Promila: https://forum.supla.org/viewtopic.php?t=18018
Image Szukasz nowego GG? Jest tutaj: https://forum.supla.org/viewtopic.php?t=18036
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

zzrr wrote: Sat Mar 14, 2026 8:13 pm
SOYER wrote: Sat Mar 14, 2026 7:26 pm Mam jeszcze prośbę, jakby mi ktoś powiedział jak ograniczyć logi supli w czasie działania programu. Wiem(?), że jest kilka „poziomów” dla logów, ale z moim kolegą ejajem poległem na tym.
Używasz ArduinoIDE czy PlatformIO? To robi różnicę jeśli chodzi o Twoje pytanie.
Używam w tym wypadku arduino ide.

Co do jakości kamery to się nie wypowiem bo nie testowałem, a już szczególnie w nocy. Reflektor 500W jednak chyba trochę przesadzony;). Tym bardziej że warstwa odblaskowa na tablicy by wtedy prześwietliła zdjęcie. Akurat tablice są bardzo trudne do odczytu w nocy, specjalistyczne kamery swoje kosztują, a przynajmniej kiedyś kosztowały.

Jak pisałem, było to zrobione bardziej jako wyzwanie i zrobienie czegoś nowego, a nie pod konkretną potrzebę. Teoretycznie nie musiał bym używać esp cam bo przecież łączę się z rejestratorem i konkretną kamerą która patrzy na wjazd. Oprócz info o przekroczeniu linii mógłbym pobrać też zrobione zdjęcie które rejestrator i tak wysyła na maila w momencie przekroczenia linii.
Jedynym kryterium przy zakupie tej kamery była niska cena i chęć poznania czegoś nowego. Chcę jeszcze poeksperymentować z rozpoznawaniem twarzy;).
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Zibi pisze:
Teraz o kolorze nic nie widzę. Nie sprawdziło się?

Sprawdziło się bardzo dobrze w warunkach garażu gdzie robiłem testy, jednak wymagało by z pewnością poszerzania algorytmów o ewentualne różnice odcieni, np w garażu przy sztucznym oświetleniu prawidłowo widziało dark grey, jednak czy w pełnym słońcu gemini nie uznało by go po prostu jako grey? To wszystko trzeba by uwzględnić w kodzie lub promcie.
You do not have the required permissions to view the files attached to this post.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

I jeszcze kilka zdjęć z testów:
You do not have the required permissions to view the files attached to this post.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
[email protected]
Posts: 1584
Joined: Mon Feb 06, 2023 8:56 am
Has thanked: 18 times
Been thanked: 26 times

Post

Warunki mega optymalne do tych testów, kamera na wprost auta, światło wręcz dzienne, spróbuj wieczorem
zzrr
Posts: 1864
Joined: Wed Oct 26, 2022 7:35 pm
Has thanked: 76 times
Been thanked: 119 times

Post

SOYER wrote: Sun Mar 15, 2026 6:55 am
zzrr wrote: Sat Mar 14, 2026 8:13 pm
SOYER wrote: Sat Mar 14, 2026 7:26 pm Mam jeszcze prośbę, jakby mi ktoś powiedział jak ograniczyć logi supli w czasie działania programu. Wiem(?), że jest kilka „poziomów” dla logów, ale z moim kolegą ejajem poległem na tym.
Używasz ArduinoIDE czy PlatformIO? To robi różnicę jeśli chodzi o Twoje pytanie.
Używam w tym wypadku arduino ide.
....

Teraz patrzę jak logi pokazałeś i coś mi się zdaje że Tobie chodzi o wyłączenie logów chyba z samej supli. Zrozumiałem że chcesz wszystkie. Jeśli wszystkie to w ArduinoIDE to się wyłącza USB CDC ON BOOT na DISABLE, to już tak przy okazji a jeśli same SUPLA to spróbuj może w setup SuplaDevice.setProtoVerboseLog(false); . Ale nie pamiętam czy to używałem i nie wiem jak to zadziała.
User avatar
SOYER
Posts: 1623
Joined: Wed Aug 10, 2022 12:29 pm
Location: Kryry
Been thanked: 2 times

Post

Sprawdzony kod do nasłuchiwania rejestratora Dahua. Nie gubi żadnego powiadomienia.

Code: Select all

//płytka esp32 dev module
/////////////////////////////////////
#include <WiFi.h>
#include <lwip/sockets.h>
#include <MD5Builder.h>
#include <SuplaDevice.h>
#include <supla/network/esp_wifi.h>
#include <supla/control/virtual_relay.h>

// --- KONFIGURACJA ---
const char* ssid = "x";
const char* password = "x";
const char* host = "x";
const char* user = "x";
const char* pass = "x";
const char* url  = "/cgi-bin/eventManager.cgi?action=attach&codes=[CrossLineDetection]&channel=2&heartbeat=30";
IPAddress local_IP(x, x, x, x); // Wybierz wolny adres, np. .150
IPAddress gateway(192, 168, 0, 1);    // Adres Twojego Archera
IPAddress subnet(255, 255, 255, 0);
IPAddress primaryDNS(8, 8, 8, 8);     // DNS Google (opcjonalnie)
char GUID[16] = {x};
char AUTHKEY[16] = {x};

WiFiClient d_client;
Supla::ESPWifi supla_wifi(ssid, password); 
auto vRelay = new Supla::Control::VirtualRelay();

unsigned long lastEventTime = 0;
unsigned long lastDataTime = 0;
String currentLine = "";                 // Deklaracja globalna bufora
volatile bool alarmPending = false;      // Deklaracja globalna flagi (volatile dla Core 0/1)

// --- FUNKCJE POMOCNICZE ---
String md5(String payload) {
  MD5Builder _md5; _md5.begin(); _md5.add(payload); _md5.calculate();
  return _md5.toString();
}

String getDigestAuth(String header) {
  auto getParam = [&](String param) {
    int start = header.indexOf(param + "=\"");
    if (start == -1) return String("");
    start += param.length() + 2;
    return header.substring(start, header.indexOf("\"", start));
  };
  String realm = getParam("realm"), nonce = getParam("nonce"), qop = "auth", nc = "00000001", cnonce = "abcdefgh";
  String ha1 = md5(String(user) + ":" + realm + ":" + String(pass));
  String ha2 = md5("GET:" + String(url));
  String resp = md5(ha1 + ":" + nonce + ":" + nc + ":" + cnonce + ":" + qop + ":" + ha2);
  return "Digest username=\"" + String(user) + "\", realm=\"" + realm + "\", nonce=\"" + nonce + 
         "\", uri=\"" + url + "\", qop=" + qop + ", nc=" + nc + ", cnonce=\"" + cnonce + 
         "\", response=\"" + resp + "\", algorithm=MD5";
}

// Funkcja chroniąca przed zrywaniem przez router Archer
void setupKeepAlive(int fd) {
  int enable = 1;
  int idle = 5;     // Wyślij pierwszy pakiet po 5s ciszy
  int interval = 3; // Kolejne co 3s
  int count = 2;     // Po 2 nieudanych próbach zamknij
  setsockopt(fd, SOL_SOCKET, SO_KEEPALIVE, &enable, sizeof(int));
  setsockopt(fd, IPPROTO_TCP, TCP_KEEPIDLE, &idle, sizeof(int));
  setsockopt(fd, IPPROTO_TCP, TCP_KEEPINTVL, &interval, sizeof(int));
  setsockopt(fd, IPPROTO_TCP, TCP_KEEPCNT, &count, sizeof(int));
}

// --- WĄTEK DAHUA (Core 0) ---
void dahuaTask(void * pvParameters) {

  while(1) {
    if (WiFi.status() == WL_CONNECTED) {
      if (!d_client.connected()) {
        d_client.stop(); 
        vTaskDelay(500 / portTICK_PERIOD_MS);
        
        Serial.println("\n[XVR] Logowanie...");
        if (d_client.connect(host, 80)) {
          d_client.print(String("GET ") + url + " HTTP/1.1\r\nHost: " + host + "\r\nConnection: close\r\n\r\n");

          String response = "";
          unsigned long t = millis();
          while (millis() - t < 3000) {
            if (d_client.available()) {
              char c = d_client.read(); // Czytamy znak 
              Serial.write(c);          // Wypisujemy go
              response += c;            // Dodajemy do analizy autoryzacji
              if (response.indexOf("\r\n\r\n") != -1) break;
            }
            vTaskDelay(1);
          }
          
          int authPos = response.indexOf("WWW-Authenticate: Digest");
          if (authPos != -1) {
            String authLine = response.substring(authPos, response.indexOf("\r", authPos));
            d_client.stop();
            vTaskDelay(200); 
            
            if (d_client.connect(host, 80)) {
              setupKeepAlive(d_client.fd()); 
              d_client.print(String("GET ") + url + " HTTP/1.1\r\nHost: " + host + 
                             "\r\nAuthorization: " + getDigestAuth(authLine) + 
                             "\r\nConnection: keep-alive\r\n\r\n");
              
              bool loginSuccess = false;
              unsigned long waitStart = millis();
              while (millis() - waitStart < 5000) {
                if (d_client.available()) {
                  String headerLine = d_client.readStringUntil('\n');
                  if (headerLine.indexOf("200 OK") != -1) { loginSuccess = true; break; }
                }
                vTaskDelay(1);
              }

              if (loginSuccess) {
                Serial.println("[XVR] POŁĄCZONO.");
                lastDataTime = millis();
                currentLine = "";

                while (d_client.connected()) {
                  while (d_client.available() > 0) {
                    char c = d_client.read();
                    lastDataTime = millis(); 
                    currentLine += c;

                    // Szukamy alarmu w locie
                    if (currentLine.indexOf("CrossLineDetection") != -1) {
                        if (currentLine.indexOf("Start") != -1) {
                            Serial.println("\n>>> [XVR] ALARM WYKRYTY !!! <<<");
                            alarmPending = true; // USTAWIANIE FLAGI DLA LOOP
                            currentLine = ""; 
                        }
                    }

                    if (currentLine.length() > 400) {
                      currentLine = currentLine.substring(currentLine.length() - 64);
                    }
                  }

                  if (millis() - lastDataTime > 3600000) { 
                    Serial.println("\n[XVR] Timeout 1h - restart.");
                    break;
                  }
                  vTaskDelay(1); 
                }
              }
            }
          }
        }
        d_client.stop();
        vTaskDelay(5000 / portTICK_PERIOD_MS);
      }
    }
    vTaskDelay(100 / portTICK_PERIOD_MS);
  }
}


void setup() {
  Serial.begin(115200);
   if (!WiFi.config(local_IP, gateway, subnet, primaryDNS)) {
    Serial.println("[WiFi] Błąd konfiguracji statycznego IP!");
  }
  WiFi.setSleep(false);
  currentLine.reserve(512); 
  // Start Supla
  SuplaDevice.begin(GUID, "svrx.supla.org", "[email protected]", AUTHKEY);

  // Uruchomienie Dahua na Core 0 (Supla działa na Core 1)
  xTaskCreatePinnedToCore(dahuaTask, "DahuaTask", 8192, NULL, 1, NULL, 0);
  
  Serial.println("System gotowy.");
}

void loop() {
  SuplaDevice.iterate();

  if (alarmPending) {
    vRelay->turnOn();
    lastEventTime = millis();
    alarmPending = false; // Resetujemy flagę po obsłużeniu
    Serial.println("[Supla] Virtual Relay ON.");
  }

  // Automatyczne wyłączenie po 2 sekundach
  if (vRelay->isOn() && (millis() - lastEventTime > 2000)) {
    vRelay->turnOff();
    Serial.println("[Supla] Virtual Relay OFF.");
  }
}
Z ciekawości zamówię esp32s3, które pozwoli mi wyłapać klatkę ze streamingu rejestratora, a następnie wysłać tą klatkę do gemini, dalej wiadomo. Pozwoli to na użycie tylko jednego esp, powieszonego w zasięgu sieci w której jest też rejestrator. Odpada instalacja kolejnej kamerki. Do niczego mi to wszystko potrzebne;-), wolę otworzyć bramę wcześniej zamiast czekać na otwarcie pod bramą, ale doświadczenie będzie ciekawe.
https://youtube.com/@tomaszhamer8134?si=_J1cT_QWsXxgt1Fm
https://kryry01.aqi.eco/pl
https://app.weathercloud.net/d4311785603
https://github.com/Soyer79
Adamo28
Posts: 223
Joined: Sun Nov 08, 2020 2:54 pm

Post

Mega fajne, nocą zamiast reflektora możesz dać naświetlacz IR tak jak jest w kamerach monitoringu, do odczytania rejestracji powinno starczyć tylko robale nocą strasznie lgną do tych diod.
Leszekbialy
Posts: 153
Joined: Fri Apr 06, 2018 9:29 pm
Has thanked: 2 times

Post

Białe tablice świecą jak neony w IR, może jakaś regulacja mocy do nich by pomogła

Return to “Projekty użytkowników”