From 57bc5c4f8130393bce99b325901eb9e69e36776c Mon Sep 17 00:00:00 2001 From: ske087 Date: Tue, 3 Jun 2025 16:34:15 +0300 Subject: [PATCH] updated trips --- main.py | 103 ++++++++++++++++++++++++++++------ resources/credentials.enc | 2 +- resources/server_settings.enc | 2 +- t | 1 + test_traccar_trip.py | 94 ++++++++++--------------------- traccar.kv | 64 ++++++++++++++++++--- 6 files changed, 176 insertions(+), 90 deletions(-) create mode 100644 t diff --git a/main.py b/main.py index f69639c..46fd3d6 100644 --- a/main.py +++ b/main.py @@ -226,30 +226,28 @@ class GetTripFromServer(Screen): # Renamed from HomeScreen else: self.ids.devices_spinner.background_color = (1, 1, 1, 1) # Reset to white if no valid device is selected - def open_date_picker(self): - """Open a popup to select a date.""" + def open_date_picker(self, which): + """Open a popup to select a date for start or end.""" today = date.today() - selected_date = [None] # Use a mutable object to store the selected date + selected_date = [None] def on_date_selected(instance): selected_date[0] = instance.text - # Update the button text with the selected date - self.ids.date_picker_button.text = f"Date: {today.year}-{today.month:02d}-{int(selected_date[0]):02d}" - # Change the background color of the button to green - self.ids.date_picker_button.background_color = (0.008, 0.525, 0.290, 1) # Green color (#02864A) - print(f"Date selected: {self.ids.date_picker_button.text}") + date_str = f"{today.year}-{today.month:02d}-{int(selected_date[0]):02d}" + if which == 'start': + self.ids.start_date_picker_button.text = date_str + else: + self.ids.end_date_picker_button.text = date_str popup.dismiss() - # Create a popup with a grid layout for the days layout = GridLayout(cols=7, spacing=5, padding=10) - for day in range(1, 32): # Assuming a maximum of 31 days in a month + for day in range(1, 32): try: current_date = date(today.year, today.month, day) button = Button(text=str(day), size_hint=(None, None), size=(40, 40)) button.bind(on_press=on_date_selected) layout.add_widget(button) except ValueError: - # Skip invalid dates (e.g., February 30) pass popup = Popup(title="Select a Date", content=layout, size_hint=(0.8, 0.8)) @@ -258,21 +256,92 @@ class GetTripFromServer(Screen): # Renamed from HomeScreen def get_trip_server_data(self): """Handle the Get trip server data button press.""" selected_device = self.ids.devices_spinner.text - selected_date = self.ids.date_picker_button.text + start_date = self.ids.start_date_picker_button.text + end_date = self.ids.end_date_picker_button.text if selected_device == "Loading devices..." or selected_device == "No devices found": print("No valid device selected.") self.ids.result_label.text = "Please select a valid device." return - if selected_date == "Select Date": + if start_date == "Select Date" or end_date == "Select Date": print("No valid date selected.") - self.ids.result_label.text = "Please select a valid date." + self.ids.result_label.text = "Please select valid start and end dates." return - # Simulate fetching trip data from the server - print(f"Fetching trip data for device: {selected_device} on date: {selected_date}") - self.ids.result_label.text = f"Fetching trip data for {selected_device} on {selected_date}..." + # Fetch trip data from the server + print(f"Fetching trip data for device: {selected_device} from {start_date} to {end_date}") + self.ids.result_label.text = f"Fetching trip data for {selected_device} from {start_date} to {end_date}..." + + positions = self.fetch_positions_for_selected_day() + if positions: + print("Positions received:") + for pos in positions: + print(f"{pos['deviceTime']}: {pos['latitude']}, {pos['longitude']}") + else: + print("No positions found or error occurred.") + + def fetch_positions_for_selected_day(self): + """Fetch all positions for the selected device and date/time range from the Traccar server.""" + settings = check_server_settings() + if not settings: + self.ids.result_label.text = "Server settings not found." + return [] + + server_url = settings["server_url"] + token = settings["token"] + + selected_device = self.ids.devices_spinner.text + if selected_device not in self.device_mapping: + self.ids.result_label.text = "Please select a valid device." + return [] + + device_id = self.device_mapping[selected_device] + + # Get start/end date and hour from UI + start_date = self.ids.start_date_picker_button.text + start_hour = self.ids.start_hour_spinner.text + end_date = self.ids.end_date_picker_button.text + end_hour = self.ids.end_hour_spinner.text + + # Validate + if "Select" in start_date or "Select" in end_date: + self.ids.result_label.text = "Please select both start and end dates." + return [] + + # Build ISO 8601 time strings + from_time = f"{start_date}T{start_hour}:00:00Z" + to_time = f"{end_date}T{end_hour}:59:59Z" + + # Prepare request for /reports/route + url = f"{server_url}/reports/route" + headers = {"Authorization": f"Bearer {token}", "Accept": "application/json"} + params = { + "deviceId": device_id, + "from": from_time, + "to": to_time + } + + try: + print(f"Request Payload: {params}") + response = requests.get(url, params=params, headers=headers, timeout=15) + print(f"Response Status Code: {response.status_code}") + print(f"Response Content: {response.text}") + + if response.status_code == 200: + positions = response.json() + print(f"Retrieved {len(positions)} positions.") + self.ids.result_label.text = f"Retrieved {len(positions)} positions." + return positions + elif response.status_code == 400: + self.ids.result_label.text = "Bad Request: Please check the request payload and token." + return [] + else: + self.ids.result_label.text = f"Failed: {response.status_code} - {response.reason}" + return [] + except requests.exceptions.RequestException as e: + self.ids.result_label.text = f"Error fetching positions: {str(e)}" + return [] class RegisterScreen(Screen): diff --git a/resources/credentials.enc b/resources/credentials.enc index 7a996ee..ab02649 100644 --- a/resources/credentials.enc +++ b/resources/credentials.enc @@ -1 +1 @@ -gAAAAABoPaPrItydUFVvwuzoJNOIF45pusZlJtW62JzZ74gfMb04ZfpUkkZq2Vl7TVSruG0_vH9b-ig_WFInrvwSTcxxN1hRN3Xz9yLdgZ_7qfE3qFS_KZpNtjW_5l9Fj5gpDAXJwX2v \ No newline at end of file +gAAAAABoPvmJa0okDG59jZQf9ZCFZ-qB7cFGQ18uF-duofQnBUYZncvyAG3OBhyB68lQQroIf8xRpHPGYtUy2jFMF1-bhvPkexBECo2BHz0Yun7w_gveksc05I0XKSR-tDvQuS3FKf_3 \ No newline at end of file diff --git a/resources/server_settings.enc b/resources/server_settings.enc index 7eabde5..8f5ec6d 100644 --- a/resources/server_settings.enc +++ b/resources/server_settings.enc @@ -1 +1 @@ -gAAAAABoPZo4DMcBt7anBtvn5wMfvWpsjR4Zi1BPdQhvnvSj0SyQmrQEF1uhsUjf0Y6Le3vBPKSplUypYURK_BUlJMbxUh2yI93KCcXdMJIy23TyNlVlt7dv1mPN3aQAAd4TqhA_dEVPAfBtT5ckcQAXqCRwd1RjRp06Qgz3XNHeLs14MxGet0rbWCLppopr6BTGulvbAdvCFoDqmRFYbfyWYlqqsN4-ZF0Q0qObOVPn7hqYHFTenK6tidi-JOx7Lx0jrCZWA2V0OgwCZOsTA-BYZeWK8RI2U645SJ_DBTBwK2avb6wDduJKOOIKJWKdUF5HaN3Ffc61KWxYO_8Eb21bYmNsDB31l9n-OgJLdzStT-WqLMmmw027YG_SZJsv-P2Ce0lCaw29s2Lbh_2VxWShJW6aDRxibZgHK3CoPajqR0MAkGJxT2w7pt7wT1zeMKHu51q3yPpV \ No newline at end of file +gAAAAABoPu5x585IL9U8GSHw4j-KQTpHJixfiwEHQf9KHR25D2fFcYDz6HrJzFP4U3iFxcV9dQQ1VhgDfDPO_nVDafVjMz9kiJdbp1KtiSyB8odqNmq1v6ZfLr_YXqzqNhMHfuA1zr4NgUkaivF-dQr84Z4WA4i1crmR-BA7tMIQti7rDjtmIxQATfKrNw1zD5yYrDiI2jOkUAGiJ1hIY0Ue-x0wmykzktwD_xIsixxX3IOeqgY39gZ7XmwRYA4boZsSbWqqmVDgjBElaUYCUKlp_t-50vHeMNySt5AHDwmY3cOb0zePMEVYzQiKMOTRsSMrAavnIquY6BHytWKOJuuOoWS5aTiuy1YGw6wMQZT7MFcza9u4iYjJm39cdLnGl4tWn8StvawbXepPFqrwcoJXAfkvd8f--eCPuAXIFi__EMM0jlO2PGSbj-5YjFnCdKspnycrlLB6 \ No newline at end of file diff --git a/t b/t new file mode 100644 index 0000000..5ff1748 --- /dev/null +++ b/t @@ -0,0 +1 @@ +SDBGAiEA4sNXvVhL8w_Jd-5oCiXAuS5La5yelCQemfNysZYItaMCIQDOkzaoWKHbNnbZJw9ruGlsvbp35d90x3EGOZLXW_Gls3sidSI6MSwiZSI6IjIwMjUtMDYtMDlUMjE6MDA6MDAuMDAwKzAwOjAwIn0 \ No newline at end of file diff --git a/test_traccar_trip.py b/test_traccar_trip.py index b2b6f4e..f45ea3d 100644 --- a/test_traccar_trip.py +++ b/test_traccar_trip.py @@ -1,73 +1,41 @@ import requests -def get_positions(server_url, token, device_ids, from_time, to_time): +def get_device_route(server_url, token, device_id, from_time, to_time): """ - Fetch position information from the Traccar server. - - Args: - server_url (str): The URL of the Traccar server. - token (str): The authentication token. - device_ids (list of int): List of device IDs. - from_time (str): The start time in ISO 8601 format. - to_time (str): The end time in ISO 8601 format. - - Returns: - list: The position information. + Fetch all positions for a device in a time frame from Traccar server. """ - if not device_ids or not from_time or not to_time: - print("deviceId, from, and to are required parameters.") - return None - - headers = {"Authorization": f"Bearer {token}"} - url = f"{server_url}/positions" - payload = { - "deviceId": device_ids, # Send as list + url = f"{server_url}/reports/route" + headers = { + "Authorization": f"Bearer {token}", + "Accept": "application/json" + } + params = { + "deviceId": device_id, "from": from_time, "to": to_time } - - try: - print(f"Request Payload: {payload}") - response = requests.get(url, params=payload, headers=headers) - print(f"Response Status Code: {response.status_code}") - print(f"Response Content: {response.text}") - - if response.status_code == 200: + response = requests.get(url, headers=headers, params=params) + if response.status_code == 200: + try: positions = response.json() - print(f"Retrieved {len(positions)} positions:") - for position in positions: - print(position) + print(f"Retrieved {len(positions)} positions.") return positions - elif response.status_code == 400: - print("Bad Request: Please check the request payload and token.") - return None - else: - print(f"Failed to fetch positions: {response.status_code} - {response.reason}") - return None - except requests.exceptions.RequestException as e: - print(f"Error fetching positions: {str(e)}") - return None - - -# Test the function -if __name__ == "__main__": - # Manually enter the server URL and token - server_url = "https://gps.moto-adv.com/api" - token = "RjBEAiB69jflCQJ9HQwGyFdAHF8J5JPMwIIclglbWiKMWeX6PwIgdBWc-YllE_-RwoQi7zX25WxQJqQX_OTIKOHk9a3mmBN7InUiOjEsImUiOiIyMDI1LTA2LTA4VDIxOjAwOjAwLjAwMCswMDowMCJ9" - - device_id = input("Enter the device ID (required): ").strip() - if not device_id: - print("Device ID is required.") - exit(1) - device_ids = [int(device_id)] - - # Set fixed time interval - from_time = "2024-06-01T12:00:00Z" - to_time = "2024-06-01T23:00:00Z" - print(f"Using time interval: {from_time} to {to_time}") - - positions = get_positions(server_url, token, device_ids, from_time, to_time) - if positions: - print("Position data retrieved successfully!") + except Exception as e: + print(f"Error parsing JSON: {e}") + print(response.text) + return [] else: - print("No position data found or an error occurred.") \ No newline at end of file + print(f"Failed to fetch positions: {response.status_code} - {response.text}") + return [] + +# Example usage: +if __name__ == "__main__": + # Use your actual Traccar API endpoint (not /reports/route) + server_url = "https://gps.moto-adv.com/api" + token = "SDBGAiEA4sNXvVhL8w_Jd-5oCiXAuS5La5yelCQemfNysZYItaMCIQDOkzaoWKHbNnbZJw9ruGlsvbp35d90x3EGOZLXW_Gls3sidSI6MSwiZSI6IjIwMjUtMDYtMDlUMjE6MDA6MDAuMDAwKzAwOjAwIn0" + device_id = 1 # Replace with your device ID + from_time = "2024-06-02T21:00:00Z" + to_time = "2025-06-03T20:59:00Z" + positions = get_device_route(server_url, token, device_id, from_time, to_time) + for pos in positions: + print(f"{pos['deviceTime']}: {pos['latitude']}, {pos['longitude']}") \ No newline at end of file diff --git a/traccar.kv b/traccar.kv index 69243c6..2c632a4 100644 --- a/traccar.kv +++ b/traccar.kv @@ -227,7 +227,7 @@ BoxLayout: orientation: "vertical" size_hint_y: None - height: 120 # Adjusted height for the frame + height: 180 # Adjusted height for the frame spacing: 10 padding: 10 canvas.before: @@ -255,16 +255,64 @@ values: [] # Initially empty size_hint: (0.5, None) height: 25 - font_size: 14 # Reduced font size - on_text: root.on_device_selected(self.text) # Trigger background color change + font_size: 14 + on_text: root.on_device_selected(self.text) + + # New row: Starting date and hour + BoxLayout: + orientation: "horizontal" + size_hint_y: None + height: 30 + spacing: 10 + + Label: + text: "Starting Date" + size_hint_x: 0.3 + font_size: 14 Button: - id: date_picker_button - text: "Select Date" - size_hint: (0.5, None) + id: start_date_picker_button + text: "Select Start Date" + size_hint_x: 0.4 height: 25 - font_size: 14 # Reduced font size - on_press: root.open_date_picker() + font_size: 14 + on_press: root.open_date_picker('start') + + Spinner: + id: start_hour_spinner + text: "00" + values: [f"{i:02d}" for i in range(24)] + size_hint_x: 0.2 + height: 25 + font_size: 14 + + # New row: End date and hour + BoxLayout: + orientation: "horizontal" + size_hint_y: None + height: 30 + spacing: 10 + + Label: + text: "End Date" + size_hint_x: 0.3 + font_size: 14 + + Button: + id: end_date_picker_button + text: "Select End Date" + size_hint_x: 0.4 + height: 25 + font_size: 14 + on_press: root.open_date_picker('end') + + Spinner: + id: end_hour_spinner + text: "23" + values: [f"{i:02d}" for i in range(24)] + size_hint_x: 0.2 + height: 25 + font_size: 14 # New row: Get trip server data button Button: