/**
* Roboliq: Automation for liquid-handling robots
* @copyright 2017, ETH Zurich, Ellis Whitehead
* @license GPL-3.0
*/
/**
* Module for a 1-site Tecan shaker.
* @module
*/
const _ = require('lodash');
const assert = require('assert');
const math = require('mathjs');
const commandHelper = require('roboliq-processor/dist/commandHelper.js');
const expect = require('roboliq-processor/dist/expect.js');
/**
* @typedef ShakerTecan1Params
* @type {object}
* @property {!string} evowareId - the Evoware ID of this equipment
* @property {?string} evowareGrid - the grid that the equipment is on
* @param {!string} site - the equipment's site name (just the base part, without namespace)
* ```
* evowareId: "HPShaker",
* site: "P3"
* ```
*/
/**
* Configure the Tecan 1-site shaker
* @param {ShakerTecan1Params} params - parameters for the configuration
* @return {EquipmentConfig}
*/
function configure(config, equipmentName, params) {
const agent = config.getAgentName();
const equipment = config.getEquipmentName(equipmentName);
const siteName = config.getSiteName(params.site);
const objects = {};
_.set(objects, equipment, {
type: "Shaker",
evowareId: params.evowareId
});
const predicates = [
{
"shaker.canAgentEquipmentSite": {
agent,
equipment,
site: siteName
}
},
];
// console.log("shaker.predicates: "+JSON.stringify(predicates, null, '\t'));
const schemas = {
[`shaker.run|${agent}|${equipment}`]: {
properties: {
agent: {description: "Agent identifier", type: "Agent"},
equipment: {description: "Equipment identifier", type: "Equipment"},
program: {
description: "Program for shaking",
properties: {
rpm: {description: "Rotations per minute (RPM)", type: "number"},
duration: {description: "Duration of shaking", type: "Duration"}
},
required: ["duration"]
},
object: {description: "Plate identifier (optional)", type: "Plate"}
},
required: ["agent", "equipment", "program"]
}
};
const commandHandlers = {
[`shaker.run|${agent}|${equipment}`]: function(params, parsed, data) {
//console.log("equipment.run|ourlab.mario.evoware|ourlab.mario.shaker: "+JSON.stringify(parsed, null, '\t'))
const equipmentId = commandHelper.getParsedValue(parsed, data, "equipment", "evowareId");
const rpm = parsed.value.program.rpm || 750;
// Construct the shaker program data
const shakerNo = 1;
// FIXME: Let the user specify mode1, steps1, mode2, steps2, power
const mode1 = 2;
const steps1 = 0;
const mode2 = 1;
const steps2 = 0;
const freq = (60000000/rpm).toFixed(0);
const cycles = Math.floor(rpm * parsed.value.program.duration.toNumber("minute")).toFixed(0);
const powerPerc = 50;
const power = Math.floor(255 * powerPerc / 100).toFixed(0);
const s0 = `*27${shakerNo}|${freq}|${mode1}|${steps1}|${mode2}|${steps2}|${cycles}|${power}*27`;
// Replace all occurences of '0' with "*30"
const s1 = s0.replace(/0/g, "*30");
// Finally, split string into 32 char parts, then rebind them, separated by commas
const s2 = _(s1).chunk(32).map(s => s.join("")).join(",");
return {
expansion: [
{
command: "evoware._facts",
agent: parsed.objectName.agent,
factsEquipment: equipmentId,
factsVariable: equipmentId+"_HP__Start",
factsValue: s2
},
{
command: "timer.sleep",
agent: parsed.objectName.agent,
duration: parsed.orig.program.duration
},
{
command: "evoware._facts",
agent: parsed.objectName.agent,
factsEquipment: equipmentId,
factsVariable: equipmentId+"_HP__Stop",
factsValue: "1"
},
]
};
},
};
const protocol = {
objects,
predicates,
schemas,
commandHandlers
};
return protocol;
}
module.exports = {
configure
};