Skip to content

Commit

Permalink
Update io.openems.edge.battery.fenecon
Browse files Browse the repository at this point in the history
  • Loading branch information
sfeilmeier committed Jan 8, 2022
1 parent 03ca4d3 commit d2eda2a
Show file tree
Hide file tree
Showing 9 changed files with 76 additions and 73 deletions.
Original file line number Diff line number Diff line change
Expand Up @@ -19,7 +19,7 @@ public interface FeneconHomeBattery extends Battery, OpenemsComponent, StartStop

/**
* Gets the Channel for {@link ChannelId#BMS_CONTROL}.
*
*
* @return the Channel
*/
public default Channel<BmsControl> getBmsControlChannel() {
Expand All @@ -28,7 +28,7 @@ public default Channel<BmsControl> getBmsControlChannel() {

/**
* Gets the BmsControl, see {@link ChannelId#BMS_CONTROL}.
*
*
* @return the Channel {@link Value}
*/
public default BmsControl getBmsControl() {
Expand All @@ -38,7 +38,7 @@ public default BmsControl getBmsControl() {
/**
* Internal method to set the 'nextValue' on {@link ChannelId#BMS_CONTROL}
* Channel.
*
*
* @param value the next value
*/
public default void _setBmsControl(BmsControl value) {
Expand All @@ -47,7 +47,7 @@ public default void _setBmsControl(BmsControl value) {

/**
* Gets the target Start/Stop mode from config or StartStop-Channel.
*
*
* @return {@link StartStop}
*/
public StartStop getStartStopTarget();
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -47,7 +47,6 @@
import io.openems.edge.common.channel.BooleanWriteChannel;
import io.openems.edge.common.channel.Channel;
import io.openems.edge.common.channel.Doc;
import io.openems.edge.common.channel.value.Value;
import io.openems.edge.common.component.ComponentManager;
import io.openems.edge.common.component.OpenemsComponent;
import io.openems.edge.common.event.EdgeEventConstants;
Expand Down Expand Up @@ -90,7 +89,7 @@ public class FeneconHomeBatteryImpl extends AbstractOpenemsModbusComponent imple
*/
private final StateMachine stateMachine = new StateMachine(State.UNDEFINED);

private final AtomicReference<StartStop> startStopTarget = new AtomicReference<StartStop>(StartStop.UNDEFINED);
private final AtomicReference<StartStop> startStopTarget = new AtomicReference<>(StartStop.UNDEFINED);

private Config config;
private BatteryProtection batteryProtection = null;
Expand All @@ -106,6 +105,7 @@ public FeneconHomeBatteryImpl() {
);
}

@Override
@Reference(policy = ReferencePolicy.STATIC, policyOption = ReferencePolicyOption.GREEDY, cardinality = ReferenceCardinality.MANDATORY)
protected void setModbus(BridgeModbus modbus) {
super.setModbus(modbus);
Expand Down Expand Up @@ -158,7 +158,7 @@ private void handleStateMachine() {
} catch (IllegalArgumentException | OpenemsNamedException e1) {
batteryStartUpRelayChannel = null;
}
Context context = new Context(this, batteryStartUpRelayChannel);
var context = new Context(this, batteryStartUpRelayChannel);

// Call the StateMachine
try {
Expand Down Expand Up @@ -326,10 +326,10 @@ protected ModbusProtocol defineModbusProtocol() throws OpenemsException {

/**
* Generates prefix for Channel-IDs for Cell Temperature and Voltage channels.
*
*
* <p>
* "%03d" creates string number with leading zeros
*
*
* @param num number of the Cell
* @param module number of the Module
* @param tower number of the Tower
Expand All @@ -341,28 +341,28 @@ private static String getSingleCellPrefix(int tower, int module, int num) {

/**
* Generates a Channel-ID for channels that are specific to a tower.
*
*
* @param tower number of the Tower
* @param channelIdSuffix e.g. "STATUS_ALARM"
* @param openemsType specified type e.g. "INTEGER"
* @return a channel with Channel-ID "TOWER_1_STATUS_ALARM"
*/
private ChannelIdImpl generateTowerChannel(int tower, String channelIdSuffix, OpenemsType openemsType) {
ChannelIdImpl channelId = new ChannelIdImpl("TOWER_" + tower + "_" + channelIdSuffix, Doc.of(openemsType));
var channelId = new ChannelIdImpl("TOWER_" + tower + "_" + channelIdSuffix, Doc.of(openemsType));
this.addChannel(channelId);
return channelId;
}

/**
* Generates a Channel-ID for channels that are specific to a tower.
*
*
* @param tower number of the Tower
* @param channelIdSuffix e.g. "STATUS_ALARM"
* @param level specified level e.g. "INFO"
* @return a channel with Channel-ID "TOWER_1_STATUS_ALARM"
*/
private ChannelIdImpl generateTowerChannel(int tower, String channelIdSuffix, Level level) {
ChannelIdImpl channelId = new ChannelIdImpl("TOWER_" + tower + "_" + channelIdSuffix, Doc.of(level));
var channelId = new ChannelIdImpl("TOWER_" + tower + "_" + channelIdSuffix, Doc.of(level));
this.addChannel(channelId);
return channelId;
}
Expand Down Expand Up @@ -415,7 +415,7 @@ public StartStop getStartStopTarget() {
* Unfortunately the battery may report too small wrong values in the beginning,
* so we need to recalculate on every change.
*/
protected final static Consumer<Channel<Integer>> UPDATE_NUMBER_OF_TOWERS_AND_MODULES_CALLBACK = channel -> {
protected static final Consumer<Channel<Integer>> UPDATE_NUMBER_OF_TOWERS_AND_MODULES_CALLBACK = channel -> {
channel.onChange((ignore, value) -> {
((FeneconHomeBatteryImpl) channel.getComponent()).updateNumberOfTowersAndModules();
});
Expand All @@ -428,13 +428,13 @@ public StartStop getStartStopTarget() {
private synchronized void updateNumberOfTowersAndModules() {
Channel<Integer> numberOfModulesPerTowerChannel = this
.channel(FeneconHomeBattery.ChannelId.NUMBER_OF_MODULES_PER_TOWER);
Value<Integer> numberOfModulesPerTowerOpt = numberOfModulesPerTowerChannel.value();
var numberOfModulesPerTowerOpt = numberOfModulesPerTowerChannel.value();
Channel<Integer> tower2BmsSoftwareVersionChannel = this
.channel(FeneconHomeBattery.ChannelId.TOWER_1_BMS_SOFTWARE_VERSION);
Value<Integer> tower2BmsSoftwareVersion = tower2BmsSoftwareVersionChannel.value();
var tower2BmsSoftwareVersion = tower2BmsSoftwareVersionChannel.value();
Channel<Integer> tower3BmsSoftwareVersionChannel = this
.channel(FeneconHomeBattery.ChannelId.TOWER_2_BMS_SOFTWARE_VERSION);
Value<Integer> tower3BmsSoftwareVersion = tower3BmsSoftwareVersionChannel.value();
var tower3BmsSoftwareVersion = tower3BmsSoftwareVersionChannel.value();

// Were all required registers read?
if (!numberOfModulesPerTowerOpt.isDefined() || !tower3BmsSoftwareVersion.isDefined()
Expand Down Expand Up @@ -477,19 +477,19 @@ private synchronized void updateNumberOfTowersAndModules() {

/**
* Initialize channels per towers and modules.
*
*
* @param numberOfTowers the number of towers
* @param numberOfModulesPerTower the number of modulers per tower
* @throws OpenemsException on error
*/
private synchronized void initializeTowerModulesChannels(int numberOfTowers, int numberOfModulesPerTower)
throws OpenemsException {
try {
for (int tower = this.lastNumberOfTowers; tower < numberOfTowers; tower++) {
for (var tower = this.lastNumberOfTowers; tower < numberOfTowers; tower++) {
/*
* Number Of Towers increased
*/
final int towerOffset = tower * 2000 + 10000;
final var towerOffset = tower * 2000 + 10000;
this.getModbusProtocol().addTasks(//
new FC3ReadRegistersTask(towerOffset + 1, Priority.HIGH, //
m(this.generateTowerChannel(tower, "BMS_HARDWARE_VERSION", OpenemsType.INTEGER),
Expand Down Expand Up @@ -700,50 +700,50 @@ private synchronized void initializeTowerModulesChannels(int numberOfTowers, int
new UnsignedDoublewordElement(towerOffset + 49)),
m(this.generateTowerChannel(tower, "BMS_SERIAL_NUMBER", OpenemsType.STRING),
new UnsignedDoublewordElement(towerOffset + 51),
new ElementToChannelConverter((value) -> {
new ElementToChannelConverter(value -> {
Integer intValue = TypeUtils.getAsType(OpenemsType.INTEGER, value);
return buildSerialNumber(SERIAL_NUMBER_PREFIX_BMS, intValue);
}))));
}

int towerToUse = 0;
int moduleToUse = this.lastNumberOfModulesPerTower;
var towerToUse = 0;
var moduleToUse = this.lastNumberOfModulesPerTower;
if (this.lastNumberOfTowers < numberOfTowers) {
towerToUse = this.lastNumberOfTowers;
moduleToUse = 0;
}

for (int tower = towerToUse; tower < numberOfTowers; tower++) {
final int towerOffset = tower * 2000 + 10000;
final int moduleOffset = towerOffset + 100;
for (var tower = towerToUse; tower < numberOfTowers; tower++) {
final var towerOffset = tower * 2000 + 10000;
final var moduleOffset = towerOffset + 100;

for (int module = moduleToUse; module < numberOfModulesPerTower; module++) {
for (var module = moduleToUse; module < numberOfModulesPerTower; module++) {
/*
* Number Of Modules per Tower increased.
*
*
* Dynamically generate Channels and Modbus mappings for Cell-Temperatures and
* for Cell-Voltages.Channel-IDs are like "TOWER_0_OFFSET_2_TEMPERATURE_003".
* Channel-IDs are like "TOWER_0_OFFSET_2_VOLTAGE_003".
*/
AbstractModbusElement<?>[] ameVolt = new AbstractModbusElement<?>[SENSORS_PER_MODULE];
AbstractModbusElement<?>[] ameTemp = new AbstractModbusElement<?>[SENSORS_PER_MODULE];
for (int j = 0; j < SENSORS_PER_MODULE; j++) {
var ameVolt = new AbstractModbusElement<?>[SENSORS_PER_MODULE];
var ameTemp = new AbstractModbusElement<?>[SENSORS_PER_MODULE];
for (var j = 0; j < SENSORS_PER_MODULE; j++) {
{
// Create Voltage Channel
ChannelIdImpl channelId = new ChannelIdImpl(//
var channelId = new ChannelIdImpl(//
getSingleCellPrefix(tower, module, j) + "_VOLTAGE",
Doc.of(OpenemsType.INTEGER).unit(Unit.VOLT));
this.addChannel(channelId);

// Create Modbus-Mapping for Voltages
UnsignedWordElement uwe = new UnsignedWordElement(moduleOffset + module * 100 + 2 + j);
var uwe = new UnsignedWordElement(moduleOffset + module * 100 + 2 + j);
ameVolt[j] = m(channelId, uwe);
}
{
// TODO only 8 temperatures

// Create Temperature Channel
ChannelIdImpl channelId = new ChannelIdImpl(//
var channelId = new ChannelIdImpl(//
getSingleCellPrefix(tower, module, j) + "_TEMPERATURE",
Doc.of(OpenemsType.INTEGER).unit(Unit.DEZIDEGREE_CELSIUS));
this.addChannel(channelId);
Expand All @@ -752,12 +752,12 @@ private synchronized void initializeTowerModulesChannels(int numberOfTowers, int
// Cell Temperatures Read Registers for Tower_1 starts from 10000, for Tower_2
// 12000, for Tower_3 14000
// (t-1)*2000+10000) calculates Tower Offset value
SignedWordElement uwe = new SignedWordElement(moduleOffset + module * 100 + 18 + j);
var uwe = new SignedWordElement(moduleOffset + module * 100 + 18 + j);
ameTemp[j] = m(channelId, uwe);
}
}

ChannelIdImpl channelId = new ChannelIdImpl(//
var channelId = new ChannelIdImpl(//
"TOWER_" + tower + "_MODULE_" + module + "_SERIAL_NUMBER", //
Doc.of(OpenemsType.STRING));
this.addChannel(channelId);
Expand All @@ -767,7 +767,7 @@ private synchronized void initializeTowerModulesChannels(int numberOfTowers, int
new FC3ReadRegistersTask(moduleOffset + module * 100 + 18, Priority.LOW, ameTemp),
new FC3ReadRegistersTask(moduleOffset + module * 100 + 83, Priority.LOW,
m(channelId, new UnsignedDoublewordElement(moduleOffset + module * 100 + 83),
new ElementToChannelConverter((value) -> {
new ElementToChannelConverter(value -> {
Integer intValue = TypeUtils.getAsType(OpenemsType.INTEGER, value);
return buildSerialNumber(SERIAL_NUMBER_PREFIX_MODULE, intValue);
}))));
Expand All @@ -782,7 +782,7 @@ private synchronized void initializeTowerModulesChannels(int numberOfTowers, int

/**
* Build the serial number with prefix.
*
*
* @param prefix the serial number prefix
* @param value the serial number
* @return The serial number
Expand All @@ -793,21 +793,21 @@ protected static String buildSerialNumber(String prefix, Integer value) {
return null;
}

int year = extractNumber(value, 7, 26);
int month = extractNumber(value, 4, 22);
int day = extractNumber(value, 5, 17);
int number = extractNumber(value, 16, 1);
var year = extractNumber(value, 7, 26);
var month = extractNumber(value, 4, 22);
var day = extractNumber(value, 5, 17);
var number = extractNumber(value, 16, 1);

StringBuilder serialNumber = new StringBuilder();
var serialNumber = new StringBuilder();
serialNumber.append(prefix);
serialNumber.append(year < 10 ? "0" + year : year);
serialNumber.append(month < 10 ? "0" + month : month);
serialNumber.append(day < 10 ? "0" + day : day);

int digits = String.valueOf(number).length();
var digits = String.valueOf(number).length();
if (digits <= 6) {
String maxDigits = "000000";
String formattedNumber = maxDigits.substring(0, maxDigits.length() - digits) + number;
var maxDigits = "000000";
var formattedNumber = maxDigits.substring(0, maxDigits.length() - digits) + number;
serialNumber.append(formattedNumber);
} else {
serialNumber.append(number);
Expand All @@ -818,13 +818,13 @@ protected static String buildSerialNumber(String prefix, Integer value) {

/**
* Gets number from given value via bit shifting.
*
*
* @param value to get number from
* @param length of the number
* @param position to start extracting
* @return Number
*/
private static int extractNumber(int value, int length, int position) {
return ((1 << length) - 1) & (value >> (position - 1));
return (1 << length) - 1 & value >> position - 1;
}
}
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
public class Context extends AbstractContext<FeneconHomeBattery> {

/**
* The Battery-Start-Up-Relay Channel used to start the battery; possibly null
* The Battery-Start-Up-Relay Channel used to start the battery; possibly null.
*/
protected final BooleanWriteChannel batteryStartUpRelayChannel;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -48,6 +48,7 @@ public State runAndGetNextState(Context context) throws OpenemsNamedException {
} else {
this.state = BatteryRelayState.WAIT_FOR_BMS_CONTROL;
}
break;
}

case WAIT_FOR_SWITCH_OFF: {
Expand Down Expand Up @@ -77,9 +78,10 @@ private Boolean getBatteryStartUpRelay(Context context) {

/**
* Set Switch to OFF or Switch ON Operation.
*
* @param relayOperation true to switch the relay on; <br/>
* false to switch the relay off
*
* @param context the {@link Context}
* @param value true to switch the relay on; <br/>
* false to switch the relay off
* @throws OpenemsNamedException on error
*/
public void setBatteryStartUpRelay(Context context, boolean value) throws OpenemsNamedException {
Expand All @@ -88,6 +90,7 @@ public void setBatteryStartUpRelay(Context context, boolean value) throws Openem
context.logInfo(this.log,
"Because of the wrong/missed configured Battery Start Up Relay Channel Address, relay CAN NOT SWITCH ON.");
return;

} else {
context.logInfo(this.log,
"Set output [" + context.batteryStartUpRelayChannel.address() + "] SWITCHED ON.");
Expand All @@ -97,6 +100,7 @@ public void setBatteryStartUpRelay(Context context, boolean value) throws Openem
context.logInfo(this.log,
"Because of the wrong/missed configured Battery Start Up Relay Channel Address, relay CAN NOT SWITCH OFF.");
return;

} else {
context.logInfo(this.log,
"Set output [" + context.batteryStartUpRelayChannel.address() + "] SWITCHED OFF.");
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,14 @@
package io.openems.edge.battery.fenecon.home.statemachine;

import io.openems.edge.battery.fenecon.home.FeneconHomeBattery;
import io.openems.edge.battery.fenecon.home.statemachine.StateMachine.State;
import io.openems.edge.common.startstop.StartStop;
import io.openems.edge.common.statemachine.StateHandler;

public class RunningHandler extends StateHandler<State, Context> {

@Override
public State runAndGetNextState(Context context) {
FeneconHomeBattery battery = context.getParent();
var battery = context.getParent();

if (battery.hasFaults()) {
return State.UNDEFINED;
Expand Down
Original file line number Diff line number Diff line change
@@ -1,14 +1,13 @@
package io.openems.edge.battery.fenecon.home.statemachine;

import io.openems.edge.battery.fenecon.home.FeneconHomeBattery;
import io.openems.edge.battery.fenecon.home.statemachine.StateMachine.State;
import io.openems.edge.common.statemachine.StateHandler;

public class UndefinedHandler extends StateHandler<State, Context> {

@Override
public State runAndGetNextState(Context context) {
FeneconHomeBattery battery = context.getParent();
var battery = context.getParent();

switch (battery.getStartStopTarget()) {
case UNDEFINED:
Expand Down
Loading

0 comments on commit d2eda2a

Please sign in to comment.