From 00a86984a939e71449894263368d6899d867788f Mon Sep 17 00:00:00 2001
From: wanggang <76527413@qq.com>
Date: Mon, 11 Nov 2019 15:12:20 +0800
Subject: [PATCH] update
Former-commit-id: 01fd0374e8f9ad8d90c1fed52a4698e1b1b762d7
---
.../Views/Shared/_Footer.cshtml | 4 +-
.../Views/Shared/_Header.cshtml | 1 +
projects/Infrastructure/libman.json | 5 ++
.../wwwroot/lib/toastr/toastr.min.css | 1 +
.../wwwroot/lib/toastr/toastr.min.js | 2 +
.../IoT.Shared/Application/Models/Methods.cs | 7 +-
.../Services/IoTCenter/IoTCenterHub.cs | 6 +-
.../Services/IoTNode/IoTNodeClient.cs | 9 +--
.../IoTCenter/Controllers/AppController.cs | 6 +-
projects/IoTCenter/Views/Home/Index.cshtml | 1 -
projects/IoTCenter/Views/Home/Node.cshtml | 2 +-
projects/IoTCenter/Views/Home/Nodes.cshtml | 1 -
projects/IoTCenter/iotcenter.db | Bin 430080 -> 430080 bytes
.../Assets/StreamingAssets/libman.json | 5 ++
.../StreamingAssets/wwwroot/css/app.css | 3 +
.../Assets/StreamingAssets/wwwroot/index.html | 1 -
.../Assets/StreamingAssets/wwwroot/js/node.js | 60 ++++++++++--------
.../StreamingAssets/wwwroot/js/product.js | 13 +++-
.../wwwroot/lib/toastr/toastr.min.css | 1 +
.../wwwroot/lib/toastr/toastr.min.js | 2 +
.../Assets/StreamingAssets/wwwroot/node.html | 4 +-
.../Assets/StreamingAssets/wwwroot/nodes.html | 1 -
.../StreamingAssets/wwwroot/product.html | 2 +
projects/IoTNode/iotnode.db | Bin 462848 -> 462848 bytes
projects/lib/package.json | 2 +-
25 files changed, 91 insertions(+), 48 deletions(-)
create mode 100644 projects/Infrastructure/wwwroot/lib/toastr/toastr.min.css
create mode 100644 projects/Infrastructure/wwwroot/lib/toastr/toastr.min.js
create mode 100644 projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.css
create mode 100644 projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.js
diff --git a/projects/Infrastructure/Views/Shared/_Footer.cshtml b/projects/Infrastructure/Views/Shared/_Footer.cshtml
index 598c52f1..c42c6e92 100644
--- a/projects/Infrastructure/Views/Shared/_Footer.cshtml
+++ b/projects/Infrastructure/Views/Shared/_Footer.cshtml
@@ -7,7 +7,6 @@
-@**@
@@ -18,4 +17,5 @@
-
\ No newline at end of file
+
+
\ No newline at end of file
diff --git a/projects/Infrastructure/Views/Shared/_Header.cshtml b/projects/Infrastructure/Views/Shared/_Header.cshtml
index 4ad110e9..56ea6dfe 100644
--- a/projects/Infrastructure/Views/Shared/_Header.cshtml
+++ b/projects/Infrastructure/Views/Shared/_Header.cshtml
@@ -13,4 +13,5 @@
+
\ No newline at end of file
diff --git a/projects/Infrastructure/libman.json b/projects/Infrastructure/libman.json
index aafe302d..d7bbd6a5 100644
--- a/projects/Infrastructure/libman.json
+++ b/projects/Infrastructure/libman.json
@@ -146,6 +146,11 @@
"library": "../lib/node_modules/linq/",
"destination": "wwwroot/lib/linq/",
"files": [ "linq.min.js" ]
+ },
+ {
+ "library": "../lib/node_modules/toastr/build",
+ "destination": "wwwroot/lib/toastr/",
+ "files": [ "toastr.min.css", "toastr.min.js" ]
}
]
}
\ No newline at end of file
diff --git a/projects/Infrastructure/wwwroot/lib/toastr/toastr.min.css b/projects/Infrastructure/wwwroot/lib/toastr/toastr.min.css
new file mode 100644
index 00000000..064afd07
--- /dev/null
+++ b/projects/Infrastructure/wwwroot/lib/toastr/toastr.min.css
@@ -0,0 +1 @@
+.toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#FFF}.toast-message a:hover{color:#CCC;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#FFF;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);line-height:1}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}.rtl .toast-close-button{left:-.3em;float:left;right:.3em}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999;pointer-events:none}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#FFF;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>div.rtl{direction:rtl;padding:15px 50px 15px 15px;background-position:right 15px center}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin-left:auto;margin-right:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin-left:auto;margin-right:auto}.toast{background-color:#030303}.toast-success{background-color:#51A351}.toast-error{background-color:#BD362F}.toast-info{background-color:#2F96B4}.toast-warning{background-color:#F89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}}
\ No newline at end of file
diff --git a/projects/Infrastructure/wwwroot/lib/toastr/toastr.min.js b/projects/Infrastructure/wwwroot/lib/toastr/toastr.min.js
new file mode 100644
index 00000000..06e4814f
--- /dev/null
+++ b/projects/Infrastructure/wwwroot/lib/toastr/toastr.min.js
@@ -0,0 +1,2 @@
+!function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return g({type:O.error,iconClass:m().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=m()),v=e("#"+t.containerId),v.length?v:(n&&(v=d(t)),v)}function o(e,t,n){return g({type:O.info,iconClass:m().iconClasses.info,message:e,optionsOverride:n,title:t})}function s(e){C=e}function i(e,t,n){return g({type:O.success,iconClass:m().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return g({type:O.warning,iconClass:m().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e,t){var o=m();v||n(o),u(e,o,t)||l(o)}function c(t){var o=m();return v||n(o),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function l(t){for(var n=v.children(),o=n.length-1;o>=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("
").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e(""),M=e(""),B=e(""),q=e(""),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.4",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)});
+//# sourceMappingURL=toastr.js.map
diff --git a/projects/IoT.Shared/Application/Models/Methods.cs b/projects/IoT.Shared/Application/Models/Methods.cs
index 10dbebbb..c837f42a 100644
--- a/projects/IoT.Shared/Application/Models/Methods.cs
+++ b/projects/IoT.Shared/Application/Models/Methods.cs
@@ -5,10 +5,11 @@
public const string ServerToClient = nameof(ServerToClient);
public const string ClientToServer = nameof(ClientToServer);
- public const string ExecApi = nameof(ExecApi);
+ public const string ExecApiRequest = nameof(ExecApiRequest);
+ public const string ExecApiResponse = nameof(ExecApiResponse);
+ public const string ExecSceneRequest = nameof(ExecSceneRequest);
+ public const string ExecSceneRsponse = nameof(ExecSceneRsponse);
public const string ExecCommand = nameof(ExecCommand);
- public const string ExecScene = nameof(ExecScene);
- public const string ApiCallback = nameof(ApiCallback);
public const string UpdateNodeResponse = nameof(UpdateNodeResponse); //上传节点
public const string UpdateProductResponse = nameof(UpdateProductResponse);//上传产品
diff --git a/projects/IoT.Shared/Services/IoTCenter/IoTCenterHub.cs b/projects/IoT.Shared/Services/IoTCenter/IoTCenterHub.cs
index bfd6681e..48e71271 100644
--- a/projects/IoT.Shared/Services/IoTCenter/IoTCenterHub.cs
+++ b/projects/IoT.Shared/Services/IoTCenter/IoTCenterHub.cs
@@ -256,7 +256,11 @@ namespace IoTCenter.Services
this._dataService.Delete(model);
}
//
- else if (method == Methods.ApiCallback)
+ else if (method == Methods.ExecApiResponse)
+ {
+ this.ServerToClient(method, message, to, from);
+ }
+ else if (method == Methods.ExecSceneRsponse)
{
this.ServerToClient(method, message, to, from);
}
diff --git a/projects/IoT.Shared/Services/IoTNode/IoTNodeClient.cs b/projects/IoT.Shared/Services/IoTNode/IoTNodeClient.cs
index 554e25e2..b24a1fe4 100644
--- a/projects/IoT.Shared/Services/IoTNode/IoTNodeClient.cs
+++ b/projects/IoT.Shared/Services/IoTNode/IoTNodeClient.cs
@@ -334,17 +334,16 @@ namespace IoT.Shared.Services
dataService.Delete(model);
this.ClientToServer(method, model, null);
}
- else if (method == Methods.ExecApi)
+ else if (method == Methods.ExecApiRequest)
{
var cfg = scope.ServiceProvider.GetService();
var port = cfg["server.urls"].Split(':')[2];
var url = $"http://localhost:{port}{message.FromJson()}";
var httpClient = scope.ServiceProvider.GetService().CreateClient();
var result = httpClient.GetStringAsync(url).Result;
- this.ClientToServer(Methods.ApiCallback, result, from);
+ this.ClientToServer(Methods.ExecApiResponse, result, from);
}
- ///////////////////////////////////////////////////////////
- else if (method == Methods.ExecScene)
+ else if (method == Methods.ExecSceneRequest)
{
var sceneId = message.FromJson();
var sceneCommandRepo = scope.ServiceProvider.GetService>();
@@ -355,7 +354,9 @@ namespace IoT.Shared.Services
.Select(o => o.Command)
.ToList();
this.ExecCommands(commands);
+ this.ClientToServer(Methods.ExecSceneRsponse, null, from);
}
+ ///////////////////////////////////////////////////////////
else if (method == Methods.ExecCommand)
{
var id = message.FromJson();
diff --git a/projects/IoTCenter/Controllers/AppController.cs b/projects/IoTCenter/Controllers/AppController.cs
index e6d3123d..7ada4eaa 100644
--- a/projects/IoTCenter/Controllers/AppController.cs
+++ b/projects/IoTCenter/Controllers/AppController.cs
@@ -147,7 +147,7 @@ namespace IoTCenter.Controllers
var message = $"{method}{query2}";
var group = device.Node.Number;
- this._hub.ServerToClient(Methods.ExecApi, message, group, connectionId);
+ this._hub.ServerToClient(Methods.ExecApiRequest, message, group, connectionId);
}
return Json(ApiResponse.AsyncSuccess());
}
@@ -165,7 +165,7 @@ namespace IoTCenter.Controllers
{
var userName = User.Identity.IsAuthenticated ? User.Identity.Name : this._jwtHelper.GetPayload(token)["UserName"].ToString();
var scene = this._sceneRepo.ReadOnlyTable().Include(o => o.Node).FirstOrDefault(o => o.Id == id);
- this._hub.ServerToClient(Methods.ExecScene, id, scene.Node.Number, connectionId);
+ this._hub.ServerToClient(Methods.ExecSceneRequest, id, scene.Node.Number, connectionId);
return Json(ApiResponse.AsyncSuccess());
}
catch (Exception ex)
@@ -397,7 +397,7 @@ namespace IoTCenter.Controllers
{
var api = device.Product.Apis.FirstOrDefault(o => o.Command == command);
var message = $"{api.Path}{api.Command}?number={device.Number}";
- this._hub.Clients.Group(device.Node.Number).SendAsync(Methods.ServerToClient, Methods.ExecApi, message, connectionId);
+ this._hub.Clients.Group(device.Node.Number).SendAsync(Methods.ServerToClient, Methods.ExecApiRequest, message, connectionId);
}
catch (Exception ex)
{
diff --git a/projects/IoTCenter/Views/Home/Index.cshtml b/projects/IoTCenter/Views/Home/Index.cshtml
index 0e9375e0..d3d32b1f 100644
--- a/projects/IoTCenter/Views/Home/Index.cshtml
+++ b/projects/IoTCenter/Views/Home/Index.cshtml
@@ -69,7 +69,6 @@
console.log(connectionId);
});
connection.onclose(function (err) {
- console.error(err);
setTimeout(connect, 15 * 1000);
});
connection.on("ServerToClient", function (method, json, from) {
diff --git a/projects/IoTCenter/Views/Home/Node.cshtml b/projects/IoTCenter/Views/Home/Node.cshtml
index 3ee17009..019cc88d 100644
--- a/projects/IoTCenter/Views/Home/Node.cshtml
+++ b/projects/IoTCenter/Views/Home/Node.cshtml
@@ -146,7 +146,7 @@
{{model.Name}}
-
+
diff --git a/projects/IoTCenter/Views/Home/Nodes.cshtml b/projects/IoTCenter/Views/Home/Nodes.cshtml
index 7cb61789..70c9a869 100644
--- a/projects/IoTCenter/Views/Home/Nodes.cshtml
+++ b/projects/IoTCenter/Views/Home/Nodes.cshtml
@@ -66,7 +66,6 @@
console.log(connectionId);
});
connection.onclose(function (err) {
- console.error(err);
setTimeout(connect, 15 * 1000);
});
connection.on("ServerToClient", function (method, json, from) {
diff --git a/projects/IoTCenter/iotcenter.db b/projects/IoTCenter/iotcenter.db
index 5846e47c6888af858a80f6b941a6e3ab7cb3560d..bf88f9f34df2e8fdb5564633a50138777155c8f2 100644
GIT binary patch
delta 1903
zcmb_cU1%Le6yCje@7~Q#%qFB-TB(U9wGo^+J3BKw0~WJ8JClgf*5I{ZK_d0iMANGI
zQEML>ZPHTk=cRNJ`cM$Gf-xmG=Eh<%^hFSBU!?jX)Y2qWedvoXBE;F7DuRgnP*@mt
z_k7>^&YbU@sWV%r^s``EEl$qeWw>YEUDZ}7T(T!uEE{*5PMHdcAn_0ggD?OXQVAkK
zIbb{#ic7&n;IEuMzxw_h$|XNtFuU;6W(swjvY;X1A@cwY!WiH{LmAbtF@j7+fv+f}
z8&I!~Jhg0EHEYN`=MH2@n%j{tH)Kh%2u|CA
zMj*n0ekGBv4st?q7^H!O$T$pT00fC6fIXi9<`V%zpF<>L?8_*kX`rAn#5lcI!F2aS
z6#}NX0tjh01enCoCnODgg3`#3JkEjSSX+!l7%(hjzzK(OL`5Vx!f7N#9t>2>bgL8u
zSSqetB?ypV#Cc4phoZ=@t@q^$tY+;tx4B0MMoNXcrHaNBU=(YiX@^D3g``Sg!EqLc
zXKB?dW}&S8qy$mvg=rVaA)?C(7|`+pfCQH^j1i@tpT)PCx?VR@mMZH;`lq)4k~R;m
zj;aO!XkWaVvpUjwoOA2WFVrdOCZ0dD;3nc*v-8%sbS7F#hGC@sYxqU`Z?-s{lsfYL
zEk)#XJ5M&;Q`+hL)_kqFxAtsD{%bpFzhrisL4q&qgC>pXK{gJY^r!#)np_gWsL42%oX!lrUeB29G-#&5ULeuv%Y{)n6kE|tjT3%KiK9$|6hpKKD)~?#ve*6yEA#X&kpja
V$4_4CvtP1!4+?5O_t|{|VF&?6Cj<
delta 281
zcmZozAk_dwTNqgcHnSM~k>6&($npTnVqy`HGh+YG!25>%KgVL8AnsORWzJ2=iv*K%Mo*dF7+bd7DYfxz|c|J|8bEf%vFD1b1;lm|>K5Y{9I7B-M+oUf+~
zC@_2QaA{Ypa(v}`v^_(C`4rfQ_W$b4+yASxux5a@FLDq7>T72?z_Og>0BZw_
zDC-A?=^PGh%Iv0WN7$lRKWtVM*vC5kgDcw=?tBBDPzG^fc}8K$>6hHtbi_<7%%8S)
zK5t$Abk{PjoYIPy4NXsWter0C&Zfd%q7PK8EI!@Voz0xZT+hg2dbvAWK8vZIvElYt
I?rdTn0H8oxLI3~&
diff --git a/projects/IoTClient/Assets/StreamingAssets/libman.json b/projects/IoTClient/Assets/StreamingAssets/libman.json
index 9a6ba4c9..a5d6a931 100644
--- a/projects/IoTClient/Assets/StreamingAssets/libman.json
+++ b/projects/IoTClient/Assets/StreamingAssets/libman.json
@@ -98,6 +98,11 @@
"library": "../../../lib/node_modules/linq/",
"destination": "wwwroot/lib/linq/",
"files": [ "linq.min.js" ]
+ },
+ {
+ "library": "../../../lib/node_modules/toastr/build",
+ "destination": "wwwroot/lib/toastr/",
+ "files": [ "toastr.min.css", "toastr.min.js" ]
}
]
}
\ No newline at end of file
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/css/app.css b/projects/IoTClient/Assets/StreamingAssets/wwwroot/css/app.css
index 1d215876..83b6361c 100644
--- a/projects/IoTClient/Assets/StreamingAssets/wwwroot/css/app.css
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/css/app.css
@@ -10,3 +10,6 @@
.page {
/*background-color: white;*/
}
+.toast-top-center .toast {
+ left: auto !important;
+}
\ No newline at end of file
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/index.html b/projects/IoTClient/Assets/StreamingAssets/wwwroot/index.html
index b669968a..1cefe1a4 100644
--- a/projects/IoTClient/Assets/StreamingAssets/wwwroot/index.html
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/index.html
@@ -89,7 +89,6 @@
console.log(connectionId);
});
connection.onclose(function (err) {
- console.error(err);
setTimeout(connect, 15 * 1000);
});
connection.on("ServerToClient", function (method, json, from) {
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/node.js b/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/node.js
index 95e43809..79ff393f 100644
--- a/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/node.js
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/node.js
@@ -21,6 +21,8 @@ var volume = 0.5;
if (isApp) {
Framework7.use(Framework7Vue);
}
+toastr.options.timeOut = 500;
+toastr.options.positionClass = "toast-top-center";
/*fun*/
function alert(message,title) {
if (isApp) {
@@ -31,13 +33,9 @@ function alert(message,title) {
alert(message);
}
}
-function hideLoading() {
- if (isApp) {
-
- }
- else {
- $('.overlay').hide();
- }
+function hideLoading(message) {
+ toastr.success(message||'请求成功');
+ $('.overlay').hide();
}
function loadData() {
var formData = new FormData();
@@ -57,7 +55,7 @@ function loadData() {
}
})
.catch(function (error) {
- alert(error)
+ toastr.error('数据加载失败!');
})
.then(hideLoading);
}
@@ -183,7 +181,7 @@ function ajax(url, data, type) {
data: data,
success: AjaxCallBack
}).fail(function (result) {
- console.log('error');
+ toastr.error('请求发送失败!');
console.log(result);
}).always(function () {
$('.overlay').hide();
@@ -255,19 +253,17 @@ function connect() {
}
if (connection.state === signalR.HubConnectionState.Disconnected) {
connection.start().then(function () {
-
+ toastr.success('客户端与服务器连接成功!');
}).catch(function (err) {
- console.error(err.toString());
+ toastr.error('客户端与服务器连接失败!');
setTimeout(connect, 15 * 1000);
});
}
}
connection.on('Connected', function (id) {
connectionId = id;
- console.log(connectionId);
});
connection.onclose(function (err) {
- console.error(err);
setTimeout(connect, 15 * 1000);
});
connection.on("ServerToClient", function (method, json, to,from) {
@@ -276,23 +272,32 @@ connection.on("ServerToClient", function (method, json, to,from) {
});
function onMessage(method, json,to, from) {
var item = JSON.parse(json);
- if (method === 'ApiCallback') {
+ if (method === 'ExecApiRsponse') {
console.log(json);
+ toastr.success('操作调用成功');
}
- else if
- (method == 'DataEntityInserted' || method == 'DataEntityUpdated') {
- var device = Enumerable.from(vm.model.Devices).firstOrDefault(function (o) { return o.Id === item.DeviceId; })
- if (device) {
- updateItem(device.Data, item);
- }
- }
- else if (method == 'SceneEntityInserted' ||method == 'SceneEntityUpdated') {
- updateItem(vm.model.Scenes, item);
+ else if (method === 'ExecSceneRsponse') {
+ console.log(json);
+ toastr.success('场景调用成功');
}
- else if (method == 'SceneEntityDeleted') {
- deleteItem(vm.model.Scenes, item);
-
+ else {
+ if(method == 'DataEntityInserted' || method == 'DataEntityUpdated') {
+ var device = Enumerable.from(vm.model.Devices).firstOrDefault(function (o) { return o.Id === item.DeviceId; })
+ if (device) {
+ updateItem(device.Data, item);
+ toastr.info(device.DisplayName+'更新');
+ }
+ }
+ else if (method == 'SceneEntityInserted' || method == 'SceneEntityUpdated') {
+ updateItem(vm.model.Scenes, item);
+ toastr.info(item.Name+'更新');
+ }
+ else if (method == 'SceneEntityDeleted') {
+ deleteItem(vm.model.Scenes, item);
+ toastr.info(item.Name+'删除');
+ }
}
+
}
/*vue*/
function init() {
@@ -373,6 +378,9 @@ function init() {
CallApi(number, method, query) {
ajax('/App/ExecApi', { token: token, connectionId: connectionId, number: number, method: method, query: query }, 'post');
},
+ GetScenes() {
+ return Enumerable.from(this.model.Scenes).orderBy('o=>o.DisplayOrder').toArray();
+ },
CallScene(id) {
ajax('/App/ExecScene', { token: token, connectionId: connectionId, id: id }, 'post');
},
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/product.js b/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/product.js
index 6a2fa917..c0abf744 100644
--- a/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/product.js
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/js/product.js
@@ -21,6 +21,8 @@ var volume = 0.5;
if (isApp) {
Framework7.use(Framework7Vue);
}
+toastr.options.timeOut = 500;
+toastr.options.positionClass = "toast-top-center";
/*fun*/
function alert(message, title) {
if (isApp) {
@@ -47,6 +49,7 @@ function loadData() {
else {
init();
}
+ toastr.success('数据加载成功!');
})
.catch(function (error) {
alert(error)
@@ -258,7 +261,6 @@ connection.on('Connected', function (id) {
console.log(connectionId);
});
connection.onclose(function (err) {
- console.error(err);
setTimeout(connect, 15 * 1000);
});
connection.on("ServerToClient", function (method, json, from) {
@@ -268,10 +270,17 @@ connection.on("ServerToClient", function (method, json, from) {
function onMessage(method, json, from) {
var item = JSON.parse(json);
if (method == 'DeviceEntityInserted' || method == 'DeviceEntityUpdated') {
+ toastr.info(item.DisplayName+'更新');
updateItem(vm.model.Devices, item);
} else if (method == 'DeviceEntityDeleted') {
deleteItem(vm.model.Devices, item);
-
+ toastr.info(item.DisplayName + '删除');
+ } else if (method == 'DataEntityInserted' || method == 'DataEntityUpdated') {
+ var device = Enumerable.from(vm.model.Devices).firstOrDefault(function (o) { return o.Id === item.DeviceId; })
+ if (device) {
+ updateItem(device.Data, item);
+ toastr.info(device.DisplayName + '更新');
+ }
}
}
/*vue*/
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.css b/projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.css
new file mode 100644
index 00000000..064afd07
--- /dev/null
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.css
@@ -0,0 +1 @@
+.toast-title{font-weight:700}.toast-message{-ms-word-wrap:break-word;word-wrap:break-word}.toast-message a,.toast-message label{color:#FFF}.toast-message a:hover{color:#CCC;text-decoration:none}.toast-close-button{position:relative;right:-.3em;top:-.3em;float:right;font-size:20px;font-weight:700;color:#FFF;-webkit-text-shadow:0 1px 0 #fff;text-shadow:0 1px 0 #fff;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80);line-height:1}.toast-close-button:focus,.toast-close-button:hover{color:#000;text-decoration:none;cursor:pointer;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}.rtl .toast-close-button{left:-.3em;float:left;right:.3em}button.toast-close-button{padding:0;cursor:pointer;background:0 0;border:0;-webkit-appearance:none}.toast-top-center{top:0;right:0;width:100%}.toast-bottom-center{bottom:0;right:0;width:100%}.toast-top-full-width{top:0;right:0;width:100%}.toast-bottom-full-width{bottom:0;right:0;width:100%}.toast-top-left{top:12px;left:12px}.toast-top-right{top:12px;right:12px}.toast-bottom-right{right:12px;bottom:12px}.toast-bottom-left{bottom:12px;left:12px}#toast-container{position:fixed;z-index:999999;pointer-events:none}#toast-container *{-moz-box-sizing:border-box;-webkit-box-sizing:border-box;box-sizing:border-box}#toast-container>div{position:relative;pointer-events:auto;overflow:hidden;margin:0 0 6px;padding:15px 15px 15px 50px;width:300px;-moz-border-radius:3px;-webkit-border-radius:3px;border-radius:3px;background-position:15px center;background-repeat:no-repeat;-moz-box-shadow:0 0 12px #999;-webkit-box-shadow:0 0 12px #999;box-shadow:0 0 12px #999;color:#FFF;opacity:.8;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=80);filter:alpha(opacity=80)}#toast-container>div.rtl{direction:rtl;padding:15px 50px 15px 15px;background-position:right 15px center}#toast-container>div:hover{-moz-box-shadow:0 0 12px #000;-webkit-box-shadow:0 0 12px #000;box-shadow:0 0 12px #000;opacity:1;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=100);filter:alpha(opacity=100);cursor:pointer}#toast-container>.toast-info{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGwSURBVEhLtZa9SgNBEMc9sUxxRcoUKSzSWIhXpFMhhYWFhaBg4yPYiWCXZxBLERsLRS3EQkEfwCKdjWJAwSKCgoKCcudv4O5YLrt7EzgXhiU3/4+b2ckmwVjJSpKkQ6wAi4gwhT+z3wRBcEz0yjSseUTrcRyfsHsXmD0AmbHOC9Ii8VImnuXBPglHpQ5wwSVM7sNnTG7Za4JwDdCjxyAiH3nyA2mtaTJufiDZ5dCaqlItILh1NHatfN5skvjx9Z38m69CgzuXmZgVrPIGE763Jx9qKsRozWYw6xOHdER+nn2KkO+Bb+UV5CBN6WC6QtBgbRVozrahAbmm6HtUsgtPC19tFdxXZYBOfkbmFJ1VaHA1VAHjd0pp70oTZzvR+EVrx2Ygfdsq6eu55BHYR8hlcki+n+kERUFG8BrA0BwjeAv2M8WLQBtcy+SD6fNsmnB3AlBLrgTtVW1c2QN4bVWLATaIS60J2Du5y1TiJgjSBvFVZgTmwCU+dAZFoPxGEEs8nyHC9Bwe2GvEJv2WXZb0vjdyFT4Cxk3e/kIqlOGoVLwwPevpYHT+00T+hWwXDf4AJAOUqWcDhbwAAAAASUVORK5CYII=)!important}#toast-container>.toast-error{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAHOSURBVEhLrZa/SgNBEMZzh0WKCClSCKaIYOED+AAKeQQLG8HWztLCImBrYadgIdY+gIKNYkBFSwu7CAoqCgkkoGBI/E28PdbLZmeDLgzZzcx83/zZ2SSXC1j9fr+I1Hq93g2yxH4iwM1vkoBWAdxCmpzTxfkN2RcyZNaHFIkSo10+8kgxkXIURV5HGxTmFuc75B2RfQkpxHG8aAgaAFa0tAHqYFfQ7Iwe2yhODk8+J4C7yAoRTWI3w/4klGRgR4lO7Rpn9+gvMyWp+uxFh8+H+ARlgN1nJuJuQAYvNkEnwGFck18Er4q3egEc/oO+mhLdKgRyhdNFiacC0rlOCbhNVz4H9FnAYgDBvU3QIioZlJFLJtsoHYRDfiZoUyIxqCtRpVlANq0EU4dApjrtgezPFad5S19Wgjkc0hNVnuF4HjVA6C7QrSIbylB+oZe3aHgBsqlNqKYH48jXyJKMuAbiyVJ8KzaB3eRc0pg9VwQ4niFryI68qiOi3AbjwdsfnAtk0bCjTLJKr6mrD9g8iq/S/B81hguOMlQTnVyG40wAcjnmgsCNESDrjme7wfftP4P7SP4N3CJZdvzoNyGq2c/HWOXJGsvVg+RA/k2MC/wN6I2YA2Pt8GkAAAAASUVORK5CYII=)!important}#toast-container>.toast-success{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAADsSURBVEhLY2AYBfQMgf///3P8+/evAIgvA/FsIF+BavYDDWMBGroaSMMBiE8VC7AZDrIFaMFnii3AZTjUgsUUWUDA8OdAH6iQbQEhw4HyGsPEcKBXBIC4ARhex4G4BsjmweU1soIFaGg/WtoFZRIZdEvIMhxkCCjXIVsATV6gFGACs4Rsw0EGgIIH3QJYJgHSARQZDrWAB+jawzgs+Q2UO49D7jnRSRGoEFRILcdmEMWGI0cm0JJ2QpYA1RDvcmzJEWhABhD/pqrL0S0CWuABKgnRki9lLseS7g2AlqwHWQSKH4oKLrILpRGhEQCw2LiRUIa4lwAAAABJRU5ErkJggg==)!important}#toast-container>.toast-warning{background-image:url(data:image/png;base64,iVBORw0KGgoAAAANSUhEUgAAABgAAAAYCAYAAADgdz34AAAAAXNSR0IArs4c6QAAAARnQU1BAACxjwv8YQUAAAAJcEhZcwAADsMAAA7DAcdvqGQAAAGYSURBVEhL5ZSvTsNQFMbXZGICMYGYmJhAQIJAICYQPAACiSDB8AiICQQJT4CqQEwgJvYASAQCiZiYmJhAIBATCARJy+9rTsldd8sKu1M0+dLb057v6/lbq/2rK0mS/TRNj9cWNAKPYIJII7gIxCcQ51cvqID+GIEX8ASG4B1bK5gIZFeQfoJdEXOfgX4QAQg7kH2A65yQ87lyxb27sggkAzAuFhbbg1K2kgCkB1bVwyIR9m2L7PRPIhDUIXgGtyKw575yz3lTNs6X4JXnjV+LKM/m3MydnTbtOKIjtz6VhCBq4vSm3ncdrD2lk0VgUXSVKjVDJXJzijW1RQdsU7F77He8u68koNZTz8Oz5yGa6J3H3lZ0xYgXBK2QymlWWA+RWnYhskLBv2vmE+hBMCtbA7KX5drWyRT/2JsqZ2IvfB9Y4bWDNMFbJRFmC9E74SoS0CqulwjkC0+5bpcV1CZ8NMej4pjy0U+doDQsGyo1hzVJttIjhQ7GnBtRFN1UarUlH8F3xict+HY07rEzoUGPlWcjRFRr4/gChZgc3ZL2d8oAAAAASUVORK5CYII=)!important}#toast-container.toast-bottom-center>div,#toast-container.toast-top-center>div{width:300px;margin-left:auto;margin-right:auto}#toast-container.toast-bottom-full-width>div,#toast-container.toast-top-full-width>div{width:96%;margin-left:auto;margin-right:auto}.toast{background-color:#030303}.toast-success{background-color:#51A351}.toast-error{background-color:#BD362F}.toast-info{background-color:#2F96B4}.toast-warning{background-color:#F89406}.toast-progress{position:absolute;left:0;bottom:0;height:4px;background-color:#000;opacity:.4;-ms-filter:progid:DXImageTransform.Microsoft.Alpha(Opacity=40);filter:alpha(opacity=40)}@media all and (max-width:240px){#toast-container>div{padding:8px 8px 8px 50px;width:11em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:241px) and (max-width:480px){#toast-container>div{padding:8px 8px 8px 50px;width:18em}#toast-container>div.rtl{padding:8px 50px 8px 8px}#toast-container .toast-close-button{right:-.2em;top:-.2em}#toast-container .rtl .toast-close-button{left:-.2em;right:.2em}}@media all and (min-width:481px) and (max-width:768px){#toast-container>div{padding:15px 15px 15px 50px;width:25em}#toast-container>div.rtl{padding:15px 50px 15px 15px}}
\ No newline at end of file
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.js b/projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.js
new file mode 100644
index 00000000..06e4814f
--- /dev/null
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/lib/toastr/toastr.min.js
@@ -0,0 +1,2 @@
+!function(e){e(["jquery"],function(e){return function(){function t(e,t,n){return g({type:O.error,iconClass:m().iconClasses.error,message:e,optionsOverride:n,title:t})}function n(t,n){return t||(t=m()),v=e("#"+t.containerId),v.length?v:(n&&(v=d(t)),v)}function o(e,t,n){return g({type:O.info,iconClass:m().iconClasses.info,message:e,optionsOverride:n,title:t})}function s(e){C=e}function i(e,t,n){return g({type:O.success,iconClass:m().iconClasses.success,message:e,optionsOverride:n,title:t})}function a(e,t,n){return g({type:O.warning,iconClass:m().iconClasses.warning,message:e,optionsOverride:n,title:t})}function r(e,t){var o=m();v||n(o),u(e,o,t)||l(o)}function c(t){var o=m();return v||n(o),t&&0===e(":focus",t).length?void h(t):void(v.children().length&&v.remove())}function l(t){for(var n=v.children(),o=n.length-1;o>=0;o--)u(e(n[o]),t)}function u(t,n,o){var s=!(!o||!o.force)&&o.force;return!(!t||!s&&0!==e(":focus",t).length)&&(t[n.hideMethod]({duration:n.hideDuration,easing:n.hideEasing,complete:function(){h(t)}}),!0)}function d(t){return v=e("").attr("id",t.containerId).addClass(t.positionClass),v.appendTo(e(t.target)),v}function p(){return{tapToDismiss:!0,toastClass:"toast",containerId:"toast-container",debug:!1,showMethod:"fadeIn",showDuration:300,showEasing:"swing",onShown:void 0,hideMethod:"fadeOut",hideDuration:1e3,hideEasing:"swing",onHidden:void 0,closeMethod:!1,closeDuration:!1,closeEasing:!1,closeOnHover:!0,extendedTimeOut:1e3,iconClasses:{error:"toast-error",info:"toast-info",success:"toast-success",warning:"toast-warning"},iconClass:"toast-info",positionClass:"toast-top-right",timeOut:5e3,titleClass:"toast-title",messageClass:"toast-message",escapeHtml:!1,target:"body",closeHtml:'',closeClass:"toast-close-button",newestOnTop:!0,preventDuplicates:!1,progressBar:!1,progressClass:"toast-progress",rtl:!1}}function f(e){C&&C(e)}function g(t){function o(e){return null==e&&(e=""),e.replace(/&/g,"&").replace(/"/g,""").replace(/'/g,"'").replace(//g,">")}function s(){c(),u(),d(),p(),g(),C(),l(),i()}function i(){var e="";switch(t.iconClass){case"toast-success":case"toast-info":e="polite";break;default:e="assertive"}I.attr("aria-live",e)}function a(){E.closeOnHover&&I.hover(H,D),!E.onclick&&E.tapToDismiss&&I.click(b),E.closeButton&&j&&j.click(function(e){e.stopPropagation?e.stopPropagation():void 0!==e.cancelBubble&&e.cancelBubble!==!0&&(e.cancelBubble=!0),E.onCloseClick&&E.onCloseClick(e),b(!0)}),E.onclick&&I.click(function(e){E.onclick(e),b()})}function r(){I.hide(),I[E.showMethod]({duration:E.showDuration,easing:E.showEasing,complete:E.onShown}),E.timeOut>0&&(k=setTimeout(b,E.timeOut),F.maxHideTime=parseFloat(E.timeOut),F.hideEta=(new Date).getTime()+F.maxHideTime,E.progressBar&&(F.intervalId=setInterval(x,10)))}function c(){t.iconClass&&I.addClass(E.toastClass).addClass(y)}function l(){E.newestOnTop?v.prepend(I):v.append(I)}function u(){if(t.title){var e=t.title;E.escapeHtml&&(e=o(t.title)),M.append(e).addClass(E.titleClass),I.append(M)}}function d(){if(t.message){var e=t.message;E.escapeHtml&&(e=o(t.message)),B.append(e).addClass(E.messageClass),I.append(B)}}function p(){E.closeButton&&(j.addClass(E.closeClass).attr("role","button"),I.prepend(j))}function g(){E.progressBar&&(q.addClass(E.progressClass),I.prepend(q))}function C(){E.rtl&&I.addClass("rtl")}function O(e,t){if(e.preventDuplicates){if(t.message===w)return!0;w=t.message}return!1}function b(t){var n=t&&E.closeMethod!==!1?E.closeMethod:E.hideMethod,o=t&&E.closeDuration!==!1?E.closeDuration:E.hideDuration,s=t&&E.closeEasing!==!1?E.closeEasing:E.hideEasing;if(!e(":focus",I).length||t)return clearTimeout(F.intervalId),I[n]({duration:o,easing:s,complete:function(){h(I),clearTimeout(k),E.onHidden&&"hidden"!==P.state&&E.onHidden(),P.state="hidden",P.endTime=new Date,f(P)}})}function D(){(E.timeOut>0||E.extendedTimeOut>0)&&(k=setTimeout(b,E.extendedTimeOut),F.maxHideTime=parseFloat(E.extendedTimeOut),F.hideEta=(new Date).getTime()+F.maxHideTime)}function H(){clearTimeout(k),F.hideEta=0,I.stop(!0,!0)[E.showMethod]({duration:E.showDuration,easing:E.showEasing})}function x(){var e=(F.hideEta-(new Date).getTime())/F.maxHideTime*100;q.width(e+"%")}var E=m(),y=t.iconClass||E.iconClass;if("undefined"!=typeof t.optionsOverride&&(E=e.extend(E,t.optionsOverride),y=t.optionsOverride.iconClass||y),!O(E,t)){T++,v=n(E,!0);var k=null,I=e(""),M=e(""),B=e(""),q=e(""),j=e(E.closeHtml),F={intervalId:null,hideEta:null,maxHideTime:null},P={toastId:T,state:"visible",startTime:new Date,options:E,map:t};return s(),r(),a(),f(P),E.debug&&console&&console.log(P),I}}function m(){return e.extend({},p(),b.options)}function h(e){v||(v=n()),e.is(":visible")||(e.remove(),e=null,0===v.children().length&&(v.remove(),w=void 0))}var v,C,w,T=0,O={error:"error",info:"info",success:"success",warning:"warning"},b={clear:r,remove:c,error:t,getContainer:n,info:o,options:{},subscribe:s,success:i,version:"2.1.4",warning:a};return b}()})}("function"==typeof define&&define.amd?define:function(e,t){"undefined"!=typeof module&&module.exports?module.exports=t(require("jquery")):window.toastr=t(window.jQuery)});
+//# sourceMappingURL=toastr.js.map
diff --git a/projects/IoTClient/Assets/StreamingAssets/wwwroot/node.html b/projects/IoTClient/Assets/StreamingAssets/wwwroot/node.html
index 5b83cc43..6f43af23 100644
--- a/projects/IoTClient/Assets/StreamingAssets/wwwroot/node.html
+++ b/projects/IoTClient/Assets/StreamingAssets/wwwroot/node.html
@@ -6,6 +6,7 @@
+
@@ -130,7 +131,7 @@
-
+
@@ -602,6 +603,7 @@
+
+