Core Framework: Common Remote - rdkcentral/python_raft GitHub Wiki
Common Remote Module
This document describes the commonRemote
module, a Python module designed to provide a consistent interface for interacting with various remote control devices. It abstracts away the low-level details of different remote technologies, allowing you to write test scripts that work seamlessly with different remote types.
Key Features
- Remote Control Abstraction: Offers a unified way to send commands to different types of remotes, such as Olimex, SkyProc, and Arduino.
- Key Mapping: Translates standardized key names used in test scripts to the specific key codes required by each remote.
- Configuration-Driven: Remote type and key map are defined in a configuration file for easy switching and customization.
Classes
remoteControllerMapping
- Purpose: Manages the translation of standard key names (e.g., "POWER", "VOLUME_UP") to the corresponding key codes for the currently active remote.
- Key Methods:
getMappedKey(key)
: Returns the mapped key code for the given standard key name.getKeyMap()
: Returns the currently active key map.setKeyMap(newMapName)
: Switches to a different key map.
commonRemoteClass
- Purpose: The primary interface for interacting with remote control devices. It encapsulates the
remoteControllerMapping
class and handles communication with the specific remote implementation. - Key Methods:
sendKey(keycode, delay=1, repeat=1, randomRepeat=0)
:- Translates the
keycode
using the active key map. - Sends the translated key code to the remote.
- Optionally adds delays and repeats.
- Translates the
setKeyMap(name)
: Switches to the specified key map.getKeyMap()
: Returns the currently active key map.
Configuring the Remote Control Class
The remote control interface is configured from the main framework wide config.yaml
using the subsection YAML snippet:
remoteController:
# [ type: "olimex" ip: "192.168.0.17" port: 7 map: "rc6"]
# [ type: "skyProc" map: "skyq_map" ]
# [ type: "arduino" map: "arduino" port: 'COM8' baudrate: 9600]
# [ type: "None" ]
type: "olimex"
map: "xmp_a"
port: 7
ip: "192.168.0.103"
config: "commander_maps.yaml"
This configuration specifies that:
type: "olimex"
: An Olimex remote control device is used for sending commands.map: "xmp_a"
: The key map named "xmp_a" will be used to translate standardized key names to the specific codes required by the Olimex remote. This map should be defined as per the Key Mapping Metchanism below.port: 7
: The port number used to communicate with the Olimex device.ip: "192.168.0.103"
: The IP address of the Olimex remote control device.config
: "commander_maps.yaml": This explicitly specifies the YAML file that contains the definitions of the key maps.
Supported Remote Types
The commonRemote
module supports the following remote control types:
olimex
: For Olimex remote control devices. Requiresip
andport
in the configuration.skyProc
: For SkyProc remote control devices.arduino
: For Arduino based remote control solutions. Requiresport
andbaudrate
in the configuration.None
: For simulating remote control actions or using alternative control mechanisms.
Key Mapping Mechanism
-
Remote Configuration: A configuration file (
remoteConfig
) defines thetype
of remote and themap
to use. -
Key Map Files: YAML files (e.g.,
olimex_map.yml
) store the key mappings for each remote type:- name: "MyOlimexMap" prefix: "OLIMEX_" # Optional prefix for translated keys codes: UP: "0x20" DOWN: "0x21" POWER: "0x0C"
-
Key Translation: When
sendKey(rc.POWER)
is called:- The
commonRemoteClass
retrieves the active key map. - It looks up enum "rc.POWER" in the map and finds its corresponding code (e.g., "0x0C").
- If a prefix is defined (e.g., "OLIMEX_"), it's added to the code.
- The final command (e.g., "OLIMEX_0x0C") is sent to the remote device.
- The
Usage Example
from framework.core.webpageModules.commonRemote import commonRemoteClass
# ... your test setup ...
my_remote = commonRemoteClass(my_logger, remote_config) # Initialize with remote configuration
# Send the "OK" key (which might be mapped to "ENTER" on the remote)
my_remote.setKeyMap("rc6")
my_remote.sendKey(rc.ENTER)
# Switch to a different remote
my_remote.setKeyMap("tpv")
my_remote.sendKey(rc.ENTER)
Benefits
- Simplified Test Scripts: Test scripts remain independent of specific remote control implementations.
- Maintainability: Key mappings are centralized in configuration files, making updates and modifications easier.
- Flexibility: Supports various remote types and allows for custom key mappings.
Key Map Files
Key map files are YAML files that define the mapping between enum test key names and remote-specific key codes. Each file can contain multiple key maps, each with a unique name.
Example olimex_map.yml
:
remoteMaps:
remoteCommanderMap0:
name: "MyOlimexMap"
prefix: "OLIMEX_" # Optional prefix for translated keys
codes:
UP: "0x20"
DOWN: "0x21"
POWER: "0x0C"
SELECT: "select"
Example multi remote commander maps
remoteMaps:
remoteCommanderMap0:
name : "rc6"
prefix: "RC6="
codes:
#-------------PORTABLE:--------------
NUM_0 : "0"
NUM_1 : "1"
NUM_2 : "2"
NUM_3 : "3"
NUM_4 : "4"
NUM_5 : "5"
NUM_6 : "6"
NUM_7 : "7"
NUM_8 : "8"
NUM_9 : "9"
# PREVPROG = "0x0A" # No action
POWER : "OnOff"
MUTE : "Mute"
VOL_UP : "VolUp"
VOL_DOWN : "VolDown"
PAUSE : "Pause"
DOWN : "NavDown"
LEFT : "NavLeft"
RIGHT : "NavRight"
SELECT : "NavEnter"
HOME : "Home"
#---------NON-PORTABLE:--------------
BACK : "Back"
CROSS : "Cross"
MIC : "Mic"
RGYB : "Rgyb"
MENU : "Menu"
PICK_UP : "PickUp"
EXIT: "Back"
EXIT_WAIT: "Back DURATION=5000 COR0=10 COR1=-5"
#------------------------------------
remoteCommanderMap1:
name : "tpv"
prefix: "TPV="
codes:
#-------------PORTABLE:--------------
NUM_0 : "0"
NUM_1 : "1"
NUM_2 : "2"
NUM_3 : "3"
NUM_4 : "4"
NUM_5 : "5"
NUM_6 : "6"
NUM_7 : "7"
NUM_8 : "8"
NUM_9 : "9"
MUTE : "Mute"
CHANNEL_UP : "Ch+"
CHANNEL_DOWN : "Ch-"
UP : "NavUp"
DOWN : "NavDown"
LEFT : "NavLeft"
RIGHT : "NavRight"
SELECT : "NavEnter"
#---------NON-PORTABLE:--------------
TEST : "Test"
RST : "Rst"
FAC : "Fac"
CSM : "Csm"
PATTERN : "Pattern"
ANTENNA_CABLE : "AntennaCable"
PRE_CH : "PreCh"
VOL_MAX : "VolMax"
CTC : "Ctc"
VOL_BUZZ : "VolBuzz"
MENU : "Menu"
BI : "BI"
CH_SCAN : "ChScan"
CCTT : "Cctt"
PIC : "Pic"
LOG_LED : "LogLed"
AUDIO : "Audio"
D2D3 : "D2D3"
ARC : "Arc"
CIP : "Ci+"
VIRGIN : "Virgin"
CVBS : "Cvbs"
YPBPR_SCART : "YpbprScart"
HDMI : "Hdmi"
VGA : "Vga"
REGIN : "Regin"
CLONE : "Clone"
RESERVE1 : "Reserve1"
DCR : "Dcr"
WIFI_SSID : "WifiSsid"
BLK : "Blk"
WP : "Wp"
LIGHT_SENSOR : "LightSensor"
USB : "Usb"
RJ45 : "Rj45"
RS232 : "Rs232"
RESERVE2 : "Reserve2"
EXIT_WAIT: "Back DURATION=5000 COR0=10 COR1=-5"
#------------------------------------
remoteCommanderMap2:
name: "xmp_d" # Works with XR100)
prefix: "XMP_d="
codes:
POWER: "OnOff"
HOME: "Home"
CROSS: "Cross"
MENU: "Menu" # ... on remote
UP: "NavUp"
DOWN: "NavDown"
RIGHT: "NavRight"
LEFT: "NavLeft"
SELECT: "NavEnter"
BACK: "Back"
EXIT: "Back"
NUM_1: "1"
NUM_2: "2"
NUM_3: "3"
NUM_4: "4"
NUM_5: "5"
NUM_6: "6"
NUM_7: "7"
NUM_8: "8"
NUM_9: "9"
NUM_0: "0"
INPUT : "Input"
OPTIONS : "Options"
EXIT_WAIT: "Back DURATION=5000 COR0=10 COR1=-5"
INPUT_HOLD : "Input DURATION=2000 COR0=10 COR1=-5"
remoteCommanderMap3:
name: "xmp_e"
prefix: "XMP_e="
codes:
POWER: "OnOff"
HOME: "Home"
CROSS: "Cross"
MENU: "Menu" # ... on remote
UP: "NavUp"
DOWN: "NavDown"
RIGHT: "NavRight"
LEFT: "NavLeft"
SELECT: "NavEnter"
BACK: "Back"
EXIT: "Back"
NETFLIX: "Netflix"
PRIME_VIDEO: "PrimeVideo"
PEACOCK: "Peacock"
DISNEY: "Disney"
NUM_1: "1"
NUM_2: "2"
NUM_3: "3"
NUM_4: "4"
NUM_5: "5"
NUM_6: "6"
NUM_7: "7"
NUM_8: "8"
NUM_9: "9"
NUM_0: "0"
INPUT : "Input"
OPTIONS : "Options"
EXIT_WAIT: "Back DURATION=5000 COR0=10 COR1=-5"
INPUT_HOLD : "Input DURATION=2000 COR0=10 COR1=-5"