NetSim Source Code Help v14.4
All 13 Components
 
Loading...
Searching...
No Matches
BatteryModel.c
1/************************************************************************************
2* Copyright (C) 2023 *
3* TETCOS, Bangalore. India *
4* *
5* Tetcos owns the intellectual property rights in the Product and its content. *
6* The copying, redistribution, reselling or publication of any or all of the *
7* Product or its content without express prior written consent of Tetcos is *
8* prohibited. Ownership and / or any other right relating to the software and all *
9* intellectual property rights therein shall remain at all times with Tetcos. *
10* *
11* Author: Shashi Kant Suman *
12* *
13* ---------------------------------------------------------------------------------*/
14#define _BATTERY_MODEL_CODE_
15#include "main.h"
16#include "Animation.h"
17
18#pragma comment(lib,"NetworkStack.lib")
19#pragma comment(lib,"Metrics.lib")
20
21#include "BatteryModel.h"
22
23//Function prototype
24static void battery_add_to_animation(ptrBATTERY pb);
25
26static ptrBATTERY firstBattery = NULL;
27static ptrBATTERY lastBattery = NULL;
28
29static void battery_add(ptrBATTERY b)
30{
31 if (firstBattery)
32 {
33 lastBattery->next = b;
34 lastBattery = b;
35 }
36 else
37 {
38 firstBattery = b;
39 lastBattery = b;
40 }
41}
42
43static ptrBATTERYMODE battery_find_mode(ptrBATTERY b,
44 int mode)
45{
46 int i;
47 for (i = 0; i < b->modeCount; i++)
48 {
49 if (b->mode[i].mode == mode)
50 return &b->mode[i];
51 }
52 return NULL;
53}
54
55_declspec(dllexport) ptrBATTERY battery_find(NETSIM_ID d,
56 NETSIM_ID in)
57{
58 ptrBATTERY db = NULL;
59 ptrBATTERY t = firstBattery;
60 while (t)
61 {
62 if (t->deviceId == d &&
63 t->interfaceId == in)
64 return t;
65
66 if (t->deviceId == d &&
67 t->interfaceId == 0)
68 db = t;
69 t = t->next;
70 }
71 return db;
72}
73
74_declspec(dllexport) void battery_add_new_mode(ptrBATTERY battery,
75 int mode,
76 double current,
77 char* heading)
78{
79 if (battery->modeCount)
80 battery->mode = realloc(battery->mode, (battery->modeCount + 1) * sizeof* battery->mode);
81 else
82 battery->mode = calloc(1, sizeof* battery->mode);
83 battery->mode[battery->modeCount].current = current;
84 battery->mode[battery->modeCount].mode = mode;
85 battery->mode[battery->modeCount].heading = _strdup(heading);
86 battery->mode[battery->modeCount].consumedEnergy = 0;
87 battery->modeCount++;
88}
89
90_declspec(dllexport) ptrBATTERY battery_init_new(NETSIM_ID deviceId,
91 NETSIM_ID interfaceId,
92 double initialEnergy,
93 double voltage,
94 double dRechargingCurrent)
95{
96 ptrBATTERY nb = battery_find(deviceId, interfaceId);
97 if (nb)
98 {
99 nb->SumConsumedEnergy = 0;
100 nb->SumTransmitEnergy = 0;
101 nb->SumIdleEnergy = 0;
102 nb->SumReceiveEnergy = 0;
103 nb->SumSleepEnergy = 0;
104 nb->SumHarvestedEnergy = 0;
105 if (!interfaceId)
106 return nb;
107
108 if (nb->interfaceId)
109 return nb;
110 }
111 nb = (ptrBATTERY)calloc(1, sizeof* nb);
112 nb->deviceId = deviceId;
113 nb->interfaceId = interfaceId;
114 nb->initialEnergy = initialEnergy;
115 nb->remainingEnergy = initialEnergy;
116 nb->voltage = voltage;
117 nb->rechargingCurrent = dRechargingCurrent;
118 battery_add(nb);
119 battery_add_new_mode(nb, 0, 0, NULL);
120 battery_add_to_animation(nb);
121 return nb;
122}
123
124_declspec(dllexport) void battery_free(NETSIM_ID deviceId,
125 NETSIM_ID interfaceId,
126 double time)
127{
128 ptrBATTERY nb = battery_find(deviceId, interfaceId);
129 if (nb)
130 {
131 battery_set_mode(nb, 0, time);
132 free(nb->mode);
133 free(nb);
134 }
135}
136
137_declspec(dllexport) bool battery_set_mode(ptrBATTERY battery,
138 int mode,
139 double time)
140{
141 int current_mode = battery->currentMode;
142 double mode_change_time = battery->modeChangedTime;
143 bool ret;
144 ptrBATTERYMODE pm = battery_find_mode(battery, battery->currentMode);
145 double r = battery->voltage*battery->rechargingCurrent*(time - battery->modeChangedTime) / 1000000;
146 double c = battery->voltage*pm->current*(time - battery->modeChangedTime) / 1000000;
147 battery->rechargingEnergy += r;
148 battery->remainingEnergy += r;
149 battery->modeChangedTime = time;
150 if (c > battery->remainingEnergy)
151 {
152 pm->consumedEnergy += battery->remainingEnergy;
153 battery->consumedEnergy += battery->remainingEnergy;
154 c = battery->remainingEnergy;
155 battery->remainingEnergy = 0;
156 battery->currentMode = 0;
157 ret = false;
158 }
159 else
160 {
161 pm->consumedEnergy += c;
162 battery->consumedEnergy += c;
163 battery->remainingEnergy -= c;
164 if (battery->currentMode > 0 || battery->remainingEnergy > 0)
165 {
166 battery->currentMode = mode;
167 ret = true;
168 }
169 else
170 ret = false;
171 }
172
173 double per = battery->remainingEnergy * 100;
174 per /= battery->initialEnergy;
175 if (battery->animHandle)
176 animation_add_new_entry(battery->animHandle,
177 ANIM_BATTERY,
178 "%d,%lf,%lf,",
179 DEVICE_CONFIGID(battery->deviceId),
180 per,
181 time);
182
183 switch (current_mode)
184 {
185 case 1:battery->SumIdleEnergy += c;
186 break;
187 case 2:battery->SumReceiveEnergy += c;
188 break;
189 case 3:battery->SumTransmitEnergy += c;
190 break;
191 case 4:battery->SumSleepEnergy += c;
192 break;
193 default: break;
194 }
195
196 battery->SumConsumedEnergy += c;
197 battery->SumHarvestedEnergy += r;
198
199 if(current_mode != battery->currentMode)
200 Battery_RadioMeasurements_Log(battery ,r, c, current_mode,battery->currentMode,mode_change_time,pm);
201 return ret;
202}
203
204static ANIM_HANDLE handle;
205static void battery_add_to_animation(ptrBATTERY pb)
206{
207 static bool isCalled = false;
208 if (!handle)
209 {
210 handle = anim_add_new_menu(NULL,
211 "Battery Power",
212 false,
213 false,
214 false,
215 BUFSIZ,
216 ANIMFILETYPE_GENERIC);
217 }
218 char name[BUFSIZ];
219 sprintf(name, "%s_BatteryPower", DEVICE_NAME(pb->deviceId));
220 pb->animHandle =
221 anim_add_new_menu(handle,
222 name,
223 true,
224 false,
225 true,
226 BUFSIZ,
227 ANIMFILETYPE_BATTERY);
228}
229
230_declspec(dllexport) void battery_animation()
231{
232 ptrBATTERY b = firstBattery;
233 while (b)
234 {
235 battery_add_to_animation(b);
236 b = b->next;
237 }
238}
239
241{
242 char* mode;
243 int index;
244 int count;
245 double* cols;
246 struct stru_batteryMetrics* next;
247}BATTERYMETRICS, *ptrBATTERYMETRICS;
248static ptrBATTERYMETRICS batteryMetrics = NULL;
249
250static bool isIncludedInMetricsHeading(ptrBATTERYMODE m)
251{
252 ptrBATTERYMETRICS bm = batteryMetrics;
253 while (bm)
254 {
255 if (!_stricmp(m->heading, bm->mode))
256 return true;
257 bm = bm->next;
258 }
259 return false;
260}
261
262static void addInMetricsHeading(ptrBATTERYMODE m)
263{
264 ptrBATTERYMETRICS bm = batteryMetrics;
265 ptrBATTERYMETRICS pbm = NULL;
266 int index = 0;
267 while (bm)
268 {
269 index = bm->index;
270 pbm = bm;
271 bm = bm->next;
272 }
273 index++;
274 ptrBATTERYMETRICS b = calloc(1, sizeof* b);
275 b->index = index;
276 b->mode = m->heading;
277 if (pbm)
278 pbm->next = b;
279 else
280 batteryMetrics = b;
281}
282
283static void prepare_mode_list(char* buf)
284{
285 ptrBATTERY b = firstBattery;
286 while (b)
287 {
288 int i;
289 for (i = 0; i < b->modeCount; i++)
290 {
291 if (!b->mode[i].heading)
292 continue;
293 if (!isIncludedInMetricsHeading(&b->mode[i]))
294 {
295 addInMetricsHeading(&b->mode[i]);
296 strcat(buf, b->mode[i].heading);
297 strcat(buf, "#0,");
298 }
299 }
300 b = b->next;
301 }
302}
303
304static double get_value_from_battery(ptrBATTERY b, char* mode)
305{
306 int i;
307 for (i = 0; i < b->modeCount; i++)
308 {
309 if (!b->mode[i].heading)
310 continue;
311 if (!_stricmp(b->mode[i].heading, mode))
312 return b->mode[i].consumedEnergy;
313 }
314 return -1;
315}
316
317static void add_to_mode_list(ptrBATTERY b)
318{
319 ptrBATTERYMETRICS bm = batteryMetrics;
320 while (bm)
321 {
322 if (bm->count)
323 bm->cols = realloc(bm->cols, (bm->count + 1) * sizeof* bm->cols);
324 else
325 bm->cols = calloc(1, sizeof* bm->cols);
326
327 bm->cols[bm->count] = get_value_from_battery(b, bm->mode);
328 bm->count++;
329 bm = bm->next;
330 }
331}
332
333static void add_to_table(PMETRICSNODE table,
334 int index)
335{
336 ptrBATTERYMETRICS bm = batteryMetrics;
337 while (bm)
338 {
339 add_table_row_formatted(true,
340 table,
341 "%lf,",
342 bm->cols[index]);
343 bm = bm->next;
344 }
345}
346
347_declspec(dllexport) void battery_metrics(PMETRICSWRITER metricsWriter)
348{
349 ptrBATTERY b;
350 static bool isCalled = false;
351 if (isCalled)
352 return;
353 isCalled = true;
354
355 if (!firstBattery)
356 return; // No battery is added
357
358 PMETRICSNODE menu = init_metrics_node(MetricsNode_Menu, "Battery model", NULL);
359 PMETRICSNODE table = init_metrics_node(MetricsNode_Table, "Battery model", NULL);
360 add_node_to_menu(menu, table);
361
362 char modeList[BUFSIZ]="";
363 sprintf(modeList, "Device Name#1,Initial energy(mJ)#1,Consumed energy(mJ)#1,Remaining Energy(mJ)#1,Harvested Energy(mJ)#1,");
364 prepare_mode_list(modeList);
365 add_table_heading_special(table, modeList);
366 b = firstBattery;
367 while (b)
368 {
369 add_to_mode_list(b);
370 b = b->next;
371 }
372
373 int index = 0;
374 b = firstBattery;
375 while (b)
376 {
377 add_table_row_formatted(false, table,
378 "%s,%lf,%lf,%lf,%lf,",
379 DEVICE_NAME(b->deviceId),
380 b->initialEnergy,
381 b->consumedEnergy,
382 b->remainingEnergy,
383 b->rechargingEnergy);
384 add_to_table(table, index);
385 b = b->next;
386 index++;
387 }
388 write_metrics_node(metricsWriter, WriterPosition_Current, NULL, menu);
389 delete_metrics_node(menu);
390}
391
392_declspec(dllexport) double battery_get_remaining_energy(ptrBATTERY battery)
393{
394 return battery->remainingEnergy;
395}
396
397_declspec(dllexport) double battery_get_consumed_energy(ptrBATTERY battery, int mode)
398{
399 if (!mode)
400 return battery->consumedEnergy;
401 int i;
402 for (i = 0; i < battery->modeCount; i++)
403 {
404 if (battery->mode[i].mode == mode)
405 return battery->mode[i].consumedEnergy;
406 }
407 return 0;
408}
409