import os import re import time import discord import sound import configparser from discord.ext import commands from subprocess import Popen, PIPE # Init class for bot class Bot(commands.Bot): def __init__(self, **kwargs): # If there is no custom command prefix (!help, ?help, etc.), use '>!' but also accept @ mentions if 'command_prefix' not in kwargs.keys(): kwargs['command_prefix'] = '>!' commands.Bot.__init__(self, command_prefix=commands.when_mentioned_or(kwargs['command_prefix']), activity=discord.Game(name=f"@me"), status=discord.Status.idle) # Init the core bot variables self.DEVICE_ID = kwargs['Device_ID'] self.DEVICE_NAME = kwargs['Device_Name'] self.BOT_TOKEN = kwargs['Token'] self.Default_Channel_ID = kwargs['Channel_ID'] self.Default_Mention_Group = kwargs['Mention_Group'] # Init the audio devices list self.Devices_List = sound.query_devices().items() # Init radio parameters self.profile_name = None self.freq = "104.7M" self.freq_re = re.compile('(\d+\.?\d*M)') self.mode = "wbfm" self.gain = 40 self.squelch = 0 self.sample_rate = "200k" self.play_sample_rate = '32k' self.sample_rate_re = re.compile('(\d+\.?\d*k)') # Init SDR Variables self.sdr_process = None self.system_os_type = None self.sdr_output_process = None self.sdr_started = False # Set linux or windows self.check_os_type() # Add discord commands to the bot self.add_commands() # Check the ./modules folder for any modules (cog.py) self.check_for_modules() # Start the bot def start_bot(self): self.run(self.BOT_TOKEN) # Add discord commands to the bot def add_commands(self): # Test command to see if the bot is on (help command can also be used) @self.command(help="Use this to test if the bot is alive", brief="Sends a 'pong' in response") async def ping(ctx): await ctx.send('pong') # Command to join the bot the voice channel the user who called the command is in @self.command(help="Use this command to join the bot to your channel", brief="Joins the voice channel that the caller is in") async def join(ctx, *, member: discord.Member = None): member = member or ctx.author.display_name # Wait for the bot to be ready to connect await self.wait_until_ready() # Load respective opus library self.load_opus() if discord.opus.is_loaded(): # Create an audio stream from selected device stream = sound.PCMStream() channel = ctx.author.voice.channel await ctx.send(f"Ok {member}, I'm joining {channel}") # Ensure the selected device is available and start the audio stream stream.change_device(self.DEVICE_ID) # Join the voice channel with the audio stream voice_connection = await channel.connect() voice_connection.play(discord.PCMAudio(stream)) # Start the SDR and begin playing to the audio stream self.start_sdr() # Change the activity to the channel and band-type being used self.set_activity() else: # Return that the opus library would not load await ctx.send("Opus won't load") @self.command(help="Use this command to have the bot leave your channel", brief="Leaves the current voice channel") async def leave(ctx): # Disconnect the client from the voice channel await ctx.voice_client.disconnect() # Change the presence to away and '@ me' self.set_activity(False) # Stop the SDR so it can cool off self.stop_sdr() @self.command(name='chfreq', help="Use this command to change the frequency the bot is listening to. Note: 'M'" "is required\nExample command: '@ chfreq wbfm 104.7M\n" "Example command: '@ chfreq fm 154.785M", brief="Changes radio frequency") async def chfreq(ctx, mode: str, freq: str, member: discord.Member = None): # Possible band-types that can be used possible_modes = ['wbfm', 'fm'] member = member or ctx.author.display_name # Check to make sure the frequency input matches the syntax needed if self.freq_re.search(freq): self.freq = freq # Check to make sure the selected mode is valid if mode in possible_modes: self.mode = mode await ctx.send(f"Ok {member}, I'm changing the mode to {str(self.mode).upper()} and frequency to" f" {self.freq}") # If the SDR is started, restart it with the updates if self.sdr_started: self.start_sdr() self.set_activity() else: await ctx.send(f"{member}, {mode} is not valid. You may only enter 'fm' or 'wbfm'") else: await ctx.send(f"{member}, {freq} is not valid. please refer to the help page '@ help chfreq'") @self.command(name='chsquelch', help="Use this command to change the squelch for the frequency" "the bot is listening to", brief="Changes radio squelch") async def chsquelch(ctx, squelch: int, member: discord.Member = None): member = member or ctx.author.display_name self.squelch = squelch await ctx.send(f"Ok {member}, I'm changing the squelch to {self.squelch}") # If the SDR is started, restart it with the updates if self.sdr_started: self.start_sdr() @self.command(name='chgain', help="Use this command to change the radio gain for the bot", brief="Changes radio gain") async def chgain(ctx, gain: int, member: discord.Member = None): member = member or ctx.author.display_name self.gain = gain await ctx.send(f"Ok {member}, I have changed the gain to {self.gain}") # If the SDR is started, restart it with the updates if self.sdr_started: self.start_sdr() @self.command(name='chbw', help="Use this command to change the center frequency bandwidth for the bot." "Note: 'k' is required\nExample Command: '@ chbw