Search in sources :

Example 1 with ScheduleEntry

use of com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry 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;
}
Also used : HashMap(java.util.HashMap) ArrayList(java.util.ArrayList) DeviceOutputSetting(com.alliander.osgp.core.db.api.iec61850.entities.DeviceOutputSetting) ScheduleDto(com.alliander.osgp.dto.valueobjects.ScheduleDto) LightValueDto(com.alliander.osgp.dto.valueobjects.LightValueDto) RelayType(com.alliander.osgp.core.db.api.iec61850valueobjects.RelayType) ScheduleEntry(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry) ArrayList(java.util.ArrayList) List(java.util.List) FunctionalException(com.alliander.osgp.shared.exceptionhandling.FunctionalException) ProtocolAdapterException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException)

Example 2 with ScheduleEntry

use of com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry 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);
    }
}
Also used : NodeContainer(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.NodeContainer) LogicalNode(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.LogicalNode) Function(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.Function) DeviceMessageLog(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog) ScheduleEntry(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry) BdaBoolean(org.openmuc.openiec61850.BdaBoolean) ArrayList(java.util.ArrayList) List(java.util.List) ProtocolAdapterException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException) FunctionalException(com.alliander.osgp.shared.exceptionhandling.FunctionalException)

Example 3 with ScheduleEntry

use of com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry in project Protocol-Adapter-IEC61850 by OSGP.

the class Iec61850SetScheduleCommand method convertToScheduleEntry.

private ScheduleEntry convertToScheduleEntry(final ScheduleDto schedule, final LightValueDto lightValue) throws ProtocolAdapterException {
    final ScheduleEntry.Builder builder = new ScheduleEntry.Builder();
    try {
        if (schedule.getTime() != null) {
            builder.time(this.convertTime(schedule.getTime()));
        }
        final WindowTypeDto triggerWindow = schedule.getTriggerWindow();
        if (triggerWindow != null) {
            if (triggerWindow.getMinutesBefore() > Integer.MAX_VALUE) {
                throw new IllegalArgumentException("Schedule TriggerWindow minutesBefore must not be greater than " + Integer.MAX_VALUE);
            }
            if (triggerWindow.getMinutesAfter() > Integer.MAX_VALUE) {
                throw new IllegalArgumentException("Schedule TriggerWindow minutesAfter must not be greater than " + Integer.MAX_VALUE);
            }
            builder.triggerWindowMinutesBefore((int) triggerWindow.getMinutesBefore());
            builder.triggerWindowMinutesAfter((int) triggerWindow.getMinutesAfter());
        }
        builder.triggerType(this.extractTriggerType(schedule));
        builder.enabled(schedule.getIsEnabled() == null ? true : schedule.getIsEnabled());
        final WeekDayTypeDto weekDay = schedule.getWeekDay();
        if (WeekDayTypeDto.ABSOLUTEDAY.equals(weekDay)) {
            final DateTime specialDay = schedule.getStartDay();
            if (specialDay == null) {
                throw new IllegalArgumentException("Schedule startDay must not be null when weekDay equals ABSOLUTEDAY");
            }
            builder.specialDay(specialDay);
        } else {
            builder.weekday(ScheduleWeekday.valueOf(schedule.getWeekDay().name()));
        }
        builder.on(lightValue.isOn());
        if (schedule.getMinimumLightsOn() != null) {
            builder.minimumLightsOn(schedule.getMinimumLightsOn());
        }
        return builder.build();
    } catch (IllegalStateException | IllegalArgumentException e) {
        throw new ProtocolAdapterException("Error converting ScheduleDto and LightValueDto into a ScheduleEntry: " + e.getMessage(), e);
    }
}
Also used : ScheduleEntry(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry) WindowTypeDto(com.alliander.osgp.dto.valueobjects.WindowTypeDto) WeekDayTypeDto(com.alliander.osgp.dto.valueobjects.WeekDayTypeDto) ProtocolAdapterException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException) DateTime(org.joda.time.DateTime)

Aggregations

ScheduleEntry (com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.ScheduleEntry)3 ProtocolAdapterException (com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException)3 FunctionalException (com.alliander.osgp.shared.exceptionhandling.FunctionalException)2 ArrayList (java.util.ArrayList)2 List (java.util.List)2 DeviceMessageLog (com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog)1 Function (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.Function)1 LogicalNode (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.LogicalNode)1 NodeContainer (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.NodeContainer)1 DeviceOutputSetting (com.alliander.osgp.core.db.api.iec61850.entities.DeviceOutputSetting)1 RelayType (com.alliander.osgp.core.db.api.iec61850valueobjects.RelayType)1 LightValueDto (com.alliander.osgp.dto.valueobjects.LightValueDto)1 ScheduleDto (com.alliander.osgp.dto.valueobjects.ScheduleDto)1 WeekDayTypeDto (com.alliander.osgp.dto.valueobjects.WeekDayTypeDto)1 WindowTypeDto (com.alliander.osgp.dto.valueobjects.WindowTypeDto)1 HashMap (java.util.HashMap)1 DateTime (org.joda.time.DateTime)1 BdaBoolean (org.openmuc.openiec61850.BdaBoolean)1