Conrad Posted January 2 Posted January 2 W dniu 29.12.2024 o 16:00, pomiary.el1 napisał(a): Cześć, Odnalazłem ten wątek w celu zadania pewnego pytania ale już chyba niestety znam odpowiedź 😞 Zbudowałem pulpit od EN57, w zasadzie część ślusarsko spawalnicza oraz elektryczna jest już na ukończeniu, ale zaczynam powoli pracę związaną z uruchomieniem manometrów, prędkościomierza i ogólnej komunikacji gry z sygnalizacją SHP, lampkami oraz miernikami. Z tego co tu czytam i widzę po Waszych pulpitach, twórcy gry pomimo szumnych zapowiedzi zrobili nas w balona. Liczyłem, że po wyjściu z EA będzie jakaś informacja zwrotna dla kontrolerów i wsparcie dla pulpitów , a tu jak zwykle dupa 😞 Pochwalę się i ja, efektem wielomiesięcznej pracy: Zazdroszczę! za oryginalny hardware 🙂, spory klamot, ale będzie frajda z tego.
JarkPomsky Posted January 2 Posted January 2 (edited) 31 minut temu, Conrad napisał(a): Świetnie! Jak rozumiem byłaby szansa na bypass pomiędzy SimRail, a wyjściem na zewnątrz i przekazywaniem stanów na swój hardware!? Do tego się dokopałeś (pod F8) ? Pierwszy raz widzę to okno... 😄 To jakiś tryb developerski? Nie wiem jak sie steruje silnikami krokowymi. Jeśli tak, że jakaś dana wartość przesuwa silniczek to tak, to możliwe. Wartości z amperomierzy zostały pobrane z pamięci Simrail.exe a konkretniej z biblioteki GameAssembly.dll i z określonym odpowiednim offsetem bazowym i offsetami wartości. Jest to problematyczne, bo adresy są dynamiczne i zmieniają się z każdym uruchomieniem gry. Ale znając offset bazowy można określić gdzie znajduje się szukana wartość - aczkolwiek raz na 5-10 razy to nie działa. Żeby to naprawić musiałbym wpisać logikę która korzysta np z zapasowego adresu (albo najlepiej 10 po kolei aż nie znajdzie działającego adresu). Program napisany w Phyton przy użyciu .pymem który wyciąga wartości z gry i .flask który tworzy serwer i w sieci lokalnej można wyświetlić wyniki za pomocą html JavaScript ajax np. na tablecie jak u na moim filmie. Jak za rok twórcy nie udostępnią API to będziemy pisać 😄 Edited January 2 by JarkPomsky 2
Conrad Posted January 3 Posted January 3 19 godzin temu, JarkPomsky napisał(a): Nie wiem jak sie steruje silnikami krokowymi. Jeśli tak, że jakaś dana wartość przesuwa silniczek to tak, to możliwe. Co do silników krokowych to @Maciej_ZG już wcześniej podpowiedział jakie rozwiązanie się u niego sprawdziło. Tanie i często stosowane silniczki krokowe w projektach diy, często używane przy budowie kokpitów samolotów dla zegarów analogowych. np. do Cessny. Łatwo znaleźć gotowe rozwiązania i tutoriale diy. Co do API od dev to obecnie moja nadzieja szoruje po dnie pustego basenu 🤣
Maciej_ZG Posted January 3 Posted January 3 51 minutes ago, Conrad said: Co do silników krokowych to @Maciej_ZG już wcześniej podpowiedział jakie rozwiązanie się u niego sprawdziło. Tanie i często stosowane silniczki krokowe w projektach diy, często używane przy budowie kokpitów samolotów dla zegarów analogowych. np. do Cessny. Łatwo znaleźć gotowe rozwiązania i tutoriale diy. Co do API od dev to obecnie moja nadzieja szoruje po dnie pustego basenu 🤣 Jakby co to mogę udotępnić kod Arduino na którym te silnicznki u mnie działają
JarkPomsky Posted January 3 Posted January 3 Ogólnie to gra przechowuje w pamięci konkretną wartość np dotyczącą napięcia (np. 235), a dla np. SHP/CA jest 1 albo 0.
pomiary.el1 Posted January 4 Posted January 4 W dniu 2.01.2025 o 18:14, Conrad napisał(a): Zazdroszczę! za oryginalny hardware 🙂, spory klamot, ale będzie frajda z tego. Niestety bardzo mnie ta kolubryna przerosła. Niby jest na kółkach, wszystkie wystające części są demontowalne, a ich zasilanie realizowane jest poprzez gniazda. Można też zdemontować nogi - mocowane na motylki. Niemniej jednak sama skrzynia z zawartością waży prawie 100 kilo. Ogólnie kiepski pomysł aby takie coś stało w mieszkaniu. O wściekłej żonie nie wspomnę 😞 Jeśli ktoś byłby zainteresowany historią powstawania pulpitu od samego początku, to zapraszam tu: https://rcn.tlx.pl/forum/viewtopic.php?f=31&t=760&sid=021b2ce0f8c68348daf3677dec143bc7 Wada jest taka, że niestety polityka tamtego forum wymaga zalogowania. Plus - masa zdjęć z każdego etapu budowy pulpitu oraz różnych problemów, które codziennie napotykałem. Również rozwiązań, które ciągle trzeba było zmieniać i ulepszać metodą prób i błędów. Pozdrawiam Łukasz PS. Sporo mam części rezerwowych takich jak przełączniki typu "Z", lampki LS48, przyciski, nawet jeden nastawnik hamulcowy się ostał. Gdyby ktoś, kiedyś coś... 2
JarkPomsky Posted January 9 Posted January 9 (edited) @Conrad@Maciej_ZG @pomiary.el1 Z ciekawosci. Czy Arduino /rasberry Pi które steruje waszymi pulpitami potrafi odczytywać wartości z tablic JSON po http? Edited January 9 by JarkPomsky
Maciej_ZG Posted January 9 Posted January 9 @JarkPomsky - w moim rozwiązaniu (https://github.com/maciejszymanskizg/custom_desktop_control/tree/main) aktualnie nie. Ale jak trzeba to można dopisać sobie taki InputController. Jest wiele bilbiotek (np. json-c) które można wykorzystać. 1
JarkPomsky Posted January 9 Posted January 9 (edited) Jeśli chcesz spróbować pobawić się i podłączyć pulpit, to załączam program do odczytu pamięci Amperomierza WN2 w EU07. Wyciąga on dane i umieszcza w formacie JSON na adresie hosta. Możesz przetestować po uruchomieniu wbijając w przeglądarkę: http://192.168.0.13:5000/api/receive_data - zamień adres IP na swój adres lokalny - https://i.imgur.com/Xk7m3ML.jpeg Zarówna gra jak i ten program MUSZĄ być uruchomione z uprawnieniami administratora - bez tego program nie uzyska dostępu do pamięci. Kod programu znajduje się tutaj: https://pastecode.io/s/c602k1rq Po uruchomieniu powinieneś otrzymać coś takiego: https://i.imgur.com/gjOtTpK.jpeg Skan antiwirusowy - niektóre antywirusy zgłaszają wirusa, to dlatego że aplikacja pobiera dane z procesu innej aplikacji (w tym przypadku z naszej gry) : VirusTotal - File - b7dc95461c754ef9fbe6c051ae831749d52e60775568297a43d8fe846e5984f7 Jak to zadziała to pomyślimy dalej. Edit: Jak SimRail.exe nie jest włączony to program zamula kompa, za dużo razy szuka procesu 😄 ale już nie będę poprawiał teraz 😄 main.7z Edited January 9 by JarkPomsky 3
Maciej_ZG Posted January 9 Posted January 9 Spróbuje znaleźć trochę czasu w przyszłym tygodniu i dodać support do requestów HTTP i json'a. Rozumiem że to i tak na chwilę obecną działa tylko w jedną stronę, czyli można jedynie odczytać dane z mierników itp. ?
JarkPomsky Posted January 9 Posted January 9 (edited) Tylko odczyt. Próbowałem wstrzykiwać inne wartości do pamięci, ale gra je liczy ileś tam razy na sekundę i momentalnie zastępuje je prawidłowymi. Wszystkie mierniki / kontrolki / można odczytywać - w zasadzie wszystko co jest pod F8 (dzięki @Conrad za uświadomienie, że istnieje coś takiego :D) Edited January 9 by JarkPomsky
Maciej_ZG Posted January 9 Posted January 9 Jak tylko odczyt to wciąż tylko połowiczny sukces, bo trzeba by emulować naciskanie klawiszy klawiatury przy odczytywanieu danych z fizycznego pulpitu...
Conrad Posted January 9 Posted January 9 9 godzin temu, Maciej_ZG napisał(a): Jak tylko odczyt to wciąż tylko połowiczny sukces, bo trzeba by emulować naciskanie klawiszy klawiatury przy odczytywanieu danych z fizycznego pulpitu... Niestety tylko na razie tędy droga, ale kolejne elementy pulpitu ożyją.
Conrad Posted January 9 Posted January 9 10 godzin temu, JarkPomsky napisał(a): Tylko odczyt. Próbowałem wstrzykiwać inne wartości do pamięci, ale gra je liczy ileś tam razy na sekundę i momentalnie zastępuje je prawidłowymi. Wszystkie mierniki / kontrolki / można odczytywać - w zasadzie wszystko co jest pod F8 (dzięki @Conrad za uświadomienie, że istnieje coś takiego :D) W weekand sprobuję to przetestować i dam znać co się udało uzyskać. 1
Gazz292 Posted January 14 Posted January 14 (edited) On 1/4/2025 at 1:22 AM, pomiary.el1 said: I have a lot of spare parts like "Z" switches, LS48 lights, buttons, even one brake controller is left. If someone ever... I'd really like to buy some real Polish train parts (i'd really love to buy the entire driving desk from a train similar to the EU07) But the problems i have had before when trying to buy parts from Poland is i live in the UK 😞 and that silly brexit thing we had has made it more complicated for people in europe to send things here now, having to fill in customs forms and all that (which i always offer to pay extra for the persons time to do that, and of course cover all shipping costs) Then uk customs tries to charge me import duties and UK VAT (taxes) for second hand scrap parts i buy before they will deliver the items to me (i've bought old bus parts from Germany before for my Omsi driving cab) but i am getting used to that now, and know that 'second hand parts from scrapped vehicles' should not be taxed, but that's something for me to deal with, not the seller. I did try to buy some EN57 parts last year, but was told they would not send them out of Poland, seem's i am a minority being an english person who lives Polish trains thanks to SimRail. ----- Sorry for writing in english in the Polish section, i've been told in the past not to use google translate and try to post in a language i can't speak, as it's better to let the reader of the post translate the english text themselves. Edited January 15 by Gazz292 1
Conrad Posted Saturday at 08:11 PM Posted Saturday at 08:11 PM (edited) @JarkPomsky właśnie udało mi się przekazać dane z JSON do arduino 🙂 Na razie zrobiłem test zapalania się lampki LED kiedy wartość przekroczy >100 z tego co opublikowałeś Kod dla Arduino Leonardo (8bit) #include <ArduinoJson.h> // Pin dla diody LED const int ledPin = 10; // Zmienna do przechowywania ostatniego czasu unsigned long previousMillis = 0; const long interval = 1000; // Czas oczekiwania w ms void setup() { Serial.begin(9600); // Inicjalizacja portu szeregowego pinMode(ledPin, OUTPUT); // Ustawienie pinu diody LED jako wyjścia digitalWrite(ledPin, LOW); // Wyłączenie diody na start Serial.println("Uruchomiono Arduino."); } void loop() { // Sprawdzanie, czy dostępne są dane na porcie szeregowym if (Serial.available() > 0) { String jsonData = Serial.readString(); // Odczyt danych JSON Serial.print("Odebrane dane: "); Serial.println(jsonData); // Przetwarzanie JSON StaticJsonDocument<1024> doc; DeserializationError error = deserializeJson(doc, jsonData); if (error) { Serial.print("Błąd przetwarzania JSON: "); Serial.println(error.c_str()); return; } // Odczytanie wartości value_1 if (doc.containsKey("value_1")) { float value_1 = doc["value_1"]; Serial.print("Odczytana wartość: "); Serial.println(value_1); // Sterowanie diodą LED w zależności od wartości if (value_1 > 100) { digitalWrite(ledPin, HIGH); // Włącz diodę Serial.println("Dioda WŁĄCZONA"); } else { digitalWrite(ledPin, LOW); // Wyłącz diodę Serial.println("Dioda WYŁĄCZONA"); } } else { Serial.println("Brak klucza 'value_1' w danych JSON."); } } } Jako, że mam Arduino po kablu USB-> to w pythonie zrobilem API do czytania danych import serial import time import requests from requests.adapters import HTTPAdapter from urllib3.util.retry import Retry # Ustawienia portu szeregowego serial_port = "COM11" # Zmień na właściwy port, do którego podłączone jest Arduino baud_rate = 9600 # URL API api_url = "http://192.168.0.66:5000/api/receive_data" # Konfiguracja sesji z ponownymi próbami session = requests.Session() retries = Retry(total=5, backoff_factor=1, status_forcelist=[500, 502, 503, 504]) session.mount("http://", HTTPAdapter(max_retries=retries)) def main(): try: # Inicjalizacja połączenia szeregowego ser = serial.Serial(serial_port, baud_rate, timeout=1) print(f"Połączono z Arduino na {serial_port}") while True: try: # Pobierz dane z API z timeoutem i zamykaniem połączenia with session.get(api_url, timeout=5) as response: if response.status_code == 200: json_data = response.json() # Przetwarzanie odpowiedzi JSON print(f"Otrzymane dane z API: {json_data}") # Wysyłanie danych JSON do Arduino ser.write((str(json_data) + "\n").encode('utf-8')) else: print(f"Błąd API: {response.status_code}") time.sleep(1) # Odczekaj 1 sekundę przed kolejnym żądaniem except requests.exceptions.RequestException as e: print(f"Błąd połączenia z API: {e}") time.sleep(0.01) # Odczekaj przed kolejną próbą except Exception as e: print(f"Wystąpił błąd podczas pętli głównej: {e}") break except KeyboardInterrupt: print("Zakończono działanie.") except Exception as e: print(f"Wystąpił błąd: {e}") finally: if 'ser' in locals() and ser.is_open: ser.close() print("Zamknięto port szeregowy.") if __name__ == "__main__": main() Działa 🙂 edit: dodalem zabezpieczenie do limitu otwartych połączeń sieciowych na określony portm, żeby jego nie zamykał. Edited Saturday at 10:31 PM by Conrad 4
JarkPomsky Posted Sunday at 02:37 PM Posted Sunday at 02:37 PM (edited) U mnie stan prac wygląda tak: Nie sądziłem że tak ciężko będzie znaleźć lampki w pamięci. Jedna uwaga. Manometry używają własnej skali - jedna duża kreska na tarczy to 1, 2,3 i tak dalej, a nie wartości prawdziwe. main.7z Edited Sunday at 02:48 PM by JarkPomsky 1
Conrad Posted Sunday at 06:08 PM Posted Sunday at 06:08 PM 3 godziny temu, JarkPomsky napisał(a): U mnie stan prac wygląda tak: Nie sądziłem że tak ciężko będzie znaleźć lampki w pamięci. Jedna uwaga. Manometry używają własnej skali - jedna duża kreska na tarczy to 1, 2,3 i tak dalej, a nie wartości prawdziwe. Thx Co do nanometrów to wartość rzeczywista podzielona przez 100 na skali manometrów, czyli 4,19 to wartość 0,419 Nie mam silników krokowych na razie, więc tutaj niepoeksperyemntuje, ale na razie działa to co pokazałeś powyżej. 1
JarkPomsky Posted Sunday at 09:01 PM Posted Sunday at 09:01 PM Najgorzej że każda grubsza aktualizacja gry może pozmieniać strukturę pamięci i trzeba będzie szukać wszystkiego na nowo 😄 oby nie 😄
JarkPomsky Posted Monday at 01:56 PM Posted Monday at 01:56 PM Stało się to co podejrzewałem. Najnowszy hotfix pozmieniał strukturę pamięci - dane są teraz w innym miejscu pamięci, więc program jest ślepy. Jako że jest to zbyt czasochłonne żeby aktualizować i dość trudne projekt porzucam. Lepiej poczekać na API. Jeśli jednak ktoś by chciał poszukać na własną rękę to udostępniam kod gdzie można wprowadzić znalezione offsety i skompilować samemu: https://pastecode.io/s/r1zcis5s Wartości manometrów woltomierzów i amperomierzów są typem "float". Lampki typem "int". Trzeba o tym pamiętać i pozmieniać w kodzie odpowiednio. Wartości szuka się za pomocą Cheat Engine. Szukając lampek trzeba zaznaczyć "4 Bytes" i szukać odpowiedni 0 dla wyłączonej i 1 dla zapalonej. Szukając reszty trzeba zaznaczyć "float" oraz szukać wartości konkretnie wyświetlanej (pod f8). 1 1
Conrad Posted Monday at 02:04 PM Posted Monday at 02:04 PM (edited) 18 minut temu, JarkPomsky napisał(a): Stało się to co podejrzewałem. Najnowszy hotfix pozmieniał strukturę pamięci - dane są teraz w innym miejscu pamięci, więc program jest ślepy. Jako że jest to zbyt czasochłonne żeby aktualizować i dość trudne projekt porzucam. Lepiej poczekać na API. Jeśli jednak ktoś by chciał poszukać na własną rękę to udostępniam kod gdzie można wprowadzić znalezione offsety i skompilować samemu: https://pastecode.io/s/r1zcis5s Wartości manometrów woltomierzów i amperomierzów są typem "float". Lampki typem "int". Trzeba o tym pamiętać i pozmieniać w kodzie odpowiednio. Wartości szuka się za pomocą Cheat Engine. Szukając lampek trzeba zaznaczyć "4 Bytes" i szukać odpowiedni 0 dla wyłączonej i 1 dla zapalonej. Szukając reszty trzeba zaznaczyć "float" oraz szukać wartości konkretnie wyświetlanej (pod f8). Też się tego obawiałem, że jak się tak stanie to nie ma sensu tego tak prowadzić. Pokazałeś i udostępniłeś alternatywę, więc ukłony, może pogrzebię w tym temacie, ale chłopaki w SimRail niech obiecają rzadkie aktualizacje 😉 albo udostępnią I/O dla nas, prosimy @uetam 🙂 Edited Monday at 02:15 PM by Conrad 4
Conrad Posted 12 hours ago Posted 12 hours ago Dzisiaj pobawilem się tą pamiecią, faktycznie da sie znalezc wartosci, np SHP, czy moment zalaczenia dzwieku dla czuwaka itp, ale po ponownym uruchomieniu SR gubi te dane 😕 Na razie testuje rozwiazanie na zczytywaniu danych rgb danego pixela. W weekand jak uruchomie drukarke pokaze dzialajacy element. Na razie mały test: 20250121_221626.mp4 1
Recommended Posts