Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
3 changes: 2 additions & 1 deletion .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,5 @@
.venv
.env
.venv*
.vscode
__pycache__
/dist
Expand Down
3 changes: 1 addition & 2 deletions pyemvue/__init__.py
Original file line number Diff line number Diff line change
@@ -1,2 +1 @@

from pyemvue.pyemvue import PyEmVue
from pyemvue.pyemvue import PyEmVue
19 changes: 9 additions & 10 deletions pyemvue/__main__.py
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
import sys
import datetime
import sys

import dateutil

# Our files
Expand Down Expand Up @@ -49,7 +50,7 @@ def main():
deviceGids: list[int] = []
deviceInfo: dict[int, VueDevice] = {}
for device in devices:
if not device.device_gid in deviceGids:
if device.device_gid not in deviceGids:
deviceGids.append(device.device_gid)
deviceInfo[device.device_gid] = device
print(
Expand Down Expand Up @@ -100,9 +101,7 @@ def main():
),
)

monthly, start = vue.get_chart_usage(
devices[0].channels[0], scale=Scale.MONTH.value
)
monthly, start = vue.get_chart_usage(devices[0].channels[0], scale=Scale.MONTH)
print(monthly[0], "kwh used since", start.isoformat())
now = datetime.datetime.now(datetime.timezone.utc)
midnight = (
Expand All @@ -114,7 +113,7 @@ def main():
yesterday = yesterday.replace(tzinfo=None)
print("Total usage for today in kwh: ")

use = vue.get_device_list_usage(deviceGids, now, Scale.DAY.value)
use = vue.get_device_list_usage(deviceGids, now, Scale.DAY)
print_recursive(use, deviceInfo)
print("Total usage for yesterday in kwh: ")
for gid, device in deviceInfo.items():
Expand All @@ -123,20 +122,20 @@ def main():
chan,
yesterday,
yesterday + datetime.timedelta(hours=23, minutes=59),
Scale.DAY.value,
Scale.DAY,
)
if usage and usage[0]:
print(f"{chan.device_gid} ({chan.channel_num}): {usage[0][0]} kwh")
print("Average usage over the last minute in watts: ")
use = vue.get_device_list_usage(deviceGids, None, Scale.MINUTE.value)
use = vue.get_device_list_usage(deviceGids, None, Scale.MINUTE)
print_recursive(use, deviceInfo, scaleBy=60000, unit="W")

usage_over_time, start_time = vue.get_chart_usage(
devices[0].channels[0],
datetime.datetime.now(datetime.timezone.utc) - datetime.timedelta(days=7),
datetime.datetime.now(datetime.timezone.utc),
scale=Scale.DAY.value,
unit=Unit.KWH.value,
scale=Scale.DAY,
unit=Unit.KWH,
)

print("Usage for the last seven days starting", start_time.isoformat())
Expand Down
5 changes: 3 additions & 2 deletions pyemvue/auth.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,7 @@
from datetime import datetime
import time
from typing import Any, Optional, Callable
from datetime import datetime
from typing import Any, Callable, Optional

import jwt
import requests

Expand Down
52 changes: 52 additions & 0 deletions pyemvue/basemodel.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,52 @@
from __future__ import annotations

import datetime
from typing import Any, Optional

import pydantic
from humps import camelize
from pydantic import Field


class BaseModel(pydantic.BaseModel):
class Config:
alias_generator = camelize

# for backwards compatibility
def as_dictionary(self) -> dict[str, Any]:
return self.model_dump()


class LatitudeLongitude(BaseModel):
latitude: float = Field(ge=-90.0, le=90.0)
longitude: float = Field(ge=-180.0, le=180.0)


class LocationInformation(BaseModel):
air_conditioning: Optional[str]
heat_source: Optional[str]
location_sq_ft: Optional[str]
num_electric_cars: Optional[str]
location_type: Optional[str]
num_people: Optional[str]
swimming_pool: Optional[str]
hot_tub: Optional[str]


class LocationProperties(BaseModel):
display_name: Optional[str] = Field(default=None)
device_gid: Optional[int] = Field(default=None)
device_name: Optional[str] = Field(default=None)
latitude_longitude: Optional[LatitudeLongitude] = Field(default=None)
time_zone: Optional[str] = Field(default=None)
utility_rate_gid: Optional[str] = Field(default=None)
billing_cycle_start_day: Optional[int] = Field(default=None)
location_information: Optional[LocationInformation] = Field(default=None)
peak_demand_dollar_per_kw: Optional[float] = Field(default=None)
usageCentPerKwHour: Optional[float] = Field(default=None)
zip_code: Optional[str] = Field(default=None)


class ChannelUsageData(BaseModel):
first_usage_instant: datetime.datetime
usage_list: list[Optional[float]]
38 changes: 10 additions & 28 deletions pyemvue/customer.py
Original file line number Diff line number Diff line change
@@ -1,31 +1,13 @@
import datetime
from datetime import datetime

from pydantic import Field

class Customer(object):
def __init__(
self,
gid=0,
email="",
firstName="",
lastName="",
createdAt=datetime.datetime(1970, 1, 1),
):
self.customer_gid = gid
self.email = email
self.first_name = firstName
self.last_name = lastName
self.created_at = createdAt
from pyemvue.basemodel import BaseModel

def from_json_dictionary(self, js):
"""Populate customer data from a dictionary extracted from the response json."""
if "customerGid" in js:
self.customer_gid = js["customerGid"]
if "email" in js:
self.email = js["email"]
if "firstName" in js:
self.first_name = js["firstName"]
if "lastName" in js:
self.last_name = js["lastName"]
if "createdAt" in js:
self.created_at = js["createdAt"]
return self

class Customer(BaseModel):
customer_gid: int = Field(default=0)
email: str = Field(default="")
first_name: str = Field(default="")
last_name: str = Field(default="")
created_at: datetime = Field(default=datetime(1970, 1, 1))
Loading