@iotize/cli
Version:
IoTize command line interface
483 lines • 19.5 kB
JavaScript
;
var __decorate = (this && this.__decorate) || function (decorators, target, key, desc) {
var c = arguments.length, r = c < 3 ? target : desc === null ? desc = Object.getOwnPropertyDescriptor(target, key) : desc, d;
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") r = Reflect.decorate(decorators, target, key, desc);
else for (var i = decorators.length - 1; i >= 0; i--) if (d = decorators[i]) r = (c < 3 ? d(r) : c > 3 ? d(target, key, r) : d(target, key)) || r;
return c > 3 && r && Object.defineProperty(target, key, r), r;
};
var __metadata = (this && this.__metadata) || function (k, v) {
if (typeof Reflect === "object" && typeof Reflect.metadata === "function") return Reflect.metadata(k, v);
};
var __awaiter = (this && this.__awaiter) || function (thisArg, _arguments, P, generator) {
function adopt(value) { return value instanceof P ? value : new P(function (resolve) { resolve(value); }); }
return new (P || (P = Promise))(function (resolve, reject) {
function fulfilled(value) { try { step(generator.next(value)); } catch (e) { reject(e); } }
function rejected(value) { try { step(generator["throw"](value)); } catch (e) { reject(e); } }
function step(result) { result.done ? resolve(result.value) : adopt(result.value).then(fulfilled, rejected); }
step((generator = generator.apply(thisArg, _arguments || [])).next());
});
};
var __importDefault = (this && this.__importDefault) || function (mod) {
return (mod && mod.__esModule) ? mod : { "default": mod };
};
Object.defineProperty(exports, "__esModule", { value: true });
require("@iotize/device-client.js/ext/factory-reset");
require("@iotize/device-client.js/ext/gpio");
require("@iotize/device-client.js/ext/keep-alive");
const cli_core_1 = require("@iotize/cli-core");
const byte_converter_1 = require("@iotize/common/byte-converter");
const impl_1 = require("@iotize/device-client.js/client/impl");
const clime_1 = require("clime");
const inquirer_1 = __importDefault(require("inquirer"));
const ui_1 = require("../../../ui");
const constants_1 = require("../../constants");
const device_1 = require("../../options/device");
const change_password_1 = __importDefault(require("./change-password"));
const read_1 = __importDefault(require("./config/read"));
const reset_1 = __importDefault(require("./config/reset"));
const wifi_1 = __importDefault(require("./connectivity/wifi"));
const info_1 = __importDefault(require("./datalog/info"));
const version_1 = __importDefault(require("./firmware/version"));
const configure_1 = __importDefault(require("./gpio/configure"));
const mapping_1 = __importDefault(require("./gpio/mapping"));
const read_2 = __importDefault(require("./gpio/read"));
const write_1 = __importDefault(require("./gpio/write"));
const info_2 = __importDefault(require("./info"));
const put_1 = require("./lwm2m/put");
const reboot_1 = __importDefault(require("./reboot"));
const info_3 = __importDefault(require("./variable/info"));
// const ioHook = require('iohook');
inquirer_1.default.registerPrompt('autocomplete', require('inquirer-autocomplete-prompt'));
const parseArgs = require('minimist');
class MyOptions extends device_1.DeviceOptions {
}
__decorate([
clime_1.option({
description: 'Keep alive period (in millisecond)'
}),
__metadata("design:type", Number)
], MyOptions.prototype, "keepAlive", void 0);
exports.MyOptions = MyOptions;
var KeyboardKeyCode;
(function (KeyboardKeyCode) {
KeyboardKeyCode[KeyboardKeyCode["ARROW_UP"] = 38] = "ARROW_UP";
KeyboardKeyCode[KeyboardKeyCode["ARROW_DOWN"] = 40] = "ARROW_DOWN";
KeyboardKeyCode[KeyboardKeyCode["ARROW_TAB"] = 9] = "ARROW_TAB";
})(KeyboardKeyCode || (KeyboardKeyCode = {}));
let default_1 = class default_1 extends clime_1.Command {
constructor() {
super(...arguments);
this.actions = [
new ConnectAction(),
new DisconnectAction(),
new info_2.default(),
new LoginAction(),
new SessionStateAction(),
new ExitAction(),
new RequestAction(),
new HelpAction(),
new reset_1.default(),
new KeepAliveAction(),
new LogoutAction(),
new configure_1.default(),
new read_2.default(),
new write_1.default(),
new mapping_1.default(),
// new GpioAction(),
new TargetResetKeepAction(),
new TargetResetReleaseAction(),
new info_3.default(),
new VariableAction(),
new version_1.default(),
new reboot_1.default(),
new info_1.default(),
new read_1.default(),
new change_password_1.default(),
new wifi_1.default()
];
}
execute(options) {
return __awaiter(this, void 0, void 0, function* () {
const tap = yield options.getDevice(true, false);
if (options.keepAlive) {
tap.keepAlive.period = options.keepAlive;
tap.keepAlive.start();
}
const context = {
tap,
continue: true,
actions: this.actions
};
const commandHistory = [];
// ioHook.on('keydown', (keydown: any) => {
// switch (keydown.keycode) {
// case KeyboardKeyCode.ARROW_UP:
// if (commandHistory.length > 0) {
// process.stdin.write(commandHistory[commandHistory.length - 1]);
// }
// break;
// case KeyboardKeyCode.ARROW_DOWN:
// break;
// case KeyboardKeyCode.ARROW_TAB:
// break;
// }
// });
// // Register and start hook
// ioHook.start();
while (context.continue) {
const commandString = yield cli_core_1.ask.string('>');
if (commandString.length === 0) {
continue;
}
const parsedCommand = this.parseCommand(commandString);
if (!parsedCommand) {
ui_1.display.warn(`Command not found: ${commandString}`);
continue;
}
if (commandHistory.length > 0 && commandHistory[commandHistory.length - 1] !== commandString) {
commandHistory.push(commandString);
}
try {
if (parsedCommand.options.help) {
if (parsedCommand.action instanceof clime_1.Command) {
const help = yield clime_1.HelpInfo.build(parsedCommand.action);
// TODO
console.log('HELP', help);
continue;
}
else {
// TODO
throw new Error(`No help for this command`);
}
}
else {
yield parsedCommand.action.run(context, {
args: parsedCommand.args,
options: parsedCommand.options
});
}
}
catch (err) {
if (isTruthy(process.env.DEBUG)) {
console.warn(err);
}
ui_1.display.warn(err.message);
}
}
yield tap.disconnect().catch(err => { });
});
}
parseCommand(commandString) {
// TODO use clime instead for validation...
const action = this.actions.find(a => {
return commandString.startsWith(a.command);
});
if (!action) {
return undefined;
}
const paramsString = commandString.substr(action.command.length + 1);
const parsedArgs = parseArgs(paramsString.split(' '));
return {
action,
args: parsedArgs._,
options: parsedArgs
};
}
};
__decorate([
clime_1.metadata,
__metadata("design:type", Function),
__metadata("design:paramtypes", [MyOptions]),
__metadata("design:returntype", Promise)
], default_1.prototype, "execute", null);
default_1 = __decorate([
clime_1.command({
description: 'Interactive mode'
})
], default_1);
exports.default = default_1;
class RequestAction {
constructor() {
this.command = 'lwm2m';
this.help = 'Execute LWM2M requests';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
const calls = constants_1.tapApiExplorer.resources;
const { tap } = context;
const { value } = yield inquirer_1.default.prompt({
message: 'Request ?',
type: 'autocomplete',
name: 'value',
source: ((answersSoFar, input) => __awaiter(this, void 0, void 0, function* () {
return calls
.filter(call => {
if (!input) {
return true;
}
const callString = `${call.methodType} ${call.path} ${call.bodyEncoder || ''}`;
return callString.indexOf(input) >= 0;
})
.map(call => ({
value: call,
name: `${call.methodType} ${call.path} ${call.bodyEncoder || ''}`
}));
}))
});
if (value) {
const pathParametersName = impl_1.PathParameter.extractParams(value.path);
if (pathParametersName.length > 0) {
if (!value.pathParameters) {
value.pathParameters = {};
}
for (const paramName of pathParametersName) {
const paramValue = yield cli_core_1.ask.number(`${paramName}`);
value.pathParameters[paramName] = paramValue;
}
}
if (value.bodyEncoder) {
const requestBody = yield cli_core_1.ask.string('Body ?');
value.body = put_1.parseUserInput(requestBody);
}
const result = yield tap.lwm2m.call(value);
result.successful();
const rawBody = result.rawBody();
const body = result.body();
ui_1.display.success(`Request successful`);
if (body instanceof Uint8Array) {
if (body.length > 0) {
ui_1.display.infonl(`Body (hex): ${byte_converter_1.bufferToHexString(body)}`);
ui_1.display.infonl(`Body (ascii): ${byte_converter_1.bufferToAsciiString(body)}`);
}
}
else if (body instanceof Object) {
ui_1.display.infonl(`Body:`);
ui_1.display.pretty(body);
ui_1.display.message('');
}
else {
ui_1.display.infonl(`Body: ${body}`);
}
}
});
}
}
function isTruthy(val) {
return !!(val && !(val === "false" || val === "0"));
}
class VariableAction {
constructor() {
this.command = 'variable';
this.help = 'Read/Write value for configured Tap variable';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
const { tap } = context;
if (!params.args) {
throw new Error(`Missing variable id parameter`);
}
const variableId = parseInt(params.args[0], 10);
if (isNaN(variableId)) {
throw new Error(`Invalid variable id: ${variableId}`);
}
const variable = tap.variables.getById(variableId);
const value = yield variable.read();
if (value instanceof Uint8Array) {
ui_1.display.infonl(`Variable ${variableId} value:
Hex: 0x${byte_converter_1.bufferToHexString(value)}
Ascii: ${byte_converter_1.bufferToAsciiString(value)}`);
}
else {
ui_1.display.infonl(`Variable ${variableId} value: ${value}`);
}
});
}
}
// class GpioAction implements ActionInterface {
// command = 'gpio';
// help = 'Gpio actions';
// async run(context: ActionContext, params: ActionParams) {
// const { tap } = context;
// if (!params.args || params.args.length === 0) {
// throw new Error(`Missing pin index parameter`);
// }
// const index = parseInt(params.args[0], 10);
// if (isNaN(index)) {
// throw new Error(`Invalid pin index: ${params.args ? params.args[0] : 'No index'}`)
// }
// const pin = tap.gpio.getPinByIndex(index);
// if (params.args && params.args.length > 1) {
// const valueOrConfig = params.args[1];
// if (valueOrConfig === 'config') {
// const config = await pin.readConfig();
// display.infonl(`Pin ${index} configuration: ${GPIOMode[config[0]]}`);
// }
// else {
// await pin.writeConfig({
// mode: GPIOMode.OUTPUT_PUSHPULL
// });
// const newValue = isTruthy(valueOrConfig);
// const value = await pin.writeValue(newValue);
// display.success(`Pin ${index} set value to ${newValue}`);
// }
// }
// else {
// const configData = await pin.readConfig();
// const config = configData[0] as GPIOMode;
// if (config !== GPIOMode.INPUT_FLOATING) {
// display.infonl(`Current pin ${index} config: ${GPIOMode[config]}`);
// await pin.writeConfig({
// mode: GPIOMode.INPUT_FLOATING
// });
// display.infonl(`Configured pin ${index} as INPUT_FLOATING`);
// }
// const value = await pin.readValue();
// display.infonl(`Pin ${index} value: ${value}`);
// }
// }
// }
class HelpAction {
constructor() {
this.command = 'help';
this.help = 'Display help';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
const usages = (context.actions || []).map(action => {
return `* ${action.command}: ${action.help}`;
});
ui_1.display.infonl(usages.join(`\n`));
});
}
}
class ConnectAction {
constructor() {
this.command = 'connect';
this.help = 'Connect to Tap';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
yield context.tap.connect();
ui_1.display.success('connected!');
});
}
}
class ExitAction {
constructor() {
this.command = 'exit';
this.help = 'Exit interactif mode';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
context.continue = false;
});
}
}
class KeepAliveAction {
constructor() {
this.command = 'keep alive';
this.help = 'Keep alive start/stop';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
const { tap } = context;
if (params.args && params.args.length > 0) {
if (params.args[0] === 'start') {
tap.keepAlive.start();
ui_1.display.success('Keep alive started!');
return;
}
else if (params.args[0] === 'stop') {
tap.keepAlive.stop();
ui_1.display.success('Keep alive stopped!');
return;
}
}
ui_1.display.infonl(`Keep alive running ? ${tap.keepAlive.running}`);
ui_1.display.infonl(`Period ? ${tap.keepAlive.period}`);
});
}
}
class DisconnectAction {
constructor() {
this.command = 'disconnect';
this.help = 'Disconnect Tap';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
yield context.tap.disconnect();
ui_1.display.success('disconnected!');
});
}
}
class TargetResetKeepAction {
constructor() {
this.command = 'target-reset-keep';
this.help = 'Target reset and keep reset until otherwise';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
yield context.tap.service.target.postResetKeep();
// await sleep(500);
// await context.tap.service.target.reset();
ui_1.display.success(`Target reset keep successful!`);
});
}
}
class TargetResetReleaseAction {
constructor() {
this.command = 'target-reset-release';
this.help = 'Target reset release';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
yield context.tap.service.target.reset();
ui_1.display.success(`Target reset release successful!`);
});
}
}
class LogoutAction {
constructor() {
this.command = 'logout';
this.help = 'Logout from Tap';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
yield context.tap.logout();
});
}
}
class SessionStateAction {
constructor() {
this.command = 'session';
this.help = 'Show session state';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
const { tap } = context;
yield tap.refreshSessionState();
ui_1.display.table(tap.currentSessionState);
});
}
}
class LoginAction {
constructor() {
this.command = 'login';
this.help = 'Login to Tap';
}
run(context, params) {
return __awaiter(this, void 0, void 0, function* () {
const username = yield cli_core_1.ask.string('Username', {
default: 'admin',
maxLength: 16
});
const password = yield cli_core_1.ask.password('Password', {
default: 'admin',
maxLength: 16
});
yield context.tap.login(username, password);
ui_1.display.success(`Successful login as ${username}`);
});
}
}
//# sourceMappingURL=interactif.js.map