Example #1
0
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;
}
Example #2
0
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
}