Compare commits

...

2 Commits

3 changed files with 326 additions and 4 deletions

View File

@@ -13,6 +13,9 @@ bool sendOctoUpdate = false;
String octoUrl = ""; String octoUrl = "";
String octoToken = ""; String octoToken = "";
uint16_t remainingWeight = 0; uint16_t remainingWeight = 0;
uint16_t createdVendorId = 0; // Store ID of newly created vendor
uint16_t foundVendorId = 0; // Store ID of found vendor
uint16_t foundFilamentId = 0; // Store ID of found filament
bool spoolmanConnected = false; bool spoolmanConnected = false;
struct SendToApiParams { struct SendToApiParams {
@@ -114,6 +117,7 @@ void sendToApi(void *parameter) {
int httpCode; int httpCode;
if (httpType == "PATCH") httpCode = http.PATCH(updatePayload); if (httpType == "PATCH") httpCode = http.PATCH(updatePayload);
else if (httpType == "POST") httpCode = http.POST(updatePayload); else if (httpType == "POST") httpCode = http.POST(updatePayload);
else if (httpType == "GET") httpCode = http.GET();
else httpCode = http.PUT(updatePayload); else httpCode = http.PUT(updatePayload);
if (httpCode == HTTP_CODE_OK) { if (httpCode == HTTP_CODE_OK) {
@@ -153,6 +157,58 @@ void sendToApi(void *parameter) {
oledShowProgressBar(5, 5, "Spool Tag", ("Done: " + String(remainingWeight) + " g remain").c_str()); oledShowProgressBar(5, 5, "Spool Tag", ("Done: " + String(remainingWeight) + " g remain").c_str());
remainingWeight = 0; remainingWeight = 0;
break; break;
case API_REQUEST_VENDOR_CREATE:
Serial.println("Vendor successfully created!");
createdVendorId = doc["id"].as<uint16_t>();
Serial.print("Created Vendor ID: ");
Serial.println(createdVendorId);
oledShowProgressBar(1, 1, "Vendor", "Created!");
break;
case API_REQUEST_VENDOR_CHECK:
if (doc.isNull() || doc.size() == 0) {
Serial.println("Vendor not found in response");
foundVendorId = 0;
} else {
foundVendorId = doc[0]["id"].as<uint16_t>();
Serial.print("Found Vendor ID: ");
Serial.println(foundVendorId);
}
break;
case API_REQUEST_FILAMENT_CHECK:
if (doc.isNull() || doc.size() == 0) {
Serial.println("Filament not found in response");
foundFilamentId = 0;
} else {
foundFilamentId = doc[0]["id"].as<uint16_t>();
Serial.print("Found Filament ID: ");
Serial.println(foundFilamentId);
}
break;
}
}
doc.clear();
} else if (httpCode == HTTP_CODE_CREATED) {
Serial.println("Spoolman erfolgreich erstellt");
// Parse response for created resources
String payload = http.getString();
JsonDocument doc;
DeserializationError error = deserializeJson(doc, payload);
if (error) {
Serial.print("Fehler beim Parsen der JSON-Antwort: ");
Serial.println(error.c_str());
} else {
switch(requestType){
case API_REQUEST_VENDOR_CREATE:
Serial.println("Vendor successfully created!");
createdVendorId = doc["id"].as<uint16_t>();
Serial.print("Created Vendor ID: ");
Serial.println(createdVendorId);
oledShowProgressBar(1, 1, "Vendor", "Created!");
break;
default:
// Handle other create operations if needed
break;
} }
} }
doc.clear(); doc.clear();
@@ -169,6 +225,9 @@ void sendToApi(void *parameter) {
case API_REQUEST_BAMBU_UPDATE: case API_REQUEST_BAMBU_UPDATE:
oledShowProgressBar(1, 1, "Failure!", "Bambu update"); oledShowProgressBar(1, 1, "Failure!", "Bambu update");
break; break;
case API_REQUEST_VENDOR_CREATE:
oledShowProgressBar(1, 1, "Failure!", "Vendor create");
break;
} }
Serial.println("Fehler beim Senden an Spoolman! HTTP Code: " + String(httpCode)); Serial.println("Fehler beim Senden an Spoolman! HTTP Code: " + String(httpCode));
@@ -433,6 +492,238 @@ bool updateSpoolBambuData(String payload) {
return true; return true;
} }
// #### Filament Fabrik
uint16_t checkVendor(String vendor) {
// Check if vendor exists using task system
foundVendorId = 0; // Reset previous value
String spoolsUrl = spoolmanUrl + apiUrl + "/vendor?name=" + vendor;
Serial.print("Check vendor with URL: ");
Serial.println(spoolsUrl);
SendToApiParams* params = new SendToApiParams();
if (params == nullptr) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return 0;
}
params->requestType = API_REQUEST_VENDOR_CHECK;
params->httpType = "GET";
params->spoolsUrl = spoolsUrl;
params->updatePayload = ""; // Empty for GET request
// Check if API is idle before creating task
if(spoolmanApiState == API_IDLE){
// Erstelle die Task
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
} else {
Serial.println("Not spawning new task, API still active!");
delete params;
return 0;
}
// Wait for task completion
while(spoolmanApiState != API_IDLE) {
vTaskDelay(100 / portTICK_PERIOD_MS);
}
// Check if vendor was found
if (foundVendorId == 0) {
Serial.println("Vendor not found, creating new vendor...");
uint16_t vendorId = createVendor(vendor);
if (vendorId == 0) {
Serial.println("Failed to create vendor, returning 0.");
return 0; // Failed to create vendor
} else {
Serial.println("Vendor created with ID: " + String(vendorId));
checkFilament(vendorId);
return vendorId;
}
} else {
Serial.println("Vendor found: " + vendor);
Serial.print("Vendor ID: ");
Serial.println(foundVendorId);
return foundVendorId;
}
}
uint16_t createVendor(String vendor) {
// Create new vendor in Spoolman database using task system
// Note: Due to async nature, the ID will be stored in createdVendorId global variable
createdVendorId = 0; // Reset previous value
String spoolsUrl = spoolmanUrl + apiUrl + "/vendor";
Serial.print("Create vendor with URL: ");
Serial.println(spoolsUrl);
// Create JSON payload for vendor creation
JsonDocument vendorDoc;
vendorDoc["name"] = vendor;
vendorDoc["comment"] = "automatically generated";
vendorDoc["empty_spool_weight"] = 180;
vendorDoc["external_id"] = vendor;
String vendorPayload;
serializeJson(vendorDoc, vendorPayload);
Serial.print("Vendor Payload: ");
Serial.println(vendorPayload);
SendToApiParams* params = new SendToApiParams();
if (params == nullptr) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
vendorDoc.clear();
return 0;
}
params->requestType = API_REQUEST_VENDOR_CREATE;
params->httpType = "POST";
params->spoolsUrl = spoolsUrl;
params->updatePayload = vendorPayload;
// Check if API is idle before creating task
if(spoolmanApiState == API_IDLE){
// Erstelle die Task
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
} else {
Serial.println("Not spawning new task, API still active!");
delete params;
vendorDoc.clear();
return 0;
}
vendorDoc.clear();
// Wait for task completion and return the created vendor ID
// Note: createdVendorId will be set by sendToApi when response is received
while(spoolmanApiState != API_IDLE) {
vTaskDelay(100 / portTICK_PERIOD_MS);
}
return createdVendorId;
}
uint16_t checkFilament(uint16_t vendorId) {
// Check if filament exists using task system
foundFilamentId = 0; // Reset previous value
String spoolsUrl = spoolmanUrl + apiUrl + "/filament?vendor.id=" + String(vendorId);
Serial.print("Check filament with URL: ");
Serial.println(spoolsUrl);
SendToApiParams* params = new SendToApiParams();
if (params == nullptr) {
Serial.println("Fehler: Kann Speicher für Task-Parameter nicht allokieren.");
return 0;
}
params->requestType = API_REQUEST_FILAMENT_CHECK;
params->httpType = "GET";
params->spoolsUrl = spoolsUrl;
params->updatePayload = ""; // Empty for GET request
// Check if API is idle before creating task
if(spoolmanApiState == API_IDLE){
// Erstelle die Task
BaseType_t result = xTaskCreate(
sendToApi, // Task-Funktion
"SendToApiTask", // Task-Name
6144, // Stackgröße in Bytes
(void*)params, // Parameter
0, // Priorität
NULL // Task-Handle (nicht benötigt)
);
} else {
Serial.println("Not spawning new task, API still active!");
delete params;
return 0;
}
// Wait for task completion
while(spoolmanApiState != API_IDLE) {
vTaskDelay(100 / portTICK_PERIOD_MS);
}
// Check if filament was found
if (foundFilamentId == 0) {
Serial.println("Filament not found, creating new filament...");
uint16_t filamentId = createFilament();
if (filamentId == 0) {
Serial.println("Failed to create filament, returning 0.");
return 0; // Failed to create filament
} else {
Serial.println("Filament created with ID: " + String(filamentId));
checkSpool();
return filamentId;
}
} else {
Serial.println("Filament found for vendor ID: " + String(vendorId));
Serial.print("Filament ID: ");
Serial.println(foundFilamentId);
return foundFilamentId;
}
}
bool createFilament() {
// {
// "name": "PolyTerra Charcoal Black",
// "vendor_id": 0,
// "material": "PLA",
// "price": 20,
// "density": 1.24,
// "diameter": 1.75,
// "weight": 1000,
// "spool_weight": 140,
// "article_number": "PM70820",
// "comment": "automatically generated",
// "settings_extruder_temp": 210,
// "settings_bed_temp": 60,
// "color_hex": "FF0000",
// "multi_color_hexes": "FF0000,00FF00,0000FF",
// "multi_color_direction": "coaxial",
// "external_id": "polymaker_pla_polysonicblack_1000_175",
// "extra": {
// "nozzle_temperature": "string"
// }
// }
}
uint16_t checkSpool() {
}
bool createSpool() {
// Implement specific handling for Spool creation
// {
// "first_used": "2019-08-24T14:15:22Z",
// "last_used": "2019-08-24T14:15:22Z",
// "filament_id": 0,
// "price": 20,
// "initial_weight": 200,
// "spool_weight": 200,
// "remaining_weight": 800,
// "used_weight": 200,
// "location": "Shelf A",
// "lot_nr": "52342",
// "comment": "",
// "archived": false,
// "extra": {
// "nfc_id": "string"
// }
// }
}
// #### Spoolman init // #### Spoolman init
bool checkSpoolmanExtraFields() { bool checkSpoolmanExtraFields() {
HTTPClient http; HTTPClient http;

View File

@@ -17,7 +17,10 @@ typedef enum {
API_REQUEST_BAMBU_UPDATE, API_REQUEST_BAMBU_UPDATE,
API_REQUEST_SPOOL_TAG_ID_UPDATE, API_REQUEST_SPOOL_TAG_ID_UPDATE,
API_REQUEST_SPOOL_WEIGHT_UPDATE, API_REQUEST_SPOOL_WEIGHT_UPDATE,
API_REQUEST_SPOOL_LOCATION_UPDATE API_REQUEST_SPOOL_LOCATION_UPDATE,
API_REQUEST_VENDOR_CREATE,
API_REQUEST_VENDOR_CHECK,
API_REQUEST_FILAMENT_CHECK
} SpoolmanApiRequestType; } SpoolmanApiRequestType;
extern volatile spoolmanApiStateType spoolmanApiState; extern volatile spoolmanApiStateType spoolmanApiState;
@@ -27,6 +30,9 @@ extern bool octoEnabled;
extern bool sendOctoUpdate; extern bool sendOctoUpdate;
extern String octoUrl; extern String octoUrl;
extern String octoToken; extern String octoToken;
extern uint16_t createdVendorId; // ID of newly created vendor
extern uint16_t foundVendorId; // ID of found vendor
extern uint16_t foundFilamentId; // ID of found filament
extern bool spoolmanConnected; extern bool spoolmanConnected;
bool checkSpoolmanInstance(const String& url); bool checkSpoolmanInstance(const String& url);
@@ -40,5 +46,12 @@ uint8_t updateSpoolLocation(String spoolId, String location);
bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman bool initSpoolman(); // Neue Funktion zum Initialisieren von Spoolman
bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten bool updateSpoolBambuData(String payload); // Neue Funktion zum Aktualisieren der Bambu-Daten
bool updateSpoolOcto(int spoolId); // Neue Funktion zum Aktualisieren der Octo-Daten bool updateSpoolOcto(int spoolId); // Neue Funktion zum Aktualisieren der Octo-Daten
uint16_t checkVendor(String vendor); // Check if vendor exists, return ID
uint16_t createVendor(String vendor); // Create vendor, return ID
uint16_t checkFilament(); // Check if filament exists, return ID
bool createFilament(); // Create filament
uint16_t checkSpool(); // Check if spool exists, return ID
bool createSpool(); // Create spool
void createFilamentFabrik(JsonDocument payload);
#endif #endif

View File

@@ -37,6 +37,11 @@ volatile nfcReaderStateType nfcReaderState = NFC_IDLE;
// ***** PN532 // ***** PN532
// ##### Recycling Fabrik #####
bool isRecyclingFabrik(const char* brand) {
return strcmp(brand, "Recycling Fabrik") == 0;
}
// ##### Funktionen für RFID ##### // ##### Funktionen für RFID #####
void payloadToJson(uint8_t *data) { void payloadToJson(uint8_t *data) {
const char* startJson = strchr((char*)data, '{'); const char* startJson = strchr((char*)data, '{');
@@ -57,7 +62,13 @@ void payloadToJson(uint8_t *data) {
int min_temp = doc["min_temp"]; int min_temp = doc["min_temp"];
int max_temp = doc["max_temp"]; int max_temp = doc["max_temp"];
const char* brand = doc["brand"]; const char* brand = doc["brand"];
// Recycling Fabrik
if (isRecyclingFabrik(brand)) {
// TODO: Implement specific handling for Recycling Fabrik
Serial.println("Recycling Fabrik erkannt.");
}
Serial.println(); Serial.println();
Serial.println("-----------------"); Serial.println("-----------------");
Serial.println("JSON-Parsed Data:"); Serial.println("JSON-Parsed Data:");
@@ -215,7 +226,7 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
} }
// JSON-Dokument verarbeiten // JSON-Dokument verarbeiten
JsonDocument doc; // Passen Sie die Größe an den JSON-Inhalt an JsonDocument doc;
DeserializationError error = deserializeJson(doc, nfcJsonData); DeserializationError error = deserializeJson(doc, nfcJsonData);
if (error) if (error)
{ {
@@ -232,7 +243,7 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
// Sende die aktualisierten AMS-Daten an alle WebSocket-Clients // Sende die aktualisierten AMS-Daten an alle WebSocket-Clients
Serial.println("JSON-Dokument erfolgreich verarbeitet"); Serial.println("JSON-Dokument erfolgreich verarbeitet");
Serial.println(doc.as<String>()); Serial.println(doc.as<String>());
if (doc["sm_id"].is<String>() && doc["sm_id"] != "") if (doc["sm_id"].is<String>() && doc["sm_id"] != "" && doc["sm_id"] != "0")
{ {
oledShowProgressBar(2, octoEnabled?5:4, "Spool Tag", "Weighing"); oledShowProgressBar(2, octoEnabled?5:4, "Spool Tag", "Weighing");
Serial.println("SPOOL-ID gefunden: " + doc["sm_id"].as<String>()); Serial.println("SPOOL-ID gefunden: " + doc["sm_id"].as<String>());
@@ -254,6 +265,13 @@ bool decodeNdefAndReturnJson(const byte* encodedMessage) {
oledShowProgressBar(1, 1, "Failure", "Scan spool first"); oledShowProgressBar(1, 1, "Failure", "Scan spool first");
} }
} }
// Recycling Fabrik
else if (isRecyclingFabrik(doc["type"].as<String>().c_str())) {
// If no sm_id is present but the brand is Recycling Fabrik then
// create a new spool, maybe brand too, in Spoolman
Serial.println("Recycling Fabrik Tag found!");
createFilamentFabrik(doc);
}
else else
{ {
Serial.println("Keine SPOOL-ID gefunden."); Serial.println("Keine SPOOL-ID gefunden.");