use of me.retrodaredevil.solarthing.actions.environment.LatestPacketGroupEnvironment in project solarthing by wildmountainfarms.
the class PacketHandlerInit method initHandlers.
public static <T extends PacketHandlingOption & CommandOption> Result initHandlers(T options, Supplier<? extends EnvironmentUpdater> environmentUpdaterSupplier, Collection<? extends PacketHandler> additionalPacketHandlers) throws IOException {
List<DatabaseConfig> databaseConfigs = ConfigUtil.getDatabaseConfigs(options);
PacketHandlerBundle packetHandlerBundle = PacketHandlerInit.getPacketHandlerBundle(databaseConfigs, SolarThingConstants.STATUS_DATABASE, SolarThingConstants.EVENT_DATABASE, options.getSourceId(), options.getFragmentId());
List<PacketHandler> statusPacketHandlers = new ArrayList<>();
final Runnable updateCommandActions;
if (options.hasCommands()) {
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Command are enabled!");
// this is used to determine the state of the system when a command is requested
LatestPacketHandler latestPacketHandler = new LatestPacketHandler();
statusPacketHandlers.add(latestPacketHandler);
Map<String, ActionNode> actionNodeMap = ActionUtil.getActionNodeMap(CONFIG_MAPPER, options);
ActionNodeDataReceiver commandReceiver = new ActionNodeDataReceiver(actionNodeMap, (source, injectEnvironmentBuilder) -> {
injectEnvironmentBuilder.add(new NanoTimeProviderEnvironment(NanoTimeProvider.SYSTEM_NANO_TIME)).add(new TimeZoneEnvironment(options.getZoneId())).add(new LatestPacketGroupEnvironment(latestPacketHandler::getLatestPacketCollection)).add(new SourceEnvironment(source)).add(new EventReceiverEnvironment(PacketListReceiverHandlerBundle.createEventPacketListReceiverHandler(SolarMain.getSourceAndFragmentUpdater(options), options.getZoneId(), packetHandlerBundle)));
EnvironmentUpdater environmentUpdater = environmentUpdaterSupplier.get();
if (environmentUpdater == null) {
throw new NullPointerException("The EnvironmentUpdater supplier gave a null value! (Fatal)");
}
environmentUpdater.updateInjectEnvironment(source, injectEnvironmentBuilder);
});
PacketGroupReceiver mainPacketGroupReceiver = new PacketGroupReceiverMultiplexer(Arrays.asList(commandReceiver, new RequestHeartbeatReceiver(PacketListReceiverHandlerBundle.createEventPacketListReceiverHandler(SolarMain.getSourceAndFragmentUpdater(options), options.getZoneId(), packetHandlerBundle))));
statusPacketHandlers.add((packetCollection) -> commandReceiver.getActionUpdater().update());
List<PacketHandler> commandPacketHandlers = CommandUtil.getCommandRequesterHandlerList(databaseConfigs, mainPacketGroupReceiver, options);
statusPacketHandlers.add(new PacketHandlerMultiplexer(commandPacketHandlers));
updateCommandActions = () -> commandReceiver.getActionUpdater().update();
} else {
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Commands are disabled");
updateCommandActions = () -> {
};
}
statusPacketHandlers.addAll(additionalPacketHandlers);
statusPacketHandlers.addAll(packetHandlerBundle.getStatusPacketHandlers());
PacketListReceiverHandlerBundle bundle = PacketListReceiverHandlerBundle.createFrom(options, packetHandlerBundle, statusPacketHandlers);
return new Result(bundle, updateCommandActions);
}
use of me.retrodaredevil.solarthing.actions.environment.LatestPacketGroupEnvironment in project solarthing by wildmountainfarms.
the class ACModeActionNode method createAction.
@Override
public Action createAction(ActionEnvironment actionEnvironment) {
LatestPacketGroupEnvironment latestPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestPacketGroupEnvironment.class);
PacketGroupProvider packetGroupProvider = latestPacketGroupEnvironment.getPacketGroupProvider();
return new SimpleAction(false) {
@Override
protected void onUpdate() {
super.onUpdate();
PacketGroup packetGroup = packetGroupProvider.getPacketGroup();
if (packetGroup == null) {
LOGGER.warn("packetGroup is null!");
return;
}
FXStatusPacket fxStatusPacket = OutbackUtil.getMasterFX(packetGroup);
if (fxStatusPacket == null) {
LOGGER.warn("No master FX Status Packet!");
} else {
setDone((fxStatusPacket.getACMode() == acMode) == !not);
}
}
};
}
use of me.retrodaredevil.solarthing.actions.environment.LatestPacketGroupEnvironment in project solarthing by wildmountainfarms.
the class FXOperationalModeActionNode method createAction.
@Override
public Action createAction(ActionEnvironment actionEnvironment) {
LatestPacketGroupEnvironment latestPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestPacketGroupEnvironment.class);
PacketGroupProvider packetGroupProvider = latestPacketGroupEnvironment.getPacketGroupProvider();
return new SimpleAction(false) {
@Override
protected void onUpdate() {
super.onUpdate();
PacketGroup packetGroup = packetGroupProvider.getPacketGroup();
if (packetGroup == null) {
// packetGroup will only be null in the automation program if a query fails or something. This should never happen in the mate program
LOGGER.warn("packetGroup is null!");
return;
}
FXStatusPacket fxStatusPacket = OutbackUtil.getMasterFX(packetGroup);
if (fxStatusPacket == null) {
LOGGER.warn("No master FX Status Packet!");
} else {
setDone((fxStatusPacket.getOperationalMode() == operationalMode) == !not);
}
}
};
}
use of me.retrodaredevil.solarthing.actions.environment.LatestPacketGroupEnvironment in project solarthing by wildmountainfarms.
the class DeserializeTest method testRunAlertGeneratorOffWhileAuxOn.
@Test
void testRunAlertGeneratorOffWhileAuxOn() throws IOException, ParsePacketAsciiDecimalDigitException, CheckSumException {
File file = new File(ACTION_CONFIG_DIRECTORY, "alert_generator_off_while_aux_on.json");
ActionNode actionNode = MAPPER.readValue(file, ActionNode.class);
// We need to simulate an automation program environment to run this action
Duration[] timeReference = new Duration[] { Duration.ZERO };
FragmentedPacketGroup[] packetGroupReference = new FragmentedPacketGroup[] { null };
FragmentedPacketGroupProvider fragmentedPacketGroupProvider = () -> requireNonNull(packetGroupReference[0]);
InjectEnvironment injectEnvironment = new InjectEnvironment.Builder().add(new NanoTimeProviderEnvironment(() -> timeReference[0].toNanos())).add(new LatestPacketGroupEnvironment(fragmentedPacketGroupProvider)).add(new LatestFragmentedPacketGroupEnvironment(fragmentedPacketGroupProvider)).build();
FXStatusPacket auxOnNoAC = FXStatusPackets.createFromChars("\n1,00,00,02,123,123,00,10,000,00,252,136,000,999\r".toCharArray(), IgnoreCheckSum.IGNORE);
FXStatusPacket auxOffNoAC = FXStatusPackets.createFromChars("\n1,00,00,02,123,123,00,10,000,00,252,008,000,999\r".toCharArray(), IgnoreCheckSum.IGNORE);
FXStatusPacket auxOnACUse = FXStatusPackets.createFromChars("\n1,00,00,02,123,123,00,10,000,02,252,136,000,999\r".toCharArray(), IgnoreCheckSum.IGNORE);
FXStatusPacket auxOffACUse = FXStatusPackets.createFromChars("\n1,00,00,02,123,123,00,10,000,02,252,008,000,999\r".toCharArray(), IgnoreCheckSum.IGNORE);
for (FXStatusPacket packet : new FXStatusPacket[] { auxOffNoAC, auxOnACUse, auxOffACUse }) {
// for these three cases, the action should end immediately
packetGroupReference[0] = PacketGroups.createInstancePacketGroup(Collections.singleton(packet), 0L, "my_source_id", 999);
Action action = actionNode.createAction(new ActionEnvironment(new VariableEnvironment(), new VariableEnvironment(), injectEnvironment));
action.update();
assertTrue(action.isDone());
}
{
// Test that no alert is sent unless the aux is on, and it's in No AC for 30 seconds
packetGroupReference[0] = PacketGroups.createInstancePacketGroup(Collections.singleton(auxOnNoAC), 0L, "my_source_id", 999);
Action action = actionNode.createAction(new ActionEnvironment(new VariableEnvironment(), new VariableEnvironment(), injectEnvironment));
action.update();
assertFalse(action.isDone());
timeReference[0] = timeReference[0].plus(Duration.ofSeconds(29));
action.update();
assertFalse(action.isDone());
packetGroupReference[0] = PacketGroups.createInstancePacketGroup(Collections.singleton(auxOnACUse), 0L, "my_source_id", 999);
action.update();
// No alert has been sent, since it started to AC Use before the 30 second period completed.
assertTrue(action.isDone());
}
{
// Test that the alert gets sent and the action doesn't end until the 300-second timeout completes
packetGroupReference[0] = PacketGroups.createInstancePacketGroup(Collections.singleton(auxOnNoAC), 0L, "my_source_id", 999);
Action action = actionNode.createAction(new ActionEnvironment(new VariableEnvironment(), new VariableEnvironment(), injectEnvironment));
action.update();
assertFalse(action.isDone());
timeReference[0] = timeReference[0].plus(Duration.ofSeconds(30));
action.update();
assertFalse(action.isDone());
packetGroupReference[0] = PacketGroups.createInstancePacketGroup(Collections.singleton(auxOnACUse), 0L, "my_source_id", 999);
action.update();
// Alert has been sent, so the action isn't going to end
assertFalse(action.isDone());
timeReference[0] = timeReference[0].plus(Duration.ofSeconds(299));
action.update();
assertFalse(action.isDone());
timeReference[0] = timeReference[0].plus(Duration.ofSeconds(1));
action.update();
// the 300-second timeout has completed, so the action will end
assertTrue(action.isDone());
}
}
use of me.retrodaredevil.solarthing.actions.environment.LatestPacketGroupEnvironment in project solarthing by wildmountainfarms.
the class AuxStateActionNode method createAction.
@Override
public Action createAction(ActionEnvironment actionEnvironment) {
LatestPacketGroupEnvironment latestPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestPacketGroupEnvironment.class);
PacketGroupProvider packetGroupProvider = latestPacketGroupEnvironment.getPacketGroupProvider();
return new SimpleAction(false) {
/**
* A simple variable to prevent spamming of the log file
*/
private boolean hadFX = true;
@Override
protected void onUpdate() {
super.onUpdate();
PacketGroup packetGroup = packetGroupProvider.getPacketGroup();
if (packetGroup == null) {
LOGGER.warn("packetGroup is null!");
return;
}
FXStatusPacket fxStatusPacket = OutbackUtil.getMasterFX(packetGroup);
if (fxStatusPacket == null) {
if (hadFX) {
LOGGER.warn("No master FX Status Packet!");
}
hadFX = false;
} else {
setDone(fxStatusPacket.isAuxOn() == on);
if (!hadFX) {
LOGGER.info("We now have a master FX Status Packet");
}
hadFX = true;
}
}
};
}
Aggregations