Device management (List, Create, Delete)

This commit is contained in:
formulahendry 2016-11-04 23:07:12 +08:00
Родитель 7b199f4653
Коммит c28637e177
11 изменённых файлов: 226 добавлений и 40 удалений

Просмотреть файл

@ -10,7 +10,7 @@ Toolkit makes Azure IoT Development easier
[ ] Send messages from Azure IoT Hub to device (cloud-to-device message)
[ ] Device management (List, Create, Update, Delete)
[*] Device management (List, Create, Delete)
[ ] And more...
@ -21,16 +21,24 @@ Toolkit makes Azure IoT Development easier
| Send message to IoT Hub | Ctrl+Alt+F9 | editor/context |
| Start monitoring | Ctrl+Alt+F10 | editor/context |
| Stop monitoring | Ctrl+Alt+F11 | editor/context |
| List device | Ctrl+Alt+F1 | editor/context |
| Create device | Ctrl+Alt+F2 | editor/context |
| Delete device | Ctrl+Alt+F3 | editor/context |
## Usages
* Send messages to Azure IoT Hub
![Usage](images/send.gif)
![Send](images/send.gif)
* Monitor device-to-cloud messages
![Usage](images/monitor.gif)
![Monitor](images/monitor.gif)
* Device management (List, Create, Delete)
![Device](images/device.gif)
## Configuration
@ -64,6 +72,9 @@ By default, anonymous telemetry data collection is turned on to understand user
```
## Change Log
### 0.0.2
* Device management (List, Create, Delete)
### 0.0.1
* Send messages to Azure IoT Hub
* Monitor device-to-cloud messages

Двоичные данные
images/device.gif Normal file

Двоичный файл не отображается.

После

Ширина:  |  Высота:  |  Размер: 956 KiB

Двоичные данные
images/monitor.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 169 KiB

После

Ширина:  |  Высота:  |  Размер: 394 KiB

Двоичные данные
images/send.gif

Двоичный файл не отображается.

До

Ширина:  |  Высота:  |  Размер: 86 KiB

После

Ширина:  |  Высота:  |  Размер: 148 KiB

Просмотреть файл

@ -1,8 +1,8 @@
{
"name": "azure-iot-toolkit",
"displayName": "Azure IoT Toolkit",
"description": "Send messages to Azure IoT Hub, monitor device-to-cloud messages",
"version": "0.0.1",
"description": "Send messages to Azure IoT Hub, monitor device-to-cloud messages, IoT Device Management",
"version": "0.0.2",
"publisher": "formulahendry",
"icon": "images/logo.png",
"engines": {
@ -15,7 +15,7 @@
"azure",
"iot",
"device",
"manage",
"explorer",
"cloud"
],
"bugs": {
@ -29,7 +29,9 @@
},
"activationEvents": [
"onCommand:azure-iot-toolkit.sendD2CMessage",
"onCommand:azure-iot-toolkit.startMonitoringMessage"
"onCommand:azure-iot-toolkit.startMonitoringMessage",
"onCommand:azure-iot-toolkit.listDevice",
"onCommand:azure-iot-toolkit.createDevice"
],
"main": "./out/src/extension",
"contributes": {
@ -45,6 +47,18 @@
{
"command": "azure-iot-toolkit.stopMonitoringMessage",
"title": "Stop monitoring"
},
{
"command": "azure-iot-toolkit.listDevice",
"title": "List device"
},
{
"command": "azure-iot-toolkit.createDevice",
"title": "Create device"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"title": "Delete device"
}
],
"keybindings": [
@ -59,6 +73,18 @@
{
"command": "azure-iot-toolkit.stopMonitoringMessage",
"key": "ctrl+alt+f11"
},
{
"command": "azure-iot-toolkit.listDevice",
"key": "ctrl+alt+f1"
},
{
"command": "azure-iot-toolkit.createDevice",
"key": "ctrl+alt+f2"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"key": "ctrl+alt+f3"
}
],
"menus": {
@ -74,6 +100,18 @@
{
"command": "azure-iot-toolkit.stopMonitoringMessage",
"group": "azure-iot-toolkit"
},
{
"command": "azure-iot-toolkit.listDevice",
"group": "azure-iot-toolkit"
},
{
"command": "azure-iot-toolkit.createDevice",
"group": "azure-iot-toolkit"
},
{
"command": "azure-iot-toolkit.deleteDevice",
"group": "azure-iot-toolkit"
}
]
},
@ -117,6 +155,7 @@
"applicationinsights": "^0.16.0",
"azure-event-hubs": "^0.0.4",
"azure-iot-device": "^1.0.16",
"azure-iot-device-http": "^1.0.16"
"azure-iot-device-http": "^1.0.16",
"azure-iothub": "^1.0.18"
}
}
}

Просмотреть файл

@ -1,16 +1,18 @@
'use strict';
import * as vscode from 'vscode';
import { MessageExplorer } from './messageExplorer';
import { DeviceExplorer } from './deviceExplorer';
import { AppInsightsClient } from './appInsightsClient';
export class AzureIoTExplorer {
private _messageExplorer: MessageExplorer;
private _deviceExplorer: DeviceExplorer;
constructor() {
let outputChannel = vscode.window.createOutputChannel('Azure IoT Toolkit');
let appInsightsClient = new AppInsightsClient();
this._messageExplorer = new MessageExplorer(outputChannel, appInsightsClient);
this._deviceExplorer = new DeviceExplorer(outputChannel, appInsightsClient);
}
public sendD2CMessage(): void {
@ -24,4 +26,16 @@ export class AzureIoTExplorer {
public stopMonitoringMessage(): void {
this._messageExplorer.stopMonitoringMessage();
}
public listDevice(): void {
this._deviceExplorer.listDevice();
}
public createDevice(): void {
this._deviceExplorer.createDevice();
}
public deleteDevice(): void {
this._deviceExplorer.deleteDevice();
}
}

17
src/baseExplorer.ts Normal file
Просмотреть файл

@ -0,0 +1,17 @@
'use strict';
import * as vscode from 'vscode';
import { AppInsightsClient } from './appInsightsClient';
export class BaseExplorer {
protected _outputChannel: vscode.OutputChannel;
protected _appInsightsClient: AppInsightsClient;
constructor(outputChannel: vscode.OutputChannel, appInsightsClient: AppInsightsClient) {
this._outputChannel = outputChannel;
this._appInsightsClient = appInsightsClient;
}
output(label: string, message: string): void {
this._outputChannel.appendLine(`[${label}] ${message}`);
}
}

89
src/deviceExplorer.ts Normal file
Просмотреть файл

@ -0,0 +1,89 @@
'use strict';
import * as vscode from 'vscode';
import { Utility } from './utility';
import { AppInsightsClient } from './appInsightsClient';
import { BaseExplorer } from './baseExplorer';
let iothub = require('azure-iothub');
export class DeviceExplorer extends BaseExplorer {
constructor(outputChannel: vscode.OutputChannel, appInsightsClient: AppInsightsClient) {
super(outputChannel, appInsightsClient);
}
public listDevice(): void {
let label = 'Device';
let iotHubConnectionString = Utility.getConnectionString('iotHubConnectionString', 'IoT Hub Connection String');
if (!iotHubConnectionString) {
return;
}
let registry = iothub.Registry.fromConnectionString(iotHubConnectionString);
this._outputChannel.show();
this.output(label, 'Querying devices...')
registry.list((err, deviceList) => {
this.output(label, `${deviceList.length} device(s) found`)
if (deviceList.length > 0) {
this.output(label, '<Device Id>: <Primary Key>')
}
deviceList.forEach((device) => {
var key = device.authentication ? device.authentication.SymmetricKey.primaryKey : '<no primary key>';
this.output(label, `${device.deviceId}: ${key}`)
});
});
}
public createDevice(): void {
let label = 'Device';
let iotHubConnectionString = Utility.getConnectionString('iotHubConnectionString', 'IoT Hub Connection String');
if (!iotHubConnectionString) {
return;
}
let registry = iothub.Registry.fromConnectionString(iotHubConnectionString);
vscode.window.showInputBox({ prompt: 'Enter device id to create' }).then((deviceId: string) => {
if (deviceId !== undefined) {
var device = {
deviceId: deviceId
};
this._outputChannel.show();
this.output(label, `Creating device '${device.deviceId}'`);
registry.create(device, this.done('create', label));
}
});
}
public deleteDevice(): void {
let label = 'Device';
let iotHubConnectionString = Utility.getConnectionString('iotHubConnectionString', 'IoT Hub Connection String');
if (!iotHubConnectionString) {
return;
}
let registry = iothub.Registry.fromConnectionString(iotHubConnectionString);
vscode.window.showInputBox({ prompt: 'Enter device id to delete' }).then((deviceId: string) => {
if (deviceId !== undefined) {
this._outputChannel.show();
this.output(label, `Deleting device ${deviceId}`);
registry.delete(deviceId, this.done('delete', label));
}
});
}
private done(op: string, label: string) {
return (err, deviceInfo, res) => {
if (err) {
this.output(label, `[${op}] error: ${err.toString()}`);
}
if (res) {
let result = '[fail]';
if (res.statusCode < 300) {
result = '[success]';
}
this.output(label, `[${op}]${result} status: ${res.statusCode} ${res.statusMessage}`);
}
if (deviceInfo) {
this.output(label, `[${op}] device info: ${JSON.stringify(deviceInfo)}`);
}
};
}
}

Просмотреть файл

@ -17,9 +17,24 @@ export function activate(context: vscode.ExtensionContext) {
azureIoTExplorer.stopMonitoringMessage();
});
let listDevice = vscode.commands.registerCommand('azure-iot-toolkit.listDevice', () => {
azureIoTExplorer.listDevice();
});
let createDevice = vscode.commands.registerCommand('azure-iot-toolkit.createDevice', () => {
azureIoTExplorer.createDevice();
});
let deleteDevice = vscode.commands.registerCommand('azure-iot-toolkit.deleteDevice', () => {
azureIoTExplorer.deleteDevice();
});
context.subscriptions.push(sendD2CMessage);
context.subscriptions.push(startMonitoringMessage);
context.subscriptions.push(stopMonitoringMessage);
context.subscriptions.push(listDevice);
context.subscriptions.push(createDevice);
context.subscriptions.push(deleteDevice);
}
export function deactivate() {

Просмотреть файл

@ -4,25 +4,21 @@ import { Utility } from './utility';
import { clientFromConnectionString } from 'azure-iot-device-http';
import { Message, Client } from 'azure-iot-device';
import { AppInsightsClient } from './appInsightsClient';
import { BaseExplorer } from './baseExplorer'
let EventHubClient = require('azure-event-hubs').Client;
export class MessageExplorer {
private _outputChannel: vscode.OutputChannel;
private _appInsightsClient: AppInsightsClient;
export class MessageExplorer extends BaseExplorer {
private _eventHubClient;
constructor(outputChannel: vscode.OutputChannel, appInsightsClient: AppInsightsClient) {
this._outputChannel = outputChannel;
this._appInsightsClient = appInsightsClient;
super(outputChannel, appInsightsClient);
}
public sendD2CMessage(): void {
let label = 'D2CMessage';
let config = Utility.getConfiguration();
let deviceConnectionString = config.get<string>('deviceConnectionString');
if (!deviceConnectionString || deviceConnectionString.startsWith('<<insert')) {
vscode.window.showErrorMessage('Please set your Device Connection String in settings.json');
let deviceConnectionString = Utility.getConnectionString('deviceConnectionString', 'Device Connection String');
if (!deviceConnectionString) {
return;
}
@ -33,7 +29,7 @@ export class MessageExplorer {
client.sendEvent(new Message(JSON.stringify(message)), this.sendEventDone(true, client, label));
}
catch (e) {
Utility.output(this._outputChannel, label, e);
this.output(label, e);
}
}
});
@ -41,25 +37,24 @@ export class MessageExplorer {
public startMonitoringMessage(): void {
let label = 'Monitor';
let config = Utility.getConfiguration();
let iotHubConnectionString = config.get<string>('iotHubConnectionString');
if (!iotHubConnectionString || iotHubConnectionString.startsWith('<<insert')) {
vscode.window.showErrorMessage('Please set your IoT Hub Connection String in settings.json');
let iotHubConnectionString = Utility.getConnectionString('iotHubConnectionString', 'IoT Hub Connection String');
if (!iotHubConnectionString) {
return;
}
let config = Utility.getConfiguration();
let consumerGroup = config.get<string>('consumerGroup');
try {
this._eventHubClient = EventHubClient.fromConnectionString(iotHubConnectionString);
this._outputChannel.show();
Utility.output(this._outputChannel, label, 'Start monitoring...');
this.output(label, 'Start monitoring...');
this._appInsightsClient.sendEvent('D2C.startMonitoring')
this._eventHubClient.open()
.then(this._eventHubClient.getPartitionIds.bind(this._eventHubClient))
.then((partitionIds) => {
return partitionIds.map((partitionId) => {
return this._eventHubClient.createReceiver(consumerGroup, partitionId, { 'startAfterTime': Date.now() }).then((receiver) => {
Utility.output(this._outputChannel, label, `Created partition receiver [${partitionId}] for consumerGroup [${consumerGroup}]`);
this.output(label, `Created partition receiver [${partitionId}] for consumerGroup [${consumerGroup}]`);
receiver.on('errorReceived', this.printError(this._outputChannel, label, this._eventHubClient));
receiver.on('message', this.printMessage(this._outputChannel, label));
});
@ -68,13 +63,13 @@ export class MessageExplorer {
.catch(this.printError(this._outputChannel, label, this._eventHubClient));
}
catch (e) {
Utility.output(this._outputChannel, label, e);
this.output(label, e);
}
}
public stopMonitoringMessage(): void {
if (this._eventHubClient) {
Utility.output(this._outputChannel, 'Monitor', 'Stop monitoring...');
this.output('Monitor', 'Stop monitoring...');
this._appInsightsClient.sendEvent('D2C.stopMonitoring')
this._eventHubClient.close();
}
@ -82,16 +77,16 @@ export class MessageExplorer {
private sendEventDone(close: boolean, client: Client, label: string) {
this._outputChannel.show();
Utility.output(this._outputChannel, label, 'Sending message to IoT Hub...');
this.output(label, 'Sending message to IoT Hub...');
return (err, result) => {
if (err) {
Utility.output(this._outputChannel, label, 'Failed to send message to IoT Hub');
Utility.output(this._outputChannel, label, err.toString());
this.output(label, 'Failed to send message to IoT Hub');
this.output(label, err.toString());
this._appInsightsClient.sendEvent('D2C.Send', { Result: 'Fail' })
}
if (result) {
Utility.output(this._outputChannel, label, '[Success] Message sent to IoT Hub');
this.output(label, '[Success] Message sent to IoT Hub');
this._appInsightsClient.sendEvent('D2C.Send', { Result: 'Success' })
}
if (close) {
@ -102,8 +97,8 @@ export class MessageExplorer {
private printError(outputChannel: vscode.OutputChannel, label: string, eventHubClient) {
return (err) => {
Utility.output(this._outputChannel, label, err.message);
Utility.output(this._outputChannel, label, 'Stop monitoring...');
this.output(label, err.message);
this.output(label, 'Stop monitoring...');
if (eventHubClient) {
eventHubClient.close();
}
@ -112,8 +107,8 @@ export class MessageExplorer {
private printMessage(outputChannel: vscode.OutputChannel, label: string) {
return (message) => {
Utility.output(this._outputChannel, label, 'Message received: ');
Utility.output(this._outputChannel, label, JSON.stringify(message.body));
this.output(label, 'Message received: ');
this.output(label, JSON.stringify(message.body));
};
};
}

Просмотреть файл

@ -2,11 +2,17 @@
import * as vscode from 'vscode';
export class Utility {
static output(outputChannel: vscode.OutputChannel, label: string, message: string): void {
outputChannel.appendLine(`[${label}] ${message}`);
}
static getConfiguration(): vscode.WorkspaceConfiguration {
return vscode.workspace.getConfiguration('azure-iot-toolkit');
}
static getConnectionString(id: string, name: string): string {
let config = Utility.getConfiguration();
let iotHubConnectionString = config.get<string>(id);
if (!iotHubConnectionString || iotHubConnectionString.startsWith('<<insert')) {
vscode.window.showErrorMessage(`Please set your ${name} in settings.json`);
return null;
}
return iotHubConnectionString;
}
}