Обновление контроля АФСП
Some checks failed
Локальный тест / test (push) Has been cancelled

This commit is contained in:
TotMaxim
2026-04-05 15:52:50 +03:00
parent 6db678b163
commit 38529ac0cc
8 changed files with 382 additions and 88 deletions

View File

@@ -123,6 +123,7 @@ prd="*res://scripts/prd.gd"
navi="*res://scripts/navigation.gd" navi="*res://scripts/navigation.gd"
trassa="*res://scripts/trassa.gd" trassa="*res://scripts/trassa.gd"
yemstg="*res://scripts/yemstg.gd" yemstg="*res://scripts/yemstg.gd"
scouting="*res://scripts/rtr.gd"
[debug] [debug]

View File

@@ -1,7 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://8ll27id5ajq1"] [gd_scene load_steps=3 format=3 uid="uid://8ll27id5ajq1"]
[ext_resource type="Script" uid="uid://d0jwv5opi3mrl" path="res://scenes/pribor-afsp/pribor-afsp.gd" id="1_151rh"] [ext_resource type="Script" uid="uid://d0jwv5opi3mrl" path="res://scenes/pribor-afsp/pribor-afsp.gd" id="1_151rh"]
[ext_resource type="Script" uid="uid://bux47vkw71w1t" path="res://scenes/контроль/request.gd" id="2_4vyhj"]
[ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/pribor-afsp/bort-afsp.tscn" id="3_d7iti"] [ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/pribor-afsp/bort-afsp.tscn" id="3_d7iti"]
[node name="pribor_afsp" type="Control"] [node name="pribor_afsp" type="Control"]
@@ -20,13 +19,6 @@ settings_path_to_url = "Адрес АФСП левого борта"
settings_path_to_wait_time = "Период опроса состояния АФСП, секунды" settings_path_to_wait_time = "Период опроса состояния АФСП, секунды"
metadata/DeviceName = &"Устройство РР левого борта" metadata/DeviceName = &"Устройство РР левого борта"
[node name="request" type="HTTPRequest" parent="."]
use_threads = true
script = ExtResource("2_4vyhj")
[node name="timer" type="Timer" parent="request"]
autostart = true
[node name="bort" parent="." instance=ExtResource("3_d7iti")] [node name="bort" parent="." instance=ExtResource("3_d7iti")]
layout_mode = 0 layout_mode = 0
offset_left = 24.0 offset_left = 24.0
@@ -35,7 +27,4 @@ offset_right = 604.0
offset_bottom = 1216.78 offset_bottom = 1216.78
metadata/DeviceName = &"Устройство РР левого борта" metadata/DeviceName = &"Устройство РР левого борта"
[connection signal="child_entered_tree" from="request" to="request" method="_on_child_entered_tree"]
[connection signal="request_completed" from="request" to="." method="_on_request_completed"]
[connection signal="timeout" from="request/timer" to="request" method="_on_request_timer"]
[connection signal="pressed" from="bort" to="." method="_on_item_pressed"] [connection signal="pressed" from="bort" to="." method="_on_item_pressed"]

View File

@@ -1,7 +1,6 @@
[gd_scene load_steps=4 format=3 uid="uid://5uv1idl3lqet"] [gd_scene load_steps=3 format=3 uid="uid://5uv1idl3lqet"]
[ext_resource type="Script" uid="uid://d0jwv5opi3mrl" path="res://scenes/pribor-afsp/pribor-afsp.gd" id="1_tfses"] [ext_resource type="Script" uid="uid://d0jwv5opi3mrl" path="res://scenes/pribor-afsp/pribor-afsp.gd" id="1_tfses"]
[ext_resource type="Script" uid="uid://bux47vkw71w1t" path="res://scenes/контроль/request.gd" id="2_miwrd"]
[ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/pribor-afsp/bort-afsp.tscn" id="3_xpxb5"] [ext_resource type="PackedScene" uid="uid://dnxq870xf6pkh" path="res://scenes/pribor-afsp/bort-afsp.tscn" id="3_xpxb5"]
[node name="pribor_afsp" type="Control"] [node name="pribor_afsp" type="Control"]
@@ -20,13 +19,6 @@ settings_path_to_url = "Адрес АФСП правого борта"
settings_path_to_wait_time = "Период опроса состояния АФСП, секунды" settings_path_to_wait_time = "Период опроса состояния АФСП, секунды"
metadata/DeviceName = &"Устройство РР правого борта" metadata/DeviceName = &"Устройство РР правого борта"
[node name="request" type="HTTPRequest" parent="."]
use_threads = true
script = ExtResource("2_miwrd")
[node name="timer" type="Timer" parent="request"]
autostart = true
[node name="bort" parent="." instance=ExtResource("3_xpxb5")] [node name="bort" parent="." instance=ExtResource("3_xpxb5")]
layout_mode = 0 layout_mode = 0
offset_left = 12.0 offset_left = 12.0
@@ -35,7 +27,4 @@ offset_right = 592.0
offset_bottom = 1130.0 offset_bottom = 1130.0
metadata/DeviceName = &"Устройство РР правого борта" metadata/DeviceName = &"Устройство РР правого борта"
[connection signal="child_entered_tree" from="request" to="request" method="_on_child_entered_tree"]
[connection signal="request_completed" from="request" to="." method="_on_request_completed"]
[connection signal="timeout" from="request/timer" to="request" method="_on_request_timer"]
[connection signal="pressed" from="bort" to="." method="_on_item_pressed"] [connection signal="pressed" from="bort" to="." method="_on_item_pressed"]

View File

@@ -7,98 +7,164 @@ class_name pribor_afsp extends 'res://scenes/контроль/прибор.gd'
@export var settings_path_to_url: String = '' ## Должно быть в ProjectSettings @export var settings_path_to_url: String = '' ## Должно быть в ProjectSettings
@export var settings_path_to_wait_time: String = '' ## Должно быть в ProjectSettings @export var settings_path_to_wait_time: String = '' ## Должно быть в ProjectSettings
signal receive_response_afp_bpo()
static var json_conv: JSON = JSON.new() static var json_conv: JSON = JSON.new()
static var node_maper = load('res://scenes/контроль/node-maper.gd') static var node_maper = load('res://scenes/контроль/node-maper.gd')
static var node_request: Node
static var node_request_timer: Node
var ctrl_pos = 0 var ctrl_pos = 0
# SystemName: "gen" DevList - там состояние связи с генератором по кан шине # SystemName: "gen" DevList - там состояние связи с генератором по кан шине
func _ready() -> void: func _ready() -> void:
ProjectSettings.connect('settings_changed', on_settings_chaged) # Подключаемся к сигналам в зависимости от борта
node_request = $request if this_afsp_name == 'Устройство РР левого борта':
node_request_timer = $request/timer scouting.response_received_left.connect(_on_response_received)
on_settings_chaged() else:
scouting.response_received_right.connect(_on_response_received)
# При старте отрисовываем последние данные (если есть)
_on_press_device()
func on_settings_chaged(): # Обработка полученного ответа от rtr
node_request.request_url = ProjectSettings.get_setting('application/config/%s' % settings_path_to_url) func _on_response_received(response: String, success: bool) -> void:
node_request_timer.wait_time = float(ProjectSettings.get_setting('application/config/%s' % settings_path_to_wait_time)) var unit_instance = network.get_unit_instance(unit_name)
tools.allways(node_request.request_url != null)
if not success:
log.error('Ошибка запроса: %s' % response)
func _on_request_completed(result, _response_code, headers, body: PackedByteArray):
var unit_instance: = network.get_unit_instance(unit_name)
if result != 0:
var rs = node_request.get_result_string(result)
log.error('\"%s\"' % rs)
if unit_instance.online: if unit_instance.online:
unit_instance.online = false unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance) unit_instance.emit_signal('line_changed', unit_instance)
# При ошибке сбрасываем UI в 0
_reset_ui_to_zero()
return return
var json_str: String = body.get_string_from_utf8() # Парсим JSON строку
if not json_str: var parse_result = json_conv.parse(response)
push_error('не удаётся получить строку utf8 из данных (%s)' % headers) if parse_result != OK:
var err = json_conv.get_error_message()
push_error('разбор json прерван - "%s"' % err)
if unit_instance.online: if unit_instance.online:
unit_instance.online = false unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance) unit_instance.emit_signal('line_changed', unit_instance)
# При ошибке парсинга сбрасываем UI в 0
_reset_ui_to_zero()
return return
var rc: = json_conv.parse(json_str) # Ищем имя прибора в JSON
if rc != Error.OK:
var err: = json_conv.get_error_message()
push_error('разбор json прерван - \"%s\" (%s)' % [err, headers])
if unit_instance.online:
unit_instance.online = false
unit_instance.emit_signal('line_changed', unit_instance)
return
var pp = [] var pp = []
tools.map_solid_to_array(prefix_path, pp) tools.map_solid_to_array(prefix_path, pp)
var ret_val = [null, false, 0] var ret_val = [null, false, 0]
var pp_copy = pp.duplicate(true) var pp_copy = pp.duplicate(true)
tools.get_value_by_path(json_conv.data, pp, ret_val) tools.get_value_by_path(json_conv.data, pp, ret_val)
if not ret_val[1]: if not ret_val[1]:
push_error('путь %s не найден (%s)' % [pp_copy, ret_val[2]]) push_error('путь %s не найден (%s)' % [pp_copy, ret_val[2]])
# Если путь не найден, сбрасываем UI в 0
_reset_ui_to_zero()
return return
var received_afsp_name: StringName = ret_val[0] var received_afsp_name: StringName = ret_val[0]
# Проверяем, что ответ от нужного прибора
if this_afsp_name != received_afsp_name: if this_afsp_name != received_afsp_name:
# TODO: Сюда попадаем, когда приходит от другого борта # Ответ от другого борта - игнорируем
#push_error('не известное устройство: \"%s\", ожидадось: \"%s\"' % [received_afsp_name, this_afsp_name])
return return
# Обновляем статус online
unit_instance.rx_tick = Time.get_ticks_msec() unit_instance.rx_tick = Time.get_ticks_msec()
if not unit_instance.online: if not unit_instance.online:
unit_instance.online = true unit_instance.online = true
unit_instance.emit_signal('line_changed', unit_instance) unit_instance.emit_signal('line_changed', unit_instance)
# Обновляем UI элементы из JSON
_update_ui(json_conv.data)
# Обновление интерфейса из JSON данных
func _update_ui(json_data: Dictionary) -> void:
# Конвертер
for child in $bort.get_node('konverter/grid').get_children(): for child in $bort.get_node('konverter/grid').get_children():
node_maper.map_value_to_item(json_conv.data, child, 'value0') node_maper.map_value_to_item(json_data, child, 'value0')
node_maper.map_value_to_item(json_conv.data, child, 'value1') node_maper.map_value_to_item(json_data, child, 'value1')
node_maper.map_value_to_item(json_conv.data, child, 'value2') node_maper.map_value_to_item(json_data, child, 'value2')
node_maper.map_error_codes_to_item(json_conv.data, child, 'state', 0) node_maper.map_error_codes_to_item(json_data, child, 'state', 0)
# Антенна 1
for child in $bort.get_node('antenna1/grid').get_children(): for child in $bort.get_node('antenna1/grid').get_children():
node_maper.map_value_to_item(json_conv.data, child, 'value0') node_maper.map_value_to_item(json_data, child, 'value0')
node_maper.map_value_to_item(json_conv.data, child, 'value1') node_maper.map_value_to_item(json_data, child, 'value1')
node_maper.map_error_codes_to_item(json_conv.data, child, 'state', 0) node_maper.map_error_codes_to_item(json_data, child, 'state', 0)
# Антенна 2
for child in $bort.get_node('antenna2/grid').get_children(): for child in $bort.get_node('antenna2/grid').get_children():
node_maper.map_value_to_item(json_conv.data, child, 'value0') node_maper.map_value_to_item(json_data, child, 'value0')
node_maper.map_value_to_item(json_conv.data, child, 'value1') node_maper.map_value_to_item(json_data, child, 'value1')
node_maper.map_error_codes_to_item(json_conv.data, child, 'state', 0) node_maper.map_error_codes_to_item(json_data, child, 'state', 0)
# Остальные элементы
for child in $bort.get_children(): for child in $bort.get_children():
node_maper.map_value_to_item(json_conv.data, child, 'value0') node_maper.map_value_to_item(json_data, child, 'value0')
node_maper.map_value_to_item(json_conv.data, child, 'value1') node_maper.map_value_to_item(json_data, child, 'value1')
node_maper.map_error_codes_to_item(json_conv.data, child, 'state', 0) node_maper.map_error_codes_to_item(json_data, child, 'state', 0)
emit_signal('receive_response_afp_bpo')
# Сброс всех UI элементов в 0 (при отсутствии данных)
func _reset_ui_to_zero() -> void:
# Конвертер
for child in $bort.get_node('konverter/grid').get_children():
_reset_item_value(child)
# Антенна 1
for child in $bort.get_node('antenna1/grid').get_children():
_reset_item_value(child)
# Антенна 2
for child in $bort.get_node('antenna2/grid').get_children():
_reset_item_value(child)
# Остальные элементы
for child in $bort.get_children():
_reset_item_value(child)
# Сброс конкретного элемента в 0
func _reset_item_value(item) -> void:
item.set('value0', 0)
item.set('value1', 0)
item.set('value2', 0)
item.set('state', 0)
# Отрисовывание при нажатии на прибор
func _on_press_device() -> void:
# Проверяем, есть ли сохраненные данные в rtr
var has_data = false
var last_response = ""
if this_afsp_name == 'Устройство РР левого борта':
has_data = scouting.has_left_success()
if has_data:
last_response = scouting.get_left_response()
else:
has_data = scouting.has_right_success()
if has_data:
last_response = scouting.get_right_response()
# Если есть данные - парсим и отображаем
if has_data and not last_response.is_empty():
var parse_result = json_conv.parse(last_response)
if parse_result == OK:
# Проверяем, что это данные именно от этого прибора
var pp = []
tools.map_solid_to_array(prefix_path, pp)
var ret_val = [null, false, 0]
tools.get_value_by_path(json_conv.data, pp, ret_val)
if ret_val[1] and ret_val[0] == this_afsp_name:
_update_ui(json_conv.data)
return
# Если данных нет или они не подходят - сбрасываем в 0
_reset_ui_to_zero()
## Вызывается при клике мыши на элементе. ## Вызывается при клике мыши на элементе.

View File

@@ -29,6 +29,7 @@ func get_result_string(result: Result):
func _on_request_timer(): func _on_request_timer():
print('_on_request_timer: ', Time.get_ticks_msec())
if HTTPClient.Status.STATUS_DISCONNECTED != get_http_client_status(): if HTTPClient.Status.STATUS_DISCONNECTED != get_http_client_status():
return return
var rc: = request(request_url) var rc: = request(request_url)

View File

@@ -123,6 +123,8 @@ func _ready():
signaller.conn(signaller.режим_настройки, on_mode_changed) signaller.conn(signaller.режим_настройки, on_mode_changed)
signaller.conn(signaller.режим_эмс, on_mode_changed) signaller.conn(signaller.режим_эмс, on_mode_changed)
signaller.connect('debag_control_pressed', Callable(self, 'on_debag_button_pressed')) signaller.connect('debag_control_pressed', Callable(self, 'on_debag_button_pressed'))
scouting.request_sent_left.connect(_on_request_sent_left.bind($pribor_afsp_1))
scouting.response_received_left.connect(_on_response_received.bind($pribor_afsp_1))
func online_change_arr(_u, conn_node, pribor_meta): func online_change_arr(_u, conn_node, pribor_meta):
@@ -166,24 +168,17 @@ func on_pribor_press(pribor_path, header_text, pribor_node):
pribor.add_to_group('pribor_items') pribor.add_to_group('pribor_items')
add_child(pribor) add_child(pribor)
update_pribor_items_visibility() update_pribor_items_visibility()
if pribor_node.get_meta('unit_name')[0] == 'уарэп-афсп-левый' or pribor_node.get_meta('unit_name')[0] == 'уарэп-афсп-правый':
pribor.node_request.connect('send_http_request', Callable(self, 'on_send_http_request').bind(pribor_node, pribor.node_request_timer.wait_time))
pribor.connect('receive_response_afp_bpo', Callable(self, 'on_receive_response_afp_bpo').bind(pribor_node))
if pribor_node.get_meta('unit_name')[0] == 'уарэп-бпо-1' or pribor_node.get_meta('unit_name')[0] == 'уарэп-бпо-2':
pribor.node_request_1.connect('send_http_request', Callable(self, 'on_send_http_request').bind(pribor_node, pribor.node_request_timer_1.wait_time))
pribor.connect('receive_response_afp_bpo', Callable(self, 'on_receive_response_afp_bpo').bind(pribor_node))
#signal receive_response_afp_bpo
# Вызов при отправке запроса на селфтест АФСП # Вызов при отправке запроса на селфтест АФСП
func on_send_http_request(node: Node, time_req: float) -> void: func _on_request_sent_left(_url: String, node: Node) -> void:
node.progress_max_value = 100 node.progress_max_value = 100
node.progress_value = 0 node.progress_value = 0
node.progress_visible = true node.progress_visible = true
node.timeout_tween = time_req node.timeout_tween = float(ProjectSettings.get_setting('application/config/%s' % 'Период опроса состояния АФСП, секунды'))
func on_receive_response_afp_bpo(node: Node) -> void: func _on_response_received(_response: String, _success: bool, node: Node):
node.progress_value = 100 node.progress_value = 100
node.progress_visible = false node.progress_visible = false

252
scripts/rtr.gd Normal file
View File

@@ -0,0 +1,252 @@
class_name rtr
extends Node
#region Перечисления
enum State { IDLE, REQUESTING_LEFT, REQUESTING_RIGHT, WAITING_TIMEOUT }
#endregion
#region Сигналы
# Сигналы отправки запроса
signal request_sent_left(url: String) # Отправлен запрос к левому борту
signal request_sent_right(url: String) # Отправлен запрос к правому борту
# Сигналы получения ответа
signal response_received_left(response: String, success: bool) # Получен ответ от левого борта
signal response_received_right(response: String, success: bool) # Получен ответ от правого борта
#endregion
#region Константы
# Словарь с текстовым описанием кодов результатов HTTP запросов
const RESULT_STRINGS = {
HTTPRequest.Result.RESULT_SUCCESS: 'Запрос успешен',
HTTPRequest.Result.RESULT_CHUNKED_BODY_SIZE_MISMATCH: 'Несоответствие размеров частей сообщения',
HTTPRequest.Result.RESULT_CANT_CONNECT: 'Запрос не выполнен при подключении',
HTTPRequest.Result.RESULT_CANT_RESOLVE: 'Запрос не выполнен при разрешении',
HTTPRequest.Result.RESULT_CONNECTION_ERROR: 'Запрос не выполнен из-за ошибки соединения',
HTTPRequest.Result.RESULT_TLS_HANDSHAKE_ERROR: 'Запрос не выполнен на TLS рукопожатии',
HTTPRequest.Result.RESULT_NO_RESPONSE: 'Запрос не имеет ответа (пока)',
HTTPRequest.Result.RESULT_BODY_SIZE_LIMIT_EXCEEDED: 'Запрос превысил максимальный размер',
HTTPRequest.Result.RESULT_BODY_DECOMPRESS_FAILED: 'Не удалось распаковать сообщение',
HTTPRequest.Result.RESULT_REQUEST_FAILED: 'Запрос не удался',
HTTPRequest.Result.RESULT_DOWNLOAD_FILE_CANT_OPEN: 'Невозможно открыть файл загрузки',
HTTPRequest.Result.RESULT_DOWNLOAD_FILE_WRITE_ERROR: 'Невозможно записать в файл загрузки',
HTTPRequest.Result.RESULT_REDIRECT_LIMIT_REACHED: 'Достигнут лимит перенаправлений',
HTTPRequest.Result.RESULT_TIMEOUT: 'Время истекло'
}
#endregion
#region Переменные
var http_request: HTTPRequest # HTTP клиент для выполнения запросов
var addresses: Dictionary # Словарь с URL адресами устройств
var current_state: State = State.IDLE # Текущее состояние машины состояний
var current_url: String = '' # Текущий URL для запроса
var timeout_timer: Timer # Таймер ожидания ответа (30 секунд)
# Результаты запросов
var last_response_left: String = '' # Последний успешный ответ левого борта
var last_response_right: String = '' # Последний успешный ответ правого борта
var last_error_left: String = '' # Последняя ошибка левого борта
var last_error_right: String = '' # Последняя ошибка правого борта
var timeout: float
#endregion
#region Инициализация
func _ready() -> void:
# Создаем и настраиваем HTTP клиент
http_request = HTTPRequest.new()
add_child(http_request)
http_request.request_completed.connect(_on_request_completed)
# Создаем и настраиваем таймер для обработки таймаутов
timeout_timer = Timer.new()
add_child(timeout_timer)
timeout_timer.timeout.connect(_on_timeout)
timeout_timer.one_shot = true # Таймер срабатывает только один раз
# Подписываемся на сигнал запуска управления устройством
signaller.conn(signaller.start_contol_device, Callable(self, '_on_start_contol_device'))
#endregion
#region Публичные методы
# Возвращает текстовое описание кода результата HTTP запроса
func get_result_string(result: int) -> String:
return RESULT_STRINGS.get(result, '<неизвестный код результата HTTPRequest - %d>' % result)
# Геттеры для получения результатов запросов
func get_left_response() -> String:
return last_response_left
func get_right_response() -> String:
return last_response_right
func get_left_error() -> String:
return last_error_left
func get_right_error() -> String:
return last_error_right
# Проверка успешности запросов
func has_left_success() -> bool:
return not last_response_left.is_empty()
func has_right_success() -> bool:
return not last_response_right.is_empty()
#endregion
#region Обработчики сигналов
# Сигнал от signaller - начало управления устройством
func _on_start_contol_device() -> void:
# Если уже выполняется запрос - игнорируем
if current_state != State.IDLE:
return
# Сбрасываем предыдущие результаты
last_response_left = ''
last_response_right = ''
last_error_left = ''
last_error_right = ''
# Загружаем URL адреса из ProjectSettings
addresses['Адрес АФСП левого борта'] = ProjectSettings.get_setting('application/config/%s' % 'Адрес АФСП левого борта')
addresses['Адрес АФСП правого борта'] = ProjectSettings.get_setting('application/config/%s' % 'Адрес АФСП правого борта')
timeout = float(ProjectSettings.get_setting('application/config/%s' % 'Период опроса состояния АФСП, секунды'))
# Начинаем с запроса к левому борту
_request_next(State.REQUESTING_LEFT)
# Сигнал от HTTPRequest - получен ответ на запрос
func _on_request_completed(result: int, response_code: int, _headers: PackedStringArray, body: PackedByteArray) -> void:
# Если таймаут уже сработал - игнорируем ответ
if current_state == State.WAITING_TIMEOUT:
return
# Останавливаем таймер ожидания
timeout_timer.stop()
# Проверяем успешность ответа
if response_code == 200:
var response_text = body.get_string_from_utf8()
_save_response(response_text)
# Испускаем сигнал успешного получения ответа
match current_state:
State.REQUESTING_LEFT:
emit_signal('response_received_left', response_text, true)
State.REQUESTING_RIGHT:
emit_signal('response_received_right', response_text, true)
_on_request_finished()
else:
var error_msg = 'HTTP ошибка %d: %s' % [response_code, get_result_string(result)]
_save_error(error_msg)
# Испускаем сигнал с ошибкой
match current_state:
State.REQUESTING_LEFT:
emit_signal('response_received_left', error_msg, false)
State.REQUESTING_RIGHT:
emit_signal('response_received_right', error_msg, false)
_on_request_finished()
# Сигнал от таймера - истекло время ожидания ответа
func _on_timeout() -> void:
current_state = State.WAITING_TIMEOUT
http_request.cancel_request() # Отменяем текущий запрос
var timeout_msg = 'Таймаут %.1f секунд - %s' % [timeout, get_result_string(HTTPRequest.Result.RESULT_TIMEOUT)]
_save_error(timeout_msg)
# Испускаем сигнал с ошибкой таймаута
match current_state:
State.REQUESTING_LEFT:
emit_signal('response_received_left', timeout_msg, false)
State.REQUESTING_RIGHT:
emit_signal('response_received_right', timeout_msg, false)
_on_request_finished()
#endregion
#region Управление запросами
# Переход к следующему запросу в очереди
func _request_next(next_state: State) -> void:
current_state = next_state
# Определяем URL для текущего состояния
match current_state:
State.REQUESTING_LEFT:
current_url = addresses.get('Адрес АФСП левого борта', '')
State.REQUESTING_RIGHT:
current_url = addresses.get('Адрес АФСП правого борта', '')
State.IDLE:
return
# Проверяем, задан ли URL
if current_url.is_empty():
print('URL не задан для ', current_state)
var error_msg = 'URL не задан'
_save_error(error_msg)
# Испускаем сигнал с ошибкой
match current_state:
State.REQUESTING_LEFT:
emit_signal('response_received_left', error_msg, false)
State.REQUESTING_RIGHT:
emit_signal('response_received_right', error_msg, false)
_on_request_finished()
return
# Испускаем сигнал отправки запроса
match current_state:
State.REQUESTING_LEFT:
emit_signal('request_sent_left', current_url)
State.REQUESTING_RIGHT:
emit_signal('request_sent_right', current_url)
# Запускаем таймер и отправляем запрос
timeout_timer.start(timeout)
var error = http_request.request(current_url)
if error != OK:
print('Ошибка запроса: ', error_string(error))
var error_msg = 'Ошибка запроса: ' + error_string(error)
_save_error(error_msg)
# Испускаем сигнал с ошибкой
match current_state:
State.REQUESTING_LEFT:
emit_signal('response_received_left', error_msg, false)
State.REQUESTING_RIGHT:
emit_signal('response_received_right', error_msg, false)
_on_request_finished()
# Обработка завершения текущего запроса (успех/ошибка/таймаут)
func _on_request_finished() -> void:
match current_state:
State.REQUESTING_LEFT:
# После левого борта переходим к правому
_request_next(State.REQUESTING_RIGHT)
State.REQUESTING_RIGHT, State.WAITING_TIMEOUT:
# После правого борта или таймаута возвращаемся в IDLE
current_state = State.IDLE
print('Цикл запросов завершен')
#endregion
#region Сохранение результатов
# Сохраняет успешный ответ от устройства
func _save_response(response: String) -> void:
match current_state:
State.REQUESTING_LEFT:
last_response_left = response
State.REQUESTING_RIGHT:
last_response_right = response
# Сохраняет ошибку от устройства
func _save_error(error: String) -> void:
match current_state:
State.REQUESTING_LEFT:
last_error_left = error
State.REQUESTING_RIGHT:
last_error_right = error
#endregion

1
scripts/rtr.gd.uid Normal file
View File

@@ -0,0 +1 @@
uid://ctqcvjqjb1av3