@openrfid/cli 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +23 -0
- package/dist/index.d.ts +1 -0
- package/dist/index.js +333 -0
- package/dist/index.js.map +1 -0
- package/package.json +52 -0
package/LICENSE
ADDED
|
@@ -0,0 +1,23 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 RFID Software India Private Limited - https://rfidsoftwares.com
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
22
|
+
|
|
23
|
+
For RFID developer resources, documentation, hardware integrations, and enterprise software solutions, visit https://rfidsoftwares.com
|
package/dist/index.d.ts
ADDED
|
@@ -0,0 +1 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
package/dist/index.js
ADDED
|
@@ -0,0 +1,333 @@
|
|
|
1
|
+
#!/usr/bin/env node
|
|
2
|
+
"use strict";
|
|
3
|
+
var __create = Object.create;
|
|
4
|
+
var __defProp = Object.defineProperty;
|
|
5
|
+
var __getOwnPropDesc = Object.getOwnPropertyDescriptor;
|
|
6
|
+
var __getOwnPropNames = Object.getOwnPropertyNames;
|
|
7
|
+
var __getProtoOf = Object.getPrototypeOf;
|
|
8
|
+
var __hasOwnProp = Object.prototype.hasOwnProperty;
|
|
9
|
+
var __copyProps = (to, from, except, desc) => {
|
|
10
|
+
if (from && typeof from === "object" || typeof from === "function") {
|
|
11
|
+
for (let key of __getOwnPropNames(from))
|
|
12
|
+
if (!__hasOwnProp.call(to, key) && key !== except)
|
|
13
|
+
__defProp(to, key, { get: () => from[key], enumerable: !(desc = __getOwnPropDesc(from, key)) || desc.enumerable });
|
|
14
|
+
}
|
|
15
|
+
return to;
|
|
16
|
+
};
|
|
17
|
+
var __toESM = (mod, isNodeMode, target) => (target = mod != null ? __create(__getProtoOf(mod)) : {}, __copyProps(
|
|
18
|
+
// If the importer is in node compatibility mode or this is not an ESM
|
|
19
|
+
// file that has been converted to a CommonJS file using a Babel-
|
|
20
|
+
// compatible transform (i.e. "__esModule" has not been set), then set
|
|
21
|
+
// "default" to the CommonJS "module.exports" for node compatibility.
|
|
22
|
+
isNodeMode || !mod || !mod.__esModule ? __defProp(target, "default", { value: mod, enumerable: true }) : target,
|
|
23
|
+
mod
|
|
24
|
+
));
|
|
25
|
+
|
|
26
|
+
// src/index.ts
|
|
27
|
+
var import_commander = require("commander");
|
|
28
|
+
var import_chalk = __toESM(require("chalk"));
|
|
29
|
+
var import_inquirer = __toESM(require("inquirer"));
|
|
30
|
+
var import_ora = __toESM(require("ora"));
|
|
31
|
+
var import_fs = __toESM(require("fs"));
|
|
32
|
+
var import_path = __toESM(require("path"));
|
|
33
|
+
var import_cli_table3 = __toESM(require("cli-table3"));
|
|
34
|
+
var import_core = require("@openrfid/core");
|
|
35
|
+
var import_simulator = require("@openrfid/simulator");
|
|
36
|
+
var import_plugin_api = require("@openrfid/plugin-api");
|
|
37
|
+
var import_rest = require("@openrfid/rest");
|
|
38
|
+
var import_websocket = require("@openrfid/websocket");
|
|
39
|
+
var import_mqtt = require("@openrfid/mqtt");
|
|
40
|
+
var import_hopeland_discovery = require("@openrfid/hopeland-discovery");
|
|
41
|
+
var import_readers = require("@openrfid/readers");
|
|
42
|
+
var import_tags = require("@openrfid/tags");
|
|
43
|
+
var program = new import_commander.Command();
|
|
44
|
+
program.name("openrfid").description("OpenRFID Simulator CLI tool for headless operations and automation.").version("1.0.0");
|
|
45
|
+
program.command("init").description("Initialize a new OpenRFID Simulator configuration file").action(async () => {
|
|
46
|
+
const configPath = import_path.default.join(process.cwd(), "openrfid.config.json");
|
|
47
|
+
if (import_fs.default.existsSync(configPath)) {
|
|
48
|
+
const { overwrite } = await import_inquirer.default.prompt([
|
|
49
|
+
{
|
|
50
|
+
type: "confirm",
|
|
51
|
+
name: "overwrite",
|
|
52
|
+
message: "openrfid.config.json already exists. Overwrite it?",
|
|
53
|
+
default: false
|
|
54
|
+
}
|
|
55
|
+
]);
|
|
56
|
+
if (!overwrite) {
|
|
57
|
+
console.log(import_chalk.default.yellow("Initialization cancelled."));
|
|
58
|
+
return;
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
const answers = await import_inquirer.default.prompt([
|
|
62
|
+
{
|
|
63
|
+
type: "input",
|
|
64
|
+
name: "dbPath",
|
|
65
|
+
message: "Database storage path:",
|
|
66
|
+
default: "./openrfid.db"
|
|
67
|
+
},
|
|
68
|
+
{
|
|
69
|
+
type: "number",
|
|
70
|
+
name: "port",
|
|
71
|
+
message: "REST API Server Port:",
|
|
72
|
+
default: 3e3
|
|
73
|
+
},
|
|
74
|
+
{
|
|
75
|
+
type: "number",
|
|
76
|
+
name: "wsPort",
|
|
77
|
+
message: "WebSocket Server Port:",
|
|
78
|
+
default: 4e3
|
|
79
|
+
},
|
|
80
|
+
{
|
|
81
|
+
type: "confirm",
|
|
82
|
+
name: "mqttEnabled",
|
|
83
|
+
message: "Enable MQTT Broker client integration?",
|
|
84
|
+
default: false
|
|
85
|
+
}
|
|
86
|
+
]);
|
|
87
|
+
const configContent = {
|
|
88
|
+
dbPath: answers.dbPath,
|
|
89
|
+
server: {
|
|
90
|
+
port: answers.port,
|
|
91
|
+
host: "0.0.0.0"
|
|
92
|
+
},
|
|
93
|
+
websocket: {
|
|
94
|
+
port: answers.wsPort
|
|
95
|
+
},
|
|
96
|
+
mqtt: {
|
|
97
|
+
enabled: answers.mqttEnabled,
|
|
98
|
+
brokerUrl: "mqtt://localhost:1883"
|
|
99
|
+
},
|
|
100
|
+
hopeland: {
|
|
101
|
+
enabled: true,
|
|
102
|
+
tcpPort: 9090,
|
|
103
|
+
udpPort: 9091
|
|
104
|
+
}
|
|
105
|
+
};
|
|
106
|
+
import_fs.default.writeFileSync(configPath, JSON.stringify(configContent, null, 2));
|
|
107
|
+
console.log(import_chalk.default.green(`
|
|
108
|
+
Success! Created configuration file: ${configPath}`));
|
|
109
|
+
console.log(`Run ${import_chalk.default.cyan("openrfid simulator")} to start the simulator server.`);
|
|
110
|
+
});
|
|
111
|
+
program.command("simulator").description("Start the headless simulator server").option("-c, --config <path>", "Path to openrfid.config.json", "openrfid.config.json").action(async (options) => {
|
|
112
|
+
const configPath = import_path.default.resolve(process.cwd(), options.config);
|
|
113
|
+
let configData = {};
|
|
114
|
+
if (import_fs.default.existsSync(configPath)) {
|
|
115
|
+
try {
|
|
116
|
+
configData = JSON.parse(import_fs.default.readFileSync(configPath, "utf8"));
|
|
117
|
+
console.log(import_chalk.default.blue(`[CLI] Loaded configuration from: ${configPath}`));
|
|
118
|
+
} catch (err) {
|
|
119
|
+
console.error(import_chalk.default.red(`[CLI] Error parsing config file: ${err.message}`));
|
|
120
|
+
process.exit(1);
|
|
121
|
+
}
|
|
122
|
+
} else {
|
|
123
|
+
console.log(import_chalk.default.yellow(`[CLI] No config file found at ${options.config}. Using default parameters.`));
|
|
124
|
+
configData = {
|
|
125
|
+
dbPath: "./openrfid.db",
|
|
126
|
+
server: { port: 3e3, host: "0.0.0.0" },
|
|
127
|
+
websocket: { port: 4e3 },
|
|
128
|
+
mqtt: { enabled: false },
|
|
129
|
+
hopeland: { enabled: true, tcpPort: 9090, udpPort: 9091 }
|
|
130
|
+
};
|
|
131
|
+
}
|
|
132
|
+
const spinner = (0, import_ora.default)("Starting OpenRFID Headless Services...").start();
|
|
133
|
+
const eventBus = new import_core.EventBus();
|
|
134
|
+
const config = new import_core.ConfigManager(configData);
|
|
135
|
+
const logger = new import_core.Logger("Simulator");
|
|
136
|
+
const dbPath = configData.dbPath || "./openrfid.db";
|
|
137
|
+
const storage = new import_core.SqliteStorageDriver(dbPath);
|
|
138
|
+
await storage.connect();
|
|
139
|
+
const simulator = new import_simulator.SimulatorManager(eventBus, storage);
|
|
140
|
+
const pluginManager = new import_plugin_api.PluginManager({ eventBus, config, logger, simulator, storage });
|
|
141
|
+
pluginManager.register(new import_rest.RestPlugin());
|
|
142
|
+
pluginManager.register(new import_websocket.WebSocketPlugin());
|
|
143
|
+
if (configData.mqtt?.enabled) {
|
|
144
|
+
pluginManager.register(new import_mqtt.MqttPlugin());
|
|
145
|
+
}
|
|
146
|
+
if (configData.hopeland?.enabled) {
|
|
147
|
+
pluginManager.register(new import_hopeland_discovery.HopelandDiscoveryPlugin());
|
|
148
|
+
}
|
|
149
|
+
await pluginManager.initializeAll();
|
|
150
|
+
await pluginManager.startAll();
|
|
151
|
+
const allReaders = simulator.getAllReaders();
|
|
152
|
+
let onlineCount = 0;
|
|
153
|
+
for (const r of allReaders) {
|
|
154
|
+
if (r.status === "ONLINE") {
|
|
155
|
+
await simulator.startReader(r.id);
|
|
156
|
+
onlineCount++;
|
|
157
|
+
}
|
|
158
|
+
}
|
|
159
|
+
spinner.succeed(import_chalk.default.green("OpenRFID Headless Simulator running successfully!"));
|
|
160
|
+
console.log(import_chalk.default.gray("----------------------------------------------------"));
|
|
161
|
+
console.log(`* REST API Server: ${import_chalk.default.cyan(`http://localhost:${configData.server?.port || 3e3}`)}`);
|
|
162
|
+
console.log(`* WebSocket Server: ${import_chalk.default.cyan(`ws://localhost:${configData.websocket?.port || 4e3}`)}`);
|
|
163
|
+
if (configData.mqtt?.enabled) {
|
|
164
|
+
console.log(`* MQTT Broker: ${import_chalk.default.cyan(configData.mqtt.brokerUrl)}`);
|
|
165
|
+
}
|
|
166
|
+
if (configData.hopeland?.enabled) {
|
|
167
|
+
console.log(`* Hopeland TCP: ${import_chalk.default.cyan(`port ${configData.hopeland.tcpPort || 9090}`)}`);
|
|
168
|
+
console.log(`* Hopeland UDP Mult: ${import_chalk.default.cyan(`port ${configData.hopeland.udpPort || 9091}`)}`);
|
|
169
|
+
}
|
|
170
|
+
console.log(`* SQLite Storage: ${import_chalk.default.cyan(dbPath)} (Running: ${allReaders.length} total readers, ${onlineCount} active)`);
|
|
171
|
+
console.log(import_chalk.default.gray("----------------------------------------------------"));
|
|
172
|
+
console.log(import_chalk.default.yellow("Press Ctrl+C to stop the simulator server."));
|
|
173
|
+
process.on("SIGINT", async () => {
|
|
174
|
+
console.log(import_chalk.default.blue("\n[CLI] Shutting down headless servers..."));
|
|
175
|
+
const stopSpinner = (0, import_ora.default)("Stopping active readers and plugins...").start();
|
|
176
|
+
try {
|
|
177
|
+
await pluginManager.stopAll();
|
|
178
|
+
await storage.disconnect();
|
|
179
|
+
stopSpinner.succeed("Graceful shutdown completed.");
|
|
180
|
+
process.exit(0);
|
|
181
|
+
} catch (err) {
|
|
182
|
+
stopSpinner.fail(`Error during shutdown: ${err.message}`);
|
|
183
|
+
process.exit(1);
|
|
184
|
+
}
|
|
185
|
+
});
|
|
186
|
+
});
|
|
187
|
+
program.command("create-reader").description("Interactively create a new virtual reader").option("-c, --config <path>", "Path to openrfid.config.json", "openrfid.config.json").action(async (options) => {
|
|
188
|
+
const configPath = import_path.default.resolve(process.cwd(), options.config);
|
|
189
|
+
let dbPath = "./openrfid.db";
|
|
190
|
+
if (import_fs.default.existsSync(configPath)) {
|
|
191
|
+
const configData = JSON.parse(import_fs.default.readFileSync(configPath, "utf8"));
|
|
192
|
+
dbPath = configData.dbPath || "./openrfid.db";
|
|
193
|
+
}
|
|
194
|
+
const storage = new import_core.SqliteStorageDriver(dbPath);
|
|
195
|
+
await storage.connect();
|
|
196
|
+
const answers = await import_inquirer.default.prompt([
|
|
197
|
+
{
|
|
198
|
+
type: "input",
|
|
199
|
+
name: "name",
|
|
200
|
+
message: "Reader Name:",
|
|
201
|
+
default: "Gate-1"
|
|
202
|
+
},
|
|
203
|
+
{
|
|
204
|
+
type: "list",
|
|
205
|
+
name: "protocol",
|
|
206
|
+
message: "Reader Protocol:",
|
|
207
|
+
choices: ["Hopeland", "LLRP"],
|
|
208
|
+
default: "Hopeland"
|
|
209
|
+
},
|
|
210
|
+
{
|
|
211
|
+
type: "input",
|
|
212
|
+
name: "ip",
|
|
213
|
+
message: "Listen IP Address:",
|
|
214
|
+
default: "127.0.0.1"
|
|
215
|
+
},
|
|
216
|
+
{
|
|
217
|
+
type: "number",
|
|
218
|
+
name: "port",
|
|
219
|
+
message: "Listen Port:",
|
|
220
|
+
default: 9090
|
|
221
|
+
}
|
|
222
|
+
]);
|
|
223
|
+
const reader = new import_readers.VirtualReader({
|
|
224
|
+
name: answers.name,
|
|
225
|
+
protocol: answers.protocol,
|
|
226
|
+
ip: answers.ip,
|
|
227
|
+
port: answers.port,
|
|
228
|
+
vendor: answers.protocol === "Hopeland" ? "Hopeland" : "Generic",
|
|
229
|
+
model: "Sim passive v1"
|
|
230
|
+
});
|
|
231
|
+
await storage.saveReader({
|
|
232
|
+
id: reader.id,
|
|
233
|
+
name: reader.name,
|
|
234
|
+
vendor: reader.vendor,
|
|
235
|
+
model: reader.model,
|
|
236
|
+
ip: reader.ip,
|
|
237
|
+
port: reader.port,
|
|
238
|
+
protocol: reader.protocol,
|
|
239
|
+
status: "OFFLINE",
|
|
240
|
+
createdAt: (/* @__PURE__ */ new Date()).toISOString()
|
|
241
|
+
});
|
|
242
|
+
for (let i = 1; i <= 4; i++) {
|
|
243
|
+
await storage.saveAntenna({
|
|
244
|
+
id: `${reader.id}-ant-${i}`,
|
|
245
|
+
readerId: reader.id,
|
|
246
|
+
index: i,
|
|
247
|
+
gain: 6,
|
|
248
|
+
power: 30,
|
|
249
|
+
frequency: 865,
|
|
250
|
+
rssiOffset: 0,
|
|
251
|
+
readZone: `Zone ${i}`,
|
|
252
|
+
enabled: i === 1
|
|
253
|
+
});
|
|
254
|
+
}
|
|
255
|
+
console.log(import_chalk.default.green(`
|
|
256
|
+
Success! Virtual reader ${answers.name} created with ID: ${reader.id}`));
|
|
257
|
+
await storage.disconnect();
|
|
258
|
+
});
|
|
259
|
+
program.command("create-tag").description("Interactively generate a batch of virtual RFID tags").option("-c, --config <path>", "Path to openrfid.config.json", "openrfid.config.json").action(async (options) => {
|
|
260
|
+
const configPath = import_path.default.resolve(process.cwd(), options.config);
|
|
261
|
+
let dbPath = "./openrfid.db";
|
|
262
|
+
if (import_fs.default.existsSync(configPath)) {
|
|
263
|
+
const configData = JSON.parse(import_fs.default.readFileSync(configPath, "utf8"));
|
|
264
|
+
dbPath = configData.dbPath || "./openrfid.db";
|
|
265
|
+
}
|
|
266
|
+
const storage = new import_core.SqliteStorageDriver(dbPath);
|
|
267
|
+
await storage.connect();
|
|
268
|
+
const answers = await import_inquirer.default.prompt([
|
|
269
|
+
{
|
|
270
|
+
type: "list",
|
|
271
|
+
name: "type",
|
|
272
|
+
message: "Tag EPC Generation Type:",
|
|
273
|
+
choices: ["sequential", "random", "sgtin96"],
|
|
274
|
+
default: "sequential"
|
|
275
|
+
},
|
|
276
|
+
{
|
|
277
|
+
type: "number",
|
|
278
|
+
name: "count",
|
|
279
|
+
message: "Number of tags to generate:",
|
|
280
|
+
default: 10
|
|
281
|
+
}
|
|
282
|
+
]);
|
|
283
|
+
const spinner = (0, import_ora.default)("Generating tags...").start();
|
|
284
|
+
const batch = import_tags.TagGenerator.generateBatch({ count: answers.count, type: answers.type });
|
|
285
|
+
for (const tag of batch) {
|
|
286
|
+
await storage.saveTag({
|
|
287
|
+
id: tag.epc,
|
|
288
|
+
epc: tag.epc,
|
|
289
|
+
tid: tag.tid,
|
|
290
|
+
protocol: tag.protocol
|
|
291
|
+
});
|
|
292
|
+
}
|
|
293
|
+
spinner.succeed(import_chalk.default.green(`Successfully generated and saved ${answers.count} tags of type: ${answers.type}`));
|
|
294
|
+
await storage.disconnect();
|
|
295
|
+
});
|
|
296
|
+
program.command("mqtt").description("Launch a CLI MQTT telemetry monitoring session").option("-b, --broker <url>", "MQTT Broker URL", "mqtt://localhost:1883").action(async (options) => {
|
|
297
|
+
const mqtt = require("mqtt");
|
|
298
|
+
console.log(import_chalk.default.blue(`[MQTT Monitor] Connecting to MQTT broker at: ${options.broker}`));
|
|
299
|
+
const client = mqtt.connect(options.broker);
|
|
300
|
+
client.on("connect", () => {
|
|
301
|
+
console.log(import_chalk.default.green('[MQTT Monitor] Connected! Subscribing to "openrfid/events/#"...'));
|
|
302
|
+
client.subscribe("openrfid/events/#");
|
|
303
|
+
});
|
|
304
|
+
client.on("message", (topic, message) => {
|
|
305
|
+
try {
|
|
306
|
+
const payload = JSON.parse(message.toString());
|
|
307
|
+
const table = new import_cli_table3.default({
|
|
308
|
+
head: [import_chalk.default.cyan("Topic"), import_chalk.default.cyan("Reader ID"), import_chalk.default.cyan("EPC"), import_chalk.default.cyan("Antenna"), import_chalk.default.cyan("RSSI")],
|
|
309
|
+
colWidths: [25, 20, 26, 10, 10]
|
|
310
|
+
});
|
|
311
|
+
table.push([
|
|
312
|
+
topic,
|
|
313
|
+
payload.readerId || "N/A",
|
|
314
|
+
payload.epc || "N/A",
|
|
315
|
+
payload.antennaIndex !== void 0 ? payload.antennaIndex.toString() : "N/A",
|
|
316
|
+
payload.rssi !== void 0 ? `${payload.rssi} dBm` : "N/A"
|
|
317
|
+
]);
|
|
318
|
+
console.log(table.toString());
|
|
319
|
+
} catch (err) {
|
|
320
|
+
console.log(import_chalk.default.red(`[MQTT Monitor] Error parsing payload: ${err.message}`));
|
|
321
|
+
}
|
|
322
|
+
});
|
|
323
|
+
client.on("error", (err) => {
|
|
324
|
+
console.error(import_chalk.default.red(`[MQTT Monitor] Connection error: ${err.message}`));
|
|
325
|
+
});
|
|
326
|
+
process.on("SIGINT", () => {
|
|
327
|
+
client.end();
|
|
328
|
+
console.log(import_chalk.default.yellow("\n[MQTT Monitor] Disconnected."));
|
|
329
|
+
process.exit(0);
|
|
330
|
+
});
|
|
331
|
+
});
|
|
332
|
+
program.parse(process.argv);
|
|
333
|
+
//# sourceMappingURL=index.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"sources":["../src/index.ts"],"sourcesContent":["#!/usr/bin/env node\n/**\n * OpenRFID Simulator - The Open Source RFID Reader Simulator for Developers.\n * Copyright (c) 2026 RFID Software India Private Limited - https://rfidsoftwares.com\n *\n * Licensed under the MIT License.\n * For RFID software, enterprise tools, and hardware drivers, visit https://rfidsoftwares.com\n */\n\nimport { Command } from 'commander';\nimport chalk from 'chalk';\nimport inquirer from 'inquirer';\nimport ora from 'ora';\nimport fs from 'fs';\nimport path from 'path';\nimport Table from 'cli-table3';\nimport { EventBus, ConfigManager, Logger, SqliteStorageDriver } from '@openrfid/core';\nimport { SimulatorManager } from '@openrfid/simulator';\nimport { PluginManager } from '@openrfid/plugin-api';\nimport { RestPlugin } from '@openrfid/rest';\nimport { WebSocketPlugin } from '@openrfid/websocket';\nimport { MqttPlugin } from '@openrfid/mqtt';\nimport { HopelandDiscoveryPlugin } from '@openrfid/hopeland-discovery';\nimport { VirtualReader } from '@openrfid/readers';\nimport { TagGenerator } from '@openrfid/tags';\n\nconst program = new Command();\n\nprogram\n .name('openrfid')\n .description('OpenRFID Simulator CLI tool for headless operations and automation.')\n .version('1.0.0');\n\n// ── INIT COMMAND ─────────────────────────────────────────────────────────────\nprogram\n .command('init')\n .description('Initialize a new OpenRFID Simulator configuration file')\n .action(async () => {\n const configPath = path.join(process.cwd(), 'openrfid.config.json');\n if (fs.existsSync(configPath)) {\n const { overwrite } = await inquirer.prompt([\n {\n type: 'confirm',\n name: 'overwrite',\n message: 'openrfid.config.json already exists. Overwrite it?',\n default: false,\n },\n ]);\n if (!overwrite) {\n console.log(chalk.yellow('Initialization cancelled.'));\n return;\n }\n }\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'dbPath',\n message: 'Database storage path:',\n default: './openrfid.db',\n },\n {\n type: 'number',\n name: 'port',\n message: 'REST API Server Port:',\n default: 3000,\n },\n {\n type: 'number',\n name: 'wsPort',\n message: 'WebSocket Server Port:',\n default: 4000,\n },\n {\n type: 'confirm',\n name: 'mqttEnabled',\n message: 'Enable MQTT Broker client integration?',\n default: false,\n },\n ]);\n\n const configContent = {\n dbPath: answers.dbPath,\n server: {\n port: answers.port,\n host: '0.0.0.0',\n },\n websocket: {\n port: answers.wsPort,\n },\n mqtt: {\n enabled: answers.mqttEnabled,\n brokerUrl: 'mqtt://localhost:1883',\n },\n hopeland: {\n enabled: true,\n tcpPort: 9090,\n udpPort: 9091,\n },\n };\n\n fs.writeFileSync(configPath, JSON.stringify(configContent, null, 2));\n console.log(chalk.green(`\\nSuccess! Created configuration file: ${configPath}`));\n console.log(`Run ${chalk.cyan('openrfid simulator')} to start the simulator server.`);\n });\n\n// ── SIMULATOR HEADLESS SERVER COMMAND ──────────────────────────────────────────\nprogram\n .command('simulator')\n .description('Start the headless simulator server')\n .option('-c, --config <path>', 'Path to openrfid.config.json', 'openrfid.config.json')\n .action(async (options) => {\n const configPath = path.resolve(process.cwd(), options.config);\n let configData: any = {};\n if (fs.existsSync(configPath)) {\n try {\n configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n console.log(chalk.blue(`[CLI] Loaded configuration from: ${configPath}`));\n } catch (err: any) {\n console.error(chalk.red(`[CLI] Error parsing config file: ${err.message}`));\n process.exit(1);\n }\n } else {\n console.log(chalk.yellow(`[CLI] No config file found at ${options.config}. Using default parameters.`));\n configData = {\n dbPath: './openrfid.db',\n server: { port: 3000, host: '0.0.0.0' },\n websocket: { port: 4000 },\n mqtt: { enabled: false },\n hopeland: { enabled: true, tcpPort: 9090, udpPort: 9091 }\n };\n }\n\n const spinner = ora('Starting OpenRFID Headless Services...').start();\n\n // Initialize core services\n const eventBus = new EventBus();\n const config = new ConfigManager(configData);\n const logger = new Logger('Simulator');\n \n const dbPath = configData.dbPath || './openrfid.db';\n const storage = new SqliteStorageDriver(dbPath);\n await storage.connect();\n\n const simulator = new SimulatorManager(eventBus, storage);\n const pluginManager = new PluginManager({ eventBus, config, logger, simulator, storage });\n\n // Register active server plugins\n pluginManager.register(new RestPlugin());\n pluginManager.register(new WebSocketPlugin());\n \n if (configData.mqtt?.enabled) {\n pluginManager.register(new MqttPlugin());\n }\n if (configData.hopeland?.enabled) {\n pluginManager.register(new HopelandDiscoveryPlugin());\n }\n\n await pluginManager.initializeAll();\n await pluginManager.startAll();\n\n // Auto-start any readers that are marked ONLINE in the DB\n const allReaders = simulator.getAllReaders();\n let onlineCount = 0;\n for (const r of allReaders) {\n if (r.status === 'ONLINE') {\n await simulator.startReader(r.id);\n onlineCount++;\n }\n }\n\n spinner.succeed(chalk.green('OpenRFID Headless Simulator running successfully!'));\n console.log(chalk.gray('----------------------------------------------------'));\n console.log(`* REST API Server: ${chalk.cyan(`http://localhost:${configData.server?.port || 3000}`)}`);\n console.log(`* WebSocket Server: ${chalk.cyan(`ws://localhost:${configData.websocket?.port || 4000}`)}`);\n if (configData.mqtt?.enabled) {\n console.log(`* MQTT Broker: ${chalk.cyan(configData.mqtt.brokerUrl)}`);\n }\n if (configData.hopeland?.enabled) {\n console.log(`* Hopeland TCP: ${chalk.cyan(`port ${configData.hopeland.tcpPort || 9090}`)}`);\n console.log(`* Hopeland UDP Mult: ${chalk.cyan(`port ${configData.hopeland.udpPort || 9091}`)}`);\n }\n console.log(`* SQLite Storage: ${chalk.cyan(dbPath)} (Running: ${allReaders.length} total readers, ${onlineCount} active)`);\n console.log(chalk.gray('----------------------------------------------------'));\n console.log(chalk.yellow('Press Ctrl+C to stop the simulator server.'));\n\n process.on('SIGINT', async () => {\n console.log(chalk.blue('\\n[CLI] Shutting down headless servers...'));\n const stopSpinner = ora('Stopping active readers and plugins...').start();\n try {\n await pluginManager.stopAll();\n await storage.disconnect();\n stopSpinner.succeed('Graceful shutdown completed.');\n process.exit(0);\n } catch (err: any) {\n stopSpinner.fail(`Error during shutdown: ${err.message}`);\n process.exit(1);\n }\n });\n });\n\n// ── CREATE READER COMMAND ──────────────────────────────────────────────────────\nprogram\n .command('create-reader')\n .description('Interactively create a new virtual reader')\n .option('-c, --config <path>', 'Path to openrfid.config.json', 'openrfid.config.json')\n .action(async (options) => {\n const configPath = path.resolve(process.cwd(), options.config);\n let dbPath = './openrfid.db';\n if (fs.existsSync(configPath)) {\n const configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n dbPath = configData.dbPath || './openrfid.db';\n }\n\n const storage = new SqliteStorageDriver(dbPath);\n await storage.connect();\n\n const answers = await inquirer.prompt([\n {\n type: 'input',\n name: 'name',\n message: 'Reader Name:',\n default: 'Gate-1',\n },\n {\n type: 'list',\n name: 'protocol',\n message: 'Reader Protocol:',\n choices: ['Hopeland', 'LLRP'],\n default: 'Hopeland',\n },\n {\n type: 'input',\n name: 'ip',\n message: 'Listen IP Address:',\n default: '127.0.0.1',\n },\n {\n type: 'number',\n name: 'port',\n message: 'Listen Port:',\n default: 9090,\n },\n ]);\n\n const reader = new VirtualReader({\n name: answers.name,\n protocol: answers.protocol,\n ip: answers.ip,\n port: answers.port,\n vendor: answers.protocol === 'Hopeland' ? 'Hopeland' : 'Generic',\n model: 'Sim passive v1',\n });\n\n await storage.saveReader({\n id: reader.id,\n name: reader.name,\n vendor: reader.vendor,\n model: reader.model,\n ip: reader.ip,\n port: reader.port,\n protocol: reader.protocol,\n status: 'OFFLINE',\n createdAt: new Date().toISOString(),\n });\n\n for (let i = 1; i <= 4; i++) {\n await storage.saveAntenna({\n id: `${reader.id}-ant-${i}`,\n readerId: reader.id,\n index: i,\n gain: 6,\n power: 30,\n frequency: 865,\n rssiOffset: 0,\n readZone: `Zone ${i}`,\n enabled: i === 1,\n });\n }\n\n console.log(chalk.green(`\\nSuccess! Virtual reader ${answers.name} created with ID: ${reader.id}`));\n await storage.disconnect();\n });\n\n// ── CREATE TAG COMMAND ─────────────────────────────────────────────────────────\nprogram\n .command('create-tag')\n .description('Interactively generate a batch of virtual RFID tags')\n .option('-c, --config <path>', 'Path to openrfid.config.json', 'openrfid.config.json')\n .action(async (options) => {\n const configPath = path.resolve(process.cwd(), options.config);\n let dbPath = './openrfid.db';\n if (fs.existsSync(configPath)) {\n const configData = JSON.parse(fs.readFileSync(configPath, 'utf8'));\n dbPath = configData.dbPath || './openrfid.db';\n }\n\n const storage = new SqliteStorageDriver(dbPath);\n await storage.connect();\n\n const answers = await inquirer.prompt([\n {\n type: 'list',\n name: 'type',\n message: 'Tag EPC Generation Type:',\n choices: ['sequential', 'random', 'sgtin96'],\n default: 'sequential',\n },\n {\n type: 'number',\n name: 'count',\n message: 'Number of tags to generate:',\n default: 10,\n },\n ]);\n\n const spinner = ora('Generating tags...').start();\n const batch = TagGenerator.generateBatch({ count: answers.count, type: answers.type as any });\n \n for (const tag of batch) {\n await storage.saveTag({\n id: tag.epc,\n epc: tag.epc,\n tid: tag.tid,\n protocol: tag.protocol,\n });\n }\n\n spinner.succeed(chalk.green(`Successfully generated and saved ${answers.count} tags of type: ${answers.type}`));\n await storage.disconnect();\n });\n\n// ── MQTT TELEMETRY MONITOR COMMAND ──────────────────────────────────────────────\nprogram\n .command('mqtt')\n .description('Launch a CLI MQTT telemetry monitoring session')\n .option('-b, --broker <url>', 'MQTT Broker URL', 'mqtt://localhost:1883')\n .action(async (options) => {\n const mqtt = require('mqtt');\n console.log(chalk.blue(`[MQTT Monitor] Connecting to MQTT broker at: ${options.broker}`));\n const client = mqtt.connect(options.broker);\n\n client.on('connect', () => {\n console.log(chalk.green('[MQTT Monitor] Connected! Subscribing to \"openrfid/events/#\"...'));\n client.subscribe('openrfid/events/#');\n });\n\n client.on('message', (topic: string, message: Buffer) => {\n try {\n const payload = JSON.parse(message.toString());\n const table = new Table({\n head: [chalk.cyan('Topic'), chalk.cyan('Reader ID'), chalk.cyan('EPC'), chalk.cyan('Antenna'), chalk.cyan('RSSI')],\n colWidths: [25, 20, 26, 10, 10]\n });\n\n table.push([\n topic,\n payload.readerId || 'N/A',\n payload.epc || 'N/A',\n payload.antennaIndex !== undefined ? payload.antennaIndex.toString() : 'N/A',\n payload.rssi !== undefined ? `${payload.rssi} dBm` : 'N/A'\n ]);\n\n console.log(table.toString());\n } catch (err: any) {\n console.log(chalk.red(`[MQTT Monitor] Error parsing payload: ${err.message}`));\n }\n });\n\n client.on('error', (err: any) => {\n console.error(chalk.red(`[MQTT Monitor] Connection error: ${err.message}`));\n });\n\n process.on('SIGINT', () => {\n client.end();\n console.log(chalk.yellow('\\n[MQTT Monitor] Disconnected.'));\n process.exit(0);\n });\n });\n\nprogram.parse(process.argv);\n"],"mappings":"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","names":["path","fs","inquirer","chalk","ora","Table"]}
|
package/package.json
ADDED
|
@@ -0,0 +1,52 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@openrfid/cli",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"description": "Headless CLI and terminal management tools for OpenRFID Simulator.",
|
|
5
|
+
"main": "./dist/index.js",
|
|
6
|
+
"types": "./dist/index.d.ts",
|
|
7
|
+
"bin": {
|
|
8
|
+
"openrfid": "./dist/index.js"
|
|
9
|
+
},
|
|
10
|
+
"files": [
|
|
11
|
+
"dist"
|
|
12
|
+
],
|
|
13
|
+
"dependencies": {
|
|
14
|
+
"chalk": "^4.1.2",
|
|
15
|
+
"cli-table3": "^0.6.4",
|
|
16
|
+
"commander": "^12.0.0",
|
|
17
|
+
"inquirer": "^8.2.6",
|
|
18
|
+
"ora": "^5.4.1",
|
|
19
|
+
"@openrfid/hopeland-discovery": "0.1.0",
|
|
20
|
+
"@openrfid/core": "0.1.0",
|
|
21
|
+
"@openrfid/mqtt": "0.1.0",
|
|
22
|
+
"@openrfid/readers": "0.1.0",
|
|
23
|
+
"@openrfid/plugin-api": "0.1.0",
|
|
24
|
+
"@openrfid/tags": "0.1.0",
|
|
25
|
+
"@openrfid/rest": "0.1.0",
|
|
26
|
+
"@openrfid/simulator": "0.1.0",
|
|
27
|
+
"@openrfid/websocket": "0.1.0"
|
|
28
|
+
},
|
|
29
|
+
"devDependencies": {
|
|
30
|
+
"@types/inquirer": "^8.2.10",
|
|
31
|
+
"@types/node": "^20.11.24",
|
|
32
|
+
"tsup": "^8.0.2",
|
|
33
|
+
"typescript": "^5.4.5"
|
|
34
|
+
},
|
|
35
|
+
"publishConfig": {
|
|
36
|
+
"access": "public"
|
|
37
|
+
},
|
|
38
|
+
"license": "MIT",
|
|
39
|
+
"repository": {
|
|
40
|
+
"type": "git",
|
|
41
|
+
"url": "https://github.com/rfidsoftwares/openrfid-simulator.git"
|
|
42
|
+
},
|
|
43
|
+
"bugs": {
|
|
44
|
+
"url": "https://github.com/rfidsoftwares/openrfid-simulator/issues"
|
|
45
|
+
},
|
|
46
|
+
"homepage": "https://rfidsoftwares.com",
|
|
47
|
+
"scripts": {
|
|
48
|
+
"build": "tsup",
|
|
49
|
+
"dev": "tsup --watch",
|
|
50
|
+
"typecheck": "tsc --noEmit"
|
|
51
|
+
}
|
|
52
|
+
}
|