diff --git a/scenes/nine-patch-button.gd b/scenes/nine-patch-button.gd index 3179f104..f810563d 100644 --- a/scenes/nine-patch-button.gd +++ b/scenes/nine-patch-button.gd @@ -4,28 +4,28 @@ extends PanelContainer @export var texture_state0: Texture2D = preload('res://data/кнопка-квадрат-0.png'): - set(val): $state.set_texture(val) + set(val): $state.set_texture(val) @export var texture_state1: Texture2D = preload('res://data/кнопка-квадрат-1.png'): - set(val): $state.set_texture(val) + set(val): $state.set_texture(val) @export var text: String = '': - set(val): $button.set_text(val) - get: return $button.get_text() + set(val): $button.set_text(val) + get: return $button.get_text() @export var pressed: bool = false: - set(val): $button.set_pressed(val) - get: return $button.is_pressed() + set(val): $button.set_pressed(val) + get: return $button.is_pressed() @export var toggle_mode: bool = false: - set(val): - if is_inside_tree(): - $button.set_toggle_mode(val) - get: return $button.is_toggle_mode() + set(val): + if is_inside_tree(): + $button.set_toggle_mode(val) + get: return $button.is_toggle_mode() func set_text (val: String): $button.set_text(val) @@ -33,8 +33,8 @@ func set_pressed (val: bool): $button.set_pressed(val) func set_toggle_mode (val: bool): - if is_inside_tree(): - $button.set_toggle_mode(val) + if is_inside_tree(): + $button.set_toggle_mode(val) func get_text(): return $button.get_text() @@ -43,9 +43,9 @@ func is_toggle_mode(): return $button.is_toggle_mode() func _on_button_toggled(val: bool): - if val: $state.set_texture(texture_state1) - else: $state.set_texture(texture_state0) + if val: $state.set_texture(texture_state1) + else: $state.set_texture(texture_state0) func button_connect(button_signal: String, proc: Callable): - $button.connect(button_signal, proc) + $button.connect(button_signal, proc) diff --git a/scenes/tab_switch.tscn b/scenes/tab_switch.tscn index 32af829b..46db2b10 100644 --- a/scenes/tab_switch.tscn +++ b/scenes/tab_switch.tscn @@ -1,10 +1,10 @@ -[gd_scene load_steps=5 format=3 uid="uid://3slb0i3pvowc"] +[gd_scene load_steps=6 format=3 uid="uid://3slb0i3pvowc"] [ext_resource type="Script" path="res://scenes/tab_switch.gd" id="1_33fiq"] [ext_resource type="PackedScene" uid="uid://b276iygic5itk" path="res://scenes/работа.tscn" id="1_uow82"] [ext_resource type="PackedScene" uid="uid://lwmw4egynmd1" path="res://scenes/контроль.tscn" id="2_83m7a"] [ext_resource type="PackedScene" uid="uid://trt0q8th3bn2" path="res://scenes/журнал.tscn" id="3_hgnup"] -[ext_resource type="PackedScene" uid="uid://c6uls7q4e2m4h" path="res://scenes/ЭМС.tscn" id="4_2bmbm"] +[ext_resource type="PackedScene" path="res://scenes/ЭМС.tscn" id="4_2bmbm"] [node name="tab_switch" type="TabContainer"] offset_right = 1600.0 diff --git a/scenes/ЭМС.gd b/scenes/ЭМС.gd index b11ceafa..de894cdf 100644 --- a/scenes/ЭМС.gd +++ b/scenes/ЭМС.gd @@ -9,38 +9,38 @@ var CellOptBtn = preload('res://scenes/кнопка-5.tscn') # Таблица с данными для входов, первое значение - индекс устройства в ячейке КЭМС const INPUT_ROWS = [ - [1,['НРЛС МР-231S, УИЗП', 'X31', '0', '0']], - [2,['НРЛС МР-231S, Строб ЭМС', 'X32', '0', '0']], - [3,['НРЛС МР-231-3, УИЗП', 'X34', '0', '0']], - [4,['НРЛС МР-231-3, Строб ЭМС', 'X35', '0', '0']], - [5,['ЦИСВС-1010, УИЗП', 'X43', '0', '0']], - [8,['4302-01, 4302-04, УИЗП', 'X46', '0', '0']], - [11,['НРЛС МР-231S, УИЗП', 'X51', '0', '0']], - [12,['НРЛС МР-231S, Строб ЭМС', 'X52', '0', '0']], - [13,['НРЛС МР-231-3, УИЗП', 'X54', '0', '0']], - [14,['НРЛС МР-231-3, Строб ЭМС', 'X55', '0', '0']], - [15,['ЦИСВС-1010, УИЗП', 'X23', '0', '0']], - [21,['НРЛС МР-231S, УИЗП', 'X21', '0', '0']], - [22,['НРЛС МР-231S, Строб ЭМС', 'X22', '0', '0']], - [23,['НРЛС МР-231-3, УИЗП', 'X24', '0', '0']], - [24,['НРЛС МР-231-3, Строб ЭМС', 'X25', '0', '0']], - [25,['ЦИСВС-1010, УИЗП', 'X23', '0', '0']]] + [1,['НРЛС МР-231S, УИЗП', 'X31', '0', '0']], + [2,['НРЛС МР-231S, Строб ЭМС', 'X32', '0', '0']], + [3,['НРЛС МР-231-3, УИЗП', 'X34', '0', '0']], + [4,['НРЛС МР-231-3, Строб ЭМС', 'X35', '0', '0']], + [5,['ЦИСВС-1010, УИЗП', 'X43', '0', '0']], + [8,['4302-01, 4302-04, УИЗП', 'X46', '0', '0']], + [11,['НРЛС МР-231S, УИЗП', 'X51', '0', '0']], + [12,['НРЛС МР-231S, Строб ЭМС', 'X52', '0', '0']], + [13,['НРЛС МР-231-3, УИЗП', 'X54', '0', '0']], + [14,['НРЛС МР-231-3, Строб ЭМС', 'X55', '0', '0']], + [15,['ЦИСВС-1010, УИЗП', 'X23', '0', '0']], + [21,['НРЛС МР-231S, УИЗП', 'X21', '0', '0']], + [22,['НРЛС МР-231S, Строб ЭМС', 'X22', '0', '0']], + [23,['НРЛС МР-231-3, УИЗП', 'X24', '0', '0']], + [24,['НРЛС МР-231-3, Строб ЭМС', 'X25', '0', '0']], + [25,['ЦИСВС-1010, УИЗП', 'X23', '0', '0']]] # Таблица с данными для выходов, первое значение - индекс устройства в ячейке КЭМС const OUTPUT_ROWS = [ - [41,['НРЛС МР-231S, БИ', 'X61', '0', '0']], - [42,['НРЛС МР-231S', 'X62', '0', '0']], - [43,['НРЛС МР-231-3, БИ', 'X64', '0', '0']], - [44,['НРЛС МР-231-3', 'X65', '0', '0']], - [45,['ЦИСВС-1010, БИ', 'X63', '0', '0']], - [46,['4302-01, 4302-04, БИ', 'X66', '0', '0']], - [48,['НРЛС 11111111', 'X69', '0', '0']], - [49,['НРЛС-222222, БИ', 'X62', '0', '0']]] - + [41,['НРЛС МР-231S, БИ', 'X61', '0', '0']], + [42,['НРЛС МР-231S', 'X62', '0', '0']], + [43,['НРЛС МР-231-3, БИ', 'X64', '0', '0']], + [44,['НРЛС МР-231-3', 'X65', '0', '0']], + [45,['ЦИСВС-1010, БИ', 'X63', '0', '0']], + [46,['4302-01, 4302-04, БИ', 'X66', '0', '0']], + [48,['НРЛС 11111111', 'X69', '0', '0']], + [49,['НРЛС-222222, БИ', 'X62', '0', '0']]] + # Режимы работы выходов const OUT_MODE: Array = ['Работа', 'Контроль', '1', '0'] const COLUMN_OPTS_BTN: Array = [6] - + const TABLE_ENTRY_COLUMNS: Array = [2,3,5] var g_in_devices : Dictionary # Словарь с входными устройствами КЭМС @@ -50,141 +50,141 @@ var posx: int = 50 # Позиция элементов по x var posy: int = 80 # Позиция элементов по y func _ready() -> void: - $tbl_in.set_position(Vector2(posx,posy)) - $tbl_out.set_position(Vector2(posx,len(INPUT_ROWS)*33+posy+10)) - $tbl_files.set_position(Vector2(posx + 890,len(INPUT_ROWS)*33+posy+300)) - $btn_new.set_position(Vector2(posx + 1270,len(INPUT_ROWS)*33+posy+294)) - $btn_save.set_position(Vector2(posx + 1270,len(INPUT_ROWS)*33+posy+344)) - $btn_edit.set_position(Vector2(posx + 1270,len(INPUT_ROWS)*33+posy+394)) - $lbl_online.set_position(Vector2(posx,posy-40)) - $marker_in.set_position(Vector2(posx-15,posy+35)) - $marker_out.set_position(Vector2(posx-15,len(INPUT_ROWS)*33+posy+45)) - $btn_flash_read.set_position(Vector2(posx+1400,posy)) - $btn_flash_write.set_position(Vector2(posx+1400,posy+35)) - call_deferred('init_tbl_out') - call_deferred('init_tbl_in') - call_deferred('init_tbl_files') - $btn_flash_read.button_connect('pressed', Callable(self, 'on_btn_flash_read').bind($btn_flash_read)) - $btn_flash_write.button_connect('pressed', Callable(self, 'on_btn_flash_write').bind($btn_flash_write)) - $tbl_in.connect('row_pressed', Callable(self, 'on_row_pressed')) - $tbl_out.connect('row_pressed', Callable(self, 'on_row_pressed')) + $tbl_in.set_position(Vector2(posx,posy)) + $tbl_out.set_position(Vector2(posx,len(INPUT_ROWS)*33+posy+10)) + $tbl_files.set_position(Vector2(posx + 890,len(INPUT_ROWS)*33+posy+300)) + $btn_new.set_position(Vector2(posx + 1270,len(INPUT_ROWS)*33+posy+294)) + $btn_save.set_position(Vector2(posx + 1270,len(INPUT_ROWS)*33+posy+344)) + $btn_edit.set_position(Vector2(posx + 1270,len(INPUT_ROWS)*33+posy+394)) + $lbl_online.set_position(Vector2(posx,posy-40)) + $marker_in.set_position(Vector2(posx-15,posy+35)) + $marker_out.set_position(Vector2(posx-15,len(INPUT_ROWS)*33+posy+45)) + $btn_flash_read.set_position(Vector2(posx+1400,posy)) + $btn_flash_write.set_position(Vector2(posx+1400,posy+35)) + call_deferred('init_tbl_out') + call_deferred('init_tbl_in') + call_deferred('init_tbl_files') + $btn_flash_read.button_connect('pressed', Callable(self, 'on_btn_flash_read').bind($btn_flash_read)) + $btn_flash_write.button_connect('pressed', Callable(self, 'on_btn_flash_write').bind($btn_flash_write)) + $tbl_in.connect('row_pressed', Callable(self, 'on_row_pressed')) + $tbl_out.connect('row_pressed', Callable(self, 'on_row_pressed')) func on_btn_flash_read(btn): - await get_tree().create_timer(0.1).timeout - btn.pressed = false + await get_tree().create_timer(0.1).timeout + btn.pressed = false func on_btn_flash_write(btn): - await get_tree().create_timer(0.1).timeout - btn.pressed = false + await get_tree().create_timer(0.1).timeout + btn.pressed = false func on_row_pressed(i_row: int): - $tbl_in.set_row_selected(i_row, false) + $tbl_in.set_row_selected(i_row, false) func init_tbl_files(): - $tbl_files.set_header([TableHeader, TableHeader, TableHeader]) - $tbl_files.set_header_text(['Имя файла', 'Размер', 'Дата']) - $tbl_files.set_columns_min_size([200, 70, 100]) - - + $tbl_files.set_header([TableHeader, TableHeader, TableHeader]) + $tbl_files.set_header_text(['Имя файла', 'Размер', 'Дата']) + $tbl_files.set_columns_min_size([200, 70, 100]) + + func init_tbl_out(): - var header_text = ['Выходы', 'Разъём', 'мкс', 'мкс', 'Состояние', 'Частота, Мгц', 'Режим'] - $tbl_out.set_header([TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader]) - $tbl_out.set_header_text(header_text) - for item in OUTPUT_ROWS: - $tbl_out.add_row([TableNode, TableNode, CellLineEdit, CellLineEdit, CellState, CellLineEdit, CellOptBtn]) - var row_index : int = $tbl_out.get_rows_count() - 1 - var params : Array = item[1] - var out_dev = YemsDevs.OutDev.new(item[0], params, row_index) - g_out_devices[item[0]] = out_dev - for i in range(len(header_text)): - if i < len(params): - var cell = $tbl_out.get_node2(i, row_index) - cell.text = params[i] - $tbl_out.set_node_user_data(i, row_index, out_dev) - if i in COLUMN_OPTS_BTN: - var cell = $tbl_out.get_node2(i, row_index) - for opt in OUT_MODE: - cell.add_item(opt) - cell.select(0) - $tbl_out.set_columns_min_size([270, 100, 70, 70, 100, 100, 100]) - $tbl_out.set_callbacks(self, 'text_submitted', 'on_edit_entry_in', TABLE_ENTRY_COLUMNS, []) - $tbl_out.set_callbacks(self, 'item_selected', 'on_item_selected', COLUMN_OPTS_BTN, []) - - + var header_text = ['Выходы', 'Разъём', 'мкс', 'мкс', 'Состояние', 'Частота, Мгц', 'Режим'] + $tbl_out.set_header([TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader]) + $tbl_out.set_header_text(header_text) + for item in OUTPUT_ROWS: + $tbl_out.add_row([TableNode, TableNode, CellLineEdit, CellLineEdit, CellState, CellLineEdit, CellOptBtn]) + var row_index : int = $tbl_out.get_rows_count() - 1 + var params : Array = item[1] + var out_dev = YemsDevs.OutDev.new(item[0], params, row_index) + g_out_devices[item[0]] = out_dev + for i in range(len(header_text)): + if i < len(params): + var cell = $tbl_out.get_node2(i, row_index) + cell.text = params[i] + $tbl_out.set_node_user_data(i, row_index, out_dev) + if i in COLUMN_OPTS_BTN: + var cell = $tbl_out.get_node2(i, row_index) + for opt in OUT_MODE: + cell.add_item(opt) + cell.select(0) + $tbl_out.set_columns_min_size([270, 100, 70, 70, 100, 100, 100]) + $tbl_out.set_callbacks(self, 'text_submitted', 'on_edit_entry_in', TABLE_ENTRY_COLUMNS, []) + $tbl_out.set_callbacks(self, 'item_selected', 'on_item_selected', COLUMN_OPTS_BTN, []) + + func init_tbl_in(): - var header_type: Array = [TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader] - var header_text: Array = ['Входы', 'Разъём', 'мкс', 'мкс', 'Состояние', 'Частота, Мгц',' '] - var row_type: Array = [TableNode, TableNode, CellLineEdit, CellLineEdit, CellState, CellLineEdit, TableNode] - var yams_alligment_in: Array = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] - var column_size: Array = [270, 100, 70, 70, 100, 100, 300] - var dot_collums: Array - var column_offset: int = 7 - for i in range(len(OUTPUT_ROWS)): - header_type.append(TableHeader) - header_text.append('...') - row_type.append(CellYemsButton) - yams_alligment_in.append(HORIZONTAL_ALIGNMENT_LEFT) - column_size.append(25) - dot_collums.append(column_offset+i) - $tbl_in.set_header(header_type) - $tbl_in.set_header_text(header_text) - $tbl_in.set_columns_alignments(yams_alligment_in) - for item in INPUT_ROWS: - $tbl_in.add_row(row_type) - var row_index : int = $tbl_in.get_rows_count() - 1 - var params : Array = item[1] - var in_dev: YemsDevs.InDev = YemsDevs.InDev.new(item[0], params, row_index) - g_in_devices[item[0]] = in_dev - for i in range(len(row_type)): - if i < len(params): - var node = $tbl_in.get_node2(i, row_index) - node.text = params[i] - if i in dot_collums: - var btn = $tbl_in.get_node2(i, row_index) - var out_dev = g_out_devices[OUTPUT_ROWS[i-column_offset][0]] - in_dev.out_dots = [btn, out_dev] - btn.button_connect('pressed', Callable(self, 'on_dot_button').bind(btn, i, row_index)) - btn.connect('mouse_entered', Callable(self, 'on_mouse_entered').bind(btn, i - dot_collums[0], row_index)) - $tbl_in.set_node_user_data(i, row_index, in_dev) - $tbl_in.set_columns_min_size(column_size) - $tbl_in.set_callbacks(self, 'text_submitted', 'on_edit_entry_in', TABLE_ENTRY_COLUMNS, []) - - + var header_type: Array = [TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader, TableHeader] + var header_text: Array = ['Входы', 'Разъём', 'мкс', 'мкс', 'Состояние', 'Частота, Мгц',' '] + var row_type: Array = [TableNode, TableNode, CellLineEdit, CellLineEdit, CellState, CellLineEdit, TableNode] + var yams_alligment_in: Array = [ HORIZONTAL_ALIGNMENT_LEFT, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER, HORIZONTAL_ALIGNMENT_CENTER] + var column_size: Array = [270, 100, 70, 70, 100, 100, 300] + var dot_collums: Array = [] + var column_offset: int = 7 + for i in range(len(OUTPUT_ROWS)): + header_type.append(TableHeader) + header_text.append('...') + row_type.append(CellYemsButton) + yams_alligment_in.append(HORIZONTAL_ALIGNMENT_LEFT) + column_size.append(25) + dot_collums.append(column_offset+i) + $tbl_in.set_header(header_type) + $tbl_in.set_header_text(header_text) + $tbl_in.set_columns_alignments(yams_alligment_in) + for item in INPUT_ROWS: + $tbl_in.add_row(row_type) + var row_index : int = $tbl_in.get_rows_count() - 1 + var params : Array = item[1] + var in_dev: YemsDevs.InDev = YemsDevs.InDev.new(item[0], params, row_index) + g_in_devices[item[0]] = in_dev + for i in range(len(row_type)): + if i < len(params): + var node = $tbl_in.get_node2(i, row_index) + node.text = params[i] + if i in dot_collums: + var btn = $tbl_in.get_node2(i, row_index) + var out_dev = g_out_devices[OUTPUT_ROWS[i-column_offset][0]] + in_dev.out_dots = [btn, out_dev] + btn.button_connect('pressed', Callable(self, 'on_dot_button').bind(btn, i, row_index)) + btn.connect('mouse_entered', Callable(self, 'on_mouse_entered').bind(btn, i - dot_collums[0], row_index)) + $tbl_in.set_node_user_data(i, row_index, in_dev) + $tbl_in.set_columns_min_size(column_size) + $tbl_in.set_callbacks(self, 'text_submitted', 'on_edit_entry_in', TABLE_ENTRY_COLUMNS, []) + + func on_dot_button(btn, i: int, j: int): - """ Вызывается при нажатии на кнопку-точку (соединение) - i - индекс входа, j - индекс выхода """ - print('on_dot_button(%d, %d)' % [i, j]) - + """ Вызывается при нажатии на кнопку-точку (соединение) + i - индекс входа, j - индекс выхода """ + print('on_dot_button(%d, %d)' % [i, j]) + func on_edit_entry_in(text : String, entry): - var indexis = $tbl_in.get_key_indexes(entry[0].name) - var row_i = indexis[1] - var col_i = indexis[0] - print('ЭМС.gd -> on_edit_entry_in', text, row_i, col_i) + var indexis = $tbl_in.get_key_indexes(entry[0].name) + var row_i = indexis[1] + var col_i = indexis[0] + print('ЭМС.gd -> on_edit_entry_in', text, row_i, col_i) func on_edit_entry_out(text : String, entry): - var indexis = $tbl_out.get_key_indexes(entry[0].name) - var row_i = indexis[1] - var col_i = indexis[0] - print('ЭМС.gd -> on_edit_entry_out', text, row_i, col_i) + var indexis = $tbl_out.get_key_indexes(entry[0].name) + var row_i = indexis[1] + var col_i = indexis[0] + print('ЭМС.gd -> on_edit_entry_out', text, row_i, col_i) func on_item_selected(item_num, node): - var optbtn_text = node[0].text - var indexis = $tbl_out.get_key_indexes(node[0].name) - var row_i = indexis[1] - var col_i = indexis[0] - print('ЭМС.gd -> on_item_selected row: %d col: %d text: %s' %[row_i, col_i, optbtn_text]) - + var optbtn_text = node[0].text + var indexis = $tbl_out.get_key_indexes(node[0].name) + var row_i = indexis[1] + var col_i = indexis[0] + print('ЭМС.gd -> on_item_selected row: %d col: %d text: %s' %[row_i, col_i, optbtn_text]) + func on_mouse_entered(btn, i, j): - $marker_in.position.y = $tbl_in.position.y + btn.position.y + btn.size.y / 2 - $marker_out.position.y = $tbl_out.position.y + (btn.size.y + 4) * i + btn.size.y / 2 - + $marker_in.position.y = $tbl_in.position.y + btn.position.y + btn.size.y / 2 + $marker_out.position.y = $tbl_out.position.y + (btn.size.y + 4) * i + btn.size.y / 2 + func _process(delta): - pass + pass diff --git a/scenes/рамка.gd b/scenes/рамка.gd index 1801b461..0bb06c22 100644 --- a/scenes/рамка.gd +++ b/scenes/рамка.gd @@ -4,15 +4,15 @@ extends NinePatchRect @export var horizontal_alignment: HorizontalAlignment = HorizontalAlignment.HORIZONTAL_ALIGNMENT_CENTER: - get: return $header.horizontal_alignment - set(val): $header.horizontal_alignment = val + get: return $header.horizontal_alignment + set(val): $header.horizontal_alignment = val @export var vertical_alignment: VerticalAlignment = VerticalAlignment.VERTICAL_ALIGNMENT_CENTER: - get: return $header.vertical_alignment - set(val): $header.vertical_alignment = val + get: return $header.vertical_alignment + set(val): $header.vertical_alignment = val @export var text: String = 'caption text': - get: return $header.text - set(val): $header.text = val + get: return $header.text + set(val): $header.text = val diff --git a/scenes/состояния-эмс.gd b/scenes/состояния-эмс.gd index dae63dc2..39a0d965 100644 --- a/scenes/состояния-эмс.gd +++ b/scenes/состояния-эмс.gd @@ -1,5 +1,5 @@ extends Control var align : get = get_align, set = set_align var _align: int = 0 -func set_align(align: int): _align = align +func set_align(val: int): _align = val func get_align(): return _align diff --git a/scripts/repnetwork.gd b/scripts/repnetwork.gd index 9f947dab..1afa5c74 100644 --- a/scripts/repnetwork.gd +++ b/scripts/repnetwork.gd @@ -30,21 +30,21 @@ func create_socket(nm) -> Socket: func _ready() -> void: var addr = REPSettings.addr['уарэп-яу07-частный'][1] var port = REPSettings.addr['уарэп-яу07-частный'][2] - sock_unicast = PacketPeerUDP.new() + sock_unicast = Socket.new() sock_unicast.bind(port, addr) for key in REPSettings.addr: var setting = REPSettings.addr[key] var proto = setting[0] if proto in PROTO_TYPE: var unit = PROTO_TYPE[proto].new(key) - var addr = REPSettings.get_unit_key(setting) - units[addr] = unit - unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(addr)) - unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(addr)) + var k = REPSettings.get_unit_key(setting) + units[k] = unit + unit.connect('line_changed', Callable(logger_page, 'on_line_changed').bind(k)) + unit.connect('command_fail', Callable(logger_page, 'on_command_fail').bind(k)) - for addr in units: - var unit = units[addr] - Log.info('%s %s:%d' % [unit.name, addr[0], addr[1]]) + for key in units: + var unit = units[key] + Log.info('%s %s:%d' % [unit.name, key[0], key[1]]) func poll_receive(sock: Socket):