Zugang zu USB-HID-Geräten verschaffen?

Wenn du dir nicht sicher bist, in welchem der anderen Foren du die Frage stellen sollst, dann bist du hier im Forum für allgemeine Fragen sicher richtig.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

__blackjack__ hat geschrieben: Montag 2. Juli 2018, 21:39 @xXSkyWalkerXx1: Was meinst Du mit ”öffnen”? Da ist Maschinensprache drin die Dein Prozessor ausführen kann, und eventuell auch Daten. Wobei es heutzutage auch möglich wäre das .NET-Bytecode für die .NET-VM enthalten ist. Dann könnte man den Code *vielleicht* auch auf einem Raspi verwenden. Auf jeden Fall bräuchte man eine API-Beschreibung, denn an den exportierten Symbolen alleine wird man wohl nur in seltenen/einfachen Fällen raten können wie man die API benutzt.

Werkzeug für native DLLs wäre beispielsweise Dependency Walker. Für .NET gibt's sicher auch irgendwas was da ein wenig Reflection betreibt.
Hier die "API Dokumentation":

Code: Alles auswählen

Classes:

OutputBuffer:
	public readonly int[] Outputs; - an array holding the 36 output values (index 0 - 29 are controller outputs and 30 - 35 are TRACE_1 - TRACE_6)
	public int Output00; - A property that directly gets you the value of index 0 from the above array
	public int Output01; - A property that directly gets you the value of index 1 from the above array
		... all the way to Output29

	public int Trace1; - A Property that directly gets you the TRACE_1 value from the above array
	public int Trace2; - A Property that directly gets you the TRACE_2 value from the above array
		... all the way to Trace6
		
	This class is used to hold the Output & Trace values for I/O Status
	
InputBuffer:
	public readonly int[] Inputs; - Similar to Outputs in OutputBuffer except for Inputs...
	public int Input00; - A property that directly gets you the value of index 0 from the above array
	public int Input01; - A property that directly gets you the value of index 1 from the above array
		... all the way to Input29
	
	This class is used to hold the Input values for I/O Status
	
CmCommand:
	Same as OutputBuffer, just used slightly differently internally

	This class is used to send controller output to the CM through the API Mode (it ONLY effects the controller output, nothing else)
	
CmCommandEx:
	Same as CmCommand with the addition of controlling various other things:
	
	public bool ResetLeds; - A variable used to determine if you wish to reset the leds to their default values (as defined by the console)
	public bool TurnOffController; - A variable used to determine if you wish to turn off the controller
	public bool ResetRumble; - A property used to determine if you wish to reset the rumble to their default state (and thus disable blocking rumble)
	public int RumbleA; - A property used to determine how much RUMBLE_A should be set to - Range: 0 - 100
	public int RumbleB; - A property used to determine how much RUMBLE_B should be set to - Range: 0 - 100
	public int RumbleLT; - A property used to determine how much RUMBLE_LT should be set to - Range: 0 - 100
	public int RumbleRT; - A property used to determine how much RUMBLE_RT should be set to - Range: 0 - 100
	public bool BlockRumble; - A Property used to determine if you wish to block the rumble packet completely
	public IOStatus.LedState Led1; - A Property used to determine the state of LED_1
	public IOStatus.LedState Led2; - A Property used to determine the state of LED_2
	public IOStatus.LedState Led3; - A Property used to determine the state of LED_3
	public IOStatus.LedState Led4; - A Property used to determine the state of LED_4
	
	public CmCommandEx CreateCoppy(); - A Function that generates a copy to retain settings without sending flags that things changed (use this if you already have a instance of this class, otherwise create a new instance)
	
IOStatus:

	public enum ConsoleType {
		None 		= 0x00, 			// No Console connected
		Ps3 		= 0x01, 			// Connected to a PS3
		Xb360 		= 0x02, 			// Connected to a Xbox 360
		Ps4 		= 0x03, 			// Connected to a PS4
		Xb1 		= 0x04, 			// Connected to a Xbox One
		Wheel 		= 0x08, 			// Wheel Edition outputs as a Wheel, this bit is set for that
		Ps3Wheel	= Ps3 | Wheel,		// A Combination flag for PS3/Wheel (Not used)
		Xb360Wheel	= Xb360 | Wheel,	// A Combination flag for Xbox 360/Wheel (Not used)
		Ps4Wheel	= Ps4 | Wheel, 		// A Combination flag for PS4/Wheel - Used with Wheel Edition (Outputting as a G29)
		Xb1Wheel	= Xb1 | Wheel		// A Combination flag for Xbox 1/Wheel (Not used)
    }

    public enum ControllerType {
		None 	= 0x00,	// No Controller connected
		Ps3		= 0x10,	// A Dualshock 3 Controller connected
		Xb360	= 0x20,	// A Xbox 360 Controller connected
		Wii		= 0x30,	// A Wiimote Controller connected
		WiiN	= 0x31,	// A Wiimote Controller with a Nunchuck connected
		WiiPro	= 0x32,	// A Wii Classic Pro controller connected
		Ps4		= 0x40,	// A Dualshock 4 Controller connected
		Xb1		= 0x50,	// A Xbox One Controller connected
		G25		= 0x69,	// A Logitech G25 Wheel connected (Wheel Edition Only)
		G27		= 0x6B 	// A Logitech G27 Wheel connected (Wheel Edition Only)
	}

    public enum LedState {
		Off 		= 0,	// Led# is Off
		On 			= 1,	// Led# is On
		Blink 		= 2,	// Led# is Blinking
		BlinkSlow	= 3		// Led# is Blinking Slowly
	}
	
	public readonly InputBuffer InputStatus; - A Variable holding the current Input Values
	public readonly OutputBuffer OutputStatus; - A Variable holding the current Output & Trace Values	
	public string Console; - A Readonly Property that is a text representation of the currently connected console
	public ConsoleType ConnectedConsole; - A Readonly Property that holds a flag telling you what console the CM is connected to
	public string Controller; - A Readonly Property that is a text representation of the currently connected controller
	public ControllerType ConnectedController; - A Readonly Property that holds a flag telling you what controller is connected to the CM
	public DateTime Timestamp; - A Readonly Property that is a timestamp for when this I/O Status was generated
	public string Slot; - A Readonly Property that is a text representation of the currently used slot
	public int SlotValue; - A Readonly Property that holds the value of the current slot, range: 0 - 10 (10 is when you have loaded a script rather then using an actual slot on the CM)
	public string Battery; - A Readonly Property that is a text representation of the current state of the battery, 0 - 100% or "Charging"
	public int BatteryValue; - A Readonly Property that holds the value of the battery Range: 0 - 100 (normal) anything above 100 means it's charging... the stepping is 10
	public string Cpuload; - A Readonly Property that is a text representation of the current Cpuload of the CM
	public int CpuloadValue; - A Readonly Property that holds the current value of the current Cpuload of the CmCommand
	public string Led1; - A Readonly Property that is a text representation of the current state of LED_1
	public LedState LedState1; - A Readonly Property that holds the current state of LED_1	
	public string Led2; - A Readonly Property that is a text representation of the current state of LED_2
	public LedState LedState2; - A Readonly Property that holds the current state of LED_2	
	public string Led3; - A Readonly Property that is a text representation of the current state of LED_3
	public LedState LedState3; - A Readonly Property that holds the current state of LED_3	
	public string Led4; - A Readonly Property that is a text representation of the current state of LED_4
	public LedState LedState4; - A Readonly Property that holds the current state of LED_4
	public string RumbleA; - A Readonly Property that is a text representation of the current state of RUMBLE_A
	public int RumbleA; - A Readonly Property that holds the value of the current state of RUMBLE_A, Range: 0 - 100	
	public string RumbleB; - A Readonly Property that is a text representation of the current state of RUMBLE_B
	public int RumbleB; - A Readonly Property that holds the value of the current state of RUMBLE_B, Range: 0 - 100	
	public string RumbleLt; - A Readonly Property that is a text representation of the current state of RUMBLE_LT
	public int RumbleLt; - A Readonly Property that holds the value of the current state of RUMBLE_LT, Range: 0 - 100	
	public string RumbleRt; - A Readonly Property that is a text representation of the current state of RUMBLE_RT
	public int RumbleRt; - A Readonly Property that holds the value of the current state of RUMBLE_RT, Range: 0 - 100
	
	This class is used to tell you what the current state of the CM is in (Everything you can see in Device Monitor)
	
IOLabels:
	public static string[] GetLabels(IOStatus.ControllerType controller); - A Function that returns an array of 30 strings representing the fields of the controller passed to the function, where there is no name a null value is set
	public static string[] GetLabels(IOStatus.ConsoleType console); - A Function that returns an array of 30 strings representing the fields of the console passed to the function, where there is no name a null value is set
	
	This static class is used to get the labels for the various buttons
	
DeviceSettings:

	public enum BackLightValues {
		Disabled					= 0x00,													// CM Backlight Disabled
		Blue						= 0x01,													// CM Backlight Custom - Blue
		Green						= 0x02,													// CM Backlight Custom - Green
		Cyan						= 0x03,													// CM Backlight Custom - Cyan
		Red							= 0x04,													// CM Backlight Custom - Red
		Magenta						= 0x05,													// CM Backlight Custom - Magenta
		Yellow						= 0x06,													// CM Backlight Custom - Yellow
		White						= 0x07,													// CM Backlight Custom - White
		Custom						= Blue | Green | Cyan | Red | Magenta | Yellow | White, // CM Backlight Custom - This value should NOT be set, it's a flag you can use to check if it's custom or not
		StrictControllerPlayerLeds	= 0x40,													// CM Backlight Strict Controller Player Leds (It ignores GPC changes)
		MimicControllerPlayerLeds	= 0x80													// CM Backlight Mimic Controller Player Leds (It follows whatever GPC says)
    }

	public enum BtRumbles {
		Fullspeed		= 0x00,	// Full Speed - No limitations
		FlowControl		= 0x01, // Flow Control - Some limitations
		FlowControlPlus = 0x02, // Flow Control+ - Less limitations then above
		Disabled		= 0x03	// Disabled - Completely disabled
	}

	public enum Consoles {
		Automatic	= 0x00,	// Automatic Output Protocol
		Ps3			= 0x01,	// Force PS3 Output Protocol
		Xb360		= 0x02,	// Force Xbox 360 Output Protocol
		Ps4			= 0x03,	// Force PS4 Output Protocol
		Xb1			= 0x04	// Force Xbox One Output Protocol
	}

	public enum TimeoutValues {
		Disabled	= 0,	// Don't turn off the controller due to inactivity
		Minutes5	= 5,	// Wait 5 minutes before turning off the controller
		Minutes10	= 10,	// Wait 10 minutes before turning off the controller
		Minutes15	= 15,	// Wait 15 minutes before turning off the controller
		Minutes20	= 20,	// Wait 20 minutes before turning off the controller
		Minutes30	= 30,	// Wait 30 minutes before turning off the controller
		Minutes60	= 60	// Wait 60 minutes before turning off the controller
	}
	
	public BtRumbles BtRumble;
	public bool BtSearching;
	public bool Ds3AutoPair;
	public byte Ds4LightbarBrightness;
	public TimeoutValues IdleTimeout;
	public Consoles OutputProtocol;
	public bool PartialDs4CrossOver;
	public bool RemoteControlSlot;
	public bool RemoteControlSlotG8;
	public bool SlotRecall;
	public bool InFrameOut;
	public bool InFrameIn;
	public bool OneMsResponse;
	public bool Ds4BtBoost;
	
	This class is used to determine what settings the current CM has along with saving new settings
	
DeviceInformation:

	public enum OperationalModes {
		Unknown,			// The operational mode of this CM isn't supported/known
		Standard,			// It's the Standard Edition firmware...
		TournamentEdition,	// It's the Tournament Edition firmware...
		WheelEdition		// It's the PS4 Wheel Edition firmware...
	}

	public enum States {
		Disconnected,	// There is no supported CM connected/detected/found
		Connected,		// There is a supported CM connected in it's standard mode, and it's ready for communication
		ApiMode,		// There is a supported CM connected in it's API mode, and it's ready for API commands
		Updating		// There is a supported CM connected, and we are attempting to get information about it (Operational Mode, Firmware Version etc.)
	}
	
	 public States State; - A readonly property telling you what state the CM is currently in
	 public Version Fw; - A readonly property telling you what firmware the currently connected CM has (null if unknown [only happening while "updating"])
	 public OperationalModes OperationalMode; - A readonly property telling you what operational mode the current CM is in
	 public bool IsHubCompatible; - A readonly property telling you whether or not the currently connected CM is "Hub Compatible" (1.21+ only)
	 
	This class i used to determine what state the current CM is in, along with giving you some basic information about it...

CommandFailedEventArgs:

	public enum Commands {
		RequestIoStatus,
		LoadScript,
		ApiModeBuffer,
		RequestDeviceSettings,
		SaveDeviceSettings,
		EnterApiMode,
		ExitApiMode,
		UnloadGpc,
		ChangeSlot,
		TurnOffController,
		GetDeviceInfo
	}

	public enum FailureReasons {
		DeviceNotConnected,
		FailedToSendCommand,
		FailedToReadResult,
		NeedApiMode
        }

	public Commands Command; - The command that failed
	public FailureReasons Reason; - The reason it failed (DeviceNotConnected means it was disconnected, or you didn't have a CM connected before sending a request, NeedApiMode means you're currently not in API Mode which you need to be to use that particular command...)

SingleDevice:

	public EventHandler<DeviceInformation> DeviceInformationChanged; - A EventHandler that you can register to in order to be notified of when the information/status of the connected CM changes
	public EventHandler<DeviceSettings> DeviceSettingsChanged; - A EventHandler that you can register to in order to be notified of when the settings changed (when a request for the device settings has been completed)
	public EventHandler<IOStatus> IOStatusChanged; - A EventHandler that you can register to in order to be notified of when the I/O Status changes (as a response to your request for an IO Status update, or an API mode output call)
	public EventHandler<CommandFailedEventArgs> CommandFailed; - A Eventhandler that you can register to in order to be notified if/when a command failed, this is primarily for debugging purposes and/or so you can tell when the CM is malfunctioning for whatever reason
	
	public void StartWorkerThreads(); - A function you must call in order for the API to actually work (this is what makes the API actually function, it's got it's own threads for the communication with the CM)
	public void StopWorkerThreads(); - A function you can call to stop the API's worker threads, use this when you close your application, otherwise it may prevent your app from exiting
	
	public DeviceInformation GetLastDeviceInfo(); - A function you can call to get the last DeviceInformation/State (current info/state)
	public DeviceSettings GetLastDeviceSettings(); - A function you can call to get the last DeviceSettings (current settings, NOTE: this function only returns the last settings as per your last request's response from the CM) NOTE: this function will return null if there has been no request made, otherwise it'll return whatever is cached in memory since last completed request
	
	public void RequestSettings(); - A function you can call to request the current settings of the currently connected CM, NOTE: this function cannot be used while in API mode
	public void SaveSettings(DeviceSettings settings); - A function you can call to save the settings you pass to it to the currently connected CM, NOTE: this function cannot be used while in API mode
	
	public void EnterApiMode(); - A function you must call before you can start sending out API output packets, NOTE: this function cannot be used while in API mode
	public void ExitApiMode(); - A function you can call to return to "normal" state if/when you want to stop sending API output packets, NOTE: This function can only be used while in API mode
	
	public void RequestIoStatus(); - A function you can call to request the current I/O status, NOTE: this function cannot be used while in API mode
	
	public void UnloadGpc(); - A function you can call to unload the current GPC script from memory, NOTE: this function cannot be used while in API mode
	public void LoadGpc(byte[] bytecode); - A function you can call to send a compiled GPC script (bytecode) to the CM, NOTE: this function cannot be used while in API mode
	public void LoadGpc(string filename); - Same as above, except it takes a filename and will load whatever is in the file as bytecode, NOTE: this function cannot be used while in API mode
	
	public void ChangeSlot(); - A function you can call to switch slot on the CM, NOTE: this function cannot be used while in API mode
	public void TurnOffController(); - A function you can call to turn off the currently connected controller, NOTE: this function cannot be used while in API mode
	
	public bool SendApiModeData(CmCommand buffer); - A function you can call to send controller output, see CmCommand for more information about the buffer, it will return true if the buffer was actually sent, otherwise false, NOTE: This function can only be used while in API Mode
	public bool SendApiModeData(CmCommandEx buffer); - A function you can call to send controller output along with Leds, Rumbles etc. see CmCommandEx for more information about the buffer, it will return true if the buffer was actually sent, otherwise false, NOTE: This function can only be used while in API Mode
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Na das ist eine C#-API. Das geht auch eher nur unter Windows. Mono gibt es zwar, ob man das auf dem PI laufen lassen *will* ist die erste Frage, aber vor allem ist das ja USB Gedoens hier, das nutzt unter Garantie proprietare Schnittstellen. Geht also nicht auf dem PI. Und was diese API nun genau tut, kann man ohne damit mal wirklich gespielt zu haben nicht sagen.

Dies ganze Projekt wird so nicht funktionieren. Nicht, weil es prinzipiell nicht gehen kann. Aber das ganze Oekosystem von diesem CronusMax ist komplex, und das kann man mal nicht so eben aus der Lameng hier mit ein paar warmen Tipps garnieren, so das du begreifst, was du da machen musst. Da es dir ja offensichtlich an wirklich allen Grundlagen fehlt, und auf der anderen Seite diese Geschichte weder was mit Python im allgemeinen zu tun hat, noch jemand hier zu sein scheint, der das spezielle Problem hat, kennt, und loesen kann.

Wenn du da grundsaetzlich drauf hinarbeiten willst, fang an C# zu lernen, und bau Tools mit dieser API. Da stellt sich dann hoffentlich auch ein Verstaendnis dafuer ein, wie genau das funktioniert. Und dieses C#-Tool kannst du ja auch genauso vertreiben wie ein potentielles Python-Tool.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Hmm, okey... :D

Dann lass ich einfach erstmal die Idee weg, dass direkt auf dem CronusMax installieren zu lassen.

Welche Möglichkeiten gäbe es aber, um in einem Programm einen Skript zu integrieren, der bloß erstmal an bestimmten Stellen verändert werden soll - also keine Funktion in dem Sinne hat?
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Was ist "einen Skript". Redest du immer noch von deinem GDC Ding?
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ja.

Hast du eigentlich ne Idee, wie ich Python am Besten richtig erlernen kann? Will jetzt aber auch nichts mit zu einfachen anfangen. ^^
Würde ja sagen, ich machs wie bei GPC, aber Python hat einfach zu viele Funktionen und Module, um mich wie bei GPC einfach drauf zu stürzen... :lol:
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Zu dem GDC Ding habe ich ja schon was gesagt - vergleichen, wie zwei unterschiedliche Skripte aussehen, die sich nur durch eine einzige Konstante unterscheiden. Dazu hilft einem zB ein Hex-Editor, ein Werkzeug das man als Programmierer gelegentlich mal braucht. Und programmieren lernt man IMHO durch machen. Nur sollte man mit seinen Ambitionen da ein bisschen realistisch sein. Du wirst fuer eine ganze Weile kleine Broetchen backen. So ist es nunmal.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Wie meinst das mit dem Vergleichen?

Das ist mir klar - aber so als "Kleinprogammierer" aus GPC zu nem richtigen Programmierer mit Python - is'n enormer Unterschied, da es einfach massig and an Modulen und Funktionen gibt! :D
Okey, also sprich: einfach Projekte starten, aber es nicht gleich zum Anfang übertreiben? :D
__deets__
User
Beiträge: 14539
Registriert: Mittwoch 14. Oktober 2015, 14:29

Vergleichen. Anschauen, was gleich ist, und was unterschiedlich. Wie ein Suchbild mit Unterschieden. So arbeitet halt ein Compiler: werte und code werden in eine Datei geschrieben, die dann von irgendwas abgearbeitet wird. Meistens dem Prozessor. Wenn du daran schraubst, siehst du, was sich aendert. Das ist halt fummelige Arbeit, weil nicht notwendigerweise alles, was sich geaendert hat, auch relevant ist. Da kommt es dann auf die eigentlichen Werte an.

Und ja, einfach Projekte starten, und nicht uebertreiben.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Ich glaube wir reden bissel vorbei... :D
Aber ist auch egal, denn ich hatte doch bereits ne Idee. ^^

Okey, dann hab ich schonmal richtig angefangen. :D
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Was muss ich eigentlich schreiben, um ein Programm zu erstellen, was im Skript nach jedem Zeilenende ein "\n\" anhängt?
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hängst einfach ein `"\n\"` an jedes Zeilenende. Ernsthaft, wenn Du ein konkretes Problem hast, dann zeig den Code, beschreibst, was das Programm macht und wie sich das von dem gewünschten Verhalten abweicht.
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Es soll ja einfach bloß ein Programm sein, dass an einer Textdatei an jedem Zeilenende ein "\n\" anhängen, dazu ist es nicht nötig ein Code zu posten.
Sirius3
User
Beiträge: 17749
Registriert: Sonntag 21. Oktober 2012, 17:20

Du hast es ja scheinbar versucht und bist gescheitert. Dann kannst Du doch Deinen Versuch zeigen. Sonst ist der Lerneffekt bei Dir gleich Null, weil Du einfach das vorgefertigte Skript benutzt und bei der nächsten kleinen Änderung wieder hier nachfragen mußt.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Also in der Programmiersprache Rust könnte man das so lösen:

Code: Alles auswählen

use std::fs::File;
use std::io;
use std::io::prelude::*;
use std::io::BufReader;

fn main() -> io::Result<()> {
    let in_file = File::open("test.txt")?;
    let mut out_file = File::create("test2.txt")?;
    let reader = BufReader::new(in_file);
    reader.lines().for_each(|line|
        out_file.write_all((line.unwrap() + "\n\\\n").as_bytes()).unwrap()
    );
    Ok(())
}
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

https://github.com/ahtn/python-easyhid
Könnte mir das eigentlich helfen?
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Wobei helfen?
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
xXSkyWalkerXx1
User
Beiträge: 379
Registriert: Mittwoch 27. Juni 2018, 17:39

Um so vllt sehr leicht Daten zu HID USB Geräten zu übermittel bzw von denen zu bekommen?
Ist zwar nur ein Modul, aber naja...das Beispiel da sah unkompliziert aus um Daten zu bekommen bzw senden.
Benutzeravatar
__blackjack__
User
Beiträge: 13103
Registriert: Samstag 2. Juni 2018, 10:21
Wohnort: 127.0.0.1
Kontaktdaten:

Ja klar, dabei kann das helfen. Solange man weiss wie das Protokoll aussieht das die Gegenseite verwendet.
„All religions are the same: religion is basically guilt, with different holidays.” — Cathy Ladman
Antworten