org.bidib.wizard.common.script.test.CvGetEmergencyIPCommand Maven / Gradle / Ivy
package org.bidib.wizard.common.script.test;
import java.util.ArrayList;
import java.util.Collections;
import java.util.HashMap;
import java.util.List;
import java.util.Map;
import java.util.Scanner;
import java.util.regex.Matcher;
import java.util.regex.Pattern;
import org.apache.commons.collections4.CollectionUtils;
import org.apache.commons.lang3.StringUtils;
import org.bidib.jbidibc.core.node.ConfigurationVariable;
import org.bidib.wizard.api.context.ApplicationContext;
import org.bidib.wizard.api.model.NodeInterface;
import org.bidib.wizard.api.service.console.ConsoleService;
import org.bidib.wizard.common.script.AbstractScriptCommand;
import org.bidib.wizard.common.script.DefaultScriptContext;
import org.bidib.wizard.common.script.ScriptExecutionException;
import org.bidib.wizard.common.script.ScriptUtils;
import org.bidib.wizard.common.script.node.NodeScripting;
import org.bidib.wizard.common.script.node.types.CvType;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
public class CvGetEmergencyIPCommand extends AbstractScriptCommand {
private static final Logger LOGGER = LoggerFactory.getLogger(CvGetEmergencyIPCommand.class);
public static final String KEY = "cvGetEmergencyIPCommand";
public static final String HELP =
CODE_BLOCK_START + KEY + prepareHelpHtml(" [--V:P] [--all] --firstCV=") + DIV_END
+ prepareHelpHtml(
"\nGet the CV value(s) and combine the read values to an Emergency IP address. The formatted Emergency IP address is stored in the parameter map "
+ "of the script context and can be used with placeholder key \"emergencyIP\" for parameter subsitution (see echo command).");
private int[] vidPid;
private boolean processAllNodes;
private final List cvValues;
public CvGetEmergencyIPCommand(final ConsoleService consoleService) {
super(consoleService, KEY, HELP);
this.cvValues = new ArrayList<>();
}
@Override
public void parse(String commandLine) {
try (Scanner scanner = new Scanner(commandLine)) {
if (!getKey().equals(scanner.next())) {
LOGGER.info("Invalid command is scanned, key does not match.");
throw new IllegalArgumentException("Invalid command is scanned, key does not match.");
}
line = commandLine.trim();
String arguments = line.substring(KEY.length() + 1);
try {
vidPid = ScriptUtils.scanVidPid(scanner, true);
if (vidPid != null) {
LOGGER.info("Current vidPid: {}:{}", vidPid[0], vidPid[1]);
}
}
catch (IllegalArgumentException ex) {
LOGGER.info("Parse VID/PID failed.", ex);
throw new IllegalArgumentException("Parse VID/PID failed.\n" + getHelpHtml());
}
if (arguments.indexOf("--all") > -1) {
LOGGER.info("Process all nodes is activated.");
processAllNodes = true;
}
Pattern pattern = Pattern.compile("--firstCV=\\w+");
Matcher matcher = pattern.matcher(arguments);
if (matcher.find()) {
String cvPair = matcher.group();
String[] values = cvPair.split("=");
// MAC address contains of 4 subsequent CV values
int firstCvNumber = Integer.parseInt(values[1]);
for (int index = 0; index < 4; index++) {
cvValues.add(new CvType(Integer.toString(firstCvNumber + index), null));
}
}
else {
LOGGER.warn("Mandatory parameter firstCV is missing.");
throw new IllegalArgumentException("Mandatory parameter firstCV is missing.\n" + getHelpHtml());
}
}
LOGGER.info("Parsed command, cvValues: {}", cvValues);
}
public List getCvValues() {
return Collections.unmodifiableList(cvValues);
}
protected String getFormattedEmergencyIPAddress() {
if (this.cvValues == null || this.cvValues.size() != 4) {
LOGGER.warn("The CV values to prepare the EmergencyIP address are not available.");
throw new IllegalArgumentException("The CV values to prepare the EmergencyIP address are not available.");
}
final StringBuilder sb = new StringBuilder();
for (CvType cvType : this.cvValues) {
String val = cvType.getCvValue();
if (StringUtils.isBlank(val)) {
throw new IllegalArgumentException(
"The CV value to prepare the EmergencyIP address are not available. Current cvType: " + cvType);
}
int intVal = Integer.parseInt(val);
if (sb.length() > 0) {
sb.append('.');
}
sb.append(String.format("%d", intVal));
}
return sb.toString();
}
public int[] getVidPid() {
return vidPid;
}
public boolean isProcessAllNodes() {
return processAllNodes;
}
@Override
protected void internalExecute(final T scripting, final ApplicationContext context) {
LOGGER.info("Get the cv values: {}", cvValues);
final List nodes = new ArrayList<>();
if (vidPid != null) {
List currentNodes = scripting.getNodesByVidAndPid(vidPid[0], vidPid[1]);
if (CollectionUtils.isNotEmpty(currentNodes)) {
if (processAllNodes) {
nodes.addAll(currentNodes);
}
else {
nodes.add(currentNodes.get(0));
}
}
else {
addError(context, "No matching node with provided VID/PID found.");
return;
}
}
else {
NodeInterface node = context.get(DefaultScriptContext.KEY_SELECTED_NODE, NodeInterface.class);
LOGGER.info("Fetched the registered selected node: {}", node);
nodes.add(node);
}
if (CollectionUtils.isEmpty(nodes)) {
LOGGER.warn("No node selected and registered in context. Skip set CV values.");
throw new ScriptExecutionException("No registered node in execution context.", this);
}
final List cvTypes = cvValues;
for (NodeInterface node : nodes) {
final List cvReadList =
scripting.getCv(node.getUniqueId(), cvTypes.toArray(new CvType[0]));
for (CvType currentCv : cvValues) {
final String cvNumber = currentCv.getCvNumber();
ConfigurationVariable readCv =
cvReadList.stream().filter(cv -> cvNumber.equals(cv.getName())).findFirst().orElse(null);
if (readCv == null) {
addError(context, "No CV value returned for CV number: " + cvNumber);
throw new IllegalStateException("No CV value returned for CV number: " + cvNumber);
}
else {
// update the value
currentCv.setCvValue(readCv.getValue());
}
}
}
String formattedEmergencyIPAddress = getFormattedEmergencyIPAddress();
Map parameters = context.get(DefaultScriptContext.KEY_PARAMETERS, Map.class);
if (parameters == null) {
parameters = new HashMap<>();
context.register(DefaultScriptContext.KEY_PARAMETERS, parameters);
}
parameters.put("emergencyIP", formattedEmergencyIPAddress);
}
}