UNPKG

qbuzz

Version:

A library for handling signals and events in Das Keyboard Q Cloud

336 lines (318 loc) 9.16 kB
const request = require('request'); const signalHeaders = { "Content-Type": "application/json" } /** * The base class for apps that run on the Q Desktop */ class QDesktopApp { constructor() { process.on('SIGINT', (message) => { this.shutdown(); process.exit(); }) } /** * The extension point for any activities that should * take place before shutting down. */ shutdown() {} } /** * Class representing a single point to be sent to the device * @param {string} color - The hexadecimal RGB color to activate, e.g. '#FFCCDD' * @param {string} effect - The effect to activate. Enumerated in Effects. Default is empty. */ class QPoint { constructor(color, effect = Effects.SET_COLOR) { this.color = color; this.effect = effect; } } class QDesktopSignal { /** * * @param {string} extensionId The id of the Extension that is sending the signal * @param {QPoint[][]} points A 2D array of QPoints expressing the signal */ constructor(extensionId, points) { this.extensionId = extensionId; this.points = points; } } /** * Class representing a signal (version 1) to be sent to the device. */ class SignalV1 { /** * Create a signal. * @param {string} clientName - The name of the client registering the signal. * @param {string} zoneId - The zone to activate. Enumerated in ZoneCodes. * @param {string} color - The hexadecimal RGB color to activate, e.g. '#FFCCDD' * @param {string} effect - The effect to activate. Enumerated in Effects. Default is empty. * @param {string} action - The action. Default is empty. * @param {string} name - The name of the signal. Default is empty. * @param {string} pid - The product ID. Default is 'DK5QPID'. * @param {boolean} isMuted - If false, the Signal Center will not create a notification. * Default is true. * @pram {string} message - The message to display, if any. Default is empty. * */ constructor({ clientName, zoneId, color, effect = Effects.SET_COLOR, action = '', name = '', pid = 'DK5QPID', isMuted = true, message = '' } = {}) { this.clientName = clientName; this.zoneId = zoneId; this.color = color; this.effect = effect; this.name = name; this.action = action; this.pid = pid; this.isMuted = isMuted.toString(); this.message = message; } } /** * Class representing a device zone */ class Zone { /** * Create a zone * @param {string} code - The device's code for the zone. Enumerated in ZoneCodes. * @param {number} x - The x position of the zone * @param {number} y - The y position of the zone */ constructor(code, x, y) { this.code = code; this.x = x; this.y = y; } } /** * An enumeration of zone codes */ const ZoneCodes = Object.freeze({ 'KEY_BACKSPACE': 'KEY_BACKSPACE', 'KEY_TAB': 'KEY_TAB', 'KEY_ENTER': 'KEY_ENTER', 'KEY_SHIFT_LEFT': 'KEY_SHIFT_LEFT', 'KEY_SHIFT_RIGHT': 'KEY_SHIFT_RIGHT', 'KEY_CONTROL_RIGHT': 'KEY_CONTROL_RIGHT', 'KEY_CONTROL_LEFT': 'KEY_CONTROL_LEFT', 'KEY_ALT_LEFT': 'KEY_ALT_LEFT', 'KEY_ALT_RIGHT': 'KEY_ALT_RIGHT', 'KEY_PAUSE_BREAK': 'KEY_PAUSE_BREAK', 'KEY_CAPS_LOCK': 'KEY_CAPS_LOCK', 'KEY_ESCAPE': 'KEY_ESCAPE', 'KEY_SPACE': 'KEY_SPACE', 'KEY_PAGE_UP': 'KEY_PAGE_UP', 'KEY_PAGE_DOWN': 'KEY_PAGE_DOWN', 'KEY_END': 'KEY_END', 'KEY_HOME': 'KEY_HOME', 'KEY_ARROW_LEFT': 'KEY_ARROW_LEFT', 'KEY_ARROW_UP': 'KEY_ARROW_UP', 'KEY_ARROW_RIGHT': 'KEY_ARROW_RIGHT', 'KEY_ARROW_DOWN': 'KEY_ARROW_DOWN', 'KEY_INSERT': 'KEY_INSERT', 'KEY_DELETE': 'KEY_DELETE', 'KEY_0': 'KEY_0', 'KEY_1': 'KEY_1', 'KEY_2': 'KEY_2', 'KEY_3': 'KEY_3', 'KEY_4': 'KEY_4', 'KEY_5': 'KEY_5', 'KEY_6': 'KEY_6', 'KEY_7': 'KEY_7', 'KEY_8': 'KEY_8', 'KEY_9': 'KEY_9', 'KEY_A': 'KEY_A', 'KEY_B': 'KEY_B', 'KEY_C': 'KEY_C', 'KEY_D': 'KEY_D', 'KEY_E': 'KEY_E', 'KEY_F': 'KEY_F', 'KEY_G': 'KEY_G', 'KEY_H': 'KEY_H', 'KEY_I': 'KEY_I', 'KEY_J': 'KEY_J', 'KEY_K': 'KEY_K', 'KEY_L': 'KEY_L', 'KEY_M': 'KEY_M', 'KEY_N': 'KEY_N', 'KEY_O': 'KEY_O', 'KEY_P': 'KEY_P', 'KEY_Q': 'KEY_Q', 'KEY_R': 'KEY_R', 'KEY_S': 'KEY_S', 'KEY_T': 'KEY_T', 'KEY_U': 'KEY_U', 'KEY_V': 'KEY_V', 'KEY_W': 'KEY_W', 'KEY_X': 'KEY_X', 'KEY_Y': 'KEY_Y', 'KEY_Z': 'KEY_Z', 'KEY_LESS_THAN': 'KEY_LESS_THAN', 'KEY_GREATER_THAN': 'KEY_GREATER_THAN', 'KEY_META': 'KEY_META', 'KEY_CONTEXT_MENU': 'KEY_CONTEXT_MENU', 'KEY_F1': 'KEY_F1', 'KEY_F2': 'KEY_F2', 'KEY_F3': 'KEY_F3', 'KEY_F4': 'KEY_F4', 'KEY_F5': 'KEY_F5', 'KEY_F6': 'KEY_F6', 'KEY_F7': 'KEY_F7', 'KEY_F8': 'KEY_F8', 'KEY_F9': 'KEY_F9', 'KEY_F10': 'KEY_F10', 'KEY_F11': 'KEY_F11', 'KEY_F12': 'KEY_F12', 'KEY_F13': 'KEY_F13', 'KEY_F14': 'KEY_F14', 'KEY_F15': 'KEY_F15', 'KEY_F16': 'KEY_F16', 'KEY_F17': 'KEY_F17', 'KEY_F18': 'KEY_F18', 'KEY_F19': 'KEY_F19', 'KEY_NUMLOCK': 'KEY_NUMLOCK', 'KEY_SCROLL_LOCK': 'KEY_SCROLL_LOCK', 'KEY_PRINT_SCREEN': 'KEY_PRINT_SCREEN', 'KEY_EXCLAMATION_MARK': 'KEY_EXCLAMATION_MARK', 'KEY_SEMICOLON': 'KEY_SEMICOLON', 'KEY_EQUAL': 'KEY_EQUAL', 'KEY_COMMA': 'KEY_COMMA', 'KEY_SUBTRACT': 'KEY_SUBTRACT', 'KEY_DOT': 'KEY_DOT', 'KEY_SLASH': 'KEY_SLASH', 'KEY_BACKTICK': 'KEY_BACKTICK', 'KEY_OPEN_SQUARE_BRACKET': 'KEY_OPEN_SQUARE_BRACKET', 'KEY_BACKSLASH': 'KEY_BACKSLASH', 'KEY_CLOSE_SQUARE_BRACKET': 'KEY_CLOSE_SQUARE_BRACKET', 'KEY_QUOTE': 'KEY_QUOTE', 'KEY_OEM_8': 'KEY_OEM_8', 'KEY_OEM_102': 'KEY_OEM_102', 'KEY_NUMPAD_0': 'KEY_NUMPAD_0', 'KEY_NUMPAD_1': 'KEY_NUMPAD_1', 'KEY_NUMPAD_2': 'KEY_NUMPAD_2', 'KEY_NUMPAD_3': 'KEY_NUMPAD_3', 'KEY_NUMPAD_4': 'KEY_NUMPAD_4', 'KEY_NUMPAD_5': 'KEY_NUMPAD_5', 'KEY_NUMPAD_6': 'KEY_NUMPAD_6', 'KEY_NUMPAD_7': 'KEY_NUMPAD_7', 'KEY_NUMPAD_8': 'KEY_NUMPAD_8', 'KEY_NUMPAD_9': 'KEY_NUMPAD_9', 'KEY_NUMPAD_ADD': 'KEY_NUMPAD_ADD', 'KEY_NUMPAD_SEPARATOR': 'KEY_NUMPAD_SEPARATOR', 'KEY_NUMPAD_SUBTRACT': 'KEY_NUMPAD_SUBTRACT', 'KEY_NUMPAD_DECIMAL': 'KEY_NUMPAD_DECIMAL', 'KEY_NUMPAD_DIVIDE': 'KEY_NUMPAD_DIVIDE', 'KEY_NUMPAD_ENTER': 'KEY_NUMPAD_ENTER', 'KEY_DOLLAR_SIGN': 'KEY_DOLLAR_SIGN', 'KEY_PERCENT': 'KEY_PERCENT', 'KEY_MICRO': 'KEY_MICRO', 'KEY_MACRO_1': 'KEY_MACRO_1', 'KEY_MACRO_2': 'KEY_MACRO_2', 'KEY_MACRO_3': 'KEY_MACRO_3', 'KEY_MACRO_4': 'KEY_MACRO_4', 'KEY_MACRO_5': 'KEY_MACRO_5', 'KEY_MACRO_6': 'KEY_MACRO_6', 'KEY_MACRO_7': 'KEY_MACRO_7', 'KEY_MACRO_8': 'KEY_MACRO_8', 'KEY_MACRO_9': 'KEY_MACRO_9', 'KEY_MACRO_10': 'KEY_MACRO_10', 'KEY_MACRO_11': 'KEY_MACRO_11', 'KEY_MACRO_12': 'KEY_MACRO_12', 'KEY_VOLUME_Q_BUTTON': 'KEY_VOLUME_Q_BUTTON', 'KEY_VOLUME_KNOB': 'KEY_VOLUME_KNOB', 'KEY_LIGHT_PIPE_RIGHT': 'KEY_LIGHT_PIPE_RIGHT', 'KEY_LIGHT_PIPE_LEFT': 'KEY_LIGHT_PIPE_LEFT', 'KEY_FN_KEY': 'KEY_FN_KEY', 'KEY_META_LEFT': 'KEY_META_LEFT', 'KEY_META_RIGHT': 'KEY_META_RIGHT', 'KEY_LIGHT_INDICATOR_GAMING_MODE': 'KEY_LIGHT_INDICATOR_GAMING_MODE', 'KEY_LIGHT_INDICATOR_CAPSLOCK': 'KEY_LIGHT_INDICATOR_CAPSLOCK', 'KEY_LIGHT_INDICATOR_NUMLOCK': 'KEY_LIGHT_INDICATOR_NUMLOCK', 'KEY_LIGHT_INDICATOR_SCROLLOCK': 'KEY_LIGHT_INDICATOR_SCROLLOCK', 'KEY_LIGHT_INDICATOR_DPI': 'KEY_LIGHT_INDICATOR_DPI', 'KEY_WHEEL': 'KEY_WHEEL', 'KEY_LIGHT_SHOE': 'KEY_LIGHT_SHOE', 'KEY_LIGHT_LOGO': 'KEY_LIGHT_LOGO', 'KEY_ACUTE_ACCENT': 'KEY_ACUTE_ACCENT', 'KEY_CEDILLA': 'KEY_CEDILLA', 'KEY_SPANISH_N': 'KEY_SPANISH_N', 'KEY_UBERMUT': 'KEY_UBERMUT', 'KEY_ADD': 'KEY_ADD', 'KEY_OKONOM': 'KEY_OKONOM', 'KEY_ARGER': 'KEY_ARGER', 'KEY_HASH': 'KEY_HASH', 'KEY_PIPE': 'KEY_PIPE', 'KEY_ROOFTOP': 'KEY_ROOFTOP', 'KEY_EXP_2': 'KEY_EXP_2' }); /** * An enumeration of effects */ const Effects = Object.freeze({ 'SET_COLOR': 'SET_COLOR', 'BLINK': 'BLINK', 'BREATHE': 'BREATHE', 'COLOR_CYCLE': 'COLOR_CYCLE', 'RIPPLE': 'RIPPLE', 'INWARD_RIPPLE': 'INWARD_RIPPLE', 'BOUNCING_LIGHT': 'BOUNCING_LIGHT', 'LASER': 'LASER', 'WAVE': 'WAVE' }); var backendUrl = 'http://localhost:27301'; /** * Send a signal. * @param {Signal} signal */ function sendLocal(signal) { request.post({ url: backendUrl + '/api/1.0/signals', headers: signalHeaders, body: signal, json: true }, (err) => { if (err && err.code === 'ECONNREFUSED') { console.error(`Error: failed to connect to ${config.qUrl}, make sure the Das Keyboard Q software` + ' is running'); } }); } /** * Read the configuration from command line arguments. The first command line argument should be a JSON string. */ function readConfig() { if (process.argv.length > 2) { try { let config = JSON.parse(process.argv[2]); Object.freeze(config); console.log("Configuration:\n", JSON.stringify(config)); return config; } catch (error) { console.error("Could not parse config as JSON: " + process.argv[2]); process.exit(1); } } else { return Object.freeze({}); } } module.exports = { backendUrl: backendUrl, Config: readConfig, DesktopApp: QDesktopApp, Point: QPoint, Send: sendLocal, Signal: QDesktopSignal, Effects: Effects }