AutoBoot for telegram and Sonic Pi Jukebox

SonicPiJukeBox

Headless Sonic Pi Jukebox video using autobooted telegram and sonic-pi-cli

Before you attempt this project, you MUST have telegram set up and working as described in the first part of this article here. You can use the QUICKTRACK route in that article if you just want to control Sonic Pi and not the GPIO as well.

If you are impatient, then all of the scripts and sample files used in the project can be downloaded and installed using the procedures listed at the end of the article. However, en-route you must also do the following.
For Sonic Pi control, install Method 3 of autoboot

For GPIO only control, you can choose to install Method 2, or Method 3, depending on whether you want to boot to the command line or the GUI.
For ALL users, do the section Installing the sonic-pi-cli
You can then jump to the section Installing the project at the end

A reader asked me if it was possible to get the telegram GPIO control project to autostart on boot on the Raspberry Pi. This seemed quite a cool and useful idea, so I gave it some thought.

Method one: (abandoned). Initially I looked at adding a script at the end of the /etc/rc.local file which could be called at the end of the boot process.  In fact I got this to work but it was very messy and had problems, the main one being that the user environment is not set up at this point, and so the method of locating the various files in the project needed a great deal of alteration.

Method two: (no good for Sonic Pi control). The second technique I looked at involved altering /etc/inittab This file is used to control the booting process, it deals with starting the Pi at different run time levels and sets up the login terminal. If you are going to alter it, it is a good idea to make a backup first.
sudo cp /etc/inittab /etc/inittab.original
Then you can acces it with
nano /etc/inittab
You search for the line

1:2345:respawn:/sbin/getty --noclear 38400 tty1

comment it out and add a replacement in the next line, giving:

#1:2345:respawn:/sbin/getty --noclear 38400 tty1
1:2345:respawn:/bin/login -f pi tty1 </dev/tty1 >/dev/tty1 2>&1

then exit nano with ctrl+x press Y then return key
This will boot  and log in automatically as the user ‘pi’ to a command line prompt on the terminal screen.
You can then call a script from the .bashrc file in the Pi home directory, by adding the following lines to the end of that file, using a script startup.sh is added to the telegram directory set up in the first part of this article:
access the file with
nano .bashrc
Again, you can make a backup first if you want with
cp .bashrc .bashrc.original

if [ $(tty) == /dev/tty1 ]; then
   ./telegram/startup.sh
fi

then exit nano with ctrl+x press Y then return key
This checks to see it the user is local (on tty1) and if so launches the telegram startup script (which will be added later) This means that a user logging on via ssh will not start up telegram automatically.

This autoboot procedure is discussed in an article at http://www.raspberrypi.org/forums/viewtopic.php?f=29&t=7192

One tip. If you have set it up, before trying it out, as a precaution it is worth making sure that you have ssh access to your pi. Then if you have made a mistake and it fails to boot, you can use ssh to access and repair any problems with the inttab file.
If you want to run from the command-line interface then this method is fine, and telegram and the control of GPIO connected devices works fine in this environment.

Method 3: (adopted for Sonic Pi control). I had no sooner set this up than I received an email saying that a command line interface had just been published to the program Sonic Pi.
As you can see, from much of the other content in my blog, this is a program which I use a lot, and so immediately I wondered if this project could be used with the sonic-pi-cli. The major difference is that Sonic Pi is a gui based program and so needs X to be running to work. So the question became, can you autoboot directly to the GUI and automatically start up Sonic Pi AND an xterminal running telegram? The first part is easy. One of the choices in the configuration program raspi-config lets you choose between booting to a logon prompt, OR into the gui logged on as user ‘pi’. After a bit of googling and experimentation I found that you could automatically start Sonic Pi and the xterminal by adding entries to the file

/etc/xdg/lxsession/LXDE-pi/autostart

If you want to be cautious, you can backup the file first with

sudo cp /etc/xdg/lxsession/LXDE-pi/autostart /etc/xdg/lxsession/LXDE-pi/autostart.original

at the end of the file, which you can access with

sudo nano /etc/xdg/lxsession/LXDE-pi/autostart

you can add two lines

@sonic-pi
@lxterminal --command "/home/pi/telegram/startup.sh"

where again startup.sh is a script which we will add to the telegram directory later.
Then exit nano with ctrl+x press Y then return key

Don’t at this stage switch raspi-config to boot into the gui, as it is probably easier to work in the command line environment till things are set up.

Having discussed the autostart from boot, we can now look at the changes to the telegram project itself to accommodate the autostart, and to add commands to allow Sonic Pi to be controlled.

QUICKSTART: If you are coming down the QUICKSTART route from the first article, you probably won’t yet have a directory called telegram in which we will assemble the files associated with the project. You should create it at this point.
cd ~
mkdir telegram

First, there are some additional scripts to be added. The first is startup.sh This is called from the .bashrc script if you are using the first method of automatic logon, or from the command line added to the autostart file if you are going to use the GUI autostart mechanism. The file is the same in both cases. Use nano to create it
cd telegram
nano startup.sh
then add the content below

#!/bin/bash
cd telegram
telegram-cli -s rpicontrol.lua

Then exit nano with ctrl+x press Y then return key

Having created the file, you should type chmod 755 startup.sh to make it executable. When run, the file changes to the telegram directory and then issues the command to start telegram-cli with the rpicontrol.lua file containing the added commands to control the GPIO or Sonic Pi QUICKSTART: the rpicontrol.lua file has yet to be added if you are on the quickstart route

So that you can easily enable or disable this, two further copies of the file are made.
from with the telegraph directory

cp startup.sh startup.sh.on
cp startup.sh startup.sh.off
Then use nano to comment out the command lines in startup.sh.off to give

#!/bin/bash
#cd telegram
#telegram-cli -s rpicontrol.lua
#don't do anything!

Use nano startup.sh.off to access it and exit in the usual manner after editing.
We add a final script called autotelegraph.sh which lets us copy back one of these two possibilities to replace startup.sh so that it is either effective or not as required:

#!/bin/bash
if [ $# -eq 0 ]
  then
    echo 'Need argument on or off'
else

  if [ $1 == 'on' ]
    then
      cp ~/telegram/startup.sh.on ~/telegram/startup.sh
      echo 'Telegram autostart enabled'
  else
    if [ $1 == 'off' ]
      then
        cp ~/telegram/startup.sh.off ~/telegram/startup.sh
        echo 'Telegram autostart disabled'
    fi
  fi
fi

Use nano autotelegraph.sh to create it, and edit and save in the usual way.
Again, having written the file, make it executable using chmod 755 autotelegram.sh
This file is called from the Pi home directory by ./telegram/autotelegram.sh on or ./telegram/autotelegram.sh off
and will enable or disable the autostart of telegram accordingly.

If you just want to autostart the original project then you are now done, as the existing rpicontrol.lua file controls the GPIO examples as in the first part of the article. nb the file is NOT there if you are on the QUICKSTART route.

Controlling Sonic Pi

I decided at this point, to add the sonic-pi-cli and to replace the rpicontrol.lua with a new one which JUST controls Sonic Pi, and has the GPIO and camera control removed. For the sake of those who want both in the same app, I have included in the download a separate rpicontrol.lua control file which contains both sets of commands, but for what follows I think it is easier to keep them separate. Also, if you don’t want the GPIO and camera stuff, and you installed them in the first article, you can delete the three Python scripts which are used to control the leds camera and buzzer from the telegram directory. nb they are not there if on the QUICKSTART route

Installiing the sonic-pi-cli

The sonic-pi-cli is downloaded from github. Thanks to Nick Johnstone for a great project. THERE ARE TWO VERSIONS OF THE GEM, BECAUSE OF CHANGES IN SONIC PI. MAKE SURE YOU HAVE THE LATEST ONE version 0.0.4 to use with Sonic Pi versions after and including version 2.7. The previous cli version 0.0.3 will NOT work with Sonic Pi 2.7

cd ~
git clone https://github.com/Widdershin/sonic-pi-cli.git

Once it has downloaded you can type

sudo gem install sonic-pi-cli

to install it.

For the impatient you can jump to install downloads from this point

The new Sonic Pi rpicontrol.lua file looks like this:

--Sonic Pi control only this version
started = 0
our_id = 0
path = os.getenv("HOME").."/telegram"
spfiles= os.getenv("HOME").."/spfiles"
linked= os.getenv("HOME").."/linked" 
function vardump(value, depth, key)
  local linePrefix = ""
  local spaces = ""
  
  if key ~= nil then
    linePrefix = "["..key.."] = "
  end
  
  if depth == nil then
    depth = 0
  else
    depth = depth + 1
    for i=1, depth do spaces = spaces .. "  " end
  end
  
  if type(value) == 'table' then
    mTable = getmetatable(value)
    if mTable == nil then
      print(spaces ..linePrefix.."(table) ")
    else
      print(spaces .."(metatable) ")
        value = mTable
    end		
    for tableKey, tableValue in pairs(value) do
      vardump(tableValue, depth, tableKey)
    end
  elseif type(value)	== 'function' or 
      type(value)	== 'thread' or 
      type(value)	== 'userdata' or
      value		== nil
  then
    print(spaces..tostring(value))
  else
    print(spaces..linePrefix.."("..type(value)..") "..tostring(value))
  end
end

print ("HI, this is lua script")
print ("Python scripts, photo.jpg and rpicontrol.lua should be in "..path)

function ok_cb(extra, success, result)
end

-- Notification code {{{

function get_title (P, Q)
  if (Q.type == 'user') then
    return P.first_name .. " " .. P.last_name
  elseif (Q.type == 'chat') then
    return Q.title
  elseif (Q.type == 'encr_chat') then
    return 'Secret chat with ' .. P.first_name .. ' ' .. P.last_name
  else
    return ''
  end
end

local lgi = require ('lgi')
local notify = lgi.require('Notify')
notify.init ("Telegram updates")
local icon = os.getenv("HOME") .. "/.telegram-cli/telegram-pics/telegram_64.png"

function do_notify (user, msg)
  local n = notify.Notification.new(user, msg, icon)
  n:show ()
end

-- }}}

function on_msg_receive (msg)
  if started == 0 then
    return
  end
  if msg.out then
    return
  end
  do_notify (get_title (msg.from, msg.to), msg.text)

  if (msg.text == 'ping') then
    if (msg.to.id == our_id) then
      send_msg (msg.from.print_name, 'pong', ok_cb, false)
    else
      send_msg (msg.to.print_name, 'pong', ok_cb, false)
    end
    return
  end
  if (msg.text == 'PING') then
    if (msg.to.id == our_id) then
      fwd_msg (msg.from.print_name, msg.id, ok_cb, false)
    else
      fwd_msg (msg.to.print_name, msg.id, ok_cb, false)
    end
    return
  end
  if (msg.text == 'Shutdown') then
    os.execute('sudo halt')   
    return
  end

  if (msg.text == 'Reboot') then
    os.execute('sudo reboot')   
    return
  end
  if (msg.text == 'AutoOn') then
    os.execute('sudo cp '..path..'/startup.sh.on '..path..'/startup.sh')   
    send_msg (msg.from.print_name, 'Turned Autostart On',ok_cb,false)
    return
  end
  if (msg.text == 'AutoOff') then
     os.execute('sudo cp '..path..'/startup.sh.off '..path..'/startup.sh')   
     send_msg (msg.from.print_name, 'Turned Autostart Off',ok_cb,false)
    return
  end

  if (msg.text == 'Hp') then
     os.execute('amixer cset numid=3 1')   
     send_msg (msg.from.print_name, 'Headphones selected',ok_cb,false)
    return
  end

  if (msg.text == 'HDMI') then
     os.execute('amixer cset numid=3 2')   
     send_msg (msg.from.print_name, 'HDMI selected selected',ok_cb,false)
    return
  end
 
  if (msg.text == 'List') then
    os.execute('ls '..spfiles..' > '..path..'/mnlist.txt')
    os.execute('cat -n '..path..'/mnlist.txt > '..path..'/mlist.txt')
    os.execute('rm '..path..'/mnlist.txt')
    send_text(msg.from.print_name,path..'/mlist.txt' , ok_cb, false)
    return
  end

  if (string.sub(msg.text,1,4) == 'Play') then
    local text=msg.text
    text=string.sub(text,6)
    os.execute("head -'"..text.."' "..path.."/mlist.txt | tail -1 |sed 's/^.......//' > "..path.."/comm.txt 2>&1")
    local file=io.open(path.."/comm.txt","r")
    io.input(file)
    local f=file:read()
    file:close()
    --stop any existing files that are playing
    os.execute('/usr/local/bin/sonic_pi stop')
    os.execute('/usr/local/bin/sonic_pi stop')
    -- send commands to reset pling defaults in Sonic Pi from init.txt file
    os.execute('cat '..path..'/init.txt '..spfiles..'/'..f..' | /usr/local/bin/sonic_pi &')
    send_msg (msg.from.print_name, 'Playing '..f, ok_cb, false)
    return
  end
  
  if (msg.text == 'Brand') then
     --stop any existing files that are playing
    os.execute('/usr/local/bin/sonic_pi stop')
    os.execute('/usr/local/bin/sonic_pi stop')
    --send dbf.txt (use_debug false) to all files except the last
    os.execute('cat '..path..'/dbf.txt '..linked..'/seven.txt | /usr/local/bin/sonic_pi &')
    os.execute('cat '..path..'/dbf.txt '..linked..'/six.txt | /usr/local/bin/sonic_pi &')
    os.execute('cat '..path..'/dbf.txt '..linked..'/five.txt | /usr/local/bin/sonic_pi &')
    os.execute('cat '..path..'/dbf.txt '..linked..'/four.txt | /usr/local/bin/sonic_pi &')
    os.execute('cat '..path..'/dbf.txt '..linked..'/three.txt | /usr/local/bin/sonic_pi &')
    os.execute('cat '..path..'/dbf.txt '..linked..'/two.txt | /usr/local/bin/sonic_pi &')
    --send init.txt (reset pling and use_debug false to last file (one which starts things off)
    os.execute('cat '..path..'/init.txt '..linked..'/one.txt | /usr/local/bin/sonic_pi &')
    send_msg (msg.from.print_name, 'Brandenburg 5 playing', ok_cb, false)
    return
  end

  if (msg.text == 'Gigue') then
    --stop any existing files that are playing
    os.execute('/usr/local/bin/sonic_pi stop')
    os.execute('/usr/local/bin/sonic_pi stop')
    -- see comments above in Brand section for dbf.txt and init.txt files
    os.execute('cat '..path..'/dbf.txt '..linked..'/BachGigueInGMinorSuite3Samp2.rb | /usr/local/bin/sonic_pi &')
    os.execute('cat '..path..'/init.txt '..linked..'/BachGigueInGMinorSuite3Samp1.rb | /usr/local/bin/sonic_pi &')
    send_msg (msg.from.print_name, 'BachGigueInGMinor sampled version playing', ok_cb, false)
    return
  end

  if (msg.text == 'Stop') then
    -- do twice
    os.execute('/usr/local/bin/sonic_pi stop')
    os.execute('/usr/local/bin/sonic_pi stop')
    send_msg (msg.from.print_name, 'Sonic Pi stopped', ok_cb, false)
    return
  end

  if (msg.text == 'Raspi') then
    os.execute('sudo /usr/bin/raspi-config')
    send_msg (msg.from.print_name, 'raspi-config used', ok_cb, false)
    return
  end

  if (msg.text == 'ListAll') then
    send_msg (msg.from.print_name, 'Extra Commands: ping, PING, AutoOn, AutoOff, Reboot, Shutdown,Raspi', ok_cb, false)
    send_msg (msg.from.print_name, 'Sonic Pi Music Commands:Hp, HDMI, List, Play (num), Brand, Gigue, Stop', ok_cb, false)
    return
  end

end

function on_our_id (id)
  our_id = id
end

function on_user_update (user, what)
  --vardump (user)
end

function on_chat_update (chat, what)
  --vardump (chat)
end

function on_secret_chat_update (schat, what)
  --vardump (schat)
end

function on_get_difference_end ()
end

function cron()
  -- do something
  postpone (cron, false, 1.0)
end

function on_binlog_replay_end ()
  started = 1
  postpone (cron, false, 1.0)
end

This is based on the original test.lua file supplied with the telegram-cli github download.
Three lines are added near the beginning which set up path variables for the location of various files.
path = os.getenv(“HOME”)..”/telegram”
spfiles= os.getenv(“HOME”)..”/spfiles”
linked= os.getenv(“HOME”)..”/linked”
The first sets path to the location of the telegram directory, the second sets spfiles to the location of the spfiles directory which will contain a selection of Sonic Pi files which can be played by the application, and the third, linked contains files which use Sonic Pi cue and sync commands to link together and play one after the other automatically.

The files in the example spfiles folder supplied in the download are all the current example files copied from the Sonic Pi help system. The two linked file examples, are a sample based piano rendition of a Bach Gigue, and a seven linked files which play the Minuet, Trio and Polacca sections of Bach’s Brandenburg number 5. The linking overcomes a maximum size issue for a single file in Sonic Pi.

The bulk of the changes occur in the function on_msg_receive
This contains several very similar sections which check the message content against a keyword and then select an os command to be executed in response to a keyword match, followed by sending a message back to the calling station to say that the command has been completed.

Added sections deal with Shutdown, Reboot (these don’t send messages back for obvious reasons!)
AutoOn and AutoOff which run the autotelegram.sh script discussed above, and set the behaviour as far as telegram is concerned for the next reboot
Hp and HDMI which set the sound output to Headphone or HDMI routes.
List, which is a bit more involved. It saves a list of the files in the spfiles directory to a file mnlist.txt.
It then adds line numbers to that file sending the results to a second file mlist.txt, and removes the first temporary file mnlist.txt
It then returns the contents of this numbered file list to the sender of the List command.

Play n This is the heart of the Sonic Pi control, and is also the most complex additional command. It checks for the word Play at the start of a message. If there is a match, it extracts the remainder of the message (which should be a number`) to a variable text
It uses a rather complex command to save the file name from mlist.txt file corresponding to that number into a separate file comm.txt

os.execute("head -'"..text.."' "..path.."/mlist.txt | tail -1 |sed 's/^.......//' > "..path.."/comm.txt 2>&1")

This boils down to head -n /home/pi/telegram/mliost ~ tail -1 |sed ‘s/^…….//’ > /home/pi/telegram/comm.txt 2>&1 which outputs the file from line n for 1 line and then cuts the first 7 characters of the line and redirects the remainder of the line which is the filename to the file comm.txt.
It then opens this file and reads the filename to a variable f
It stops any existing sonic pi files which may be playing using the os.execute command and sonic-pi-cli. (Command sent twice, as sometimes not fully effective on Model B)
it sends the contents of the file init.txt via the cli. This resets the set_time_ahead_sched! and volume! commands both to 1, and sends a use-debug false command to turn off the output panel in Sonic Pi.
It then invokes the sonic-pi-cli by piping the contents of the file name in f to sonic_pi via the cli.
Finally it sends a message back to the user indicating the filename that is being played.
Two commands Bach and Brand  each enable you to play a sequence of files in the linked directory which contain Sonic Pi cue and sync commands enabling them to be played seamlessly one after the other. This enables you to get round the limit on file size currently imposed by Sonic Pi. Each file is preceded by the contents of the file dbf.txt which contains the command use_debug false. All but the last file start with sync commands and therefore remain waiting. The last file sent (which is the first one to play is preceded by teh contents of init.txt as for the Play n command. When the first file finishes playing it cues the next one and so on.
Stop stops Sonic Pi from playing. This is an important command, as some pieces are in endless loops. Also it lets you cut short a piece before it has finished playing.

Raspi is useful if you are running the Pi with a screen attached. It runs raspi-config and you can use it on the Pi to reset the bootup between the GUI and the command prompt login on subsequent boots.
Finally ListAll lists all the added command words that the lua file responds to.

Once you get the hang of this file you should find it easy to add or amend the commands to suit your own requirements.

Two further files need to be created in the telegram directory. These are init.txt and dbf.txt
the former is created with
cat > init.txt
use_debug false
set_sched_ahead_time! 2
set_volume! 1
(ctrl+c to exit)
and the latter
cat > dbf.txt
use_debug false
(ctrl+c to exit)

If you have read the explanation above you will see that the program accesses sonic pi files to play from folder spfiles and linked. The former contains straight sonic pi command files, and the contents in the download uses all the example scripts from the Help section of Sonic Pi examples section. The downloadable linked folder contains two sets of linked files, one accessed by the Brand command, the other by the Gigue command. One of these uses audio samples from the folder samples which is also contained in the download.

Also downloadable is a copy of the telegram folder containing all the scripts and files used by the project.

Installing the project

1. Install telegram as per the first article, including relocating the telegram binaries and moving the server.pub file.
2. from the Pi home directory download the file tgv2files.tar.gz using
wget http://r.newman.ch/rpi/telegram/tgvfiles2.tar.gz
3. tar zxvf tgv2files.tar.gz to extract the contents (if you ls tgv2files you will see four further tar.gz files. We will extract three of them to their final locations)
NB you can omit 4, 5 and 6 if you only want to control GPIO
4. tar zxvf tgv2files/linkedv2.tar.gz (add the linked folder to the Pi home directory) 
5. tar zxvf tgv2files/spfilesv2.tar.gz (add the spfiles folder to the Pi home directory)
6. tar zxvf tgv2files/samplesv2.tar.gz (add the samples folder to the Pi home directory containing the audio samples used by the Gigue command)
7. The final tarred file contains the telegram directory. So that it doesn’t overwrite any existing telegram directory, we extract it INSIDE the tgv2files folder.
cd tgv2files
tar zxvf telegramfilesv2.tar.gz
8. look inside the telegram folder in tgv2files
ls telegram
you should see

autotelegram.sh  (the script to switch auto start of telegram on and off)
Buzz.py
 (the GPIO program to beep the buzzer 5 times)
comm.txt
(internally generated. Contains the last run Sonic Pi program name)
dbf.txt
(contains the command use_debug false, sent to Sonic Pi by the cli)
init.txt
(contains commands to reset ! command values and use_debug false)
LedSet.py (The GPIO Led control script)
mlist.txt
(internally generated list of Sonic Pi program files)
photo.jpg
(the last photo sent)
rpicontrol.lua
(The current lua script. As supplied Sonic Pi only commands)
rpicontrol.luaGPIOandSP
(Alternative lua script for both SP and GPIO use)
rpicontrol.luaGPIOonly
(alternative lua script for GPIO only commands)
rpicontrol.luaSPonly
(alternative lua script Sonic Pi only commands)
startup.sh
(the current startup script specified by autotelgram.sh)
startup.sh.off
(dummy startup script selected by autotelgram.sh off)
startup.sh.on
(startup script selected by autotelegram.sh on)
takepic.py
(program to take a photo)

You can copy files from here to your existing telegram folder if you have one, or you can rename your existing telegram folder, and replace it with this one. For Sonic Pi only use you do NOT need the three python scripts, or the alternative lua script files. For GPIO only use you do not need the SP versions of the lua script, and you should replace the rpicontrol.lua file with rpicontrol.luaGPIOonly renamed to rpicontrol.lua Also you do not need the three folders linked, spfiles and samples if you installed them earlier.

To replace an existing telegraph directory do this
cd ~
mv telegram telegram.original
mv tgv2files/telegram ~/

if you don’t want the original telegram folder you can then
rm -fR telegram.original

Testing

That completes the installation. To test things out do the following
First checkout telegram directly
cd ~
telegram-cli
This should start it running without any additional command activated. Check that you can communicate with telegram on your phone. Sometimes it can take a little while to recognise. It is easiest to send messages from your phone to the Pi. If you have difficulty try typing quit on the Pi and rerun with telegram-cli.
Once you have estabilshed it is working type quit to exit telegram

Now make sure that the correct autostart script is selected by typing
./telegram/autostart.sh on
Make sure that you have set up the autoboot features according to the method you are using. If controlliing Sonic Pi, then type
sudo raspi-boot
select option 3
followed by Desktop login as user ‘pi’ at the graphical desktop
select Finish and take the Reboot option.
if you are using a GPIO control from the command line, the make sure you have implemented method 2 described above. Then reboot your Pi. sudo reboot

All being well, which ever option you are using, you should reboot straight into Telegram, and you should be able to try out the commands. If using the GUI and controlling Sonic Pi, then once that has started you may have to bring the xterminal window to the front.
Depending on your audio connection via HDMI or analog, you can use the commands Hp (headphone) or HDMI sent via telegram to select.
Send ListAll to see the list of added commands.
Try List to see a list of the 22 example Sonic Pi programs you can play
try Play 19 to play the file tilburg.rb

If you are using GPIO, then the commands are fully explained in the previous article. All you have added is the autoboot feature.

You can prevent telegram from automatically running using the AutoOff comand from telegram, or by quitting the program and running ./telegram/autotelegram.sh off from an lxterminal window. Note if you quit telegram from the existing lxterminal window by typing quit, then the window will close. This is a feature of the way the window was set up by the autostart file.
You can of course, open another xterminal window and restart telegram by typing
./telegram/startup.sh (assuming that you haven’t turned it off with AutoOff) If you have, then ./telegram/autotelegram.sh on on comes to your aid

Well done! It’s been a long haul, but I hope you think it is worth it

Leave a comment