Source: equipment/evoware.js

/**
 * Roboliq: Automation for liquid-handling robots
 * @copyright 2017, ETH Zurich, Ellis Whitehead
 * @license GPL-3.0
 */

/**
 * Module for Evoware commands.
 * In order to use Evoware commands in Roboliq, you'll need to calls these
 * functions in your robot configuration file.
 * @module
 */

import _ from 'lodash';
import commandHelper from 'roboliq-processor/dist/commandHelper.js';
import expect from 'roboliq-processor/dist/expect.js';
import yaml from 'yamljs';

/**
 * Create an instruction for Evoware execute an external command.
 * @static
 * @param  {string} agentName - Agent identifier
 * @param  {string} path - path to command to execute
 * @param  {array} args - array of arguments to pass
 * @param  {boolean} wait - true if evoware should wait for the command to complete execution
 * @return {object} an object representing an Evoware 'Execute' instruction.
 */
function makeEvowareExecute(agentName, path, args, wait) {
	return {
		command: "evoware._execute",
		agent: agentName,
		path, args, wait
	};
}

/**
 * Create an instruction for Evoware FACTS.
 * @static
 * @param  {object} parsed - parsed object of command parameters
 * @param  {object} data - protocol data
 * @param  {string} variable    [description]
 * @param  {any} [value] - optional value; if value is a function, it will be called with the parameters (parsed, data).
 * @param  {string} labwareName - labware used in this command
 * @return {object} an object representing an Evoware 'FACTS' instruction.
 */
function makeEvowareFacts(parsed, data, variable, value, labwareName) {
	const equipmentId = commandHelper.getParsedValue(parsed, data, "equipment", "evowareId");
	const result2 = {
		command: "evoware._facts",
		agent: parsed.objectName.agent,
		factsEquipment: equipmentId,
		factsVariable: equipmentId+"_"+variable
	};
	const value2 = (_.isFunction(value))
		? value(parsed, data)
		: value;
	return _.merge(result2, {factsValue: value2, labware: labwareName});
}

/**
 * Create the predictates to be added to Roboliq's robot
 * configuration for Evoware's site/model relationships.
 *
 * Expect spec of this form:
 * ``{siteModel: string, sites: [string], labwareModels: [string]}``
 * @static
 */
function makeSiteModelPredicates(spec) {
	return _.flatten([
		{isSiteModel: {model: spec.siteModel}},
		_.map(spec.sites, site => ({siteModel: {site, siteModel: spec.siteModel}})),
		_.map(spec.labwareModels, labwareModel => ({stackable: {below: spec.siteModel, above: labwareModel}}))
	]);
}

/**
 * Create the predictates to be added to Roboliq's robot
 * configuration for Evoware's RoMa relationships.
 *
 * Expect specs of this form:
 * ``{<transporter>: {<program>: [site names]}}``
 * @static
 */
function makeTransporterPredicates(namespaceName, agentName, specs) {
	let siteCliqueId = 1;
	const l = [];
	_.forEach(specs, (programs, equipment) => {
		_.forEach(programs, (cliques, program) => {
			_.forEach(cliques, (sites) => {
				const siteClique = `${namespaceName}.${agentName}.siteClique${siteCliqueId}`;
				siteCliqueId++;
				_.forEach(sites, site => {
					l.push({"siteCliqueSite": {siteClique, site}});
				});
				l.push({
					"transporter.canAgentEquipmentProgramSites": {
						"agent": agentName,
						equipment,
						program,
						siteClique
					}
				});
			});
		});
	});
	return l;
}

module.exports = {
	makeEvowareExecute,
	makeEvowareFacts,
	makeSiteModelPredicates,
	makeTransporterPredicates,

	/**
	 * objectToPredicateConverters for Evoware
	 */
	objectToPredicateConverters: {
		"EvowareRobot": function(name) {
			return [{ "isAgent": { "agent": name } }];
		}
	},
	/**
	 * Returns the schemas for Evoware commands and objects.
	 * @return {object} map from name to schema
	 */
	getSchemas: () => yaml.load(__dirname+"/../schemas/commands/evoware.yaml"),
	/**
	 * Return command handlers for low-level evoware instructions.
	 * @return {object} map from instruction name to handler.
	 */
	getCommandHandlers: () => ({
		"evoware._execute": function(params, parsed, data) {},
		"evoware._facts": function(params, parsed, data) {},
		"evoware._raw": function(params, parsed, data) {},
		"evoware._subroutine": function(params, parsed, data) {},
		"evoware._userPrompt": function(params, parsed, data) {},
	}),
};