Search in sources :

Example 1 with MeasurementConfig

use of net.solarnetwork.node.io.dnp3.domain.MeasurementConfig in project solarnetwork-node by SolarNetwork.

the class OutstationService method changeSetForDatumCapturedEvent.

private OutstationChangeSet changeSetForDatumCapturedEvent(final Datum datum, final Event event) {
    Map<MeasurementType, List<MeasurementConfig>> map = measurementTypeMap(getMeasurementConfigs());
    Map<ControlType, List<ControlConfig>> controlMap = controlTypeMap(getControlConfigs());
    if (datum == null || ((map == null || map.isEmpty()) && (controlMap == null || controlMap.isEmpty()))) {
        return null;
    }
    final String sourceId = datum.getSourceId();
    final Instant timestamp = datum.getTimestamp();
    if (timestamp == null) {
        return null;
    }
    final long ts = timestamp.toEpochMilli();
    final Map<String, ?> datumProps = datum.getSampleData();
    OutstationChangeSet changes = null;
    if (map != null) {
        for (Map.Entry<MeasurementType, List<MeasurementConfig>> me : map.entrySet()) {
            MeasurementType type = me.getKey();
            List<MeasurementConfig> list = me.getValue();
            for (ListIterator<MeasurementConfig> itr = list.listIterator(); itr.hasNext(); ) {
                MeasurementConfig config = itr.next();
                if (sourceId.equals(config.getSourceId())) {
                    Object propVal = datumProps.get(config.getPropertyName());
                    if (propVal != null) {
                        if (propVal instanceof Number) {
                            if (config.getUnitMultiplier() != null) {
                                propVal = applyUnitMultiplier((Number) propVal, config.getUnitMultiplier());
                            }
                            if (config.getDecimalScale() >= 0) {
                                propVal = applyDecimalScale((Number) propVal, config.getDecimalScale());
                            }
                        }
                        if (changes == null) {
                            changes = new OutstationChangeSet();
                        }
                        log.debug("Updating DNP3 {}[{}] from [{}].{} -> {}", type, itr.previousIndex(), sourceId, config.getPropertyName(), propVal);
                        switch(type) {
                            case AnalogInput:
                                if (propVal instanceof Number) {
                                    changes.update(new AnalogInput(((Number) propVal).doubleValue(), (byte) AnalogQuality.ONLINE.toType(), ts), itr.previousIndex());
                                }
                                break;
                            case AnalogOutputStatus:
                                if (propVal instanceof Number) {
                                    changes.update(new AnalogOutputStatus(((Number) propVal).doubleValue(), (byte) AnalogOutputStatusQuality.ONLINE.toType(), ts), itr.previousIndex());
                                }
                                break;
                            case BinaryInput:
                                changes.update(new BinaryInput(booleanPropertyValue(propVal), (byte) BinaryQuality.ONLINE.toType(), ts), itr.previousIndex());
                                break;
                            case BinaryOutputStatus:
                                changes.update(new BinaryOutputStatus(booleanPropertyValue(propVal), (byte) BinaryOutputStatusQuality.ONLINE.toType(), ts), itr.previousIndex());
                                break;
                            case Counter:
                                if (propVal instanceof Number) {
                                    changes.update(new Counter(((Number) propVal).longValue(), (byte) CounterQuality.ONLINE.toType(), ts), itr.previousIndex());
                                }
                                break;
                            case DoubleBitBinaryInput:
                                changes.update(new DoubleBitBinaryInput(booleanPropertyValue(propVal) ? DoubleBit.DETERMINED_ON : DoubleBit.DETERMINED_OFF, (byte) DoubleBitBinaryQuality.ONLINE.toType(), ts), itr.previousIndex());
                                break;
                            case FrozenCounter:
                                if (propVal instanceof Number) {
                                    changes.update(new FrozenCounter(((Number) propVal).longValue(), (byte) FrozenCounterQuality.ONLINE.toType(), ts), itr.previousIndex());
                                }
                                break;
                        }
                    }
                }
            }
        }
        if (controlMap != null) {
            int analogStatusOffset = typeConfigCount(MeasurementType.AnalogOutputStatus, map);
            int binaryStatusOffset = typeConfigCount(MeasurementType.BinaryOutputStatus, map);
            for (Map.Entry<ControlType, List<ControlConfig>> me : controlMap.entrySet()) {
                ControlType type = me.getKey();
                List<ControlConfig> list = me.getValue();
                for (ListIterator<ControlConfig> itr = list.listIterator(); itr.hasNext(); ) {
                    ControlConfig config = itr.next();
                    if (sourceId.equals(config.getControlId())) {
                        if (changes == null) {
                            changes = new OutstationChangeSet();
                        }
                        int index = (type == ControlType.Analog ? analogStatusOffset : binaryStatusOffset) + itr.previousIndex();
                        Object propVal = datumProps.get("value");
                        log.debug("Updating DNP3 control {}[{}] from [{}].value -> {}", type, index, sourceId, propVal);
                        switch(type) {
                            case Analog:
                                try {
                                    Number n = null;
                                    if (propVal instanceof Number) {
                                        n = (Number) propVal;
                                    } else {
                                        n = new BigDecimal(propVal.toString());
                                    }
                                    changes.update(new AnalogOutputStatus(n.doubleValue(), (byte) AnalogOutputStatusQuality.ONLINE.toType(), ts), index);
                                } catch (NumberFormatException e) {
                                    log.warn("Cannot convert control [{}] value [{}] to number: {}", sourceId, propVal, e.getMessage());
                                }
                                break;
                            case Binary:
                                changes.update(new BinaryOutputStatus(booleanPropertyValue(propVal), (byte) BinaryOutputStatusQuality.ONLINE.toType(), ts), index);
                                break;
                        }
                    }
                }
            }
        }
    }
    return changes;
}
Also used : AnalogInput(com.automatak.dnp3.AnalogInput) Counter(com.automatak.dnp3.Counter) FrozenCounter(com.automatak.dnp3.FrozenCounter) DoubleBitBinaryInput(com.automatak.dnp3.DoubleBitBinaryInput) MeasurementType(net.solarnetwork.node.io.dnp3.domain.MeasurementType) List(java.util.List) ArrayList(java.util.ArrayList) BinaryOutputStatus(com.automatak.dnp3.BinaryOutputStatus) MeasurementConfig(net.solarnetwork.node.io.dnp3.domain.MeasurementConfig) BinaryInput(com.automatak.dnp3.BinaryInput) DoubleBitBinaryInput(com.automatak.dnp3.DoubleBitBinaryInput) ControlConfig(net.solarnetwork.node.io.dnp3.domain.ControlConfig) Instant(java.time.Instant) BigDecimal(java.math.BigDecimal) OutstationChangeSet(com.automatak.dnp3.OutstationChangeSet) FrozenCounter(com.automatak.dnp3.FrozenCounter) ControlType(net.solarnetwork.node.io.dnp3.domain.ControlType) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap) AnalogOutputStatus(com.automatak.dnp3.AnalogOutputStatus)

Example 2 with MeasurementConfig

use of net.solarnetwork.node.io.dnp3.domain.MeasurementConfig in project solarnetwork-node by SolarNetwork.

the class OutstationService method getSettingSpecifiers.

/*
	 * =========================================================================
	 * SettingSpecifierProvider implementation
	 * =========================================================================
	 */
@Override
public List<SettingSpecifier> getSettingSpecifiers() {
    List<SettingSpecifier> result = new ArrayList<>(16);
    result.add(new BasicTitleSettingSpecifier("status", getStackStatusMessage(), true));
    result.add(new BasicTextFieldSettingSpecifier("uid", DEFAULT_UID));
    result.add(new BasicTextFieldSettingSpecifier("groupUid", ""));
    result.add(new BasicTextFieldSettingSpecifier("eventBufferSize", String.valueOf(DEFAULT_EVENT_BUFFER_SIZE)));
    result.add(new BasicTextFieldSettingSpecifier("dnp3Channel.propertyFilters['uid']", TcpServerChannelService.DEFAULT_UID));
    result.addAll(linkLayerSettings("linkLayerConfig.", new LinkLayerConfig(false)));
    result.addAll(outstationSettings("outstationConfig.", new OutstationConfig()));
    MeasurementConfig[] measConfs = getMeasurementConfigs();
    List<MeasurementConfig> measConfsList = (measConfs != null ? Arrays.asList(measConfs) : Collections.<MeasurementConfig>emptyList());
    result.add(SettingUtils.dynamicListSettingSpecifier("measurementConfigs", measConfsList, new SettingUtils.KeyedListCallback<MeasurementConfig>() {

        @Override
        public Collection<SettingSpecifier> mapListSettingKey(MeasurementConfig value, int index, String key) {
            BasicGroupSettingSpecifier configGroup = new BasicGroupSettingSpecifier(MeasurementConfig.settings(key + "."));
            return Collections.<SettingSpecifier>singletonList(configGroup);
        }
    }));
    ControlConfig[] cntrlConfs = getControlConfigs();
    List<ControlConfig> cntrlConfsList = (cntrlConfs != null ? Arrays.asList(cntrlConfs) : Collections.<ControlConfig>emptyList());
    result.add(SettingUtils.dynamicListSettingSpecifier("controlConfigs", cntrlConfsList, new SettingUtils.KeyedListCallback<ControlConfig>() {

        @Override
        public Collection<SettingSpecifier> mapListSettingKey(ControlConfig value, int index, String key) {
            BasicGroupSettingSpecifier configGroup = new BasicGroupSettingSpecifier(ControlConfig.settings(key + "."));
            return Collections.<SettingSpecifier>singletonList(configGroup);
        }
    }));
    return result;
}
Also used : MeasurementConfig(net.solarnetwork.node.io.dnp3.domain.MeasurementConfig) ControlConfig(net.solarnetwork.node.io.dnp3.domain.ControlConfig) LinkLayerConfig(net.solarnetwork.node.io.dnp3.domain.LinkLayerConfig) ArrayList(java.util.ArrayList) OutstationConfig(net.solarnetwork.node.io.dnp3.domain.OutstationConfig) BasicGroupSettingSpecifier(net.solarnetwork.settings.support.BasicGroupSettingSpecifier) SettingSpecifier(net.solarnetwork.settings.SettingSpecifier) BasicTitleSettingSpecifier(net.solarnetwork.settings.support.BasicTitleSettingSpecifier) BasicGroupSettingSpecifier(net.solarnetwork.settings.support.BasicGroupSettingSpecifier) BasicTextFieldSettingSpecifier(net.solarnetwork.settings.support.BasicTextFieldSettingSpecifier) BasicTextFieldSettingSpecifier(net.solarnetwork.settings.support.BasicTextFieldSettingSpecifier) BasicTitleSettingSpecifier(net.solarnetwork.settings.support.BasicTitleSettingSpecifier)

Example 3 with MeasurementConfig

use of net.solarnetwork.node.io.dnp3.domain.MeasurementConfig in project solarnetwork-node by SolarNetwork.

the class OutstationService method createOutstationStackConfig.

private OutstationStackConfig createOutstationStackConfig() {
    Map<MeasurementType, List<MeasurementConfig>> configs = measurementTypeMap(getMeasurementConfigs());
    Map<ControlType, List<ControlConfig>> controlConfigs = controlTypeMap(getControlConfigs());
    OutstationStackConfig config = new OutstationStackConfig(createDatabaseConfig(configs, controlConfigs), createEventBufferConfig(configs, controlConfigs));
    copySettings(getLinkLayerConfig(), config.linkConfig);
    copySettings(getOutstationConfig(), config.outstationConfig);
    return config;
}
Also used : MeasurementType(net.solarnetwork.node.io.dnp3.domain.MeasurementType) OutstationStackConfig(com.automatak.dnp3.OutstationStackConfig) List(java.util.List) ArrayList(java.util.ArrayList) ControlType(net.solarnetwork.node.io.dnp3.domain.ControlType)

Example 4 with MeasurementConfig

use of net.solarnetwork.node.io.dnp3.domain.MeasurementConfig in project solarnetwork-node by SolarNetwork.

the class OutstationService method createEventBufferConfig.

private EventBufferConfig createEventBufferConfig(Map<MeasurementType, List<MeasurementConfig>> configs, Map<ControlType, List<ControlConfig>> controlConfigs) {
    EventBufferConfig config = EventBufferConfig.allTypes(0);
    final int size = getEventBufferSize();
    if (configs != null) {
        for (Map.Entry<MeasurementType, List<MeasurementConfig>> me : configs.entrySet()) {
            MeasurementType type = me.getKey();
            List<MeasurementConfig> list = me.getValue();
            if (type == null || list == null || list.isEmpty()) {
                continue;
            }
            switch(type) {
                case AnalogInput:
                    config.maxAnalogEvents = size;
                    break;
                case AnalogOutputStatus:
                    config.maxAnalogOutputStatusEvents = size;
                    break;
                case BinaryInput:
                    config.maxBinaryEvents = size;
                    break;
                case BinaryOutputStatus:
                    config.maxBinaryOutputStatusEvents = size;
                    break;
                case Counter:
                    config.maxCounterEvents = size;
                    break;
                case DoubleBitBinaryInput:
                    config.maxDoubleBinaryEvents = size;
                    break;
                case FrozenCounter:
                    config.maxFrozenCounterEvents = size;
                    break;
            }
        }
    }
    if (controlConfigs != null) {
        for (Map.Entry<ControlType, List<ControlConfig>> me : controlConfigs.entrySet()) {
            ControlType type = me.getKey();
            List<ControlConfig> list = me.getValue();
            if (type == null || list == null || list.isEmpty()) {
                continue;
            }
            switch(type) {
                case Analog:
                    config.maxAnalogOutputStatusEvents = size;
                    break;
                case Binary:
                    config.maxBinaryOutputStatusEvents = size;
                    break;
            }
        }
    }
    return config;
}
Also used : EventBufferConfig(com.automatak.dnp3.EventBufferConfig) MeasurementConfig(net.solarnetwork.node.io.dnp3.domain.MeasurementConfig) ControlConfig(net.solarnetwork.node.io.dnp3.domain.ControlConfig) MeasurementType(net.solarnetwork.node.io.dnp3.domain.MeasurementType) List(java.util.List) ArrayList(java.util.ArrayList) ControlType(net.solarnetwork.node.io.dnp3.domain.ControlType) Map(java.util.Map) LinkedHashMap(java.util.LinkedHashMap)

Example 5 with MeasurementConfig

use of net.solarnetwork.node.io.dnp3.domain.MeasurementConfig in project solarnetwork-node by SolarNetwork.

the class OutstationService method appendMeasurementInfos.

private void appendMeasurementInfos(StringBuilder buf, MeasurementType type, List<MeasurementConfig> list) {
    buf.append(type.getTitle()).append(" (").append(list != null ? list.size() : 0).append(")\n");
    if (list != null) {
        int i = 0;
        for (MeasurementConfig conf : list) {
            buf.append(String.format("  %3d: %s\n", i, conf.getSourceId()));
            i++;
        }
    }
}
Also used : MeasurementConfig(net.solarnetwork.node.io.dnp3.domain.MeasurementConfig)

Aggregations

ArrayList (java.util.ArrayList)5 MeasurementConfig (net.solarnetwork.node.io.dnp3.domain.MeasurementConfig)5 List (java.util.List)4 ControlConfig (net.solarnetwork.node.io.dnp3.domain.ControlConfig)4 ControlType (net.solarnetwork.node.io.dnp3.domain.ControlType)4 MeasurementType (net.solarnetwork.node.io.dnp3.domain.MeasurementType)4 LinkedHashMap (java.util.LinkedHashMap)3 Map (java.util.Map)3 AnalogInput (com.automatak.dnp3.AnalogInput)1 AnalogOutputStatus (com.automatak.dnp3.AnalogOutputStatus)1 BinaryInput (com.automatak.dnp3.BinaryInput)1 BinaryOutputStatus (com.automatak.dnp3.BinaryOutputStatus)1 Counter (com.automatak.dnp3.Counter)1 DatabaseConfig (com.automatak.dnp3.DatabaseConfig)1 DoubleBitBinaryInput (com.automatak.dnp3.DoubleBitBinaryInput)1 EventBufferConfig (com.automatak.dnp3.EventBufferConfig)1 FrozenCounter (com.automatak.dnp3.FrozenCounter)1 OutstationChangeSet (com.automatak.dnp3.OutstationChangeSet)1 OutstationStackConfig (com.automatak.dnp3.OutstationStackConfig)1 BigDecimal (java.math.BigDecimal)1