1
2
3
4
5 package org.epics.pvmanager.sim;
6
7 import java.util.HashMap;
8 import java.util.List;
9 import java.util.Map;
10 import java.util.concurrent.ScheduledExecutorService;
11 import java.util.concurrent.ScheduledFuture;
12 import java.util.concurrent.TimeUnit;
13 import java.util.logging.Level;
14 import java.util.logging.Logger;
15 import org.epics.pvmanager.ChannelWriteCallback;
16 import org.epics.pvmanager.MultiplexedChannelHandler;
17 import org.epics.pvmanager.util.FunctionParser;
18 import org.epics.vtype.AlarmSeverity;
19 import org.epics.vtype.VType;
20 import static org.epics.vtype.ValueFactory.*;
21
22
23
24
25
26 class IntermittentChannelHandler extends MultiplexedChannelHandler<Object, Object> {
27
28 private final Object value;
29 private final double delayInSeconds;
30 private final ScheduledExecutorService exec;
31 private final Runnable task = new Runnable() {
32
33 @Override
34 public void run() {
35
36 try {
37 boolean toConnect = !isConnected();
38
39 if (toConnect) {
40 processConnection(new Object());
41 processMessage(toVTypeChecked(value));
42 } else {
43 processMessage(toVTypeChecked(value, newAlarm(AlarmSeverity.UNDEFINED, "Disconnected"), timeNow(), displayNone()));
44 processConnection(null);
45 }
46 } catch (Exception ex) {
47 log.log(Level.WARNING, "Data simulation problem", ex);
48 }
49 }
50 };
51 private static final Logger log = Logger.getLogger(SimulationChannelHandler.class.getName());
52 private ScheduledFuture<?> taskFuture;
53
54 IntermittentChannelHandler(String channelName, ScheduledExecutorService exec) {
55 super(channelName);
56 String errorMessage = "Incorrect syntax. Must match intermittentChannel(delayInSeconds, value)";
57 List<Object> tokens = FunctionParser.parseFunctionAnyParameter(channelName);
58 if (tokens == null || tokens.size() <= 1) {
59 throw new IllegalArgumentException(errorMessage);
60 }
61 if (tokens.size() == 2) {
62 value = "Initial Value";
63 } else {
64 value = FunctionParser.asScalarOrList(tokens.subList(2, tokens.size()));
65 if (value == null) {
66 throw new IllegalArgumentException(errorMessage);
67 }
68 }
69 delayInSeconds = (Double) tokens.get(1);
70 if (delayInSeconds < 0.001) {
71 throw new IllegalArgumentException("Delay must be at least 0.001");
72 }
73 this.exec = exec;
74 }
75
76 @Override
77 public void connect() {
78 taskFuture = exec.scheduleWithFixedDelay(task, 0, (long) (delayInSeconds * 1000), TimeUnit.MILLISECONDS);
79 }
80
81 @Override
82 public void disconnect() {
83 taskFuture.cancel(false);
84 processConnection(null);
85 }
86
87 @Override
88 public Map<String, Object> getProperties() {
89 Map<String, Object> result = new HashMap<>();
90 result.put("delayInSeconds", delayInSeconds);
91 result.put("value", value);
92 return result;
93 }
94
95 @Override
96 protected boolean isConnected(Object payload) {
97 return payload != null;
98 }
99
100 @Override
101 public void write(Object newValue, ChannelWriteCallback callback) {
102 throw new UnsupportedOperationException("Can't write to simulation channel.");
103 }
104
105 }