Skip to content

Commit

Permalink
Merge pull request #183 from webdjoe/feature-requests
Browse files Browse the repository at this point in the history
Feature requests
  • Loading branch information
webdjoe committed May 19, 2023
2 parents bb9060b + 1b4c6f0 commit 308a988
Show file tree
Hide file tree
Showing 18 changed files with 787 additions and 152 deletions.
117 changes: 87 additions & 30 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -44,6 +44,7 @@ pyvesync is a library to manage VeSync compatible [smart home devices](#supporte
- [Cosori 3.7 and 5.8 Quart Air Fryer](#cosori-37-and-58-quart-air-fryer)
- [Air Fryer Properties](#air-fryer-properties)
- [Air Fryer Methods](#air-fryer-methods)
- [Timer DataClass](#timer-dataclass)
- [JSON Output API](#json-output-api)
- [JSON Output for All Devices](#json-output-for-all-devices)
- [JSON Output for Outlets](#json-output-for-outlets)
Expand All @@ -52,7 +53,6 @@ pyvesync is a library to manage VeSync compatible [smart home devices](#supporte
- [JSON Output for Tunable Bulb](#json-output-for-tunable-bulb)
- [JSON Output for Multicolor Bulb](#json-output-for-multicolor-bulb)
- [JSON Output for Air Purifier](#json-output-for-air-purifier)
- [JSON Output for 300S Humidifier](#json-output-for-300s-humidifier)
- [JSON Output for Core200S Purifier](#json-output-for-core200s-purifier)
- [JSON Output for 400S Purifier](#json-output-for-400s-purifier)
- [JSON Output for 600S Purifier](#json-output-for-600s-purifier)
Expand All @@ -61,7 +61,6 @@ pyvesync is a library to manage VeSync compatible [smart home devices](#supporte
- [Redact mode](#redact-mode)
- [Feature Requests](#feature-requests)


## Installation

Install the latest version from pip:
Expand All @@ -81,6 +80,7 @@ pip install pyvesync
5. Two Plug Outdoor Outlet (ESO15-TB) (Each plug is a separate `VeSyncOutlet` object, energy readings are for both plugs combined)

### Wall Switches

1. Etekcity Smart WiFi Light Switch (model ESWL01)
2. Etekcity Wifi Dimmer Switch (ESD16)

Expand All @@ -98,16 +98,19 @@ pip install pyvesync
2. Cool to Soft White Tunable Dimmable Bulb (ESL100CW)

### Valceno Bulbs

1. Multicolor Bulb (XYD0001)

### Levoit Humidifiers

1. Dual 200S
2. Classic 300S
3. LUH-D301S-WEU Dual (200S)
4. LV600S
5. OasisMist LUS-O415S-WUS

Cosori Air Fryer

1. Cosori 3.7 and 5.8 Quart Air Fryer

## Usage
Expand Down Expand Up @@ -139,6 +142,7 @@ my_bulb.set_brightness(75)
# get its details in JSON and print
print(my_bulb.displayJSON())
```

Devices are stored in the respective lists in the instantiated `VeSync` class:

```python
Expand All @@ -163,14 +167,17 @@ for switch in manager.switches:
if switch.device_name == switch_name:
switch.turn_on()
```

## Configuration

### Time Zones

The `time_zone` argument is optional but the specified time zone must match time zone in the tz database (IANNA Time Zone Database), see this link for reference:
[tz database](https://en.wikipedia.org/wiki/List_of_tz_database_time_zones).
The time zone determines how the energy history is generated for the smart outlets, i.e. for the week starts at 12:01AM Sunday morning at the specified time zone. If no time zone or an invalid time zone is entered the default is America/New_York

### Outlet energy data update interval

If outlets are going to be continuously polled, a custom energy update interval can be set - The default is 6 hours (21600 seconds)

```python
Expand All @@ -182,7 +189,9 @@ manager.energy_update_interval = 360 # time in seconds
### Get electricity metrics of outlets

Bypass the interval check to trigger outlet energy update.

```python

for s in manager.outlets:
s.update_energy(check_bypass=False) # Get energy history for each device
```
Expand Down Expand Up @@ -311,6 +320,7 @@ NOTE: LV-PUR131S outputs `air_quality` as a string, such as `Excellent`
`VeSyncFan.change_fan_speed(speed=None)` - Change fan speed. Call without speed to toggle to next speed

Compatible levels for each model:

- Core 200S [1, 2, 3]
- Core 300S/400S [1, 2, 3, 4]
- PUR131S [1, 2, 3]
Expand All @@ -333,6 +343,11 @@ Compatible levels for each model:

`VeSyncFan.set_night_light('on'|'dim'|'off')` - Set night light brightness

`VeSyncFan.get_timer()` - Get any running timers, stores Timer DataClass in `VeSyncFan.timer`

`VeSyncFan.set_timer(timer_duration=3000)` - Set a timer for the device, only turns device off. Timer DataClass stored in `VeSyncFan.timer`

`VeSyncFan.clear_timer()` - Cancel any running timer

### Lights API Methods & Properties

Expand All @@ -356,9 +371,9 @@ Compatible levels for each model:

*Compatible with ESL100MC & Valceno Bulbs*
**Properties**
`VeSyncBulb.color` - Returns a dataclass with HSV and RGB attributes that are named tuples
`VeSyncBulb.color` - Returns a Dataclass with HSV and RGB attributes that are named tuples

```
```python
VeSyncBulb.color.rbg = namedtuple('RGB', ['red', 'green', 'blue'])
VeSyncBulb.color.hsv = namedtuple('HSV', ['hue', 'saturation', 'value'])
```
Expand Down Expand Up @@ -549,6 +564,7 @@ They can be set through the `VeSyncAirFryer158.fryer_status` dataclass but shoul
`VeSyncAirFryer158.preheat_last_time` - The last minutes remaining returned from API for preheat mode

`VeSyncAirFryer158.cook_status` - Status of air fryer. This can be the following states:

1. `standby` - Air fryer is off and no cook or preheat is in progress
2. `cooking` - Air fryer is actively cooking
3. `cookStop` - Cooking is paused and can be resumed
Expand All @@ -565,7 +581,7 @@ They can be set through the `VeSyncAirFryer158.fryer_status` dataclass but shoul

`VeSyncAirFryer158.remaining_time` - Returns minutes remaining based on timestamp of last API return when air fryer is running. Returns `None` if not running

`VeSyncAirFryer158.fryer_status` - Dataclass that contains the status of the air fryer. The attributes of this dataclass are directly accessible from the `VeSyncAirFryer158` properties and **should not be directly set.**
`VeSyncAirFryer158.fryer_status` - Dataclass that contains the status of the air fryer. The attributes of this Dataclass are directly accessible from the `VeSyncAirFryer158` properties and **should not be directly set.**

##### Air Fryer Methods

Expand All @@ -583,6 +599,43 @@ They can be set through the `VeSyncAirFryer158.fryer_status` dataclass but shoul

`VeSyncAirFryer158.end()` - End cooking or preheating and return air fryer to `standby` state


### Timer DataClass

This is the a Timer DataClass that is used in the `get_timer()` or `set_timer()` methods *only implemented for Levoit Core 200S and 300S Air Purifier*, will eventually integrate with remaining devices. This object is created when the device timer methods are called. **The `pause()`, `resume()` and `stop()` methods for this DataClass only impact the timer locally and do not update the API.**

```python
from pyvesync.helpers import Timer

timer = Timer(timer_duration=60, id=1)

# Get time remaining in seconds
# Calculates based on timer elapsed each time property is called
timer.remaining_time

# Get status
timer.status

# Get action
timer.action

# Set status - active or done
timer.status = 'active'

# set time remaining in seconds, does not edit status
timer.remaining_time = 120

# Pause timer - Does not update API - only pauses locally
timer.pause()

# End timer -Does not update API - only ends locally
timer.end()

# Resume timer - Does not update API - only Resumes locally
timer.start()
```


### JSON Output API

The `device.displayJSON()` method outputs properties and status of the device
Expand Down Expand Up @@ -682,9 +735,9 @@ This output only applies to dimmable switch. The standard switch has the defaul
"Filter Life": "99" # remaining filter life in percent
}
```
#### JSON Output for 300S Humidifier

```python

{
"Mode": "manual", # auto, manual, sleep
"Humidity": 20, # percent
Expand All @@ -703,21 +756,21 @@ This output only applies to dimmable switch. The standard switch has the defaul

```python
{
"Device Name": "MyPurifier",
"Model": "Core200S",
"Subdevice No": "None",
"Status": "on",
"Online": "online",
"Type": "wifi-air",
"CID": "asd_sdfKIHG7IJHGwJGJ7GJ_ag5h3G55",
"Mode": "manual",
"Filter Life": "99",
"Fan Level": "1",
"Display": true,
"Child Lock": false,
"Night Light": "off",
"Display Config": true,
"Display_Forever Config": false
"Device Name": "MyPurifier",
"Model": "Core200S",
"Subdevice No": "None",
"Status": "on",
"Online": "online",
"Type": "wifi-air",
"CID": "asd_sdfKIHG7IJHGwJGJ7GJ_ag5h3G55",
"Mode": "manual",
"Filter Life": "99",
"Fan Level": "1",
"Display": true,
"Child Lock": false,
"Night Light": "off",
"Display Config": true,
"Display_Forever Config": false
}
```

Expand All @@ -744,6 +797,7 @@ This output only applies to dimmable switch. The standard switch has the defaul
"Display_Forever Config": false
}
```

#### JSON Output for 600S Purifier

```python
Expand Down Expand Up @@ -813,7 +867,7 @@ manager.update()

~~If you would like new devices to be added, you will need to capture the packets from the app. The easiest way to do this is by using [Packet Capture for Android](https://play.google.com/store/apps/details?id=app.greyshirts.sslcapture&hl=en_US&gl=US). This works without rooting the device. If you do not have an android or are concerned with adding an app that uses a custom certificate to read the traffic, you can use an Android emulator such as [Nox](https://www.bignox.com/).~~

SSL pinning makes capturing packets with Android ~~not feasible anymore~~ harder than before. A system-wide proxy (https://play.google.com/store/apps/details?id=org.proxydroid&hl=en) can be used if ssl pinning is disabled (https://github.com/ViRb3/TrustMeAlready).
SSL pinning makes capturing packets with Android ~~not feasible anymore~~ harder than before. A system-wide proxy [ProxyDroid](https://play.google.com/store/apps/details?id=org.proxydroid&hl=en) can be used if ssl pinning is disabled [TrustMeAlready](https://github.com/ViRb3/TrustMeAlready).

Charles Proxy is a proxy that allows you to perform MITM SSL captures on an iOS device. This is the only way to capture packets that I am aware of that is currently possible.

Expand All @@ -824,19 +878,22 @@ After you capture the packets, please redact the `accountid` and `token`. If you
For example:

Before:
```

```json
{
'tk': 'abc123abc123==3rf',
'accountId': '123456789',
'cid': 'abcdef12-3gh-ij'
"tk": "abc123abc123==3rf",
"accountId": "123456789",
"cid": "abcdef12-3gh-ij"
}
```

After:
```

```json
{
'tk': 'AAA111AAA111==1AA',
'accountId': '111111111',
'cid': 'AAAAAA11-1AA-AA'
"tk": "AAA111AAA111==1AA",
"accountId": "111111111",
"cid": "AAAAAA11-1AA-AA"
}
```

Expand Down
5 changes: 3 additions & 2 deletions setup.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,9 +10,10 @@

setup(
name='pyvesync',
version='2.1.6',
version='2.1.7',
description='pyvesync is a library to manage Etekcity\
Devices and Levoit Air Purifier',
Devices, Cosori Air Fryers and Levoit Air \
Purifiers run on the VeSync app.',
long_description=long_description,
long_description_content_type='text/markdown',
url='https://github.com/webdjoe/pyvesync',
Expand Down
Loading

0 comments on commit 308a988

Please sign in to comment.