use of com.alliander.osgp.shared.exceptionhandling.FunctionalException in project Protocol-Adapter-IEC61850 by OSGP.
the class Iec61850SetScheduleCommand method createScheduleEntries.
/**
* Returns a map of schedule entries, grouped by the internal index.
*/
private Map<Integer, List<ScheduleEntry>> createScheduleEntries(final List<ScheduleDto> scheduleList, final Ssld ssld, final RelayTypeDto relayTypeDto, final SsldDataService ssldDataService) throws FunctionalException {
final Map<Integer, List<ScheduleEntry>> relaySchedulesEntries = new HashMap<>();
final RelayType relayType = RelayType.valueOf(relayTypeDto.name());
for (final ScheduleDto schedule : scheduleList) {
for (final LightValueDto lightValue : schedule.getLightValue()) {
final List<Integer> indexes = new ArrayList<>();
if (lightValue.getIndex() == 0 && (RelayType.TARIFF.equals(relayType) || RelayType.TARIFF_REVERSED.equals(relayType))) {
// Index 0 is not allowed for tariff switching.
throw new FunctionalException(FunctionalExceptionType.VALIDATION_ERROR, ComponentType.PROTOCOL_IEC61850);
} else if (lightValue.getIndex() == 0 && RelayType.LIGHT.equals(relayType)) {
// Index == 0, getting all light relays and adding their
// internal indexes to the indexes list.
final List<DeviceOutputSetting> settings = ssldDataService.findByRelayType(ssld, relayType);
for (final DeviceOutputSetting deviceOutputSetting : settings) {
indexes.add(deviceOutputSetting.getInternalId());
}
} else {
// Index != 0, adding just the one index to the list.
indexes.add(ssldDataService.convertToInternalIndex(ssld, lightValue.getIndex()));
}
ScheduleEntry scheduleEntry;
try {
scheduleEntry = this.convertToScheduleEntry(schedule, lightValue);
} catch (final ProtocolAdapterException e) {
throw new FunctionalException(FunctionalExceptionType.VALIDATION_ERROR, ComponentType.PROTOCOL_IEC61850, e);
}
for (final Integer internalIndex : indexes) {
if (relaySchedulesEntries.containsKey(internalIndex)) {
// Internal index already in the Map, adding to the List
relaySchedulesEntries.get(internalIndex).add(scheduleEntry);
} else {
// First time we come across this relay, checking its
// type.
this.checkRelayForSchedules(ssldDataService.getDeviceOutputSettingForInternalIndex(ssld, internalIndex).getRelayType(), relayType, internalIndex);
// Adding it to scheduleEntries.
final List<ScheduleEntry> scheduleEntries = new ArrayList<>();
scheduleEntries.add(scheduleEntry);
relaySchedulesEntries.put(internalIndex, scheduleEntries);
}
}
}
}
return relaySchedulesEntries;
}
use of com.alliander.osgp.shared.exceptionhandling.FunctionalException in project Protocol-Adapter-IEC61850 by OSGP.
the class Iec61850SetScheduleCommand method setScheduleOnDevice.
public void setScheduleOnDevice(final Iec61850Client iec61850Client, final DeviceConnection deviceConnection, final RelayTypeDto relayType, final List<ScheduleDto> scheduleList, final Ssld ssld, final SsldDataService ssldDataService) throws ProtocolAdapterException {
final String tariffOrLight = relayType.equals(RelayTypeDto.LIGHT) ? "light" : "tariff";
try {
// Creating a list of all Schedule entries, grouped by relay index.
final Map<Integer, List<ScheduleEntry>> relaySchedulesEntries = this.createScheduleEntries(scheduleList, ssld, relayType, ssldDataService);
final Function<Void> function = new Function<Void>() {
@Override
public Void apply(final DeviceMessageLog deviceMessageLog) throws Exception {
for (final Integer relayIndex : relaySchedulesEntries.keySet()) {
final List<ScheduleEntry> scheduleEntries = relaySchedulesEntries.get(relayIndex);
final int numberOfScheduleEntries = scheduleEntries.size();
if (numberOfScheduleEntries > MAX_NUMBER_OF_SCHEDULE_ENTRIES) {
throw new ProtocolAdapterException("Received " + numberOfScheduleEntries + " " + tariffOrLight + " schedule entries for relay " + relayIndex + " for device " + ssld.getDeviceIdentification() + ". Setting more than " + MAX_NUMBER_OF_SCHEDULE_ENTRIES + " is not possible.");
}
final LogicalNode logicalNode = LogicalNode.getSwitchComponentByIndex(relayIndex);
final NodeContainer schedule = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, logicalNode, DataAttribute.SCHEDULE, Fc.CF);
iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), schedule.getFcmodelNode());
// entries.
for (int i = 0; i < MAX_NUMBER_OF_SCHEDULE_ENTRIES; i++) {
final String scheduleEntryName = SubDataAttribute.SCHEDULE_ENTRY.getDescription() + (i + 1);
final NodeContainer scheduleNode = schedule.getChild(scheduleEntryName);
final boolean enabled = scheduleNode.getBoolean(SubDataAttribute.SCHEDULE_ENABLE).getValue();
LOGGER.info("Checking if schedule entry {} is enabled: {}", i + 1, enabled);
if (enabled) {
LOGGER.info("Disabling schedule entry {} of {} for relay {} before setting new {} schedule", i + 1, MAX_NUMBER_OF_SCHEDULE_ENTRIES, relayIndex, tariffOrLight);
scheduleNode.writeBoolean(SubDataAttribute.SCHEDULE_ENABLE, false);
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_ENABLE, Boolean.toString(false));
}
}
for (int i = 0; i < numberOfScheduleEntries; i++) {
LOGGER.info("Writing {} schedule entry {} for relay {}", tariffOrLight, i + 1, relayIndex);
final ScheduleEntry scheduleEntry = scheduleEntries.get(i);
final String scheduleEntryName = SubDataAttribute.SCHEDULE_ENTRY.getDescription() + (i + 1);
final NodeContainer scheduleNode = schedule.getChild(scheduleEntryName);
final BdaBoolean enabled = scheduleNode.getBoolean(SubDataAttribute.SCHEDULE_ENABLE);
if (enabled.getValue() != scheduleEntry.isEnabled()) {
scheduleNode.writeBoolean(SubDataAttribute.SCHEDULE_ENABLE, scheduleEntry.isEnabled());
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_ENABLE, Boolean.toString(scheduleEntry.isEnabled()));
}
final Integer day = scheduleNode.getInteger(SubDataAttribute.SCHEDULE_DAY).getValue();
if (day != scheduleEntry.getDay()) {
scheduleNode.writeInteger(SubDataAttribute.SCHEDULE_DAY, scheduleEntry.getDay());
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_DAY, Integer.toString(scheduleEntry.getDay()));
}
/*
* A schedule entry on the platform is about
* switching on a certain time, or on a certain
* trigger. The schedule entries on the device are
* about a period with a time on and a time off. To
* bridge these different approaches, either the on
* or the off values on the device are set to a
* certain default to indicate they are not relevant
* to the schedule entry.
*/
int timeOnValue = DEFAULT_SCHEDULE_VALUE;
byte timeOnTypeValue = DEFAULT_SCHEDULE_VALUE;
int timeOffValue = DEFAULT_SCHEDULE_VALUE;
byte timeOffTypeValue = DEFAULT_SCHEDULE_VALUE;
if (scheduleEntry.isOn()) {
timeOnValue = scheduleEntry.getTime();
timeOnTypeValue = (byte) scheduleEntry.getTriggerType().getIndex();
} else {
timeOffValue = scheduleEntry.getTime();
timeOffTypeValue = (byte) scheduleEntry.getTriggerType().getIndex();
}
final Integer timeOn = scheduleNode.getInteger(SubDataAttribute.SCHEDULE_TIME_ON).getValue();
if (timeOn != timeOnValue) {
scheduleNode.writeInteger(SubDataAttribute.SCHEDULE_TIME_ON, timeOnValue);
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_TIME_ON, Integer.toString(timeOnValue));
}
final Byte timeOnActionTime = scheduleNode.getByte(SubDataAttribute.SCHEDULE_TIME_ON_TYPE).getValue();
if (timeOnActionTime != timeOnTypeValue) {
scheduleNode.writeByte(SubDataAttribute.SCHEDULE_TIME_ON_TYPE, timeOnTypeValue);
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_TIME_ON_TYPE, Byte.toString(timeOnTypeValue));
}
final Integer timeOff = scheduleNode.getInteger(SubDataAttribute.SCHEDULE_TIME_OFF).getValue();
if (timeOff != timeOffValue) {
scheduleNode.writeInteger(SubDataAttribute.SCHEDULE_TIME_OFF, timeOffValue);
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_TIME_OFF, Integer.toString(timeOffValue));
}
final Byte timeOffActionTime = scheduleNode.getByte(SubDataAttribute.SCHEDULE_TIME_OFF_TYPE).getValue();
if (timeOffActionTime != timeOffTypeValue) {
scheduleNode.writeByte(SubDataAttribute.SCHEDULE_TIME_OFF_TYPE, timeOffTypeValue);
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_TIME_OFF_TYPE, Byte.toString(timeOffTypeValue));
}
final Integer minimumTimeOn = scheduleNode.getUnsignedShort(SubDataAttribute.MINIMUM_TIME_ON).getValue();
final Integer newMinimumTimeOn = scheduleEntry.getMinimumLightsOn() / 60;
if (minimumTimeOn != newMinimumTimeOn) {
scheduleNode.writeUnsignedShort(SubDataAttribute.MINIMUM_TIME_ON, newMinimumTimeOn);
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.MINIMUM_TIME_ON, Integer.toString(newMinimumTimeOn));
}
final Integer triggerMinutesBefore = scheduleNode.getUnsignedShort(SubDataAttribute.SCHEDULE_TRIGGER_MINUTES_BEFORE).getValue();
if (triggerMinutesBefore != scheduleEntry.getTriggerWindowMinutesBefore()) {
scheduleNode.writeUnsignedShort(SubDataAttribute.SCHEDULE_TRIGGER_MINUTES_BEFORE, scheduleEntry.getTriggerWindowMinutesBefore());
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_TRIGGER_MINUTES_BEFORE, Integer.toString(scheduleEntry.getTriggerWindowMinutesBefore()));
}
final Integer triggerMinutesAfter = scheduleNode.getUnsignedShort(SubDataAttribute.SCHEDULE_TRIGGER_MINUTES_AFTER).getValue();
if (triggerMinutesAfter != scheduleEntry.getTriggerWindowMinutesAfter()) {
scheduleNode.writeUnsignedShort(SubDataAttribute.SCHEDULE_TRIGGER_MINUTES_AFTER, scheduleEntry.getTriggerWindowMinutesAfter());
deviceMessageLog.addVariable(logicalNode, DataAttribute.SCHEDULE, Fc.CF, scheduleEntryName, SubDataAttribute.SCHEDULE_TRIGGER_MINUTES_AFTER, Integer.toString(scheduleEntry.getTriggerWindowMinutesAfter()));
}
}
}
DeviceMessageLoggingService.logMessage(deviceMessageLog, deviceConnection.getDeviceIdentification(), deviceConnection.getOrganisationIdentification(), false);
return null;
}
};
iec61850Client.sendCommandWithRetry(function, "SetSchedule", deviceConnection.getDeviceIdentification());
} catch (final FunctionalException e) {
throw new ProtocolAdapterException(e.getMessage(), e);
}
}
use of com.alliander.osgp.shared.exceptionhandling.FunctionalException in project Protocol-Adapter-OSLP by OSGP.
the class DeviceRequestMessageProcessor method handleExpectedError.
protected void handleExpectedError(final Exception e, final String correlationUid, final String organisationIdentification, final String deviceIdentification, final String domain, final String domainVersion, final String messageType) {
LOGGER.error("Expected error while processing message", e);
final FunctionalException ex = new FunctionalException(FunctionalExceptionType.VALIDATION_ERROR, ComponentType.PROTOCOL_OSLP, e);
final DeviceMessageMetadata deviceMessageMetadata = new DeviceMessageMetadata(deviceIdentification, organisationIdentification, correlationUid, messageType, MessagePriorityEnum.DEFAULT.getPriority());
final ProtocolResponseMessage protocolResponseMessage = ProtocolResponseMessage.newBuilder().domain(domain).domainVersion(domainVersion).deviceMessageMetadata(deviceMessageMetadata).result(ResponseMessageResultType.NOT_OK).osgpException(ex).build();
this.responseMessageSender.send(protocolResponseMessage);
}
use of com.alliander.osgp.shared.exceptionhandling.FunctionalException in project Protocol-Adapter-IEC61850 by OSGP.
the class DeviceRequestMessageListener method sendException.
private void sendException(final ObjectMessage objectMessage, final Exception exception) {
try {
final String domain = objectMessage.getStringProperty(Constants.DOMAIN);
final String domainVersion = objectMessage.getStringProperty(Constants.DOMAIN_VERSION);
final ResponseMessageResultType result = ResponseMessageResultType.NOT_OK;
final FunctionalException osgpException = new FunctionalException(FunctionalExceptionType.UNSUPPORTED_DEVICE_ACTION, ComponentType.PROTOCOL_IEC61850, exception);
final Serializable dataObject = objectMessage.getObject();
final DeviceMessageMetadata deviceMessageMetadata = new DeviceMessageMetadata(objectMessage);
final ProtocolResponseMessage protocolResponseMessage = new ProtocolResponseMessage.Builder().deviceMessageMetadata(deviceMessageMetadata).domain(domain).domainVersion(domainVersion).result(result).osgpException(osgpException).dataObject(dataObject).scheduled(false).build();
this.deviceResponseMessageSender.send(protocolResponseMessage);
} catch (final Exception e) {
LOGGER.error("Unexpected error during sendException(ObjectMessage, Exception)", e);
}
}
Aggregations