This commit is contained in:
L 2017-07-28 16:01:36 -07:00
Коммит d21ed892c0
49 изменённых файлов: 7684 добавлений и 0 удалений

288
.gitignore поставляемый Normal file
Просмотреть файл

@ -0,0 +1,288 @@
## Ignore Visual Studio temporary files, build results, and
## files generated by popular Visual Studio add-ons.
##
## Get latest from https://github.com/github/gitignore/blob/master/VisualStudio.gitignore
# User-specific files
*.suo
*.user
*.userosscache
*.sln.docstates
# User-specific files (MonoDevelop/Xamarin Studio)
*.userprefs
# Build results
[Dd]ebug/
[Dd]ebugPublic/
[Rr]elease/
[Rr]eleases/
x64/
x86/
bld/
[Bb]in/
[Oo]bj/
[Ll]og/
# Visual Studio 2015 cache/options directory
.vs/
# Uncomment if you have tasks that create the project's static files in wwwroot
#wwwroot/
# MSTest test Results
[Tt]est[Rr]esult*/
[Bb]uild[Ll]og.*
# NUNIT
*.VisualState.xml
TestResult.xml
# Build Results of an ATL Project
[Dd]ebugPS/
[Rr]eleasePS/
dlldata.c
# .NET Core
project.lock.json
project.fragment.lock.json
artifacts/
**/Properties/launchSettings.json
*_i.c
*_p.c
*_i.h
*.ilk
*.meta
*.obj
*.pch
*.pdb
*.pgc
*.pgd
*.rsp
*.sbr
*.tlb
*.tli
*.tlh
*.tmp
*.tmp_proj
*.log
*.vspscc
*.vssscc
.builds
*.pidb
*.svclog
*.scc
# Chutzpah Test files
_Chutzpah*
# Visual C++ cache files
ipch/
*.aps
*.ncb
*.opendb
*.opensdf
*.sdf
*.cachefile
*.VC.db
*.VC.VC.opendb
# Visual Studio profiler
*.psess
*.vsp
*.vspx
*.sap
# TFS 2012 Local Workspace
$tf/
# Guidance Automation Toolkit
*.gpState
# ReSharper is a .NET coding add-in
_ReSharper*/
*.[Rr]e[Ss]harper
*.DotSettings.user
# JustCode is a .NET coding add-in
.JustCode
# TeamCity is a build add-in
_TeamCity*
# DotCover is a Code Coverage Tool
*.dotCover
# Visual Studio code coverage results
*.coverage
*.coveragexml
# NCrunch
_NCrunch_*
.*crunch*.local.xml
nCrunchTemp_*
# MightyMoose
*.mm.*
AutoTest.Net/
# Web workbench (sass)
.sass-cache/
# Installshield output folder
[Ee]xpress/
# DocProject is a documentation generator add-in
DocProject/buildhelp/
DocProject/Help/*.HxT
DocProject/Help/*.HxC
DocProject/Help/*.hhc
DocProject/Help/*.hhk
DocProject/Help/*.hhp
DocProject/Help/Html2
DocProject/Help/html
# Click-Once directory
publish/
# Publish Web Output
*.[Pp]ublish.xml
*.azurePubxml
# TODO: Comment the next line if you want to checkin your web deploy settings
# but database connection strings (with potential passwords) will be unencrypted
*.pubxml
*.publishproj
# Microsoft Azure Web App publish settings. Comment the next line if you want to
# checkin your Azure Web App publish settings, but sensitive information contained
# in these scripts will be unencrypted
PublishScripts/
# NuGet Packages
*.nupkg
# The packages folder can be ignored because of Package Restore
**/packages/*
# except build/, which is used as an MSBuild target.
!**/packages/build/
# Uncomment if necessary however generally it will be regenerated when needed
#!**/packages/repositories.config
# NuGet v3's project.json files produces more ignorable files
*.nuget.props
*.nuget.targets
# Microsoft Azure Build Output
csx/
*.build.csdef
# Microsoft Azure Emulator
ecf/
rcf/
# Windows Store app package directories and files
AppPackages/
BundleArtifacts/
Package.StoreAssociation.xml
_pkginfo.txt
# Visual Studio cache files
# files ending in .cache can be ignored
*.[Cc]ache
# but keep track of directories ending in .cache
!*.[Cc]ache/
# Others
ClientBin/
~$*
*~
*.dbmdl
*.dbproj.schemaview
*.jfm
*.pfx
*.publishsettings
orleans.codegen.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
#bower_components/
# RIA/Silverlight projects
Generated_Code/
# Backup & report files from converting an old project file
# to a newer Visual Studio version. Backup files are not needed,
# because we have git ;-)
_UpgradeReport_Files/
Backup*/
UpgradeLog*.XML
UpgradeLog*.htm
# SQL Server files
*.mdf
*.ldf
*.ndf
# Business Intelligence projects
*.rdl.data
*.bim.layout
*.bim_*.settings
# Microsoft Fakes
FakesAssemblies/
# GhostDoc plugin setting file
*.GhostDoc.xml
# Node.js Tools for Visual Studio
.ntvs_analysis.dat
node_modules/
# Typescript v1 declaration files
typings/
# Visual Studio 6 build log
*.plg
# Visual Studio 6 workspace options file
*.opt
# Visual Studio 6 auto-generated workspace file (contains which files were open etc.)
*.vbw
# Visual Studio LightSwitch build output
**/*.HTMLClient/GeneratedArtifacts
**/*.DesktopClient/GeneratedArtifacts
**/*.DesktopClient/ModelManifest.xml
**/*.Server/GeneratedArtifacts
**/*.Server/ModelManifest.xml
_Pvt_Extensions
# Paket dependency manager
.paket/paket.exe
paket-files/
# FAKE - F# Make
.fake/
# JetBrains Rider
.idea/
*.sln.iml
# CodeRush
.cr/
# Python Tools for Visual Studio (PTVS)
__pycache__/
*.pyc
# Cake - Uncomment if you are using it
# tools/**
# !tools/packages.config
# Telerik's JustMock configuration file
*.jmconfig
# BizTalk build output
*.btp.cs
*.btm.cs
*.odx.cs
*.xsd.cs

68
README.md Normal file
Просмотреть файл

@ -0,0 +1,68 @@
### IoTHub
Fully featured IoT Hub input and output bindings to Azure IoT Hub, allowing common interactions between cloud and devices to be done from Azure Functions. Common scenarios currently supported are:
* Cloud to Device: output binding that sends messages from Azure Functions to IoTHub, which then transfer the messages to specified device id in the message structure
* Direct Method: output binding that invokes methods in the device from Azure Functions
* Set Device Twin: output binding that updates desired properties of specified device from Azure Functions
* Get Device Twin: input binding that gets device twin of the specified device once the Function's trigger is fired
#### Example
##### Cloud to Device
###### function.json
```csharp
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"path": "messages/events",
"connection": "IoTConnectionString",
"consumerGroup": "secondconsumergroup"
},
{
"name": "cloudToDevice",
"type": "ioTCloudToDevice",
"direction": "out",
"connection": "IoTConnectionString" // connection string can differ from the trigger's
}
],
"disabled": false
}
```
###### run.csx
```csharp
using System;
public static void Run(string myEventHubMessage, ICollector<string> cloudToDevice, ICollector<string> setDeviceTwin, TraceWriter log)
{
cloudToDevice.Add("{\"DeviceId\":\"myFirstDevice\",\"MessageId\":1,\"Message\":\"C2D message\"}");
}
```
See more [sample code](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/functions) for each scenario
#### Sample Code
[functions folders](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/functions) contains functions to use in Azure Functions portal. To run, do the following:
1. Zip extension .dll files and put them in Function's library via **Advanced tools (Kudu)**
2. Add the path where the extension lives to appsetting using **AzureWebJobs_ExtensionsPath** as key
3. Create a new function in portal and copy codes from selected scenario in the sample folder
4. Change the appsetting key for **connection string** in function.json to **IoTConnectionString** or change the key for **connection string** (and/or **consumerGroup** for EventHubTrigger) in function.json according to your custom app setting.
5. Run your device code or [sender.js](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/simulatedDevices/sender)
Your function should receive messages from **sender.js**
6. Run your device receiver code or select ones in [simulatedDevices folder](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/simulatedDevices) according to your scenario.
* [receiverAlice](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/simulatedDevices/receiverAlice): **Direct Method** or **Set/Get Device Twin**
* [receiverBob](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/simulatedDevices/receiverBob): **Cloud to Device** or **Set/Get Device Twin**
* [receiverCarol](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/simulatedDevices/receiverCarol): **Set/Get Device Twin**
* [receiverDave](https://github.com/ElleTojaroon/azure-functions-iothub-extension/tree/master/samples/simulatedDevices/receiverDave): **Cloud to Device** or **Set/Get Device Twin**
> Direct Method assumes that the device has a method matched with the specified method's name given in the argument. Otherwise, Function throws an exception.
> Executing direct method that takes longer than the lifetime of a Function (5 minutes by default and can be set up to 10 minutes) can never be completed.

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

@ -0,0 +1,36 @@

Microsoft Visual Studio Solution File, Format Version 12.00
# Visual Studio 15
VisualStudioVersion = 15.0.26430.14
MinimumVisualStudioVersion = 10.0.40219.1
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Webjobs.Extensions.IoTHub.Tests", "test\Webjobs.Extensions.IoTHub.Tests\Webjobs.Extensions.IoTHub.Tests.csproj", "{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "WebJobs.Extensions.IoTHub", "src\WebJobs.Extensions.IoTHub\WebJobs.Extensions.IoTHub.csproj", "{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "test", "test", "{C5A6A582-90C8-4C55-A0E8-F7EDB6F6D6AC}"
EndProject
Project("{2150E333-8FDC-42A3-9474-1A3956D46DE8}") = "src", "src", "{05892904-2034-4A3D-A1FC-F5D268C0C630}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Debug|Any CPU = Debug|Any CPU
Release|Any CPU = Release|Any CPU
EndGlobalSection
GlobalSection(ProjectConfigurationPlatforms) = postSolution
{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D}.Debug|Any CPU.Build.0 = Debug|Any CPU
{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D}.Release|Any CPU.ActiveCfg = Release|Any CPU
{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D}.Release|Any CPU.Build.0 = Release|Any CPU
{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588}.Debug|Any CPU.Build.0 = Debug|Any CPU
{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588}.Release|Any CPU.ActiveCfg = Release|Any CPU
{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588}.Release|Any CPU.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
EndGlobalSection
GlobalSection(NestedProjects) = preSolution
{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D} = {C5A6A582-90C8-4C55-A0E8-F7EDB6F6D6AC}
{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588} = {05892904-2034-4A3D-A1FC-F5D268C0C630}
EndGlobalSection
EndGlobal

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

@ -0,0 +1,25 @@
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"path": "messages/events",
"connection": "IoTConnectionString",
"consumerGroup": "secondconsumergroup"
},
{
"name": "cloudToDevice",
"type": "ioTCloudToDevice",
"direction": "out",
"connection": "IoTConnectionString"
},
{
"name": "setDeviceTwin",
"type": "ioTSetDeviceTwin",
"direction": "out",
"connection": "IoTConnectionString"
}
],
"disabled": false
}

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

@ -0,0 +1,56 @@
#r "Newtonsoft.Json"
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
/* Sending D2C messages to C2D */
public static void Run(string myEventHubMessage, ICollector<string> cloudToDevice, ICollector<string> setDeviceTwin, TraceWriter log)
{
// myEventHubMessage = D2C message
log.Info($"C# Event Hub trigger function processed a message: {myEventHubMessage}");
var msgJson = JsonConvert.DeserializeObject<Dictionary<string, string>>(myEventHubMessage);
var c2dItem = new
{
DeviceId = msgJson["DeviceId"],
MessageId = msgJson["MessageId"],
Message = "CLOUD " + msgJson["Message"]
};
var setDTItem = new
{
DeviceId = "receiverCarol",
UpdateId = msgJson["MessageId"],
Patch = new
{
properties = new
{
desired = new
{
telemetryConfig = new
{
configId = Guid.NewGuid().ToString()
}
}
}
}
};
try {
cloudToDevice.Add(JsonConvert.SerializeObject(c2dItem));
}
catch(Exception e) {
log.Error("Exception caught for c2dItem method: ", e);
log.Info("failed to add to Dave");
}
try {
setDeviceTwin.Add(JsonConvert.SerializeObject(setDTItem));
}
catch(Exception e) {
log.Error("Exception caught while sending DT ", e);
}
}

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

@ -0,0 +1,18 @@
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "eventHubMessage",
"direction": "in",
"path": "eventhubdirectmethods",
"connection": "DirectMethodEH_RootManageSharedAccessKey_EVENTHUB"
},
{
"name": "dm",
"type": "ioTDirectMethod",
"direction": "out",
"connection": "IoTConnectionString"
}
],
"disabled": false
}

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

@ -0,0 +1,9 @@
{
"frameworks": {
"net46":{
"dependencies": {
"Microsoft.Azure.Devices.Shared": "1.0.11"
}
}
}
}

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

@ -0,0 +1,21 @@
#r "Newtonsoft.Json"
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
public static void Run(string eventHubMessage, ICollector<string> dm, TraceWriter log)
{
log.Info($"C# Event Hub trigger function processed a message: {eventHubMessage}");
var msgJson = JsonConvert.DeserializeObject<Dictionary<string, string>>(eventHubMessage);
var item = new
{
DeviceId = msgJson["DeviceId"],
InvokeId = msgJson["MessageId"],
MethodName = msgJson["Message"]
};
dm.Add(JsonConvert.SerializeObject(item));
}

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

@ -0,0 +1,26 @@
{
"bindings": [
{
"type": "eventHubTrigger",
"name": "myEventHubMessage",
"direction": "in",
"path": "messages/events",
"connection": "IoTConnectionString",
"consumerGroup": "$Default"
},
{
"DeviceId": "{DeviceId}",
"name": "getDeviceTwin",
"type": "iotGetDeviceTwin",
"direction": "in",
"connection": "IoTConnectionString"
},
{
"name": "setDeviceTwin",
"type": "ioTSetDeviceTwin",
"direction": "out",
"connection": "IoTConnectionString"
}
],
"disabled": false
}

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

@ -0,0 +1,9 @@
{
"frameworks": {
"net452":{
"dependencies": {
"Microsoft.Azure.Devices.Shared": "1.0.11"
}
}
}
}

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

@ -0,0 +1,52 @@
#r "Newtonsoft.Json"
#r "Microsoft.Azure.Devices.Shared"
using System;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.Devices.Shared;
public class DataInput
{
public string DeviceId { get; set; }
public string MessageId { get; set; }
public string Message { get; set; }
}
public static void Run(DataInput myEventHubMessage, Twin getDeviceTwin, ICollector<string> setDeviceTwin, TraceWriter log)
{
log.Info($"C# Event Hub trigger function processed a message: {myEventHubMessage}");
log.Info($"C# Event Hub trigger function processed a message: {myEventHubMessage.DeviceId}");
log.Info($"C# get device twin: {getDeviceTwin.DeviceId}");
log.Info($"C# get device twin: {getDeviceTwin.Properties.Desired}");
// set device twin
var setDTItem = new
{
DeviceId = getDeviceTwin.DeviceId,
UpdateId = myEventHubMessage.MessageId,
Patch = new
{
properties = new
{
desired = new
{
telemetryConfig = new
{
configId = Guid.NewGuid().ToString()
}
}
}
}
};
try {
setDeviceTwin.Add(JsonConvert.SerializeObject(setDTItem));
}
catch(Exception e) {
log.Error("Exception caught while sending DT ", e);
}
}

1294
samples/simulatedDevices/receiverAlice/package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,15 @@
{
"name": "receiveralice",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"azure-iot-device": "^1.1.14",
"azure-iot-device-mqtt": "^1.1.14"
}
}

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

@ -0,0 +1,89 @@
'use strict';
var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var DeviceClient = require('azure-iot-device').Client;
var connectionString = 'HostName=<Host Name>;DeviceId=<Device Name>;SharedAccessKey=<Device Key>';
var client = DeviceClient.fromConnectionString(connectionString, Mqtt);
function onWriteLine(request, response) {
response.send(200, 'Input was written to log.', function (err) {
if (err) {
console.error('An error occurred when sending a method response:\n' + err.toString());
} else {
console.log('Response to method \'' + request.methodName + '\' sent successfully.');
}
});
}
var initConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
currentTelemetryConfig.pendingConfig = twin.properties.desired.telemetryConfig;
currentTelemetryConfig.status = "\x1b[36m Pending \x1b[0m";
var patch = {
telemetryConfig: currentTelemetryConfig
};
twin.properties.reported.update(patch, function (err) {
if (err) {
console.log('\x1b[36m Could not report properties \x1b[0m');
} else {
console.log('\x1b[36m Reported pending config change: ' + JSON.stringify(patch) + " \x1b[0m");
setTimeout(function () { completeConfigChange(twin); }, 60000);
}
});
}
var completeConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
try {
currentTelemetryConfig.configId = currentTelemetryConfig.pendingConfig.configId;
currentTelemetryConfig.sendFrequency = currentTelemetryConfig.pendingConfig.sendFrequency;
currentTelemetryConfig.status = "\x1b[36m Success \x1b[0m";
delete currentTelemetryConfig.pendingConfig;
var patch = {
telemetryConfig: currentTelemetryConfig
};
patch.telemetryConfig.pendingConfig = null;
twin.properties.reported.update(patch, function (err) {
if (err) {
console.error('\x1b[36m Error reporting properties: ' + err + " \x1b[0m");
} else {
console.log('\x1b[36m Reported completed config change: ' + JSON.stringify(patch) + " \x1b[0m");
}
});
} catch (error) {
console.log("Fails to complete setting device twin. Check the currect config to see if your change went through");
console.log(currentTelemetryConfig)
}
}
client.open(function (err) {
if (err) {
console.error('could not open IotHub client');
} else {
console.log('client opened');
client.onDeviceMethod('writeLine', onWriteLine);
client.getTwin(function (err, twin) {
if (err) {
console.error('\x1b[36m could not get twin \x1b[0m');
} else {
console.log('\x1b[36m retrieved device twin \x1b[0m');
twin.properties.reported.telemetryConfig = {
configId: "0",
sendFrequency: "24h"
}
twin.on('properties.desired', function (desiredChange) {
console.log("\x1b[36m received device twin change: " + JSON.stringify(desiredChange) + " \x1b[0m");
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
if (desiredChange.telemetryConfig && desiredChange.telemetryConfig.configId !== currentTelemetryConfig.configId) {
initConfigChange(twin);
}
});
}
});
}
});

2570
samples/simulatedDevices/receiverBob/package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,16 @@
{
"name": "receiverbob",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"azure-event-hubs": "0.0.8",
"azure-iot-device": "^1.1.14",
"azure-iot-device-mqtt": "^1.1.14"
}
}

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

@ -0,0 +1,108 @@
'use strict';
// var wpi = require('wiring-pi');
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;
var Message = require('azure-iot-device').Message;
var connectionString = 'HostName=<Host Name>;DeviceId=<Device Name>;SharedAccessKey=<Device Key>';
var client = clientFromConnectionString(connectionString);
// GPIO pin of the led
// var configPin = 7;
// wpi.setup('wpi');
// wpi.pinMode(configPin, wpi.OUTPUT);
// var isLedOn = 0;
function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}
var initConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
currentTelemetryConfig.pendingConfig = twin.properties.desired.telemetryConfig;
currentTelemetryConfig.status = "\x1b[36m Pending \x1b[0m";
var patch = {
telemetryConfig: currentTelemetryConfig
};
twin.properties.reported.update(patch, function (err) {
if (err) {
console.log('\x1b[36m Could not report properties \x1b[0m');
} else {
console.log('\x1b[36m Reported pending config change: ' + JSON.stringify(patch) + " \x1b[0m");
setTimeout(function () { completeConfigChange(twin); }, 60000);
}
});
}
var completeConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
try {
currentTelemetryConfig.configId = currentTelemetryConfig.pendingConfig.configId;
currentTelemetryConfig.sendFrequency = currentTelemetryConfig.pendingConfig.sendFrequency;
currentTelemetryConfig.status = "\x1b[36m Success \x1b[0m";
delete currentTelemetryConfig.pendingConfig;
var patch = {
telemetryConfig: currentTelemetryConfig
};
patch.telemetryConfig.pendingConfig = null;
twin.properties.reported.update(patch, function (err) {
if (err) {
console.error('\x1b[36m Error reporting properties: ' + err + " \x1b[0m");
} else {
console.log('\x1b[36m Reported completed config change: ' + JSON.stringify(patch) + " \x1b[0m");
}
});
} catch (error) {
console.log("Fails to complete setting device twin. Check the currect config to see if your change went through");
console.log(currentTelemetryConfig)
}
}
// var blinkLED = function () {
// isLedOn = 1;
// wpi.digitalWrite(configPin, isLedOn );
// setTimeout(function(){
// isLedOn = 0;
// wpi.digitalWrite(configPin, isLedOn );
// }, 1000);
// }
var connectCallback = function (err) {
if (err) {
console.log('Could not connect: ' + err);
} else {
console.log('Client connected');
client.on('message', function (msg) {
// blinkLED();
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
client.complete(msg, printResultFor('completed'));
});
client.getTwin(function (err, twin) {
if (err) {
console.error('\x1b[36m could not get twin \x1b[0m');
} else {
console.log('\x1b[36m retrieved device twin \x1b[0m');
twin.properties.reported.telemetryConfig = {
configId: "0",
sendFrequency: "24h"
}
twin.on('properties.desired', function (desiredChange) {
console.log("\x1b[36m received device twin change: " + JSON.stringify(desiredChange) + " \x1b[0m");
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
if (desiredChange.telemetryConfig && desiredChange.telemetryConfig.configId !== currentTelemetryConfig.configId) {
initConfigChange(twin);
}
});
}
});
}
};
client.open(connectCallback);

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

@ -0,0 +1,15 @@
{
"name": "receivercarol",
"version": "1.0.0",
"description": "",
"main": "receivercarol.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"azure-iot-device": "^1.1.15",
"azure-iot-device-mqtt": "^1.1.15"
}
}

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

@ -0,0 +1,77 @@
'use strict';
var Mqtt = require('azure-iot-device-mqtt').Mqtt;
var DeviceClient = require('azure-iot-device').Client;
var connectionString = 'HostName=<Host Name>;DeviceId=<Device Name>;SharedAccessKey=<Device Key>';
var client = DeviceClient.fromConnectionString(connectionString, Mqtt);
var initConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
currentTelemetryConfig.pendingConfig = twin.properties.desired.telemetryConfig;
currentTelemetryConfig.status = "\x1b[36m Pending \x1b[0m";
var patch = {
telemetryConfig: currentTelemetryConfig
};
twin.properties.reported.update(patch, function (err) {
if (err) {
console.log('\x1b[36m Could not report properties \x1b[0m');
} else {
console.log('\x1b[36m Reported pending config change: ' + JSON.stringify(patch) + " \x1b[0m");
setTimeout(function () { completeConfigChange(twin); }, 60000);
}
});
}
var completeConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
try {
currentTelemetryConfig.configId = currentTelemetryConfig.pendingConfig.configId;
currentTelemetryConfig.sendFrequency = currentTelemetryConfig.pendingConfig.sendFrequency;
currentTelemetryConfig.status = "\x1b[36m Success \x1b[0m";
delete currentTelemetryConfig.pendingConfig;
var patch = {
telemetryConfig: currentTelemetryConfig
};
patch.telemetryConfig.pendingConfig = null;
twin.properties.reported.update(patch, function (err) {
if (err) {
console.error('\x1b[36m Error reporting properties: ' + err + " \x1b[0m");
} else {
console.log('\x1b[36m Reported completed config change: ' + JSON.stringify(patch) + " \x1b[0m");
}
});
} catch (error) {
console.log("Fails to complete setting device twin. Check the currect config to see if your change went through");
console.log(currentTelemetryConfig)
}
}
client.open(function (err) {
if (err) {
console.error('could not open IotHub client');
} else {
console.log('client opened');
client.getTwin(function (err, twin) {
if (err) {
console.error('\x1b[36m could not get twin \x1b[0m');
} else {
console.log('\x1b[36m retrieved device twin \x1b[0m');
twin.properties.reported.telemetryConfig = {
configId: "0",
sendFrequency: "24h"
}
twin.on('properties.desired', function (desiredChange) {
console.log("\x1b[36m received device twin change: " + JSON.stringify(desiredChange) + " \x1b[0m");
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
if (desiredChange.telemetryConfig && desiredChange.telemetryConfig.configId !== currentTelemetryConfig.configId) {
initConfigChange(twin);
}
});
}
});
}
});

1294
samples/simulatedDevices/receiverDave/package-lock.json сгенерированный Normal file

Разница между файлами не показана из-за своего большого размера Загрузить разницу

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

@ -0,0 +1,14 @@
{
"name": "receiverdave",
"version": "1.0.0",
"description": "",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"author": "",
"license": "ISC",
"dependencies": {
"azure-iot-device-mqtt": "^1.1.16"
}
}

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

@ -0,0 +1,108 @@
'use strict';
// var wpi = require('wiring-pi');
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;
var Message = require('azure-iot-device').Message;
var connectionString = 'HostName=<Host Name>;DeviceId=<Device Name>;SharedAccessKey=<Device Key>';
var client = clientFromConnectionString(connectionString);
// GPIO pin of the led
// var configPin = 7;
// wpi.setup('wpi');
// wpi.pinMode(configPin, wpi.OUTPUT);
// var isLedOn = 0;
function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}
var initConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
currentTelemetryConfig.pendingConfig = twin.properties.desired.telemetryConfig;
currentTelemetryConfig.status = "\x1b[36m Pending \x1b[0m";
var patch = {
telemetryConfig: currentTelemetryConfig
};
twin.properties.reported.update(patch, function (err) {
if (err) {
console.log('\x1b[36m Could not report properties \x1b[0m');
} else {
console.log('\x1b[36m Reported pending config change: ' + JSON.stringify(patch) + " \x1b[0m");
setTimeout(function () { completeConfigChange(twin); }, 60000);
}
});
}
var completeConfigChange = function (twin) {
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
try {
currentTelemetryConfig.configId = currentTelemetryConfig.pendingConfig.configId;
currentTelemetryConfig.sendFrequency = currentTelemetryConfig.pendingConfig.sendFrequency;
currentTelemetryConfig.status = "\x1b[36m Success \x1b[0m";
delete currentTelemetryConfig.pendingConfig;
var patch = {
telemetryConfig: currentTelemetryConfig
};
patch.telemetryConfig.pendingConfig = null;
twin.properties.reported.update(patch, function (err) {
if (err) {
console.error('\x1b[36m Error reporting properties: ' + err + " \x1b[0m");
} else {
console.log('\x1b[36m Reported completed config change: ' + JSON.stringify(patch) + " \x1b[0m");
}
});
} catch (error) {
console.log("Fails to complete setting device twin. Check the currect config to see if your change went through");
console.log(currentTelemetryConfig)
}
}
// var blinkLED = function () {
// isLedOn = 1;
// wpi.digitalWrite(configPin, isLedOn );
// setTimeout(function(){
// isLedOn = 0;
// wpi.digitalWrite(configPin, isLedOn );
// }, 1000);
// }
var connectCallback = function (err) {
if (err) {
console.log('Could not connect: ' + err);
} else {
console.log('Client connected');
client.on('message', function (msg) {
// blinkLED();
console.log('Id: ' + msg.messageId + ' Body: ' + msg.data);
client.complete(msg, printResultFor('completed'));
});
client.getTwin(function (err, twin) {
if (err) {
console.error('\x1b[36m could not get twin \x1b[0m');
} else {
console.log('\x1b[36m retrieved device twin \x1b[0m');
twin.properties.reported.telemetryConfig = {
configId: "0",
sendFrequency: "24h"
}
twin.on('properties.desired', function (desiredChange) {
console.log("\x1b[36m received device twin change: " + JSON.stringify(desiredChange) + " \x1b[0m");
var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
if (desiredChange.telemetryConfig && desiredChange.telemetryConfig.configId !== currentTelemetryConfig.configId) {
initConfigChange(twin);
}
});
}
});
}
};
client.open(connectCallback);

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

@ -0,0 +1,19 @@
{
"name": "sender",
"version": "1.0.0",
"description": "send telemetry data points and direct method requests",
"main": "index.js",
"scripts": {
"test": "echo \"Error: no test specified\" && exit 1"
},
"repository": {
"type": "git",
"url": "elle_elle-555"
},
"author": "ElleTojaroon",
"license": "ISC",
"dependencies": {
"azure-iot-device": "^1.1.14",
"azure-iot-device-mqtt": "^1.1.14"
}
}

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

@ -0,0 +1,134 @@
'use strict';
var clientFromConnectionString = require('azure-iot-device-mqtt').clientFromConnectionString;
var Message = require('azure-iot-device').Message;
var connectionString = 'HostName=<Host Name>;DeviceId=<Device Name>;SharedAccessKey=<Device Key>';
var client = clientFromConnectionString(connectionString);
var count = 0;
var isAllTelemetry = 1;
var isAllDirectMethods = 0;
var isAllSBQueue = 0;
var isAllSBTopic = 0;
var isAnyAll = isAllTelemetry || isAllDirectMethods || isAllSBQueue || isAllSBTopic;
function printResultFor(op) {
return function printResult(err, res) {
if (err) console.log(op + ' error: ' + err.toString());
if (res) console.log(op + ' status: ' + res.constructor.name);
};
}
// var initConfigChange = function (twin) {
// var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
// currentTelemetryConfig.pendingConfig = twin.properties.desired.telemetryConfig;
// currentTelemetryConfig.status = "\x1b[36m Pending \x1b[0m";
// var patch = {
// telemetryConfig: currentTelemetryConfig
// };
// twin.properties.reported.update(patch, function (err) {
// if (err) {
// console.log('\x1b[36m Could not report properties \x1b[0m');
// } else {
// console.log('\x1b[36m Reported pending config change: ' + JSON.stringify(patch) + " \x1b[0m");
// setTimeout(function () { completeConfigChange(twin); }, 60000);
// }
// });
// }
// var completeConfigChange = function (twin) {
// var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
// try {
// currentTelemetryConfig.configId = currentTelemetryConfig.pendingConfig.configId;
// currentTelemetryConfig.sendFrequency = currentTelemetryConfig.pendingConfig.sendFrequency;
// currentTelemetryConfig.status = "\x1b[36m Success \x1b[0m";
// delete currentTelemetryConfig.pendingConfig;
// var patch = {
// telemetryConfig: currentTelemetryConfig
// };
// patch.telemetryConfig.pendingConfig = null;
// twin.properties.reported.update(patch, function (err) {
// if (err) {
// console.error('\x1b[36m Error reporting properties: ' + err + " \x1b[0m");
// } else {
// console.log('\x1b[36m Reported completed config change: ' + JSON.stringify(patch) + " \x1b[0m");
// }
// });
// } catch (error) {
// console.log("Fails to complete setting device twin. Check the currect config to see if your change went through");
// console.log(currentTelemetryConfig)
// }
// }
var connectCallback = function (err) {
if (err) {
console.log('Could not connect: ' + err);
} else {
console.log('Client connected');
// Create a message and send it to the IoT Hub every second
setInterval(function () {
var isDirectMethod = false;
var isSBQueue = false;
var isSBTopic = false;
var messageString;
var fontColor;
var receiverDeviceId;
if (isAllDirectMethods || (!isAnyAll && count % 5 == 0)) {
isDirectMethod = true;
messageString = 'writeLine';
receiverDeviceId = 'receiverAlice';
fontColor = "\x1b[31m"; // red -urgent
} else if (isAllSBQueue || (!isAnyAll && count % 3 == 0)) {
isSBQueue = true;
messageString = 'writeLine';
receiverDeviceId = 'receiverAlice';
fontColor = "\x1b[32m"; // green
} else if (isAllSBTopic || (!isAnyAll && count % 7 == 0)) {
isSBTopic = true;
messageString = 'writeLine';
receiverDeviceId = 'receiverAlice';
fontColor = "\x1b[36m"; // cyan
} else { // isAllTelemetry
messageString = "telemetry data point";
receiverDeviceId = 'receiverBob'; // used to be receiverBob
fontColor = "\x1b[33m%s\x1b[0m:"; // yellow -telemetry
}
var data = JSON.stringify({ DeviceId: receiverDeviceId, MessageId: Date.now(), Message: messageString });
var message = new Message(data);
message.properties.add('isDirectMethod', isDirectMethod);
message.properties.add('isSBQueue', isSBQueue);
message.properties.add('isSBTopic', isSBTopic);
console.log("Sending message: " + fontColor, message.getData(), "\x1b[0m");
client.sendEvent(message, printResultFor('send'));
count += 1;
}, 5000);
// client.getTwin(function (err, twin) {
// if (err) {
// console.error('\x1b[36m could not get twin \x1b[0m');
// } else {
// console.log('\x1b[36m retrieved device twin \x1b[0m');
// twin.properties.reported.telemetryConfig = {
// configId: "0",
// sendFrequency: "24h"
// }
// twin.on('properties.desired', function (desiredChange) {
// console.log("\x1b[36m received device twin change: " + JSON.stringify(desiredChange) + " \x1b[0m");
// var currentTelemetryConfig = twin.properties.reported.telemetryConfig;
// if (desiredChange.telemetryConfig && desiredChange.telemetryConfig.configId !== currentTelemetryConfig.configId) {
// initConfigChange(twin);
// }
// });
// }
// });
}
};
client.open(connectCallback);

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

@ -0,0 +1,26 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6" />
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="System.Net.Http" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.1.0" newVersion="4.1.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Diagnostics.DiagnosticSource" publicKeyToken="cc7b13ffcd2ddd51" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.0.1.0" newVersion="4.0.1.0" />
</dependentAssembly>
<dependentAssembly>
<assemblyIdentity name="System.Xml.ReaderWriter" publicKeyToken="b03f5f7f11d50a3a" culture="neutral" />
<bindingRedirect oldVersion="0.0.0.0-4.1.0.0" newVersion="4.1.0.0" />
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

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

@ -0,0 +1,41 @@
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.Devices;
using System.Threading;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
/// <summary>
/// Provide the implementation for a collector.
/// For the sample, we're writing <see cref="IoTCloudToDeviceItem"/>s to disk.
/// Collectors are used for emitting a series of discrete messages (ie, an output binding).
/// </summary>
public class IoTCloudToDeviceAsyncCollector : IAsyncCollector<IoTCloudToDeviceItem>
{
private static ServiceClient serviceClient;
public IoTCloudToDeviceAsyncCollector(ServiceClient serviceClient, IoTCloudToDeviceAttribute attribute)
{
// create client;
IoTCloudToDeviceAsyncCollector.serviceClient = serviceClient;
}
public Task AddAsync(IoTCloudToDeviceItem item, CancellationToken cancellationToken = default(CancellationToken))
{
SendCloudToDeviceMessageAsync(item).Wait();
return Task.CompletedTask;
}
public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
private async static Task SendCloudToDeviceMessageAsync(IoTCloudToDeviceItem item)
{
char[] messageCharArr = item.Message.ToCharArray();
var deviceToCloudMessage = new Message(Encoding.ASCII.GetBytes(messageCharArr));
await serviceClient.SendAsync(item.DeviceId, deviceToCloudMessage);
}
}
}

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

@ -0,0 +1,59 @@
using System;
using System.Collections.Generic;
using Microsoft.Azure.Devices;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Config;
using Newtonsoft.Json;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
public class IoTCloudToDeviceExtension : IExtensionConfigProvider
{
private static string connectionString;
private static ServiceClient serviceClient;
public void Initialize(ExtensionConfigContext context)
{
// This allows a user to bind to IAsyncCollector<string>, and the sdk
// will convert that to IAsyncCollector<IoTCloudToDeviceItem>
context.AddConverter<string, IoTCloudToDeviceItem>(ConvertToItem);
// This is useful on input.
context.AddConverter<IoTCloudToDeviceItem, string>(ConvertToString);
// Create 2 binding rules for the Sample attribute.
var rule = context.AddBindingRule<IoTCloudToDeviceAttribute>();
rule.BindToCollector<IoTCloudToDeviceItem>(BuildCollector);
}
private string ConvertToString(IoTCloudToDeviceItem item)
{
return JsonConvert.SerializeObject(item);
}
private IoTCloudToDeviceItem ConvertToItem(string str)
{
var item = JsonConvert.DeserializeObject<Dictionary<string, string>>(str);
return new IoTCloudToDeviceItem
{
DeviceId = item["DeviceId"],
MessageId = item["MessageId"],
Message = str
};
}
private IAsyncCollector<IoTCloudToDeviceItem> BuildCollector(IoTCloudToDeviceAttribute attribute)
{
if (serviceClient == null)
{
connectionString = attribute.Connection;
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
}
return new IoTCloudToDeviceAsyncCollector(serviceClient, attribute);
}
}
}

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

@ -0,0 +1,40 @@
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.Devices;
using System.Threading;
using System;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
public class IoTDirectMethodAsyncCollector : IAsyncCollector<IoTDirectMethodItem>
{
private static ServiceClient serviceClient;
public IoTDirectMethodAsyncCollector(ServiceClient serviceClient, IoTDirectMethodAttribute attribute)
{
// create client;
IoTDirectMethodAsyncCollector.serviceClient = serviceClient;
}
public Task AddAsync(IoTDirectMethodItem item, CancellationToken cancellationToken = default(CancellationToken))
{
InvokeMethod(item.DeviceId, item.MethodName).Wait();
return Task.CompletedTask;
}
public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
private static async Task InvokeMethod(string deviceID, string methodName)
{
var methodInvocation = new CloudToDeviceMethod(methodName) { ResponseTimeout = TimeSpan.FromSeconds(30) };
var response = await serviceClient.InvokeDeviceMethodAsync(deviceID, methodInvocation);
Console.WriteLine("Response status: {0}, payload:", response.Status);
Console.WriteLine(response.GetPayloadAsJson());
}
}
}

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

@ -0,0 +1,60 @@
using Microsoft.Azure.Devices;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Config;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
public class IoTDirectMethodExtension : IExtensionConfigProvider
{
private static string connectionString;
private static ServiceClient serviceClient;
public void Initialize(ExtensionConfigContext context)
{
// This allows a user to bind to IAsyncCollector<string>, and the sdk
// will convert that to IAsyncCollector<IoTCloudToDeviceItem>
context.AddConverter<string, IoTDirectMethodItem>(ConvertToItem);
// This is useful on input.
context.AddConverter<IoTDirectMethodItem, string>(ConvertToString);
// Create 2 binding rules for the Sample attribute.
var rule = context.AddBindingRule<IoTDirectMethodAttribute>();
//rule.BindToInput<SampleItem>(BuildItemFromAttr);
rule.BindToCollector<IoTDirectMethodItem>(BuildCollector);
}
private string ConvertToString(IoTDirectMethodItem item)
{
return JsonConvert.SerializeObject(item);
}
private IoTDirectMethodItem ConvertToItem(string str)
{
var item = JsonConvert.DeserializeObject<Dictionary<string, string>>(str);
return new IoTDirectMethodItem
{
DeviceId = item["DeviceId"],
InvokeId = item["InvokeId"],
MethodName = item["MethodName"]
};
}
private IAsyncCollector<IoTDirectMethodItem> BuildCollector(IoTDirectMethodAttribute attribute)
{
if (serviceClient == null)
{
connectionString = attribute.Connection;
serviceClient = ServiceClient.CreateFromConnectionString(connectionString);
}
return new IoTDirectMethodAsyncCollector(serviceClient, attribute);
}
}
}

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

@ -0,0 +1,76 @@
using Microsoft.Azure.Devices;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Azure.WebJobs.Host.Config;
using Newtonsoft.Json;
using Newtonsoft.Json.Linq;
using System;
using System.Collections.Generic;
using System.Threading.Tasks;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
public class IoTGetDeviceTwinExtension : IExtensionConfigProvider
{
private static string connectionString;
static RegistryManager registryManager;
private Twin deviceTwin;
public void Initialize(ExtensionConfigContext context)
{
// This is useful on input.
context.AddConverter<Twin, string>(ConvertToString);
context.AddConverter<Twin, Newtonsoft.Json.Linq.JObject>(ConvertToJObject);
//context.AddConverter<Twin, Twin>(ConvertToTwin);
// Create 2 binding rules for the Sample attribute.
var rule = context.AddBindingRule<IoTGetDeviceTwinAttribute>();
rule.BindToInput<Twin>(BuildItemFromAttr);
}
private string ConvertToString(Twin item)
{
return JsonConvert.SerializeObject(item);
}
//private Twin ConvertToTwin(Twin item)
//{
// return item;
//}
private JObject ConvertToJObject(Twin results)
{
return JObject.FromObject(results);
}
private IoTGetDeviceTwinItem ConvertToItem(string str)
{
var item = JsonConvert.DeserializeObject<Dictionary<string, object>>(str);
return new IoTGetDeviceTwinItem
{
DeviceId = (string)item["DeviceId"]
};
}
// All {} and %% in the Attribute have been resolved by now.
private Twin BuildItemFromAttr(IoTGetDeviceTwinAttribute attribute)
{
string deviceId = attribute.DeviceId;
GetDeviceTwinAsync(attribute).Wait();
return deviceTwin;
}
private async Task GetDeviceTwinAsync(IoTGetDeviceTwinAttribute attribute)
{
if (registryManager == null)
{
connectionString = attribute.Connection;
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
}
deviceTwin = await registryManager.GetTwinAsync(attribute.DeviceId);
}
}
}

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

@ -0,0 +1,37 @@
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.Devices;
using System.Threading;
using System;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
public class IoTSetDeviceTwinAsyncCollector : IAsyncCollector<IoTSetDeviceTwinItem>
{
static RegistryManager registryManager;
public IoTSetDeviceTwinAsyncCollector(RegistryManager registryManager, IoTSetDeviceTwinAttribute attribute)
{
// create client;
IoTSetDeviceTwinAsyncCollector.registryManager = registryManager;
}
public Task AddAsync(IoTSetDeviceTwinItem item, CancellationToken cancellationToken = default(CancellationToken))
{
SetDesiredConfigurationAndQuery(item).Wait();
return Task.CompletedTask;
}
public Task FlushAsync(CancellationToken cancellationToken = default(CancellationToken))
{
return Task.CompletedTask;
}
static private async Task SetDesiredConfigurationAndQuery(IoTSetDeviceTwinItem item)
{
var twin = await registryManager.GetTwinAsync(item.DeviceId);
await registryManager.UpdateTwinAsync(twin.DeviceId, item.Patch, twin.ETag);
Console.WriteLine("Updated desired configuration");
}
}
}

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

@ -0,0 +1,60 @@
using Microsoft.Azure.Devices;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host.Config;
using Newtonsoft.Json;
using System;
using System.Collections.Generic;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub.Config
{
public class IoTSetDeviceTwinExtension : IExtensionConfigProvider
{
private static string connectionString;
static RegistryManager registryManager;
public void Initialize(ExtensionConfigContext context)
{
// This allows a user to bind to IAsyncCollector<string>, and the sdk
// will convert that to IAsyncCollector<IoTCloudToDeviceItem>
context.AddConverter<string, IoTSetDeviceTwinItem>(ConvertToItem);
// This is useful on input.
context.AddConverter<IoTSetDeviceTwinItem, string>(ConvertToString);
// Create 2 binding rules for the Sample attribute.
var rule = context.AddBindingRule<IoTSetDeviceTwinAttribute>();
//rule.BindToInput<IoTSetDeviceTwinItem>(BuildItemFromAttr);
rule.BindToCollector<IoTSetDeviceTwinItem>(BuildCollector);
}
private string ConvertToString(IoTSetDeviceTwinItem item)
{
return JsonConvert.SerializeObject(item);
}
private IoTSetDeviceTwinItem ConvertToItem(string str)
{
var item = JsonConvert.DeserializeObject<Dictionary<string, object>>(str);
return new IoTSetDeviceTwinItem
{
DeviceId = (string)item["DeviceId"],
UpdateId = (string)item["UpdateId"],
Patch = JsonConvert.SerializeObject(item["Patch"])
};
}
private IAsyncCollector<IoTSetDeviceTwinItem> BuildCollector(IoTSetDeviceTwinAttribute attribute)
{
if (registryManager == null)
{
connectionString = attribute.Connection;
registryManager = RegistryManager.CreateFromConnectionString(connectionString);
}
return new IoTSetDeviceTwinAsyncCollector(registryManager, attribute);
}
}
}

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

@ -0,0 +1,30 @@
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Description;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
/// <summary>
/// Binding attribute to place on user code for WebJobs.
/// </summary>
[Binding]
public class IoTCloudToDeviceAttribute : Attribute
{
[AutoResolve]
public string DeviceId { get; set; }
[AutoResolve]
public string MessageId { get; set; }
[AutoResolve]
public string Message { get; set; }
[AppSetting]
public string Connection { get; set; }
}
}

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

@ -0,0 +1,26 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
/// <summary>
/// A "native type" for the extension. This gives full access to the extension's object model.
/// The extension may then register converters to convert between this and "bcl" types
/// like string, JObject, etc.
/// </summary>
public class IoTCloudToDeviceItem
{
// IoT DeviceId
public string DeviceId { set; get; }
// MessegeId starting with 1 per DeviceId
public string MessageId { set; get; }
// Messege sent from device to cloud
// Invariant: {paramerter key}:{paramerter value};...
public string Message { set; get; }
}
}

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

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Description;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
/// <summary>
/// Binding attribute to place on user code for WebJobs.
/// </summary>
[Binding]
public class IoTDirectMethodAttribute : Attribute
{
[AutoResolve]
public string DeviceId { get; set; }
[AutoResolve]
public string InvokeId { get; set; }
[AutoResolve]
public string MethodName { get; set; }
[AppSetting]
public string Connection { get; set; }
}
}

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

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
public class IoTDirectMethodItem
{
// Destination IoT DeviceId
public string DeviceId { set; get; }
// InvokeId starting with 1 per DeviceId
public string InvokeId { set; get; }
// MethodName to be invoked
public string MethodName { set; get; }
}
}

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

@ -0,0 +1,23 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Description;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
/// <summary>
/// Binding attribute to place on user code for WebJobs.
/// </summary>
[Binding]
public class IoTGetDeviceTwinAttribute : Attribute
{
[AutoResolve]
public string DeviceId { get; set; }
[AppSetting]
public string Connection { get; set; }
}
}

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

@ -0,0 +1,14 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
public class IoTGetDeviceTwinItem
{
// Destination IoT DeviceId
public string DeviceId { set; get; }
}
}

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

@ -0,0 +1,29 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Description;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
/// <summary>
/// Binding attribute to place on user code for WebJobs.
/// </summary>
[Binding]
public class IoTSetDeviceTwinAttribute : Attribute
{
[AutoResolve]
public string DeviceId { get; set; }
[AutoResolve]
public string UpdateId { get; set; }
[AutoResolve]
public string Patch { get; set; }
[AppSetting]
public string Connection { get; set; }
}
}

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

@ -0,0 +1,20 @@
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
namespace Microsoft.Azure.WebJobs.Extensions.IoTHub
{
public class IoTSetDeviceTwinItem
{
// Destination IoT DeviceId
public string DeviceId { set; get; }
// InvokeId starting with 1 per DeviceId
public string UpdateId { set; get; }
// new configuration to change (either tags or desired properties)
public string Patch { set; get; }
}
}

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

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("WebJobs.Extensions.IoTHub")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("WebJobs.Extensions.IoTHub")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("24e41ed3-0f5a-47da-a32e-79a8fe9d6588")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

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

@ -0,0 +1,154 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{24E41ED3-0F5A-47DA-A32E-79A8FE9D6588}</ProjectGuid>
<OutputType>Library</OutputType>
<AppDesignerFolder>Properties</AppDesignerFolder>
<RootNamespace>WebJobs.Extensions.IoTHub</RootNamespace>
<AssemblyName>WebJobs.Extensions.IoTHub</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<NuGetPackageImportStamp>
</NuGetPackageImportStamp>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Azure.Amqp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Amqp.2.0.6\lib\net45\Microsoft.Azure.Amqp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Devices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Devices.1.2.9\lib\net451\Microsoft.Azure.Devices.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Devices.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Devices.Shared.1.0.11\lib\net45\Microsoft.Azure.Devices.Shared.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Host, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Edm.5.6.4\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.OData.5.6.4\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.4\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=7.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.7.2.1\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL">
<HintPath>..\..\packages\PCLCrypto.2.0.147\lib\net45\PCLCrypto.dll</HintPath>
</Reference>
<Reference Include="PInvoke.BCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.BCrypt.0.3.2\lib\net40\PInvoke.BCrypt.dll</HintPath>
</Reference>
<Reference Include="PInvoke.Kernel32, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Kernel32.0.3.2\lib\net40\PInvoke.Kernel32.dll</HintPath>
</Reference>
<Reference Include="PInvoke.NCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.NCrypt.0.3.2\lib\net40\PInvoke.NCrypt.dll</HintPath>
</Reference>
<Reference Include="PInvoke.Windows.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.6.4\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Validation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
<HintPath>..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Core, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.247\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.Core.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Platform, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.247\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.Platform.dll</HintPath>
</Reference>
<Reference Include="Xamarin.Forms.Xaml, Version=2.0.0.0, Culture=neutral, processorArchitecture=MSIL">
<HintPath>..\..\packages\Xamarin.Forms.2.3.4.247\lib\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.Xaml.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Config\IoTCloudToDeviceAsyncCollector.cs" />
<Compile Include="Config\IoTCloudToDeviceExtension.cs" />
<Compile Include="Config\IoTDirectMethodAsyncCollector.cs" />
<Compile Include="Config\IoTDirectMethodExtension.cs" />
<Compile Include="Config\IoTGetDeviceTwinExtension.cs" />
<Compile Include="Config\IoTSetDeviceTwinAsyncCollector.cs" />
<Compile Include="Config\IoTSetDeviceTwinExtension.cs" />
<Compile Include="IoTCloudToDeviceAttribute.cs" />
<Compile Include="IoTCloudToDeviceItem.cs" />
<Compile Include="IoTDirectMethodAttribute.cs" />
<Compile Include="IoTDirectMethodItem.cs" />
<Compile Include="IoTGetDeviceTwinAttribute.cs" />
<Compile Include="IoTGetDeviceTwinItem.cs" />
<Compile Include="IoTSetDeviceTwinAttribute.cs" />
<Compile Include="IoTSetDeviceTwinItem.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
<Import Project="..\..\packages\Xamarin.Forms.2.3.4.247\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets" Condition="Exists('..\..\packages\Xamarin.Forms.2.3.4.247\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" />
<Target Name="EnsureNuGetPackageBuildImports" BeforeTargets="PrepareForBuild">
<PropertyGroup>
<ErrorText>This project references NuGet package(s) that are missing on this computer. Use NuGet Package Restore to download them. For more information, see http://go.microsoft.com/fwlink/?LinkID=322105. The missing file is {0}.</ErrorText>
</PropertyGroup>
<Error Condition="!Exists('..\..\packages\Xamarin.Forms.2.3.4.247\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets')" Text="$([System.String]::Format('$(ErrorText)', '..\..\packages\Xamarin.Forms.2.3.4.247\build\portable-win+net45+wp80+win81+wpa81+MonoAndroid10+Xamarin.iOS10+xamarinmac20\Xamarin.Forms.targets'))" />
</Target>
</Project>

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

@ -0,0 +1,57 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.Azure.Amqp" version="2.0.6" targetFramework="net452" />
<package id="Microsoft.Azure.Devices" version="1.2.9" targetFramework="net452" />
<package id="Microsoft.Azure.Devices.Shared" version="1.0.11" targetFramework="net452" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Azure.WebJobs" version="2.1.0-beta1" targetFramework="net452" />
<package id="Microsoft.Azure.WebJobs.Core" version="2.1.0-beta1" targetFramework="net452" />
<package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net452" />
<package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net452" />
<package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net452" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.1" targetFramework="net452" />
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net452" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="PCLCrypto" version="2.0.147" targetFramework="net452" />
<package id="PInvoke.BCrypt" version="0.3.2" targetFramework="net452" />
<package id="PInvoke.Kernel32" version="0.3.2" targetFramework="net452" />
<package id="PInvoke.NCrypt" version="0.3.2" targetFramework="net452" />
<package id="PInvoke.Windows.Core" version="0.3.2" targetFramework="net452" />
<package id="System.Collections" version="4.3.0" targetFramework="net452" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net452" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net452" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net452" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net452" />
<package id="System.Globalization" version="4.3.0" targetFramework="net452" />
<package id="System.IO" version="4.3.0" targetFramework="net452" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Linq" version="4.3.0" targetFramework="net452" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net452" />
<package id="System.Net.Http" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net452" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net452" />
<package id="System.Reflection" version="4.3.0" targetFramework="net452" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net452" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net452" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net452" />
<package id="System.Spatial" version="5.6.4" targetFramework="net452" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net452" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net452" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net452" />
<package id="System.Threading" version="4.3.0" targetFramework="net452" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net452" />
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net452" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net452" />
<package id="Validation" version="2.2.8" targetFramework="net452" />
<package id="WindowsAzure.Storage" version="7.2.1" targetFramework="net452" />
<package id="Xamarin.Forms" version="2.3.4.247" targetFramework="net452" />
</packages>

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

@ -0,0 +1,14 @@
<?xml version="1.0" encoding="utf-8"?>
<configuration>
<startup>
<supportedRuntime version="v4.0" sku=".NETFramework,Version=v4.6"/>
</startup>
<runtime>
<assemblyBinding xmlns="urn:schemas-microsoft-com:asm.v1">
<dependentAssembly>
<assemblyIdentity name="Newtonsoft.Json" publicKeyToken="30ad4fe6b2a6aeed" culture="neutral"/>
<bindingRedirect oldVersion="0.0.0.0-9.0.0.0" newVersion="9.0.0.0"/>
</dependentAssembly>
</assemblyBinding>
</runtime>
</configuration>

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

@ -0,0 +1,184 @@
using Microsoft.Azure.WebJobs;
using Microsoft.Azure.WebJobs.Host;
using Newtonsoft.Json;
using System;
using Newtonsoft.Json.Linq;
using Microsoft.Azure.Devices.Shared;
using Microsoft.Azure.WebJobs.Extensions.IoTHub;
namespace SampleFunctions
{
public class Functions
{
// Write some messages
[NoAutomaticTrigger]
public void WriteMessageFromC2D([IoTCloudToDevice] ICollector<string> output)
{
var item = new
{
DeviceId = "receiverBob",
MessageId = "1",
Message = "Hello"
};
output.Add(JsonConvert.SerializeObject(item));
item = new
{
DeviceId = "receiverBob",
MessageId = "2",
Message = "From"
};
output.Add(JsonConvert.SerializeObject(item));
item = new
{
DeviceId = "receiverBob",
MessageId = "3",
Message = "Cloud"
};
output.Add(JsonConvert.SerializeObject(item));
}
// Write some messages
[NoAutomaticTrigger]
public void WriteMessageFromC2DArg(string deviceId, // from trigger
[IoTCloudToDevice(DeviceId = "{deviceId}", Connection = "IoTConnectionString")] ICollector<string> output)
{
var item = new
{
DeviceId = deviceId,
MessageId = "1",
Message = "telemetry data point"
};
output.Add(JsonConvert.SerializeObject(item));
}
// Write some messages
[NoAutomaticTrigger]
public void DirectInvokeMethod(string deviceId, // from trigger
[IoTDirectMethod(DeviceId = "{deviceId}", Connection = "IoTConnectionString")] ICollector<string> output)
{
var item = new
{
DeviceId = deviceId,
InvokeId = "1",
MethodName = "writeLine"
};
output.Add(JsonConvert.SerializeObject(item));
item = new
{
DeviceId = deviceId,
InvokeId = "2",
MethodName = "writeLine"
};
output.Add(JsonConvert.SerializeObject(item));
item = new
{
DeviceId = deviceId,
InvokeId = "3",
MethodName = "writeLine"
};
output.Add(JsonConvert.SerializeObject(item));
}
// Write some messages
[NoAutomaticTrigger]
public void SetDeviceTwin(string deviceId, // from trigger
[IoTSetDeviceTwin(DeviceId = "{deviceId}", Connection = "IoTConnectionString")] ICollector<string> output)
{
var item2 = new
{
DeviceId = deviceId,
UpdateId = "2",
Patch = new
{
properties = new
{
desired = new
{
telemetryConfig = new
{
configId = Guid.NewGuid().ToString()
}
}
}
}
};
output.Add(JsonConvert.SerializeObject(item2));
var item = new
{
DeviceId = deviceId,
UpdateId = "1",
Patch = new
{
tags = new
{
location = new
{
region = "US",
plant = "Redmond43"
}
}
}
};
output.Add(JsonConvert.SerializeObject(item));
var item3 = new
{
DeviceId = deviceId,
UpdateId = "3",
Patch = new
{
properties = new
{
desired = new
{
telemetryConfig = new
{
configId = Guid.NewGuid().ToString()
}
}
}
}
};
output.Add(JsonConvert.SerializeObject(item3));
}
// Write some messages
[NoAutomaticTrigger]
public void GetDeviceTwin(string deviceId, // from trigger
[IoTGetDeviceTwin(DeviceId = "{deviceId}", Connection = "IoTConnectionString")]JObject result,
TraceWriter log)
{
log.Info(JsonConvert.SerializeObject(result));
}
[NoAutomaticTrigger]
public void GetDeviceTwinTwinObject(string deviceId, // from trigger
[IoTGetDeviceTwin(DeviceId = "{deviceId}", Connection = "IoTConnectionString")]Twin result,
TraceWriter log)
{
log.Info(result.ToJson());
}
#if false
#region Using 2nd extensions
// Bind to input as rich type:
// BindToInput<SampleItem> --> item
[NoAutomaticTrigger]
public void Reader3(
string name, // from trigger
[Sample(Name = "{name}")] CustomType<int> item,
TextWriter log)
{
log.WriteLine($"Via custom type {item.Name}:{item.Value}");
}
#endregion
#endif
}
}

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

@ -0,0 +1,60 @@
// Copyright (c) .NET Foundation. All rights reserved.
// Licensed under the MIT License. See License.txt in the project root for license information.
using Microsoft.Azure.WebJobs;
using SampleFunctions;
using System;
using IoTHubExtension = Microsoft.Azure.WebJobs.Extensions.IoTHub;
namespace Host
{
// WebJobs is .NET 4.6
class Program
{
static void Main(string[] args)
{
var config = new JobHostConfiguration();
config.DashboardConnectionString = null;
// apply config before creating the host.
var cloudToDeviceExtension = new IoTHubExtension.Config.IoTCloudToDeviceExtension();
config.AddExtension(cloudToDeviceExtension);
var directMethodExtension = new IoTHubExtension.Config.IoTDirectMethodExtension();
config.AddExtension(directMethodExtension);
var setDeviceTwinExtension = new IoTHubExtension.Config.IoTSetDeviceTwinExtension();
config.AddExtension(setDeviceTwinExtension);
var getDeviceTwinExtension = new IoTHubExtension.Config.IoTGetDeviceTwinExtension();
config.AddExtension(getDeviceTwinExtension);
// Debug diagnostics!
config.CreateMetadataProvider().DebugDumpGraph(Console.Out);
var host = new JobHost(config);
//Test some invocations.
//var method = typeof(Functions).GetMethod("WriteMessageFromC2D");
//host.Call(method);
var method = typeof(Functions).GetMethod("WriteMessageFromC2DArg");
host.Call(method, new { deviceId = "receiverBob" });
//Test some invocations.
method = typeof(Functions).GetMethod("DirectInvokeMethod");
host.Call(method, new { deviceId = "receiverAlice" });
//// Test some invocations.
method = typeof(Functions).GetMethod("SetDeviceTwin");
host.Call(method, new { deviceId = "receiverBob" });
//// Test some invocations.
method = typeof(Functions).GetMethod("GetDeviceTwinTwinObject");
host.Call(method, new { deviceId = "receiverCarol", messageId = "123" });
// host.RunAndBlock();
}
}
}

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

@ -0,0 +1,36 @@
using System.Reflection;
using System.Runtime.CompilerServices;
using System.Runtime.InteropServices;
// General Information about an assembly is controlled through the following
// set of attributes. Change these attribute values to modify the information
// associated with an assembly.
[assembly: AssemblyTitle("Webjobs.Extensions.IoTHub.Tests")]
[assembly: AssemblyDescription("")]
[assembly: AssemblyConfiguration("")]
[assembly: AssemblyCompany("")]
[assembly: AssemblyProduct("Webjobs.Extensions.IoTHub.Tests")]
[assembly: AssemblyCopyright("Copyright © 2017")]
[assembly: AssemblyTrademark("")]
[assembly: AssemblyCulture("")]
// Setting ComVisible to false makes the types in this assembly not visible
// to COM components. If you need to access a type in this assembly from
// COM, set the ComVisible attribute to true on that type.
[assembly: ComVisible(false)]
// The following GUID is for the ID of the typelib if this project is exposed to COM
[assembly: Guid("623c71b0-8b5e-46b4-83ae-6ce9e3e4b13d")]
// Version information for an assembly consists of the following four values:
//
// Major Version
// Minor Version
// Build Number
// Revision
//
// You can specify all the values or you can default the Build and Revision Numbers
// by using the '*' as shown below:
// [assembly: AssemblyVersion("1.0.*")]
[assembly: AssemblyVersion("1.0.0.0")]
[assembly: AssemblyFileVersion("1.0.0.0")]

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

@ -0,0 +1,134 @@
<?xml version="1.0" encoding="utf-8"?>
<Project ToolsVersion="15.0" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
<Import Project="$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props" Condition="Exists('$(MSBuildExtensionsPath)\$(MSBuildToolsVersion)\Microsoft.Common.props')" />
<PropertyGroup>
<Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
<Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
<ProjectGuid>{623C71B0-8B5E-46B4-83AE-6CE9E3E4B13D}</ProjectGuid>
<OutputType>Exe</OutputType>
<RootNamespace>Webjobs.Extensions.IoTHub.Tests</RootNamespace>
<AssemblyName>Webjobs.Extensions.IoTHub.Tests</AssemblyName>
<TargetFrameworkVersion>v4.6</TargetFrameworkVersion>
<FileAlignment>512</FileAlignment>
<AutoGenerateBindingRedirects>true</AutoGenerateBindingRedirects>
<TargetFrameworkProfile />
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugSymbols>true</DebugSymbols>
<DebugType>full</DebugType>
<Optimize>false</Optimize>
<OutputPath>bin\Debug\</OutputPath>
<DefineConstants>DEBUG;TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<PlatformTarget>AnyCPU</PlatformTarget>
<DebugType>pdbonly</DebugType>
<Optimize>true</Optimize>
<OutputPath>bin\Release\</OutputPath>
<DefineConstants>TRACE</DefineConstants>
<ErrorReport>prompt</ErrorReport>
<WarningLevel>4</WarningLevel>
</PropertyGroup>
<ItemGroup>
<Reference Include="Microsoft.Azure.Amqp, Version=2.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Amqp.2.0.6\lib\net45\Microsoft.Azure.Amqp.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Devices, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Devices.1.2.9\lib\net451\Microsoft.Azure.Devices.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.Devices.Shared, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.Devices.Shared.1.0.11\lib\net45\Microsoft.Azure.Devices.Shared.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.KeyVault.Core, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.KeyVault.Core.1.0.0\lib\net40\Microsoft.Azure.KeyVault.Core.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.Core.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Azure.WebJobs.Host, Version=2.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Azure.WebJobs.2.1.0-beta1\lib\net45\Microsoft.Azure.WebJobs.Host.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Edm, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Edm.5.6.4\lib\net40\Microsoft.Data.Edm.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.OData, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.OData.5.6.4\lib\net40\Microsoft.Data.OData.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Data.Services.Client, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Data.Services.Client.5.6.4\lib\net40\Microsoft.Data.Services.Client.dll</HintPath>
</Reference>
<Reference Include="Microsoft.Extensions.Logging.Abstractions, Version=1.1.1.0, Culture=neutral, PublicKeyToken=adb9793829ddae60, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.Extensions.Logging.Abstractions.1.1.1\lib\netstandard1.1\Microsoft.Extensions.Logging.Abstractions.dll</HintPath>
</Reference>
<Reference Include="Microsoft.WindowsAzure.Storage, Version=7.2.1.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\WindowsAzure.Storage.7.2.1\lib\net40\Microsoft.WindowsAzure.Storage.dll</HintPath>
</Reference>
<Reference Include="Newtonsoft.Json, Version=9.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
<HintPath>..\..\packages\Newtonsoft.Json.9.0.1\lib\net45\Newtonsoft.Json.dll</HintPath>
</Reference>
<Reference Include="PCLCrypto, Version=2.0.0.0, Culture=neutral, PublicKeyToken=d4421c8a4786956c, processorArchitecture=MSIL">
<HintPath>..\..\packages\PCLCrypto.2.0.147\lib\net45\PCLCrypto.dll</HintPath>
</Reference>
<Reference Include="PInvoke.BCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.BCrypt.0.3.2\lib\net40\PInvoke.BCrypt.dll</HintPath>
</Reference>
<Reference Include="PInvoke.Kernel32, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Kernel32.0.3.2\lib\net40\PInvoke.Kernel32.dll</HintPath>
</Reference>
<Reference Include="PInvoke.NCrypt, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.NCrypt.0.3.2\lib\net40\PInvoke.NCrypt.dll</HintPath>
</Reference>
<Reference Include="PInvoke.Windows.Core, Version=0.3.0.0, Culture=neutral, PublicKeyToken=9e300f9f87f04a7a, processorArchitecture=MSIL">
<HintPath>..\..\packages\PInvoke.Windows.Core.0.3.2\lib\portable-net45+win+wpa81+MonoAndroid10+xamarinios10+MonoTouch10\PInvoke.Windows.Core.dll</HintPath>
</Reference>
<Reference Include="System" />
<Reference Include="System.ComponentModel.Composition" />
<Reference Include="System.Core" />
<Reference Include="System.Diagnostics.DiagnosticSource, Version=4.0.1.0, Culture=neutral, PublicKeyToken=cc7b13ffcd2ddd51, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Diagnostics.DiagnosticSource.4.3.0\lib\portable-net45+win8+wpa81\System.Diagnostics.DiagnosticSource.dll</HintPath>
</Reference>
<Reference Include="System.IO.Compression" />
<Reference Include="System.Net.Http.Formatting, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Client.5.2.3\lib\net45\System.Net.Http.Formatting.dll</HintPath>
</Reference>
<Reference Include="System.Numerics" />
<Reference Include="System.Runtime.InteropServices.RuntimeInformation, Version=4.0.1.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Runtime.InteropServices.RuntimeInformation.4.3.0\lib\net45\System.Runtime.InteropServices.RuntimeInformation.dll</HintPath>
</Reference>
<Reference Include="System.Runtime.Serialization" />
<Reference Include="System.Spatial, Version=5.6.4.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\System.Spatial.5.6.4\lib\net40\System.Spatial.dll</HintPath>
</Reference>
<Reference Include="System.Web.Http, Version=5.2.3.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
<HintPath>..\..\packages\Microsoft.AspNet.WebApi.Core.5.2.3\lib\net45\System.Web.Http.dll</HintPath>
</Reference>
<Reference Include="System.Xml.Linq" />
<Reference Include="System.Data.DataSetExtensions" />
<Reference Include="Microsoft.CSharp" />
<Reference Include="System.Data" />
<Reference Include="System.Net.Http" />
<Reference Include="System.Xml" />
<Reference Include="Validation, Version=2.2.0.0, Culture=neutral, PublicKeyToken=2fc06f0d701809a7, processorArchitecture=MSIL">
<HintPath>..\..\packages\Validation.2.2.8\lib\dotnet\Validation.dll</HintPath>
</Reference>
</ItemGroup>
<ItemGroup>
<Compile Include="Functions.cs" />
<Compile Include="Program.cs" />
<Compile Include="Properties\AssemblyInfo.cs" />
</ItemGroup>
<ItemGroup>
<None Include="App.config" />
<None Include="packages.config" />
</ItemGroup>
<ItemGroup>
<ProjectReference Include="..\..\src\WebJobs.Extensions.IoTHub\WebJobs.Extensions.IoTHub.csproj">
<Project>{24e41ed3-0f5a-47da-a32e-79a8fe9d6588}</Project>
<Name>WebJobs.Extensions.IoTHub</Name>
</ProjectReference>
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>

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

@ -0,0 +1,58 @@
<?xml version="1.0" encoding="utf-8"?>
<packages>
<package id="Microsoft.AspNet.WebApi.Client" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.AspNet.WebApi.Core" version="5.2.3" targetFramework="net452" />
<package id="Microsoft.Azure.Amqp" version="2.0.6" targetFramework="net452" />
<package id="Microsoft.Azure.Devices" version="1.2.9" targetFramework="net452" />
<package id="Microsoft.Azure.Devices.Shared" version="1.0.11" targetFramework="net452" />
<package id="Microsoft.Azure.KeyVault.Core" version="1.0.0" targetFramework="net452" />
<package id="Microsoft.Azure.WebJobs" version="2.1.0-beta1" targetFramework="net452" />
<package id="Microsoft.Azure.WebJobs.Core" version="2.1.0-beta1" targetFramework="net452" />
<package id="Microsoft.Data.Edm" version="5.6.4" targetFramework="net452" />
<package id="Microsoft.Data.OData" version="5.6.4" targetFramework="net452" />
<package id="Microsoft.Data.Services.Client" version="5.6.4" targetFramework="net452" />
<package id="Microsoft.Extensions.Logging.Abstractions" version="1.1.1" targetFramework="net452" />
<package id="Microsoft.NETCore.Platforms" version="1.1.0" targetFramework="net452" />
<package id="NETStandard.Library" version="1.6.1" targetFramework="net452" />
<package id="Newtonsoft.Json" version="9.0.1" targetFramework="net452" />
<package id="PCLCrypto" version="2.0.147" targetFramework="net452" />
<package id="PInvoke.BCrypt" version="0.3.2" targetFramework="net452" />
<package id="PInvoke.Kernel32" version="0.3.2" targetFramework="net452" />
<package id="PInvoke.NCrypt" version="0.3.2" targetFramework="net452" />
<package id="PInvoke.Windows.Core" version="0.3.2" targetFramework="net452" />
<package id="runtime.any.System.Globalization.Calendars" version="4.3.0" targetFramework="net452" />
<package id="System.Collections" version="4.3.0" targetFramework="net452" />
<package id="System.Collections.Concurrent" version="4.3.0" targetFramework="net452" />
<package id="System.Diagnostics.Debug" version="4.3.0" targetFramework="net452" />
<package id="System.Diagnostics.DiagnosticSource" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Diagnostics.Tools" version="4.3.0" targetFramework="net452" />
<package id="System.Diagnostics.Tracing" version="4.3.0" targetFramework="net452" />
<package id="System.Globalization" version="4.3.0" targetFramework="net452" />
<package id="System.IO" version="4.3.0" targetFramework="net452" />
<package id="System.IO.Compression" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Linq" version="4.3.0" targetFramework="net452" />
<package id="System.Linq.Expressions" version="4.3.0" targetFramework="net452" />
<package id="System.Net.Http" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Net.Primitives" version="4.3.0" targetFramework="net452" />
<package id="System.ObjectModel" version="4.3.0" targetFramework="net452" />
<package id="System.Reflection" version="4.3.0" targetFramework="net452" />
<package id="System.Reflection.Extensions" version="4.3.0" targetFramework="net452" />
<package id="System.Reflection.Primitives" version="4.3.0" targetFramework="net452" />
<package id="System.Resources.ResourceManager" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.Extensions" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.InteropServices" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.InteropServices.RuntimeInformation" version="4.3.0" targetFramework="net452" />
<package id="System.Runtime.Numerics" version="4.3.0" targetFramework="net452" />
<package id="System.Spatial" version="5.6.4" targetFramework="net452" />
<package id="System.Text.Encoding" version="4.3.0" targetFramework="net452" />
<package id="System.Text.Encoding.Extensions" version="4.3.0" targetFramework="net452" />
<package id="System.Text.RegularExpressions" version="4.3.0" targetFramework="net452" />
<package id="System.Threading" version="4.3.0" targetFramework="net452" />
<package id="System.Threading.Tasks" version="4.3.0" targetFramework="net452" />
<package id="System.Threading.Timer" version="4.3.0" targetFramework="net452" />
<package id="System.Xml.ReaderWriter" version="4.3.0" targetFramework="net452" requireReinstallation="true" />
<package id="System.Xml.XDocument" version="4.3.0" targetFramework="net452" />
<package id="Validation" version="2.2.8" targetFramework="net452" />
<package id="WindowsAzure.Storage" version="7.2.1" targetFramework="net452" />
</packages>