Merge two pieces good working code

Hi there, I have bought a remote control to match my Raspberry Pi 4b 8 gig. I got it working.

I want to make a media player from my RPI. Not with Kodi or something but own chosen app.
Audacious
VLC
RaspiCast
GoodVibes
FreeTuxTV

Now I have found code to work with on the internet. I have edit the code to my needs. And it is working, happy me. It is to manage my IR rc.

Now I also found a piece of code to make a menu. I edit this too to make it to my needs. It is working.

So, you guys can guess the next: I want to merge the two pieces of code into one working main menu for my media RPI.
Somebody willing to help me out here?

The code for the ir rc:

#!/usr/bin/python

import subprocess
import sys
import os
import time
import xdotool
import lirc

from lirc import RawConnection
def ProcessIRRemote():
    #get IR command
    #keypress format = (hexcode, repeat_num, command_key, remote_id)
    try:
        keypress = conn.readline(.0001)
    except:
        keypress=""

    if (keypress != "" and keypress != None):

        data = keypress.split()
        sequence = data[1]
        command = data[2]

        #ignore command repeats
        if (sequence != "00"):
            return

        #print(command)


        match command:
            case "KEY_POWER":
                print("De aan en uit knop.")
                sys.exit()
                #os.system('systemctl poweroff')
            case "KEY_MUTE":
                os.system("amixer sset Master toggle")
                print("Stilte.")
            case "KEY_PREVIOUS":
                os.system("audacious --rew")
                print("Vorige nummer.")
            case "KEY_PLAY":
                os.system("audtool --playback-playpause")
                print("Huidige nummer afspelen.")
            case "KEY_NEXT":
                os.system("audacious --fwd")
                print("Volgende nummer.")
            case "KEY_UP":
                os.system("xdotool key Up")
                print("Wielpijl op.")
            case "KEY_LEFT":
                os.system("xdotool key Left")
                print("Wielpijl links.")
            case "KEY_OK":
                os.system("xdotool key Return")
                print("Wielpijl OK.")
            case "KEY_RIGHT":
                os.system("xdotool key Right")
                print("Wielpijl rechts.")
            case "KEY_DOWN":
                os.system("xdotool key Down")
                print("Wielpijl neer.")
            case "KEY_EXIT":
                print("De Exit knop.")
            case "KEY_CHANNEL":
                print("Kanaalknop.")
            case "KEY_SELECT":
                print("Selecteerknop.")
            case "KEY_VOLUMEDOWN":
                os.system("amixer sset Master 5%-")
                print("Geluid zachter.")
            case "KEY_VOLUMEUP":
                os.system("amixer sset Master 5%+")
                print("Geluid harder.")

#define Global
conn = RawConnection()
print("Starting Up...")
while True:
      ProcessIRRemote()

The code for the menu:

#!/usr/bin/env python
# encoding: utf-8

import curses
import npyscreen

screen = curses.initscr()

class TestApp(npyscreen.NPSApp):
    def main(self):
        height, width = screen.getmaxyx()
        boxw = int(width / 1.586666)
        boxh = int(height / 1.475)
        hboxw = boxw / 2
        hboxh = boxh / 2
        boxx = int((width / 2) - hboxw)
        boxy = int((height / 2) - hboxh)
        F  = npyscreen.Form(name = "Hoofdmenu Media PI", lines=boxh, columns=boxw)
        F.show_atx = boxx
        F.show_aty = boxy
        ms = F.add(npyscreen.TitleSelectOne, max_height=7, value = [0,], name="Kies de media applicatie", values = ["Audacious muziek","VLC film","GoodVibes radio","Spotify-QT spotify","Kodi IPTV","RaspiCast telefoon casting"], scroll_exit=True)
        F.edit()



if __name__ == "__main__":
    App = TestApp()
    App.run()

Thanks, Pit.

Hey there,
just to make sure I understand you correctly, you plan on having some kind of user interface on the Pi as well as an infrared remote. Both should be able to control the media playback.

I think the most straight forward way here would be to run the menu and the IR part in different threads. For example running the menu in the “main” one and opening another for the IR processing loop. You could start with threads.

Now slightly more opinionated, but I would also consider interprocess communication for example with sockets. This way you could have a process that handles the playback and just extend it with other processes that handle UI menus, IR receivers, a webserver that provides API access to your playback, … This way, you could easily add new functionality without having to touch other parts as often.

Thx Robin, I am going to look into the threads business.
First I will make the program work the “old” way then I will look into your second part of your answer. :slight_smile:

Pit

You have two processes, and you would like to run them both based on user needs. Assuming they don’t run in parallel (only one runs at any given time but not both). Because there are two processes, you can create a flag (i.e., a variable) that can have either two values: 0 and 1. If its value is 0, run the media app process. If it is 1, run the ir rc process. From a high-level, you can potentially set it up something like this:

# app_flag = 0, run media process
# app_flag = 1, run ir rc process
MEDIA = 0
MENU = 1

app_flag = 'MEDIA'  # Default at start-up

def mainloop(app_to_run_flag):

    while(True):

        match app_to_run_flag:

            case "MEDIA":

                process_IR_remote()

            case "MENU":

                menu_app()

            case _:
                pass

mainloop(app_flag)  # run the code
       

You will have to add code that changes (toggles) the value of the flag based on some condition (i.e., input from the user, app selection, etc.).

Since you already have “working” code for each app, this should be pretty straightforward to set up.

Cheers!

If you want to add the ir_rc function into the existing menu, you may add the def ProcessIRRemote(): into the class:

class TestApp(npyscreen.NPSApp):

    def main(self):
        # body statements here

    def ProcessIRRemote():  # call app when needed (qualify the method)
        # body statements here