use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.
the class RequireFullOutputActionNode method createAction.
@Override
public Action createAction(ActionEnvironment actionEnvironment) {
LatestFragmentedPacketGroupEnvironment latestPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestFragmentedPacketGroupEnvironment.class);
return new SimpleAction(false) {
@Override
protected void onUpdate() {
super.onUpdate();
FragmentedPacketGroup latestPacketGroup = latestPacketGroupEnvironment.getFragmentedPacketGroupProvider().getPacketGroup();
if (latestPacketGroup != null) {
setDone(isFullOutput(latestPacketGroup));
}
}
};
}
use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.
the class AutomationMain method startAutomation.
public static int startAutomation(List<ActionNode> actionNodes, DatabaseTimeZoneOptionBase options, long periodMillis) {
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Starting automation program.");
final CouchDbDatabaseSettings couchSettings;
try {
couchSettings = ConfigUtil.expectCouchDbDatabaseSettings(options);
} catch (IllegalArgumentException ex) {
LOGGER.error("(Fatal)", ex);
return SolarThingConstants.EXIT_CODE_INVALID_CONFIG;
}
SolarThingDatabase database = CouchDbSolarThingDatabase.create(CouchDbUtil.createInstance(couchSettings.getCouchProperties(), couchSettings.getOkHttpProperties()));
VariableEnvironment variableEnvironment = new VariableEnvironment();
// Use atomic reference so that access is thread safe
AtomicReference<FragmentedPacketGroup> latestPacketGroupReference = new AtomicReference<>(null);
// Use atomic reference so that access is thread safe
AtomicReference<List<VersionedPacket<StoredAlterPacket>>> alterPacketsReference = new AtomicReference<>(null);
// note this may return null, and that's OK // This is thread safe if needed
FragmentedPacketGroupProvider fragmentedPacketGroupProvider = latestPacketGroupReference::get;
Clock clock = Clock.systemUTC();
SimpleDatabaseCache statusDatabaseCache = SimpleDatabaseCache.createDefault(clock);
// not thread safe
ResourceManager<SimpleDatabaseCache> statusDatabaseCacheManager = new BasicResourceManager<>(statusDatabaseCache);
SimpleDatabaseCache eventDatabaseCache = SimpleDatabaseCache.createDefault(clock);
ResourceManager<SimpleDatabaseCache> eventDatabaseCacheManager = new ReadWriteResourceManager<>(eventDatabaseCache);
SimpleDatabaseCache openDatabaseCache = new SimpleDatabaseCache(Duration.ofMinutes(60), Duration.ofMinutes(40), Duration.ofMinutes(20), Duration.ofMinutes(15), clock);
// not thread safe
ResourceManager<SimpleDatabaseCache> openDatabaseCacheManager = new BasicResourceManager<>(openDatabaseCache);
SimplePacketCache<AuthorizationPacket> authorizationPacketCache = new SimplePacketCache<>(Duration.ofSeconds(20), DatabaseDocumentKeyMap.createPacketSourceFromDatabase(database), false);
String sourceId = options.getSourceId();
InjectEnvironment injectEnvironment = new InjectEnvironment.Builder().add(new NanoTimeProviderEnvironment(NanoTimeProvider.SYSTEM_NANO_TIME)).add(new SourceIdEnvironment(sourceId)).add(// most of the time, it's better to use SolarThingDatabaseEnvironment instead, but this option is here in case it's needed
new CouchDbEnvironment(couchSettings)).add(new SolarThingDatabaseEnvironment(CouchDbSolarThingDatabase.create(CouchDbUtil.createInstance(couchSettings.getCouchProperties(), couchSettings.getOkHttpProperties())))).add(new TimeZoneEnvironment(options.getZoneId())).add(// access is thread safe if needed
new LatestPacketGroupEnvironment(fragmentedPacketGroupProvider)).add(// access is thread safe if needed
new LatestFragmentedPacketGroupEnvironment(fragmentedPacketGroupProvider)).add(new EventDatabaseCacheEnvironment(eventDatabaseCacheManager)).add(new OpenDatabaseCacheEnvironment(openDatabaseCache)).add(// access is thread safe if needed
new AlterPacketsEnvironment(alterPacketsReference::get)).add(new AuthorizationEnvironment(new DatabaseDocumentKeyMap(authorizationPacketCache))).build();
ActionMultiplexer multiplexer = new Actions.ActionMultiplexerBuilder().build();
while (!Thread.currentThread().isInterrupted()) {
queryAndFeed(database.getStatusDatabase(), statusDatabaseCacheManager, true);
queryAndFeed(database.getEventDatabase(), eventDatabaseCacheManager, true);
queryAndFeed(database.getOpenDatabase(), openDatabaseCacheManager, false);
{
// Never cache alter packets, because it's always important that we have up-to-date data, or no data at all.
List<VersionedPacket<StoredAlterPacket>> alterPackets = null;
try {
alterPackets = database.getAlterDatabase().queryAll(sourceId);
LOGGER.debug("Got " + alterPackets.size() + " alter packets");
} catch (SolarThingDatabaseException e) {
LOGGER.error("Could not get alter packets", e);
}
alterPacketsReference.set(alterPackets);
}
// we have auto update turned off, so we have to call this
authorizationPacketCache.updateIfNeeded();
List<FragmentedPacketGroup> statusPacketGroups = PacketUtil.getPacketGroups(options.getSourceId(), options.getDefaultInstanceOptions(), statusDatabaseCache.getAllCachedPackets());
if (statusPacketGroups != null) {
FragmentedPacketGroup statusPacketGroup = statusPacketGroups.get(statusPacketGroups.size() - 1);
latestPacketGroupReference.set(statusPacketGroup);
}
for (ActionNode actionNode : actionNodes) {
multiplexer.add(actionNode.createAction(new ActionEnvironment(variableEnvironment, new VariableEnvironment(), injectEnvironment)));
}
multiplexer.update();
LOGGER.debug("There are " + multiplexer.getActiveActions().size() + " active actions");
try {
Thread.sleep(periodMillis);
} catch (InterruptedException ex) {
Thread.currentThread().interrupt();
throw new RuntimeException(ex);
}
}
return 0;
}
use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.
the class RequiredIdentifierActionNode method createAction.
@Override
public Action createAction(ActionEnvironment actionEnvironment) {
LatestFragmentedPacketGroupEnvironment latestPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestFragmentedPacketGroupEnvironment.class);
return new SimpleAction(false) {
@Override
protected void onUpdate() {
super.onUpdate();
FragmentedPacketGroup packetGroup = latestPacketGroupEnvironment.getFragmentedPacketGroupProvider().getPacketGroup();
if (packetGroup == null) {
return;
}
String reason = IdentifierUtil.getRequirementNotMetReason(requiredIdentifierMap, packetGroup);
if (reason != null) {
if (log) {
LOGGER.info("Requirement not met: " + reason);
}
} else {
setDone(true);
}
}
};
}
use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.
the class AccumulationUtil method mapPackets.
@SuppressWarnings("unchecked")
@Contract(pure = true)
public static <T extends Identifiable> Map<IdentifierFragment, List<TimestampedPacket<T>>> mapPackets(Class<T> clazz, List<? extends FragmentedPacketGroup> packetGroups) {
Map<IdentifierFragment, List<TimestampedPacket<T>>> packetMap = new HashMap<>();
for (FragmentedPacketGroup packetGroup : packetGroups) {
for (Packet packet : packetGroup.getPackets()) {
if (clazz.isInstance(packet)) {
int fragmentId = packetGroup.getFragmentId(packet);
T t = (T) packet;
IdentifierFragment identifierFragment = IdentifierFragment.create(fragmentId, t.getIdentifier());
List<TimestampedPacket<T>> packetList = packetMap.computeIfAbsent(identifierFragment, k -> new ArrayList<>());
long dateMillis = packetGroup.getDateMillisOrKnown(packet);
packetList.add(new TimestampedPacket<>(t, dateMillis));
}
}
}
return packetMap;
}
use of me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup in project solarthing by wildmountainfarms.
the class SolcastActionNode method createAction.
@Override
public Action createAction(ActionEnvironment actionEnvironment) {
LatestFragmentedPacketGroupEnvironment latestPacketGroupEnvironment = actionEnvironment.getInjectEnvironment().get(LatestFragmentedPacketGroupEnvironment.class);
return Actions.createRunOnce(() -> {
FragmentedPacketGroup packetGroup = latestPacketGroupEnvironment.getFragmentedPacketGroupProvider().getPacketGroup();
if (packetGroup == null) {
LOGGER.warn("packetGroup is null! Not uploading anything to solcast.");
return;
}
PowerUtil.Data data = PowerUtil.getPowerData(packetGroup, PowerUtil.GeneratingType.PV_ONLY);
Integer watts = data.getGeneratingWatts();
if (watts != null) {
LOGGER.debug("Total " + watts + " watts will be uploaded to Solcast");
Call<?> call = service.postMeasurement(resourceId, MeasurementData.createSingle(new Measurement(Instant.ofEpochMilli(packetGroup.getDateMillis()), Duration.ofMinutes(5), watts / 1000.0f)));
executorService.execute(() -> {
try {
Response<?> response = call.execute();
if (!response.isSuccessful()) {
LOGGER.error("Unsuccessful solcast response! Code: " + response.code());
}
} catch (IOException e) {
LOGGER.error("Solcast error", e);
}
});
}
});
}
Aggregations