1
1
using Microsoft . AspNetCore . Http ;
2
2
using Microsoft . AspNetCore . Mvc ;
3
3
using Microsoft . AspNetCore . Mvc . Rendering ;
4
- using Microsoft . AspNetCore . SignalR ;
5
- using Microsoft . Extensions . Logging ;
6
4
using Newtonsoft . Json ;
7
5
using Opc . Ua ;
8
6
using Opc . Ua . Client ;
9
7
using Opc . Ua . Cloud . Library . Models ;
10
8
using Opc . Ua . Configuration ;
9
+ using Opc . Ua . Edge . Translator . Models ;
11
10
using Opc . Ua . Export ;
12
11
using System ;
13
12
using System . Collections . Generic ;
@@ -28,89 +27,111 @@ public class BrowserController : Controller
28
27
public static List < string > _nodeSetFilenames = new List < string > ( ) ;
29
28
30
29
private static HttpClient _client = new HttpClient ( ) ;
31
-
32
30
private static Dictionary < string , string > _namespacesInCloudLibrary = new Dictionary < string , string > ( ) ;
33
-
34
31
private static Dictionary < string , string > _namesInCloudLibrary = new Dictionary < string , string > ( ) ;
32
+ private static List < string > _wotProperties = new List < string > ( ) ;
33
+ private static ThingDescription _td ;
34
+ private static string _wotFileName = string . Empty ;
35
35
36
36
private readonly OpcSessionHelper _helper ;
37
37
private readonly ApplicationInstance _application ;
38
38
39
+ private OpcSessionModel _session ;
40
+
39
41
public BrowserController ( OpcSessionHelper helper , ApplicationInstance app )
40
42
{
41
43
_helper = helper ;
42
44
_application = app ;
43
- }
44
45
45
- public ActionResult Index ( )
46
- {
47
- OpcSessionModel sessionModel = new OpcSessionModel
46
+ _session = new ( )
48
47
{
49
- SessionId = HttpContext . Session . Id ,
50
- NodesetIDs = new SelectList ( new List < string > ( ) )
48
+ NodesetIDs = new SelectList ( _namesInCloudLibrary . Values ) ,
49
+ EndpointUrl = "opc.tcp://localhost" ,
50
+ NodesetFile = string . Empty ,
51
+ WoTFile = _wotFileName ,
52
+ WoTProperties = new SelectList ( _wotProperties )
51
53
} ;
52
54
55
+ if ( _nodeSetFilenames . Count > 0 )
56
+ {
57
+ foreach ( string filename in _nodeSetFilenames )
58
+ {
59
+ _session . NodesetFile += ( filename + ", " ) ;
60
+ }
61
+ }
62
+ }
63
+
64
+ public ActionResult Index ( )
65
+ {
53
66
OpcSessionCacheData entry = null ;
54
67
if ( _helper . OpcSessionCache . TryGetValue ( HttpContext . Session . Id , out entry ) )
55
68
{
56
- sessionModel . EndpointUrl = "opc.tcp://localhost" ;
57
-
58
69
HttpContext . Session . SetString ( "EndpointUrl" , entry . EndpointURL ) ;
59
70
60
- return View ( "Browse" , sessionModel ) ;
71
+ return View ( "Browse" , _session ) ;
61
72
}
62
73
63
- return View ( "Index" , sessionModel ) ;
74
+ return View ( "Index" , _session ) ;
64
75
}
65
76
66
77
[ HttpPost ]
67
78
public ActionResult Login ( string instanceUrl , string clientId , string secret )
68
79
{
69
- OpcSessionModel sessionModel = new OpcSessionModel
80
+ if ( ! string . IsNullOrEmpty ( _client . BaseAddress ? . ToString ( ) ) )
70
81
{
71
- SessionId = HttpContext . Session . Id ,
72
- NodesetIDs = new SelectList ( new List < string > ( ) )
73
- } ;
82
+ _client . Dispose ( ) ;
83
+ _client = new HttpClient ( ) ;
84
+ }
74
85
86
+ _client . BaseAddress = new Uri ( instanceUrl ) ;
75
87
_client . DefaultRequestHeaders . Remove ( "Authorization" ) ;
76
88
_client . DefaultRequestHeaders . Add ( "Authorization" , "basic " + Convert . ToBase64String ( Encoding . UTF8 . GetBytes ( clientId + ":" + secret ) ) ) ;
77
89
78
90
if ( ! instanceUrl . EndsWith ( '/' ) )
79
91
{
80
92
instanceUrl += '/' ;
81
93
}
82
- _client . BaseAddress = new Uri ( instanceUrl ) ;
83
94
84
95
// get namespaces
85
96
string address = instanceUrl + "infomodel/namespaces" ;
86
97
HttpResponseMessage response = _client . Send ( new HttpRequestMessage ( HttpMethod . Get , address ) ) ;
87
98
string [ ] identifiers = JsonConvert . DeserializeObject < string [ ] > ( response . Content . ReadAsStringAsync ( ) . GetAwaiter ( ) . GetResult ( ) ) ;
88
99
89
100
_namespacesInCloudLibrary . Clear ( ) ;
90
- foreach ( string nodeset in identifiers )
101
+ if ( identifiers != null )
91
102
{
92
- string [ ] tuple = nodeset . Split ( "," ) ;
93
- _namespacesInCloudLibrary . Add ( tuple [ 1 ] , tuple [ 0 ] ) ;
103
+ foreach ( string nodeset in identifiers )
104
+ {
105
+ string [ ] tuple = nodeset . Split ( "," ) ;
106
+ _namespacesInCloudLibrary . Add ( tuple [ 1 ] , tuple [ 0 ] ) ;
107
+ }
94
108
}
95
109
96
110
// get names
97
111
address = instanceUrl + "infomodel/names" ;
98
112
response = _client . Send ( new HttpRequestMessage ( HttpMethod . Get , address ) ) ;
99
113
string [ ] names = JsonConvert . DeserializeObject < string [ ] > ( response . Content . ReadAsStringAsync ( ) . GetAwaiter ( ) . GetResult ( ) ) ;
100
114
101
- List < string > sortedNames = new List < string > ( names ) ;
102
- sortedNames . Sort ( ) ;
103
-
104
- _namesInCloudLibrary . Clear ( ) ;
105
- foreach ( string name in sortedNames )
115
+ if ( names != null )
106
116
{
107
- string [ ] tuple = name . Split ( "," ) ;
108
- _namesInCloudLibrary . Add ( tuple [ 1 ] , tuple [ 0 ] ) ;
117
+ List < string > sortedNames = new List < string > ( names ) ;
118
+ sortedNames . Sort ( ) ;
119
+
120
+
121
+ _namesInCloudLibrary . Clear ( ) ;
122
+ if ( sortedNames != null )
123
+ {
124
+ foreach ( string name in sortedNames )
125
+ {
126
+ string [ ] tuple = name . Split ( "," ) ;
127
+ _namesInCloudLibrary . Add ( tuple [ 1 ] , tuple [ 0 ] ) ;
128
+ }
129
+ }
109
130
}
110
131
111
- sessionModel . NodesetIDs = new SelectList ( _namesInCloudLibrary . Values ) ;
132
+ _session . NodesetIDs = new SelectList ( _namesInCloudLibrary . Values ) ;
112
133
113
- return View ( "Index" , sessionModel ) ;
134
+ return View ( "Index" , _session ) ;
114
135
}
115
136
116
137
public ActionResult Privacy ( )
@@ -149,12 +170,11 @@ public ActionResult GenerateAAS()
149
170
}
150
171
catch ( Exception ex )
151
172
{
152
- OpcSessionModel sessionModel = new OpcSessionModel
153
- {
154
- StatusMessage = HttpUtility . HtmlDecode ( ex . Message )
155
- } ;
173
+ Trace . TraceError ( ex . Message ) ;
174
+
175
+ _session . StatusMessage = ex . Message ;
156
176
157
- return View ( "Error" , sessionModel ) ;
177
+ return View ( "Error" , _session ) ;
158
178
}
159
179
}
160
180
@@ -172,22 +192,13 @@ private void CopyStream(Stream source, Stream target)
172
192
[ HttpPost ]
173
193
public ActionResult Error ( string errorMessage )
174
194
{
175
- OpcSessionModel sessionModel = new OpcSessionModel
176
- {
177
- StatusMessage = HttpUtility . HtmlDecode ( errorMessage ) ,
178
- NodesetIDs = new SelectList ( new List < string > ( ) )
179
- } ;
195
+ _session . StatusMessage = HttpUtility . HtmlDecode ( errorMessage ) ;
180
196
181
- return View ( "Error" , sessionModel ) ;
197
+ return View ( "Error" , _session ) ;
182
198
}
183
199
184
200
public async Task < ActionResult > CloudLibrayFileOpen ( string nodesetfile )
185
201
{
186
- OpcSessionModel sessionModel = new OpcSessionModel
187
- {
188
- EndpointUrl = "opc.tcp://localhost"
189
- } ;
190
-
191
202
string address = _client . BaseAddress + "infomodel/download/" ;
192
203
foreach ( KeyValuePair < string , string > ns in _namesInCloudLibrary )
193
204
{
@@ -209,23 +220,18 @@ public async Task<ActionResult> CloudLibrayFileOpen(string nodesetfile)
209
220
string error = ValidateNamespacesAndModels ( true ) ;
210
221
if ( ! string . IsNullOrEmpty ( error ) )
211
222
{
212
- sessionModel . StatusMessage = error ;
213
- return View ( "Error" , sessionModel ) ;
223
+ _session . StatusMessage = error ;
224
+ return View ( "Error" , _session ) ;
214
225
}
215
226
216
- await StartClientAndServer ( sessionModel ) . ConfigureAwait ( false ) ;
227
+ await StartClientAndServer ( ) . ConfigureAwait ( false ) ;
217
228
218
- return View ( "Browse" , sessionModel ) ;
229
+ return View ( "Browse" , _session ) ;
219
230
}
220
231
221
232
[ HttpPost ]
222
233
public async Task < ActionResult > LocalFileOpen ( IFormFile [ ] files , bool autodownloadreferences )
223
234
{
224
- OpcSessionModel sessionModel = new OpcSessionModel
225
- {
226
- EndpointUrl = "opc.tcp://localhost"
227
- } ;
228
-
229
235
try
230
236
{
231
237
if ( ( files == null ) || ( files . Length == 0 ) )
@@ -257,25 +263,96 @@ public async Task<ActionResult> LocalFileOpen(IFormFile[] files, bool autodownlo
257
263
string error = ValidateNamespacesAndModels ( autodownloadreferences ) ;
258
264
if ( ! string . IsNullOrEmpty ( error ) )
259
265
{
260
- sessionModel . StatusMessage = error ;
261
- return View ( "Error" , sessionModel ) ;
266
+ _session . StatusMessage = error ;
267
+ return View ( "Error" , _session ) ;
268
+ }
269
+
270
+ await StartClientAndServer ( ) . ConfigureAwait ( false ) ;
271
+
272
+ return View ( "Browse" , _session ) ;
273
+ }
274
+ catch ( Exception ex )
275
+ {
276
+ Trace . TraceError ( ex . Message ) ;
277
+
278
+ _session . StatusMessage = ex . Message ;
279
+
280
+ return View ( "Error" , _session ) ;
281
+ }
282
+ }
283
+
284
+ [ HttpPost ]
285
+ public async Task < ActionResult > WoTFileOpen ( IFormFile file )
286
+ {
287
+ try
288
+ {
289
+ if ( ( file == null ) || ( file . Length == 0 ) )
290
+ {
291
+ throw new ArgumentException ( "No file specified!" ) ;
262
292
}
263
293
264
- await StartClientAndServer ( sessionModel ) . ConfigureAwait ( false ) ;
294
+ // file name validation
295
+ new FileInfo ( file . FileName ) ;
296
+ _wotFileName = file . FileName ;
297
+ _session . WoTFile = _wotFileName ;
298
+
299
+ using ( MemoryStream stream = new ( ) )
300
+ {
301
+ await file . CopyToAsync ( stream ) . ConfigureAwait ( false ) ;
302
+
303
+ string contents = Encoding . UTF8 . GetString ( stream . ToArray ( ) ) ;
304
+
305
+ // parse WoT TD file contents
306
+ _td = JsonConvert . DeserializeObject < ThingDescription > ( contents ) ;
265
307
266
- return View ( "Browse" , sessionModel ) ;
308
+ _wotProperties = new List < string > ( ) ;
309
+ foreach ( string propertyName in _td . Properties . Keys )
310
+ {
311
+ _wotProperties . Add ( propertyName ) ;
312
+ }
313
+ _session . WoTProperties = new SelectList ( _wotProperties ) ;
314
+ }
315
+
316
+ return View ( "Browse" , _session ) ;
267
317
}
268
318
catch ( Exception ex )
269
319
{
270
320
Trace . TraceError ( ex . Message ) ;
271
321
272
- sessionModel . StatusMessage = ex . Message ;
322
+ _session . StatusMessage = ex . Message ;
273
323
274
- return View ( "Error" , sessionModel ) ;
324
+ return View ( "Error" , _session ) ;
275
325
}
276
326
}
277
327
278
- private async Task StartClientAndServer ( OpcSessionModel sessionModel )
328
+ public IActionResult MapWoTProperty ( string wotproperty )
329
+ {
330
+ return View ( "Browse" , _session ) ;
331
+ }
332
+
333
+ [ HttpPost ]
334
+ public IActionResult DownloadWoT ( )
335
+ {
336
+ try
337
+ {
338
+ string content = JsonConvert . SerializeObject ( _td , Formatting . Indented ) ;
339
+
340
+ using ( MemoryStream stream = new ( ) )
341
+ {
342
+ return File ( Encoding . UTF8 . GetBytes ( content ) , "application/json" , _wotFileName ) ;
343
+ }
344
+ }
345
+ catch ( Exception ex )
346
+ {
347
+ Trace . TraceError ( ex . Message ) ;
348
+
349
+ _session . StatusMessage = ex . Message ;
350
+
351
+ return View ( "Error" , _session ) ;
352
+ }
353
+ }
354
+
355
+ private async Task StartClientAndServer ( )
279
356
{
280
357
// (re-)start the UA server
281
358
if ( _application . Server != null )
@@ -464,13 +541,7 @@ public ActionResult Disconnect()
464
541
_application . Stop ( ) ;
465
542
}
466
543
467
- OpcSessionModel sessionModel = new OpcSessionModel
468
- {
469
- SessionId = HttpContext . Session . Id ,
470
- NodesetIDs = new SelectList ( new List < string > ( ) )
471
- } ;
472
-
473
- return View ( "Index" , sessionModel ) ;
544
+ return View ( "Index" , _session ) ;
474
545
}
475
546
}
476
547
}
0 commit comments