示例#1
0
    def _create_dmr_data(self):
        dmr_id_file = RadioWriter.input_writer('dmr_id.csv', '\n')
        dmr_id = DmrIdDefault({
            'radio_id': '00000',
            'name': 'DMR',
        })
        dmr_id_file.writerow(dmr_id.headers())
        dmr_id_file.writerow(dmr_id.output(1))
        dmr_id_file.close()

        digital_contacts_file = RadioWriter.input_writer(
            'digital_contacts.csv', '\n')
        analog_contact = DmrContactDefault({
            'digital_id':
            dmr_id.radio_id.fmt_val(),
            'name':
            'Analog',
            'call_type':
            'all',
        })
        group_contact = DmrContactDefault({
            'digital_id': 99999,
            'name': 'Some Repeater',
            'call_type': 'group',
        })

        digital_contacts_file.writerow(analog_contact.headers())
        digital_contacts_file.writerow(analog_contact.output(1))
        digital_contacts_file.writerow(group_contact.output(2))
        digital_contacts_file.close()
示例#2
0
 def _create_zone_data(self):
     zone_id_file = RadioWriter.input_writer('zones.csv', '\n')
     zone = RadioZoneDefault({
         'number': 1,
         'name': 'Zone 1',
     })
     zone_id_file.writerow(zone.headers())
     zone_id_file.writerow(zone.output())
     zone_id_file.close()
示例#3
0
 def _create_dmr_user_data(self):
     user_file = RadioWriter.input_writer('user.csv', '\n')
     dmr_user = DmrUserDefault({
         'RADIO_ID': '00000',
         'CALLSIGN': 'N0CALL',
         'FIRST_NAME': 'Sample',
         'LAST_NAME': 'User',
         'CITY': 'Somewhere',
         'STATE': 'Stateville',
         'COUNTRY': 'Theremany',
         'REMARKS': 'Sample Entry',
     })
     user_file.writerow(dmr_user.headers())
     user_file.writerow(dmr_user.output(None))
     user_file.close()
     return
示例#4
0
    def channels_to_file(self, channels):
        logging.info('Writing imported files.')
        headers = RadioChannelDefault.create_empty().headers()
        writer = RadioWriter.output_writer('import_result.csv', '\r\n')
        writer.writerow(headers)
        channel_num = 1
        for chan in channels:  # who is this for chan
            channel_default = RadioChannelBuilder.casted(
                chan, radio_types.DEFAULT)
            writer.writerow(channel_default.output(channel_num))
            channel_num += 1
        writer.close()

        result_path = PathManager.get_output_path('import_result.csv')
        logging.info(
            f'Import complete! Your imported file is in `{result_path}`')
示例#5
0
    def _output_radioids(self):
        logging.info(f"Writing {radio_types.D878} radio IDs")
        if self._dmr_ids is None:
            logging.error(f"No DMR ids found for {radio_types.D878}.")
            return

        radio_id_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_radioid.csv', '\r\n')

        headers = DmrIdD878.create_empty()
        radio_id_file.writerow(headers.headers())
        number = 1
        for dmr_id in self._dmr_ids.values():
            casted_id = DmrIdBuilder.casted(dmr_id, radio_types.D878)
            radio_id_file.writerow(casted_id.output(number))
            number += 1

        radio_id_file.close()
        return
示例#6
0
    def _output_zones(self):
        logging.info(f"Writing {radio_types.D878} zones")
        if self._zones is None:
            logging.error(f"No zones list found for {radio_types.D878}.")
            return

        zone_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_zone.csv', '\r\n')

        headers = RadioZoneD878.create_empty()
        zone_file.writerow(headers.headers())
        for zone in self._zones.values():
            if not zone.has_channels():
                continue
            casted_zone = RadioZoneBuilder.casted(zone.cols,
                                                  zone._associated_channels,
                                                  radio_types.D878)
            zone_file.writerow(casted_zone.output())

        zone_file.close()
示例#7
0
    def _output_contacts(self):
        logging.info(f"Writing {radio_types.D878} contacts")
        if self._digital_contacts is None:
            logging.error(f"No digital contacts found for {radio_types.D878}.")
            return

        dmr_contact_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_talkgroup.csv', '\r\n')

        headers = DmrContactD878.create_empty()
        dmr_contact_file.writerow(headers.headers())
        number = 1
        for dmr_contact in self._digital_contacts.values():
            casted_contact = DmrContactBuilder.casted(dmr_contact,
                                                      radio_types.D878)
            row_data = casted_contact.output(number)
            dmr_contact_file.writerow(row_data)
            number += 1

        dmr_contact_file.close()
    def output(self):
        gpx = gpxpy.gpx.GPX()
        gpx.name = 'Ham Radio Stations'
        gpx.description = 'Ham radio station locations generated by Ham Radio Sync'

        for channel in self._channels:
            if channel.latitude.fmt_val() is None or channel.longitude.fmt_val(
            ) is None:
                continue

            gpx_waypoint = gpxpy.gpx.GPXWaypoint()
            gpx_waypoint.latitude = channel.latitude.fmt_val()
            gpx_waypoint.longitude = channel.longitude.fmt_val()
            gpx_waypoint.name = channel.name.fmt_val()
            gpx_waypoint.description = self._get_description(channel)
            gpx.waypoints.append(gpx_waypoint)

        xml = gpx.to_xml()
        writer = RadioWriter.output_writer(
            f'{radio_types.GPX}/ham_radio_sync.gpx', '\r\n')
        writer.write_raw(xml)
        writer.close()
示例#9
0
    def _output_user(self):
        logging.info(f"Writing {radio_types.D878} users")
        if self._users is None:
            logging.error(f"No zones list found for {radio_types.D878}.")
            return

        users_file = RadioWriter.output_writer(
            f'{radio_types.D878}/{radio_types.D878}_digital_contacts.csv',
            '\n')

        headers = DmrUserD878.create_empty()
        users_file.writerow(headers.headers())

        rows_processed = 1
        for user in self._users.values():
            casted_user = DmrUserBuilder.casted(user.cols, radio_types.D878)
            users_file.writerow(casted_user.output(None))
            rows_processed += 1
            logging.debug(f"Writing user row {rows_processed}")
            if rows_processed % file_util.USER_LINE_LOG_INTERVAL == 0:
                logging.info(f"Writing user row {rows_processed}")

        users_file.close()
示例#10
0
 def _create_channel_file(self):
     channel_file = RadioWriter.input_writer('input.csv', '\n')
     first_channel = RadioChannelDefault(
         {
             'name': 'National 2m',
             'medium_name': 'Natl 2m',
             'short_name': 'NATL 2M',
             'zone_id': '',
             'rx_freq': '146.520',
             'rx_ctcss': '',
             'rx_dcs': '',
             'rx_dcs_invert': '',
             'tx_power': 'Low',
             'tx_offset': '',
             'tx_ctcss': '',
             'tx_dcs': '',
             'tx_dcs_invert': '',
             'digital_timeslot': '',
             'digital_color': '',
             'digital_contact_id': '',
             'latitude': '',
             'longitude': '',
         },
         digital_contacts=None,
         dmr_ids=None)
     second_channel = RadioChannelDefault(
         {
             'name': 'Basic Repeater',
             'medium_name': 'BasicRpt',
             'short_name': 'BASRPTR',
             'zone_id': '1',
             'rx_freq': '145.310',
             'rx_ctcss': '',
             'rx_dcs': '',
             'rx_dcs_invert': '',
             'tx_power': 'High',
             'tx_offset': '-0.600',
             'tx_ctcss': '88.5',
             'tx_dcs': '',
             'tx_dcs_invert': '',
             'digital_timeslot': '',
             'digital_color': '',
             'digital_contact_id': '',
             'latitude': '',
             'longitude': '',
         },
         digital_contacts=None,
         dmr_ids=None)
     third_channel = RadioChannelDefault(
         {
             'name': 'DMR Repeater',
             'medium_name': 'DMR Rpt',
             'short_name': 'DMR RPT',
             'zone_id': '1',
             'rx_freq': '144.310',
             'rx_ctcss': '',
             'rx_dcs': '',
             'rx_dcs_invert': '',
             'tx_power': 'High',
             'tx_offset': '-0.600',
             'tx_ctcss': '',
             'tx_dcs': '',
             'tx_dcs_invert': '',
             'digital_timeslot': '1',
             'digital_color': '4',
             'digital_contact_id': '99999',
             'latitude': '',
             'longitude': '',
         },
         digital_contacts=None,
         dmr_ids=None)
     fourth_channel = RadioChannelDefault(
         {
             'name': 'Has lat and long',
             'medium_name': 'lat long',
             'short_name': 'latlong',
             'zone_id': '',
             'rx_freq': '146.520',
             'rx_ctcss': '',
             'rx_dcs': '',
             'rx_dcs_invert': '',
             'tx_power': 'Low',
             'tx_offset': '',
             'tx_ctcss': '',
             'tx_dcs': '',
             'tx_dcs_invert': '',
             'digital_timeslot': '',
             'digital_color': '',
             'digital_contact_id': '',
             'latitude': '38.903450',
             'longitude': '-77.007470',
         },
         digital_contacts=None,
         dmr_ids=None)
     channel_file.writerow(first_channel.headers())
     channel_file.writerow(
         RadioChannelBuilder.casted(first_channel,
                                    radio_types.DEFAULT).output(1))
     channel_file.writerow(
         RadioChannelBuilder.casted(second_channel,
                                    radio_types.DEFAULT).output(2))
     channel_file.writerow(
         RadioChannelBuilder.casted(third_channel,
                                    radio_types.DEFAULT).output(3))
     channel_file.writerow(
         RadioChannelBuilder.casted(fourth_channel,
                                    radio_types.DEFAULT).output(4))
     channel_file.close()
示例#11
0
    def generate_all_declared(self):
        file_errors = self._validator.validate_files_exist()
        self._validator.flush_names()
        if len(file_errors) > 0:
            return False

        results = self._migrations.check_migrations_needed()
        if len(results.keys()) > 0:
            logging.warning(
                'You may be using an old version of the input files. Have you run migrations?'
            )
            logging.warning("Migrations check is under the 'File' menu.")
            sleep(1)

        for radio in radio_types.radio_choices():
            radio_folder = PathManager.get_output_path(radio)
            if not os.path.exists(radio_folder):
                continue
            logging.info(f'Deleting old output folder `{radio}`')
            FileUtil.safe_delete_dir(radio_folder)

        digital_contacts, digi_contact_errors = self._generate_digital_contact_data(
        )
        dmr_ids, dmr_id_errors = self._generate_dmr_id_data()
        zones, zone_errors = self._generate_zone_data()
        user, user_data_errors = self._generate_user_data()
        preload_errors = digi_contact_errors + dmr_id_errors + zone_errors + user_data_errors

        feed = PathManager.open_input_file('input.csv', 'r')
        csv_reader = csv.DictReader(feed)

        radio_channel_errors = []
        radio_channels = []
        line_num = 1
        for line in csv_reader:
            line_errors = self._validator.validate_radio_channel(
                line, line_num, feed.name, digital_contacts, zones)
            radio_channel_errors += line_errors
            line_num += 1

            if len(line_errors) > 0:
                continue

            radio_channel = RadioChannel(line, digital_contacts, dmr_ids)
            radio_channels.append(radio_channel)

            if radio_channel.zone_id.fmt_val(None) is not None:
                zones[radio_channel.zone_id.fmt_val()].add_channel(
                    radio_channel)
        feed.close()

        all_errors = preload_errors + radio_channel_errors
        if len(all_errors) > 0:
            logging.error('--- VALIDATION ERRORS, CANNOT CONTINUE ---')
            for err in all_errors:
                logging.error(
                    f'\t\tfile: `{err.file_name}` line:{err.line_num} validation error: {err.message}'
                )
            return False
        else:
            logging.info(
                'File validation complete, no obvious formatting errors found')

        radio_files = dict()
        headers_gen = RadioChannel.create_empty()
        FileUtil.safe_create_dir('out')

        channel_numbers = dict()
        for radio in self.radio_list:
            radio_casted = RadioChannelBuilder.casted(headers_gen, radio)
            FileUtil.safe_create_dir(f'out/{radio}')
            logging.info(f'Generating for radio type `{radio}`')

            if radio_casted.skip_radio_csv():
                logging.info(
                    f'`{radio}` uses special output style. Skipping channels csv'
                )
                continue
            output = RadioWriter.output_writer(f'{radio}/{radio}_channels.csv',
                                               '\r\n')
            file_headers = radio_casted.headers()
            output.writerow(file_headers)
            radio_files[radio] = output
            channel_numbers[radio] = 1

        logging.info('Processing radio channels')
        line = 1
        for radio_channel in radio_channels:
            logging.debug(f'Processing radio line {line}')
            if line % file_util.RADIO_LINE_LOG_INTERVAL == 0:
                logging.info(f'Processing radio line {line}')
            line += 1
            for radio in self.radio_list:
                if radio not in radio_files.keys():
                    continue

                if not radio_types.supports_dmr(
                        radio) and radio_channel.is_digital():
                    continue

                casted_channel = RadioChannelBuilder.casted(
                    radio_channel, radio)

                input_data = casted_channel.output(channel_numbers[radio])
                radio_files[radio].writerow(input_data)
                channel_numbers[radio] += 1

        additional_data = RadioAdditional(radio_channels, dmr_ids,
                                          digital_contacts, zones, user)
        for radio in self.radio_list:
            if radio in radio_files.keys():
                radio_files[radio].close()
            casted_additional_data = RadioAdditionalBuilder.casted(
                additional_data, radio)
            casted_additional_data.output()

        logging.info(f'''Radio generator complete. Your output files are in 
					`{os.path.abspath('out')}`
					The next step is to import these files into your radio programming application. (e.g. CHiRP)'''
                     )
        return True