Controlling MythTV from any phone using Asterisk

From MythTV Official Wiki
Jump to: navigation, search

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;
        }
}