Skip to content

Commit ffde6af

Browse files
Merge branch 'master' into CSSTUDIO-2734
2 parents 0a07e8f + 50ecd42 commit ffde6af

File tree

69 files changed

+1429
-1261
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

69 files changed

+1429
-1261
lines changed

app/alarm/audio-annunciator/src/main/java/org/phoebus/applications/alarm/audio/annunciator/AudioAnnunciator.java

Lines changed: 72 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -15,6 +15,8 @@
1515
import org.phoebus.applications.alarm.ui.annunciator.AnnunciatorMessage;
1616

1717
import java.util.List;
18+
import java.util.logging.Level;
19+
import java.util.logging.Logger;
1820

1921
/**
2022
* Annunciator class. Uses Audio files to annunciate passed messages.
@@ -23,6 +25,7 @@
2325
*/
2426
@SuppressWarnings("nls")
2527
public class AudioAnnunciator implements Annunciator {
28+
private static final Logger logger = Logger.getLogger(AudioAnnunciator.class.getName());
2629
private final MediaPlayer alarmSound;
2730
private final MediaPlayer minorAlarmSound;
2831
private final MediaPlayer majorAlarmSound;
@@ -33,26 +36,63 @@ public class AudioAnnunciator implements Annunciator {
3336
* Constructor
3437
*/
3538
public AudioAnnunciator() {
36-
alarmSound = new MediaPlayer(new Media(Preferences.alarm_sound_url));
37-
minorAlarmSound = new MediaPlayer(new Media(Preferences.minor_alarm_sound_url));
38-
majorAlarmSound = new MediaPlayer(new Media(Preferences.major_alarm_sound_url));
39-
invalidAlarmSound = new MediaPlayer(new Media(Preferences.invalid_alarm_sound_url));
40-
undefinedAlarmSound = new MediaPlayer(new Media(Preferences.undefined_alarm_sound_url));
39+
alarmSound = createMediaPlayer(Preferences.alarm_sound_url);
40+
minorAlarmSound = createMediaPlayer(Preferences.minor_alarm_sound_url);
41+
majorAlarmSound = createMediaPlayer(Preferences.major_alarm_sound_url);
42+
invalidAlarmSound = createMediaPlayer(Preferences.invalid_alarm_sound_url);
43+
undefinedAlarmSound = createMediaPlayer(Preferences.undefined_alarm_sound_url);
4144
// configure the media players for the different alarm sounds
4245
List.of(alarmSound, minorAlarmSound, majorAlarmSound, invalidAlarmSound, undefinedAlarmSound)
4346
.forEach(sound -> {
44-
sound.setStopTime(Duration.seconds(Preferences.max_alarm_duration));
45-
sound.setVolume(Preferences.volume);
47+
if (sound != null) {
48+
sound.setStopTime(Duration.seconds(Preferences.max_alarm_duration));
49+
sound.setVolume(Preferences.volume);
50+
}
4651
});
4752
}
4853

54+
/**
55+
* Create a MediaPlayer for the given URL
56+
*
57+
* @param url URL of the audio file
58+
* @return MediaPlayer
59+
*/
60+
private MediaPlayer createMediaPlayer(String url) {
61+
try {
62+
MediaPlayer player = new MediaPlayer(new Media(url));
63+
if (player.getError() == null) {
64+
player.setOnError(() -> logger.log(Level.SEVERE, "Error playing alarm sound: " + url, player.getError()));
65+
player.setOnPlaying(() -> logger.log(Level.FINE, "Playing alarm sound: " + url));
66+
player.setOnStopped(() -> logger.log(Level.FINE, "Alarm sound stopped: " + url));
67+
player.setOnEndOfMedia(() -> logger.log(Level.FINE, "Alarm sound finished: " + url));
68+
return player;
69+
}
70+
else {
71+
logger.log(Level.SEVERE, "Error creating MediaPlayer for URL: " + url, player.getError());
72+
return null;
73+
}
74+
} catch (Exception e) {
75+
logger.log(Level.SEVERE, "Failed to create MediaPlayer for URL: " + url, e);
76+
return null;
77+
}
78+
}
79+
4980
/**
5081
* Annunciate the message.
5182
*
5283
* @param message Message text
5384
*/
5485
@Override
5586
public void speak(final AnnunciatorMessage message) {
87+
if (message == null) {
88+
logger.log(Level.WARNING, "Received null AnnunciatorMessage");
89+
return;
90+
}
91+
if (message.severity == null) {
92+
logger.log(Level.WARNING, "Received AnnunciatorMessage with null severity: " + message + ". Playing default alarm sound");
93+
speakAlone(alarmSound); // Play the default alarm sound
94+
return;
95+
}
5696
switch (message.severity) {
5797
case MINOR -> speakAlone(minorAlarmSound);
5898
case MAJOR -> speakAlone(majorAlarmSound);
@@ -62,12 +102,27 @@ public void speak(final AnnunciatorMessage message) {
62102
}
63103
}
64104

105+
/**
106+
* Play the alarm sound alone by first stopping any alarm sounds.
107+
*
108+
* @param alarm Alarm sound
109+
*/
65110
synchronized private void speakAlone(MediaPlayer alarm) {
111+
if (alarm == null) {
112+
logger.log(Level.WARNING, "Alarm sound is null, cannot play sound");
113+
return;
114+
}
66115
List.of(alarmSound, minorAlarmSound, majorAlarmSound, invalidAlarmSound, undefinedAlarmSound)
67116
.forEach(sound -> {
68-
sound.stop();
117+
if (sound != null) {
118+
sound.stop();
119+
}
69120
});
70-
alarm.play();
121+
try {
122+
alarm.play();
123+
} catch (Exception e) {
124+
logger.log(Level.SEVERE, "Failed to play alarm sound", e);
125+
}
71126
}
72127

73128
/**
@@ -77,8 +132,14 @@ synchronized private void speakAlone(MediaPlayer alarm) {
77132
public void shutdown() {
78133
List.of(alarmSound, minorAlarmSound, majorAlarmSound, invalidAlarmSound, undefinedAlarmSound)
79134
.forEach(sound -> {
80-
sound.stop();
81-
sound.dispose();
135+
if (sound != null) {
136+
try {
137+
sound.stop();
138+
sound.dispose();
139+
} catch (Exception e) {
140+
logger.log(Level.WARNING, "Failed to stop and dispose alarm sound" , e);
141+
}
142+
}
82143
});
83144
}
84145
}

app/alarm/logging-ui/src/main/java/org/phoebus/applications/alarm/logging/ui/AlarmLogTableController.java

Lines changed: 31 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -148,6 +148,33 @@ public AlarmLogTableController(HttpClient client) {
148148
setClient(client);
149149
}
150150

151+
private final String replaceKey(final String key) {
152+
String repKey = key;
153+
if(key == Keys.SEVERITY.getName())
154+
repKey = "alarm_severity";
155+
else if(key == Keys.MESSAGE.getName())
156+
repKey = "alarm_message";
157+
else if(key == Keys.CURRENTSEVERITY.getName())
158+
repKey = "pv_severity";
159+
else if(key == Keys.CURRENTMESSAGE.getName())
160+
repKey = "pv_message";
161+
162+
return repKey;
163+
}
164+
165+
private String recoverKey(String key) {
166+
if(key.contains("alarm_severity"))
167+
key = "severity";
168+
else if(key.contains("alarm_message"))
169+
key = "message";
170+
else if(key.contains("pv_severity"))
171+
key = "current_severity";
172+
else if(key.contains("pv_message"))
173+
key = "current_message";
174+
175+
return key;
176+
}
177+
151178
@FXML
152179
public void initialize() {
153180
resize.setText("<");
@@ -294,7 +321,7 @@ protected void updateItem(String item, boolean empty) {
294321
searchParameters.entrySet().stream()
295322
.filter(e -> !e.getKey().getName().equals(Keys.ROOT.getName())) // Exclude alarm config (root) as selection is managed in drop-down
296323
.sorted(Map.Entry.comparingByKey())
297-
.map((e) -> e.getKey().getName().trim() + "=" + e.getValue().trim())
324+
.map((e) -> replaceKey(e.getKey().getName().trim()) + "=" + e.getValue().trim())
298325
.collect(Collectors.joining("&")));
299326

300327
searchParameters.addListener(
@@ -303,7 +330,7 @@ protected void updateItem(String item, boolean empty) {
303330
.sorted(Entry.comparingByKey())
304331
.filter(e -> !e.getKey().getName().equals(Keys.ROOT.getName())) // Exclude alarm config (root) as selection is managed in drop-down
305332
.filter(e -> !e.getValue().equals(""))
306-
.map((e) -> e.getKey().getName().trim() + "=" + e.getValue().trim())
333+
.map((e) -> replaceKey(e.getKey().getName().trim()) + "=" + e.getValue().trim())
307334
.collect(Collectors.joining("&"))));
308335

309336
query.setOnKeyPressed(keyEvent -> {
@@ -398,7 +425,7 @@ public void setIsNodeTable(Boolean isNodeTable) {
398425
searchParameters.put(Keys.STARTTIME, TimeParser.format(java.time.Duration.ofDays(7)));
399426
searchParameters.put(Keys.ENDTIME, TimeParser.format(java.time.Duration.ZERO));
400427

401-
query.setText(searchParameters.entrySet().stream().sorted(Map.Entry.comparingByKey()).map((e) -> e.getKey().getName().trim() + "=" + e.getValue().trim()).collect(Collectors.joining("&")));
428+
query.setText(searchParameters.entrySet().stream().sorted(Map.Entry.comparingByKey()).map((e) -> replaceKey(e.getKey().getName().trim()) + "=" + e.getValue().trim()).collect(Collectors.joining("&")));
402429
}
403430

404431
public void setAlarmMessages(List<AlarmLogTableItem> alarmMessages) {
@@ -488,7 +515,7 @@ void updateQuery() {
488515
searchTerms.forEach(s -> {
489516
String[] splitString = s.split("=");
490517
if (splitString.length > 1) {
491-
String key = splitString[0];
518+
String key = recoverKey(splitString[0]);
492519
searchKeywords.add(key);
493520
String value = splitString[1];
494521
if (lookup.containsKey(key)) {

app/alarm/logging-ui/src/main/resources/org/phoebus/applications/alarm/logging/ui/messages.properties

Lines changed: 36 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -16,35 +16,56 @@
1616
# Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA.
1717
#
1818
AlarmInformation=Alarm Information
19-
Command=Command
20-
Config=Config
2119
ConfigurationInfo=Configuration Info
2220
ConfigurationInfoNotFound=Configuration info not found.
2321
Configurations=Configurations:
24-
CurrentMessage=Current Message
25-
CurrentSeverity=Current Severity
26-
EndTime=End Time
22+
#
23+
Config=Config
24+
#
25+
Severity=Alarm Severity
26+
Message=Alarm Message
27+
Time=Alarm Time
28+
#
29+
MessageTime=Alarm Log Time
30+
CurrentSeverity=PV Severity
31+
CurrentMessage=PV Message
32+
#
33+
Command=Command
34+
#
35+
User=User
2736
Host=Host
28-
Message=Message
29-
MessageTime=Message Time
37+
#
38+
Value=Alarm Value
39+
#
40+
TimeDelta=Time Delta
41+
StartTime=Start Time
42+
EndTime=End Time
43+
#
3044
Mode=Mode
45+
#
3146
NoSearchResults=No Search Results
3247
Query=Query:
3348
Search=Search
3449
Configuration=Configuration(s):
35-
Severity=Severity
36-
StartTime=Start Time
37-
Time=Time
38-
User=User
39-
Value=Value
40-
TimeDelta=Time Delta
50+
# Table Column Visibility
51+
#
4152
ConfigVisible=true
53+
# PV : Always TRUE
54+
# Severity : Alarm Severity Column
55+
CSeverityVisible=true
56+
# Message : Alarm Message Column
57+
CMessageVisible=true
58+
# Value : PV Value Column
4259
ValueVisible=false
60+
# MessageTime : Alarm Log Time
4361
MTimeVisible=true
62+
# Time Delta Column
4463
TimeDeltaVisible=false
45-
CSeverityVisible=true
46-
CMessageVisible=true
64+
# Command Column
4765
CommandVisible=true
66+
# Phoebus User Columm
4867
UserVisible=true
68+
# Phoebus Host Column
4969
HostVisible=true
70+
#
5071

app/alarm/model/src/main/resources/alarm_preferences.properties

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,8 @@ alarm_tree_startup_ms=2000
6565

6666
# Order of columns in alarm table
6767
# Allows re-ordering as well as omitting columns
68-
alarm_table_columns=Icon, PV, Description, Alarm Severity, Alarm Status, Alarm Time, Alarm Value, PV Severity, PV Status
68+
# The supported columns are: Icon, PV, Description, Alarm Severity, Alarm Message, Alarm Time, Alarm Value, PV Severity, PV Message
69+
alarm_table_columns=Icon, PV, Description, Alarm Severity, Alarm Message, Alarm Time, Alarm Value, PV Severity, PV Message
6970

7071
# By default, the alarm table uses the common alarm severity colors
7172
# for both the text color and the background of cells in the "Severity" column.
@@ -142,4 +143,4 @@ shelving_options=1 hour, 6 hours, 12 hours, 1 day, 7 days, 30 days
142143
macros=TOP=/home/controls/displays,WEBROOT=http://localhost/controls/displays
143144

144145
# Max time in ms a producer call will block.
145-
max_block_ms=10000
146+
max_block_ms=10000

app/alarm/ui/src/main/java/org/phoebus/applications/alarm/ui/Messages.java

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,14 @@ public class Messages
1616
public static String acknowledgeFailed;
1717
public static String addComponentFailed;
1818
public static String disableAlarmFailed;
19+
public static String disabled;
20+
public static String disabledUntil;
1921
public static String enableAlarmFailed;
2022
public static String moveItemFailed;
23+
public static String partlyDisabled;
2124
public static String removeComponentFailed;
2225
public static String renameItemFailed;
26+
public static String timer;
2327
public static String unacknowledgeFailed;
2428

2529
static

app/alarm/ui/src/main/java/org/phoebus/applications/alarm/ui/annunciator/AnnunciatorMessage.java

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -60,6 +60,7 @@ public int compareTo(AnnunciatorMessage other)
6060
@Override
6161
public String toString()
6262
{
63-
return TimestampFormats.MILLI_FORMAT.format(time) + " " + severity + " " + message;
63+
String timeStr = (time != null) ? TimestampFormats.MILLI_FORMAT.format(time) : "null";
64+
return timeStr + " " + severity + " " + message;
6465
}
6566
}

app/alarm/ui/src/main/java/org/phoebus/applications/alarm/ui/table/AlarmTableUI.java

Lines changed: 6 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,10 @@
1616
import java.util.Optional;
1717
import java.util.logging.Level;
1818
import java.util.regex.Pattern;
19+
import java.util.stream.Collectors;
1920

2021
import javafx.application.Platform;
22+
import javafx.scene.control.TableColumnBase;
2123
import javafx.scene.layout.Background;
2224
import javafx.scene.layout.BorderPane;
2325
import javafx.scene.layout.Priority;
@@ -442,7 +444,7 @@ private TableView<AlarmInfoRow> createTable(final ObservableList<AlarmInfoRow> r
442444
sevcol.setCellFactory(c -> new SeverityLevelCell());
443445
cols.add(sevcol);
444446

445-
col = new TableColumn<>("Alarm Status");
447+
col = new TableColumn<>("Alarm Message");
446448
col.setPrefWidth(130);
447449
col.setReorderable(false);
448450
col.setCellValueFactory(cell -> cell.getValue().status);
@@ -470,7 +472,7 @@ private TableView<AlarmInfoRow> createTable(final ObservableList<AlarmInfoRow> r
470472
sevcol.setCellFactory(c -> new SeverityLevelCell());
471473
cols.add(sevcol);
472474

473-
col = new TableColumn<>("PV Status");
475+
col = new TableColumn<>("PV Message");
474476
col.setPrefWidth(130);
475477
col.setReorderable(false);
476478
col.setCellValueFactory(cell -> cell.getValue().pv_status);
@@ -493,7 +495,8 @@ private TableView<AlarmInfoRow> createTable(final ObservableList<AlarmInfoRow> r
493495
if (to_add.isPresent())
494496
table.getColumns().add(to_add.get());
495497
else
496-
logger.log(Level.WARNING, "Unknown Alarm Table column '" + header + "'");
498+
logger.log(Level.SEVERE, "Unknown Alarm Table column '" + header + "' " +
499+
" Supported columns are: " + cols.stream().map(TableColumnBase::getText).collect(Collectors.joining(", ")));
497500
}
498501

499502
// Initially, sort on PV name

0 commit comments

Comments
 (0)