esprfid / esp-rfid

ESP8266 RFID (RC522, PN532, Wiegand, RDM6300) Access Control system featuring WebSocket, JSON, NTP Client, Javascript, SPIFFS
MIT License
1.35k stars 423 forks source link

MQTT getuserlist command does not output every user #520

Closed windy54 closed 1 year ago

windy54 commented 2 years ago

I have built the dev branch as both debug and generic, both exhibit similar issue. Initially I built the debug branch and found that when I issued the MQTT getuserlist command it only output 12 users and the 13th was empty, even when there was 20 users. For less than 12 users it is okay. In order to investigate I added extra serial output but could not see where it was failing. In mqtt.esp function getuserlist I added this

if (!error)
        {
            mqttPublishEvent(&root);
        }
        else {
            Serial.println("error in getUserList ");
        }

to see if an error had been generated, nothing was ever output.

I then noticed that Free Heap had an amber warning against it so I re-built the generic version to see if this would give me extra heap space. Thinking that the debug flag would cause more memory to be used , as I write this I realise that would use more flash but not RAM memory. So do not think that is the issue.

I have added my getUserList function below, has anyone any suggestions as to how to debug and see what is happening? `void getUserList() { DynamicJsonDocument root(512); JsonArray users = root.createNestedArray("list"); Dir dir = SPIFFS.openDir("/P/");

ifdef DEBUG

Serial.println("[ INFO ] getUserList");

endif

while (dir.next())
{
    JsonObject item = users.createNestedObject();
    String uid = dir.fileName();
    Serial.println(uid);
    uid.remove(0, 3);
    item["uid"] = uid;
    Serial.println(item);
    File f = SPIFFS.open(dir.fileName(), "r");
    size_t size = f.size();
    Serial.println(size);
    std::unique_ptr<char[]> buf(new char[size]);
    f.readBytes(buf.get(), size);
    DynamicJsonDocument json(512);
    auto error = deserializeJson(json, buf.get());
    if (!error)
    {
        mqttPublishEvent(&root);
    }
    else {
        Serial.println("error in getUserList ");
    }

}

}

I do not understand what this block of code is doing std::unique_ptr<char[]> buf(new char[size]); f.readBytes(buf.get(), size); DynamicJsonDocument json(512); auto error = deserializeJson(json, buf.get());

because getuserlist only transmits the uid which has already been captured and added to root.

any suggestions?

Steve

windy54 commented 2 years ago

After talking it through with another hackspace member , instead of transmitting mqttPublishEvent(&root);

it should be &json.

this then outputs all 100 of our current members sequentially in separate messages, each message identical to the list of users on the webpage.

Steve

bumaas commented 1 year ago

I can confirm that.

In an example I get correct values ​​after the change:

TXT: 22.01.2023, 18:54:37 | MQTT:TX:PUBLISH | Topic: RFID/cmd, Payload: {"cmd":"getuserlist","doorip":"192.168.178.113"} TXT: 22.01.2023, 18:54:37 | MQTT:TX:PUBLISH | Sending to esp8266-b02fc9 (192.168.178.113:52957) TXT: 22.01.2023, 18:54:37 | MQTT:RX:PUBLISH | Topic: RFID/send, Payload: {"command":"userfile","uid":"ddb8fc59","pincode":"","user":"Card","acctype":99,"acctype2":null,"acctype3":null,"acctype4":null,"validsince":0,"validuntil":2145916800} TXT: 22.01.2023, 18:54:37 | MQTT:RX:PUBLISH | Topic: RFID/send, Payload: {"command":"userfile","uid":"ac68b46e","pincode":"","user":"button","acctype":1,"acctype2":null,"acctype3":null,"acctype4":null,"validsince":1674345600,"validuntil":2145916800}

matjack1 commented 1 year ago

Thank you @windy54 and @bumaas !!

I have fixed it here: https://github.com/esprfid/esp-rfid/pull/579 if you can confirm, please.

I'm going to close this for now and we can keep discussing on the PR if needed.

matjack1 commented 1 year ago

I have merged the fix on dev but if the problem persists, please reopen