Search in sources :

Example 1 with DeviceMessageLog

use of org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog in project Protocol-Adapter-IEC61850 by OSGP.

the class Iec61850GetConfigurationCommand method getConfigurationFromDevice.

public ConfigurationDto getConfigurationFromDevice(final Iec61850Client iec61850Client, final DeviceConnection deviceConnection, final Ssld ssld, final Iec61850Mapper mapper) throws ProtocolAdapterException {
    final Function<ConfigurationDto> function = new Function<ConfigurationDto>() {

        @Override
        public ConfigurationDto apply(final DeviceMessageLog deviceMessageLog) throws Exception {
            // Keeping the hardcoded values and values that aren't fetched
            // from the device out of the Function.
            // Hardcoded (not supported)
            final MeterTypeDto meterType = MeterTypeDto.AUX;
            // Hardcoded (not supported)
            final Integer shortTermHistoryIntervalMinutes = 15;
            // Hardcoded (not supported)
            final LinkTypeDto preferredLinkType = LinkTypeDto.ETHERNET;
            // Hardcoded (not supported)
            final Integer longTermHistoryInterval = 1;
            // Hardcoded (not supported)
            final LongTermIntervalTypeDto longTermHistoryIntervalType = LongTermIntervalTypeDto.DAYS;
            final List<RelayMapDto> relayMaps = new ArrayList<>();
            for (final DeviceOutputSetting deviceOutputSetting : ssld.getOutputSettings()) {
                Iec61850GetConfigurationCommand.this.checkRelayType(iec61850Client, deviceConnection, deviceOutputSetting, deviceMessageLog);
                relayMaps.add(mapper.map(deviceOutputSetting, RelayMapDto.class));
            }
            final RelayConfigurationDto relayConfiguration = new RelayConfigurationDto(relayMaps);
            // PSLD specific => just sending null so it'll be ignored
            final DaliConfigurationDto daliConfiguration = null;
            // getting the software configuration values
            LOGGER.info("Reading the software configuration values");
            final NodeContainer softwareConfiguration = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.SOFTWARE_CONFIGURATION, Fc.CF);
            iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), softwareConfiguration.getFcmodelNode());
            String lightTypeValue = softwareConfiguration.getString(SubDataAttribute.LIGHT_TYPE);
            // Fix for Kaifa bug KI-31
            if (lightTypeValue == null || lightTypeValue.isEmpty()) {
                lightTypeValue = "RELAY";
            }
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.SOFTWARE_CONFIGURATION, Fc.CF, SubDataAttribute.LIGHT_TYPE, lightTypeValue);
            final LightTypeDto lightType = LightTypeDto.valueOf(lightTypeValue);
            final short astroGateSunRiseOffset = softwareConfiguration.getShort(SubDataAttribute.ASTRONOMIC_SUNRISE_OFFSET).getValue();
            final short astroGateSunSetOffset = softwareConfiguration.getShort(SubDataAttribute.ASTRONOMIC_SUNSET_OFFSET).getValue();
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.SOFTWARE_CONFIGURATION, Fc.CF, SubDataAttribute.ASTRONOMIC_SUNRISE_OFFSET, Short.toString(astroGateSunRiseOffset));
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.SOFTWARE_CONFIGURATION, Fc.CF, SubDataAttribute.ASTRONOMIC_SUNSET_OFFSET, Short.toString(astroGateSunSetOffset));
            final ConfigurationDto configuration = new ConfigurationDto(lightType, daliConfiguration, relayConfiguration, shortTermHistoryIntervalMinutes, preferredLinkType, meterType, longTermHistoryInterval, longTermHistoryIntervalType);
            // getting the registration configuration values
            LOGGER.info("Reading the registration configuration values");
            final NodeContainer registration = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.REGISTRATION, Fc.CF);
            iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), registration.getFcmodelNode());
            final String serverAddress = registration.getString(SubDataAttribute.SERVER_ADDRESS);
            final int serverPort = registration.getInteger(SubDataAttribute.SERVER_PORT).getValue();
            configuration.setOsgpIpAddress(serverAddress);
            configuration.setOsgpPortNumber(serverPort);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.REGISTRATION, Fc.CF, SubDataAttribute.SERVER_ADDRESS, serverAddress);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.REGISTRATION, Fc.CF, SubDataAttribute.SERVER_PORT, Integer.toString(serverPort));
            // getting the IP configuration values
            LOGGER.info("Reading the IP configuration values");
            final NodeContainer ipConfiguration = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.IP_CONFIGURATION, Fc.CF);
            iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), ipConfiguration.getFcmodelNode());
            final String deviceFixedIpAddress = ipConfiguration.getString(SubDataAttribute.IP_ADDRESS);
            final String deviceFixedIpNetmask = ipConfiguration.getString(SubDataAttribute.NETMASK);
            final String deviceFixedIpGateway = ipConfiguration.getString(SubDataAttribute.GATEWAY);
            final boolean isDhcpEnabled = ipConfiguration.getBoolean(SubDataAttribute.ENABLE_DHCP).getValue();
            final DeviceFixedIpDto deviceFixedIp = new DeviceFixedIpDto(deviceFixedIpAddress, deviceFixedIpNetmask, deviceFixedIpGateway);
            configuration.setDeviceFixedIp(deviceFixedIp);
            configuration.setDhcpEnabled(isDhcpEnabled);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.IP_CONFIGURATION, Fc.CF, SubDataAttribute.IP_ADDRESS, deviceFixedIpAddress);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.IP_CONFIGURATION, Fc.CF, SubDataAttribute.NETMASK, deviceFixedIpNetmask);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.IP_CONFIGURATION, Fc.CF, SubDataAttribute.GATEWAY, deviceFixedIpGateway);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.IP_CONFIGURATION, Fc.CF, SubDataAttribute.ENABLE_DHCP, Boolean.toString(isDhcpEnabled));
            // setting the software configuration values
            configuration.setAstroGateSunRiseOffset((int) astroGateSunRiseOffset);
            configuration.setAstroGateSunSetOffset((int) astroGateSunSetOffset);
            // getting the clock configuration values
            LOGGER.info("Reading the clock configuration values");
            final NodeContainer clock = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.CLOCK, Fc.CF);
            iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), clock.getFcmodelNode());
            final int timeSyncFrequency = clock.getUnsignedShort(SubDataAttribute.TIME_SYNC_FREQUENCY).getValue();
            final boolean automaticSummerTimingEnabled = clock.getBoolean(SubDataAttribute.AUTOMATIC_SUMMER_TIMING_ENABLED).getValue();
            final String summerTimeDetails = clock.getString(SubDataAttribute.SUMMER_TIME_DETAILS);
            final String winterTimeDetails = clock.getString(SubDataAttribute.WINTER_TIME_DETAILS);
            configuration.setTimeSyncFrequency(timeSyncFrequency);
            configuration.setAutomaticSummerTimingEnabled(automaticSummerTimingEnabled);
            configuration.setSummerTimeDetails(new DaylightSavingTimeTransition(TIME_ZONE_AMSTERDAM, summerTimeDetails).getDateTimeForNextTransition().toDateTime(DateTimeZone.UTC));
            configuration.setWinterTimeDetails(new DaylightSavingTimeTransition(TIME_ZONE_AMSTERDAM, winterTimeDetails).getDateTimeForNextTransition().toDateTime(DateTimeZone.UTC));
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.CLOCK, Fc.CF, SubDataAttribute.TIME_SYNC_FREQUENCY, Integer.toString(timeSyncFrequency));
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.CLOCK, Fc.CF, SubDataAttribute.AUTOMATIC_SUMMER_TIMING_ENABLED, Boolean.toString(automaticSummerTimingEnabled));
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.CLOCK, Fc.CF, SubDataAttribute.SUMMER_TIME_DETAILS, summerTimeDetails);
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.CLOCK, Fc.CF, SubDataAttribute.WINTER_TIME_DETAILS, winterTimeDetails);
            // getting the TLS configuration values
            // LOGGER.info("Reading the TLS configuration values");
            // final NodeContainer tls =
            // deviceConnection.getFcModelNode(LogicalDevice.LIGHTING,
            // LogicalNode.STREET_LIGHT_CONFIGURATION,
            // DataAttribute.TLS_CONFIGURATION, Fc.CF);
            //
            // iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(),
            // tls.getFcmodelNode());
            //
            // final int tlsPortNumber = (int)
            // tls.getUnsignedInteger(SubDataAttribute.TLS_PORT_NUMBER).getValue();
            // final boolean tlsEnabled =
            // tls.getBoolean(SubDataAttribute.TLS_ENABLED).getValue();
            // final String commonName =
            // tls.getString(SubDataAttribute.TLS_COMMON_NAME);
            //
            // configuration.setTlsPortNumber(tlsPortNumber);
            // configuration.setTlsEnabled(tlsEnabled);
            // configuration.setCommonNameString(commonName);
            DeviceMessageLoggingService.logMessage(deviceMessageLog, deviceConnection.getDeviceIdentification(), deviceConnection.getOrganisationIdentification(), false);
            return configuration;
        }
    };
    return iec61850Client.sendCommandWithRetry(function, "GetConfiguration", deviceConnection.getDeviceIdentification());
}
Also used : LinkTypeDto(com.alliander.osgp.dto.valueobjects.LinkTypeDto) DaliConfigurationDto(com.alliander.osgp.dto.valueobjects.DaliConfigurationDto) LightTypeDto(com.alliander.osgp.dto.valueobjects.LightTypeDto) DeviceFixedIpDto(com.alliander.osgp.dto.valueobjects.DeviceFixedIpDto) ArrayList(java.util.ArrayList) MeterTypeDto(com.alliander.osgp.dto.valueobjects.MeterTypeDto) DeviceOutputSetting(com.alliander.osgp.core.db.api.iec61850.entities.DeviceOutputSetting) NodeContainer(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.NodeContainer) LongTermIntervalTypeDto(com.alliander.osgp.dto.valueobjects.LongTermIntervalTypeDto) Function(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.Function) DaylightSavingTimeTransition(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DaylightSavingTimeTransition) DeviceMessageLog(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog) ConfigurationDto(com.alliander.osgp.dto.valueobjects.ConfigurationDto) DaliConfigurationDto(com.alliander.osgp.dto.valueobjects.DaliConfigurationDto) RelayConfigurationDto(com.alliander.osgp.dto.valueobjects.RelayConfigurationDto) RelayMapDto(com.alliander.osgp.dto.valueobjects.RelayMapDto) RelayConfigurationDto(com.alliander.osgp.dto.valueobjects.RelayConfigurationDto)

Example 2 with DeviceMessageLog

use of org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog in project Protocol-Adapter-IEC61850 by OSGP.

the class Iec61850GetFirmwareVersionCommand method getFirmwareVersionFromDevice.

public List<FirmwareVersionDto> getFirmwareVersionFromDevice(final Iec61850Client iec61850Client, final DeviceConnection deviceConnection) throws ProtocolAdapterException {
    final Function<List<FirmwareVersionDto>> function = new Function<List<FirmwareVersionDto>>() {

        @Override
        public List<FirmwareVersionDto> apply(final DeviceMessageLog deviceMessageLog) throws Exception {
            final List<FirmwareVersionDto> output = new ArrayList<>();
            // Getting the functional firmware version
            LOGGER.info("Reading the functional firmware version");
            final NodeContainer functionalFirmwareNode = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.FUNCTIONAL_FIRMWARE, Fc.ST);
            iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), functionalFirmwareNode.getFcmodelNode());
            final String functionalFirmwareVersion = functionalFirmwareNode.getString(SubDataAttribute.CURRENT_VERSION);
            // Adding it to the list
            output.add(new FirmwareVersionDto(FirmwareModuleType.FUNCTIONAL, functionalFirmwareVersion));
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.FUNCTIONAL_FIRMWARE, Fc.ST, SubDataAttribute.CURRENT_VERSION, functionalFirmwareVersion);
            // Getting the security firmware version
            LOGGER.info("Reading the security firmware version");
            final NodeContainer securityFirmwareNode = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.SECURITY_FIRMWARE, Fc.ST);
            iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), securityFirmwareNode.getFcmodelNode());
            final String securityFirmwareVersion = securityFirmwareNode.getString(SubDataAttribute.CURRENT_VERSION);
            // Adding it to the list
            output.add(new FirmwareVersionDto(FirmwareModuleType.SECURITY, securityFirmwareVersion));
            deviceMessageLog.addVariable(LogicalNode.STREET_LIGHT_CONFIGURATION, DataAttribute.SECURITY_FIRMWARE, Fc.ST, SubDataAttribute.CURRENT_VERSION, securityFirmwareVersion);
            DeviceMessageLoggingService.logMessage(deviceMessageLog, deviceConnection.getDeviceIdentification(), deviceConnection.getOrganisationIdentification(), false);
            return output;
        }
    };
    return iec61850Client.sendCommandWithRetry(function, "GetFirmwareVersion", deviceConnection.getDeviceIdentification());
}
Also used : Function(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.Function) DeviceMessageLog(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog) ArrayList(java.util.ArrayList) NodeContainer(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.NodeContainer) ArrayList(java.util.ArrayList) List(java.util.List) FirmwareVersionDto(com.alliander.osgp.dto.valueobjects.FirmwareVersionDto)

Example 3 with DeviceMessageLog

use of org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog in project Protocol-Adapter-IEC61850 by OSGP.

the class Iec61850Client method sendCommandWithRetry.

/**
     * Executes the apply method of the given {@link Function} with retries and
     * message logging.
     *
     * @return The given T.
     */
public <T> T sendCommandWithRetry(final Function<T> function, final String functionName, final String deviceIdentification) throws ProtocolAdapterException {
    T output = null;
    final DeviceMessageLog deviceMessageLog = new DeviceMessageLog(IED.FLEX_OVL, LogicalDevice.LIGHTING, functionName);
    try {
        output = function.apply(deviceMessageLog);
    } catch (final NodeWriteException | NodeReadException e) {
        if (ConnectionState.OK.equals(e.getConnectionState())) {
            // ServiceError means we have to retry.
            LOGGER.error("Caught ServiceError, retrying", e);
            this.sendCommandWithRetry(function, deviceIdentification, 1, deviceMessageLog);
        } else {
            LOGGER.error("Caught IOException, connection with device is broken.", e);
        }
    } catch (final ConnectionFailureException e) {
        throw e;
    } catch (final Exception e) {
        throw new ProtocolAdapterException(e == null ? "Could not execute command" : e.getMessage(), e);
    }
    return output;
}
Also used : DeviceMessageLog(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog) NodeWriteException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.NodeWriteException) ConnectionFailureException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ConnectionFailureException) NodeReadException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.NodeReadException) ProtocolAdapterException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException) SclParseException(org.openmuc.openiec61850.SclParseException) NodeWriteException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.NodeWriteException) NodeReadException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.NodeReadException) ConnectionFailureException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ConnectionFailureException) IOException(java.io.IOException) ProtocolAdapterException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException)

Example 4 with DeviceMessageLog

use of org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog in project Protocol-Adapter-IEC61850 by OSGP.

the class Iec61850SetLightCommand method switchLightRelay.

public Boolean switchLightRelay(final Iec61850Client iec61850Client, final DeviceConnection deviceConnection, final int index, final boolean on) throws ProtocolAdapterException {
    // Commands don't return anything, so returnType is Void.
    final Function<Boolean> function = new Function<Boolean>() {

        @Override
        public Boolean apply(final DeviceMessageLog deviceMessageLog) throws Exception {
            try {
                final LogicalNode logicalNode = LogicalNode.getSwitchComponentByIndex(index);
                // Check if CfSt.enbOper [CF] is set to true. If it is not
                // set to true, the relay can not be operated.
                final NodeContainer masterControl = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, logicalNode, DataAttribute.MASTER_CONTROL, Fc.CF);
                iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), masterControl.getFcmodelNode());
                final BdaBoolean enbOper = masterControl.getBoolean(SubDataAttribute.ENABLE_OPERATION);
                if (enbOper.getValue()) {
                    LOGGER.info("masterControl.enbOper is true, switching of relay {} is enabled", index);
                } else {
                    LOGGER.info("masterControl.enbOper is false, switching of relay {} is disabled", index);
                    // Set the value to true.
                    masterControl.writeBoolean(SubDataAttribute.ENABLE_OPERATION, true);
                    LOGGER.info("set masterControl.enbOper to true to enable switching of relay {}", index);
                    deviceMessageLog.addVariable(logicalNode, DataAttribute.MASTER_CONTROL, Fc.CF, SubDataAttribute.ENABLE_OPERATION, Boolean.toString(true));
                }
                // Switch the relay using Pos.Oper.ctlVal [CO].
                final NodeContainer position = deviceConnection.getFcModelNode(LogicalDevice.LIGHTING, logicalNode, DataAttribute.POSITION, Fc.CO);
                iec61850Client.readNodeDataValues(deviceConnection.getConnection().getClientAssociation(), position.getFcmodelNode());
                final NodeContainer operation = position.getChild(SubDataAttribute.OPERATION);
                final BdaBoolean controlValue = operation.getBoolean(SubDataAttribute.CONTROL_VALUE);
                LOGGER.info(String.format("Switching relay %d %s", index, on ? "on" : "off"));
                controlValue.setValue(on);
                operation.write();
                deviceMessageLog.addVariable(logicalNode, DataAttribute.POSITION, Fc.CO, SubDataAttribute.OPERATION, SubDataAttribute.CONTROL_VALUE, Boolean.toString(on));
                DeviceMessageLoggingService.logMessage(deviceMessageLog, deviceConnection.getDeviceIdentification(), deviceConnection.getOrganisationIdentification(), false);
                return true;
            } catch (final Exception e) {
                LOGGER.error("Exception during switchLightRelay()", e);
                return false;
            }
        }
    };
    return iec61850Client.sendCommandWithRetry(function, "SetLight", deviceConnection.getDeviceIdentification());
}
Also used : Function(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.Function) DeviceMessageLog(com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog) BdaBoolean(org.openmuc.openiec61850.BdaBoolean) NodeContainer(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.NodeContainer) LogicalNode(com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.LogicalNode) BdaBoolean(org.openmuc.openiec61850.BdaBoolean) ProtocolAdapterException(com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException)

Example 5 with DeviceMessageLog

use of org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog 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)

Aggregations

DeviceMessageLog (com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog)16 Function (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.Function)15 DeviceMessageLog (org.opensmartgridplatform.adapter.protocol.iec61850.domain.valueobjects.DeviceMessageLog)14 Function (org.opensmartgridplatform.adapter.protocol.iec61850.infra.networking.helper.Function)12 NodeContainer (org.opensmartgridplatform.adapter.protocol.iec61850.infra.networking.helper.NodeContainer)12 NodeContainer (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.NodeContainer)10 ArrayList (java.util.ArrayList)10 BdaBoolean (com.beanit.openiec61850.BdaBoolean)6 DateTime (org.joda.time.DateTime)6 BdaBoolean (org.openmuc.openiec61850.BdaBoolean)5 ProtocolAdapterException (org.opensmartgridplatform.adapter.protocol.iec61850.exceptions.ProtocolAdapterException)5 ProtocolAdapterException (com.alliander.osgp.adapter.protocol.iec61850.exceptions.ProtocolAdapterException)4 LogicalNode (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.helper.LogicalNode)4 Date (java.util.Date)4 List (java.util.List)4 DeviceOutputSetting (com.alliander.osgp.core.db.api.iec61850.entities.DeviceOutputSetting)3 IOException (java.io.IOException)3 LogicalNode (org.opensmartgridplatform.adapter.protocol.iec61850.infra.networking.helper.LogicalNode)3 DaylightSavingTimeTransition (com.alliander.osgp.adapter.protocol.iec61850.domain.valueobjects.DaylightSavingTimeTransition)2 SystemService (com.alliander.osgp.adapter.protocol.iec61850.infra.networking.SystemService)2