Skip to content

Commit

Permalink
Extend CLI to list and change device status #33
Browse files Browse the repository at this point in the history
  • Loading branch information
h4de5 committed May 26, 2021
1 parent 5e47c9f commit f1baf02
Show file tree
Hide file tree
Showing 6 changed files with 122 additions and 79 deletions.
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -2,3 +2,5 @@ __pycache__
logos/@eaDir/
logos/Thumbs.db
*.bac
examples/rootCA.VIMAR.crt
examples/credentials.cfg
10 changes: 7 additions & 3 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -168,9 +168,13 @@ You can use the vimarlink library in the command line like this:
python3.9 -m pip install async_timeout homeassistant
# see examples
cd examples
# edit example.py and add your credentials
# run the example script, which will turn on and off the first light it will find
python3.9 example.py
# copy credentials.cfg.dist to credentials.cfg and add your credentials
# run the example script - print help
python3.9 example.py -h
# run the example script - list all lights
python3.9 example.py --platform lights
# run the example script - change a specific cover to open
python3.9 example.py --platform covers --device 721 --status "up/down" --value 0
```

## contribution
Expand Down
2 changes: 1 addition & 1 deletion custom_components/vimar/manifest.json
Original file line number Diff line number Diff line change
Expand Up @@ -6,6 +6,6 @@
"dependencies": [],
"config_flow": false,
"codeowners": ["@h4de5"],
"version": "2021.5.2",
"version": "2021.5.3",
"iot_class": "local_polling"
}
6 changes: 3 additions & 3 deletions custom_components/vimar/vimarlink/vimarlink.py
Original file line number Diff line number Diff line change
Expand Up @@ -312,7 +312,7 @@ def get_room_devices(self, devices={}, start: int = None, limit: int = None):
if VimarLink._room_ids is None:
return None

start, limit = self._sanitaze_limits(start, limit)
start, limit = self._sanitize_limits(start, limit)

_LOGGER.debug("get_room_devices started - from %d to %d", start, start + limit)

Expand Down Expand Up @@ -341,7 +341,7 @@ def get_remote_devices(self, devices={}, start: int = None, limit: int = None):
if len(devices) == 0:
_LOGGER.debug("get_remote_devices started - from %d to %d", start, start + limit)

start, limit = self._sanitaze_limits(start, limit)
start, limit = self._sanitize_limits(start, limit)

select = """SELECT '' AS room_ids, o2.id AS object_id, o2.name AS object_name, o2.VALUES_TYPE AS object_type,
o2.NAME AS object_name, o2.VALUES_TYPE AS object_type,
Expand All @@ -355,7 +355,7 @@ def get_remote_devices(self, devices={}, start: int = None, limit: int = None):

return self._generate_device_list(select, devices)

def _sanitaze_limits(self, start: int, limit: int):
def _sanitize_limits(self, start: int, limit: int):
"""Check for sane values in start and limit."""
# upper limit is hardcoded - too many results will kill webserver
if limit is None or limit > MAX_ROWS_PER_REQUEST or limit <= 0:
Expand Down
9 changes: 9 additions & 0 deletions examples/credentials.cfg.dist
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
; CHANGE YOUR CREDENTIALS HERE
[webserver]
schema=https
host=192.168.0.100
port=443
username=admin
password=password
certificate=rootCA.VIMAR.crt
timeout=5
172 changes: 100 additions & 72 deletions examples/example.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,7 +2,8 @@
# import async_timeout
import os
import sys
import time
import configparser
import argparse

# those imports only work in that directory
# this will be easier to use, as soon as we have a separate python package
Expand All @@ -20,74 +21,101 @@
"sensors": 'sensor',
}

# initialize credentials
# CHANGE YOUR CREDENTIALS HERE
schema = 'https'
host = '192.168.0.100'
port = 443
username = 'admin'
password = 'password'
certificate = 'rootCA.VIMAR.crt'
timeout = 5

# setup link to vimar web server
vimarconnection = VimarLink(schema, host, port, username, password, certificate, timeout)

# if certificate is not available, download it
if os.path.isfile(certificate) is False:
vimarconnection.install_certificate()

# initialize project
vimarproject = VimarProject(vimarconnection)

# try to login
try:
valid_login = vimarconnection.check_login()
except BaseException as err:
print("Login Exception: %s" % err)
valid_login = False

if (not valid_login):
print("Login failed")
exit(1)

# load all devices and device status
vimarproject.update()

# check all available device types
for device_type, platform in AVAILABLE_PLATFORMS.items():
device_count = vimarproject.platform_exists(device_type)
if device_count:
print("load platform %s with %d %s" % (platform, device_count, device_type))

# get all lights
lights = vimarproject.get_by_device_type("lights")

# list all lights and their status
for device_id, device in lights.items():
print(device_id, "-", device["object_name"], "available status:", list(device["status"].keys()))

# SELECT YOUR OWN DEVICE ID FROM THE LIST ABOVE
test_device_id = "704"

# if the default device_id is not available turn on the first found light
if (test_device_id not in lights):
test_device_id = list(lights)[0]

if ("on/off" not in lights[test_device_id]["status"]):
print("given device does not support 'on/off' status - available:", list(lights[test_device_id]["status"].keys()))
exit(1)

# get optionals parameter for given status name
optionals = vimarconnection.get_optionals_param("on/off")

# change a single status to on
print("Turn on device", test_device_id, "-", lights[test_device_id]["object_name"])
vimarconnection.set_device_status(lights[test_device_id]["status"]["on/off"]["status_id"], '1', optionals)

# wait 2 seconds
time.sleep(2)

# change a single status to off again
print("Turn off device", test_device_id, "-", lights[test_device_id]["object_name"])
vimarconnection.set_device_status(lights[test_device_id]["status"]["on/off"]["status_id"], '0', optionals)

def main():

parser = argparse.ArgumentParser(description='Command line client for controlling a vimar webserver')
parser.add_argument('-c', '--config', type=str, default="credentials.cfg", dest="configpath", help="Path to your credentials settings")
parser.add_argument('-p', '--platform', type=str, dest="platform", help="Must be one of: lights, covers, switches, climates, media_players, scenes or sensors")
# parser.add_argument('-l', '--list', action='store_true', dest="list", help="List all available devices found in the given platform")
parser.add_argument('-d', '--device', type=int, dest="device_id", help="ID of the device you want to change")
parser.add_argument('-s', '--status', type=str, dest="status_name", help="Status that you want to change")
parser.add_argument('-v', '--value', type=str, dest="target_value", help="Change status to the given value")
args = parser.parse_args()

if os.path.isfile("credentials.cfg") is False:
print("credentials not found - please rename credentials.cfg.dist to credentials.cfg and adapt the settings.")
exit(1)

# read credentials from config files
config = configparser.ConfigParser()
config.read(args.configpath)
config.sections()

# setup link to vimar web server
vimarconnection = VimarLink(
config['webserver']['schema'],
config['webserver']['host'],
int(config['webserver']['port']),
config['webserver']['username'],
config['webserver']['password'],
config['webserver']['certificate'],
int(config['webserver']['timeout']))

# if certificate is not available, download it
if os.path.isfile(config['webserver']['certificate']) is False:
vimarconnection.install_certificate()

# initialize project
vimarproject = VimarProject(vimarconnection)

# try to login
try:
valid_login = vimarconnection.check_login()
except BaseException as err:
print("Login Exception: %s" % err)
valid_login = False
if (not valid_login):
print("Login failed")
exit(1)

# load all devices and device status
vimarproject.update()

# check all available platforms
if args.platform is None:
for device_type, platform in AVAILABLE_PLATFORMS.items():
device_count = vimarproject.platform_exists(device_type)
if device_count:
print("found platform %s with %d %s" % (platform, device_count, device_type))
exit(0)

# get all devices
devices = vimarproject.get_by_device_type(args.platform)

if not devices:
print("No devices found for platform:", args.platform)
exit(1)

# list all available devices for given platform
if not args.device_id:
# list all lights and their status
for device_id, device in devices.items():
print(device_id, "-", device["object_name"], "available status:", list(device["status"].keys()))
exit(0)

# show single device
if args.device_id:
args.device_id = str(args.device_id)
# if the default device_id is not available turn on the first found light
if args.device_id not in devices:
print("No device found with id:", args.device_id, "in platform", args.platform)
exit(1)

statusdict = devices.get(args.device_id)["status"]
print(args.device_id, "-", devices.get(args.device_id)["object_name"], "available status:", [key + ": " + value['status_value'] for key, value in statusdict.items()])

if args.status_name:
if args.status_name not in devices[args.device_id]["status"]:
print("given device does not support '", args.status_name, "' status")
exit(1)

optionals = vimarconnection.get_optionals_param(args.status_name)

if args.target_value:
print("Setting", args.status_name, "to", args.target_value)
vimarconnection.set_device_status(statusdict[args.status_name]["status_id"], args.target_value, optionals)


if __name__ == "__main__":
main()

0 comments on commit f1baf02

Please sign in to comment.