diff --git a/examples/configs/example_keymap.yml b/examples/configs/example_keymap.yml index ed4a621..30f26c7 100644 --- a/examples/configs/example_keymap.yml +++ b/examples/configs/example_keymap.yml @@ -1,3 +1,25 @@ +#!/usr/bin/env python3 +#** ***************************************************************************** +# * +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2023 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# * +#* ****************************************************************************** # Remote Commander Key Translation Maps remoteMaps: @@ -56,8 +78,7 @@ remoteMaps: HELP: "HELP" HOME: "HOME" INFO: "INFO" - INPUT_DOWN: "INPUT_DOWN" - INPUT_UP: "INPUT_UP" + INTERACTIVE: "INTERACTIVE" INTERNET: "INTERNET" INTERNET_RADIO: "INTERNET_RADIO" LAST: "LAST" @@ -83,6 +104,7 @@ remoteMaps: NUM_7: "NUM_7" NUM_8: "NUM_8" NUM_9: "NUM_9" + OPEN: "OPEN" OPTIONS: "OPTIONS" PAGE_DOWN: "PAGE_DOWN" PAGE_UP: "PAGE_UP" @@ -115,7 +137,10 @@ remoteMaps: RS232: "RS232" RESET: "RESET" SEARCH: "SEARCH" + SEARCH_BACK: "SEARCH_BACK" + SEARCH_FWD: "SEARCH_FWD" SELECT: "SELECT" + SERVICES: "SERVICES" SETUP: "SETUP" SKY: "SKY" SOURCE: "SOURCE" @@ -128,8 +153,6 @@ remoteMaps: TEST: "TEST" TEXT: "TEXT" TOOLS: "TOOLS" - TUNING_LEFT: "TUNING_LEFT" - TUNING_RIGHT: "TUNING_RIGHT" USB: "USB" VGA: "VGA" VIRGIN: "VIRGIN" diff --git a/examples/configs/example_rack_config.yml b/examples/configs/example_rack_config.yml index eb9b2a0..8add0bf 100644 --- a/examples/configs/example_rack_config.yml +++ b/examples/configs/example_rack_config.yml @@ -73,6 +73,7 @@ rackConfig: # [ type: "None" ] # To use keySimulator RDK Middleware is required # [ type: "keySimulator", ip: "192.168.50.99", port: 10022, username: "root", password: '', map: "keysimulator_rdk", config: "rdk_keymap.yml" ] + # [ type: "redrat", hub_ip: "192.168.0.1" hub_port: 10022, netbox_ip(optional): 192.168.0.2, netbox_name(optional): "IRNetBox IV 21089", netbox_mac(optional): "70-B3-D5-fd-10-10" output(optional, default=1): "10", map: 'SKY+', config: "example_redrat_keymap.yml"] # [ outbound: optional ] - This section is used to configure paths for downloads and uploads from your test # supported usage: diff --git a/examples/configs/example_redrat_keymap.yml b/examples/configs/example_redrat_keymap.yml new file mode 100644 index 0000000..46ad537 --- /dev/null +++ b/examples/configs/example_redrat_keymap.yml @@ -0,0 +1,331 @@ +#** ***************************************************************************** +# * +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2023 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# * +#* ****************************************************************************** +# Remote Commander Key Translation Maps + +remoteMaps: + remoteCommanderMap0: + name : 'XfinityXR2' + prefix: 'dataset="XfinityXR2" ' + codes: + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + BLUE: 'signal="Blue"' + CHANNEL_UP: 'signal="Chan+"' + CHANNEL_DOWN: 'signal="Chan-"' + ARROW_DOWN: 'signal="Down"' + EXIT: 'signal="Exit"' + FFORWARD: 'signal="FF"' + GREEN: 'signal="Green"' + GUIDE: 'signal="Guide"' + INFO: 'signal="Info"' + LAST: 'signal="Last"' + ARROW_LEFT: 'signal="Left"' + MUTE: 'signal="Mute"' + SELECT: 'signal="OK"' + PAGE_DOWN: 'signal="PageDown"' + PAGE_UP: 'signal="PageUp"' + PLAY: 'signal="Play-Pause"' + POWER: 'signal="Power"' + RECORD: 'signal="Record"' + RED: 'signal="Red"' + REPLAY: 'signal="Replay"' + REWIND: 'signal="Rew"' + ARROW_RIGHT: 'signal="Right"' + ARROW_UP: 'signal="Up"' + VOL_UP: 'signal="Vol+"' + VOL_DOWN: 'signal="Vol-"' + XFINITY: 'signal="xfinity"' + YELLOW: 'signal="Yellow"' + + remoteCommanderMap1: + name: 'Panasonic' + prefix: 'dataset="Panasonic" ' + codes: + ARROW_DOWN: 'signal="Down"' + SELECT: 'signal="OK"' + CHANNEL_UP: 'signal="Program+"' + CHANNEL_DOWN: 'signal="Program-"' + ARROW_UP: 'signal="Up"' + + remoteCommanderMap2: + name: 'Sky Digibox' + prefix: 'dataset="Sky Digibox" ' + codes: + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + BACK: 'signal="Backup' + BLUE: 'signal="Blue"' + CHANNEL_UP: 'signal="Chan+"' + CHANNEL_DOWN: 'signal="Chan-"' + ARROW_DOWN: 'signal="Down"' + GREEN: 'signal="Green"' + HELP: 'signal="Help"' + INFO: 'signal="i"' + INTERACTIVE: 'signal="Interactive' + ARROW_LEFT: 'signal="Left"' + MUTE: 'signal="Mute"' + POWER: 'signal="Power"' + RED: 'signal="Red"' + ARROW_RIGHT: 'signal="Right"' + SELECT: 'signal="Select"' + SERVICES: 'signal="Services"' + SKY: 'signal="SKY"' + TEXT: 'signal="Text"' + SOURCE: 'signal="TV"' + GUIDE: 'signal="TV_GUIDE"' + ARROW_UP: 'signal="Up"' + VOL_UP: 'signal="Vol+"' + VOL_DOWN: 'signal="Vol-"' + YELLOW: 'signal="Yellow"' + + remoteCommanderMap3: + name: 'Hauppauge' + prefix: 'dataset="Hauppauge" ' + codes: + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + + remoteCommanderMap4: + name: 'CD' + prefix: 'dataset="CD"' + codes: + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + OPEN: 'signal="Open"' + PAUSE: 'signal="Pause"' + PLAY: 'signal="Play"' + SEARCH_FWD: 'signal="Search+"' + SEARCH_BACK: 'signal="Search-"' + FFORWARD: 'signal="Skip+"' + REWIND: 'signal="Skip-"' + STOP: 'signal="Stop"' + + remoteCommanderMap5: + name: 'Tuner' + prefix: 'dataset="Tuner" ' + codes: + CHANNEL_UP: 'signal="Channel+"' + CHANNEL_DOWN: 'signal="Channel+"' + + remoteCommanderMap6: + name: 'Sony_Sat' + prefix: 'dataset="Sony_Sat" ' + codes: + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + + remoteCommanderMap7: + name: 'BlaupunkTV' + prefix: 'dataset="BlaupunkTV" ' + codes: + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + BLUE: 'signal="Blue"' + CHANNEL_UP: 'signal="Chan+"' + CHANNEL_DOWN: 'signal="Chan-"' + ARROW_DOWN: 'signal="Down"' + EXIT: 'signal="Exit"' + GREEN: 'signal="Green"' + INFO: 'signal="Info"' + ARROW_LEFT: 'signal="Left"' + MENU: 'signal="Menu"' + SELECT: 'signal="OK"' + VOL_UP: 'signal="Vol+"' + VOL_DOWN: 'signal="Vol-"' + YELLOW: 'signal="Yellow"' + + remoteCommanderMap8: + name: 'eTRV' + prefix: 'dataset="eTRV" ' + codes: + NUM_2: 'signal="2"' + NUM_5: 'signal="5"' + NUM_8: 'signal="8"' + ARROW_DOWN: 'signal="DOWN"' + SELECT: 'signal="SET"' + ARROW_UP: 'signal="UP"' + + remoteCommanderMap9: + name: 'Sony Mini System' + prefix: 'dataset="Sony Mini System" ' + codes: + PAUSE: 'signal="Pause"' + PLAY: 'signal="Play"' + + remoteCommanderMap10: + name: 'Extigy' + prefix: 'dataset="Extigy" ' + codes: + ARROW_DOWN: 'signal="Down"' + POWER: 'signal="Power"' + ARROW_UP: 'signal="Up"' + VOL_UP: 'signal="Vol+"' + VOL_DOWN: 'signal="Vol-"' + + remoteCommanderMap11: + name: 'SKY+' + prefix: 'dataset="SKY+" ' + codes: + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + BACK: 'signal="Backup"' + BLUE: 'signal="Blue"' + MOVIE: 'signal="Box_office"' + CHANNEL_UP: 'signal="Channel+"' + CHANNEL_DOWN: 'signal="Channel+"' + ARROW_DOWN: 'signal="Down"' + FFORWARD: 'signal="FFwd"' + GREEN: 'signal="Green"' + HELP: 'signal="Help"' + INFO: 'signal="Info"' + INTERACTIVE: 'signal="Interactive"' + ARROW_LEFT: 'signal="Left"' + MUTE: 'signal="Mute"' + PAUSE: 'signal="Pause"' + PLAY: 'signal="Play"' + POWER: 'signal="Power"' + RECORD: 'signal="Record"' + RED: 'signal="Red"' + REWIND: 'signal="Rew"' + ARROW_RIGHT: 'signal="Right"' + SELECT: 'signal="Select"' + SERVICES: 'signal="Services"' + SKY: 'signal="SKY"' + STOP: 'signal="Stop"' + TEXT: 'signal="Text"' + SOURCE: 'signal="TV"' + GUIDE: 'signal="TV_Guide"' + ARROW_UP: 'signal="Up"' + VOL_UP: 'signal="Vol +"' + VOL_DOWN: 'signal="Vol -"' + YELLOW: 'signal="Yellow"' + + remoteCommanderMap12: + name : 'Xione' + prefix: 'dataset="Xione" ' + codes: + ARROW_DOWN: 'signal="Arrow_down"' + ARROW_LEFT: 'signal="Arrow_left"' + ARROW_RIGHT: 'signal="Arrow_right"' + ARROW_UP: 'signal="Arrow_up"' + BACK: 'signal="Back"' + CI_PLUS: 'signal="Plus"' + DISPLAY: 'signal="Play"' + ELLIPSIS: 'signal="Ellipses"' + HOME: 'signal="Home"' + MIC: 'signal="Mic"' + MUTE: 'signal="Mute"' + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + PLAY: 'signal="Play"' + POWER: 'signal="Power"' + RGYB: 'signal="Coloured_dots"' + SELECT: 'signal="Select"' + + remoteCommanderMap13: + name : 'Element' + prefix: 'dataset="Element" ' + codes: + ARROW_DOWN: 'signal="Arrow_down"' + ARROW_LEFT: 'signal="Arrow_left"' + ARROW_RIGHT: 'signal="Arrow_right"' + ARROW_UP: 'signal="Arrow_up"' + BACK: 'signal="Back"' + CI_PLUS: 'signal="Plus"' + DISNEY: 'signal="Disney+"' + ELLIPSIS: 'signal="Ellipses"' + HOME: 'signal="Home"' + MIC: 'signal="Mic"' + MUTE: 'signal="Mute"' + NETFLIX: 'signal="Netflix"' + NUM_0: 'signal="0"' + NUM_1: 'signal="1"' + NUM_2: 'signal="2"' + NUM_3: 'signal="3"' + NUM_4: 'signal="4"' + NUM_5: 'signal="5"' + NUM_6: 'signal="6"' + NUM_7: 'signal="7"' + NUM_8: 'signal="8"' + NUM_9: 'signal="9"' + PEACOCK: 'signal="Peacock"' + POWER: 'signal="Power"' + PRIME_VIDEO: 'signal="Prime"' + SELECT: 'signal="Select"' + SETUP: 'signal="Settings"' + SOURCE: 'signal="Input"' + VOL_DOWN: 'signal="Vol-"' + VOL_UP: 'signal="Vol+"' \ No newline at end of file diff --git a/framework/core/commonRemote.py b/framework/core/commonRemote.py index ef87447..967d13c 100644 --- a/framework/core/commonRemote.py +++ b/framework/core/commonRemote.py @@ -34,11 +34,12 @@ import os from framework.core.logModule import logModule from framework.core.rcCodes import rcCode as rc -from framework.core.remoteControllerModules.olimex import remoteOlimex -from framework.core.remoteControllerModules.skyProc import remoteSkyProc -from framework.core.remoteControllerModules.arduino import remoteArduino -from framework.core.remoteControllerModules.none import remoteNone -from framework.core.remoteControllerModules.keySimulator import remoteKeySimulator +from framework.core.remoteControllerModules import remoteArduino, \ + remoteKeySimulator, \ + remoteNone, \ + remoteOlimex, \ + remoteRedRat, \ + remoteSkyProc class remoteControllerMapping(): def __init__(self, log:logModule, mappingConfig:dict): @@ -137,6 +138,8 @@ def __init__(self, log:logModule, remoteConfig:dict, **kwargs:dict): self.remoteController = remoteArduino (self.log, remoteConfig) elif self.type == "keySimulator": self.remoteController = remoteKeySimulator (self.log, remoteConfig) + elif self.type == "redrat": + self.remoteController = remoteRedRat(self.log, remoteConfig) else: # remoteNone otherwise self.remoteController = remoteNone( self.log, remoteConfig ) diff --git a/framework/core/rcCodes.py b/framework/core/rcCodes.py index 65ff247..4ec5eaa 100644 --- a/framework/core/rcCodes.py +++ b/framework/core/rcCodes.py @@ -87,6 +87,7 @@ class rcCode(Enum): HELP = "HELP" HOME = "HOME" INFO = "INFO" + INTERACTIVE = "INTERACTIVE" INTERNET = "INTERNET" INTERNET_RADIO = "INTERNET_RADIO" LAST = "LAST" @@ -113,6 +114,7 @@ class rcCode(Enum): NUM_7 = "NUM_7" NUM_8 = "NUM_8" NUM_9 = "NUM_9" + OPEN = "OPEN" OPTIONS = "OPTIONS" PAGE_DOWN = "PAGE_DOWN" PAGE_UP = "PAGE_UP" @@ -150,6 +152,7 @@ class rcCode(Enum): SEARCH_BACK = "SEARCH_BACK" SEARCH_FWD = "SEARCH_FWD" SELECT = "SELECT" + SERVICES = "SERVICES" SETUP = "SETUP" SKY = "SKY" SOURCE = "SOURCE" diff --git a/framework/core/remoteControllerModules/__init__.py b/framework/core/remoteControllerModules/__init__.py new file mode 100644 index 0000000..dfb6112 --- /dev/null +++ b/framework/core/remoteControllerModules/__init__.py @@ -0,0 +1,28 @@ +#!/usr/bin/env python3 +#** ***************************************************************************** +# * +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2023 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# * +#* ****************************************************************************** +from .arduino import remoteArduino +from .keySimulator import remoteKeySimulator +from .none import remoteNone +from .olimex import remoteOlimex +from .redrat import remoteRedRat +from .skyProc import remoteSkyProc \ No newline at end of file diff --git a/framework/core/remoteControllerModules/redrat.py b/framework/core/remoteControllerModules/redrat.py new file mode 100644 index 0000000..a38e252 --- /dev/null +++ b/framework/core/remoteControllerModules/redrat.py @@ -0,0 +1,125 @@ +#!/usr/bin/env python3 +#** ***************************************************************************** +# * +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2023 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# * +#* ****************************************************************************** +#* +#* ** Project : RAFT +#* ** @addtogroup : core.remoteControllerModules +#* ** @date : 22/11/2021 +#* ** +#* ** @brief : remote Redrat +#* ** +#* ****************************************************************************** + +import socket +import time + +from framework.core.logModule import logModule +from .remoteInterface import RemoteInterface + +class HubClient(): + + def __init__(self): + self._socket = socket.socket() + self._is_open = False + + def __del__(self): + self.stop() + + def start(self, hub_ip: str, hub_port: int = 40000, netbox_id: None|str=None): + """Start a socket connection to the RedRat Hub on the given IP and port. + If the netbox ID s is given, it will check that it's available on the hub. + + Args: + hub_ip (str): IP address of the RedRat Hub server. + hub_port (int, optional): Socket port of the RedRat Hub server. Defaults to 40000. + netbox_id (None | str, optional): ID (name, IP address or Mac) of the IR Netbox expected + to be connected to the RedRat Hub server. Defaults to None. + + Raises: + ConnectionError: If IR Netbox IP address isn't found on the RedRat Hub. + This will also occur if the hub address/port is not actually a + RedRat Hub socker server. + """ + self._socket.settimeout(0.5) + self._socket.connect((hub_ip, hub_port)) + if netbox_ip is not None: + response = self.send_message('hubquery="list redrats"') + netbox_on_hub = list(filter(lambda x: netbox_ip in x, response.splitlines())) + if len(netbox_on_hub) <= 0: + raise ConnectionError('Could not connect to RedRat Hub. It may be misconfigured.') + + self._is_open = True + + def stop(self): + if self._is_open: + self._socket.close() + self._is_open = False + + def send_message(self, message: str) -> str: + """Send a message to the RedRatHub via the socket + + Args: + message (str): The message to send. + + Returns: + str: The response from the socket. + """ + self._socket.send(f'{message}\n'.encode()) + response = '' + while True: + try: + response += self._socket.recv(64).decode() + except TimeoutError: + break + return response + +class remoteRedRat(RemoteInterface): + + def __init__(self, log: logModule, config: dict): + super().__init__(log, config) + self._hub_ip = config.get('hub_ip') + self._hub_port = config.get('hub_port',5248) + self._client = HubClient() + if id:=config.get('netbox_ip',None): + self._netbox_id = id + self._netbox_id_type = 'ip' + elif id:= config.get('netbox_mac',None): + self._netbox_id = id + self._netbox_id_type = 'mac' + elif id:=config.get('netbox_name',None): + self._netbox_id = id + self._netbox_id_type = 'name' + if None in (self._hub_ip, self._netbox_id): + raise AttributeError('hub_id and either netbox_ip, netbox_name or netbox_mac are required') + self._client.start(self._hub_ip, hub_port=self._hub_port, netbox_id=self._netbox_id) + self._output = config.get('output', 1) + + def sendKey(self, code, repeat, delay): + msg = f'{self._netbox_id_type}="{self._netbox_id}" {code} output="{self._output}"' + for _ in range(repeat): + if 'OK' not in self._client.send_message(msg): + self.log.error("sendKey(), Command [{}] failed.".format( code ) ) + return False + time.sleep( delay ) + return True + + diff --git a/framework/core/remoteControllerModules/remoteInterface.py b/framework/core/remoteControllerModules/remoteInterface.py new file mode 100644 index 0000000..7d32978 --- /dev/null +++ b/framework/core/remoteControllerModules/remoteInterface.py @@ -0,0 +1,58 @@ +#!/usr/bin/env python3 +#** ***************************************************************************** +# * +# * If not stated otherwise in this file or this component's LICENSE file the +# * following copyright and licenses apply: +# * +# * Copyright 2023 RDK Management +# * +# * Licensed under the Apache License, Version 2.0 (the "License"); +# * you may not use this file except in compliance with the License. +# * You may obtain a copy of the License at +# * +# * +# http://www.apache.org/licenses/LICENSE-2.0 +# * +# * Unless required by applicable law or agreed to in writing, software +# * distributed under the License is distributed on an "AS IS" BASIS, +# * WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. +# * See the License for the specific language governing permissions and +# * limitations under the License. +# * +#* ****************************************************************************** +#* +#* ** Project : RAFT +#* ** @addtogroup : core.remoteControllerModules +#* ** @date : 22/11/2021 +#* ** +#* ** @brief : remote Interface +#* +#* ****************************************************************************** +from abc import abstractmethod +from framework.core.logModule import logModule + +class RemoteInterface(): + + def __init__( self, log:logModule, remoteConfig:dict): + """Initalise a remoteNone class + + Args: + log (logModule): logging module + remoteConfig (dict): remote controller configuration + """ + self.log = log + self._config = remoteConfig + + @abstractmethod + def sendKey(self, code:str, repeat:int, delay:int ): + """Send a key + + Args: + code (str): keycode + repeat (int): number of repeats required + delay (int): delay in seconds between repeats + + Returns: + bool: true on success otherwise failure + """ + pass \ No newline at end of file