diff --git a/bridge_master.py b/bridge_master.py index a2f836b..bbd26ce 100644 --- a/bridge_master.py +++ b/bridge_master.py @@ -995,12 +995,13 @@ def _sendFilteredByTG(_sys_obj, pkt, _tg, _ts, _label, _pkt_idx): else: return 0 -def _announcementSendBroadcast(_targets, _pkts, _pkt_idx, _source_id, _dst_id, _tg, _ts, _ann_num=1, _next_time=None): +def _announcementSendBroadcast(_targets, _pkts_by_ts, _pkt_idx, _source_id, _dst_id, _tg, _ts_unused, _ann_num=1, _next_time=None): global _announcement_running _label = 'LOCUCION' if _ann_num == 1 else 'LOCUCION-{}'.format(_ann_num) - if _pkt_idx >= len(_pkts): + _total_pkts = len(_pkts_by_ts[1]) + if _pkt_idx >= _total_pkts: for _t in _targets: try: for _sid in list(_t['sys_obj'].STATUS.keys()): @@ -1009,17 +1010,18 @@ def _announcementSendBroadcast(_targets, _pkts, _pkt_idx, _source_id, _dst_id, _ except: pass _announcement_running[_ann_num] = False - logger.info('(%s) Broadcast complete: %s packets sent to %s systems', _label, len(_pkts), len(_targets)) + logger.info('(%s) Broadcast complete: %s packets sent to %s targets', _label, _total_pkts, len(_targets)) return _now = time() - pkt = _pkts[_pkt_idx] - _stream_id = pkt[16:20] for _t in _targets: try: _sys_obj = _t['sys_obj'] _slot = _t['slot'] + _t_ts = _t['ts'] + pkt = _pkts_by_ts[_t_ts][_pkt_idx] + _stream_id = pkt[16:20] if _stream_id not in _sys_obj.STATUS: _sys_obj.STATUS[_stream_id] = { 'START': _now, @@ -1032,11 +1034,11 @@ def _announcementSendBroadcast(_targets, _pkts, _pkt_idx, _source_id, _dst_id, _ else: _sys_obj.STATUS[_stream_id]['LAST'] = _now _slot['TX_TIME'] = _now - _fc = _sendFilteredByTG(_sys_obj, pkt, _tg, _ts, _label, _pkt_idx) + _fc = _sendFilteredByTG(_sys_obj, pkt, _tg, _t_ts, _label, _pkt_idx) if _pkt_idx == 0 and _fc == 0: - logger.debug('(%s) TG %s TS%s not active on %s, skipping', _label, _tg, _ts, _t['name']) + logger.debug('(%s) TG %s TS%s not active on %s, skipping', _label, _tg, _t_ts, _t['name']) except Exception as e: - logger.error('(%s) Error sending packet %s to %s: %s', _label, _pkt_idx, _t['name'], e) + logger.error('(%s) Error sending packet %s to %s/TS%s: %s', _label, _pkt_idx, _t['name'], _t.get('ts', '?'), e) _elapsed = time() - _now if _next_time is None: @@ -1046,9 +1048,9 @@ def _announcementSendBroadcast(_targets, _pkts, _pkt_idx, _source_id, _dst_id, _ _delay = max(0.001, _next_time - time()) if _pkt_idx < 3: - logger.debug('(%s) Packet %s/%s broadcast to %s systems (proc: %.1fms, delay: %.1fms)', _label, _pkt_idx + 1, len(_pkts), len(_targets), _elapsed * 1000, _delay * 1000) + logger.debug('(%s) Packet %s/%s broadcast to %s targets (proc: %.1fms, delay: %.1fms)', _label, _pkt_idx + 1, _total_pkts, len(_targets), _elapsed * 1000, _delay * 1000) - reactor.callLater(_delay, _announcementSendBroadcast, _targets, _pkts, _pkt_idx + 1, _source_id, _dst_id, _tg, _ts, _ann_num, _next_time) + reactor.callLater(_delay, _announcementSendBroadcast, _targets, _pkts_by_ts, _pkt_idx + 1, _source_id, _dst_id, _tg, _ts_unused, _ann_num, _next_time) def scheduledAnnouncement(_ann_num=1): global _announcement_last_hour, _announcement_running @@ -1075,14 +1077,12 @@ def scheduledAnnouncement(_ann_num=1): _file = CONFIG['GLOBAL']['{}_FILE'.format(_prefix)] _tg = CONFIG['GLOBAL']['{}_TG'.format(_prefix)] - _timeslot = CONFIG['GLOBAL']['{}_TIMESLOT'.format(_prefix)] _lang = CONFIG['GLOBAL']['{}_LANGUAGE'.format(_prefix)] - _slot_index = 2 if _timeslot == 2 else 1 _dst_id = bytes_3(_tg) _source_id = bytes_3(5000) _peer_id = CONFIG['GLOBAL']['SERVER_ID'] - logger.info('(%s) Playing file: %s to TG %s TS%s (mode: %s, lang: %s)', _label, _file, _tg, _timeslot, _mode, _lang) + logger.info('(%s) Playing file: %s to TG %s (both TS, mode: %s, lang: %s)', _label, _file, _tg, _mode, _lang) _say = [] try: @@ -1096,6 +1096,8 @@ def scheduledAnnouncement(_ann_num=1): logger.debug('(%s) AMBE file loaded, %s words', _label, len(_say)) + _tg_str = str(_tg) + _excluded = ['ECHO', 'D-APRS'] _targets = [] @@ -1124,28 +1126,47 @@ def scheduledAnnouncement(_ann_num=1): if _sn not in systems: continue - _slot = systems[_sn].STATUS[_slot_index] - if (_slot['RX_TYPE'] != HBPF_SLT_VTERM) or (_slot['TX_TYPE'] != HBPF_SLT_VTERM): - logger.debug('(%s) System %s busy, skipping', _label, _sn) + _active_slots = [] + if _tg_str in BRIDGES: + for _be in BRIDGES[_tg_str]: + if _be['SYSTEM'] == _sn and _be['ACTIVE'] and _be['TS'] not in _active_slots: + _active_slots.append(_be['TS']) + + if not _active_slots: continue - _targets.append({ - 'sys_obj': systems[_sn], - 'name': _sn, - 'slot': _slot - }) + for _ts in _active_slots: + _slot_index = 2 if _ts == 2 else 1 + _slot = systems[_sn].STATUS[_slot_index] + if (_slot['RX_TYPE'] != HBPF_SLT_VTERM) or (_slot['TX_TYPE'] != HBPF_SLT_VTERM): + logger.debug('(%s) System %s TS%s busy, skipping', _label, _sn, _ts) + continue + + _targets.append({ + 'sys_obj': systems[_sn], + 'name': _sn, + 'slot': _slot, + 'ts': _ts + }) if not _targets: - logger.info('(%s) No systems with connected peers to send to', _label) + logger.info('(%s) No systems with active bridge for TG %s to send to', _label, _tg) return - _pkts = list(pkt_gen(_source_id, _dst_id, _peer_id, _slot_index - 1, _say)) - _sys_names = ', '.join([t['name'] for t in _targets[:5]]) - if len(_targets) > 5: - _sys_names += ', ... +{}'.format(len(_targets) - 5) - logger.info('(%s) Broadcasting %s packets to %s systems simultaneously: %s', _label, len(_pkts), len(_targets), _sys_names) + _pkts_by_ts = { + 1: list(pkt_gen(_source_id, _dst_id, _peer_id, 0, _say)), + 2: list(pkt_gen(_source_id, _dst_id, _peer_id, 1, _say)), + } + + _ts1_count = sum(1 for t in _targets if t['ts'] == 1) + _ts2_count = sum(1 for t in _targets if t['ts'] == 2) + _sys_names = ', '.join(['{}/TS{}'.format(t['name'], t['ts']) for t in _targets[:8]]) + if len(_targets) > 8: + _sys_names += ', ... +{}'.format(len(_targets) - 8) + logger.info('(%s) Broadcasting %s packets to %s targets (TS1:%s TS2:%s): %s', + _label, len(_pkts_by_ts[1]), len(_targets), _ts1_count, _ts2_count, _sys_names) _announcement_running[_ann_num] = True - reactor.callLater(1.0, _announcementSendBroadcast, _targets, _pkts, 0, _source_id, _dst_id, _tg, _timeslot, _ann_num) + reactor.callLater(1.0, _announcementSendBroadcast, _targets, _pkts_by_ts, 0, _source_id, _dst_id, _tg, 0, _ann_num) def _checkVoiceConfigReload(): @@ -1189,11 +1210,10 @@ def _checkVoiceConfigReload(): _ann_def = _ann_task.start(_ann_check_interval, now=False) _ann_def.addErrback(loopingErrHandle) _ann_tasks[_ann_num] = _ann_task - logger.info('(VOICE-RELOAD) %s activada - mode: %s, file: %s, TG: %s, TS: %s', + logger.info('(VOICE-RELOAD) %s activada - mode: %s, file: %s, TG: %s, TS: auto', _label, _ann_mode, CONFIG['GLOBAL']['{}_FILE'.format(_prefix)], - CONFIG['GLOBAL']['{}_TG'.format(_prefix)], - CONFIG['GLOBAL']['{}_TIMESLOT'.format(_prefix)]) + CONFIG['GLOBAL']['{}_TG'.format(_prefix)]) for _tts_num in range(1, 5): _prefix = 'TTS_ANNOUNCEMENT{}'.format(_tts_num) @@ -1215,11 +1235,10 @@ def _checkVoiceConfigReload(): _tts_def = _tts_task.start(_tts_check_interval, now=False) _tts_def.addErrback(loopingErrHandle) _tts_tasks[_tts_num] = _tts_task - logger.info('(VOICE-RELOAD) %s activada - mode: %s, file: %s, TG: %s, TS: %s', + logger.info('(VOICE-RELOAD) %s activada - mode: %s, file: %s, TG: %s, TS: auto', _label, _tts_mode, CONFIG['GLOBAL']['{}_FILE'.format(_prefix)], - CONFIG['GLOBAL']['{}_TG'.format(_prefix)], - CONFIG['GLOBAL']['{}_TIMESLOT'.format(_prefix)]) + CONFIG['GLOBAL']['{}_TG'.format(_prefix)]) logger.info('(VOICE-RELOAD) Recarga de voice.cfg completada') @@ -3699,12 +3718,11 @@ if __name__ == '__main__': _ann_def = _ann_task.start(_ann_check_interval, now=False) _ann_def.addErrback(loopingErrHandle) _ann_tasks[_ann_num] = _ann_task - logger.info('(%s) Scheduled announcements enabled - mode: %s, file: %s, TG: %s, TS: %s, lang: %s', + logger.info('(%s) Scheduled announcements enabled - mode: %s, file: %s, TG: %s, TS: auto, lang: %s', _label, _ann_mode, CONFIG['GLOBAL']['{}_FILE'.format(_prefix)], CONFIG['GLOBAL']['{}_TG'.format(_prefix)], - CONFIG['GLOBAL']['{}_TIMESLOT'.format(_prefix)], CONFIG['GLOBAL']['{}_LANGUAGE'.format(_prefix)]) if _ann_mode == 'interval': logger.info('(%s) Interval: every %s seconds', _label, _ann_check_interval) @@ -3722,12 +3740,11 @@ if __name__ == '__main__': _tts_def = _tts_task.start(_tts_check_interval, now=False) _tts_def.addErrback(loopingErrHandle) _tts_tasks[_tts_num] = _tts_task - logger.info('(%s) Scheduled TTS announcements enabled - mode: %s, file: %s, TG: %s, TS: %s, lang: %s', + logger.info('(%s) Scheduled TTS announcements enabled - mode: %s, file: %s, TG: %s, TS: auto, lang: %s', _label, _tts_mode, CONFIG['GLOBAL']['{}_FILE'.format(_prefix)], CONFIG['GLOBAL']['{}_TG'.format(_prefix)], - CONFIG['GLOBAL']['{}_TIMESLOT'.format(_prefix)], CONFIG['GLOBAL']['{}_LANGUAGE'.format(_prefix)]) if _tts_mode == 'interval': logger.info('(%s) Interval: every %s seconds', _label, _tts_check_interval)