use of me.retrodaredevil.solarthing.type.alter.packets.FlagPacket in project solarthing by wildmountainfarms.
the class AlterManagerAction method onUpdate.
@Override
protected void onUpdate() {
super.onUpdate();
// Supply queried solarthing_open packets to the security packet receiver, which may execute code to put commands requested to be scheduled in solarthing_alter
List<StoredPacketGroup> packets = openDatabaseCache.getAllCachedPackets();
securityPacketReceiver.receivePacketGroups(packets);
// Check packets in solarthing_alter and see if we need to send a command because of a scheduled command packet
Instant now = Instant.now();
List<VersionedPacket<StoredAlterPacket>> alterPackets = alterPacketsProvider.getPackets();
if (alterPackets == null) {
LOGGER.info("alterPackets is null. Maybe query failed? Maybe additional info in previous logs?");
} else {
for (VersionedPacket<StoredAlterPacket> versionedPacket : alterPackets) {
AlterPacket packet = versionedPacket.getPacket().getPacket();
if (packet instanceof ScheduledCommandPacket) {
ScheduledCommandPacket scheduledCommandPacket = (ScheduledCommandPacket) packet;
ScheduledCommandData data = scheduledCommandPacket.getData();
if (data.getScheduledTimeMillis() <= now.toEpochMilli()) {
if (now.toEpochMilli() - data.getScheduledTimeMillis() > Duration.ofMinutes(5).toMillis()) {
LOGGER.warn("Not going to send a command scheduled for more than 5 minutes ago! data: " + data);
} else {
doSendCommand(versionedPacket, scheduledCommandPacket);
}
}
} else if (packet instanceof FlagPacket) {
FlagPacket flagPacket = (FlagPacket) packet;
FlagData data = flagPacket.getFlagData();
ActivePeriod activePeriod = data.getActivePeriod();
if (activePeriod instanceof TimeRangeActivePeriod) {
// We only try to "manage" flags that use this type of ActivePeriod
TimeRangeActivePeriod period = (TimeRangeActivePeriod) activePeriod;
TimeRange timeRange = period.getTimeRange();
Instant endTime = timeRange.getEndTime();
if (endTime != null && endTime.compareTo(now) < 0) {
// If there is an end time, and it is in the past, then we should remove the flag
executorService.execute(() -> {
try {
database.getAlterDatabase().delete(versionedPacket);
} catch (SolarThingDatabaseException e) {
LOGGER.error("Could not delete a FlagPacket with an expired time", e);
// If we cannot delete it, no need to try again, it'll still be here next time around
}
});
}
}
}
}
}
}
use of me.retrodaredevil.solarthing.type.alter.packets.FlagPacket in project solarthing by wildmountainfarms.
the class FlagUtil method isFlagActive.
public static boolean isFlagActive(Instant now, String flagName, Stream<? extends StoredAlterPacket> packetStream) {
return packetStream.anyMatch(storedAlterPacket -> {
AlterPacket alterPacket = storedAlterPacket.getPacket();
if (alterPacket instanceof FlagPacket) {
FlagPacket flagPacket = (FlagPacket) alterPacket;
FlagData data = flagPacket.getFlagData();
return data.getFlagName().equals(flagName) && data.getActivePeriod().isActive(now);
}
return false;
});
}
use of me.retrodaredevil.solarthing.type.alter.packets.FlagPacket in project solarthing by wildmountainfarms.
the class AlterManagerAction method receivePacketWithIntegrity.
private void receivePacketWithIntegrity(String sender, TargetPacketGroup packetGroup) {
LOGGER.debug("Sender: " + sender + " is authorized and sent a packet targeting no fragments, so we will see if we want to handle anything from it.");
long now = System.currentTimeMillis();
List<StoredAlterPacket> storedAlterPacketsToUpload = new ArrayList<>();
List<DeleteAlterPacket> deleteAlterPackets = new ArrayList<>();
for (Packet packet : packetGroup.getPackets()) {
if (packet instanceof ScheduleCommandPacket) {
ScheduleCommandPacket scheduleCommandPacket = (ScheduleCommandPacket) packet;
ScheduledCommandData data = scheduleCommandPacket.getData();
ExecutionReason executionReason = new OpenSourceExecutionReason(new OpenSource(sender, packetGroup.getDateMillis(), scheduleCommandPacket, // this is legacy data and shouldn't be used anywhere, so it doesn't matter what we put here
scheduleCommandPacket.getUniqueString()));
ScheduledCommandPacket scheduledCommandPacket = new ScheduledCommandPacket(data, executionReason);
// This databaseId is basically an arbitrary way to generate a unique ID. It contains some stuff such as the command name to debug more easily
String databaseId = "alter-scheduled-command-" + data.getCommandName() + "-" + Long.toHexString(data.getScheduledTimeMillis()) + "-" + sender + "-" + Math.random();
StoredAlterPacket storedAlterPacket = new ImmutableStoredAlterPacket(databaseId, now, scheduledCommandPacket, this.sourceId);
storedAlterPacketsToUpload.add(storedAlterPacket);
} else if (packet instanceof DeleteAlterPacket) {
DeleteAlterPacket deleteAlterPacket = (DeleteAlterPacket) packet;
try {
database.validateUpdateToken(deleteAlterPacket.getUpdateToken());
deleteAlterPackets.add(deleteAlterPacket);
} catch (IncompatibleUpdateTokenException ex) {
LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "For some reason we have an incompatible update token!", ex);
}
} else if (packet instanceof RequestFlagPacket) {
RequestFlagPacket requestFlagPacket = (RequestFlagPacket) packet;
// Originally I was going to not upload a FlagPacket if an existing FlagPacket's
// time range fully encapsulated the newly requested one, but that adds some complexity
// that is not needed at the moment
FlagData flagData = requestFlagPacket.getFlagData();
ExecutionReason executionReason = new OpenSourceExecutionReason(new OpenSource(sender, packetGroup.getDateMillis(), requestFlagPacket, // this is legacy data and shouldn't be used anywhere, so it doesn't matter what we put here
requestFlagPacket.getUniqueString()));
FlagPacket flagPacket = new FlagPacket(flagData, executionReason);
String databaseId = "alter-flag-" + flagData.getFlagName() + "-" + sender + "-" + Math.random();
StoredAlterPacket storedAlterPacket = new ImmutableStoredAlterPacket(databaseId, now, flagPacket, sourceId);
storedAlterPacketsToUpload.add(storedAlterPacket);
}
}
if (storedAlterPacketsToUpload.isEmpty() && deleteAlterPackets.isEmpty()) {
// Nothing for us to do, so no need to schedule a runnable
return;
}
executorService.execute(() -> {
int uploadCount = 0;
try {
for (StoredAlterPacket storedAlterPacket : storedAlterPacketsToUpload) {
this.database.getAlterDatabase().upload(storedAlterPacket);
uploadCount++;
}
} catch (SolarThingDatabaseException e) {
// TODO in future we should try multiple times to upload
LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "Could not upload a stored alter packet! uploaded: " + uploadCount + " / " + storedAlterPacketsToUpload.size(), e);
}
int deleteCount = 0;
try {
for (DeleteAlterPacket deleteAlterPacket : deleteAlterPackets) {
this.database.getAlterDatabase().delete(deleteAlterPacket.getDocumentIdToDelete(), deleteAlterPacket.getUpdateToken());
deleteCount++;
}
} catch (SolarThingDatabaseException e) {
LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "Could not delete alter packets! deleted: " + deleteCount + " / " + deleteAlterPackets.size(), e);
}
});
}
use of me.retrodaredevil.solarthing.type.alter.packets.FlagPacket in project solarthing by wildmountainfarms.
the class FlagCommandChatBotHandler method clearFlag.
private void clearFlag(MessageSender messageSender, String flagName) {
List<VersionedPacket<StoredAlterPacket>> packets = getPacketsWithFlagName(flagName);
if (packets == null) {
messageSender.sendMessage("Could not get flags. Please try again.");
return;
}
Instant now = Instant.now();
if (packets.isEmpty()) {
messageSender.sendMessage("Flag: '" + flagName + "' is not set!");
return;
}
List<VersionedPacket<StoredAlterPacket>> activePackets = packets.stream().filter(versionedPacket -> {
FlagPacket flagPacket = (FlagPacket) versionedPacket.getPacket().getPacket();
return flagPacket.getFlagData().getActivePeriod().isActive(now);
}).collect(Collectors.toList());
if (activePackets.isEmpty()) {
messageSender.sendMessage("Flag: '" + flagName + "' is not currently active. In a future update we may allow you to clear inactive flags.");
return;
}
// We know that the user wants this flag cleared, so let's delete all the packets that are active.
for (VersionedPacket<StoredAlterPacket> packetToRequestDeleteFor : activePackets) {
DeleteAlterPacket deleteAlterPacket = new ImmutableDeleteAlterPacket(packetToRequestDeleteFor.getPacket().getDbId(), packetToRequestDeleteFor.getUpdateToken());
PacketCollectionCreator creator = commandHelper.getCommandManager().makeCreator(sourceId, zoneId, null, deleteAlterPacket, PacketCollectionIdGenerator.Defaults.UNIQUE_GENERATOR);
PacketCollection packetCollection = creator.create(now);
boolean success = false;
try {
database.getOpenDatabase().uploadPacketCollection(packetCollection, null);
success = true;
} catch (SolarThingDatabaseException e) {
LOGGER.error("Could not upload request to delete alter packet for ID: " + packetToRequestDeleteFor.getPacket().getDbId(), e);
}
if (success) {
messageSender.sendMessage("Requested delete for flag: '" + flagName + "' under ID: " + packetToRequestDeleteFor.getPacket().getDbId());
} else {
messageSender.sendMessage("Could not request delete for flag: '" + flagName + "' under ID: " + packetToRequestDeleteFor.getPacket().getDbId() + ". See logs for details.");
}
}
}
Aggregations