ASL to DMR Bridge...changing talkgroups
Mark I have something I have been working on.
But I'm not finished yet. Want to be able to query where it is
and some other stuff. (all dtmf)
But in my system, it's integrated in a larger package I built
years ago to bypass some of the constants off app_rpt. Something
also being re-written.
I really do not want to provide support for that larger package,
so, you will just have to wait till I finish it and separate it
from the whole package or someone else releases something. But it
does work quite well once I coded against all? the blunders a
person can make when using it.... like trying to change TG's while
in TX to the bridge (allison blows through). Stuff like that.
But whatever I put out there will have to be simpler than it's
current form. I'll get there. Only been working on it a few weeks
here and there. I think I can make it real simple when I finish
all the features I want in there.
...mike/kb8jnm
Has anyone figured out a fast way to change talkgroups? As it is, I need to go into change the TG is Analog Bridge.ini and also Brandmeister under Static groups. Is there a clever, faster way to switch TG using the ASL to DMR Bridge?
Mark
Once the command is sent, a quick PTT will do the trick. Dont forget you should also use TG 4000 to disconnect.
Mike
function tune() {
I don't know if you were directing this to me Mike/KB8JNM or not
Your message is to the dvswitch main group @ goups.io
---
Ports do not have to be 'any certain port number' except:
to not conflict with any port number in use &
to match the port number where it is handshaking TO or FROM.
If you look at the HOW2, there is a nice graphic showing the
digital flow of ports for dmr to asl.
I use (analog_bridge.ini)
fromDMRPort = 31100
toDMRPort = 31103
It must match the port number it interfaces with in
dvswitch.ini
TXPort = 31100 ; Port to send AMBE TLV frames to
(export)
RXPort = 31103 ; Port to listen on (import)
The port number you use are up to you. But they must match where they are going to or coming from without conflict.
All modes/formats would be they same.
...mike/kb8jnm
hi Mike, i just wanted to confirm that the port 31000 is in reference to fromDMRPort, so i should change the script to 31100 correct? Below is from my ini.
[AMBE_AUDIO]
server = 127.0.0.1
fromDMRPort = 31100
toDMRPort = 31103
.
.
.
rpt.conf
871 = autopatchup,context=command_radio,noct=1,farenddisconnect=1,dialtime=20000,quiet=1
extensions.conf
[command_radio]
exten => _1X.,1,SayDigits(${EXTEN:1})
exten => _1X.,n,System(/scripts/tg_connect.py ${EXTEN:1})
exten => _1X.,n,Wait(2)
exten => _1X.,n,Hangup()
tg_connect.py
#!/usr/bin/env python
import sys
import socket
import struct
import os
#import parser
from ConfigParser import SafeConfigParser
#store cmd line arg
new_txTg = sys.argv[1]
#strip off first character
#new_txTg = new_txTg[1:]
#read config file
parser = SafeConfigParser()
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "Existing talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
print "Desired talkgroup is: " + new_txTg
#set config file
parser.set('AMBE_AUDIO', 'txTg', new_txTg)
#writing our configuration file to
with open('/opt/Analog_Bridge/Analog_Bridge.ini', 'wb') as configfile:
parser.write(configfile)
#verify
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "New talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
#restart bridge
os.system('systemctl restart analog_bridge')
I didn't get Mike Z's code working out of the box and haven't had time to troubleshoot his yet. My setup allows you to enter *8711 and then the talkgroup number you want to connect to. the extenstions.conf will strip off the leading 1 and pass the variable into tg_connect.py. The python script will read the ini, update txTg, write the ini file(side effect of removing all comments), and restart the analog bridge. Backup your ini file first!
rpt.conf871 = autopatchup,context=command_radio,noct=1,farenddisconnect=1,dialtime=20000,quiet=1
extensions.conf[command_radio]
exten => _1X.,1,SayDigits(${EXTEN:1})
exten => _1X.,n,System(/scripts/tg_connect.py ${EXTEN:1})
exten => _1X.,n,Wait(2)
exten => _1X.,n,Hangup()
tg_connect.py
#!/usr/bin/env python
import sys
import socket
import struct
import os
#import parser
from ConfigParser import SafeConfigParser
#store cmd line arg
new_txTg = sys.argv[1]
#strip off first character
#new_txTg = new_txTg[1:]
#read config file
parser = SafeConfigParser()
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "Existing talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
print "Desired talkgroup is: " + new_txTg
#set config file
parser.set('AMBE_AUDIO', 'txTg', new_txTg)
#writing our configuration file to
with open('/opt/Analog_Bridge/Analog_Bridge.ini', 'wb') as configfile:
parser.write(configfile)
#verify
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "New talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
#restart bridge
os.system('systemctl restart analog_bridge')
The purpose of this list it to exchange information. Moving information exchange off list defeats that purpose.
Steve N4IRS
Could you please send me off list your python program and your modifying extensions . Conf. Thank you73 Neil k8itK8it@...
I didn't get Mike Z's code working out of the box and haven't had time to troubleshoot his yet. My setup allows you to enter *8711 and then the talkgroup number you want to connect to. the extenstions.conf will strip off the leading 1 and pass the variable into tg_connect.py. The python script will read the ini, update txTg, write the ini file(side effect of removing all comments), and restart the analog bridge. Backup your ini file first!
rpt.conf871 = autopatchup,context=command_radio,noct=1,farenddisconnect=1,dialtime=20000,quiet=1
extensions.conf[command_radio]
exten => _1X.,1,SayDigits(${EXTEN:1})
exten => _1X.,n,System(/scripts/tg_connect.py ${EXTEN:1})
exten => _1X.,n,Wait(2)
exten => _1X.,n,Hangup()
tg_connect.py
#!/usr/bin/env python
import sys
import socket
import struct
import os
#import parser
from ConfigParser import SafeConfigParser
#store cmd line arg
new_txTg = sys.argv[1]
#strip off first character
#new_txTg = new_txTg[1:]
#read config file
parser = SafeConfigParser()
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "Existing talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
print "Desired talkgroup is: " + new_txTg
#set config file
parser.set('AMBE_AUDIO', 'txTg', new_txTg)
#writing our configuration file to
with open('/opt/Analog_Bridge/Analog_Bridge.ini', 'wb') as configfile:
parser.write(configfile)
#verify
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "New talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
#restart bridge
os.system('systemctl restart analog_bridge')
I didn't get Mike Z's code working out of the box and haven't had time to troubleshoot his yet. My setup allows you to enter *8711 and then the talkgroup number you want to connect to. the extenstions.conf will strip off the leading 1 and pass the variable into tg_connect.py. The python script will read the ini, update txTg, write the ini file(side effect of removing all comments), and restart the analog bridge. Backup your ini file first!
rpt.conf871 = autopatchup,context=command_radio,noct=1,farenddisconnect=1,dialtime=20000,quiet=1
extensions.conf[command_radio]
exten => _1X.,1,SayDigits(${EXTEN:1})
exten => _1X.,n,System(/scripts/tg_connect.py ${EXTEN:1})
exten => _1X.,n,Wait(2)
exten => _1X.,n,Hangup()
tg_connect.py
#!/usr/bin/env python
import sys
import socket
import struct
import os
#import parser
from ConfigParser import SafeConfigParser
#store cmd line arg
new_txTg = sys.argv[1]
#strip off first character
#new_txTg = new_txTg[1:]
#read config file
parser = SafeConfigParser()
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "Existing talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
print "Desired talkgroup is: " + new_txTg
#set config file
parser.set('AMBE_AUDIO', 'txTg', new_txTg)
#writing our configuration file to
with open('/opt/Analog_Bridge/Analog_Bridge.ini', 'wb') as configfile:
parser.write(configfile)
#verify
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "New talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
#restart bridge
os.system('systemctl restart analog_bridge')
Here is a shell script for changing TGs on the fly when using Analog_Bridge and MMDVM bridge connected to BM.
#!/bin/bash
# /*
# * Copyright (C) 2018 N4IRR
# *
# * Permission to use, copy, modify, and/or distribute this software for any
# * purpose with or without fee is hereby granted, provided that the above
# * copyright notice and this permission notice appear in all copies.
# *
# * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH
# * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY
# * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,
# * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM
# * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE
# * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR
# * PERFORMANCE OF THIS SOFTWARE.
# */
function tune() {
python - <<END
#!/usr/bin/env python
import sys
import socket
import struct
cmd = "txTg=$1"
_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
cmd = struct.pack("BB", 0x05, len(cmd))[0:2] + cmd
# Set the second value below to match the rxPort in the [AMBE_AUDIO] stanza of Analog_Bridge.ini
_sock.sendto(cmd, ('127.0.0.1', 31100))
_sock.close()
END
}
tune $1
Don't forget to mark the script executable chmod +x tune.sh
Assuming the script is named tune.sh and the rxPort is set to 31100 in Analog_bridge.ini start the program with:
./tune.sh 1234
Where the desired TG is 1234
Send a quick PTT on the analog side and you will be tuned to TG 1234
There is quite a list of possible commands available. Some are dependent on the mode. Along with the other 1001 things we need to do we will try to get the info out.
Steve N4IRS
I didn't get Mike Z's code working out of the box and haven't had time to troubleshoot his yet. My setup allows you to enter *8711 and then the talkgroup number you want to connect to. the extenstions.conf will strip off the leading 1 and pass the variable into tg_connect.py. The python script will read the ini, update txTg, write the ini file(side effect of removing all comments), and restart the analog bridge. Backup your ini file first!
rpt.conf871 = autopatchup,context=command_radio,noct=1,farenddisconnect=1,dialtime=20000,quiet=1
extensions.conf[command_radio]
exten => _1X.,1,SayDigits(${EXTEN:1})
exten => _1X.,n,System(/scripts/tg_connect.py ${EXTEN:1})
exten => _1X.,n,Wait(2)
exten => _1X.,n,Hangup()
tg_connect.py
#!/usr/bin/env python
import sys
import socket
import struct
import os
#import parser
from ConfigParser import SafeConfigParser
#store cmd line arg
new_txTg = sys.argv[1]
#strip off first character
#new_txTg = new_txTg[1:]
#read config file
parser = SafeConfigParser()
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "Existing talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
print "Desired talkgroup is: " + new_txTg
#set config file
parser.set('AMBE_AUDIO', 'txTg', new_txTg)
#writing our configuration file to
with open('/opt/Analog_Bridge/Analog_Bridge.ini', 'wb') as configfile:
parser.write(configfile)
#verify
parser.read('/opt/Analog_Bridge/Analog_Bridge.ini')
print "New talkgroup is: " + parser.get('AMBE_AUDIO', 'txTg')
#restart bridge
os.system('systemctl restart analog_bridge')
Now we have a script to change TG "on the fly" Let's make it available to DTMF and Allmon.
First we need ASL to execute the script from within. There is more then one way to do this. I'll use the internal command.
Lets assume you placed the script in /usr/local/sbin and called it tune.sh
You can run the program from the Linux command prompt with /usr/local/sbin/tune.sh 1234 to tune to TG 1234
Let's add it to rpt.conf
To run a external script the ASL command is:
4321=cmd,/usr/local/sbin/tune.sh 1234 (This ASSUMES 4321 is not in use nor is 43 or 432)
When a user on the node sends *4321 ASL will execute the script /usr/local/sbin/tune.sh with a parameter of 1234
So far so good? Now let's add it to Allmon2
in the allmon directory is a file, controlpanel.ini in that file as a example you will find:
labels[] = "Say Time of Day (local only) the TT way"
Poof! you have added a command to Allmon2 which will tell ASL to execute the script.
Clear as mud?
73, Steve N4IRS
I've installed the script you've listed, but am getting an error message.
Hopefully you can help me out fixing it?
Any idea?
Do you need more information from me?
Matt
VE3OY
Please paste the script as you have it.
Steve
Steve,
I've installed the script you've listed, but am getting an error message.
Hopefully you can help me out fixing it?
[root@ve3xxx ~]# /usr/local/sbin/changeTG.sh 3023Traceback (most recent call last):File "<stdin>", line 9, in <module>TypeError: can't concat bytes to str
Any idea?
Do you need more information from me?
Matt
VE3OY
This is my script (changeTG.sh)
====
After doing some more research (about Python) it would seem that this is a known problem.
[SNIP]
Python3 has several different 'string' types.
You are trying to combine a bytes string (basically an immutable character array) to a unicode string.
[/SNIP]
I may have fixed the script by changing this one line:
cmd = "txTg=$1".encode("utf-8")
So far, it has not returned an error.
I can't test further until later tonight, but I am hoping this has fixed it.
I'll update later with any results.
====
A little more information ...
I am running "Asterisk 1.4.23-pre.hamvoip-V1.5.3-27-app_rpt-0.327-04/04/2018" which comes with Python 3.5.1
After reading more on this problem, it has been reported that the issue did not appear in Python 2.
I cannot confirm or deny the claim, but if anyone runs into this error - try the fix I've included above.
73 de Matt
VE3OY
I wanted to make sure you had no line wraps etc in the script. I am not getting the error.
Can you tell me the result of:
python -V
Steve
I just copied the script you posted above ...
This is my script (changeTG.sh)
#!/bin/bash# /*# * Copyright (C) 2018 N4IRR# *# * Permission to use, copy, modify, and/or distribute this software for any# * purpose with or without fee is hereby granted, provided that the above# * copyright notice and this permission notice appear in all copies.# *# * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH# * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY# * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,# * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM# * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE# * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR# * PERFORMANCE OF THIS SOFTWARE.# */function tune() {python - <<END#!/usr/bin/env pythonimport sysimport socketimport structcmd = "txTg=$1"_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)cmd = struct.pack("BB", 0x05, len(cmd))[0:2] + cmd# Set the second value below to match the rxPort in the [AMBE_AUDIO] stanza of Analog_Bridge.ini_sock.sendto(cmd, ('127.0.0.1', 31100))_sock.close()END}tune $1
Matt
I use Notepad+ for all editing, and so the first thing I checked was that my EOL coding was set to *nix.
I am running "Asterisk 1.4.23-pre.hamvoip-V1.5.3-27-app_rpt-0.327-04/04/2018" which comes with Python 3.5.1
python -V = Python 3.5.1
I can now confirm that changing the one line ...
cmd = "txTg=$1".encode("utf-8")
... works properly without any issues.
Dynamic change of TG's on demand is working great!
Thanks!
Matt
#!/bin/bash# /*# * Copyright (C) 2018 N4IRR# *# * Permission to use, copy, modify, and/or distribute this software for any# * purpose with or without fee is hereby granted, provided that the above# * copyright notice and this permission notice appear in all copies.# *# * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH# * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY# * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,# * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM# * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE# * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR# * PERFORMANCE OF THIS SOFTWARE.# */function tune() {python - <<END#!/usr/bin/env pythonimport sysimport socketimport structcmd = "txTg=$1".encode("utf-8")_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)cmd = struct.pack("BB", 0x05, len(cmd))[0:2] + cmd# Set the second value below to match the rxPort in the [AMBE_AUDIO] stanza of Analog_Bridge.ini_sock.sendto(cmd, ('127.0.0.1', 31100))_sock.close()END}tune $1
OK,
Now we have a script to change TG "on the fly" Let's make it available to DTMF and Allmon.
First we need ASL to execute the script from within. There is more then one way to do this. I'll use the internal command.
Lets assume you placed the script in /usr/local/sbin and called it tune.sh
You can run the program from the Linux command prompt with /usr/local/sbin/tune.sh 1234 to tune to TG 1234
Let's add it to rpt.conf
To run a external script the ASL command is:
4321=cmd,/usr/local/sbin/tune.sh 1234 (This ASSUMES 4321 is not in use nor is 43 or 432)
When a user on the node sends *4321 ASL will execute the script /usr/local/sbin/tune.sh with a parameter of 1234
So far so good? Now let's add it to Allmon2
in the allmon directory is a file, controlpanel.ini in that file as a example you will find:
labels[] = "Say Time of Day (local only) the TT way"cmds[] = "rpt fun %node% *74"Lets add a command. Copy and edit above:labels[] = "Tune DMR to Talk Group 1234"cmds[] = "rpt fun %node% *4321"
Poof! you have added a command to Allmon2 which will tell ASL to execute the script.
Clear as mud?
73, Steve N4IRS
[Edited Message Follows]
I just copied the script you posted above ...
This is my script (changeTG.sh)
#!/bin/bash# /*# * Copyright (C) 2018 N4IRR# *# * Permission to use, copy, modify, and/or distribute this software for any# * purpose with or without fee is hereby granted, provided that the above# * copyright notice and this permission notice appear in all copies.# *# * THE SOFTWARE IS PROVIDED "AS IS" AND ISC DISCLAIMS ALL WARRANTIES WITH# * REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF MERCHANTABILITY# * AND FITNESS. IN NO EVENT SHALL ISC BE LIABLE FOR ANY SPECIAL, DIRECT,# * INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES WHATSOEVER RESULTING FROM# * LOSS OF USE, DATA OR PROFITS, WHETHER IN AN ACTION OF CONTRACT, NEGLIGENCE# * OR OTHER TORTIOUS ACTION, ARISING OUT OF OR IN CONNECTION WITH THE USE OR# * PERFORMANCE OF THIS SOFTWARE.# */function tune() {python - <<END#!/usr/bin/env pythonimport sysimport socketimport structcmd = "txTg=$1"_sock = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)cmd = struct.pack("BB", 0x05, len(cmd))[0:2] + cmd# Set the second value below to match the rxPort in the [AMBE_AUDIO] stanza of Analog_Bridge.ini_sock.sendto(cmd, ('127.0.0.1', 31100))_sock.close()END}tune $1
====
After doing some more research (about Python) it would seem that this is a known problem.
[SNIP]
Python3 has several different 'string' types.
You are trying to combine a bytes string (basically an immutable character array) to a unicode string.
[/SNIP]
I may have fixed the script by changing this one line:
cmd = "txTg=$1".encode("utf-8")
So far, it has not returned an error.
I can't test further until later tonight, but I am hoping this has fixed it.
I'll update later with any results.
====
A little more information ...
I am running "Asterisk 1.4.23-pre.hamvoip-V1.5.3-27-app_rpt-0.327-04/04/2018" which comes with Python 3.5.1
After reading more on this problem, it has been reported that the issue did not appear in Python 2.
I cannot confirm or deny the claim, but if anyone runs into this error - try the fix I've included above.
73 de Matt
VE3OY