File: wifispeaker.py

package info (click to toggle)
python-miio 0.5.12-4
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid
  • size: 1,888 kB
  • sloc: python: 23,425; makefile: 9
file content (166 lines) | stat: -rw-r--r-- 4,946 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
import enum
import logging

import click

from .click_common import command, format_output
from .device import Device, DeviceStatus

_LOGGER = logging.getLogger(__name__)


class PlayState(enum.Enum):
    Playing = "PLAYING"
    Stopped = "STOPPED"
    Paused = "PAUSED_PLAYBACK"
    NoMedia = "NO_MEDIA_PRESENT"
    Transitioning = "TRANSITIONING"


class TransportChannel(enum.Enum):
    Playlist = "PLAYLIST"
    OneTime = "ONETIME"
    Auxiliary = "AUX"
    Bluetooth = "BT"
    Radio = "RADIO"
    Air = "AIR"
    Qplay = "QPLAY"


class WifiSpeakerStatus(DeviceStatus):
    """Container of a speaker state.

    This contains information such as the name of the device, and what is currently
    being played by it.
    """

    def __init__(self, data):
        """Example response of a xiaomi.wifispeaker.v2:

        {"DeviceName": "Mi Internet Speaker", "channel_title\": "XXX",
         "current_state": "PLAYING", "hardware_version": "S602",
         "play_mode": "REPEAT_ALL", "track_artist": "XXX",
         "track_duration": "00:04:58", "track_title": "XXX",
         "transport_channel": "PLAYLIST"}
        """
        self.data = data

    @property
    def device_name(self) -> str:
        """Name of the device."""
        return self.data["DeviceName"]

    @property
    def channel(self) -> str:
        """Name of the channel."""
        return self.data["channel_title"]

    @property
    def state(self) -> PlayState:
        """State of the device, e.g. PLAYING."""
        return PlayState(self.data["current_state"])

    @property
    def hardware_version(self) -> str:
        return self.data["hardware_version"]

    @property
    def play_mode(self):
        """Play mode such as REPEAT_ALL."""
        # note: this can be enumized when all values are known
        return self.data["play_mode"]

    @property
    def track_artist(self) -> str:
        """Artist of the current track."""
        return self.data["track_artist"]

    @property
    def track_title(self) -> str:
        """Title of the current track."""
        return self.data["track_title"]

    @property
    def track_duration(self) -> str:
        """Total duration of the current track."""
        return self.data["track_duration"]

    @property
    def transport_channel(self) -> TransportChannel:
        """Transport channel, e.g. PLAYLIST."""
        return TransportChannel(self.data["transport_channel"])


class WifiSpeaker(Device):
    """Device class for Xiaomi Smart Wifi Speaker."""

    _supported_models = ["xiaomi.wifispeaker.v2"]

    @command(
        default_output=format_output(
            "",
            "Device name: {result.device_name}\n"
            "Channel: {result.channel}\n"
            "State: {result.state}\n"
            "Play mode: {result.play_mode}\n"
            "Track artist: {result.track_artist}\n"
            "Track title: {result.track_title}\n"
            "Track duration: {result.track_duration}\n"
            "Transport channel: {result.transport_channel}\n"
            "Hardware version: {result.hardware_version}\n",
        )
    )
    def status(self) -> WifiSpeakerStatus:
        """Return device status."""
        return WifiSpeakerStatus(self.send("get_prop", ["umi"]))

    @command(default_output=format_output("Powering on"))
    def power(self):
        """Toggle power on and off."""
        # is this a toggle?
        return self.send("power")

    @command(default_output=format_output("Toggling play"))
    def toggle(self):
        """Toggle play."""
        return self.send("toggle")

    @command(
        click.argument("amount", type=int),
        default_output=format_output("Increasing volume by {amount} percent"),
    )
    def volume_up(self, amount: int = 5):
        """Set volume up."""
        return self.send("vol_up", [amount])

    @command(
        click.argument("amount", type=int),
        default_output=format_output("Decreasing volume by {amount} percent"),
    )
    def volume_down(self, amount: int = 5):
        """Set volume down."""
        return self.send("vol_down", [amount])

    @command(default_output=format_output("Playing previous track"))
    def track_previous(self):
        """Move to previous track."""
        return self.send("previous_track")

    @command(default_output=format_output("Playing next track"))
    def track_next(self):
        """Move to next track."""
        return self.send("next_track")

    @command(default_output=format_output("Switching to the next transport channel"))
    def channel_next(self):
        """Change transport channel."""
        return self.send("next_channel")

    @command(default_output=format_output("Track position: {result.rel_time}"))
    def track_position(self):
        """Return current track position."""
        return self.send("get_prop", ["rel_time"])

    def volume(self):
        """Speaker volume."""
        return self.send("get_prop", ["volume"])