-
Notifications
You must be signed in to change notification settings - Fork 1
/
Copy path__init__.py
242 lines (193 loc) · 11 KB
/
__init__.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
194
195
196
197
198
199
200
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
228
229
230
231
232
233
234
235
236
237
238
239
240
241
242
import logging
from eventmanager import Evt
from Database import Pilot, Profiles
import json
import RHAPI
import requests
import time
from RHUI import UIField, UIFieldType, UIFieldSelectOption
logger = logging.getLogger(__name__)
class heatSender:
current_round = 1
def __init__(self, rhapi:RHAPI.RHAPI):
# Store the RHAPI object to allow connections in the future
self._rhapi = rhapi
# Setup an event for when the active heat changes
# Avaliable events can be found at https://github.com/RotorHazard/RotorHazard/blob/264d39a01c2a391c4ed059d84c5f21969f14dae9/src/server/eventmanager.py#L100
self._rhapi.events.on(Evt.HEAT_SET, self.onHeatChange)
self._rhapi.events.on(Evt.LAPS_SAVE, self.raceSave)
self._rhapi.events.on(Evt.RACE_LAP_RECORDED, self.raceProgress)
rhapi.ui.register_panel("next_format", "Next", "format")
self._rhapi.events.on(Evt.LAPS_RESAVE, self.on_laps_resave)
rhapi.fields.register_option( UIField('next_status', 'Turn On service', field_type = UIFieldType.CHECKBOX), 'next_format' )
rhapi.fields.register_option( UIField('next_ip', "IP Next Server", UIFieldType.TEXT), 'next_format' )
rhapi.fields.register_option( UIField('next_event_id', "Next Event Id", UIFieldType.TEXT), 'next_format')
rhapi.ui.register_quickbutton('next_format', 'import_pilots', 'Import pilots', self.importPilots)
def importPilots(self, args):
self._rhapi.ui.message_notify(self._rhapi.language.__("Next - Pilot importing starts"))
if (self._rhapi.db.option("next_status") == "1"):
data = {
'nextId': self._rhapi.db.option("next_event_id"),
}
response = requests.post('http://' + self._rhapi.db.option("next_ip") + "/data/import_pilots", json=data)
response_data = response.json()
logger.info("Pilots to import: %s", response_data)
for pilot_name in response_data["pilots"]:
self._rhapi.db.pilot_add(name=pilot_name, callsign=pilot_name)
self._rhapi.ui.message_notify(self._rhapi.language.__("Next - Pilot importing finished"))
def onHeatChange(self, args):
currentRound = self._rhapi.race.round
currentHeat = self._rhapi.race.heat
race_id = str(currentHeat) + str(currentRound + 1)
logger.info("Race on change: %s", race_id)
if (self._rhapi.db.option("next_status") == "1"):
# Since you only care about the active race, we can ignore the heat_id and utalize the rhapi.race api.
# This connection only provides data for the currently active race
# https://github.com/RotorHazard/RotorHazard/blob/main/doc/RHAPI.md#active-race
# Gets the currently active frequency set
# https://github.com/RotorHazard/RotorHazard/blob/main/doc/RHAPI.md#racefrequencyset
frequencyset:Profiles = self._rhapi.race.frequencyset
# Get the frequencies for the set. The different list should be loaded in used the json module:
# "b" : access to the list of bands
# "c" : access to the list of channels
# "f" : access to the list of frequencies
frequencies:dict[str,list] = json.loads(frequencyset.frequencies)
slots_bands:list[str] = frequencies["b"]
slots_channels:list[int] = frequencies["c"]
slots_frequencies:list[int] = frequencies["f"]
# This variable provides a dictionary of in the format of {slot_index : pilot_id}
# https://github.com/RotorHazard/RotorHazard/blob/main/doc/RHAPI.md#racepilots
pilots:dict[int,int] = self._rhapi.race.pilots
payload = []
# Loop through each slot and grab the callsign and frequency info for the pilot (if there is one)
for slot_index, pilot_id in pilots.items():
if pilot_id != 0:
pilot:Pilot = self._rhapi.db.pilot_by_id(pilot_id)
data_dic = {
"callsign":pilot.callsign,
"band":slots_bands[slot_index],
"channel":slots_channels[slot_index],
"frequency":slots_frequencies[slot_index],
"heat":race_id
}
payload.append(data_dic)
#logger.info(data_dic)
race_data = {
'data': payload,
"nextId": self._rhapi.db.option("next_event_id")
}
#logger.info("Next push data:" + self._rhapi.db.option("next_ip") + "/v1/next/data/pilots")
requests.post('http://' + self._rhapi.db.option("next_ip") + "/data/pilots", json=race_data)
def raceSave(self, args):
if (self._rhapi.db.option("next_status") == "1"):
currentRound = self._rhapi.race.round
currentHeat = self._rhapi.race.heat
raceId = str(currentHeat) + str(currentRound)
logger.info("Save race Id: %s", raceId)
data = self._rhapi.race.results
# Extraer datos deseados
pilots_vector = []
for pilot in data.get("by_consecutives", []):
pilot_data = {
"callsign": pilot.get("callsign"),
"laps": pilot.get("laps"),
"total_time": pilot.get("total_time"),
"total_time_laps": pilot.get("total_time_laps"),
"average_lap": pilot.get("average_lap"),
"fastest_lap": pilot.get("fastest_lap"),
"consecutives": pilot.get("consecutives"),
"position": pilot.get("position")
}
pilots_vector.append(pilot_data)
# Crear un nuevo array con las claves 'pilots_vector' y 'race_id'
race_data = {
'pilots_vector': pilots_vector,
'race_id': raceId,
"nextId": self._rhapi.db.option("next_event_id")
}
#logger.info("Heat laps: %s", pilots_vector)
requests.post('http://' + self._rhapi.db.option("next_ip") + "/data/heat_data", json=race_data)
def to_dict(self, obj):
if hasattr(obj, '__dict__'):
return {
k: self.to_dict(v) if isinstance(v, (list, dict)) else v
for k, v in obj.__dict__.items() if not k.startswith('_')
}
return obj
def raceProgress(self, args):
if (self._rhapi.db.option("next_status") == "1"):
parsed_data = args
logger.info("Heat laps: %s", args)
result_vector = []
heat_id = "00"
for obj in parsed_data["results"]["by_race_time"]:
fastest_lap_source = obj.get("fastest_lap_source", {})
# Concatenar heat y round si están disponibles
heatId = (
f"heat: {fastest_lap_source.get('heat')}, round: {fastest_lap_source.get('round')}"
if isinstance(fastest_lap_source, dict)
else "00"
)
result_vector.append({
"callsign": obj["callsign"],
"laps": obj["laps"],
"last_lap": obj["last_lap"],
"position": obj["position"],
"heatId": heatId
})
heat_id = heat_id
laps_data = {
'pilots_vector': result_vector,
'heat_id': heat_id,
'nextId': self._rhapi.db.option("next_event_id")
}
logger.info("Heat laps: %s", laps_data)
requests.post('http://' + self._rhapi.db.option("next_ip") + "/data/laps_data", json=laps_data)
def on_laps_resave(self, args):
if (self._rhapi.db.option("next_status") == "1"):
time.sleep(2) # Retraso mínimo para asegurar persistencia en la BD
self.raceResave(args)
def raceResave(self, args):
race_id = args.get('race_id')
laps_raw = self._rhapi.db.race_by_id(race_id)
if hasattr(laps_raw, "__dict__"):
laps_raw = vars(laps_raw) # Convierte el objeto en un diccionario
results = laps_raw.get("results", {})
# Log para depuración
logger.info("Results data: %s", results)
pilots_vector = []
round_heat_concat = ""
# Verificar que 'by_consecutives' exista antes de iterar
if isinstance(results, dict) and "by_consecutives" in results:
for pilot in results["by_consecutives"]:
# Extraer round y heat si existen en consecutives_source
consecutives_source = pilot.get("consecutives_source")
if consecutives_source: # Verifica si consecutives_source existe y no es None
round_num = consecutives_source.get("round", 0) + 1 # Incrementar round en 1
heat = consecutives_source.get("heat", 0)
round_heat_concat = f"{heat}{round_num}" # Concatenar heat y round
pilot_data = {
"callsign": pilot.get("callsign"),
"laps": pilot.get("laps"),
"total_time": pilot.get("total_time"),
"total_time_laps": pilot.get("total_time_laps"),
"average_lap": pilot.get("average_lap"),
"fastest_lap": pilot.get("fastest_lap"),
"consecutives": pilot.get("consecutives"),
"position": pilot.get("position")
}
pilots_vector.append(pilot_data)
else:
logger.warning("No data found in 'by_consecutives'")
# Imprimir resultado
logger.info("Pilots Vector: %s", pilots_vector)
# Crear un nuevo array con las claves 'pilots_vector' y 'race_id'
race_data = {
'pilots_vector': pilots_vector,
'heat_id': round_heat_concat,
"nextId": self._rhapi.db.option("next_event_id")
}
logger.info("Resave: %s", race_data)
requests.post('http://' + self._rhapi.db.option("next_ip") + "/data/resave_data", json=race_data)
def initialize(rhapi):
heatSender(rhapi)