# Use a media keyboard with your pHat Beat, can it be done?

**URL:** <https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176>\
**Category:** Support\
**Created:** [July 1, 2017, 12:53pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176 "2017-07-01T12:53:12Z")\
**Posts on this page:** 20\
**Page:** 1

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 1, 2017, 12:53pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/1 "2017-07-01T12:53:12Z")

</div>

Is there a way to use a wireless keyboard, namely the media keys, with the pHat Beat Pirate radio setup? I plugged my mini WIFI keyboard dongle in but nothing happens when I press volume up down etc. I’m running the Full Raspbian, its just set to boot to command line instead of desktop GUI. This would be a really nice add on feature as those little side buttons are a bit tricky to push. If it had worked, my next step would have been to plug my FLIRC in and use a remote control to change channels and adjust the volume etc.

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 1, 2017, 7:04pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/2 "2017-07-01T19:04:53Z")

</div>

Your best bet is to- and this is slightly less complicated than it sounds- use Python USB to grab the keyboard or remote control device and act upon the button-presses directly.

This is a good place to start looking into how to do that: [https://learn.pimoroni.com/tutorial/robots/controlling-your-robot-wireless-keyboard](https://learn.pimoroni.com/tutorial/robots/controlling-your-robot-wireless-keyboard)

And, if I’m right in thinking the FLIRC is a USB device, (I’ve never used one!) you should be able to use the same trick and script it to do anything you like.

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 1, 2017, 7:30pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/3 "2017-07-01T19:30:29Z")

</div>

Thanks, yes the FLIRC is a USB device. As far as the Pi or PC is concerned its a USB keyboard. Its a programmable IR receiver. It learns the codes your remote sends out and lets you map them to a key press. this may work out even better than I planed. Some time down the road I plan on building a rover project and want to control it with a second Pi via WIFI or Blue Tooth. I have an Explorer pHat mounted to a Pi Zero W, just don’t have the rest, yet. Thanks again.

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 3, 2017, 12:34pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/4 "2017-07-03T12:34:39Z")

</div>

I’m getting an “unindent does not match any outer indentation level” error at the “try” line when running the py file to find the key codes? I took the indent out and then it errored at the “print control” line, missing parenthesis I think was the error?

Is this because I did a sudo python **3** [setup.py](http://setup.py) install. instead of sudo python [setup.py](http://setup.py) install? I’m running it from idle3.

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 3, 2017, 7:51pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/5 "2017-07-03T19:51:53Z")

</div>

> [@alphanumeric](#):
>
> unindent does not match any outer indentation level

I edited it to this and it now passes the check module function in idle3. Will run it on my Pi latter on tonight to see what happens.

import usb.core  
import usb.util  
import time

USB\_IF = 0 # Interface  
USB\_TIMEOUT = 5 # Timeout in MS

USB\_VENDOR = 0x1997 # Rii  
USB\_PRODUCT = 0x2433 # Mini Wireless Keyboard

dev = usb.core.find(idVendor=USB\_VENDOR, idProduct=USB\_PRODUCT)

endpoint = dev[0][(0,0)][0]

if dev.is\_kernel\_driver\_active(USB\_IF) is True:  
dev.detach\_kernel\_driver(USB\_IF)

usb.util.claim\_interface(dev, USB\_IF)

while True:  
control = None

try:  
control = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, USB\_TIMEOUT)  
print (control)  
except:  
pass

time.sleep(0.01) # Let CTRL+C actually exit

I can’t find the code tags?

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 3, 2017, 8:55pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/6 "2017-07-03T20:55:11Z")

</div>

I got the file to run Ok, and I’m getting codes when I press the up, down, left , right, and OK. Nothing happens though when I press the media keys on the left side of the keyboard? This min keyboard is branded Cana Kit but I got the same ID codes as the Rii used in that tutorial. This keyboard is identical with identical layout. I’d really like to use the media keys if possible?

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 4, 2017, 10:37am UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/7 "2017-07-04T10:37:46Z")

</div>

I’m guessing the media keys are on a different endpoint.

If you edit the line that looks like a family of owls, you might be able to find them. If I remember correctly, there are methods available for enumerating endpoints, too.

> [@alphanumeric](#):
>
> endpoint = dev[0][(0,0)][0]

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 4, 2017, 11:59am UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/8 "2017-07-04T11:59:42Z")

</div>

I got codes from my FLIRC that I think I can use. I’m struggling to figure out how to edit the file for the explorer pHat to work with my pHat Beat though. Here is what I have. Are there code tags I should be using? I ran it once as sudo from command line and one whole bar of LED’s light up on the pHat Beat. Didn’t seem too work, hard to tell things went funcky and now all I get is very low scratchy sounds from the speakers. I’m reimaging my SD card as I type this to start all over again. I’m getting close to throwing in the towel on this one. Is there a python file that starts the Pirate radio on boot up? Is that maybe the file I should be editing instead of creating a new one?

#!/usr/bin/env python

import usb.core  
import usb.util  
import phatbeat  
import time

USB\_VENDOR = 0x20a0  
USB\_PRODUCT = 0x0001

USB\_IF = 0 # Interface  
USB\_TIMEOUT = 5 # Timeout in MS

BTN\_CHANDN = 182  
BTN\_CHANUP = 181  
BTN\_VOLUMEUP = 234  
BTN\_VOLUMEDN = 223  
BTN\_MUTE = 205  
BTN\_POWER = 1

dev = usb.core.find(idVendor=USB\_VENDOR, idProduct=USB\_PRODUCT)  
endpoint = dev[0][(0,0)][0]

if dev.is\_kernel\_driver\_active(USB\_IF) is True:  
dev.detach\_kernel\_driver(USB\_IF)

usb.util.claim\_interface(dev, USB\_IF)

while True:  
control = None  
try:  
control = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, USB\_TIMEOUT)  
print(control)  
except:  
pass

```
if control != None:
    if BTN_VOLUMEDN in control:
        phatbeat.BTN_VOLDN()

    if BTN_VOLUMEUP in control:
        phatbeat.BTN_VOLUP()

    if BTN_CHANDN in control:
        phatbeat.BTN_REWIND()
        
    if BTN_CHANUP in control:
        phatbeat.BTN_FASTFWD()
        
    if BTN_POWER in control:
        phatbeat.BTN_ONOFF()

    #if BTN_EXIT in control:
        #exit()

time.sleep(0.02)
```

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 4, 2017, 4:13pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/9 "2017-07-04T16:13:38Z")

</div>

The script you’re looking for is probably this: [https://github.com/pimoroni/phat-beat/blob/master/projects/vlc-radio/phatbeatd/usr/bin/phatbeatd](https://github.com/pimoroni/phat-beat/blob/master/projects/vlc-radio/phatbeatd/usr/bin/phatbeatd)

It’s best left as-is, though, since it’s a fairly obtuse script not meant to be an editable example.

The relevant parts to understand are the socket interface for controlling VLC, which you can build into your script. Importing the `phatbeat` library wont work, since that’s just for reading buttons and doesn’t provide control over any of the software on your Pi.

```auto
import socket
import re

VLC_HOST = "127.0.0.1"
VLC_PORT = 9294

class VLC():

    def __init__ (self, host="127.0.0.1", port=9294):
        self.host = host
        self.port = port
        self.current_stream = None
        self.current_state = None
        self.connecting = False
        self.socket = None

    def send(self, command):
        if self.connecting:
            return False

        print("Sending command: {}".format(command))
        command_string = command + "\n"

        if sys.version_info[0] >= 3:
            command_string = command_string.encode("utf-8")

        try:
            self.socket.send(command_string)

        except socket.error:
            print("Failed to send command to VLC") 
            if self.connect():
                self.send(command)

    def recv(self, length):
        value = self.socket.recv(8192)

        if sys.version_info[0] >= 3:
            value = value.decode("utf-8")

        return value

    def communicate(self, command, response_length=8192):
        self.send(command)
        return self.recv(response_length)

    def get_current_stream(self):
        self.send("status")
        status = self.recv(8192)

        result = re.search("input:\ (.*)\ ", status)
        state = re.search("state\ (.*)\ ", status)

        if state is not None:
            self.current_state = state.group(1)

        if result is not None:
            self.current_stream = result.group(1)
        else:
            self.current_stream = None

        return self.current_stream

    def connect(self):
        if self.connecting:
            return

        self.connecting = True

        if self.socket is not None:
            self.socket.close()

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        for attempt in range(10):
            try:
                print("Attempting to connect to VLC on {host}:{port}".format(host=self.host, port=self.port))
                self.socket.connect((self.host, self.port))
                print("Connection successful!")
                self.connecting = False
                return True

            except socket.error:
                time.sleep(1)

        print("Connection failed!")
        self.connecting = False
        return False

vlc = VLC(host=VLC_HOST, port=VLC_PORT)

if vlc.connect():
    # Your setup code here

```

And once all of the above has set up a connection to VLC, you can use the following commands to control it:

```auto
vlc.communicate("voldown") # Turn the volume down one step
vlc.communicate("volup") # Turn the volume up one step
vlc.communicate("next") # Next track
vlc.communicate("prev") # Prev track
vlc.communicate("pause") # Pause/Play

```

Note: To paste indented code, surround it with three backticks:

````
```
Like so!
```
````

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 4, 2017, 4:47pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/10 "2017-07-04T16:47:15Z")

</div>

Ok, thanks. This is turning out to be a lot more work than I thought. I’ll have a look see, but I think it might be above my skill level.

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 5, 2017, 9:51am UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/11 "2017-07-05T09:51:35Z")

</div>

It wont be by the time you’ve finished ;)

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 5, 2017, 11:40am UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/12 "2017-07-05T11:40:20Z")

</div>

Just sat down with a cup of Java to have a go at it. Making a backup image of my SD card first though. Not knowing what I’m doing hasn’t stopped me before. ;)

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 5, 2017, 1:30pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/13 "2017-07-05T13:30:12Z")

</div>

Ok this is what I have so far. For now I just do a sudo python3 etc from the command line to run it. I’m seeing the key codes on screen so I’m thinking that’s because of the “print (control)” line, and I can remove it to stop that. After a couple of key presses, that don’t seem to be doing anything, I get a “sys not defined” error which I think is the " if sys.version\_info[0] \>= 3:" line?

```auto
import socket
import re

VLC_HOST = "127.0.0.1"
VLC_PORT = 9294

class VLC():

    def __init__ (self, host="127.0.0.1", port=9294):
        self.host = host
        self.port = port
        self.current_stream = None
        self.current_state = None
        self.connecting = False
        self.socket = None

    def send(self, command):
        if self.connecting:
            return False

        print("Sending command: {}".format(command))
        command_string = command + "\n"

        if sys.version_info[0] >= 3:
            command_string = command_string.encode("utf-8")

        try:
            self.socket.send(command_string)

        except socket.error:
            print("Failed to send command to VLC") 
            if self.connect():
                self.send(command)

    def recv(self, length):
        value = self.socket.recv(8192)

        if sys.version_info[0] >= 3:
            value = value.decode("utf-8")

        return value

    def communicate(self, command, response_length=8192):
        self.send(command)
        return self.recv(response_length)

    def get_current_stream(self):
        self.send("status")
        status = self.recv(8192)

        result = re.search("input:\ (.*)\ ", status)
        state = re.search("state\ (.*)\ ", status)

        if state is not None:
            self.current_state = state.group(1)

        if result is not None:
            self.current_stream = result.group(1)
        else:
            self.current_stream = None

        return self.current_stream

    def connect(self):
        if self.connecting:
            return

        self.connecting = True

        if self.socket is not None:
            self.socket.close()

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        for attempt in range(10):
            try:
                print("Attempting to connect to VLC on {host}:{port}".format(host=self.host, port=self.port))
                self.socket.connect((self.host, self.port))
                print("Connection successful!")
                self.connecting = False
                return True

            except socket.error:
                time.sleep(1)

        print("Connection failed!")
        self.connecting = False
        return False

vlc = VLC(host=VLC_HOST, port=VLC_PORT)

if vlc.connect():

    import usb.core
    import usb.util
    import time

    USB_VENDOR = 0x20a0
    USB_PRODUCT = 0x0001

    USB_IF = 0 # Interface
    USB_TIMEOUT = 5 # Timeout in MS

    BTN_FASTFWD = 181
    BTN_REWIND = 182
    BTN_PLAYPAUSE = 205
    BTN_VOLUP = 223
    BTN_VOLDN = 234
    BTN_ONOFF = 1

    dev = usb.core.find(idVendor=USB_VENDOR, idProduct=USB_PRODUCT)
    endpoint = dev[0][(0,0)][0]

if dev.is_kernel_driver_active(USB_IF) is True:
  dev.detach_kernel_driver(USB_IF)

usb.util.claim_interface(dev, USB_IF)

while True:
    control = None
    try:
        control = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, USB_TIMEOUT)
        print(control)
    except:
        pass

    if control != None:
        if BTN_FASTFWD in control:
           vlc.communicate("next") # Next track

        if BTN_REWIND in control:
            vlc.communicate("prev") # Prev track

        if BTN_PLAYPAUSE in control:
            vlc.communicate("pause") # Pause/Play

        if BTN_VOLUP in control:
            vlc.communicate("volup") # Turn the volume up one step

        if BTN_VOLDN in control:
            vlc.communicate("voldown") # Turn the volume down one step

        if BTN_ONOFF in control:
            vlc.communicate("power") # Turn Off

    time.sleep(0.02)

```

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 5, 2017, 3:34pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/14 "2017-07-05T15:34:53Z")

</div>

Not too bad! This is looking incredibly close to being functional from what I can tell at a glance :D

Note that if `vlc.connect()` fails then the code from `if dev.is_kernel_driver_active` onwards will still be run and the program will fail when a button is pressed.

It looks like you need to `import sys` at the top of your code too, I missed that when I was skimming through looking for the imports that the VLC class needed.

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 5, 2017, 3:54pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/15 "2017-07-05T15:54:58Z")

</div>

The `vlc.communicate("command")` lines are sending commands _directly_ to VLC media player, so they’re limited to what commands it actually supports.

I say “limited”, but there are quite a few more commands available in VLC than pHAT BEAT uses:

```nohighlight
pi@raspberry:~ $ vlc -I rc
VLC media player 2.2.5 Weatherwax (revision 2.2.5-0-g9275f0fefa)
[0204da48] pulse audio output error: PulseAudio server connection failure: Connection refused
[02045630] core interface error: no suitable interface module
[01fae8f8] core libvlc error: interface "globalhotkeys,none" initialization failed
[01fce6c0] dbus interface error: Failed to connect to the D-Bus session daemon: Unable to autolaunch a dbus-daemon without a $DISPLAY for X11
[01fce6c0] core interface error: no suitable interface module
[01fae8f8] core libvlc error: interface "dbus,none" initialization failed
[01fce608] [cli] lua interface: Listening on host "*console".
VLC media player 2.2.5 Weatherwax
Command Line Interface initialized. Type `help' for help.
longhelp
> +----[CLI commands]
| add XYZ . . . . . . . . . . . . . . . . . . . . add XYZ to playlist
| enqueue XYZ . . . . . . . . . . . . . . . . . queue XYZ to playlist
| playlist . . . . . . . . . . . . . show items currently in playlist
| search [string] . . search for items in playlist (or reset search)
| delete [X] . . . . . . . . . . . . . . . . delete item X in playlist
| move [X][Y] . . . . . . . . . . . . move item X in playlist after Y
| sort key . . . . . . . . . . . . . . . . . . . . . sort the playlist
| sd [sd] . . . . . . . . . . . . . show services discovery or toggle
| play . . . . . . . . . . . . . . . . . . . . . . . . . . play stream
| stop . . . . . . . . . . . . . . . . . . . . . . . . . . stop stream
| next . . . . . . . . . . . . . . . . . . . . . . next playlist item
| prev . . . . . . . . . . . . . . . . . . . . previous playlist item
| goto, gotoitem . . . . . . . . . . . . . . . . . goto item at index
| repeat [on|off] . . . . . . . . . . . . . . toggle playlist repeat
| loop [on|off] . . . . . . . . . . . . . . . . toggle playlist loop
| random [on|off] . . . . . . . . . . . . . . toggle playlist random
| clear . . . . . . . . . . . . . . . . . . . . . clear the playlist
| status . . . . . . . . . . . . . . . . . . . current playlist status
| title [X] . . . . . . . . . . . . . . set/get title in current item
| title_n . . . . . . . . . . . . . . . . next title in current item
| title_p . . . . . . . . . . . . . . previous title in current item
| chapter [X] . . . . . . . . . . . . set/get chapter in current item
| chapter_n . . . . . . . . . . . . . . next chapter in current item
| chapter_p . . . . . . . . . . . . previous chapter in current item
|
| seek X . . . . . . . . . . . seek in seconds, for instance `seek 12'
| pause . . . . . . . . . . . . . . . . . . . . . . . . toggle pause
| fastforward . . . . . . . . . . . . . . . . . . set to maximum rate
| rewind . . . . . . . . . . . . . . . . . . . . . set to minimum rate
| faster . . . . . . . . . . . . . . . . . . faster playing of stream
| slower . . . . . . . . . . . . . . . . . . slower playing of stream
| normal . . . . . . . . . . . . . . . . . . normal playing of stream
| rate [playback rate] . . . . . . . . . . set playback rate to value
| frame . . . . . . . . . . . . . . . . . . . . . play frame by frame
| fullscreen, f, F [on|off] . . . . . . . . . . . . toggle fullscreen
| info . . . . . . . . . . . . . information about the current stream
| stats . . . . . . . . . . . . . . . . show statistical information
| get_time . . . . . . . . . seconds elapsed since stream's beginning
| is_playing . . . . . . . . . . . . 1 if a stream plays, 0 otherwise
| get_title . . . . . . . . . . . . . the title of the current stream
| get_length . . . . . . . . . . . . the length of the current stream
|
| volume [X] . . . . . . . . . . . . . . . . . . set/get audio volume
| volup [X] . . . . . . . . . . . . . . . raise audio volume X steps
| voldown [X] . . . . . . . . . . . . . . lower audio volume X steps
| achan [X] . . . . . . . . . . . . set/get stereo audio output mode
| atrack [X] . . . . . . . . . . . . . . . . . . . set/get audio track
| vtrack [X] . . . . . . . . . . . . . . . . . . . set/get video track
| vratio [X] . . . . . . . . . . . . . . . set/get video aspect ratio
| vcrop, crop [X] . . . . . . . . . . . . . . . . set/get video crop
| vzoom, zoom [X] . . . . . . . . . . . . . . . . set/get video zoom
| vdeinterlace [X] . . . . . . . . . . . . . set/get video deinterlace
| vdeinterlace_mode [X] . . . . . . . set/get video deinterlace mode
| snapshot . . . . . . . . . . . . . . . . . . . . take video snapshot
| strack [X] . . . . . . . . . . . . . . . . . set/get subtitle track
| hotkey, key [hotkey name] . . . . . . . . . . simulate hotkey press
|
| vlm . . . . . . . . . . . . . . . . . . . . . . . . . load the VLM
| set [var [value]] . . . . . . . . . . . . . . . . . set/get env var
| save_env . . . . . . . . . . . . save env vars (for future clients)
| alias [cmd] . . . . . . . . . . . . . . . . set/get command aliases
| description . . . . . . . . . . . . . . . . . describe this module
| license . . . . . . . . . . . . . . . . print VLC's license message
| help, ? [pattern] . . . . . . . . . . . . . . . . . a help message
| longhelp [pattern] . . . . . . . . . . . . . . a longer help message
| lock . . . . . . . . . . . . . . . . . . . . lock the telnet prompt
| logout . . . . . . . . . . . . . . exit (if in a socket connection)
| quit . . . . . . . . quit VLC (or logout if in a socket connection)
| shutdown . . . . . . . . . . . . . . . . . . . . . . . shutdown VLC
+----[end of help]

```

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 5, 2017, 3:56pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/16 "2017-07-05T15:56:03Z")

</div>

I’ll have another go latter on today and post back. I have some errands to run at the moment. Thanks for all the help.

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 5, 2017, 7:27pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/17 "2017-07-05T19:27:42Z")

</div>

You’re absolutely welcome! Hope to see this up and running 'cos I think it would be a great project to share!

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 5, 2017, 10:34pm UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/18 "2017-07-05T22:34:27Z")

</div>

Got it working woot. I can even shut down when I press the power button on the remote. Here is my code. What is the best way to launch this on boot up?

```auto
import os
import socket
import re
import sys

VLC_HOST = "127.0.0.1"
VLC_PORT = 9294

class VLC():

    def __init__ (self, host="127.0.0.1", port=9294):
        self.host = host
        self.port = port
        self.current_stream = None
        self.current_state = None
        self.connecting = False
        self.socket = None

    def send(self, command):
        if self.connecting:
            return False

        print("Sending command: {}".format(command))
        command_string = command + "\n"

        if sys.version_info[0] >= 3:
            command_string = command_string.encode("utf-8")

        try:
            self.socket.send(command_string)

        except socket.error:
            print("Failed to send command to VLC") 
            if self.connect():
                self.send(command)

    def recv(self, length):
        value = self.socket.recv(8192)

        if sys.version_info[0] >= 3:
            value = value.decode("utf-8")

        return value

    def communicate(self, command, response_length=8192):
        self.send(command)
        return self.recv(response_length)

    def get_current_stream(self):
        self.send("status")
        status = self.recv(8192)

        result = re.search("input:\ (.*)\ ", status)
        state = re.search("state\ (.*)\ ", status)

        if state is not None:
            self.current_state = state.group(1)

        if result is not None:
            self.current_stream = result.group(1)
        else:
            self.current_stream = None

        return self.current_stream

    def connect(self):
        if self.connecting:
            return

        self.connecting = True

        if self.socket is not None:
            self.socket.close()

        self.socket = socket.socket(socket.AF_INET, socket.SOCK_STREAM)

        for attempt in range(10):
            try:
                print("Attempting to connect to VLC on {host}:{port}".format(host=self.host, port=self.port))
                self.socket.connect((self.host, self.port))
                print("Connection successful!")
                self.connecting = False
                return True

            except socket.error:
                time.sleep(1)

        print("Connection failed!")
        self.connecting = False
        return False

vlc = VLC(host=VLC_HOST, port=VLC_PORT)

if vlc.connect():

    import usb.core
    import usb.util
    import time

    USB_VENDOR = 0x20a0
    USB_PRODUCT = 0x0001

    USB_IF = 0 # Interface
    USB_TIMEOUT = 5 # Timeout in MS

    BTN_FASTFWD = 181
    BTN_REWIND = 182
    BTN_PLAYPAUSE = 205
    BTN_VOLUP = 233
    BTN_VOLDN = 234
    BTN_ONOFF = 1

    dev = usb.core.find(idVendor=USB_VENDOR, idProduct=USB_PRODUCT)
    endpoint = dev[0][(0,0)][0]

if dev.is_kernel_driver_active(USB_IF) is True:
  dev.detach_kernel_driver(USB_IF)

usb.util.claim_interface(dev, USB_IF)

while True:
    control = None
    try:
        control = dev.read(endpoint.bEndpointAddress, endpoint.wMaxPacketSize, USB_TIMEOUT)
        #print(control)
    except:
        pass

    if control != None:
        if BTN_FASTFWD in control:
           vlc.communicate("next") # Next track

        if BTN_REWIND in control:
            vlc.communicate("prev") # Prev track

        if BTN_PLAYPAUSE in control:
            vlc.communicate("pause") # Pause/Play

        if BTN_VOLUP in control:
            vlc.communicate("volup") # Turn the volume up one step

        if BTN_VOLDN in control:
            vlc.communicate("voldown") # Turn the volume down one step

        if BTN_ONOFF in control:
            os.system("sudo shutdown now -P")

    time.sleep(0.02)

    

```

---

<div class="post-metadata">

**Author:** ![gadgetoid](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/gadgetoid/32/13_2.png) [@gadgetoid](https://forums.pimoroni.com/u/gadgetoid)\
**Post date:** [July 6, 2017, 8:21am UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/19 "2017-07-06T08:21:14Z")

</div>

See here for loading on boot: [https://learn.pimoroni.com/tutorial/sandyj/running-scripts-at-boot](https://learn.pimoroni.com/tutorial/sandyj/running-scripts-at-boot)

There are a whole bunch of different ways, but I think this one should work for you.

---

<div class="post-metadata">

**Author:** ![alphanumeric](https://sea2.discourse-cdn.com/flex016/user_avatar/forums.pimoroni.com/alphanumeric/32/2729_2.png) [@alphanumeric](https://forums.pimoroni.com/u/alphanumeric)\
**Post date:** [July 6, 2017, 9:22am UTC](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176/20 "2017-07-06T09:22:24Z")

</div>

OK, crontab -e is how I usually do it, but in this case it didn’t work? My remote didn’t work.  
I tried  
@reboot sudo python3 /home/pi/PRRC.py &  
and just  
@reboot python3 /home/pi/PRRC.py &  
sudo python3 /home/pi/PRRC.py is what I run from command line and that works. If I don’t do sudo I get all kinds of error messages.  
I’ll have another try in an hour or so after my morning walk with my dog Ginger. Maybe I had a typo and didn’t see it?

[Next page](https://forums.pimoroni.com/t/use-a-media-keyboard-with-your-phat-beat-can-it-be-done/5176.md?page=2)
