Portsdown 4 Receive Command Line?

Discussion about this major DATV Project. See https://wiki.batc.org.uk/The_Portsdown_Transmitter
G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Portsdown 4 Receive Command Line?

Post by G4UFS » Wed Dec 16, 2020 1:58 pm

Is it possible to control the Portsdown 4 receiver from the command line?

I would like to ssh to the pi and issue a command to tune the receiver along with associated symbol rate, as if one of the presets had been pressed, thereby commanding the receiver to receive the specified frequency and symbol rate and display as normal on the 7 inch screen.

I think I could do this if the preset buttons were accessible as a simple script but I cant seem to find anything like that in the file system.

Regards
Dave - G4UFS

G8GKQ
Site Admin
Posts: 2958
Joined: Sun Mar 22, 2009 1:21 pm

Re: Portsdown 4 Receive Command Line?

Post by G8GKQ » Wed Dec 16, 2020 2:41 pm

Hi Dave

That is an interesting idea, and could be implemented, but is not currently possible.

The current receive frequency and SR are stored in the file /home/pi/rpidatv/scripts/longmynd_config.txt as freq0 and sr0 (for QO-100) or freq1 and sr1 (for terrestrial). All the button menu does is to change these values.

The receiver is started by running the script /home/pi/rpidatv/scripts/lmvlcff.sh (for VLC with ffmpeg) which reads that file, sets the receiver parameters and starts VLC.

Your best bet would be to take a copy of lmvlcff.sh, rename it and modify it to take the frequency and SR as parameters. However, there is the complication of stopping and starting the button menu, which would take some work.

Let me know if you get it to work and I can then take your code into the core build.

73

Dave, G8GKQ

G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Re: Portsdown 4 Receive Command Line?

Post by G4UFS » Wed Dec 16, 2020 4:08 pm

Thanks for the info Dave!

I have taken a look at the files and can see the parameters for QO100 and Terrestrial but what makes the script select either Q0100 or Terrestrial? Is also contained in the config file?

I tried running the lmvlcff.sh script but from a ssh, it seems to run i.e. I get output on the terminal screen telling me its running but nothing on the display. Does the script have to be run from the console directly??

Regards
Dave
G4UFS

G8GKQ
Site Admin
Posts: 2958
Joined: Sun Mar 22, 2009 1:21 pm

Re: Portsdown 4 Receive Command Line?

Post by G8GKQ » Wed Dec 16, 2020 6:15 pm

Hi Dave

An interesting little exercise. Sorry, I had forgotten that normally the gui reads the longmynd status fifo, and if that is not read, it overflows and everything stops.

The terrestrial or sat mode is also stored in the config file.

Here are 2 scripts. You need to copy them both into the rpidatv/scripts folder and make them executable. Then set Sat or Terrestrial using the touchscreen. Then open 2 ssh windows and cd ~/rpidatv/scripts for both. In the first ssh window run the first script ./lmvlcff2.sh 10491500 1500 to display the beacon (you may get sound only on the first attempt, but it will work the second time).

To stop the script you need to use the second script ./lmstop.sh.

There is no parameter overlay on the screen, as that is handled by the GUI, which we have stopped.

Here is the first script:

Code: Select all

#!/bin/bash

# Command line script to run the receiver on the Portsdown 4.
# Use the GUI to set sat or Terrestrial
# then run this script: ./lmvlcff2.sh 10491500 1500
# for the beacon

PCONFIGFILE="/home/pi/rpidatv/scripts/portsdown_config.txt"
RCONFIGFILE="/home/pi/rpidatv/scripts/longmynd_config.txt"

############ FUNCTION TO READ CONFIG FILE #############################

get_config_var() {
lua - "$1" "$2" <<EOF
local key=assert(arg[1])
local fn=assert(arg[2])
local file=assert(io.open(fn))
for line in file:lines() do
local val = line:match("^#?%s*"..key.."=(.*)$")
if (val ~= nil) then
print(val)
break
end
end
EOF
}

################ Execution starts here #############

cd /home/pi

# Make sure that the GUI is not running
sudo killall rpidatvgui

# Read from receiver config file
SYMBOLRATEK=$(get_config_var sr0 $RCONFIGFILE)
SYMBOLRATEK_T=$(get_config_var sr1 $RCONFIGFILE)
FREQ_KHZ=$(get_config_var freq0 $RCONFIGFILE)
FREQ_KHZ_T=$(get_config_var freq1 $RCONFIGFILE)
RX_MODE=$(get_config_var mode $RCONFIGFILE)
Q_OFFSET=$(get_config_var qoffset $RCONFIGFILE)
AUDIO_OUT=$(get_config_var audio $RCONFIGFILE)
INPUT_SEL=$(get_config_var input $RCONFIGFILE)
INPUT_SEL_T=$(get_config_var input1 $RCONFIGFILE)
LNBVOLTS=$(get_config_var lnbvolts $RCONFIGFILE)

# Use command line arguments for frequency and SR
FREQ_KHZ_T=$1
FREQ_KHZ=$FREQ_KHZ_T
SYMBOLRATEK_T=$2
SYMBOLRATEK=$SYMBOLRATEK_T

# Correct for LNB LO Frequency if required
if [ "$RX_MODE" == "sat" ]; then
  let FREQ_KHZ=$FREQ_KHZ-$Q_OFFSET
else
  FREQ_KHZ=$FREQ_KHZ_T
  SYMBOLRATEK=$SYMBOLRATEK_T
  INPUT_SEL=$INPUT_SEL_T
fi

# Send audio to the correct port
if [ "$AUDIO_OUT" == "rpi" ]; then
  # Check for latest Buster update
  aplay -l | grep -q 'bcm2835 Headphones'
  if [ $? == 0 ]; then
    AUDIO_DEVICE="hw:CARD=Headphones,DEV=0"
  else
    AUDIO_DEVICE="hw:CARD=ALSA,DEV=0"
  fi
else
  AUDIO_DEVICE="hw:CARD=Device,DEV=0"
fi

# Select the correct tuner input
INPUT_CMD=" "
if [ "$INPUT_SEL" == "b" ]; then
  INPUT_CMD="-w"
fi

# Set the LNB Volts
VOLTS_CMD=" "
if [ "$LNBVOLTS" == "h" ]; then
  VOLTS_CMD="-p h"
fi
if [ "$LNBVOLTS" == "v" ]; then
  VOLTS_CMD="-p v"
fi

# Create dummy marquee overlay file
echo " " >/home/pi/tmp/vlc_overlay.txt

sudo killall longmynd >/dev/null 2>/dev/null
sudo killall vlc >/dev/null 2>/dev/null

# Play a very short dummy file if this is a first start for VLC since boot
# This makes sure the RX works on first selection after boot
if [[ ! -f /home/pi/tmp/vlcprimed ]]; then
  cvlc -I rc --rc-host 127.0.0.1:1111 -f --codec ffmpeg --video-title-timeout=100 \
    --width 800 --height 480 \
    --sub-filter marq --marq-x 25 --marq-file "/home/pi/tmp/vlc_overlay.txt" \
    --gain 3 --alsa-audio-device $AUDIO_DEVICE \
    /home/pi/rpidatv/video/blank.ts vlc:quit >/dev/null 2>/dev/null &
  sleep 1
  touch /home/pi/tmp/vlcprimed
  echo shutdown | nc 127.0.0.1 1111
fi

# Create the ts fifo
sudo rm longmynd_main_ts >/dev/null 2>/dev/null
mkfifo longmynd_main_ts

# Make sure that the status FIFO gets read (usually read by the GUI)
/home/pi/longmynd/fake_read &

# Start LongMynd - and for this script accept the default status fifo name
#sudo /home/pi/longmynd/longmynd -s longmynd_status_fifo $VOLTS_CMD $INPUT_CMD $FREQ_KHZ $SYMBOLRATEK &
sudo /home/pi/longmynd/longmynd  $VOLTS_CMD $INPUT_CMD $FREQ_KHZ $SYMBOLRATEK &

# Start VLC
cvlc -I rc --rc-host 127.0.0.1:1111 --codec ffmpeg -f --video-title-timeout=100 \
  --width 800 --height 480 \
  --sub-filter marq --marq-x 25 --marq-file "/home/pi/tmp/vlc_overlay.txt" \
  --gain 3 --alsa-audio-device $AUDIO_DEVICE \
  longmynd_main_ts >/dev/null 2>/dev/null &

exit
and the second:

Code: Select all

#!/bin/bash
sudo killall -9 longmynd
sudo killall -9 fake_read
sudo killall -9 vlc

If you want the touchscreen back, simply type gui

That's about all I have time to do for now, but hopefully you can work from there.

Dave

G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Re: Portsdown 4 Receive Command Line?

Post by G4UFS » Wed Dec 16, 2020 6:47 pm

That's great Dave!

Thanks so much. This gives me something to work with. My knowledge of bash script is almost zero but enough here for me to work on some python for a project I have in mind...

73
Dave
G4UFS

G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Re: Portsdown 4 Receive Command Line?

Post by G4UFS » Wed Dec 16, 2020 9:35 pm

Hi Dave,

So far so good!

More work to do but I now have a UDP server working on my Portsdown and taking input from the QuickTune windows application and have it tuning the Portsdown receiver when I click on the QO100 signals. Much easier than watching the Spectrum Viewer and pressing the buttons for frequency and SR.

My only issue is getting back to the GUI. Is there a way of capturing a press anywhere on the screen? I could use that to trigger the kill script and start the GUI again.

Regards
Dave
G4UFS

G8GKQ
Site Admin
Posts: 2958
Joined: Sun Mar 22, 2009 1:21 pm

Re: Portsdown 4 Receive Command Line?

Post by G8GKQ » Wed Dec 16, 2020 11:22 pm

Good news Dave

Sounds like a really useful capability.

The touchscreen is not running while that script has control of the screen, but I'd like to try to integrate what you have built into the main build, and then I could solve the problem of getting back to the touchscreen.

When you've got it to a reasonable state, please send me the code, and I'll try to put it in the main build. It doesn't have to be perfect to start with, just something that we can test between us before releasing.

Thanks

Dave

G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Re: Portsdown 4 Receive Command Line?

Post by G4UFS » Thu Dec 17, 2020 5:15 pm

Hi Dave,

Please see code I have been working on for Live Tune integration.

I am by no means a programmer but can throw together a little python from time to time :)

The code is commented so should be reasonable understandable. It requires the two scripts you sent to the forum yesterday to start and stop the stream and the Live Tune app needs a receiver set up to point to the Portsdown on port 5115.

I have not yet integrated fully into my Portsdown build but have been running it from a ssh. I suspect whatever I would do to integrate it might be different if you were to use any of the code for a release.

In order to get back to a menu, I applied a bit of a gludge where if the beacon is clicked three times (Leave a second between clicks), the code stops the stream and runs the gui

It may not be worth of inclusion into the build but I am more than happy with the project :) Thanks so much for the information to allow me to get it going.

73 and best wishes for the season
Dave - G4UFS
Last edited by G4UFS on Thu Dec 17, 2020 5:18 pm, edited 1 time in total.

G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Re: Portsdown 4 Receive Command Line?

Post by G4UFS » Thu Dec 17, 2020 5:17 pm

Code: Select all


#!/usr/bin/python


# Python script that sets up a UDP server on post 5115 and listens for commands from "QO100 Live Tune" by Rob M0DTS
#     See https://wiki.batc.org.uk/QO100_Live_Tune
# QuickTune was designed to allow quick tuning of the Windows MiniTiouner application to QO100 signals as they appeared
# on the Wideband Spectrum Monitor. "UDPControl" allows QO100 Live Tune to be used with the Portsdown Longmynd in the
# manner
# 73 De Dave - G4UFS


# Version History
# 2020.12.17 - Initial release


import socket
import os
import time

# Used to track if this is the first startup of the tuning script. See showTS() for further details of use
state = 0
# Number of times to click on the beacon before returning to menu
stop_count = 3
stop_counter = stop_count

# Function to get the ip address of the Portsdown
def getIPadd():
    soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        soc.connect(('10.255.255.255', 1))
        IPadd = soc.getsockname()[0]
    except Exception:
        IPadd = '127.0.0.1'
    finally:
        soc.close()
    return IPadd



def showTS(Freq,SR):
    global state
    # Stop any receiving that may already be going on
    os.system("./lmstop.sh")
    # Setup to receive the new frequency, SR stream
    os.system("./lmvlcff2.sh " + Freq + " " + SR + " > null")
    if stop_count != 0:
      # Stream crashes if this is the first time starting it so "state" variable implemented to track the first time and start the stream again
      if state == 0:
        time.sleep(3)
        state = 1
        os.system("./lmstop.sh")
        os.system("./lmvlcff2.sh " + FreqNumber + " " + SRNumber + " > null")



###################  Main Code ################################################################################

# Get IP address so that we can bind UDP server to it
localIP = getIPadd()

# Change the below if the detected IP address does is different to the one to be used
# e.g. If using both wired and Wireless networks, the UDP server will need to bind to one
# or the other network interfaces' IP's. The desired card may not be the one detected by the
# getIPadd function
#localIP = "nnn.nnn.nnn.nnn"

print localIP

# Setup a UDP Server on the below port number
localPort   = 5115
bufferSize  = 1024
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPServerSocket.bind((localIP, localPort))
print("Listening for messages")



#################### Main Loop ################################################################################
# Listen for incoming UDP messages
while(True):
    bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
    message = bytesAddressPair[0]
    address = bytesAddressPair[1]
    #print message
    #print address

    # Split the frequency and SR data
    # In the current version of Quick Tune, split [1] = Frequency data and slpit[4] = SR
    splitMsg = message.split(",")
    #print splitMsg

    # Parse splitMsg[1] for the frequency
    StartFreqNumber = splitMsg[1].find("=")+1
    FreqNumber = splitMsg[1][StartFreqNumber:]
    print FreqNumber

    # Parse SplitMsg[4] for the Symbol Rate
    StartSRNumber = splitMsg[4].find("=")+1
    SRNumber = splitMsg[4][StartSRNumber:]
    print SRNumber



    # Not very elegant but check to see if the beacon has been clicked three times in a row and go back to menu if so
    if int(FreqNumber) < 10492000:
      stop_counter = stop_counter - 1
    else:
      stop_counter = stop_count


    if stop_counter == 0:
      os.system("./lmstop.sh")
      #time.sleep(1)
      os.system("/home/pi/rpidatv/scripts/utils/guir.sh &")
      stop_counter = stop_count
      state = 0
    else:
      # Start playing the stream
      showTS(FreqNumber,SRNumber)






G4UFS
Posts: 10
Joined: Sun Oct 04, 2020 9:40 am

Re: Portsdown 4 Receive Command Line?

Post by G4UFS » Sun Dec 20, 2020 3:54 pm

For anyone interested, I managed to get a later version of the script working by selecting "Button 1" from the "More functions" button in Menu "M2" on the Portsdown 4. The following instructions should work with version 20.12.18 of the UDPControl scrip attached. N.B. You will need the two scrips from Dave - G8GKQ ("lmstop.sh" and "lmvlcff2.sh") in the beginning of this thread.

UDPControl.py installation instructions -

1) Copy the following scripts to the /home/pi/rpidatv/scripts folder
lmvlcff2.sh
lmstop.sh
UDPControl.py

2) Make sure that all the above scripts are executable
sudo chmod +x lmvlcff2.sh
sudo chmod +x lmstop.sh
sudo chmod +x UDPControl.py

3) Edit user_button.sh (or whatever user button you prefer) and make look like this :-

#! /bin/bash
/home/pi/rpidatv/scripts/UDPControl.py

4) Reboot the Portsdown

5) If not done so already, download an install Quick Tune on Windows PC

6) Go to setting and type the IP address of your Portsdown in the "IP Address" field
Make "Port" number = 5115
Click "Add New Receiver"

UDPControl usage -
To activate Quick Tune on the Portsdown, goto Menu M2 > More functions > Button 1 (or which ever you edited above)
Now, when clicking signals on Quick tune, the Portsdown should switch to them.

To exit quick tune on the Portsdown, click the beacon signal three times (leave a second or so between clicks).
N.B to enable it again, follow the steps above to activate it.

Sometimes the Portsdown doesn't tune first time. If no signal is received within 10 seconds or so, try clicking the signal again in Quick Tune. N.B, if the beacon is clicked 3 times, the script will exit and you will need to activate it again.


TODO :
Work out a way of exiting the script from the Portsdown screen instead of clicking the beacon three times
Work out a way to add the information overlay, currently the overlay will not display

One final note. This works for "me". Please make sure you take a backup of your system before doing anything. The usual disclaimers apply - that I wont be responsible for anything etc...

Merry Christmas All !! :)

UDPControl.py 20.12.18

Code: Select all

#!/usr/bin/python


# Python script that sets up a UDP server on post 5115 and listens for commands from "QO100 Live Tune" by Rob M0DTS
#     See https://wiki.batc.org.uk/QO100_Live_Tune
# QuickTune was designed to allow quick tuning of the Windows MiniTiouner application to QO100 signals as they appeared
# on the Wideband Spectrum Monitor. "UDPControl" allows QO100 Live Tune to be used with the Portsdown Longmynd in the same
# manner
# 73 De Dave - G4UFS


# Version History
# 2020.12.17 - Initial release
# 2020.12.18 -
# Fixed releasing of UDP port when script exited
# Changed to absolute names for supporting script so that UDPControl script can be called from anywhere
#       (N.B. Supporting scrips must be in /home/pi/rpidatv/scripts)
# Modified to exit script when beacon clicked three times
# This script can be called from "Button 1" on "More Functions" menu so that is can be started from the Portsdown menu system


import socket
import os
import sys
import time

# Used to track if this is the first startup of the tuning script. See showTS() for furter details of use
state = 0
# Number of times to click on the beacon before returning to menu
stop_count = 3
stop_counter = stop_count

# Function to get the ip address of the Portsdown
def getIPadd():
    soc = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
    try:
        soc.connect(('10.255.255.255', 1))
        IPadd = soc.getsockname()[0]
    except Exception:
        IPadd = '127.0.0.1'
    finally:
        soc.close()
    return IPadd



def showTS(Freq,SR):
    global state
    # Stop any receiving that may already be going on
    os.system("/home/pi/rpidatv/scripts/lmstop.sh")
    # Setup to receive the new frequency, SR stream
    os.system("/home/pi/rpidatv/scripts/lmvlcff2.sh " + Freq + " " + SR + " > null")
    if stop_count != 0:
      # Stream crashes if this is the first time starting it so "state" variable implemented to track the first time and start the stream again
      if state == 0:
        time.sleep(3)
        state = 1
        os.system("/home/pi/rpidatv/scripts/lmstop.sh")
        os.system("/home/pi/rpidatv/scripts/lmvlcff2.sh " + FreqNumber + " " + SRNumber + " > null")



###################  Main Code ################################################################################


# Get IP address so that we can bind UDP server to it

# Has IP been passed on the command line? if so, use it. If not, try and get one from the OS
if len(sys.argv) == 2:
     print str(sys.argv[1])
     localIP = str(sys.argv[1])
else:
     localIP = getIPadd()

# Change the below if the detected IP address is different to the one to be used
# e.g. If using both wired and Wireless networks, the UDP server will need to bind to one
# or the other network interfaces' IP's. The desired card may not be the one detected by the
# getIPadd function
#localIP = "nnn.nnn.nnn.nnn"

print localIP

# Setup a UDP Server on the below port number
localPort   = 5115
bufferSize  = 1024
UDPServerSocket = socket.socket(family=socket.AF_INET, type=socket.SOCK_DGRAM)
UDPServerSocket.setsockopt(socket.SOL_SOCKET, socket.SO_REUSEADDR, 1)
UDPServerSocket.bind((localIP, localPort))
print("Listening for messages")



#################### Main Loop ################################################################################
# Listen for incoming UDP messages
while(True):
    bytesAddressPair = UDPServerSocket.recvfrom(bufferSize)
    message = bytesAddressPair[0]
    address = bytesAddressPair[1]
    #print message
    #print address

    # Split the frequency and SR data
    # In the current version of Quick Tune, split [1] = Frequency data and split[4] = SR
    splitMsg = message.split(",")
    #print splitMsg

    # Parse splitMsg[1] for the frequency
    StartFreqNumber = splitMsg[1].find("=")+1
    FreqNumber = splitMsg[1][StartFreqNumber:]
    print FreqNumber

    # Parse SplitMsg[4] for the Symbol Rate
    StartSRNumber = splitMsg[4].find("=")+1
    SRNumber = splitMsg[4][StartSRNumber:]
    print SRNumber



    # Not very elegant but check to see if the beacon has been clicked three times in a row and go back to menu if so
    if int(FreqNumber) < 10492000:
      stop_counter = stop_counter - 1
    else:
      stop_counter = stop_count


    if stop_counter == 0:
      os.system("/home/pi/rpidatv/scripts/lmstop.sh")
      #time.sleep(1)
      os.system("/home/pi/rpidatv/scripts/utils/guir.sh &")
      stop_counter = stop_count
      state = 0
      soc.shutdown(socket.SHUT_RDWR)
      soc.close()
      sys.exit()
    else:
      # Start playing the stream
      showTS(FreqNumber,SRNumber)



Post Reply

Return to “The Portsdown Digital ATV System”