This article explains how to perform OPC communication between ActionScript SCADA software and MATLAB.
Reading and Writing in Tags
For this example, a project was created in Action.NET with two Tags: POT_1 and AMP_1.
In Action.NET, simply upload the project with the OPC Server connected.
MATLAB needs to be a newer version than 2012, with the OPC Toolbox installed.
Here is the code used:
% OPC Connection:
da = opcda('localhost', 'Action.NET.OPCDAServer.2');
connect(da);
grp = addgroup(da);
itm1 = additem(grp, 'Tag.POT_1');
itm2 = additem(grp, 'Tag.AMP_1');
POT_1 = read(itm1); %Reads value from itm1(Tag.POT_1)and keeps it
in the variable POT_1.
write(itm2, 12); %Writes at itm2(Tag.AMP_1) the value 12.
OBS.: when reading itm1 and saving it in variable POT_1, the variable POT_1 becomes a variable of type STRUC with the following structure:
POT_1 =
ItemID: 'Tag.POT_1'
Value: 0.2635
Quality: 'Good: Non-specific'
TimeStamp: [2016 7 21 9 44 37.4610]
Error: ''
Therefore, to access its value we must access it through the command:
POT_1.Value
ans =
0.2635
Power Flow with MATPOWER
In this example, a library called MATPOWER will be used, which gives us a power flow function of a modeled network.
For this, it is necessary to have a modeled network (Annex 2.1: case1_2) and all files must be within the MATPOWER directory.
In the following example, the network was modeled with only 2 buses. In the first, a source with constant voltage equal to 1 phase 0º p.u. And in the second one is connected a load consuming the power that will be read of Tag.POT_1.
The Program will read the power value of Tag.POT_1 (in MW) and calculate the current (in p.u.) in the branch that joins the two bars.
Real Time
clear;
close;
clc;
% OPC Connection:
da = opcda('localhost', 'Action.NET.OPCDAServer.2');
connect(da);
grp = addgroup(da);
itm1 = additem(grp, 'Tag.POT_1');
itm2 = additem(grp, 'Tag.AMP_1');
TEMPO = 5 * 60; %Sets the simulation time
Q = (sqrt(1-(0.92*0.92)))/0.92; %Conversion factor from active to reactive power (FP 0,92)
mpc = runpf('case1_2');
%% Simulation
for i = 1:TEMPO;
POT_1 = read(itm1); %Reads the value itm1(Tag.POT_1) and keeps it in the variable POT_1.
mpc.bus(2,3) = POT_1.Value;
mpc.bus(2,4) = Q * POT_1.Value;
save 'TempoReal';
disconnect(da);
mpc = runpf('TempoReal'); %Load Flow
connect(da);
AMP_1 = sqrt((mpc.branch(1,14) + mpc.branch(1,16))/mpc.branch(1,3));
write(itm2, AMP_1); %Writes in itm2(Tag.AMP_1) the value of the variable AMP_1.
end
disconnect(da);
OBS.: all files will be attached. Just run the file TempoReal.m.
Annex
Case1_2
function mpc = case1_2
%CASE9 Power flow data for 9 bus, 3 generator case.
% Please see CASEFORMAT for details on the case file format.
%
% Based on data from Joe H. Chow's book, p. 70.
% MATPOWER
% $Id: case9.m 1559 2010-03-10 18:08:32Z ray $
%% MATPOWER Case Format : Version 2
mpc.version = '2';
%%----- Power Flow Data -----%%
%% system MVA base
mpc.baseMVA = 2;
%% bus data
% bus_i type Pd Qd Gs Bs area Vm Va baseKV zone Vmax Vmin
mpc.bus = [
1 3 0.00000 0.00000 0 0 1 1 0 13.8 1 1.1 0.9 ;
2 1 0.00000 0.00000 0 0 1 1 0 13.8 1 1.1 0.9 ;
];
%% generator data
% bus Pg Qg Qmax Qmin Vg mBase status Pmax Pmin Pc1 Pc2 Qc1min Qc1max Qc2min Qc2max ramp_agc ramp_10 ramp_30 ramp_q apf
mpc.gen = [
1 0 0 0 0 1 1 1 300 1;
];
%% branch data
% fbus tbus r x b rateA rateB rateC ratio angle status angmin angmax
mpc.branch = [
1 2 0.9 0.4 0 250 250 250 0 0 1 -360 360;
];
%%----- OPF Data -----%%
% %% area data
% % area refbus
% mpc.areas = [
% 1 5;
% ];
%
% %% generator cost data
% % 1 startup shutdown n x1 y1 ... xn yn
% % 2 startup shutdown n c(n-1) ... c0
% mpc.gencost = [
% 2 1500 0 3 0.11 5 150;
% 2 2000 0 3 0.085 1.2 600;
% 2 3000 0 3 0.1225 1 335;
% ];