connector-ws-api
v5.0.0
Published
Comprehensive WebSocket API for connector Dispensers with full command support
Downloads
7
Readme
Cash Dispenser WebSocket API
A comprehensive WebSocket-based API for communicating with Genmega cash dispensers. This package provides a complete set of methods for controlling and monitoring cash dispenser operations.
Installation
npm install dispenser-ws-apiQuick Start
import DispenserSDK from "dispenser-ws-api";
// Initialize the SDK
const dispenser = new DispenserSDK("ws://your-server-url");
// Connect to the dispenser
await dispenser.connect();
// Initialize the dispenser
await dispenser.initialize();
// Get current status
const status = await dispenser.getStatus();
console.log("Dispenser Status:", status);
// Dispense cash
await dispenser.dispense([
{ cassetteNumber: 1, count: 5, denomination: 20 }, // 5x $20 bills
{ cassetteNumber: 2, count: 2, denomination: 50 }, // 2x $50 bills
]);API Reference
Connection Management
constructor(wsUrl)
Creates a new DispenserSDK instance.
wsUrl(string): WebSocket URL for the dispenser server
connect()
Establishes WebSocket connection to the dispenser.
- Returns:
Promise<string>- Resolves when connected
disconnect()
Closes the WebSocket connection.
onMessage(callback)
Registers a listener for all incoming messages.
callback(function): Function to call when messages are received
removeListener(callback)
Removes a message listener.
callback(function): The listener function to remove
Core Dispenser Operations
initialize()
Initializes the cash dispenser system.
- Returns:
Promise- Resolves when initialization is complete
getStatus()
Gets the current status of the dispenser.
- Returns:
Promise<Object>- Status information including:status: Current operational statuserror: Any error conditionscassettes: Cassette status array
reset()
Resets the cash dispenser to initial state.
- Returns:
Promise- Resolves when reset is complete
dispense(cassettes)
Dispenses cash from specified cassettes.
cassettes(Array): Array of cassette objects:[ { cassetteNumber: 1, // Cassette number (1-4) count: 5, // Number of notes denomination: 20, // Value per note }, ];- Returns:
Promise<Object>- Dispense result with transaction details
sendDispenseCommand(cassetteNumber, count) (Legacy)
Legacy method for dispensing from a single cassette.
cassetteNumber(number): Cassette number (1-4)count(number): Number of notes to dispense- Returns:
Promise- Resolves when dispense is complete
Cassette Management
getCassetteInfo()
Gets detailed information about all cassettes.
- Returns:
Promise<Object>- Cassette information including counts and denominations
getCashLevels()
Gets current cash levels for all cassettes.
- Returns:
Promise<Array>- Array of cassette levels
setCassetteDenomination(cassetteNumber, denomination)
Sets the denomination for a specific cassette.
cassetteNumber(number): Cassette numberdenomination(number): Note denomination value- Returns:
Promise- Resolves when denomination is set
setCassetteCount(cassetteNumber, count)
Sets the note count for a cassette (used during refilling).
cassetteNumber(number): Cassette numbercount(number): Number of notes- Returns:
Promise- Resolves when count is set
Configuration & Control
setConfiguration(config)
Sets dispenser configuration.
config(Object): Configuration object- Returns:
Promise- Resolves when configuration is applied
getConfiguration()
Gets current dispenser configuration.
- Returns:
Promise<Object>- Current configuration
setEnabled(enabled)
Enables or disables the dispenser.
enabled(boolean): Enable/disable state- Returns:
Promise- Resolves when state is changed
lock()
Locks the dispenser (prevents operations).
- Returns:
Promise- Resolves when locked
unlock()
Unlocks the dispenser.
- Returns:
Promise- Resolves when unlocked
Testing & Maintenance
selfTest(options)
Performs self-test of dispenser mechanisms.
options(Object): Test configuration options- Returns:
Promise<Object>- Test results
calibrate()
Calibrates the dispenser mechanisms.
- Returns:
Promise- Resolves when calibration is complete
performMaintenance(operation, parameters)
Performs maintenance operations.
operation(string): Maintenance operation typeparameters(Object): Operation parameters- Returns:
Promise- Resolves when maintenance is complete
testSensors(sensorIds)
Tests specific sensors.
sensorIds(Array): Array of sensor IDs to test- Returns:
Promise<Object>- Test results
getSensorReadings()
Gets current sensor readings.
- Returns:
Promise<Object>- Sensor data
Monitoring & Logging
getErrorLogs(options)
Retrieves error logs from the dispenser.
options(Object): Filter options for logs- Returns:
Promise<Array>- Array of error log entries
clearErrorLogs()
Clears the error log.
- Returns:
Promise- Resolves when logs are cleared
getTransactionHistory(options)
Gets transaction history.
options(Object): Filter options- Returns:
Promise<Array>- Array of transaction records
Limits & Security
setLimits(limits)
Sets dispenser operational limits.
limits(Object): Limit configuration:{ dailyLimit: 10000, // Daily cash limit transactionLimit: 1000, // Per-transaction limit hourlyLimit: 5000 // Hourly limit }- Returns:
Promise- Resolves when limits are set
getLimits()
Gets current operational limits.
- Returns:
Promise<Object>- Current limits
Emergency Operations
emergencyStop()
Immediately halts all dispenser operations.
- Returns:
Promise- Resolves when stopped
resumeOperations()
Resumes operations after emergency stop.
- Returns:
Promise- Resolves when resumed
System Information
getFirmwareVersion()
Gets firmware version information.
- Returns:
Promise<Object>- Firmware version details
updateFirmware(firmwareData)
Updates dispenser firmware (if supported).
firmwareData(Object): Firmware update data- Returns:
Promise- Resolves when update is complete
verifyFunctionality()
Verifies overall dispenser functionality.
- Returns:
Promise<Object>- Verification results
Event Handling
The SDK emits various events that you can listen for:
dispenser.onMessage((data) => {
switch (data.type) {
case "STATUS_UPDATE":
console.log("Status changed:", data.status);
break;
case "ERROR":
console.error("Dispenser error:", data.error);
break;
case "DISPENSE_COMPLETE":
console.log("Dispense completed:", data.result);
break;
case "CASH_LOW":
console.warn("Cash low in cassette:", data.cassetteNumber);
break;
case "MAINTENANCE_REQUIRED":
console.warn("Maintenance required:", data.details);
break;
}
});Error Handling
All methods return promises that can be caught for error handling:
try {
await dispenser.dispense([{ cassetteNumber: 1, count: 5, denomination: 20 }]);
console.log("Dispense successful");
} catch (error) {
console.error("Dispense failed:", error.message);
}Example Usage
Complete Transaction Flow
import DispenserSDK from "dispenser-ws-api";
class ATMController {
constructor(wsUrl) {
this.dispenser = new DispenserSDK(wsUrl);
this.setupEventListeners();
}
async initialize() {
try {
await this.dispenser.connect();
await this.dispenser.initialize();
const status = await this.dispenser.getStatus();
console.log("Dispenser ready:", status);
return true;
} catch (error) {
console.error("Initialization failed:", error);
return false;
}
}
async dispenseCash(amount) {
try {
// Check cash levels first
const levels = await this.dispenser.getCashLevels();
console.log("Current cash levels:", levels);
// Calculate optimal note combination
const cassettes = this.calculateOptimalDispense(amount, levels);
// Perform dispense
const result = await this.dispenser.dispense(cassettes);
console.log("Dispense completed:", result);
return result;
} catch (error) {
console.error("Dispense failed:", error);
throw error;
}
}
calculateOptimalDispense(amount, levels) {
// Your logic to calculate optimal note combination
// This is a simplified example
const cassettes = [];
// Try to use largest denominations first
if (amount >= 100 && levels[3].count > 0) {
const count = Math.min(Math.floor(amount / 100), levels[3].count);
cassettes.push({ cassetteNumber: 4, count, denomination: 100 });
amount -= count * 100;
}
if (amount >= 50 && levels[2].count > 0) {
const count = Math.min(Math.floor(amount / 50), levels[2].count);
cassettes.push({ cassetteNumber: 3, count, denomination: 50 });
amount -= count * 50;
}
if (amount >= 20 && levels[1].count > 0) {
const count = Math.min(Math.floor(amount / 20), levels[1].count);
cassettes.push({ cassetteNumber: 2, count, denomination: 20 });
amount -= count * 20;
}
if (amount >= 10 && levels[0].count > 0) {
const count = Math.min(Math.floor(amount / 10), levels[0].count);
cassettes.push({ cassetteNumber: 1, count, denomination: 10 });
amount -= count * 10;
}
if (amount > 0) {
throw new Error(
"Cannot dispense exact amount with available denominations"
);
}
return cassettes;
}
setupEventListeners() {
this.dispenser.onMessage((data) => {
switch (data.type) {
case "CASH_LOW":
this.handleLowCash(data);
break;
case "ERROR":
this.handleError(data);
break;
case "MAINTENANCE_REQUIRED":
this.handleMaintenanceRequired(data);
break;
}
});
}
handleLowCash(data) {
console.warn(
`Cash low in cassette ${data.cassetteNumber}: ${data.remainingCount} notes`
);
// Implement notification logic
}
handleError(data) {
console.error(`Dispenser error: ${data.error}`);
// Implement error handling logic
}
handleMaintenanceRequired(data) {
console.warn(`Maintenance required: ${data.details}`);
// Implement maintenance scheduling logic
}
}
// Usage
const atm = new ATMController("ws://localhost:3000");
await atm.initialize();
await atm.dispenseCash(200); // Dispense $200WebSocket Message Format
All messages follow this format:
{
messageId: 123, // Unique message ID
type: "COMMAND_TYPE", // Command type
timestamp: "2024-01-01T00:00:00Z", // ISO timestamp
// ... command-specific payload
}Response format:
{
messageId: 123, // Matching request message ID
type: "RESPONSE_TYPE", // Response type
success: true, // Success/failure flag
timestamp: "2024-01-01T00:00:00Z", // ISO timestamp
data: { /* response data */ }, // Response payload
error: "Error message" // Error message (if success: false)
}License
ISC
Support
For support and issues, please contact the development team or refer to the Genmega documentation.
