|  |  | @@ -9,18 +9,6 @@ | 
			
		
	
		
		
			
				
					
					|  |  |  | #include <time.h> |  |  |  | #include <time.h> | 
			
		
	
		
		
			
				
					
					|  |  |  | volatile spoolmanApiStateType spoolmanApiState = API_IDLE; |  |  |  | volatile spoolmanApiStateType spoolmanApiState = API_IDLE; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // Returns current date and time in ISO8601 format |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | String getCurrentDateISO8601() { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     struct tm timeinfo; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if(!getLocalTime(&timeinfo)) { |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         Serial.println("Failed to obtain time"); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |         return "1970-01-01T00:00:00Z"; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     char timeStringBuff[25]; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     strftime(timeStringBuff, sizeof(timeStringBuff), "%Y-%m-%dT%H:%M:%SZ", &timeinfo); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return String(timeStringBuff); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | //bool spoolman_connected = false; |  |  |  | //bool spoolman_connected = false; | 
			
		
	
		
		
			
				
					
					|  |  |  | String spoolmanUrl = ""; |  |  |  | String spoolmanUrl = ""; | 
			
		
	
		
		
			
				
					
					|  |  |  | bool octoEnabled = false; |  |  |  | bool octoEnabled = false; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -170,7 +158,8 @@ void sendToApi(void *parameter) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 //oledShowMessage("Remaining: " + String(remaining_weight) + "g"); |  |  |  |                 //oledShowMessage("Remaining: " + String(remaining_weight) + "g"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 if(!octoEnabled){ |  |  |  |                 if(!octoEnabled){ | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // TBD: Do not use Strings... |  |  |  |                     // TBD: Do not use Strings... | 
			
		
	
		
		
			
				
					
					|  |  |  |                     oledShowProgressBar(1, 1, "Spool Tag", ("Done: " + String(remainingWeight) + " g remain").c_str()); |  |  |  |                     //oledShowProgressBar(1, 1, "Spool Tag", ("Done: " + String(remainingWeight) + " g remain").c_str()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                     oledShowMessage("Remaining: " + String(remainingWeight) + "g"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                     remainingWeight = 0; |  |  |  |                     remainingWeight = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 }else{ |  |  |  |                 }else{ | 
			
		
	
		
		
			
				
					
					|  |  |  |                     // ocoto is enabled, trigger octo update |  |  |  |                     // ocoto is enabled, trigger octo update | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -185,7 +174,8 @@ void sendToApi(void *parameter) { | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             case API_REQUEST_OCTO_SPOOL_UPDATE: |  |  |  |             case API_REQUEST_OCTO_SPOOL_UPDATE: | 
			
		
	
		
		
			
				
					
					|  |  |  |                 // TBD: Do not use Strings... |  |  |  |                 // TBD: Do not use Strings... | 
			
		
	
		
		
			
				
					
					|  |  |  |                 oledShowProgressBar(5, 5, "Spool Tag", ("Done: " + String(remainingWeight) + " g remain").c_str()); |  |  |  |                 //oledShowProgressBar(5, 5, "Spool Tag", ("Done: " + String(remainingWeight) + " g remain").c_str()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |                 oledShowMessage("Remaining: " + String(remainingWeight) + "g"); | 
			
		
	
		
		
			
				
					
					|  |  |  |                 remainingWeight = 0; |  |  |  |                 remainingWeight = 0; | 
			
		
	
		
		
			
				
					
					|  |  |  |                 break; |  |  |  |                 break; | 
			
		
	
		
		
			
				
					
					|  |  |  |             case API_REQUEST_VENDOR_CREATE: |  |  |  |             case API_REQUEST_VENDOR_CREATE: | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -614,6 +604,8 @@ bool updateSpoolBambuData(String payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | // #### Brand Filament |  |  |  | // #### Brand Filament | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t createVendor(String vendor) { |  |  |  | uint16_t createVendor(String vendor) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     oledShowProgressBar(2, 5, "New Brand", "Create new Vendor"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Create new vendor in Spoolman database using task system |  |  |  |     // Create new vendor in Spoolman database using task system | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: Due to async nature, the ID will be stored in createdVendorId global variable |  |  |  |     // Note: Due to async nature, the ID will be stored in createdVendorId global variable | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: This function assumes that the caller has already ensured API is IDLE |  |  |  |     // Note: This function assumes that the caller has already ensured API is IDLE | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -627,7 +619,6 @@ uint16_t createVendor(String vendor) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     JsonDocument vendorDoc; |  |  |  |     JsonDocument vendorDoc; | 
			
		
	
		
		
			
				
					
					|  |  |  |     vendorDoc["name"] = vendor; |  |  |  |     vendorDoc["name"] = vendor; | 
			
		
	
		
		
			
				
					
					|  |  |  |     vendorDoc["comment"] = "automatically generated"; |  |  |  |     vendorDoc["comment"] = "automatically generated"; | 
			
		
	
		
		
			
				
					
					|  |  |  |     vendorDoc["empty_spool_weight"] = 180; |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     vendorDoc["external_id"] = vendor; |  |  |  |     vendorDoc["external_id"] = vendor; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     String vendorPayload; |  |  |  |     String vendorPayload; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -665,6 +656,9 @@ uint16_t createVendor(String vendor) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     vendorDoc.clear(); |  |  |  |     vendorDoc.clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Delay for Display Bar | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     vTaskDelay(1000 / portTICK_PERIOD_MS); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Wait for task completion and return the created vendor ID |  |  |  |     // Wait for task completion and return the created vendor ID | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: createdVendorId will be set by sendToApi when response is received |  |  |  |     // Note: createdVendorId will be set by sendToApi when response is received | 
			
		
	
		
		
			
				
					
					|  |  |  |     while(createdVendorId == 65535) { |  |  |  |     while(createdVendorId == 65535) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -675,6 +669,8 @@ uint16_t createVendor(String vendor) { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t checkVendor(String vendor) { |  |  |  | uint16_t checkVendor(String vendor) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     oledShowProgressBar(1, 5, "New Brand", "Check Vendor"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Check if vendor exists using task system |  |  |  |     // Check if vendor exists using task system | 
			
		
	
		
		
			
				
					
					|  |  |  |     foundVendorId = 65535; // Reset to invalid value to detect when API response is received |  |  |  |     foundVendorId = 65535; // Reset to invalid value to detect when API response is received | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -737,6 +733,8 @@ uint16_t checkVendor(String vendor) { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) { |  |  |  | uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     oledShowProgressBar(4, 5, "New Brand", "Create Filament"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Create new filament in Spoolman database using task system |  |  |  |     // Create new filament in Spoolman database using task system | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: Due to async nature, the ID will be stored in createdFilamentId global variable |  |  |  |     // Note: Due to async nature, the ID will be stored in createdFilamentId global variable | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: This function assumes that the caller has already ensured API is IDLE |  |  |  |     // Note: This function assumes that the caller has already ensured API is IDLE | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -748,34 +746,34 @@ uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Create JSON payload for filament creation |  |  |  |     // Create JSON payload for filament creation | 
			
		
	
		
		
			
				
					
					|  |  |  |     JsonDocument filamentDoc; |  |  |  |     JsonDocument filamentDoc; | 
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["name"] = payload["color_name"].as<String>(); |  |  |  |     filamentDoc["name"] = payload["cn"].as<String>(); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["vendor_id"] = String(vendorId); |  |  |  |     filamentDoc["vendor_id"] = String(vendorId); | 
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["material"] = payload["type"].as<String>(); |  |  |  |     filamentDoc["material"] = payload["t"].as<String>(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["density"] = (payload["density"].is<String>() && payload["density"].as<String>().length() > 0) ? payload["density"].as<String>() : "1.24"; |  |  |  |     filamentDoc["density"] = (payload["de"].is<String>() && payload["de"].as<String>().length() > 0) ? payload["de"].as<String>() : "1.24"; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["diameter"] = (payload["diameter"].is<String>() && payload["diameter"].as<String>().length() > 0) ? payload["diameter"].as<String>() : "1.75"; |  |  |  |     filamentDoc["diameter"] = (payload["di"].is<String>() && payload["di"].as<String>().length() > 0) ? payload["di"].as<String>() : "1.75"; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["weight"] = String(weight); |  |  |  |     filamentDoc["weight"] = String(weight); | 
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["spool_weight"] = payload["spool_weight"].as<String>(); |  |  |  |     filamentDoc["spool_weight"] = payload["sw"].as<String>(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["article_number"] = payload["artnr"].as<String>(); |  |  |  |     filamentDoc["article_number"] = payload["an"].as<String>(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["settings_extruder_temp"] = payload["extruder_temp"].is<String>() ? payload["extruder_temp"].as<String>() : ""; |  |  |  |     filamentDoc["settings_extruder_temp"] = payload["et"].is<String>() ? payload["et"].as<String>() : ""; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc["settings_bed_temp"] = payload["bed_temp"].is<String>() ? payload["bed_temp"].as<String>() : ""; |  |  |  |     filamentDoc["settings_bed_temp"] = payload["bt"].is<String>() ? payload["bt"].as<String>() : ""; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (payload["artnr"].is<String>()) |  |  |  |     if (payload["an"].is<String>()) | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         filamentDoc["external_id"] = payload["artnr"].as<String>(); |  |  |  |         filamentDoc["external_id"] = payload["an"].as<String>(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         filamentDoc["comment"] = payload["url"].is<String>() ? payload["url"].as<String>() + payload["artnr"].as<String>() : "automatically generated"; |  |  |  |         filamentDoc["comment"] = payload["u"].is<String>() ? payload["u"].as<String>() + payload["an"].as<String>() : "automatically generated"; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         filamentDoc["comment"] = payload["url"].is<String>() ? payload["url"].as<String>() : "automatically generated"; |  |  |  |         filamentDoc["comment"] = payload["u"].is<String>() ? payload["u"].as<String>() : "automatically generated"; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     if (payload["multi_color_hexes"].is<String>()) { |  |  |  |     if (payload["mc"].is<String>()) { | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         filamentDoc["multi_color_hexes"] = payload["multi_color_hexes"].as<String>(); |  |  |  |         filamentDoc["multi_color_hexes"] = payload["mc"].as<String>(); | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |         filamentDoc["multi_color_direction"] = payload["multi_color_direction"].is<String>() ? payload["multi_color_direction"].as<String>() : ""; |  |  |  |         filamentDoc["multi_color_direction"] = payload["mcd"].is<String>() ? payload["mcd"].as<String>() : ""; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |     else |  |  |  |     else | 
			
		
	
		
		
			
				
					
					|  |  |  |     { |  |  |  |     { | 
			
		
	
		
		
			
				
					
					|  |  |  |         filamentDoc["color_hex"] = (payload["color_hex"].is<String>() && payload["color_hex"].as<String>().length() >= 6) ? payload["color_hex"].as<String>() : "FFFFFF"; |  |  |  |         filamentDoc["color_hex"] = (payload["c"].is<String>() && payload["c"].as<String>().length() >= 6) ? payload["c"].as<String>() : "FFFFFF"; | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     } |  |  |  |     } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     String filamentPayload; |  |  |  |     String filamentPayload; | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -813,6 +811,9 @@ uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     filamentDoc.clear(); |  |  |  |     filamentDoc.clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Delay for Display Bar | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     vTaskDelay(1000 / portTICK_PERIOD_MS); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Wait for task completion and return the created filament ID |  |  |  |     // Wait for task completion and return the created filament ID | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: createdFilamentId will be set by sendToApi when response is received |  |  |  |     // Note: createdFilamentId will be set by sendToApi when response is received | 
			
		
	
		
		
			
				
					
					|  |  |  |     while(createdFilamentId == 65535) { |  |  |  |     while(createdFilamentId == 65535) { | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -823,6 +824,8 @@ uint16_t createFilament(uint16_t vendorId, const JsonDocument& payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t checkFilament(uint16_t vendorId, const JsonDocument& payload) { |  |  |  | uint16_t checkFilament(uint16_t vendorId, const JsonDocument& payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     oledShowProgressBar(3, 5, "New Brand", "Check Filament"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Check if filament exists using task system |  |  |  |     // Check if filament exists using task system | 
			
		
	
		
		
			
				
					
					|  |  |  |     foundFilamentId = 65535; // Reset to invalid value to detect when API response is received |  |  |  |     foundFilamentId = 65535; // Reset to invalid value to detect when API response is received | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -875,6 +878,8 @@ uint16_t checkFilament(uint16_t vendorId, const JsonDocument& payload) { | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& payload, String uidString) { |  |  |  | uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& payload, String uidString) { | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     oledShowProgressBar(5, 5, "New Brand", "Create new Spool"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Create new spool in Spoolman database using task system |  |  |  |     // Create new spool in Spoolman database using task system | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: Due to async nature, the ID will be stored in createdSpoolId global variable |  |  |  |     // Note: Due to async nature, the ID will be stored in createdSpoolId global variable | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Note: This function assumes that the caller has already ensured API is IDLE |  |  |  |     // Note: This function assumes that the caller has already ensured API is IDLE | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -883,17 +888,14 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo | 
			
		
	
		
		
			
				
					
					|  |  |  |     String spoolsUrl = spoolmanUrl + apiUrl + "/spool"; |  |  |  |     String spoolsUrl = spoolmanUrl + apiUrl + "/spool"; | 
			
		
	
		
		
			
				
					
					|  |  |  |     Serial.print("Create spool with URL: "); |  |  |  |     Serial.print("Create spool with URL: "); | 
			
		
	
		
		
			
				
					
					|  |  |  |     Serial.println(spoolsUrl); |  |  |  |     Serial.println(spoolsUrl); | 
			
		
	
		
		
			
				
					
					|  |  |  |     //String currentDate = getCurrentDateISO8601(); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Create JSON payload for spool creation |  |  |  |     // Create JSON payload for spool creation | 
			
		
	
		
		
			
				
					
					|  |  |  |     JsonDocument spoolDoc; |  |  |  |     JsonDocument spoolDoc; | 
			
		
	
		
		
			
				
					
					|  |  |  |     //spoolDoc["first_used"] = String(currentDate); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     //spoolDoc["last_used"] = String(currentDate); |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["filament_id"] = String(filamentId); |  |  |  |     spoolDoc["filament_id"] = String(filamentId); | 
			
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["initial_weight"] = weight > 10 ? String(weight-payload["spool_weight"].as<int>()) : "1000"; |  |  |  |     spoolDoc["initial_weight"] = weight > 10 ? String(weight - payload["sw"].as<int>()) : "1000"; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["spool_weight"] = (payload["spool_weight"].is<String>() && payload["spool_weight"].as<String>().length() > 0) ? payload["spool_weight"].as<String>() : "180"; |  |  |  |     spoolDoc["spool_weight"] = (payload["sw"].is<String>() && payload["sw"].as<String>().length() > 0) ? payload["sw"].as<String>() : "180"; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["remaining_weight"] = (payload["weight"].is<String>() && payload["weight"].as<String>().length() > 0) ? payload["weight"].as<String>() : "1000"; |  |  |  |     spoolDoc["remaining_weight"] = spoolDoc["initial_weight"]; | 
			
				
				
			
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["lot_nr"] = (payload["lotnr"].is<String>() && payload["lotnr"].as<String>().length() > 0) ? payload["lotnr"].as<String>() : ""; |  |  |  |     spoolDoc["lot_nr"] = (payload["an"].is<String>() && payload["an"].as<String>().length() > 0) ? payload["an"].as<String>() : ""; | 
			
				
				
			
		
	
		
		
	
		
		
	
		
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["comment"] = "automatically generated"; |  |  |  |     spoolDoc["comment"] = "automatically generated"; | 
			
		
	
		
		
			
				
					
					|  |  |  |     spoolDoc["extra"]["nfc_id"] = "\"" + uidString + "\""; |  |  |  |     spoolDoc["extra"]["nfc_id"] = "\"" + uidString + "\""; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
	
		
		
			
				
					
					|  |  | @@ -938,20 +940,33 @@ uint16_t createSpool(uint16_t vendorId, uint16_t filamentId, JsonDocument& paylo | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     // Write data to tag with startWriteJsonToTag |  |  |  |     // Write data to tag with startWriteJsonToTag | 
			
		
	
		
		
			
				
					
					|  |  |  |     // void startWriteJsonToTag(const bool isSpoolTag, const char* payload); |  |  |  |     // void startWriteJsonToTag(const bool isSpoolTag, const char* payload); | 
			
		
	
		
		
			
				
					
					|  |  |  |     payload["sm_id"].set(String(createdSpoolId)); |  |  |  |      | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Create optimized JSON structure with sm_id at the beginning for fast-path detection | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     JsonDocument optimizedPayload; | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     optimizedPayload["sm_id"] = String(createdSpoolId);  // Place sm_id first for fast scanning | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     optimizedPayload["b"] = payload["b"].as<String>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     optimizedPayload["cn"] = payload["an"].as<String>(); | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     String payloadString; |  |  |  |     String payloadString; | 
			
		
	
		
		
			
				
					
					|  |  |  |     serializeJson(payload, payloadString); |  |  |  |     serializeJson(optimizedPayload, payloadString); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Serial.println("Optimized JSON with sm_id first:"); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     Serial.println(payloadString); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     optimizedPayload.clear(); | 
			
		
	
		
		
			
				
					
					|  |  |  |      |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     nfcReaderState = NFC_IDLE; |  |  |  |     nfcReaderState = NFC_IDLE; | 
			
		
	
		
		
			
				
					
					|  |  |  |     vTaskDelay(50 / portTICK_PERIOD_MS); |  |  |  |  | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     // Delay for Display Bar | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |     vTaskDelay(1000 / portTICK_PERIOD_MS); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |      | 
			
		
	
		
		
			
				
					
					|  |  |  |     startWriteJsonToTag(true, payloadString.c_str()); |  |  |  |     startWriteJsonToTag(true, payloadString.c_str()); | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  |     return createdSpoolId; |  |  |  |     return createdSpoolId; | 
			
		
	
		
		
			
				
					
					|  |  |  | } |  |  |  | } | 
			
		
	
		
		
			
				
					
					|  |  |  |  |  |  |  |  | 
			
		
	
		
		
			
				
					
					|  |  |  | bool createBrandFilament(JsonDocument& payload, String uidString) { |  |  |  | bool createBrandFilament(JsonDocument& payload, String uidString) { | 
			
		
	
		
		
			
				
					
					|  |  |  |     uint16_t vendorId = checkVendor(payload["brand"].as<String>()); |  |  |  |     uint16_t vendorId = checkVendor(payload["b"].as<String>()); | 
			
				
				
			
		
	
		
		
	
		
		
			
				
					
					|  |  |  |     if (vendorId == 0) { |  |  |  |     if (vendorId == 0) { | 
			
		
	
		
		
			
				
					
					|  |  |  |         Serial.println("ERROR: Failed to create/find vendor"); |  |  |  |         Serial.println("ERROR: Failed to create/find vendor"); | 
			
		
	
		
		
			
				
					
					|  |  |  |         return false; |  |  |  |         return false; | 
			
		
	
	
		
		
			
				
					
					|  |  |   |