Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -307,6 +307,11 @@ private void handleUpdate(final ConsumerRecord<String, String> record) {
for (final AlarmClientListener listener : listeners)
listener.itemRemoved(node);
}
} else if (JsonModelReader.isConfigDeletion(json)) {
// Ignore config deletion messages; these can cause spurious updates to configs and hence
// spurious calls to itemUpdated
logger.log(Level.FINE, () -> "Ignoring tombstone config message: " + record.key() + " " + node_config);
return;
} else { // Configuration update
if (JsonModelReader.isStateUpdate(json))
logger.log(Level.WARNING, "Got config update with state content: " + record.key() + " " + node_config);
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -129,10 +129,11 @@
public boolean setEnabledDate(final LocalDateTime enabled_date)
{
final EnabledState new_enabled_state = new EnabledState(enabled_date);
if ((enabled.equals(new_enabled_state)) || enabled_date.isBefore(LocalDateTime.now()) || enabled_date.isEqual(LocalDateTime.now())) {
if ((enabled.equals(new_enabled_state))
|| enabled_date != null && enabled_date.isBefore(LocalDateTime.now())

Check warning on line 133 in app/alarm/model/src/main/java/org/phoebus/applications/alarm/client/AlarmClientLeaf.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Explicitly specify the time zone by passing a ZoneId or a Clock to the .now() method.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AaGiPlf7NaYY-PwlsE9T&open=AaGiPlf7NaYY-PwlsE9T&pullRequest=4007
|| enabled_date != null && enabled_date.isEqual(LocalDateTime.now())) {

Check warning on line 134 in app/alarm/model/src/main/java/org/phoebus/applications/alarm/client/AlarmClientLeaf.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Explicitly specify the time zone by passing a ZoneId or a Clock to the .now() method.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AaGiPlf7NaYY-PwlsE9U&open=AaGiPlf7NaYY-PwlsE9U&pullRequest=4007
return false;
}
setEnabled(false);
enabled = new_enabled_state;
return true;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,7 @@
*******************************************************************************/
package org.phoebus.applications.alarm.client;

import java.util.ArrayList;
import java.util.concurrent.CopyOnWriteArrayList;

import org.phoebus.applications.alarm.model.AlarmTreeItemWithState;
Expand All @@ -27,4 +28,17 @@ public AlarmClientNode(final String parent_path, final String name)
super(parent_path, name, new CopyOnWriteArrayList<>());
state = new BasicState(SeverityLevel.OK);
}

/** @return {@link AlarmClientNode} with same configuration, but no parent or children */
public AlarmClientNode createDetachedCopy()
{
final AlarmClientNode node = new AlarmClientNode(null, getName());

node.setGuidance(new ArrayList<>(getGuidance()));
node.setDisplays(new ArrayList<>(getDisplays()));
node.setCommands(new ArrayList<>(getCommands()));
node.setActions(new ArrayList<>(getActions()));

return node;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -11,9 +11,12 @@

import java.util.Collections;
import java.util.List;
import java.util.Objects;
import java.util.concurrent.CopyOnWriteArrayList;
import java.util.logging.Level;

import org.phoebus.applications.alarm.client.AlarmClientLeaf;
import org.phoebus.applications.alarm.client.AlarmClientNode;
import org.phoebus.util.text.CompareNatural;

/** Base class for all nodes in the alarm tree
Expand Down Expand Up @@ -232,4 +235,32 @@
{
return getName();
}

// TODO is there a nicer way to do this?

Check warning on line 239 in app/alarm/model/src/main/java/org/phoebus/applications/alarm/model/AlarmTreeItem.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Complete the task associated to this TODO comment.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AaGiPlbmNaYY-PwlsE9S&open=AaGiPlbmNaYY-PwlsE9S&pullRequest=4007
/** Compares the configurations (but not the state) of two alarm tree items */
public static boolean configsEqual(final AlarmTreeItem<?> item1, final AlarmTreeItem<?> item2) {
if (item1 instanceof final AlarmClientLeaf leaf1 && item2 instanceof final AlarmClientLeaf leaf2) {
return Objects.equals(leaf1.getName(), leaf2.getName())
&& Objects.equals(leaf1.getDescription(), leaf2.getDescription())
&& Objects.equals(leaf1.getEnabled(), leaf2.getEnabled())
&& Objects.equals(leaf1.getEnabledDate(), leaf2.getEnabledDate())
&& Objects.equals(leaf1.getFilter(), leaf2.getFilter())
&& leaf1.isLatching() == leaf2.isLatching()
&& leaf1.isAnnunciating() == leaf2.isAnnunciating()
&& leaf1.getCount() == leaf2.getCount()
&& leaf1.getDelay() == leaf2.getDelay()
&& Objects.equals(leaf1.getGuidance(), leaf2.getGuidance())
&& Objects.equals(leaf1.getDisplays(), leaf2.getDisplays())
&& Objects.equals(leaf1.getCommands(), leaf2.getCommands())
&& Objects.equals(leaf1.getActions(), leaf2.getActions());
}
if (item1 instanceof final AlarmClientNode node1 && item2 instanceof final AlarmClientNode node2) {
return Objects.equals(node1.getName(), node2.getName())
&& Objects.equals(node1.getGuidance(), node2.getGuidance())
&& Objects.equals(node1.getDisplays(), node2.getDisplays())
&& Objects.equals(node1.getCommands(), node2.getCommands())
&& Objects.equals(node1.getActions(), node2.getActions());
}
return false;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -230,7 +230,7 @@ private static boolean updateAlarmLeafConfig(final AlarmTreeLeaf node, final Jso
}
}
else {
node.setEnabled(true);
changed |= node.setEnabled(true);
}


Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -15,16 +15,38 @@ public class Messages

public static String acknowledgeFailed;
public static String addComponentFailed;
public static String automatedActions;
public static String AlarmAreaPanel;
public static String actionsHeaderAlarm;
public static String actionsHeaderNode;
public static String actionsLabel;
public static String actionsLabelAlarmTooltip;
public static String actionsLabelNodeTooltip;
public static String actionsNone;
public static String actionsPlural;
public static String actionsSingular;
public static String alarmProperties;
public static String annunciatingLabel;
public static String annunciatingLabelTooltip;
public static String AlarmTable;
public static String AlarmTree;
public static String Annunciator;
public static String commands;
public static String configure;
public static String delayTooltip0;
public static String delayTooltip1;
public static String delayTooltip2;
public static String behavior;
public static String commandsHeaderAlarm;
public static String commandsHeaderNode;
public static String commandsLabel;
public static String commandsLabelAlarmTooltip;
public static String commandsLabelNodeTooltip;
public static String commandsNone;
public static String commandsPlural;
public static String commandsSingular;
public static String nodeProperties;
public static String configChangedOnServer;
public static String countLabel;
public static String countLabelTooltip;
public static String delayLabel;
public static String delayLabelTooltip;
public static String descriptionLabel;
public static String descriptionLabelTooltip;
public static String disableAlarmFailed;
public static String disableAlarms;
public static String disabled;
Expand All @@ -33,23 +55,59 @@ public class Messages
public static String disabledUntil;
public static String disabledCommonEnableDate;
public static String disabledVaryingEnableDate;
public static String displays;
public static String discardChanges;
public static String discardChangesPrompt;
public static String displaysHeaderAlarm;
public static String displaysHeaderNode;
public static String displaysLabel;
public static String displaysLabelAlarmTooltip;
public static String displaysLabelNodeTooltip;
public static String displaysNone;
public static String displaysPlural;
public static String displaysSingular;
public static String enabled;
public static String enabledLabel;
public static String enabledLabelTooltip;
public static String enableDatetimeLabel;
public static String enableDatetimeLabelTooltip;
public static String enablingFilterLabel;
public static String enablingFilterLabelTooltip;
public static String enableAlarmFailed;
public static String enableAlarms;
public static String guidance;
public static String guidanceHeaderAlarm;
public static String guidanceHeaderNode;
public static String guidanceLabel;
public static String guidanceLabelAlarmTooltip;
public static String guidanceLabelNodeTooltip;
public static String guidanceNone;
public static String guidancePlural;
public static String guidanceSingular;
public static String headerAlreadyDisabled;
public static String headerAlreadyEnabled;
public static String headerConfirmDisable;
public static String headerConfirmDisableWithEnableDate;
public static String headerConfirmEnable;
public static String indefinitely;
public static String info;
public static String itemDeletedOnServer;
public static String latchingLabel;
public static String latchingLabelTooltip;
public static String loading;
public static String MenuPath;
public static String moveItemFailed;
public static String promptTitle;
public static String removeComponentFailed;
public static String nameLabel;
public static String nameLabelTooltip;
public static String pathLabel;
public static String pathLabelAlarmTooltip;
public static String pathLabelNodeTooltip;
public static String pvLabel;
public static String pvLabelTooltip;
public static String removeNodeFailed;
public static String renameItemFailed;
public static String saveChanges;
public static String totalPVs;
public static String unacknowledgeFailed;
public static String updateAlarmItemConfig;
public static String withEnableDate;

static
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -75,8 +75,11 @@
*/
private final AtomicReference<List<String>> item_changes = new AtomicReference<>();

/** Set of items that have updated, with iteration order based on when they updated */
private final Set<String> items_to_update = new LinkedHashSet<>();
/** Set of items that have updated, with iteration order based on when they updated
*
* SYNC on access
*/
private final Set<String> item_paths_to_update = new LinkedHashSet<>();

Check warning on line 82 in app/alarm/ui/src/main/java/org/phoebus/applications/alarm/ui/area/AlarmAreaView.java

View check run for this annotation

SonarQubeCloud / SonarCloud Code Analysis

Rename this field "item_paths_to_update" to match the regular expression '^[a-z][a-zA-Z0-9]*$'.

See more on https://sonarcloud.io/project/issues?id=ControlSystemStudio_phoebus&issues=AaGiPlZVNaYY-PwlsE9M&open=AaGiPlZVNaYY-PwlsE9M&pullRequest=4007

/** Throttle [5Hz] used for updates of existing items */
private final UpdateThrottle update_throttle = new UpdateThrottle(200, TimeUnit.MILLISECONDS, this::updateItems);
Expand Down Expand Up @@ -165,9 +168,9 @@
if (null == item_name)
return;

synchronized (items_to_update)
synchronized (item_paths_to_update)
{
items_to_update.add(item_name);
item_paths_to_update.add(item_name);
}
update_throttle.trigger();
}
Expand All @@ -178,10 +181,10 @@
final List<String> changed_items = item_changes.getAndSet(null);

final String[] update_array;
synchronized (items_to_update)
synchronized (item_paths_to_update)
{
update_array = items_to_update.toArray(new String[items_to_update.size()]);
items_to_update.clear();
update_array = item_paths_to_update.toArray(new String[item_paths_to_update.size()]);
item_paths_to_update.clear();
}
Platform.runLater(() ->
{
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,127 @@
package org.phoebus.applications.alarm.ui.config;

import javafx.geometry.HPos;
import javafx.scene.control.CheckBox;
import javafx.scene.layout.ColumnConstraints;
import javafx.scene.layout.HBox;
import javafx.scene.layout.Priority;
import org.phoebus.applications.alarm.client.AlarmClientLeaf;
import org.phoebus.applications.alarm.model.AlarmTreeItem;
import org.phoebus.applications.alarm.ui.Messages;


public class AlarmTreeAlarmConfigPanel extends AlarmTreeConfigPanel
{
/** The path of the node that this panel is for. Does not account for newName */
private final String pathName;

/** Detatched node storing the item's configuration when the panel was created */
private final AlarmClientLeaf initialConfig;

/** Detached node storing the item's configuration including the changes the user has made */
private final AlarmClientLeaf newConfig;

public AlarmTreeAlarmConfigPanel(final AlarmClientLeaf alarm)
{
super();

pathName = alarm.getPathName();
initialConfig = alarm.createDetachedCopy();
newConfig = alarm.createDetachedCopy();

getColumnConstraints().add(new ColumnConstraints(32, USE_COMPUTED_SIZE, Integer.MAX_VALUE, Priority.ALWAYS, HPos.LEFT, true));
getColumnConstraints().add(new ColumnConstraints(32, USE_COMPUTED_SIZE, Integer.MAX_VALUE, Priority.ALWAYS, HPos.LEFT, true));
getColumnConstraints().get(0).setPercentWidth(40);

addCategory(Messages.alarmProperties);
addDisabledTextRow(Messages.pathLabel, Messages.pathLabelAlarmTooltip, alarm.getPathName());
addDisabledTextRow(Messages.pvLabel, Messages.pvLabelTooltip, initialConfig.getName());

addSubcategory(Messages.info);
addTextRow(Messages.descriptionLabel, Messages.descriptionLabelTooltip, initialConfig.getDescription(), newConfig::setDescription);
addTitleDetailListBox(
Messages.guidanceLabel,
Messages.guidanceLabelAlarmTooltip,
Messages.guidanceHeaderAlarm,
Messages.guidanceNone,
Messages.guidanceSingular,
Messages.guidancePlural,
initialConfig.getGuidance(),
newConfig::getGuidance,
newConfig::setGuidance
);
addTitleDetailListBox(
Messages.displaysLabel,
Messages.displaysLabelAlarmTooltip,
Messages.displaysHeaderAlarm,
Messages.displaysNone,
Messages.displaysSingular,
Messages.displaysPlural,
initialConfig.getDisplays(),
newConfig::getDisplays,
newConfig::setDisplays
);
addTitleDetailListBox(
Messages.commandsLabel,
Messages.commandsLabelAlarmTooltip,
Messages.commandsHeaderAlarm,
Messages.commandsNone,
Messages.commandsSingular,
Messages.commandsPlural,
initialConfig.getCommands(),
newConfig::getCommands,
newConfig::setCommands
);

addSubcategory(Messages.enabled);
final CheckBox enabledCheckBox = addCheckboxRow(Messages.enabledLabel, Messages.enabledLabelTooltip, initialConfig.isEnabled(), newConfig::setEnabled);
final DateTimePicker enableDateTimePicker = addDateTimeRow(Messages.enableDatetimeLabel, Messages.enableDatetimeLabelTooltip, initialConfig.getEnabledDate(), newConfig::setEnabledDate);

enableDateTimePicker.setDisable(enabledCheckBox.isSelected());
enabledCheckBox.selectedProperty().addListener(_ -> {
enableDateTimePicker.setDisable(enabledCheckBox.isSelected());
if (enabledCheckBox.isSelected()) {
enableDateTimePicker.setDateTimeValue(null);
}
});

addTextRow(Messages.enablingFilterLabel, Messages.enablingFilterLabelTooltip, initialConfig.getFilter(), newConfig::setFilter);

addSubcategory(Messages.behavior);
addCheckboxRow(Messages.latchingLabel, Messages.latchingLabelTooltip, initialConfig.isLatching(), newConfig::setLatching);
addCheckboxRow(Messages.annunciatingLabel, Messages.annunciatingLabelTooltip, initialConfig.isAnnunciating(), newConfig::setAnnunciating);
addIntSpinnerRow(Messages.delayLabel, Messages.delayLabelTooltip, initialConfig.getDelay(), newConfig::setDelay);
addIntSpinnerRow(Messages.countLabel, Messages.countLabelTooltip, initialConfig.getCount(), newConfig::setCount);
addTitleDetailDelayListBox(
Messages.actionsLabel,
Messages.actionsLabelAlarmTooltip,
Messages.actionsHeaderAlarm,
Messages.actionsNone,
Messages.actionsSingular,
Messages.actionsPlural,
initialConfig.getActions(),
newConfig::getActions,
newConfig::setActions
);

add(new HBox(saveButton, discardButton), 0, getRowCount() + 1, 2, 1);
}

@Override
public String getPathName()
{
return pathName;
}

@Override
public AlarmTreeItem<?> getInitialConfig()
{
return initialConfig;
}

@Override
public AlarmTreeItem<?> getNewConfig()
{
return newConfig;
}
}
Loading
Loading