Search in sources :

Example 1 with SimpleDate

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());
}
Also used : OkHttpClient(okhttp3.OkHttpClient) ZoneId(java.time.ZoneId) DatabaseType(me.retrodaredevil.solarthing.config.databases.DatabaseType) PVOutputService(me.retrodaredevil.solarthing.pvoutput.service.PVOutputService) Retrofit(retrofit2.Retrofit) CouchDbDatabaseSettings(me.retrodaredevil.solarthing.config.databases.implementations.CouchDbDatabaseSettings) SimpleDate(me.retrodaredevil.solarthing.pvoutput.SimpleDate) ParseException(java.text.ParseException) CouchDbSolarThingDatabase(me.retrodaredevil.solarthing.database.couchdb.CouchDbSolarThingDatabase) SolarThingDatabase(me.retrodaredevil.solarthing.database.SolarThingDatabase) HttpLoggingInterceptor(okhttp3.logging.HttpLoggingInterceptor) DatabaseConfig(me.retrodaredevil.solarthing.program.DatabaseConfig) AnalyticsManager(me.retrodaredevil.solarthing.analytics.AnalyticsManager)

Example 2 with SimpleDate

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;
}
Also used : FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) MillisQueryBuilder(me.retrodaredevil.solarthing.database.MillisQueryBuilder) IOException(java.io.IOException) SolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException) SimpleDate(me.retrodaredevil.solarthing.pvoutput.SimpleDate) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 3 with SimpleDate

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;
}
Also used : FragmentedPacketGroup(me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup) MillisQueryBuilder(me.retrodaredevil.solarthing.database.MillisQueryBuilder) IOException(java.io.IOException) ResponseBody(okhttp3.ResponseBody) SolarThingDatabaseException(me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException) SimpleDate(me.retrodaredevil.solarthing.pvoutput.SimpleDate) JsonProcessingException(com.fasterxml.jackson.core.JsonProcessingException)

Example 4 with SimpleDate

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);
}
Also used : LocalDateTime(java.time.LocalDateTime) SimpleTime(me.retrodaredevil.solarthing.pvoutput.SimpleTime) SimpleDate(me.retrodaredevil.solarthing.pvoutput.SimpleDate) AddStatusParametersBuilder(me.retrodaredevil.solarthing.pvoutput.data.AddStatusParametersBuilder)

Aggregations

SimpleDate (me.retrodaredevil.solarthing.pvoutput.SimpleDate)4 JsonProcessingException (com.fasterxml.jackson.core.JsonProcessingException)2 IOException (java.io.IOException)2 MillisQueryBuilder (me.retrodaredevil.solarthing.database.MillisQueryBuilder)2 SolarThingDatabaseException (me.retrodaredevil.solarthing.database.exception.SolarThingDatabaseException)2 FragmentedPacketGroup (me.retrodaredevil.solarthing.packets.collection.FragmentedPacketGroup)2 ParseException (java.text.ParseException)1 LocalDateTime (java.time.LocalDateTime)1 ZoneId (java.time.ZoneId)1 AnalyticsManager (me.retrodaredevil.solarthing.analytics.AnalyticsManager)1 DatabaseType (me.retrodaredevil.solarthing.config.databases.DatabaseType)1 CouchDbDatabaseSettings (me.retrodaredevil.solarthing.config.databases.implementations.CouchDbDatabaseSettings)1 SolarThingDatabase (me.retrodaredevil.solarthing.database.SolarThingDatabase)1 CouchDbSolarThingDatabase (me.retrodaredevil.solarthing.database.couchdb.CouchDbSolarThingDatabase)1 DatabaseConfig (me.retrodaredevil.solarthing.program.DatabaseConfig)1 SimpleTime (me.retrodaredevil.solarthing.pvoutput.SimpleTime)1 AddStatusParametersBuilder (me.retrodaredevil.solarthing.pvoutput.data.AddStatusParametersBuilder)1 PVOutputService (me.retrodaredevil.solarthing.pvoutput.service.PVOutputService)1 OkHttpClient (okhttp3.OkHttpClient)1 ResponseBody (okhttp3.ResponseBody)1