Skip to content

Commit c1555fd

Browse files
committed
Adding a system time pv, with an offset and multiple format options
1 parent 6d7eca8 commit c1555fd

File tree

3 files changed

+126
-1
lines changed

3 files changed

+126
-1
lines changed

core/pv/doc/index.rst

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -135,5 +135,19 @@ If the VType is omitted, 'double' is assumed. Examples::
135135
mqtt://some_topic<VString>
136136
mqtt://some/nested/topic
137137

138+
System
139+
------
140+
System process variables are useful for representing some system attributes. They do not communicate with the control system.::
138141

142+
* sys://time
143+
* sys://timeOffset(offset, format, update_seconds)
139144

145+
The `timeOffset` pv allows you to represent a time instant offset from `now`. The optional parameters are:
146+
*offset* which is described as 1 min, 1 hour, 1 day prior to the current instant.
147+
*format* which describes how to represent the instance, the supported formats are full, milli, seconds, datetime, date, or time.
148+
*update_seconds* the update rate / period.
149+
150+
Examples ::
151+
152+
sys://timeOffset(12 hours)
153+
sys://timeOffset(1hour, time, 1)

core/pv/src/main/java/org/phoebus/pv/sys/SysPVFactory.java

Lines changed: 23 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,9 @@
1010
import org.phoebus.pv.PV;
1111
import org.phoebus.pv.PVFactory;
1212

13+
import java.util.List;
14+
import java.util.stream.Collectors;
15+
1316
/** PV Factory for system PVs
1417
* @author Kay Kasemir
1518
*/
@@ -28,8 +31,27 @@ public String getType()
2831
@Override
2932
public PV createPV(final String name, final String base_name) throws Exception
3033
{
31-
if (base_name.equals("time"))
34+
// Determine simulation function name and (optional) parameters
35+
final String func, parameters;
36+
int sep = base_name.indexOf('(');
37+
if (sep < 0)
38+
{
39+
func = base_name;
40+
parameters = "";
41+
}
42+
else
43+
{
44+
final int end = base_name.lastIndexOf(')');
45+
if (end < 0)
46+
throw new Exception("Missing closing bracket for parameters in '" + name + "'");
47+
func = base_name.substring(0, sep);
48+
parameters = base_name.substring(sep+1, end);
49+
}
50+
51+
if (func.equals("time"))
3252
return new TimePV(name);
53+
else if (func.equals("timeOffset"))
54+
return TimeOffsetPV.forParameters(name, List.of(parameters.split(",")).stream().map(String::strip).collect(Collectors.toList()));
3355
else
3456
throw new Exception("Unknown system PV " + base_name);
3557
}
Lines changed: 89 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,89 @@
1+
/*******************************************************************************
2+
* Copyright (c) 2019 Oak Ridge National Laboratory.
3+
* All rights reserved. This program and the accompanying materials
4+
* are made available under the terms of the Eclipse Public License v1.0
5+
* which accompanies this distribution, and is available at
6+
* http://www.eclipse.org/legal/epl-v10.html
7+
******************************************************************************/
8+
package org.phoebus.pv.sys;
9+
10+
import org.phoebus.pv.sim.SimulatedStringPV;
11+
import org.phoebus.util.time.TimeParser;
12+
import org.phoebus.util.time.TimestampFormats;
13+
14+
import java.time.Instant;
15+
import java.time.Period;
16+
import java.time.format.DateTimeFormatter;
17+
import java.time.temporal.TemporalAmount;
18+
import java.util.List;
19+
import java.util.Locale;
20+
21+
/** System "time" PV
22+
* @author Kay Kasemir, based on similar code in diirt
23+
*/
24+
public class TimeOffsetPV extends SimulatedStringPV
25+
{
26+
private DateTimeFormatter formatter;
27+
private TemporalAmount temporalAmount;
28+
private double updateRate;
29+
30+
/**
31+
* Factory method for creating a time pv with user defined offset, format, and update rate.
32+
*
33+
* @param name pv name
34+
* @param parameters a list of optional parameters defining timeoffset, format, update rate
35+
* @return a new TimeOffsetPV
36+
*/
37+
public static TimeOffsetPV forParameters(final String name, final List<String> parameters) throws Exception {
38+
if(parameters != null && !parameters.isEmpty()) {
39+
if(parameters.size() == 1) {
40+
return new TimeOffsetPV(name, parameters.get(0), TimestampFormats.SECONDS_FORMAT, 1.0);
41+
} else if (parameters.size() == 2) {
42+
return new TimeOffsetPV(name, parameters.get(0), TimestampFormats.SECONDS_FORMAT, Double.valueOf(parameters.get(1)));
43+
} else if (parameters.size() == 3) {
44+
DateTimeFormatter formatter;
45+
switch (parameters.get(1).toLowerCase()) {
46+
case "full":
47+
formatter = TimestampFormats.FULL_FORMAT;
48+
break;
49+
case "milli":
50+
formatter = TimestampFormats.MILLI_FORMAT;
51+
break;
52+
case "seconds":
53+
formatter = TimestampFormats.SECONDS_FORMAT;
54+
break;
55+
case "datetime":
56+
formatter = TimestampFormats.DATETIME_FORMAT;
57+
break;
58+
case "date":
59+
formatter = TimestampFormats.DATE_FORMAT;
60+
break;
61+
case "time":
62+
formatter = TimestampFormats.TIME_FORMAT;
63+
break;
64+
default:
65+
formatter = TimestampFormats.SECONDS_FORMAT;
66+
break;
67+
}
68+
return new TimeOffsetPV(name, parameters.get(0), formatter, Double.valueOf(parameters.get(2)));
69+
}
70+
} else {
71+
return new TimeOffsetPV(name, "now", TimestampFormats.SECONDS_FORMAT, 1.0);
72+
}
73+
throw new Exception("sim://timeOffset needs no parameters or (offset, update_seconds) or (offset, format, update_seconds)");
74+
}
75+
76+
public TimeOffsetPV(final String name, final String offset, final DateTimeFormatter formatter, final double updateRate) {
77+
super(name);
78+
this.temporalAmount = TimeParser.parseTemporalAmount(offset);
79+
this.formatter = formatter;
80+
this.updateRate = updateRate;
81+
start(updateRate);
82+
}
83+
84+
@Override
85+
public String compute()
86+
{
87+
return formatter.format(Instant.now().minus(temporalAmount));
88+
}
89+
}

0 commit comments

Comments
 (0)