Home-AssistantConfig/deps/nest/command_line.py
2016-10-11 16:42:06 +00:00

265 lines
8.7 KiB
Python

#! /usr/bin/python
# -*- coding:utf-8 -*-
'''
nest.py -- a python interface to the Nest Thermostats
'''
from __future__ import print_function
import argparse
import os
import sys
from . import nest
from . import utils
from . import helpers
def parse_args():
prog = os.path.basename(sys.argv[0])
config_file = os.path.sep.join(('~', '.config', prog, 'config'))
conf_parser = argparse.ArgumentParser(prog=prog, add_help=False)
conf_parser.add_argument('--conf', default=config_file,
help='config file (default %s)' % config_file,
metavar='FILE')
args, remaining_argv = conf_parser.parse_known_args()
defaults = helpers.get_config(config_path=args.conf)
description = 'Command line interface to Nest™ Thermostats'
parser = argparse.ArgumentParser(description=description,
parents=[conf_parser])
parser.set_defaults(**defaults)
parser.add_argument('--token-cache', dest='token_cache',
help='auth access token cache file',
metavar='TOKEN_CACHE_FILE')
parser.add_argument('-t', '--token', dest='token',
help='auth access token', metavar='TOKEN')
parser.add_argument('-u', '--user', dest='user',
help='username for nest.com', metavar='USER')
parser.add_argument('-p', '--password', dest='password',
help='password for nest.com', metavar='PASSWORD')
parser.add_argument('-c', '--celsius', dest='celsius', action='store_true',
help='use celsius instead of farenheit')
parser.add_argument('-s', '--serial', dest='serial',
help='optional, specify serial number of nest '
'thermostat to talk to')
parser.add_argument('-S', '--structure', dest='structure',
help='optional, specify structure name to'
'scope device actions')
parser.add_argument('-i', '--index', dest='index', default=0, type=int,
help='optional, specify index number of nest to '
'talk to')
subparsers = parser.add_subparsers(dest='command',
help='command help')
temp = subparsers.add_parser('temp', help='show/set temperature')
temp.add_argument('temperature', nargs='*', type=float,
help='target tempterature to set device to')
fan = subparsers.add_parser('fan', help='set fan "on" or "auto"')
fan_group = fan.add_mutually_exclusive_group()
fan_group.add_argument('--auto', action='store_true', default=False,
help='set fan to auto')
fan_group.add_argument('--on', action='store_true', default=False,
help='set fan to on')
mode = subparsers.add_parser('mode', help='show/set current mode')
mode_group = mode.add_mutually_exclusive_group()
mode_group.add_argument('--cool', action='store_true', default=False,
help='set mode to cool')
mode_group.add_argument('--heat', action='store_true', default=False,
help='set mode to heat')
mode_group.add_argument('--range', action='store_true', default=False,
help='set mode to range')
mode_group.add_argument('--off', action='store_true', default=False,
help='set mode to off')
away = subparsers.add_parser('away', help='show/set current away status')
away_group = away.add_mutually_exclusive_group()
away_group.add_argument('--away', action='store_true', default=False,
help='set away status to "away"')
away_group.add_argument('--home', action='store_true', default=False,
help='set away status to "home"')
subparsers.add_parser('target', help='show current temp target')
subparsers.add_parser('humid', help='show current humidity')
target_hum = subparsers.add_parser('target_hum',
help='show/set target humidty')
target_hum.add_argument('humidity', nargs='*',
help='specify target humidity value or auto '
'to auto-select a humidity based on outside '
'temp')
subparsers.add_parser('show', help='show everything')
return parser.parse_args()
def main():
args = parse_args()
def _identity(x):
return x
if args.celsius:
display_temp = _identity
convert_temp = _identity
else:
display_temp = utils.c_to_f
convert_temp = utils.f_to_c
cmd = args.command
token_cache = None
if args.token_cache:
token_cache = os.path.expanduser(args.token_cache)
# NOTE(jkoelker) Token caching is currently broken
token_cache = None
with nest.Nest(args.user, args.password, access_token=args.token,
access_token_cache_file=token_cache) as napi:
if cmd == 'away':
structure = None
if args.structure:
struct = [s for s in napi.structures
if s.name == args.structure]
if struct:
structure = struct[0]
else:
if args.serial:
serial = args.serial
else:
serial = napi.devices[args.index]._serial
struct = [s for s in napi.structures for d in s.devices
if d._serial == serial]
if struct:
structure = struct[0]
if not structure:
structure = napi.structures[0]
if args.away:
structure.away = True
elif args.home:
structure.away = False
print(structure.away)
return
if args.serial:
device = nest.Device(args.serial, napi)
elif args.structure:
struct = [s for s in napi.structures if s.name == args.structure]
if struct:
device = struct[0].devices[args.index]
else:
device = napi.structures[0].devices[args.index]
else:
device = napi.devices[args.index]
if cmd == 'temp':
if args.temperature:
if len(args.temperature) > 1:
if device.mode != 'range':
device.mode = 'range'
lower = convert_temp(args.temperature[0])
upper = convert_temp(args.temperature[1])
device.temperature = (lower, upper)
else:
temp = convert_temp(args.temperature[0])
device.temperature = temp
print('%0.1f' % display_temp(device.temperature))
elif cmd == 'fan':
if args.auto:
device.fan = False
elif args.on:
device.fan = True
print(device.fan)
elif cmd == 'mode':
if args.cool:
device.mode = 'cool'
elif args.heat:
device.mode = 'heat'
elif args.range:
device.mode = 'range'
elif args.off:
device.mode = 'off'
print(device.mode)
elif cmd == 'humid':
print(device.humidity)
elif cmd == 'target_hum':
if args.humidity:
device.target_humidity = args.humidity[0]
print(device.target_humidity)
elif cmd == 'target':
target = device.target
if isinstance(target, tuple):
print('Lower: %0.1f' % display_temp(target[0]))
print('Upper: %0.1f' % display_temp(target[1]))
else:
print('%0.1f' % display_temp(target))
elif cmd == 'show':
data = device._shared.copy()
data.update(device._device)
for k in sorted(data.keys()):
intag = any(intag in k for intag in ('temp', 'away',
'threshold'))
nottag = any(notag in k for notag in ('type', 'pin_hash',
'scale', 'enabled'))
if intag and not nottag:
try:
temp_data = '%0.1f' % display_temp(data[k])
print(k + '.'*(35-len(k)) + ':', temp_data)
except Exception:
print(k + '.'*(35-len(k)) + ':', data[k])
else:
print(k + '.'*(35-len(k)) + ':', data[k])
if __name__ == '__main__':
main()