### Initialize and Control Shockers via HTTP and Serial Source: https://github.com/c9glax/cshocker/blob/master/README.md Demonstrates initializing shockers using both HTTP and Serial connections with an API key. It shows how to retrieve shockers, control their actions (e.g., vibrate), and properly dispose of them after use. Ensure you have a valid API key for HTTP connections. ```csharp public static void Main(string[] args){ string apiKey = ":)"; OpenShockHttp openShockHttp = new (apiKey); OpenShockShocker shocker1 = openShockHttp.GetShockers().First(); shocker1.Control(ControlAction.Vibrate, 20, 1000); shocker1.Dispose(); List serialPorts = SerialHelper.GetSerialPorts(); int selectedPort = 1; OpenShockSerial openShockSerial = new(serialPorts[selectedPort], apiKey); OpenShockShocker shocker2 = openShockSerial.GetShockers().First(); shocker2.Control(ControlAction.Vibrate, 20, 1000); shocker2.Dispose(); } ``` -------------------------------- ### Initialize and Control PiShock Devices via HTTP Source: https://context7.com/c9glax/cshocker/llms.txt Instantiate the PiShockHttp API with your credentials and control individual shockers using their share codes. Intensity ranges from 0-100%, and duration is in milliseconds (sent as seconds to the API). ```csharp using CShocker.Devices.APIs; using CShocker.Shockers; string apiKey = "your-pishock-api-key"; // From https://pishock.com string username = "YourPiShockUsername"; string shareCode = "ABCDEF123456"; // Share code for the device // Instantiate PiShock HTTP API PiShockHttp api = new(apiKey, username); // Custom endpoint (optional): // PiShockHttp api = new(apiKey, username, endpoint: "https://custom.pishock.example.com/api/apioperate"); // Manually create a PiShockShocker using the device's share code PiShockShocker shocker = new(api, shareCode); // Vibrate at 50% for 2 seconds (sent as 2 to the API) shocker.Control(ControlAction.Vibrate, 50, 2000); // Beep for 1 second (minimum allowed duration) shocker.Control(ControlAction.Beep, 0, 1000); // Shock at 15% for 1 second shocker.Control(ControlAction.Shock, 15, 1000); shocker.Dispose(); ``` -------------------------------- ### JSON Serialization/Deserialization with Custom Converters Source: https://context7.com/c9glax/cshocker/llms.txt Demonstrates serializing and deserializing Shocker objects using custom Newtonsoft.Json converters. `ShockerJsonConverter` distinguishes between OpenShock and PiShock, while `ApiJsonConverter` reconstructs the correct `Api` subclass. ```csharp using CShocker.Devices.Additional; using CShocker.Shockers.Additional; using CShocker.Shockers; using Newtonsoft.Json; OpenShockHttp api = new("your-api-token"); OpenShockShocker shocker = api.GetShockers().First(); // Serialize shocker to JSON string json = JsonConvert.SerializeObject(shocker); File.WriteAllText("shocker.json", json); // {"Name":"MyCollar","ID":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","RfId":12345,"Model":1,...} // Deserialize — ShockerJsonConverter detects type by presence of "Model" key // ApiJsonConverter reconstructs the correct Api subclass from "ApiType" byte var settings = new JsonSerializerSettings(); settings.Converters.Add(new ApiJsonConverter()); settings.Converters.Add(new ShockerJsonConverter()); OpenShockShocker restored = JsonConvert.DeserializeObject( File.ReadAllText("shocker.json"), settings)!; // Restored shocker retains its API association and can be used immediately restored.Control(ControlAction.Vibrate, 20, 1000); restored.Dispose(); ``` -------------------------------- ### OpenShockSerial - Control shockers via a locally connected ESP32 over serial Source: https://context7.com/c9glax/cshocker/llms.txt Opens a serial port to a locally attached OpenShock ESP32 hub and sends RF transmit commands directly. It also uses the OpenShock HTTP API to enumerate shockers. Suitable for offline/local use. ```APIDOC ## OpenShockSerial ### Description Opens a serial port (baud rate 115200) to a locally attached OpenShock ESP32 hub and sends RF transmit commands directly to it. It also uses the OpenShock HTTP API to enumerate shockers (for their RF IDs and models). This is suitable for offline/local use without routing commands through the cloud. Intensity is 0–100%, duration is 300–30000 ms. ### Constructor #### Description Initializes the `OpenShockSerial` client, opening the specified serial port. #### Method ```csharp OpenShockSerial api = new(selectedPort, apiKey, logger: null); ``` #### Parameters - **selectedPort** (SerialPortInfo) - Required - Information about the serial port to use. - **apiKey** (string) - Required - Your OpenShock API key. - **logger** (ILogger) - Optional - A logger instance for diagnostic output. ### Get Shockers #### Description Retrieves a list of shockers available through the serial connection. #### Method ```csharp api.GetShockers() ``` ### Control Shocker #### Description Sends a control command to a shocker via the serial port. Commands are serialized as JSON. #### Method ```csharp shocker.Control(ControlAction action, int intensity, int durationMs) ``` #### Parameters - **action** (ControlAction) - Required - The action to perform (Shock, Vibrate, Beep, Stop). - **intensity** (int) - Required - The intensity of the action (0-100). - **durationMs** (int) - Required - The duration of the action in milliseconds. ### Request Example ```csharp // Commands are serialized as JSON and written to the serial port, e.g.: // rftransmit {"model":"petrainer","id":12345,"type":"vibrate","intensity":20,"durationMs":1000} shocker.Control(ControlAction.Vibrate, 20, 1000); shocker.Control(ControlAction.Shock, 5, 300); ``` ### Dispose #### Description Closes the underlying serial port and cleans up any background tasks. #### Method ```csharp shocker.Dispose() ``` ``` -------------------------------- ### Control Shockers via OpenShock Serial Connection Source: https://context7.com/c9glax/cshocker/llms.txt Use `OpenShockSerial` to connect to a local OpenShock ESP32 hub via a serial port. This method sends RF transmit commands directly, suitable for offline use. It requires enumerating serial ports and selecting the correct one. Remember to dispose of the `OpenShockSerial` instance to close the serial port and clean up tasks. ```csharp using CShocker.Devices.APIs; using CShocker.Devices.Abstract; using CShocker.Devices.Additional; using CShocker.Shockers; // Enumerate connected serial ports (Windows only - uses WMI) #pragma warning disable CA1416 List ports = SerialHelper.GetSerialPorts(); for (int i = 0; i < ports.Count; i++) Console.WriteLine($"{i}) {ports[i]}"); // Output example: // 0) SerialPortInfo // PortName: COM3 // Description: Silicon Labs CP210x USB to UART Bridge // Manufacturer: Silicon Labs // DeviceID: USB\VID_10C4&PID_EA60\... Console.Write("Select port index: "); int idx = int.Parse(Console.ReadLine()!); SerialPortInfo selectedPort = ports[idx]; string apiKey = "your-openshock-api-token"; // Constructor opens the serial port immediately; throws on failure OpenShockSerial api = new(selectedPort, apiKey, logger: null); OpenShockShocker shocker = api.GetShockers().First(); // Commands are serialized as JSON and written to the serial port, e.g.: // rftransmit {"model":"petrainer","id":12345,"type":"vibrate","intensity":20,"durationMs":1000} shocker.Control(ControlAction.Vibrate, 20, 1000); shocker.Control(ControlAction.Shock, 5, 300); shocker.Dispose(); // Closes the underlying serial port and cleans up tasks ``` -------------------------------- ### Control Shockers via OpenShock HTTP API Source: https://context7.com/c9glax/cshocker/llms.txt Use `OpenShockHttp` to connect to the OpenShock REST API using an API token. Retrieve all owned and shared shockers, then send commands like shock, vibrate, beep, or stop. Ensure to dispose of the API client to clean up queued tasks. ```csharp using CShocker.Devices.APIs; using CShocker.Devices.Additional; using CShocker.Shockers; using Microsoft.Extensions.Logging; using Microsoft.Extensions.Logging.Console; // Set up optional logging using ILoggerFactory loggerFactory = LoggerFactory.Create(b => b.AddConsole().SetMinimumLevel(LogLevel.Debug)); ILogger logger = loggerFactory.CreateLogger(); // Instantiate the HTTP API client (custom endpoint is optional) string apiKey = "your-openshock-api-token"; OpenShockHttp api = new(apiKey, logger: logger); // Alternatively with a self-hosted instance: // OpenShockHttp api = new(apiKey, endpoint: "https://my-openshock.example.com", logger: logger); // Fetch all owned + shared shockers from the OpenShock API IEnumerable shockers = api.GetShockers(); foreach (OpenShockShocker shocker in shockers) { Console.WriteLine(shocker); // Prints name, ID, RF-ID, model, created date, paused state // Vibrate at 30% intensity for 1 second shocker.Control(ControlAction.Vibrate, 30, 1000); // Beep for 500 ms shocker.Control(ControlAction.Beep, 0, 500); // Shock at 10% intensity for 300 ms (minimum safe duration) shocker.Control(ControlAction.Shock, 10, 300); // Stop any ongoing action shocker.Control(ControlAction.Stop, 0, 300); } // Always dispose to clean up queued tasks api.Dispose(); ``` -------------------------------- ### Shocker Control Method Signature Source: https://github.com/c9glax/cshocker/blob/master/README.md This is the signature for the `Shocker.Control` method. It accepts an action, intensity, and duration for controlling the shocker. Ensure the intensity and duration values are within the specified ranges. ```csharp Control(ControlAction action, int intensity, int duration) ``` -------------------------------- ### SerialHelper.GetSerialPorts Source: https://context7.com/c9glax/cshocker/llms.txt Enumerates available serial COM ports on Windows systems, providing metadata for each port. This is useful for identifying connected devices like ESP32 hubs. ```APIDOC ## `SerialHelper.GetSerialPorts` — Enumerate available serial ports (Windows) `SerialHelper.GetSerialPorts` uses WMI (`Win32_PnPEntity`) and the Windows Registry to enumerate all serial COM ports connected to the system, returning rich metadata including port name, device description, manufacturer, and PnP device ID. This is used to identify which port an OpenShock or PiShock ESP32 hub is connected to. ```csharp using CShocker.Devices.Additional; using CShocker.Devices.Abstract; using System.Runtime.Versioning; [SupportedOSPlatform("windows")] void ListAndSelectPort() { List ports = SerialHelper.GetSerialPorts(); if (ports.Count == 0) { Console.WriteLine("No serial ports found."); return; } foreach ((int i, SerialPortInfo port) in ports.Select((p, i) => (i, p))) { // SerialPortInfo fields: PortName, Description, Manufacturer, DeviceID Console.WriteLine($"[{i}] {port.PortName} — {port.Description} ({port.Manufacturer})"); // Example output: // [0] COM3 — Silicon Labs CP210x USB to UART Bridge (Silicon Labs) // [1] COM5 — USB-SERIAL CH340 (wch.cn) } } ``` ``` -------------------------------- ### Execute Control Actions on a Shocker Source: https://context7.com/c9glax/cshocker/llms.txt The Shocker.Control method sends actions like Beep, Vibrate, Shock, or Stop. It validates intensity (0-100%) and duration against device-specific ranges. Out-of-range values are ignored. ```csharp // Signature: // void Control(ControlAction action, int intensity, int duration) // ControlAction values: // ControlAction.Beep — Trigger the beeper/buzzer // ControlAction.Vibrate — Activate vibration motor // ControlAction.Shock — Deliver an electric pulse // ControlAction.Stop — Stop any ongoing action // OpenShock ranges: intensity 0–100 (%), duration 300–30000 (ms) // PiShock ranges: intensity 0–100 (%), duration 1000–15000 (ms) shocker.Control(ControlAction.Vibrate, 25, 1500); // 25% intensity, 1.5 seconds shocker.Control(ControlAction.Shock, 10, 300); // 10% intensity, 300 ms minimum shocker.Control(ControlAction.Beep, 0, 500); // Beep, intensity ignored shocker.Control(ControlAction.Stop, 0, 300); // Stop // Out-of-range values are silently ignored (logged at Information level): shocker.Control(ControlAction.Shock, 150, 300); // Ignored: intensity > 100 shocker.Control(ControlAction.Vibrate, 50, 50); // Ignored: duration < 300 (OpenShock) ``` -------------------------------- ### Enumerate Serial Ports on Windows Source: https://context7.com/c9glax/cshocker/llms.txt Lists available serial COM ports on Windows systems using WMI and the Registry. Useful for identifying connected hubs. ```csharp using CShocker.Devices.Additional; using CShocker.Devices.Abstract; using System.Runtime.Versioning; [SupportedOSPlatform("windows")] void ListAndSelectPort() { List ports = SerialHelper.GetSerialPorts(); if (ports.Count == 0) { Console.WriteLine("No serial ports found."); return; } foreach ((int i, SerialPortInfo port) in ports.Select((p, i) => (i, p))) { // SerialPortInfo fields: PortName, Description, Manufacturer, DeviceID Console.WriteLine($"[{i}] {port.PortName} — {port.Description} ({port.Manufacturer})"); // Example output: // [0] COM3 — Silicon Labs CP210x USB to UART Bridge (Silicon Labs) // [1] COM5 — USB-SERIAL CH340 (wch.cn) } } ``` -------------------------------- ### PiShockHttp - Control shockers via the PiShock cloud HTTP API Source: https://context7.com/c9glax/cshocker/llms.txt `PiShockHttp` sends commands to the PiShock REST API. Authentication requires a PiShock API key and username. Shockers are identified by a share code and must be instantiated manually as `PiShockShocker`. Intensity is 0–100%, duration is 1000–15000 ms. ```APIDOC ## `PiShockHttp` — Control shockers via the PiShock cloud HTTP API `PiShockHttp` sends commands to the PiShock REST API (`https://do.pishock.com/api/apioperate`). Authentication requires a PiShock API key and username. Shockers are identified by a share code and must be instantiated manually as `PiShockShocker`. Intensity is 0–100%, duration is 1000–15000 ms (note: duration is sent in **seconds** to the API, not milliseconds). ```csharp using CShocker.Devices.APIs; using CShocker.Shockers; string apiKey = "your-pishock-api-key"; // From https://pishock.com string username = "YourPiShockUsername"; string shareCode = "ABCDEF123456"; // Share code for the device // Instantiate PiShock HTTP API PiShockHttp api = new(apiKey, username); // Custom endpoint (optional): // PiShockHttp api = new(apiKey, username, endpoint: "https://custom.pishock.example.com/api/apioperate"); // Manually create a PiShockShocker using the device's share code PiShockShocker shocker = new(api, shareCode); // Vibrate at 50% for 2 seconds (sent as 2 to the API) shocker.Control(ControlAction.Vibrate, 50, 2000); // Beep for 1 second (minimum allowed duration) shocker.Control(ControlAction.Beep, 0, 1000); // Shock at 15% for 1 second shocker.Control(ControlAction.Shock, 15, 1000); shocker.Dispose(); ``` ``` -------------------------------- ### OpenShockHttp - Control shockers via the OpenShock cloud HTTP API Source: https://context7.com/c9glax/cshocker/llms.txt Connects to the OpenShock REST API using an API token to retrieve and control shockers. Supports shock, vibrate, beep, and stop actions with specified intensity and duration. ```APIDOC ## OpenShockHttp ### Description Connects to the OpenShock REST API (default endpoint `https://api.openshock.app`) using an API token. It supports retrieving all owned and shared shockers and sending shock/vibrate/beep/stop commands over HTTPS. Intensity is 0–100 (percent), duration is 300–30000 ms. ### Method ```csharp OpenShockHttp api = new(apiKey, logger: logger); // Alternatively with a self-hosted instance: // OpenShockHttp api = new(apiKey, endpoint: "https://my-openshock.example.com", logger: logger); ``` ### Get Shockers #### Description Fetches all owned and shared shockers from the OpenShock API. #### Method ```csharp api.GetShockers() ``` ### Control Shocker #### Description Sends a control command (Shock, Vibrate, Beep, Stop) to a specific shocker. #### Method ```csharp shocker.Control(ControlAction action, int intensity, int durationMs) ``` #### Parameters - **action** (ControlAction) - Required - The action to perform (Shock, Vibrate, Beep, Stop). - **intensity** (int) - Required - The intensity of the action (0-100). - **durationMs** (int) - Required - The duration of the action in milliseconds. ### Request Example ```csharp // Vibrate at 30% intensity for 1 second shocker.Control(ControlAction.Vibrate, 30, 1000); // Beep for 500 ms shocker.Control(ControlAction.Beep, 0, 500); // Shock at 10% intensity for 300 ms (minimum safe duration) shocker.Control(ControlAction.Shock, 10, 300); // Stop any ongoing action shocker.Control(ControlAction.Stop, 0, 300); ``` ### Dispose #### Description Cleans up queued tasks and releases resources associated with the API client. #### Method ```csharp api.Dispose() ``` ``` -------------------------------- ### Shocker.Control — Send a control action to a shocker Source: https://context7.com/c9glax/cshocker/llms.txt `Shocker.Control` is the primary method on all shocker types. It validates intensity and duration against the API's allowed ranges before enqueuing the command. Commands are executed sequentially with a 50 ms minimum gap between them, and execution waits for the duration of each command before proceeding to the next. ```APIDOC ## `Shocker.Control` — Send a control action to a shocker `Shocker.Control` is the primary method on all shocker types. It validates intensity and duration against the API's allowed ranges before enqueuing the command. Commands are executed sequentially with a 50 ms minimum gap between them, and execution waits for the duration of each command before proceeding to the next. ```csharp // Signature: // void Control(ControlAction action, int intensity, int duration) // ControlAction values: // ControlAction.Beep — Trigger the beeper/buzzer // ControlAction.Vibrate — Activate vibration motor // ControlAction.Shock — Deliver an electric pulse // ControlAction.Stop — Stop any ongoing action // OpenShock ranges: intensity 0–100 (%), duration 300–30000 (ms) // PiShock ranges: intensity 0–100 (%), duration 1000–15000 (ms) shocker.Control(ControlAction.Vibrate, 25, 1500); // 25% intensity, 1.5 seconds shocker.Control(ControlAction.Shock, 10, 300); // 10% intensity, 300 ms minimum shocker.Control(ControlAction.Beep, 0, 500); // Beep, intensity ignored shocker.Control(ControlAction.Stop, 0, 300); // Stop // Out-of-range values are silently ignored (logged at Information level): shocker.Control(ControlAction.Shock, 150, 300); // Ignored: intensity > 100 shocker.Control(ControlAction.Vibrate, 50, 50); // Ignored: duration < 300 (OpenShock) ``` ``` -------------------------------- ### Attach or Replace Logger at Runtime Source: https://context7.com/c9glax/cshocker/llms.txt Allows injecting or swapping an `ILogger` on an `Api` instance after construction. Useful for integrating with dependency injection hosts. ```csharp using CShocker.Devices.APIs; using Microsoft.Extensions.Logging; OpenShockHttp api = new("your-api-token"); // No logger initially // Later, attach a logger (e.g., from a DI container) using ILoggerFactory factory = LoggerFactory.Create(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace)); ILogger logger = factory.CreateLogger("CShocker"); api.SetLogger(logger); // From this point, all HTTP requests, command enqueues, and range violations are logged. // Remove the logger again (suppress all output) api.SetLogger(null); ``` -------------------------------- ### Retrieve OpenShock Shockers via API Source: https://context7.com/c9glax/cshocker/llms.txt Use OpenShockHttp.GetShockers to fetch all accessible OpenShock shockers, both owned and shared. The method returns a list of OpenShockShocker objects with details like ID, name, and model. It can be called as an instance or static method. ```csharp using CShocker.Devices.Abstract; using CShocker.Devices.APIs; using CShocker.Shockers; OpenShockHttp api = new("your-api-token"); // Instance method — uses the api's own credentials and endpoint IEnumerable shockers = api.GetShockers(); foreach (OpenShockShocker s in shockers) { // s.Name — Friendly name of the shocker // s.ID — UUID string (used for HTTP API calls) // s.RfId — Short RF identifier (used for serial commands) // s.Model — OpenShockModel.CaiXianlin or OpenShockModel.Petrainer // s.CreatedOn — DateTime the shocker was registered // s.IsPaused — Whether the shocker is paused on the server Console.WriteLine($"Found: {s.Name} ({s.Model}) ID={s.ID} Paused={s.IsPaused}"); } // Static method — useful when you don't have an instance yet IEnumerable staticResult = OpenShockApi.GetShockers( apiKey: "your-api-token", api: api, apiEndpoint: "https://api.openshock.app", logger: null ); ``` -------------------------------- ### ApiJsonConverter and ShockerJsonConverter Source: https://context7.com/c9glax/cshocker/llms.txt Provides custom Newtonsoft.Json converters for serializing and deserializing `Api` and `Shocker` objects, ensuring correct type reconstruction based on specific fields. ```APIDOC ## `ApiJsonConverter` and `ShockerJsonConverter` — JSON serialization of API and Shocker objects CShocker provides two Newtonsoft.Json converters for persisting and restoring `Api` and `Shocker` configurations. `ApiJsonConverter` uses the `ApiType` byte field to reconstruct the correct `Api` subclass. `ShockerJsonConverter` uses the presence of the `Model` field to distinguish `OpenShockShocker` from `PiShockShocker`. ```csharp using CShocker.Devices.Additional; using CShocker.Shockers.Additional; using CShocker.Shockers; using Newtonsoft.Json; OpenShockHttp api = new("your-api-token"); OpenShockShocker shocker = api.GetShockers().First(); // Serialize shocker to JSON string json = JsonConvert.SerializeObject(shocker); File.WriteAllText("shocker.json", json); // {"Name":"MyCollar","ID":"xxxxxxxx-xxxx-xxxx-xxxx-xxxxxxxxxxxx","RfId":12345,"Model":1,...} // Deserialize — ShockerJsonConverter detects type by presence of "Model" key // ApiJsonConverter reconstructs the correct Api subclass from "ApiType" byte var settings = new JsonSerializerSettings(); settings.Converters.Add(new ApiJsonConverter()); settings.Converters.Add(new ShockerJsonConverter()); OpenShockShocker restored = JsonConvert.DeserializeObject( File.ReadAllText("shocker.json"), settings)!; // Restored shocker retains its API association and can be used immediately restored.Control(ControlAction.Vibrate, 20, 1000); restored.Dispose(); ``` ``` -------------------------------- ### Api.SetLogger Source: https://context7.com/c9glax/cshocker/llms.txt Allows attaching or replacing an `ILogger` instance on an `Api` object at runtime, which is useful for integrating with dependency injection frameworks. ```APIDOC ## `Api.SetLogger` — Attach or replace a logger at runtime `SetLogger` allows injecting or swapping an `ILogger` on any `Api` instance after construction. This is useful when integrating CShocker into a dependency-injection host where the logger may not be available at construction time. ```csharp using CShocker.Devices.APIs; using Microsoft.Extensions.Logging; OpenShockHttp api = new("your-api-token"); // No logger initially // Later, attach a logger (e.g., from a DI container) using ILoggerFactory factory = LoggerFactory.Create(b => b.AddConsole().SetMinimumLevel(LogLevel.Trace)); ILogger logger = factory.CreateLogger("CShocker"); api.SetLogger(logger); // From this point, all HTTP requests, command enqueues, and range violations are logged. // Remove the logger again (suppress all output) api.SetLogger(null); ``` ``` -------------------------------- ### OpenShockApi.GetShockers — Retrieve all accessible OpenShock shockers Source: https://context7.com/c9glax/cshocker/llms.txt `GetShockers` queries both the `/1/shockers/own` and `/1/shockers/shared` endpoints of the OpenShock API and returns a combined list of `OpenShockShocker` instances, each pre-associated with the calling `Api` instance. It can also be called statically with explicit credentials. ```APIDOC ## `OpenShockApi.GetShockers` — Retrieve all accessible OpenShock shockers `GetShockers` queries both the `/1/shockers/own` and `/1/shockers/shared` endpoints of the OpenShock API and returns a combined list of `OpenShockShocker` instances, each pre-associated with the calling `Api` instance. It can also be called statically with explicit credentials. ```csharp using CShocker.Devices.Abstract; using CShocker.Devices.APIs; using CShocker.Shockers; OpenShockHttp api = new("your-api-token"); // Instance method — uses the api's own credentials and endpoint IEnumerable shockers = api.GetShockers(); foreach (OpenShockShocker s in shockers) { // s.Name — Friendly name of the shocker // s.ID — UUID string (used for HTTP API calls) // s.RfId — Short RF identifier (used for serial commands) // s.Model — OpenShockModel.CaiXianlin or OpenShockModel.Petrainer // s.CreatedOn — DateTime the shocker was registered // s.IsPaused — Whether the shocker is paused on the server Console.WriteLine($"Found: {s.Name} ({s.Model}) ID={s.ID} Paused={s.IsPaused}"); } // Static method — useful when you don't have an instance yet IEnumerable staticResult = OpenShockApi.GetShockers( apiKey: "your-api-token", api: api, apiEndpoint: "https://api.openshock.app", logger: null ); ``` ``` -------------------------------- ### Validate and Sample Intensity/Duration Values Source: https://context7.com/c9glax/cshocker/llms.txt Uses the `IntegerRange` value type to enforce intensity (0–100) and duration constraints. Can be used independently for random value generation within safe ranges. ```csharp using CShocker.Ranges; IntegerRange intensityRange = new(0, 100); IntegerRange durationRange = new(300, 30000); // Validation Console.WriteLine(intensityRange.IsValueWithinLimits(75)); // True Console.WriteLine(intensityRange.IsValueWithinLimits(150)); // False Console.WriteLine(durationRange.IsValueWithinLimits(200)); // False // Generate a random intensity within range int randomIntensity = intensityRange.RandomValueWithinLimits(); int randomDuration = durationRange.RandomValueWithinLimits(); Console.WriteLine($"Random command: intensity={randomIntensity}%, duration={randomDuration}ms"); // Access bounds directly Console.WriteLine($"Intensity range: {intensityRange.Min}–{intensityRange.Max}"); Console.WriteLine($"Duration range: {durationRange.Min}–{durationRange.Max}"); ``` -------------------------------- ### IntegerRange Source: https://context7.com/c9glax/cshocker/llms.txt A value type for validating and sampling integer values within specified minimum and maximum bounds, used for enforcing constraints on parameters like intensity and duration. ```APIDOC ## `IntegerRange` — Validate and sample intensity/duration values `IntegerRange` is a lightweight value type used internally by `Api` to enforce intensity (0–100) and duration (300–30000 ms for OpenShock; 1000–15000 ms for PiShock) constraints. It is publicly exposed and can be used independently for random value generation within safe ranges. ```csharp using CShocker.Ranges; IntegerRange intensityRange = new(0, 100); IntegerRange durationRange = new(300, 30000); // Validation Console.WriteLine(intensityRange.IsValueWithinLimits(75)); // True Console.WriteLine(intensityRange.IsValueWithinLimits(150)); // False Console.WriteLine(durationRange.IsValueWithinLimits(200)); // False // Generate a random intensity within range int randomIntensity = intensityRange.RandomValueWithinLimits(); int randomDuration = durationRange.RandomValueWithinLimits(); Console.WriteLine($"Random command: intensity={randomIntensity}%, duration={randomDuration}ms"); // Access bounds directly Console.WriteLine($"Intensity range: {intensityRange.Min}–{intensityRange.Max}"); Console.WriteLine($"Duration range: {durationRange.Min}–{durationRange.Max}"); ``` ``` === COMPLETE CONTENT === This response contains all available snippets from this library. No additional content exists. Do not make further requests.