1#!/usr/bin/env python3
2#
3#   Copyright 2016 - The Android Open Source Project
4#
5#   Licensed under the Apache License, Version 2.0 (the "License");
6#   you may not use this file except in compliance with the License.
7#   You may obtain a copy of the License at
8#
9#       http://www.apache.org/licenses/LICENSE-2.0
10#
11#   Unless required by applicable law or agreed to in writing, software
12#   distributed under the License is distributed on an "AS IS" BASIS,
13#   WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
14#   See the License for the specific language governing permissions and
15#   limitations under the License.
16
17from acts.controllers.relay_lib.errors import RelayConfigError
18from acts.controllers.relay_lib.relay import SynchronizeRelays
19from acts.controllers.relay_lib.relay_device import RelayDevice
20
21MISSING_RELAY_MSG = 'Relay config for %s device "%s" missing relay "%s".'
22
23
24class GenericRelayDevice(RelayDevice):
25    """A default, all-encompassing implementation of RelayDevice.
26
27    This class allows for quick access to getting relay switches through the
28    subscript ([]) operator. Note that it does not allow for re-assignment or
29    additions to the relays dictionary.
30    """
31
32    def __init__(self, config, relay_rig):
33        RelayDevice.__init__(self, config, relay_rig)
34
35    def _ensure_config_contains_relays(self, relay_names):
36        for relay_name in relay_names:
37            self._ensure_config_contains_relay(relay_name)
38
39    def _ensure_config_contains_relay(self, relay_name):
40        """Throws an error if the relay does not exist."""
41        if relay_name not in self.relays:
42            raise RelayConfigError(MISSING_RELAY_MSG % (self.__class__.__name__,
43                                                        self.name, relay_name))
44
45    def get_button_names(self):
46        """Returns the list of all button names."""
47        return list(self.relays.keys())
48
49    def setup(self):
50        """Sets all relays to their default state (off)."""
51        with SynchronizeRelays():
52            for relay in self.relays.values():
53                relay.set_no()
54
55    def clean_up(self):
56        """Sets all relays to their default state (off)."""
57        with SynchronizeRelays():
58            for relay in self.relays.values():
59                if relay.is_dirty():
60                    relay.set_no()
61
62    def press(self, button_name):
63        """Presses the button for a short period of time.
64
65        Args:
66            button_name: the name of the button to press.
67        """
68        self.relays[button_name].set_nc_for()
69
70    def hold_down(self, button_name):
71        """Holds down the button until release is called.
72
73        If the button is already being held, the state does not change.
74
75        Args:
76            button_name: the name of the button to hold down.
77        """
78        self.relays[button_name].set_nc()
79
80    def release(self, button_name):
81        """Releases the held down button with name 'button_name'.
82
83        If the button is already depressed, the state does not change.
84
85        Args:
86            button_name: the name of the button to release.
87        """
88        self.relays[button_name].set_no()
89