use of me.retrodaredevil.solarthing.pvoutput.SimpleDate in project solarthing by wildmountainfarms.
the class PVOutputUploadMain method startPVOutputUpload.
// TODO Make this an action for the automation program
@SuppressWarnings({ "SameReturnValue", "deprecation" })
public static int startPVOutputUpload(PVOutputUploadProgramOptions options, CommandOptions commandOptions, File dataDirectory) {
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Starting PV Output upload program");
ZoneId zoneId = options.getZoneId();
// Use US local since I (retrodaredevil) am the one debugging
LOGGER.info(SolarThingConstants.SUMMARY_MARKER, "Using time zone: {}", zoneId.getDisplayName(TextStyle.FULL, Locale.US));
LOGGER.info("Using default instance options: " + options.getDefaultInstanceOptions());
DatabaseConfig databaseConfig = ConfigUtil.getDatabaseConfig(options.getDatabase());
DatabaseType databaseType = databaseConfig.getType();
if (databaseType != CouchDbDatabaseSettings.TYPE) {
LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "(Fatal)Only CouchDb can be used for this program type right now!");
return SolarThingConstants.EXIT_CODE_INVALID_CONFIG;
}
CouchDbDatabaseSettings couchDbDatabaseSettings = (CouchDbDatabaseSettings) databaseConfig.getSettings();
SolarThingDatabase database = CouchDbSolarThingDatabase.create(CouchDbUtil.createInstance(couchDbDatabaseSettings.getCouchProperties(), couchDbDatabaseSettings.getOkHttpProperties()));
OkHttpClient client = PVOutputOkHttpUtil.configure(new OkHttpClient.Builder(), options.getApiKey(), options.getSystemId()).addInterceptor(new HttpLoggingInterceptor(LOGGER::debug).setLevel(HttpLoggingInterceptor.Level.BASIC)).build();
Retrofit retrofit = PVOutputRetrofitUtil.defaultBuilder().client(client).build();
PVOutputService service = retrofit.create(PVOutputService.class);
PVOutputHandler handler = new PVOutputHandler(zoneId, options.getRequiredIdentifierMap(), options.getVoltageIdentifierFragmentMatcher(), options.getTemperatureIdentifierFragmentMatcher());
String fromDateString = commandOptions.getPVOutputFromDate();
String toDateString = commandOptions.getPVOutputToDate();
if (fromDateString != null && toDateString != null) {
System.out.println("Starting range upload");
final SimpleDate fromDate;
final SimpleDate toDate;
try {
// TODO Don't use SimpleDateFormat anymore and remove supress warnings for deprecation
fromDate = SimpleDate.fromDate(DATE_FORMAT.parse(fromDateString));
toDate = SimpleDate.fromDate(DATE_FORMAT.parse(toDateString));
} catch (ParseException e) {
e.printStackTrace();
System.err.println("Unable to parser either from date or to date. Use the yyyy-MM-dd format");
return SolarThingConstants.EXIT_CODE_INVALID_OPTIONS;
}
return startRangeUpload(fromDate, toDate, options, database, handler, service, options.getZoneId());
} else if ((fromDateString == null) != (toDateString == null)) {
LOGGER.error(SolarThingConstants.SUMMARY_MARKER, "(Fatal)You need to define both from and to, or define neither to do the normal PVOutput program!");
return SolarThingConstants.EXIT_CODE_INVALID_OPTIONS;
}
AnalyticsManager analyticsManager = new AnalyticsManager(options.isAnalyticsEnabled(), dataDirectory);
analyticsManager.sendStartUp(ProgramType.PVOUTPUT_UPLOAD);
return startRealTimeProgram(options, database, handler, service, options.getZoneId());
}
use of me.retrodaredevil.solarthing.pvoutput.SimpleDate in project solarthing by wildmountainfarms.
the class PVOutputUploadMain method startRangeUpload.
private static int startRangeUpload(SimpleDate fromDate, SimpleDate toDate, PVOutputUploadProgramOptions options, SolarThingDatabase database, PVOutputHandler handler, PVOutputService service, ZoneId zoneId) {
List<AddOutputParameters> addOutputParameters = new ArrayList<>();
SimpleDate date = fromDate;
while (date.compareTo(toDate) <= 0) {
System.out.println("Doing " + date);
SimpleDate tomorrow = date.tomorrow();
long dayStart = date.getDayStartDateMillis(zoneId);
long dayEnd = tomorrow.getDayStartDateMillis(zoneId);
List<? extends PacketGroup> rawPacketGroups = null;
try {
rawPacketGroups = database.getStatusDatabase().query(new MillisQueryBuilder().startKey(dayStart).endKey(dayEnd).inclusiveEnd(false).build());
System.out.println("Got " + rawPacketGroups.size() + " packets for date: " + date.toPVOutputString());
} catch (SolarThingDatabaseException e) {
e.printStackTrace();
System.err.println("Couldn't query packets. Skipping " + date.toPVOutputString());
}
if (rawPacketGroups != null) {
List<FragmentedPacketGroup> packetGroups = PacketUtil.getPacketGroups(options.getSourceId(), options.getDefaultInstanceOptions(), rawPacketGroups);
if (packetGroups != null) {
if (!handler.checkPackets(dayStart, packetGroups)) {
System.err.println("Unsuccessfully checked packets for " + date.toPVOutputString());
try {
System.out.println(MAPPER.writeValueAsString(packetGroups.get(packetGroups.size() - 1)));
} catch (JsonProcessingException e) {
e.printStackTrace();
}
} else {
AddStatusParameters statusParameters = handler.getStatus(dayStart, packetGroups);
AddOutputParametersBuilder outputParametersBuilder = new AddOutputParametersBuilder(statusParameters.getDate()).setGenerated(statusParameters.getEnergyGeneration()).setConsumption(statusParameters.getEnergyConsumption());
PVOutputHandler.setImportedExported(outputParametersBuilder, packetGroups, AccumulationConfig.createDefault(dayStart), options.isIncludeImport(), options.isIncludeExport());
AddOutputParameters outputParameters = outputParametersBuilder.build();
addOutputParameters.add(outputParameters);
System.out.println("Added parameters for " + date.toPVOutputString() + " to queue.");
System.out.println("Generated: " + statusParameters.getEnergyGeneration());
System.out.println(Arrays.toString(outputParameters.toCsvArray()));
System.out.println(CsvUtil.toCsvString(outputParameters.toCsvArray()));
}
} else {
System.err.println("Didn't find any packets with source: " + options.getSourceId() + " for date: " + date.toPVOutputString());
}
}
date = tomorrow;
}
System.out.println("Going to upload in batches of 30...");
for (int i = 0; i < addOutputParameters.size(); i += 30) {
if (i != 0) {
System.out.println("Sleeping...");
try {
// noinspection BusyWait
Thread.sleep(7000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Interrupted");
return SolarThingConstants.EXIT_CODE_INTERRUPTED;
}
}
int endIndex = Math.min(i + 30, addOutputParameters.size());
List<AddOutputParameters> parameters = addOutputParameters.subList(i, endIndex);
System.out.println("Going to upload from " + parameters.get(0).getOutputDate().toPVOutputString() + " to " + parameters.get(parameters.size() - 1).getOutputDate().toPVOutputString());
AddBatchOutputParameters batchOutputParameters = new ImmutableAddBatchOutputParameters(parameters);
try {
LOGGER.debug("Batch Output parameters as JSON: " + MAPPER.writeValueAsString(batchOutputParameters));
} catch (JsonProcessingException e) {
LOGGER.error("Got error serializing JSON. This should never happen.", e);
}
boolean successful = false;
for (int j = 0; j < 5; j++) {
if (j != 0) {
System.out.println("Sleeping before trying again");
try {
// noinspection BusyWait
Thread.sleep(j * 7000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
System.err.println("Interrupted");
return SolarThingConstants.EXIT_CODE_INTERRUPTED;
}
}
Call<String> call = service.addBatchOutput(batchOutputParameters);
final Response<String> response;
try {
response = call.execute();
} catch (IOException e) {
e.printStackTrace();
System.err.println("Error while executing");
continue;
}
if (response.isSuccessful()) {
System.out.println("Executed successfully. Result: " + response.body());
successful = true;
break;
} else {
System.err.println("Unsuccessful. Message: " + response.message() + " code: " + response.code());
}
}
if (!successful) {
System.err.println("All tries were unsuccessful. Ending");
return SolarThingConstants.EXIT_CODE_FAIL;
}
}
System.out.println("Done!");
return 0;
}
use of me.retrodaredevil.solarthing.pvoutput.SimpleDate in project solarthing by wildmountainfarms.
the class PVOutputUploadMain method startRealTimeProgram.
private static int startRealTimeProgram(PVOutputUploadProgramOptions options, SolarThingDatabase database, PVOutputHandler handler, PVOutputService service, ZoneId zoneId) {
if (options.isJoinTeams()) {
LOGGER.info("Going to join SolarThing team...");
Call<String> call = service.joinTeam(PVOutputConstants.SOLARTHING_TEAM_ID);
LOGGER.debug("Executing call");
Response<String> response = null;
try {
response = call.execute();
} catch (IOException e) {
LOGGER.error("Exception while executing", e);
}
if (response != null) {
int code = response.code();
String errorBody;
try {
ResponseBody responseBody = response.errorBody();
if (responseBody != null) {
errorBody = responseBody.string();
} else {
errorBody = "null";
}
} catch (IOException e) {
e.printStackTrace();
errorBody = "exception occurred";
}
if (code == 200) {
LOGGER.info("Joined the SolarThing team! Response: " + response.body());
} else if (code == 400) {
if (errorBody.contains("already")) {
LOGGER.info("Already joined SolarThing team. Response: " + errorBody);
} else if (errorBody.contains("must have at least")) {
LOGGER.info("We will try joining SolarThing team later once we have more outputs. Response: " + errorBody);
} else {
LOGGER.error("Error joining SolarThing team! Response: " + errorBody);
}
} else {
LOGGER.error("Unknown error joining SolarThing team! Response: " + errorBody);
}
}
}
while (!Thread.currentThread().isInterrupted()) {
LOGGER.debug("Going to do stuff now.");
long now = System.currentTimeMillis();
SimpleDate today = SimpleDate.fromDateMillis(now, zoneId);
long dayStartTimeMillis = today.getDayStartDateMillis(zoneId);
List<? extends PacketGroup> rawPacketGroups = null;
try {
rawPacketGroups = database.getStatusDatabase().query(new MillisQueryBuilder().startKey(dayStartTimeMillis).endKey(now).build());
LOGGER.debug("Got packets");
} catch (SolarThingDatabaseException e) {
LOGGER.error("Couldn't get status packets", e);
}
if (rawPacketGroups != null) {
List<FragmentedPacketGroup> packetGroups = PacketUtil.getPacketGroups(options.getSourceId(), options.getDefaultInstanceOptions(), rawPacketGroups);
if (packetGroups != null) {
FragmentedPacketGroup latestPacketGroup = packetGroups.get(packetGroups.size() - 1);
if (latestPacketGroup.getDateMillis() < now - 5 * 60 * 1000) {
LOGGER.warn("The last packet is more than 5 minutes in the past! now=" + now + " packet date=" + latestPacketGroup.getDateMillis());
try {
LOGGER.debug("Packets: " + MAPPER.writeValueAsString(latestPacketGroup.getPackets()));
} catch (JsonProcessingException e) {
LOGGER.warn("Couldn't serialize for some reason", e);
}
} else if (!handler.checkPackets(dayStartTimeMillis, packetGroups)) {
LOGGER.warn("Checking packets unsuccessful.");
} else {
AddStatusParameters parameters = handler.getStatus(dayStartTimeMillis, packetGroups);
if (uploadStatus(service, parameters) && (options.isIncludeImport() || options.isIncludeExport())) {
// only upload output if status is successful
AddOutputParametersBuilder outputParametersBuilder = new AddOutputParametersBuilder(parameters.getDate());
PVOutputHandler.setImportedExported(outputParametersBuilder, packetGroups, AccumulationConfig.createDefault(dayStartTimeMillis), options.isIncludeImport(), options.isIncludeExport());
AddOutputParameters outputParameters = outputParametersBuilder.build();
uploadOutput(service, outputParameters);
}
}
} else {
LOGGER.warn("Got " + rawPacketGroups.size() + " packets but, there must not have been any packets with the source: " + options.getSourceId());
}
}
LOGGER.debug("Going to sleep now");
try {
// noinspection BusyWait
Thread.sleep(5 * 60 * 1000);
} catch (InterruptedException e) {
Thread.currentThread().interrupt();
}
}
return SolarThingConstants.EXIT_CODE_INTERRUPTED;
}
use of me.retrodaredevil.solarthing.pvoutput.SimpleDate in project solarthing by wildmountainfarms.
the class PVOutputHandler method createStatusBuilder.
private static AddStatusParametersBuilder createStatusBuilder(ZoneId zoneId, long dateMillis) {
LocalDateTime localDateTime = Instant.ofEpochMilli(dateMillis).atZone(zoneId).toLocalDateTime();
SimpleDate date = SimpleDate.fromTemporal(localDateTime);
SimpleTime time = SimpleTime.fromTemporal(localDateTime);
return new AddStatusParametersBuilder(date, time);
}
Aggregations