function Printer_printFromFile($gcode_path, $model_id, $time_estimation, $need_prime = TRUE, $exchange_extruder = FALSE, $array_filament = array(), $array_temper = array()) { global $CFG; $command = ''; $output = array(); $temper_json = array(); $ret_val = 0; $stats_info = array(); $CI =& get_instance(); $CI->load->helper(array('printerstate', 'errorcode', 'corestatus', 'printerlog', 'detectos')); // check if we have no file if (!file_exists($gcode_path)) { return ERROR_INTERNAL; } // only check if we are in printing when we are not called stopping printing // if ($stop_printing == FALSE) { // check if in printing $ret_val = PrinterState_checkInPrint(); if ($ret_val == TRUE) { // return ERROR_IN_PRINT; PrinterLog_logMessage('already in printing', __FILE__, __LINE__); return ERROR_BUSY_PRINTER; } // } // check extruder number if ($CI->config->item('nb_extruder') < 2) { $tmp_array = array(); $command = $CFG->config['gcanalyser'] . $gcode_path; exec($command, $output, $ret_val); if ($ret_val != ERROR_NORMAL_RC_OK) { PrinterLog_logError('gcanalyser error', __FILE__, __LINE__); return ERROR_INTERNAL; } $tmp_array = json_decode($output[0], TRUE); if ($tmp_array['N'] > $CI->config->item('nb_extruder')) { PrinterLog_logMessage('no enough extruder', __FILE__, __LINE__); return ERROR_INTERNAL; } } // check if having enough filament $ret_val = PrinterState_checkFilaments($array_filament); if ($ret_val != ERROR_OK) { return $ret_val; } if ($time_estimation == 0) { $ret_val = Printer__getEstimation($array_filament, $time_estimation); if ($ret_val != TRUE) { PrinterLog_logError('system can not get estimation time'); return ERROR_INTERNAL; } } // prepare subprinting gcode files and scripts $ret_val = Printer_preparePrint($model_id, $need_prime); if ($ret_val != ERROR_OK) { return $ret_val; } // if ($stop_printing == FALSE) { if ($CFG->config['simulator']) { // just set temperature for simulation PrinterState_setExtruder('r'); PrinterState_setTemperature(210); PrinterState_setExtruder('l'); PrinterState_setTemperature(200); PrinterState_setExtruder('r'); } // change status json file foreach ($array_temper as $abb_filament => $tmp_temper) { if ($abb_filament != 'b' && (!array_key_exists($abb_filament, $array_filament) || $array_filament[$abb_filament] <= 0)) { $temper_json[$abb_filament] = NULL; } else { $temper_json[$abb_filament] = $array_temper[$abb_filament]; } } $ret_val = CoreStatus_setInPrinting($model_id, $time_estimation, $exchange_extruder, $temper_json); // } // else { // $ret_val = CoreStatus_setInCanceling(); // } if ($ret_val == FALSE) { return ERROR_INTERNAL; } // stats info $stats_info[PRINTERLOG_STATS_MODEL] = $model_id; foreach ($temper_json as $abb_filament => $tmp_temper) { if (isset($tmp_temper)) { $json_cartridge = array(); $arrkey_type = PRINTERLOG_STATS_FILA_TYPE_R; $arrkey_color = PRINTERLOG_STATS_FILA_COLOR_R; if ($abb_filament == 'l') { $arrkey_type = PRINTERLOG_STATS_FILA_TYPE_L; $arrkey_color = PRINTERLOG_STATS_FILA_COLOR_L; } if (ERROR_OK == PrinterState_getCartridgeAsArray($json_cartridge, $abb_filament)) { $stats_info[$arrkey_type] = $json_cartridge[PRINTERSTATE_TITLE_MATERIAL]; $stats_info[$arrkey_color] = $json_cartridge[PRINTERSTATE_TITLE_COLOR]; } } } PrinterLog_statsPrint(PRINTERLOG_STATS_ACTION_START, $stats_info); // pass gcode to printer // if (!PrinterState_beforeFileCommand()) { // return ERROR_INTERNAL; // } // use different command for priming if ($need_prime == FALSE) { $command = PrinterState_getPrintCommand($array_filament, TRUE, TRUE) . $gcode_path; } else { $command = PrinterState_getPrintCommand($array_filament) . $gcode_path; } // exec($command, $output, $ret_val); // if ($ret_val != ERROR_NORMAL_RC_OK) { // return ERROR_INTERNAL; // } if ($CFG->config['simulator'] && DectectOS_checkWindows()) { pclose(popen($command, 'r')); // only for windows arcontrol client PrinterLog_logArduino($command); } else { // exec($command, $output, $ret_val); pclose(popen($command . ' > ' . PRINTERSTATE_FILE_PRINTLOG . ' &', 'r')); // if (!PrinterState_filterOutput($output)) { // PrinterLog_logError('filter arduino output error', __FILE__, __LINE__); // return ERROR_INTERNAL; // } // if ($ret_val != ERROR_NORMAL_RC_OK) { // return $ret_val; // } // PrinterLog_logArduino($command, $output); PrinterLog_logArduino($command); } // if (!PrinterState_afterFileCommand()) { // return ERROR_INTERNAL; // } return ERROR_OK; }
function PrinterState_checkBusyStatus(&$status_current, &$array_data = array()) { $ret_val = 0; $time_wait = NULL; $time_max = NULL; // $temp_status = NULL; $temp_array = array(); $CI =& get_instance(); $CI->load->helper('corestatus'); switch ($status_current) { case CORESTATUS_VALUE_WAIT_CONNECT: $ret_val = CoreStatus_checkInConnection(); if ($ret_val == FALSE) { CoreStatus_setInIdle(); $status_current = CORESTATUS_VALUE_IDLE; return TRUE; } break; case CORESTATUS_VALUE_CANCEL: // jump out if it's a simulator or when cancelling is finished if ($CI->config->item('simulator') || !file_exists(PRINTERSTATE_FILE_STOPFILE)) { $stats_info = PrinterState_prepareStatsPrintLabel(); PrinterLog_statsPrint(PRINTERLOG_STATS_ACTION_CANCEL, $stats_info); CoreStatus_setInIdle(); $status_current = CORESTATUS_VALUE_IDLE; return TRUE; } break; case CORESTATUS_VALUE_SLICE: // get percentage and check finished or not $progress = 0; $message = NULL; $array_slicer = array(); $CI->load->helper('slicer'); $ret_val = Slicer_checkSlice($progress, $message, $array_slicer); if ($ret_val != ERROR_OK) { $error_message = NULL; $url_remote = NULL; $stats_info = array(); // handle error for slicing $CI->load->helper('printerlog'); $url_remote = PRINTERLOG_STATS_VALUE_LOCAL; $array_data[PRINTERSTATE_TITLE_LASTERROR] = $ret_val; $status_current = CORESTATUS_VALUE_IDLE; switch ($ret_val) { //TODO treat the error with api and ui case ERROR_NO_SLICING: $error_message = 'not in slicing'; break; case ERROR_WRONG_PRM: $error_message = 'slicer error'; // perhaps because of parameter break; case ERROR_UNKNOWN_MODEL: $error_message = 'slicer export error'; // perhaps because of model break; case ERROR_REMOTE_SLICE: $error_message = 'remote slicer error'; $url_remote = $message; break; default: $error_message = 'slicer internal error'; // internal system error PrinterLog_logDebug('return: ' . $ret_val . ', progress: ' . $progress); break; } PrinterLog_logMessage($error_message, __FILE__, __LINE__); CoreStatus_setInIdle($ret_val, $error_message); $array_data[PRINTERSTATE_TITLE_DETAILMSG] = $error_message; // stats info $stats_info = PrinterState_prepareStatsSliceLabel(); $stats_info[PRINTERLOG_STATS_SLICE_ERROR] = $error_message; $stats_info[PRINTERLOG_STATS_SLICE_SERVER] = $url_remote; PrinterLog_statsSlice(PRINTERLOG_STATS_ACTION_ERROR, $stats_info); return TRUE; } elseif ($progress == 100) { $url_remote = NULL; $stats_info = array(); // set temp json file for every service $ret_val = PrinterState__setSlicedJson($array_slicer); $status_current = CORESTATUS_VALUE_IDLE; if ($ret_val != ERROR_OK) { $array_data[PRINTERSTATE_TITLE_LASTERROR] = $ret_val; CoreStatus_setInIdle($ret_val); } else { CoreStatus_setInIdle(); } // stats info $CI->load->helper('printerlog'); $stats_info = PrinterState_prepareStatsSliceLabel(TRUE); //detect remote slicing if (file_exists(SLICER_FILE_REMOTE_REQUEST_URL)) { $url_remote = trim(@file_get_contents(SLICER_FILE_REMOTE_REQUEST_URL)); if (strlen($url_remote) == 0) { $url_remote = PRINTERLOG_STATS_VALUE_REMOTE; } } else { $url_remote = PRINTERLOG_STATS_VALUE_LOCAL; } $stats_info[PRINTERLOG_STATS_SLICE_SERVER] = $url_remote; PrinterLog_statsSlice(PRINTERLOG_STATS_ACTION_END, $stats_info); return TRUE; } else { // still in slicing, so get percentage (estimated time is useless for now, slicer exports percentage badly) $array_data[PRINTERSTATE_TITLE_PERCENT] = $progress; $array_data[PRINTERSTATE_TITLE_DETAILMSG] = $message; } break; case CORESTATUS_VALUE_LOAD_FILA_L: case CORESTATUS_VALUE_LOAD_FILA_R: // CoreStatus_checkInIdle($temp_status, $temp_array); CoreStatus_getStatusArray($temp_array); if (array_key_exists(CORESTATUS_TITLE_FILA_MAT, $temp_array) && $temp_array[CORESTATUS_TITLE_FILA_MAT] == PRINTERSTATE_DESP_MATERIAL_PVA) { $time_wait = PRINTERSTATE_VALUE_OFFSET_TO_CHECK_LOAD_PVA; $time_max = PRINTERSTATE_VALUE_TIMEOUT_TO_CHECK_LOAD_PVA; } else { $time_wait = PRINTERSTATE_VALUE_OFFSET_TO_CHECK_LOAD; $time_max = PRINTERSTATE_VALUE_TIMEOUT_TO_CHECK_LOAD; } case CORESTATUS_VALUE_UNLOAD_FILA_L: case CORESTATUS_VALUE_UNLOAD_FILA_R: $abb_filament = 'r'; $status_fin_filament = FALSE; if (in_array($status_current, array(CORESTATUS_VALUE_LOAD_FILA_L, CORESTATUS_VALUE_UNLOAD_FILA_L))) { $abb_filament = 'l'; $status_fin_filament = TRUE; } if (is_null($time_wait) || is_null($time_max)) { if (file_exists(PRINTERSTATE_FILE_UNLOAD_HEAT)) { $time_start = @file_get_contents(PRINTERSTATE_FILE_UNLOAD_HEAT); if (is_null($time_start)) { PrinterLog_logError('check unload heat status file error', __FILE__, __LINE__); break; } else { if (time() - $time_start <= PRINTERSTATE_VALUE_TIMEOUT_UNLOAD_HEAT) { // block the status if in timeout, and refresh the start time for the following state CoreStatus_setInUnloading($abb_filament); break; } else { // always in heating when we passed timeout, we unlock the mobile site PrinterLog_logError('always in heating process when we unload filament', __FILE__, __LINE__); @unlink(PRINTERSTATE_FILE_UNLOAD_HEAT); $ret_val = CoreStatus_setInIdle(); if ($ret_val == TRUE) { $status_current = CORESTATUS_VALUE_IDLE; return TRUE; } $CI->load->helper('printerlog'); PrinterLog_logError('can not set status into idle', __FILE__, __LINE__); break; } } } // CoreStatus_checkInIdle($temp_status, $temp_array); CoreStatus_getStatusArray($temp_array); if (array_key_exists(CORESTATUS_TITLE_FILA_MAT, $temp_array) && $temp_array[CORESTATUS_TITLE_FILA_MAT] == PRINTERSTATE_DESP_MATERIAL_PVA) { $time_wait = PRINTERSTATE_VALUE_OFFSET_TO_CHECK_UNLOAD_PVA; $time_max = PRINTERSTATE_VALUE_TIMEOUT_TO_CHECK_UNLOAD_PVA; } else { $time_wait = PRINTERSTATE_VALUE_OFFSET_TO_CHECK_UNLOAD; $time_max = PRINTERSTATE_VALUE_TIMEOUT_TO_CHECK_UNLOAD; } } // wait the time for arduino before checking filament when loading / unloading filament if (CoreStatus_checkInWaitTime($time_wait)) { break; } // generate parameters by different status $ret_val = PrinterState_getFilamentStatus($abb_filament); if ($ret_val == $status_fin_filament || !CoreStatus_checkInWaitTime($time_max)) { if ($ret_val != $status_fin_filament) { $CI->load->helper('printerlog'); PrinterLog_logError('we pass timeout when we are in changing catridge, status: ' . $status_current, __FILE__, __LINE__); } $ret_val = CoreStatus_setInIdle(); if ($ret_val == TRUE) { $status_current = CORESTATUS_VALUE_IDLE; return TRUE; // continue to generate if we are now in idle } $CI->load->helper('printerlog'); PrinterLog_logError('can not set status into idle', __FILE__, __LINE__); } break; case CORESTATUS_VALUE_PRINT: $output = array(); $command = $CI->config->item('arcontrol_c') . PRINTERSTATE_CHECK_STATE; if (file_exists($CI->config->item('printstatus'))) { $output = @file($CI->config->item('printstatus')); if (count($output) == 0) { // case: read the percentage status file when arcontrol_cli is writing in it // so we let the percentage as 1 to continue printing $output = array('1'); $CI->load->helper('printerlog'); PrinterLog_logDebug('read percentage file when arcontrol_cli wrinting in it', __FILE__, __LINE__); } } else { $output = array('0'); } PrinterLog_logArduino($command, $output); // if (count($output)) { // // we have right return if ((int) $output[0] == 0) { $stats_info = array(); // not in printing(?), now we consider it is just idle (no slicing) $CI->load->helper('printerlog'); PrinterLog_logDebug('check in idle - checkstatusasarray', __FILE__, __LINE__); $status_current = CORESTATUS_VALUE_IDLE; if (!CoreStatus_setInIdle()) { PrinterLog_logError('cannot set in idle - checkstatusasarray', __FILE__, __LINE__); } //stats info $stats_info = PrinterState_prepareStatsPrintLabel(); PrinterLog_statsPrint(PRINTERLOG_STATS_ACTION_END, $stats_info); return TRUE; } else { $array_data[PRINTERSTATE_TITLE_PERCENT] = $output[0]; } // } // else { // $CI->load->helper('printerlog'); // PrinterLog_logError('print check status command error', __FILE__, __LINE__); // } break; default: // log internal API error $CI->load->helper('printerlog'); PrinterLog_logError('unknown status in work json', __FILE__, __LINE__); break; } return FALSE; // status has not changed }