From 78d81375b82a9eae1796e8f044cabf694072acb9 Mon Sep 17 00:00:00 2001 From: Paulo Meira <10246101+PMeira@users.noreply.github.com> Date: Wed, 30 Oct 2024 12:33:19 -0300 Subject: [PATCH] Fix missing `calllib` arguments in: `Monitors.Channel`, `Monitors.AsMatrix`, `Monitors.dblFreq`, `Monitors.dblHour`, `ActiveCktElement.Properties` `Monitors.AsMatrix` also had a separate issue. Example updated to test the affected functions. Closes #20 --- +DSS_MATLAB/ICktElement.m | 4 ++-- +DSS_MATLAB/IMonitors.m | 10 ++++----- examples/13Bus.zip | Bin 8024 -> 8535 bytes examples/13Bus/run.m | 43 +++++++++++++++++++++++++++++++++++--- 4 files changed, 47 insertions(+), 10 deletions(-) diff --git a/+DSS_MATLAB/ICktElement.m b/+DSS_MATLAB/ICktElement.m index 79d7092..7da0b49 100644 --- a/+DSS_MATLAB/ICktElement.m +++ b/+DSS_MATLAB/ICktElement.m @@ -160,9 +160,9 @@ function result = Properties(obj, NameOrIdx) if ischar(NameOrIdx) || isstring(NameOrIdx) - calllib('dss_capi', 'ctx_DSSProperty_Set_Name', obj.dssctx, NameOrIdx); + calllib(obj.libname, 'ctx_DSSProperty_Set_Name', obj.dssctx, NameOrIdx); elseif isinteger(NameOrIdx) - calllib('dss_capi', 'ctx_DSSProperty_Set_Index', obj.dssctx, NameOrIdx); + calllib(obj.libname, 'ctx_DSSProperty_Set_Index', obj.dssctx, NameOrIdx); else ME = MException(['DSS_MATLAB:Error'], 'Expected char, string or integer'); throw(ME); diff --git a/+DSS_MATLAB/IMonitors.m b/+DSS_MATLAB/IMonitors.m index 1ca3619..2de916a 100644 --- a/+DSS_MATLAB/IMonitors.m +++ b/+DSS_MATLAB/IMonitors.m @@ -63,14 +63,14 @@ result = 0; return end - calllib('ctx_Monitors_Get_Channel_GR', obj.dssctx, Index); + calllib(obj.libname, 'ctx_Monitors_Get_Channel_GR', obj.dssctx, Index); obj.CheckForError(); result = obj.apiutil.get_float64_gr_array(); end function result = AsMatrix(obj) % Matrix of the active monitor, containing the hour vector, seconds vector, and all channels (index 3 = channel 1) - calllib('ctx_Monitors_Get_ByteStream_GR', obj.dssctx); + calllib(obj.libname, 'ctx_Monitors_Get_ByteStream_GR', obj.dssctx); obj.CheckForError(); buffer = obj.apiutil.get_int8_gr_array(); if (numel(buffer) <= 1) @@ -80,7 +80,7 @@ record_size = typecast(buffer, 'int32'); record_size = record_size(3) + 2; data = typecast(buffer(273:end), 'single'); - data = reshape(data, [int32(data.size() / record_size), record_size]); + data = reshape(data, [record_size, size(data, 2) / record_size]); result = data; end @@ -227,14 +227,14 @@ function result = get.dblFreq(obj) % (read-only) Array of doubles containing frequency values for harmonics mode solutions; Empty for time mode solutions (use dblHour) - calllib('ctx_Monitors_Get_dblFreq_GR', obj.dssctx); + calllib(obj.libname, 'ctx_Monitors_Get_dblFreq_GR', obj.dssctx); obj.CheckForError(); result = obj.apiutil.get_float64_gr_array(); end function result = get.dblHour(obj) % (read-only) Array of doubles containgin time value in hours for time-sampled monitor values; Empty if frequency-sampled values for harmonics solution (see dblFreq) - calllib('ctx_Monitors_Get_dblHour_GR', obj.dssctx); + calllib(obj.libname, 'ctx_Monitors_Get_dblHour_GR', obj.dssctx); obj.CheckForError(); result = obj.apiutil.get_float64_gr_array(); end diff --git a/examples/13Bus.zip b/examples/13Bus.zip index 9cd28f330428b7cb9c2743316b888614526a0360..13b011b893360c349bbd83349761ee88d55adef6 100644 GIT binary patch delta 2593 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 N`9g->S?Vt$`~#}I%H#k5 delta 2151 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 DVbAOq diff --git a/examples/13Bus/run.m b/examples/13Bus/run.m index 18885e0..da0eabf 100644 --- a/examples/13Bus/run.m +++ b/examples/13Bus/run.m @@ -52,6 +52,8 @@ Solution = DSS.ActiveCircuit.Solution; Bus = DSS.ActiveCircuit.ActiveBus; Load = DSS.ActiveCircuit.Loads; +Monitors = DSS.ActiveCircuit.Monitors; +CE = DSS.ActiveCircuit.ActiveCktElement; % You can get some very basic description of the properties for most of the % objects: @@ -115,20 +117,55 @@ ylabel('Bus Y coordinate'); ylabel(handle, 'Voltage (pu)'); +%% Monitors, including the AsMatrix function (API extension) + +% Let's edit the circuit to add some variation, add a monitor, and solve +Text.Command = 'BatchEdit Load..* Daily=default'; +Text.Command = 'New Monitor.test Element=Transformer.Sub Mode=1'; +Solution.Mode = int32(DSS_MATLAB.SolveModes.Daily); +Solution.Solve(); + +% Now plot the first channel of the monitor +figure; +Monitors.Name = 'test'; +plot(Monitors.dblHour, Monitors.Channel(1)); +Monitors.dblHour +xlabel('Time (h)'); +header = Monitors.Header(); +ylabel(header(1)); + +% We can also get all data as a matrix; the first two columns are the +% integer hours and seconds (for a time solution) +figure; +mon_mat = Monitors.AsMatrix(); +h = mon_mat(1, :) + mon_mat(2, :) / 3600; +plot(h, mon_mat(3:end, :)); +xlabel('Time (h)'); +legend(header); + +%% Raw DSS properties + +% Although the Text interface can be convenient to read properties not +% exposed by the API, OpenDSS also provides a dedicated Properties API +% that can be useful for elements that don't have dedicated APIs. +Circuit.SetActiveElement('Transformer.Sub') +Prop = CE.Properties('Windings'); +fprintf('Property Name: %s, Value: %s', Prop.Name, Prop.Val); + %% Loading circuits from ZIP files (API extension, not available in the official OpenDSS) DSS.ClearAll(); ZIP = DSS.ZIP; -ZIP.Open('../13Bus.zip') +ZIP.Open('../13Bus.zip'); ZIP.List() % Running the DSS script directly from the ZIP. % This also restricts loading most files only from the ZIP archive, % so you have to use relative paths. -ZIP.Redirect('13Bus/IEEE13Nodeckt.dss') +ZIP.Redirect('13Bus/IEEE13Nodeckt.dss'); -ZIP.Close() +ZIP.Close(); DSS.ActiveCircuit.NumBuses