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;
}
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;
}
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;
}
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;
}
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++;
}
}
}
Aggregations