Why does my running total resets after few weeks? - scada

I have managed to write a code which counts running total on Citect Scada using Cicode-language. Now I have a problem because it seems that my loop has somehow reset my counter. I'm pretty new to this.
At this point, I don't know what causes this. This morning total was around 1480 before reset happened and I'm using INT as datatype. Counter has been active for about few weeks now. I'm using Citect Scada 6.1V.
FUNCTION Laskuri()
INT iState14 =0
INT iState15
WHILE 1 DO
Sleep(3600)
iState15 = ReadVar(5,"Ar",59)
iState14 = iState14 + iState15;
SetVar(5,"Ar", 58, iState14);
END
END

Related

Matlab ROS slow publishing + subscribing

In my experience Matlab performs publish subscribe operations with ROS slow for some reason. I work with components as defined in an object class as shown below, where I made a test-class. Normally objects of comparable structure are used to control mobile robots.
To quantify performance tested required time for an operation and got the following results:
1x publishing a message + 1x simple subscriber callback : 3.7ms
Simply counting in a callback (per count): 2.1318e-03 ms
Creating a new message with msg1 = rosmessage(obj.publisher) adds 3.6-4.3ms per iteration
Pinging myself indicated communication latency of 0.05 ms
The times required for a simple publish + start of a subscribe callback seems oddly slow.
I want to have multiple system components as objects in my workspace such that they respond to ROS topic updates or on timer events. The pc used for testing is not a monster but should not be garbage either.
Do you also think the shown time requirements are unneccesary large? this allows barely to publish a single topic at 200hz without doing anything else. Normally I have multiple lower frequency topics (e.g.20hz) but the total consumed time becomes significant.
Do you know any practices to make the system operate quicker?
What do you think of the OOP style of making control system components in general?
classdef subpubspeedMonitor < handle
% Use: call in matlab console, after initializing ros:
%
% SPM1 = subpubspeedMonitor()
%
% This will create an object which starts a set repetitive task upon creation
% and finally destructs itself after posting results in console.
properties
node
subscriber
publisher
timestart
messagetotal
end
methods
function obj = subpubspeedMonitor()
obj.node = ros.Node('subspeedmonitor1');
obj.subscriber = ros.Subscriber(obj.node,'topic1','sensor_msgs/NavSatFix',{#obj.rosSubCallback});
obj.publisher = ros.Publisher(obj.node,'topic1','sensor_msgs/NavSatFix');
obj.timestart = tic;
obj.messagetotal = 0;
msg1 = rosmessage(obj.publisher);
% Choose to evaluate subscriber + publisher loop or just counting
if 1
send(obj.publisher,msg1);
else
countAndDisplay(obj)
end
end
%% Test method one: repetitive publishing and subscribing
function rosSubCallback(obj,~,msg_) % ~3.7 ms per loop for a simple publish+subscribe action
% Latency to self is 0.05ms on average, according to "pinging" in terminal
obj.messagetotal = obj.messagetotal+1;
if obj.messagetotal <10000
%msg1 = rosmessage(obj.publisher); % this line adds 4.3000ms per loop
msg_.Longitude = 51; % this line adds 0.25000 ms per loop
send(obj.publisher,msg_)
else
% Display some results
timepassed = toc(obj.timestart);
time_per_pubsub = timepassed/obj.messagetotal
delete(obj);
end
end
%% Test method two: simply counting
function countAndDisplay(obj) % this costs 2.1318e-03 ms(!) per loop
obj.messagetotal = obj.messagetotal+1;
if obj.messagetotal <10000
%msg1 = rosmessage(obj.publisher); %adds 3.6ms per loop
%i = 1% adds 5.7532e-03 ms per loop
%msg1 = rosmessage("std_msgs/Bool"); %adds 1.5ms per loop
countAndDisplay(obj);
else
% Display some results
timepassed = toc(obj.timestart);
time_per_count_FCN = timepassed/obj.messagetotal
delete(obj);
end
end
%% Deconstructor
function delete(obj)
delete(obj.subscriber)
delete(obj.publisher)
delete(obj.node)
end
end
end

How to run one type of simulation for multiple times under one loop to get a series of different results?

Py newbie here (really though, I literally started yesterday)
Im basically trying to do a coin flip simulation, and its based on a BIASED distribution!
Following are the inputs needed for the sim
#prob_up (success) = 0.472835862
#prob_down(fail) = 0.527164138
#up_scale(rate of increase) = 0.091889211
#down_scale(rate of decrease) = -0.061319729
#value = 1
Below is what I did
```for i in range(30):
toss_outcome = np.random.random()
if toss_outcome <= prob_up:
value += value*(up_scale)
if toss_outcome > 1-prob_up:
value += value*(down_scale)
print(value)```
So this one works for me, but I would like to ask you how I could repeat this simulation for 100 times under one loop so that I can get something like 1.1, 1.09, 2.1, 0.98, 1.7, 0.89...
This is what I tried
#value =1
#count = 0
```for i in range(10):
count = 0
sims = []
for x in range(20):
toss_outcome = np.random.random()
if toss_outcome <= prob_up:
value+= value*(up_scale)
if toss_outcome > 1-prob_down:
value+= value*(down_scale)
if count == 20:
break
sims.append(value)
print(sims) ```
This is what I got
1.0918892105282665, 1.192222048068041, 1.3017743908394064, 1.2219499374001699, 1.1470202978485873, 1.0766853235214044, 1.1756210878871576, 1.1035323208530166, ...1.5467124250543491, 1.4518684376272906, 1.362840257848346, 1.4880705732181698 #Series 1
1.6248082034015325, 1.7741105464719504, 1.9371321639771295, 1.8183477437909779, 1.7068471521124233, 1.602183746548087, 1.5039382726953088, 1.4117171847179661, 1.541438762310887... #Series 2
So what happened here is that the new series simply continued from the previous one, instead of starting a new series of simulation from value = 1...
Id sincerely appreciate your help! Have a wonderful day.

Pinescript duplicate alerts

I have created a very basic script in pinescript.
study(title='Renko Strat w/ Alerts', shorttitle='S_EURUSD_5_[MakisMooz]', overlay=true)
rc = close
buy_entry = rc[0] > rc[2]
sell_entry = rc[0] < rc[2]
alertcondition(buy_entry, title='BUY')
alertcondition(sell_entry, title='SELL')
plot(buy_entry/10)
The problem is that I get a lot of duplicate alerts. I want to edit this script so that I only get a 'Buy' alert when the previous alert was a 'Sell' alert and visa versa. It seems like such a simple problem, but I have a hard time finding good sources to learn pinescript. So, any help would be appreciated. :)
One way to solve duplicate alters within the candle is by using "Once Per Bar Close" alert. But for alternative alerts (Buy - Sell) you have to code it with different logic.
I Suggest to use Version 3 (version shown above the study line) than version 1 and 2 and you can accomplish the result by using this logic:
buy_entry = 0.0
sell_entry = 0.0
buy_entry := rc[0] > rc[2] and sell_entry[1] == 0? 2.0 : sell_entry[1] > 0 ? 0.0 : buy_entry[1]
sell_entry := rc[0] < rc[2] and buy_entry[1] == 0 ? 2.0 : buy_entry[1] > 0 ? 0.0 : sell_entry[1]
alertcondition(crossover(buy_entry ,1) , title='BUY' )
alertcondition(crossover(sell_entry ,1), title='SELL')
You'll have to do it this way
if("Your buy condition here")
strategy.entry("Buy Alert",true,1)
if("Your sell condition here")
strategy.entry("Sell Alert",false,1)
This is a very basic form of it but it works.
You were getting duplicate alerts because the conditions were fulfulling more often. But with strategy.entry(), this won't happen
When the sell is triggered, as per paper trading, the quantity sold will be double (one to cut the long position and one to create a short position)
PS :You will have to add code to create alerts and enter this not in study() but strategy()
The simplest solution to this problem is to use the built-in crossover and crossunder functions.
They consider the entire series of in-this-case close values, only returning true the moment they cross rather than every single time a close is lower than the close two candles ago.
//#version=5
indicator(title='Renko Strat w/ Alerts', shorttitle='S_EURUSD_5_[MakisMooz]', overlay=true)
c = close
bool buy_entry = false
bool sell_entry = false
if ta.crossover(c[1], c[3])
buy_entry := true
alert('BUY')
if ta.crossunder(c[1], c[3])
sell_entry := true
alert('SELL')
plotchar(buy_entry, title='BUY', char='B', location=location.belowbar, color=color.green, offset=-1)
plotchar(sell_entry, title='SELL', char='S', location=location.abovebar, color=color.red, offset=-1)
It's important to note why I have changed to the indices to 1 and 3 with an offset of -1 in the plotchar function. This will give the exact same signals as 0 and 2 with no offset.
The difference is that you will only see the character print on the chart when the candle actually closes rather than watch it flicker on and off the chart as the close price of the incomplete candle moves.

Visual Studio 2013 SerialPort not receiving all data

I am currently working on a project that requires serial communication between PIC 24FV16KA302 and a PC software.
I have searched the Internet for the past 3 days and i cant find an answer for my problem so i decided to ask here . This is my first visual studio program so i dont have any experience with the software.
The PIC has few variables and two 8x16 tables that i need to view and modify on the PC side . The problem comes when i send the tables , all other information is received without a problem . I am using serial connection ( 38400/8-N-1 ) via uart to usb converter
FT232
When the PC send "AT+RTPM" to the PIC .
Button7.Click
SerialPort1.ReceivedBytesThreshold = 128
MachineState = MS.Receive_table
SerialPort1.Write("AT+RTPM")
End Sub
The PIC sends back 128 Bytes( the values in the table )
case read_table_pwm : // send pwm table
for (yy = 0 ; yy < 8 ; yy ++) {
for (xx = 0 ; xx < 16 ; xx++ ) {
uart_send_char(controll_by_pmw_map_lb[yy][xx]) ;
}
}
at_command = receive_state_idle ;
break ;
Which the software is suppose to get and display in a DataGrid.
Private Sub SerialPort1_DataReceived(sender As Object, e As IO.Ports.SerialDataReceivedEventArgs) Handles SerialPort1.DataReceived
If MachineState = MS.Receive_table Then
SerialPort1.Read(Buffer_array_received_data, 0, 128)
cellpos = 0
For grid_y As Int16 = 0 To 7 Step 1
For grid_x As Int16 = 0 To 15 Step 1
DataGridView1.Rows(grid_y).Cells(grid_x).Value = Buffer_array_received_data(cellpos)
cellpos += 1
Next
Next
End Sub
The problem is that most of the time ( 99 % ) it displays only part of the dataset and zeros to the end , and when i try to do it again it display the other part and it starts from the beginning .
First request
Second request
If i try the same thing with another program i always get the full dataset
Realterm
Termite
I have tried doing it cell by cell , but it only works if i request them one very second , other wise i get the same problem .
After that i need to use a timer ( 100 ms ) to request live data from the PIC .
this work better but still some of the time i get some random data. I haven't focused on that for the moment because without the dataset everything else is useless .
Am i missing something or has anyone encountered the same problem ?
I managed to solve the problem by replacing
SerialPort1.Read(Buffer_array_received_data, 0, 128)
with
For byte_pos As Int16 = 0 To 127 Step 1
Buffer_array_received_data(byte_pos) = SerialPort1.ReadByte()
Next
But aren't they supposed to be the same ?

Calculate time remaining with different length of variables

I will have to admit the title of this question sucks... I couldn't get the best description out. Let me see if I can give an example.
I have about 2700 customers with my software at one time was installed on their server. 1500 or so still do. Basically what I have going on is an Auto Diagnostics to help weed out people who have uninstalled or who have problems with the software for us to assist with. Currently we have a cURL fetching their website for our software and looking for a header return.
We have 8 different statuses that are returned
GREEN - Everything works (usually pretty quick 0.5 - 2 seconds)
RED - Software not found (usually the longest from 5 - 15 seconds)
BLUE - Software found but not activated (usually from 3 - 9 seconds)
YELLOW - Server IP mismatch (usually from 1 - 3 seconds)
ORANGE - Server IP mismatch and wrong software type (usually 5 - 10 seconds)
PURPLE - Activation key incorrect (usually within 2 seconds)
BLACK - Domain returns 404 - No longer exists (usually within a second)
UNK - Connection failed (usually due to our load balancer -- VERY rare) (never countered this yet)
Now basically what happens is a cronJob will start the process by pulling the domain and product type. It will then cURL the domain and start cycling through the status colors above.
While this is happening we have an ajax page that is returning the results so we can keep an eye on the status. The major problem is the Time Remaining is so volatile that it does not do a good estimate. Here is the current math:
# Number of accounts between NOW and when started
$completedAccounts = floor($parseData[2]*($parseData[1]/100));
# Number of seconds between NOW and when started
$completedTime = strtotime("now") - strtotime("$hour:$minute:$second");
# Avg number of seconds per account
$avgPerCompleted = $completedTime / $completedAccounts;
# Total number of remaining accounts to be scanned
$remainingAccounts = $parseData[2] - $completedAccounts;
# The total of seconds remaining for all of the remaining accounts
$remainingSeconds = $remainingAccounts * $avgPerCompleted;
$remainingTime = format_time($remainingSeconds, ":");
I could create a count on all of the green, red, blue, etc... and do an average of how long each color does, then use that for the average time, although I don't believe that would give much better results.
With the difference in times that are so varied, any suggestions would be grateful?
Thanks,
Jeff
OK, I believe I have figured it out. I had to create a class so I could calculate a single regression over a period of time.
function calc() {
$n = count($this->mDatas);
$vSumXX = $vSumXY = $vSumX = $vSumY = 0;
//var_dump($this->mDatas);
$vCnt = 0; // for time-series, start at t=0<br />
foreach ($this->mDatas AS $vOne) {
if (is_array($vOne)) { // x,y pair<br />
list($x,$y) = $vOne;
} else { // time-series<br />
$x = $vCnt; $y = $vOne;
} // fi</p>
$vSumXY += $x*$y;
$vSumXX += $x*$x;
$vSumX += $x;
$vSumY += $y;
$vCnt++;
} // rof
$vTop = ($n*$vSumXY – $vSumX*$vSumY);
$vBottom = ($n*$vSumXX – $vSumX*$vSumX);
$a = $vBottom!=0?$vTop/$vBottom:0;
$b = ($vSumY – $a*$vSumX)/$n;
//var_dump($a,$b);
return array($a,$b);
}
I take each account and start building an array, for the amount of time it takes for each one. The array then runs through this calculation so it will build a x and y time sets. Finally I then run the array through the predict function.
/** given x, return the prediction y */
function calcpredict($x) {
list($a,$b) = $this->calc();
$y = $a*$x+$b;
return $y;
}
I put static values in so you could see the results:
$eachTime = array(7,1,.5,12,11,6,3,.24,.12,.28,2,1,14,8,4,1,.15,1,12,3,8,4,5,8,.3,.2,.4,.6,4,5);
$forecastProcess = new Linear($eachTime);
$forecastTime = $forecastProcess->calcpredict(5);
This overall system gives me about a .003 difference in 10 accounts and about 2.6 difference in 2700 accounts. Next will be to calculate the Accuracy.
Thanks for trying guys and gals

Resources