public async Task <Measurement> measure(DateInterval billingInterval)
        {
            TeslaAuthToken authToken = await authService.getAuthToken();

            long energySiteId = await productService.fetchEnergySiteId(authToken);

            ICollection <Task <HistoricalCalendarDataResponse> > requests = new List <Task <HistoricalCalendarDataResponse> > {
                client.energySites.fetchHistoricalCalendarData(energySiteId, billingInterval.Start, reportTimeZone, authToken)
            };

            if (billingInterval.Start.Month != billingInterval.End.Month)
            {
                requests.Add(client.energySites.fetchHistoricalCalendarData(energySiteId, billingInterval.End, reportTimeZone,
                                                                            authToken));
            }

            HistoricalCalendarDataResponse[] responses = await Task.WhenAll(requests);

            IEnumerable <EnergyTimeSeriesEntry> timeSeries = responses.SelectMany(response => response.timeSeries);

            IEnumerable <EnergyTimeSeriesEntry> entriesInBillingInterval =
                timeSeries.Where(entry => billingInterval.Contains(entry.timestamp.Date));

            double energyExportedWattHours = entriesInBillingInterval.Aggregate(0.0, (sum, entry) => sum + entry.solarEnergyExported);

            return(new Measurement {
                generatedKilowattHours = energyExportedWattHours / 1000
            });
        }
Example #2
0
        public async Task <TeslaAuthToken> fetchAuthToken(string username, string password)
        {
            UriBuilder requestUri = OwnerApiClientImpl.apiRoot;

            requestUri.Path = "/oauth/token";

            var requestBody = new Dictionary <string, string> {
                { "email", username },
                { "password", password },
                { "grant_type", "password" },
                { "client_id", CLIENT_ID },
                { "client_secret", CLIENT_SECRET }
            };

            try {
                using HttpResponseMessage response = await httpClient.PostAsync(requestUri.Uri, new JsonEncodedContent (requestBody));

                var responseBody = await readContentAsJson <JObject>(response);

                Instant now = SystemClock.Instance.GetCurrentInstant();

                var authToken = new TeslaAuthToken {
                    accessToken = responseBody["access_token"].ToObject <string>(),
                    tokenType   = responseBody["token_type"].ToObject <string>(),
                    expiration  = now + Duration.FromSeconds(responseBody["expires_in"].ToObject <long>()),
                    creation    = Instant.FromUnixTimeSeconds(responseBody["created_at"].ToObject <long>())
                };
                return(authToken);
            } catch (HttpRequestException e) {
                throw new TeslaException("Failed to log in with credentials, username or password may be incorrect.", e);
            }
        }
        private async Task <TeslaAuthToken> logIn()
        {
            LOGGER.Debug("Logging in to Owner API as {0}", username);
            TeslaAuthToken authToken = await client.authentication.fetchAuthToken(username, password);

            LOGGER.Debug("Logged in to Owner API");
            LOGGER.Trace("Owner API auth token: {0}", authToken.accessToken);
            return(authToken);
        }
        public async Task logOut()
        {
            if (_authToken != null)
            {
                try {
                    await client.authentication.logOut(_authToken);
                } catch (TeslaException) {
                    //proceed even if log out fails, because what else can we do?
                }
            }

            _authToken = null;
            username   = null;
            password   = null;
        }
        public async Task <IEnumerable <EnergySiteProduct> > fetchProducts(TeslaAuthToken authToken)
        {
            UriBuilder uri = OwnerApiClientImpl.apiRoot
                             .WithPathSegment("products");

            try {
                HttpRequestMessage request = OwnerApiClientImpl.createRequest(HttpMethod.Get, uri, authToken);
                using HttpResponseMessage response = await httpClient.SendAsync(request);

                var products = await readContentAsJson <ProductsResponse>(response);

                return(products.response);
            } catch (HttpRequestException e) {
                throw new TeslaException("Failed to fetch site ID of the solar panels at the house", e);
            }
        }
Example #6
0
        public async Task logOut(TeslaAuthToken authToken)
        {
            UriBuilder requestUri = OwnerApiClientImpl.apiRoot;

            requestUri.Path = "/oauth/revoke";

            var requestBody = new Dictionary <string, string> {
                { "token", authToken.accessToken }
            };

            try {
                using HttpResponseMessage response = await httpClient.PostAsync(requestUri.Uri, new JsonEncodedContent (requestBody));

                response.EnsureSuccessStatusCode();
            } catch (HttpRequestException e) {
                throw new TeslaException("Failed to log out", e);
            }
        }
        public async Task <long> fetchEnergySiteId(TeslaAuthToken authToken)
        {
            IEnumerable <EnergySiteProduct> products = await client.products.fetchProducts(authToken);

            return(products.First().energySiteId);
        }
        public async Task <HistoricalCalendarDataResponse> fetchHistoricalCalendarData(long siteId,
                                                                                       LocalDate dayInDesiredMonth, DateTimeZone reportTimeZone, TeslaAuthToken authToken)
        {
            ZonedDateTime endOfMonth = getEndOfMonth(dayInDesiredMonth, reportTimeZone);
            UriBuilder    uri        = OwnerApiClientImpl.apiRoot
                                       .WithPathSegment("energy_sites")
                                       .WithPathSegment(siteId.ToString())
                                       .WithPathSegment("calendar_history")
                                       .WithParameter("kind", "energy")
                                       .WithParameter("period", "month")
                                       .WithParameter("end_date", ISO_8601_DATETIME_MILLIS_ZONE.Format(endOfMonth));

            try {
                HttpRequestMessage request = OwnerApiClientImpl.createRequest(HttpMethod.Get, uri, authToken);
                using HttpResponseMessage response = await httpClient.SendAsync(request);

                var historicalCalendarData = await readContentAsJson <HistoricalCalendarData>(response);

                return(historicalCalendarData.response);
            } catch (HttpRequestException e) {
                throw new TeslaException($"Failed to get historical solar calendar data for the month ending on {endOfMonth}", e);
            }
        }
        internal static HttpRequestMessage createRequest(HttpMethod method, UriBuilder uri, TeslaAuthToken authToken)
        {
            var request = new HttpRequestMessage(method, uri.Uri);

            request.Headers.Authorization = new AuthenticationHeaderValue("Bearer", authToken.accessToken);
            request.Headers.UserAgent.Add(new ProductInfoHeaderValue(new ProductHeaderValue("Mozilla")));
            return(request);
        }