use of me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket in project solarthing by wildmountainfarms.
the class MateAnalyticsHandler method send.
private void send(PacketCollection packetCollection) {
int fxCount = 0;
List<Integer> fxOperationalModes = new ArrayList<>();
int mxfmCount = 0;
int fmCount = 0;
Boolean isOldFirmware = null;
for (Packet packet : packetCollection.getPackets()) {
if (packet instanceof FXStatusPacket) {
fxCount++;
FXStatusPacket fx = (FXStatusPacket) packet;
fxOperationalModes.add(fx.getOperationalModeValue());
} else if (packet instanceof MXStatusPacket) {
mxfmCount++;
MXStatusPacket mx = (MXStatusPacket) packet;
if (Boolean.TRUE.equals(mx.isFlexMax())) {
fmCount++;
}
Boolean oldMate = mx.isOldMateFirmware();
if (Boolean.TRUE.equals(oldMate)) {
isOldFirmware = true;
} else if (Boolean.FALSE.equals(oldMate)) {
isOldFirmware = false;
}
}
}
String data = "";
if (fxCount > 0) {
data += "fx=" + fxCount + ",fx_op=" + fxOperationalModes + ",";
}
if (mxfmCount > 0) {
data += "mxfm=" + mxfmCount + ",";
}
if (fmCount > 0) {
data += "fm=" + fmCount + ",";
}
if (isOldFirmware != null) {
if (isOldFirmware) {
data += "old_mate,";
} else {
data += "new_mate,";
}
}
if (!data.isEmpty()) {
// remove comma
data = data.substring(0, data.length() - 1);
}
analyticsManager.sendMateStatus(data, timer.getUptimeHours());
}
use of me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket in project solarthing by wildmountainfarms.
the class RequireFullOutputActionNode method isFullOutput.
private boolean isFullOutput(FragmentedPacketGroup latestPacketGroup) {
for (Map.Entry<Integer, List<String>> entry : requiredIdentifierMap.entrySet()) {
int desiredFragmentId = entry.getKey();
if (!latestPacketGroup.hasFragmentId(desiredFragmentId)) {
continue;
}
for (String desiredIdentifierRepresentation : entry.getValue()) {
for (Packet packet : latestPacketGroup.getPackets()) {
int fragmentId = latestPacketGroup.getFragmentId(packet);
if (fragmentId != desiredFragmentId) {
continue;
}
if (packet instanceof Identifiable) {
Identifier identifier = ((Identifiable) packet).getIdentifier();
if (desiredIdentifierRepresentation.equals(identifier.getRepresentation())) {
if (packet instanceof MXStatusPacket) {
MXStatusPacket mx = (MXStatusPacket) packet;
ChargerMode mode = mx.getChargingMode();
// Some old MX firmwares consistently report being in float mode after a full absorb cycle even after the daily reset.
// This configuration option allows us to treat float as full output for a given MX
boolean canIgnoreFloatMode = ignoreReportedMXFloatMap.getOrDefault(fragmentId, Collections.emptyList()).contains(desiredIdentifierRepresentation);
if (mode != ChargerMode.SILENT && mode != ChargerMode.BULK && (!canIgnoreFloatMode || mode != ChargerMode.FLOAT)) {
if (log) {
LOGGER.info(identifier.getRepresentation() + " on fragment " + fragmentId + " is in mode " + mode.getModeName());
}
return false;
}
} else if (packet instanceof RoverStatusPacket) {
RoverStatusPacket rover = (RoverStatusPacket) packet;
ChargingState state = rover.getChargingMode();
if (state != ChargingState.ACTIVATED && state != ChargingState.DEACTIVATED && state != ChargingState.MPPT) {
if (log) {
LOGGER.info(identifier.getRepresentation() + " on fragment " + fragmentId + " is in mode " + state.getModeName());
}
return false;
}
} else if (packet instanceof TracerStatusPacket) {
TracerStatusPacket tracer = (TracerStatusPacket) packet;
ChargingStatus status = tracer.getChargingMode();
// we currently cannot tell if while in BOOST or EQUALIZE if the controller is actually in Bulk, so float is the only mode we know that isn't at full output
if (status == ChargingStatus.FLOAT) {
if (log) {
LOGGER.info(identifier.getRepresentation() + " on fragment " + fragmentId + " is in mode " + status.getModeName());
}
return false;
}
}
}
}
}
}
}
return true;
}
use of me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket in project solarthing by wildmountainfarms.
the class MXFloatModeStuckEvent method run.
@Override
public void run(MessageSender sender, FragmentedPacketGroup previous, FragmentedPacketGroup current) {
for (Packet previousPacket : previous.getPackets()) {
if (previousPacket instanceof MXStatusPacket) {
MXStatusPacket previousMX = (MXStatusPacket) previousPacket;
KnownIdentifierFragment<OutbackIdentifier> identifierFragment = IdentifierFragment.create(previous.getFragmentId(previousPacket), previousMX.getIdentifier());
MXStatusPacket currentMX = null;
for (Packet currentPacket : current.getPackets()) {
if (currentPacket instanceof Identifiable) {
IdentifierFragment currentIdentifierFragment = IdentifierFragment.create(current.getFragmentId(currentPacket), ((Identifiable) currentPacket).getIdentifier());
if (identifierFragment.equals(currentIdentifierFragment)) {
currentMX = (MXStatusPacket) currentPacket;
}
}
}
if (currentMX == null) {
continue;
}
if (currentMX.isNewDay(previousMX)) {
enabledMap.put(identifierFragment, true);
}
if (enabledMap.getOrDefault(identifierFragment, false)) {
ChargerMode mode = currentMX.getChargingMode();
if (mode == ChargerMode.FLOAT) {
doAlert(sender, identifierFragment);
} else if (mode != ChargerMode.SILENT) {
enabledMap.put(identifierFragment, false);
LOGGER.debug("Disabling " + identifierFragment + " because mode is " + mode);
}
}
}
}
}
use of me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket in project solarthing by wildmountainfarms.
the class PowerUtil method getPowerData.
public static Data getPowerData(PacketGroup packetGroup, GeneratingType generatingType) {
requireNonNull(packetGroup);
requireNonNull(generatingType);
Integer generatingW = null;
Integer usingW = null;
for (Packet packet : packetGroup.getPackets()) {
if (packet instanceof MXStatusPacket) {
if (generatingW == null) {
generatingW = 0;
}
if (generatingType == GeneratingType.PV_ONLY) {
generatingW += ((MXStatusPacket) packet).getPVWattage();
} else if (generatingType == GeneratingType.TOTAL_CHARGING) {
generatingW += ((MXStatusPacket) packet).getChargingPower().intValue();
} else
throw new AssertionError("Unknown generatingType: " + generatingType);
} else if (packet instanceof FXStatusPacket) {
if (usingW == null) {
usingW = 0;
}
usingW += ((FXStatusPacket) packet).getPowerUsageWattage();
} else if (packet instanceof RoverStatusPacket) {
if (generatingW == null) {
generatingW = 0;
}
if (usingW == null) {
usingW = 0;
}
if (generatingType == GeneratingType.PV_ONLY) {
generatingW += ((RoverStatusPacket) packet).getPVWattage().intValue();
} else if (generatingType == GeneratingType.TOTAL_CHARGING) {
generatingW += ((RoverStatusPacket) packet).getChargingPower();
} else
throw new AssertionError("Unknown generatingType: " + generatingType);
usingW += ((RoverStatusPacket) packet).getLoadPower();
} else if (packet instanceof TracerStatusPacket) {
if (generatingW == null) {
generatingW = 0;
}
if (usingW == null) {
usingW = 0;
}
if (generatingType == GeneratingType.PV_ONLY) {
generatingW += ((TracerStatusPacket) packet).getPVWattage().intValue();
} else if (generatingType == GeneratingType.TOTAL_CHARGING) {
generatingW += ((TracerStatusPacket) packet).getChargingPower().intValue();
} else
throw new AssertionError("Unknown generatingType: " + generatingType);
usingW += (int) ((TracerStatusPacket) packet).getLoadPower();
}
}
return new Data(generatingW, usingW);
}
use of me.retrodaredevil.solarthing.solar.outback.mx.MXStatusPacket in project solarthing by wildmountainfarms.
the class OutbackPacketsTest method testExistingPackets.
@Test
void testExistingPackets() throws IOException {
assertTrue(DIRECTORY_FX.isDirectory());
assertTrue(DIRECTORY_MX.isDirectory());
ObjectMapper mapper = JacksonUtil.defaultMapper();
for (File file : requireNonNull(DIRECTORY_FX.listFiles())) {
SolarStatusPacket packet = mapper.readValue(file, SolarStatusPacket.class);
assertTrue(packet instanceof FXStatusPacket);
}
for (File file : requireNonNull(DIRECTORY_MX.listFiles())) {
SolarStatusPacket packet = mapper.readValue(file, SolarStatusPacket.class);
assertTrue(packet instanceof MXStatusPacket);
}
}
Aggregations