1
+ /*
2
+ ****************************************************************************
3
+ * Copyright (c) 2023, Skyline Communications NV All Rights Reserved. *
4
+ ****************************************************************************
5
+
6
+ By using this script, you expressly agree with the usage terms and
7
+ conditions set out below.
8
+ This script and all related materials are protected by copyrights and
9
+ other intellectual property rights that exclusively belong
10
+ to Skyline Communications.
11
+
12
+ A user license granted for this script is strictly for personal use only.
13
+ This script may not be used in any way by anyone without the prior
14
+ written consent of Skyline Communications. Any sublicensing of this
15
+ script is forbidden.
16
+
17
+ Any modifications to this script by the user are only allowed for
18
+ personal use and within the intended purpose of the script,
19
+ and will remain the sole responsibility of the user.
20
+ Skyline Communications will not be responsible for any damages or
21
+ malfunctions whatsoever of the script resulting from a modification
22
+ or adaptation by the user.
23
+
24
+ The content of this script is confidential information.
25
+ The user hereby agrees to keep this confidential information strictly
26
+ secret and confidential and not to disclose or reveal it, in whole
27
+ or in part, directly or indirectly to any person, entity, organization
28
+ or administration without the prior written consent of
29
+ Skyline Communications.
30
+
31
+ Any inquiries can be addressed to:
32
+
33
+ Skyline Communications NV
34
+ Ambachtenstraat 33
35
+ B-8870 Izegem
36
+ Belgium
37
+ Tel. : +32 51 31 35 69
38
+ Fax. : +32 51 31 01 29
39
+ E-mail : info@skyline.be
40
+ Web : www.skyline.be
41
+ Contact : Ben Vandenberghe
42
+
43
+ ****************************************************************************
44
+ Revision History:
45
+
46
+ DATE VERSION AUTHOR COMMENTS
47
+
48
+ dd/mm/2023 1.0.0.1 XXX, Skyline Initial version
49
+ ****************************************************************************
50
+ */
51
+
52
+ namespace Show_Resource_Utilization_1
53
+ {
54
+ using System ;
55
+ using System . Collections . Generic ;
56
+ using System . Linq ;
57
+ using AdaptiveCards ;
58
+ using Newtonsoft . Json ;
59
+ using Skyline . DataMiner . Automation ;
60
+ using Skyline . DataMiner . Net . Helper ;
61
+ using Skyline . DataMiner . Net . Messages ;
62
+ using Skyline . DataMiner . Net . Messages . SLDataGateway ;
63
+ using Skyline . DataMiner . Net . ResourceManager . Objects ;
64
+ using Skyline . DataMiner . Net . Time ;
65
+
66
+ /// <summary>
67
+ /// DataMiner Script Class.
68
+ /// </summary>
69
+ public class Script
70
+ {
71
+ private static int durationInDays = 7 ;
72
+ DateTime start ;
73
+ DateTime end ;
74
+
75
+ /// <summary>
76
+ /// The Script entry point.
77
+ /// </summary>
78
+ /// <param name="engine">Link with SLAutomation process.</param>
79
+ public void Run ( Engine engine )
80
+ {
81
+ try
82
+ {
83
+ RunSafe ( engine ) ;
84
+ }
85
+ catch ( Exception ex )
86
+ {
87
+ ReturnErrorMessage ( engine , ex . Message ) ;
88
+ }
89
+ }
90
+
91
+ private void RunSafe ( Engine engine )
92
+ {
93
+ end = DateTime . UtcNow ;
94
+ start = end . AddDays ( - durationInDays ) ;
95
+
96
+ var resourcePoolName = engine . GetScriptParam ( "Resource Pool Name" ) . Value ;
97
+
98
+ ResourceManagerHelper rmHelper = new ResourceManagerHelper ( ) ;
99
+ rmHelper . RequestResponseEvent += ( sender , e ) => e . responseMessage = engine . SendSLNetSingleResponseMessage ( e . requestMessage ) ;
100
+
101
+ List < Resource > resources = GetResourcesByPoolName ( rmHelper , resourcePoolName ) ;
102
+ if ( resources . Count == 0 )
103
+ {
104
+ ReturnErrorMessage ( engine , "No resources available." ) ;
105
+
106
+ return ;
107
+ }
108
+
109
+ var resourceMapping = resources . ToDictionary ( r => r . ID , r => new ResourceInfo { Resource = r , Duration = 0 } ) ;
110
+ foreach ( var reservation in GetReservationsByResources ( rmHelper , resourceMapping . Keys . ToList ( ) ) )
111
+ {
112
+ reservation . ResourcesInReservationInstance
113
+ . Where ( resource => resourceMapping . Keys . Contains ( resource . GUID ) )
114
+ . ForEach ( resource => UpdateTimeRange ( resource . GUID , reservation . TimeRange , resourceMapping ) ) ;
115
+ }
116
+
117
+ ReturnResultMessage ( engine , resourceMapping . Values . ToList ( ) , false ) ;
118
+ }
119
+
120
+ private List < Resource > GetResourcesByPoolName ( ResourceManagerHelper rmHelper , string name )
121
+ {
122
+ ResourcePool resourcePool = rmHelper . GetResourcePools ( new ResourcePool { Name = name } ) . FirstOrDefault ( ) ;
123
+ if ( resourcePool == null )
124
+ {
125
+ throw new ArgumentException ( $ "No resource pool found with name '{ name } '.") ;
126
+ }
127
+
128
+ return rmHelper . GetResources ( ResourceExposers . PoolGUIDs . Contains ( resourcePool . GUID ) ) . ToList ( ) ;
129
+ }
130
+
131
+ private List < ReservationInstance > GetReservationsByResources ( ResourceManagerHelper rmHelper , List < Guid > resourceIds )
132
+ {
133
+ var resourceFilter = new ORFilterElement < ReservationInstance > ( resourceIds . Select ( id => ReservationInstanceExposers . ResourceIDsInReservationInstance . Contains ( id ) ) . ToArray ( ) ) ;
134
+
135
+ var now = DateTime . UtcNow ;
136
+ var timeRangeUtc = new TimeRangeUtc ( now . AddDays ( - 7 ) , now ) ;
137
+
138
+ var filter = resourceFilter
139
+ . AND ( ReservationInstanceExposers . Start . LessThanOrEqual ( timeRangeUtc . Stop )
140
+ . AND ( ReservationInstanceExposers . End . GreaterThanOrEqual ( timeRangeUtc . Start ) ) ) ;
141
+
142
+ return rmHelper . GetReservationInstances ( filter ) . ToList ( ) ;
143
+ }
144
+
145
+ private void UpdateTimeRange ( Guid resourceId , TimeRangeUtc timeRange , Dictionary < Guid , ResourceInfo > dic )
146
+ {
147
+ DateTime startToUse = ( timeRange . Start < start ) ? start : timeRange . Start ;
148
+ DateTime endToUse = ( timeRange . Stop > end ) ? end : timeRange . Stop ;
149
+
150
+ dic [ resourceId ] . Duration += ( endToUse - startToUse ) . TotalMinutes ;
151
+ }
152
+
153
+ private void ReturnResultMessage ( Engine engine , List < ResourceInfo > resources , bool skipNotUsed )
154
+ {
155
+ var table = new AdaptiveTable
156
+ {
157
+ Type = "Table" ,
158
+ FirstRowAsHeaders = true ,
159
+ Columns = new List < AdaptiveTableColumnDefinition >
160
+ {
161
+ new AdaptiveTableColumnDefinition
162
+ {
163
+ Width = 250 ,
164
+ } ,
165
+ new AdaptiveTableColumnDefinition
166
+ {
167
+ Width = 100 ,
168
+ } ,
169
+ } ,
170
+ Rows = new List < AdaptiveTableRow >
171
+ {
172
+ new AdaptiveTableRow
173
+ {
174
+ Type = "TableRow" ,
175
+ Cells = new List < AdaptiveTableCell >
176
+ {
177
+ new AdaptiveTableCell
178
+ {
179
+ Type = "TableCell" ,
180
+ Items = new List < AdaptiveElement >
181
+ {
182
+ new AdaptiveTextBlock ( "Resource" )
183
+ {
184
+ Type = "TextBlock" ,
185
+ Weight = AdaptiveTextWeight . Bolder ,
186
+ } ,
187
+ } ,
188
+ } ,
189
+ new AdaptiveTableCell
190
+ {
191
+ Type = "TableCell" ,
192
+ Items = new List < AdaptiveElement >
193
+ {
194
+ new AdaptiveTextBlock ( "Utilization" )
195
+ {
196
+ Type = "TextBlock" ,
197
+ Weight = AdaptiveTextWeight . Bolder ,
198
+ } ,
199
+ } ,
200
+ } ,
201
+ } ,
202
+ } ,
203
+ } ,
204
+ } ;
205
+
206
+ Double maxDuration = 24 * 60 * 7 ;
207
+
208
+ foreach ( var resourceInfo in resources )
209
+ {
210
+ if ( skipNotUsed && resourceInfo . Duration . Equals ( 0 ) )
211
+ {
212
+ continue ;
213
+ }
214
+
215
+ var row = new AdaptiveTableRow
216
+ {
217
+ Type = "TableRow" ,
218
+ Cells = new List < AdaptiveTableCell >
219
+ {
220
+ new AdaptiveTableCell
221
+ {
222
+ Type = "TableCell" ,
223
+ Items = new List < AdaptiveElement >
224
+ {
225
+ new AdaptiveTextBlock ( resourceInfo . Resource . Name )
226
+ {
227
+ Type = "TextBlock" ,
228
+ } ,
229
+ } ,
230
+ } ,
231
+ new AdaptiveTableCell
232
+ {
233
+ Type = "TableCell" ,
234
+ Items = new List < AdaptiveElement >
235
+ {
236
+ new AdaptiveTextBlock ( $ "{ resourceInfo . Duration / maxDuration * 100 : N2} %")
237
+ {
238
+ Type = "TextBlock" ,
239
+ } ,
240
+ } ,
241
+ } ,
242
+ } ,
243
+ } ;
244
+
245
+ table . Rows . Add ( row ) ;
246
+ }
247
+
248
+ var adaptiveCardBody = new List < AdaptiveElement > ( ) ;
249
+ adaptiveCardBody . Add ( table ) ;
250
+
251
+ engine . AddScriptOutput ( "AdaptiveCard" , JsonConvert . SerializeObject ( adaptiveCardBody ) ) ;
252
+ }
253
+
254
+ private void ReturnErrorMessage ( Engine engine , string message )
255
+ {
256
+ var adaptiveCardBody = new List < AdaptiveElement >
257
+ {
258
+ new AdaptiveTextBlock ( message )
259
+ {
260
+ Type = "TextBlock" ,
261
+ Weight = AdaptiveTextWeight . Bolder ,
262
+ Size = AdaptiveTextSize . Default ,
263
+ } ,
264
+ } ;
265
+
266
+ engine . AddScriptOutput ( "AdaptiveCard" , JsonConvert . SerializeObject ( adaptiveCardBody ) ) ;
267
+ }
268
+ }
269
+
270
+ internal class ResourceInfo
271
+ {
272
+ public Resource Resource { get ; set ; }
273
+
274
+ public double Duration { get ; set ; }
275
+ }
276
+ }
0 commit comments