/** * Copyright (C) 2010-14 diirt developers. See COPYRIGHT.TXT * All rights reserved. Use is subject to license terms. See LICENSE.TXT */ package org.diirt.datasource.sim; import java.util.HashMap; import java.util.List; import java.util.Map; import java.util.concurrent.ScheduledExecutorService; import java.util.concurrent.ScheduledFuture; import java.util.concurrent.TimeUnit; import java.util.logging.Level; import java.util.logging.Logger; import org.diirt.datasource.ChannelWriteCallback; import org.diirt.datasource.MultiplexedChannelHandler; import org.diirt.datasource.util.FunctionParser; import org.diirt.vtype.AlarmSeverity; import static org.diirt.vtype.ValueFactory.*; /** * * @author carcassi */ class IntermittentChannelHandler extends MultiplexedChannelHandler<Object, Object> { private final Object value; private final double delayInSeconds; private final ScheduledExecutorService exec; private final Runnable task = new Runnable() { @Override public void run() { // Protect the timer thread for possible problems. try { boolean toConnect = !isConnected(); if (toConnect) { processConnection(new Object()); processMessage(toVTypeChecked(value)); } else { processMessage(toVTypeChecked(value, newAlarm(AlarmSeverity.UNDEFINED, "Disconnected"), timeNow(), displayNone())); processConnection(null); } } catch (Exception ex) { log.log(Level.WARNING, "Data simulation problem", ex); } } }; private static final Logger log = Logger.getLogger(SimulationChannelHandler.class.getName()); private ScheduledFuture<?> taskFuture; IntermittentChannelHandler(String channelName, ScheduledExecutorService exec) { super(channelName); String errorMessage = "Incorrect syntax. Must match intermittentChannel(delayInSeconds, value)"; List<Object> tokens = FunctionParser.parseFunctionAnyParameter(channelName); if (tokens == null || tokens.size() <= 1) { throw new IllegalArgumentException(errorMessage); } if (tokens.size() == 2) { value = "Initial Value"; } else { value = FunctionParser.asScalarOrList(tokens.subList(2, tokens.size())); if (value == null) { throw new IllegalArgumentException(errorMessage); } } delayInSeconds = (Double) tokens.get(1); if (delayInSeconds < 0.001) { throw new IllegalArgumentException("Delay must be at least 0.001"); } this.exec = exec; } @Override public void connect() { taskFuture = exec.scheduleWithFixedDelay(task, 0, (long) (delayInSeconds * 1000), TimeUnit.MILLISECONDS); } @Override public void disconnect() { taskFuture.cancel(false); processConnection(null); } @Override public Map<String, Object> getProperties() { Map<String, Object> result = new HashMap<>(); result.put("delayInSeconds", delayInSeconds); result.put("value", value); return result; } @Override protected boolean isConnected(Object payload) { return payload != null; } @Override public void write(Object newValue, ChannelWriteCallback callback) { throw new UnsupportedOperationException("Can't write to simulation channel."); } }