tellcore_tool (example)ΒΆ

The example below is an implementation of tdtool similar to the one included in the official Telldus Core distribution.

#!/usr/bin/env python
# Copyright (c) 2014 Erik Johansson <erik@ejohansson.se>
#
# This program is free software; you can redistribute it and/or
# modify it under the terms of the GNU General Public License as
# published by the Free Software Foundation; either version 3 of the
# License, or (at your option) any later version.
#
# This program is distributed in the hope that it will be useful, but
# WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
# General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program; if not, write to the Free Software
# Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307
# USA

import argparse
import sys
import time

import tellcore.telldus as td
import tellcore.constants as const

if sys.version_info < (3, 0):
    import tellcore.library as lib
    lib.Library.DECODE_STRINGS = False

def print_devices(devices):
    print("Number of devices: {}\n".format(len(devices)))
    print("{:<5s} {:<25s} {:<10s} {:<10s} {:<20s} {}".format(
            "ID", "NAME", "STATE", "PROTOCOL", "MODEL", "PARAMETERS"))
    for device in devices:
        cmd = device.last_sent_command(
            const.TELLSTICK_TURNON
            | const.TELLSTICK_TURNOFF
            | const.TELLSTICK_DIM)
        if cmd == const.TELLSTICK_TURNON:
            cmd_str = "ON"
        elif cmd == const.TELLSTICK_TURNOFF:
            cmd_str = "OFF"
        elif cmd == const.TELLSTICK_DIM:
            cmd_str = "DIMMED:{}".format(device.last_sent_value())
        else:
            cmd_str = "UNKNOWN:{}".format(cmd)
        params_str = ""
        for name, value in device.parameters().items():
            params_str += " {}:{}".format(name, value)
        print("{:<5d} {:<25s} {:<10s} {:<10s} {:<20s}{}".format(
                device.id, device.name, cmd_str,
                device.protocol, device.model, params_str))

def print_sensors(sensors):
    print("Number of sensors: {}\n".format(len(sensors)))
    print("{:<15s} {:<15s} {:<5s} {:<8s} {:<8s} {:<18s} {:<20s} {}".format(
            "PROTOCOL", "MODEL", "ID", "TEMP", "HUMIDITY", "RAIN", "WIND",
            "LAST UPDATED"))

    def format_value(sensor, datatype, formatter):
        if not sensor.has_value(datatype):
            return ("", None)
        value = sensor.value(datatype)
        return (formatter(value.value), value.datetime)

    for sensor in sensors:
        values = []
        values.append(format_value(sensor, const.TELLSTICK_TEMPERATURE,
                                   lambda x: "{} C".format(x)))
        values.append(format_value(sensor, const.TELLSTICK_HUMIDITY,
                                   lambda x: "{} %".format(x)))
        values.append(format_value(sensor, const.TELLSTICK_RAINRATE,
                                   lambda x: x + " mm/h "))
        values.append(format_value(sensor, const.TELLSTICK_RAINTOTAL,
                                   lambda x: x + " mm"))
        values.append(format_value(sensor, const.TELLSTICK_WINDDIRECTION,
                                   lambda x: ["N", "NNE", "NE", "ENE",
                                              "E", "ESE", "SE", "SSE",
                                              "S", "SSW", "SW", "WSW",
                                              "W", "WNW", "NW", "NNW"]
                                   [int(float(x) / 22.5)] + " "))
        values.append(format_value(sensor, const.TELLSTICK_WINDAVERAGE,
                                   lambda x: x + " m/s "))
        values.append(format_value(sensor, const.TELLSTICK_WINDGUST,
                                   lambda x: "({} m/s)".format(x)))

        # Get first valid timestamp
        timestamp = [v[1] for v in values if v[1] is not None][0]

        s = [v[0] for v in values]
        values_str = "{:<8s} {:<8s} ".format(s[0], s[1])
        values_str += "{:<18s} ".format(s[2] + s[3])
        values_str += "{:<20s} ".format(s[4] + s[5] + s[6])

        print("{:<15s} {:<15s} {:<5d} {}{}".format(
            sensor.protocol, sensor.model, sensor.id, values_str,
            timestamp))

def find_device(device, devices):
    for d in devices:
        if str(d.id) == device or d.name == device:
            return d
    print("Device '{}' not found".format(device))
    return None

parser = argparse.ArgumentParser(
    description='Telldus administration tool',
    epilog='DEVICE can be either device id or name')
group = parser.add_mutually_exclusive_group(required=True)

group.add_argument(
    '-l', '--list', action='store_true',
    help='List all configured devices and discovered sensors')
group.add_argument(
    '--list-devices', action='store_true',
    help='List all configured devices')
group.add_argument(
    '--list-sensors', action='store_true',
    help='List all discovered sensors')
group.add_argument(
    '--on', metavar='DEVICE', help='Turn on device')
group.add_argument(
    '--off', metavar='DEVICE', help='Turn off device')
group.add_argument(
    '--learn', metavar='DEVICE', help='Send learn command to device')
group.add_argument(
    '--remove', metavar='DEVICE', help='Remove device')

args = vars(parser.parse_args())

core = td.TelldusCore()

if args['list']:
    print_devices(core.devices())
    print("")
    print_sensors(core.sensors())
elif args['list_devices']:
    print_devices(core.devices())
elif args['list_sensors']:
    print_sensors(core.sensors())
elif args['on'] is not None:
    device = find_device(args['on'], core.devices())
    if device is not None:
        device.turn_on()
elif args['off'] is not None:
    device = find_device(args['off'], core.devices())
    if device is not None:
        device.turn_off()
elif args['learn'] is not None:
    device = find_device(args['learn'], core.devices())
    if device is not None:
        device.learn()
elif args['remove'] is not None:
    device = find_device(args['remove'], core.devices())
    if device is not None:
        device.remove()