Beispiel #1
0
/*
 * rpt_populate_filtered_status_report() - populate cmdObj body with status values
 *
 *	Designed to be displayed as a JSON object; i;e; no footer or header
 *	Returns 'true' if the report has new data, 'false' if there is nothing to report.
 *
 *	NOTE: Unlike rpt_populate_unfiltered_status_report(), this function does NOT set 
 *	the SR index, which is a relatively expensive operation. In current use this 
 *	doesn't matter, but if the caller assumes its set it may lead to a side-effect (bug)
 *
 *	NOTE: Room for improvement - look up the SR index initially and cache it, use the 
 *		  cached value for all remaining reports.
 */
uint8_t rpt_populate_filtered_status_report()
{
	uint8_t has_data = false;
	char tmp[CMD_TOKEN_LEN+1];
	cmdObj_t *cmd = cmd_reset_list();		// sets cmd to the start of the body

	cmd->objtype = TYPE_PARENT; 			// setup the parent object
	strcpy(cmd->token, "sr");
//	sprintf_P(cmd->token, PSTR("sr"));		// alternate form of above: less RAM, more FLASH & cycles
//	cmd->index = cmd_get_index("","sr");	// OMITTED - set the index - may be needed by calling function
	cmd = cmd->nx;							// no need to check for NULL as list has just been reset

	for (uint8_t i=0; i<CMD_STATUS_REPORT_LEN; i++) {
		if ((cmd->index = cfg.status_report_list[i]) == 0) { break;}

		cmd_get_cmdObj(cmd);
		if (cfg.status_report_value[i] == cmd->value) {	// float == comparison runs the risk of overreporting. So be it
			cmd->objtype = TYPE_EMPTY;
			continue;
		} else {
			strcpy(tmp, cmd->group);		// flatten out groups
			strcat(tmp, cmd->token);
			strcpy(cmd->token, tmp);
			cfg.status_report_value[i] = cmd->value;
			if ((cmd = cmd->nx) == NULL) return (false); // should never be NULL unless SR length exceeds available buffer array
			has_data = true;
		}
	}
//	cmd->pv->nx = NULL;						// back up one and terminate the body
	return (has_data);
}
Beispiel #2
0
static stat_t _homing_error_exit(int8_t axis)
{
	// Generate the warning message. Since the error exit returns via the homing callback
	// - and not the main controller - it requires its own display processing
	cmd_reset_list();

	if (axis == -2) {
		cmd_add_conditional_message((const char_t *)"*** WARNING *** Homing error: Specified axis(es) cannot be homed");;
	} else {
		char message[CMD_MESSAGE_LEN];
		sprintf_P(message, PSTR("*** WARNING *** Homing error: %c axis settings misconfigured"), cm_get_axis_char(axis));
		cmd_add_conditional_message((char_t *)message);
	}
	cmd_print_list(STAT_HOMING_CYCLE_FAILED, TEXT_INLINE_VALUES, JSON_RESPONSE_FORMAT);

	// clean up and exit
	mp_flush_planner(); 						// should be stopped, but in case of switch closure
												// don't use cm_request_queue_flush() here
	cm_set_coord_system(hm.saved_coord_system);	// restore to work coordinate system
	cm_set_units_mode(hm.saved_units_mode);
	cm_set_distance_mode(hm.saved_distance_mode);
	cm_set_feed_rate(hm.saved_feed_rate);
	cm_set_motion_mode(MODEL, MOTION_MODE_CANCEL_MOTION_MODE);
	cm.cycle_state = CYCLE_OFF;
	cm_cycle_end();
	return (STAT_HOMING_CYCLE_FAILED);			// homing state remains HOMING_NOT_HOMED
}
Beispiel #3
0
void _startup_helper(uint8_t status, const char *msg)
{
#ifndef __SUPPRESS_STARTUP_MESSAGES
	cmd_reset_list();
	cmd_add_object("fb");
	cmd_add_object("fv");
	cmd_add_object("hv");
	cmd_add_object("id");
	cmd_add_string_P("msg", msg);
	js_print_json_response(status);
#endif
}
Beispiel #4
0
/* 
 * rpt_init_status_report()
 *
 *	Call this function to completely re-initialze the status report
 *	Sets SR list to hard-coded defaults and re-initializes sr values in NVM
 */
void rpt_init_status_report()
{
	cmdObj_t *cmd = cmd_reset_list();	// used for status report persistence locations
	char sr_defaults[CMD_STATUS_REPORT_LEN][CMD_TOKEN_LEN+1] = { SR_DEFAULTS };	// see settings.h
	cm.status_report_counter = (cfg.status_report_interval / RTC_MILLISECONDS);	// RTC fires every 10 ms

	cmd->index = cmd_get_index("","se00");				// set first SR persistence index
	for (uint8_t i=0; i < CMD_STATUS_REPORT_LEN ; i++) {
		if (sr_defaults[i][0] == NUL) break;			// quit on first blank array entry
		cfg.status_report_value[i] = -1234567;			// pre-load values with an unlikely number
		cmd->value = cmd_get_index("", sr_defaults[i]);	// load the index for the SR element
		cmd_set(cmd);
		cmd_persist(cmd);								// conditionally persist - automatic by cmd_persis()
		cmd->index++;									// increment SR NVM index
	}
}
Beispiel #5
0
void rpt_populate_unfiltered_status_report()
{
	char tmp[CMD_TOKEN_LEN+1];
	cmdObj_t *cmd = cmd_reset_list();		// sets *cmd to the start of the body
	cmd->objtype = TYPE_PARENT; 			// setup the parent object
	strcpy(cmd->token, "sr");
//	sprintf_P(cmd->token, PSTR("sr"));		// alternate form of above: less RAM, more FLASH & cycles
	cmd->index = cmd_get_index("","sr");	// set the index - may be needed by calling function
	cmd = cmd->nx;							// no need to check for NULL as list has just been reset

	for (uint8_t i=0; i<CMD_STATUS_REPORT_LEN; i++) {
		if ((cmd->index = cfg.status_report_list[i]) == 0) { break;}
		cmd_get_cmdObj(cmd);
		strcpy(tmp, cmd->group);			// concatenate groups and tokens
		strcat(tmp, cmd->token);
		strcpy(cmd->token, tmp);
		if ((cmd = cmd->nx) == NULL) return; // should never be NULL unless SR length exceeds available buffer array 
	}
}
Beispiel #6
0
stat_t _json_parser_kernal(char *str)
{
	uint8_t status;
	int8_t depth;
	cmdObj_t *cmd = cmd_reset_list();			// get a fresh cmdObj list
	char group[CMD_GROUP_LEN+1] = {""};			// group identifier - starts as NUL
	int8_t i = CMD_BODY_LEN;

	ritorno(_normalize_json_string(str, JSON_OUTPUT_STRING_MAX));	// return if error

	// parse the JSON command into the cmd body
	do {
		if (--i == 0) { return (STAT_JSON_TOO_MANY_PAIRS); }			// length error
		if ((status = _get_nv_pair_strict(cmd, &str, &depth)) > STAT_EAGAIN) { // erred out
			return (status);
		}
		// propagate the group from previous NV pair (if relevant)
		if (group[0] != NUL) {
			strncpy(cmd->group, group, CMD_GROUP_LEN);// copy the parent's group to this child
		}
		// validate the token and get the index
		if ((cmd->index = cmd_get_index(cmd->group, cmd->token)) == NO_MATCH) { 
			return (STAT_UNRECOGNIZED_COMMAND);
		}
		if ((cmd_index_is_group(cmd->index)) && (cmd_group_is_prefixed(cmd->token))) {
			strncpy(group, cmd->token, CMD_GROUP_LEN);// record the group ID
		}
		if ((cmd = cmd->nx) == NULL) return (STAT_JSON_TOO_MANY_PAIRS);// Not supposed to encounter a NULL
	} while (status != STAT_OK);					// breaks when parsing is complete

	// execute the command
	cmd = cmd_body;
	if (cmd->objtype == TYPE_NULL){				// means GET the value
		ritorno(cmd_get(cmd));					// ritorno returns w/status on any errors
	} else {
		ritorno(cmd_set(cmd));					// set value or call a function (e.g. gcode)
		cmd_persist(cmd);
	}
	return (STAT_OK);								// only successful commands exit through this point
}
Beispiel #7
0
/****************************************************************************
 * cmd_text_parser() - update a config setting from a text block (text mode)
 * _text_parser() 	 - helper for above
 * 
 * Use cases handled:
 *	- $xfr=1200	set a parameter
 *	- $xfr		display a parameter
 *	- $x		display a group
 *	- ?			generate a status report (multiline format)
 */
uint8_t cmd_text_parser(char *str)
{
//	return (SC_OK); // There is no text parser in this code - just JSON
//}

	cmdObj_t *cmd = cmd_reset_list();		// returns first object in the body
	uint8_t status = SC_OK;

	// single-unit parser processing
	ritorno(_text_parser(str, cmd));		// decode the request or return if error
	if ((cmd->type == TYPE_PARENT) || (cmd->type == TYPE_NULL)) {
		if (cmd_get(cmd) == SC_COMPLETE) {	// populate value, group values, or run uber-group displays
			return (SC_OK);					// return for uber-group displays so they don't print twice
		}
	} else { 								// process SET and RUN commands
		status = cmd_set(cmd);				// set single value
		cmd_persist(cmd);
	}
	cmd_print_list(status, TEXT_MULTILINE_FORMATTED, JSON_RESPONSE_FORMAT); // print the results
	return (status);

	return (SC_OK);
}
Beispiel #8
0
void _test_serialize()
{
	cmdObj_t *cmd = cmd_array;
//	printf("\n\nJSON serialization tests\n");

	// null list
	_reset_array();
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// parent with a null child
	cmd = _reset_array();
	cmd = _add_parent(cmd, "r");
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// single string element (message)
	cmd = _reset_array();
	cmd = _add_string(cmd, "msg", "test message");
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// string element and an integer element
	cmd = _reset_array();
	cmd = _add_string(cmd, "msg", "test message");
	cmd = _add_integer(cmd, "answer", 42);
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// parent with a string and an integer element
	cmd = _reset_array();
	cmd = _add_parent(cmd, "r");
	cmd = _add_string(cmd, "msg", "test message");
	cmd = _add_integer(cmd, "answer", 42);
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// parent with a null child followed by a final level 0 element (footer)
	cmd = _reset_array();
	cmd = _add_parent(cmd, "r");
	cmd = _add_empty(cmd);
	cmd = _add_string(cmd, "f", "[1,0,12,1234]");	// fake out a footer
	cmd->pv->depth = 0;
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// parent with a single element child followed by empties folowed by a final level 0 element
	cmd = _reset_array();
	cmd = _add_parent(cmd, "r");
	cmd = _add_integer(cmd, "answer", 42);
	cmd = _add_empty(cmd);
	cmd = _add_empty(cmd);
	cmd = _add_string(cmd, "f", "[1,0,12,1234]");	// fake out a footer
	cmd->pv->depth = 0;
	js_serialize_json(cmd_array, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// response object parent with no children w/footer
	cmd_reset_list();								// works with the header/body/footer list
	_add_array(cmd, "1,0,12,1234");					// fake out a footer
	js_serialize_json(cmd_header, tg.out_buf, sizeof(tg.out_buf));
	_printit();

	// response parent with one element w/footer
	cmd_reset_list();								// works with the header/body/footer list
	cmd_add_string("msg", "test message");
	_add_array(cmd, "1,0,12,1234");					// fake out a footer
	js_serialize_json(cmd_header, tg.out_buf, sizeof(tg.out_buf));
	_printit();
}