Controlling MythTV from any phone using Asterisk
Contents
Asterisk
Asteirsk is an open source telephony applications platform. It can be used to build an office PBX, or something less common, such as controlling your tv.
Usage
By using the network control interface in the MythTV frontend application, you can easily turn any phone into a control for MythTV. The details for how to configure different types of phones to work with Asterisk are out of the scope of this reference. The dialplan code given below provides the following basic functionality.
When you first call this extension, the phone is in the first mode. You can press "*" on the phone to switch to the second mode.
In the first mode, numbers 0 through 9 are sent as regular digits for changing channels. The "#" key is used for pressing enter.
In the second mode, numbers 2, 4, 5, and 6 are used as arrow keys for navigating menus. The "1" key is mapped to the letter "m" to bring up the menu while watching live tv or recordings. The "3" key is mapped to the escape key. "#" is used for enter in this mode, as well. 7, 8, and 9 are not mapped to anything right now.
Interfacing with MythTV
The dialplan example given uses netcat to connect to MythTV. It also assumes that the frontend network control interface is configured to listen on port 6546 at address 192.168.1.199.
Dialplan (extensions.conf)
[globals] MYTHTV_IP=192.168.1.199 MYTHTV_PORT=6546 [mythtv] ; Switch to menu mode on "*" ; Pass all other digits as they are exten => key-num,1,GotoIf($["x${CMD}" != "x*"]?return) exten => key-num,n,Set(MODE=menu) exten => key-num,n,Set(CMD=none) exten => key-num,n(return),Return exten => key-menu,1,GotoIf($["x${CMD}" != "x*"]?translatekey) exten => key-menu,n,Set(MODE=num) exten => key-menu,n,Set(CMD=none) exten => key-menu,n,Return exten => key-menu,n(translatekey),GotoIf($["x${CMD}" != "x1"]?check2) exten => key-menu,n,Set(CMD=m) exten => key-menu,n,Return exten => key-menu,n(check2),GotoIf($["x${CMD}" != "x2"]?check3) exten => key-menu,n,Set(CMD=up) exten => key-menu,n,Return exten => key-menu,n(check3),GotoIf($["x${CMD}" != "x3"]?check4) exten => key-menu,n,Set(CMD=escape) exten => key-menu,n,Return exten => key-menu,n(check4),GotoIf($["x${CMD}" != "x4"]?check5) exten => key-menu,n,Set(CMD=left) exten => key-menu,n,Return exten => key-menu,n(check5),GotoIf($["x${CMD}" != "x5"]?check6) exten => key-menu,n,Set(CMD=down) exten => key-menu,n,Return exten => key-menu,n(check6),GotoIf($["x${CMD}" != "x6"]?check7) exten => key-menu,n,Set(CMD=right) exten => key-menu,n,Return exten => key-menu,n(check7),GotoIf($["x${CMD}" != "x7"]?check8) exten => key-menu,n,Set(CMD=escape) exten => key-menu,n,Return exten => key-menu,n(check8),GotoIf($["x${CMD}" != "x8"]?check9) exten => key-menu,n,Set(CMD=escape) exten => key-menu,n,Return exten => key-menu,n(check9),GotoIf($["x${CMD}" != "x9"]?check0) exten => key-menu,n,Set(CMD=escape) exten => key-menu,n,Return exten => key-menu,n(check0),GotoIf($["x${CMD}" != "x0"]?return) exten => key-menu,n,Set(CMD=escape) exten => key-menu,n(return),Return exten => key,1,GoSub(key-${MODE}|1) ; Do mode-specific processing exten => key,n,GotoIf($["x${CMD}" != "xnone"]?checkpound) exten => key,n,Goto(return) exten => key,n(checkpound),GotoIf($["x${CMD}" != "x"]?send) ; on "#", CMD will be empty exten => key,n,Set(CMD=enter) exten => key,n(send),System(printf \'key ${CMD}\\r\\nquit\\r\\n\' | nc ${MYTHTV_IP} ${MYTHTV_PORT}) exten => key,n(return),Return exten => s,1,Set(MODE=num) exten => s,n(loop),While(1) exten => s,n,Read(CMD||1) ; Read a digit from the phone exten => s,n,GoSub(key|1) ; Run the key extension to process the digit exten => s,n,EndWhile
Dialplan (extensions.ael)
This example uses AEL, the Asterisk Extension Language.
globals { MYTHTV_IP=192.168.1.199; MYTHTV_PORT=6546; } context mythtv { /* Start by going here when the phone goes off hook */ s => { MODE=num; while (1) { begin: Read(CMD,,1); goto mode_${MODE}|begin; process_key: if ("x${CMD}" = "xnone") { goto begin; } else if ("x${CMD}" = "x") { /* CMD empty on # */ CMD=enter; } System(printf \'key ${CMD}\\r\\nquit\\r\\n\' | nc ${MYTHTV_IP} ${MYTHTV_PORT}); } } mode_num => { begin: /* Switch to menu mode on *, pass all other digits as they are */ if ("x${CMD}" = "x*") { MODE=menu; CMD=none; } goto s|process_key; } mode_menu = { begin: if ("x${CMD}" = "x*") { MODE=num; CMD=none; } else if ("x${CMD}" = "x1") { CMD=m; /* TV menu */ } else if ("x${CMD}" = "x2") { CMD=up; } else if ("x${CMD}" = "x3") { CMD=escape; } else if ("x${CMD}" = "x4") { CMD=left; } else if ("x${CMD}" = "x5") { CMD=down; } else if ("x${CMD}" = "x6") { CMD=right; } else if ("x${CMD}" = "x7") { CMD=escape; } else if ("x${CMD}" = "x8") { CMD=escape; } else if ("x${CMD}" = "x9") { CMD=escape; } else if ("x${CMD}" = "x0") { CMD=escape; } goto s|process_key; } }