Being new in PLC programming, I am struggling with the programming of countdown timer in PLC.
I want to add a countdown timer for 90 days that will be reset to again 90 days once the button on HMI is pressed. The countdown time should be shown on the HMI display. No IO connected, only countdown timer.
You question is too wide in my opinion. Have you tried to solve it yourself? What is the PLC environment you are using?
Here is something for start, perhaps?
When the button is pressed, save current timestamp to a variable and clear reset request
Every PLC cycle: Calculate difference with that saved variable and current timestamp. Save the difference to variable and show in HMI.
if difference > 90 days, set reset request and go to step 1
Edit: Here is a working program for Infoteam OpenPCS. I have never used it before but had to test it for curiosity. I managed to get current datetime but it wasn't possible to convert to DWORD for calculation, so I used this kind of approach (Sergey, do you know how to do it? I tried to convert it using POINTER but couldn't dereference it..) I haven't tested it for longer delays, so please note that it might not be 100% working.
It calculates 60 second intervals (=minutes) and when enough minutes are passed, timer stops. Note that the minutes should be saved to persistent memory if power losses etc. shouldn't affect it.
VAR
RunTimer : BOOL;
MinutesElapsed : UDINT;
StartTime : TIME;
TimeDifference : TIME;
END_VAR
IF RunTimer THEN
IF StartTime = t#0s THEN
StartTime := GetTime(StartTime);
END_IF;
TimeDifference := GetTime(StartTime);
(*IF one minute has elapsed*)
IF TimeDifference >= t#1m THEN
MinutesElapsed := MinutesElapsed + 1;
(*Reset StartTime to start minute over*)
StartTime := t#0s;
END_IF;
(*IF enough minutes has passed, stop (90*24*60 = 90 days)*)
IF MinutesElapsed >= (90 * 24 * 60) THEN
RunTimer := false;
StartTime := t#0s;
TimeDifference := t#0s;
MinutesElapsed := 0;
END_IF;
else
(*Time is not running*)
StartTime := t#0s;
TimeDifference := t#0s;
MinutesElapsed := 0;
(*Here we would set RunTimer to TRUE when button is pressed to start time again*)
END_IF;
Related
I use the following Code to execute an export data pump.
set serveroutput on;
DECLARE
ind NUMBER; -- Loop index
h1 NUMBER; -- Data Pump job handle
percent_done NUMBER; -- Percentage of job complete
job_state VARCHAR2(30); -- To keep track of job state
le ku$_LogEntry; -- For WIP and error messages
js ku$_JobStatus; -- The job status from get_status
jd ku$_JobDesc; -- The job description from get_status
sts ku$_Status; -- The status object returned by get_status
>>>>>>>>>>>>>>v_systimestamp TIMESTAMP := SYSTIMESTAMP;<<<<<<<<<<<<<<
BEGIN
h1 := DBMS_DATAPUMP.OPEN('EXPORT','SCHEMA',NULL,'EXAMPLE3','LATEST');
DBMS_DATAPUMP.ADD_FILE(h1, 'dumpfile.dmp', 'EXPORT_DIRECTORY', NULL, DBMS_DATAPUMP.KU$_FILE_TYPE_DUMP_FILE, 1);
DBMS_DATAPUMP.METADATA_FILTER(h1,'SCHEMA_EXPR','IN (''SchemaName'')');
DBMS_DATAPUMP.START_JOB(h1);
percent_done := 0;
job_state := 'UNDEFINED';
while (job_state != 'COMPLETED') and (job_state != 'STOPPED') loop
DBMS_OUTPUT.PUT_LINE(v_systimestamp);
dbms_datapump.get_status(h1,
dbms_datapump.ku$_status_job_error +
dbms_datapump.ku$_status_job_status +
dbms_datapump.ku$_status_wip,-1,job_state,sts);
js := sts.job_status;
-- If the percentage done changed, display the new value.
if js.percent_done != percent_done
then
dbms_output.put_line('*** Job percent done = ' ||
to_char(js.percent_done));
percent_done := js.percent_done;
end if;
-- If any work-in-progress (WIP) or error messages were received for the job,
-- display them.
if (bitand(sts.mask,dbms_datapump.ku$_status_wip) != 0)
then
le := sts.wip;
else
if (bitand(sts.mask,dbms_datapump.ku$_status_job_error) != 0)
then
le := sts.error;
else
le := null;
end if;
end if;
if le is not null
then
ind := le.FIRST;
while ind is not null loop
>>>>>>>>>>>>>>DBMS_OUTPUT.PUT_LINE(v_systimestamp);<<<<<<<<<<<<<<
dbms_output.put_line(le(ind).LogText);
ind := le.NEXT(ind);
end loop;
end if;
end loop;
-- Indicate that the job finished and detach from it.
dbms_output.put_line('Job has completed');
dbms_output.put_line('Final job state = ' || job_state);
dbms_datapump.detach(h1);
END;
The problem is that the export takes too long. It takes 25 minutes with this SQL Code. The Size of the schema is 1.8 GB.
And I would like to find out how much time individual steps take. That's why I want to insert a timestamp in after each process step. Then I can see how long individual steps need.
I have marked the code for the timestamp with (>>>> <<<<) in the code.
The timestamp is not updating the time. I need the CURRENT time after each process. Can you help me?
In your code, you are setting the value of v_systimestamp at the beginning of your script - this will not change throughout the script run. You can reset the value before you log like:
v_systimestamp TIMESTAMP := SYSTIMESTAMP
DBMS_OUTPUT.PUT_LINE(v_systimestamp)
or doing something like the following before and after each section you want to monitor (no variable required):
DBMS_OUTPUT.PUT_LINE('Time Started: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));
DBMS_OUTPUT.PUT_LINE('Time Ended: ' || TO_CHAR(SYSDATE, 'DD-MON-YYYY HH24:MI:SS'));
Here example 'CURRENT_TIMESTAMP'
curDateTime TIMESTAMP := CURRENT_TIMESTAMP ;
DBMS_OUTPUT.PUT_LINE('CUR TIME '|| curDateTime);
If a procedure you run takes a long time, DBMS_OUTPUT.PUT_LINE won't help much. Well, it will display something, but - as you use a loop, depending on number of iterations, DBMS_OUTPUT might run out of buffer size or exceed number of visible lines in SQL*Plus (if you use it) and you'll lose part of the output.
Besides, you won't see a single letter of the DBMS_OUTPUT.PUT_LINE until the procedure finishes.
Therefore, I'd suggest you to use another approach - a simple logging which requires a table, a sequence and an (autonomous transaction) procedure. Here's the script:
CREATE TABLE a1_log
(
id NUMBER,
datum DATE,
descr VARCHAR2 (500)
);
CREATE SEQUENCE seqlognap START WITH 1 INCREMENT BY 1;
CREATE OR REPLACE PROCEDURE a1_p_log (par_descr IN VARCHAR2)
IS
PRAGMA AUTONOMOUS_TRANSACTION;
BEGIN
INSERT INTO a1_log
SELECT seqlognap.NEXTVAL, SYSDATE, par_descr FROM DUAL;
COMMIT;
END a1_p_log;
Then put A1_P_LOG calls into your own procedure; something like
begin
a1_p_log('selecting from a large table');
select ... into ... from ...;
a1_p_log('entering the loop');
while ... loop
a1_p_log('doing something');
end loop;
a1_p_log('the end');
end;
Here's where the autonomous transaction matters - it'll commit inserts into the log table (without affecting the main transaction), so you can (in another session, of course) trace the execution, simply by repeatedly issuing
SELECT *
FROM a1_log
ORDER BY id;
It'll show (imaginary example):
1 22.05.2018 18:13:00 selecting from a large table
2 22.05.2018 18:20:07 entering the loop
3 22.05.2018 18:20:07 doing something
4 22.05.2018 18:20:08 doing something
5 22.05.2018 18:20:09 doing something
6 22.05.2018 18:20:10 the end
and you'll see that step 1 takes 7 minutes to execute, so - that's what you need to investigate. It means that you don't have to wait the main procedure to finish - cancel it and start working on the bottleneck. Once you fix it, run everything again.
i have below code i want to show date according to hours how to add 48 hours in my current date please help me in this i am new in angularjs.
"startjob_datetime" : ISODate("2017-03-13T14:21:12.231Z"),
var hours = 48 ;
var startdate = new Date(schedule_entry.startjob_datetime);
var enddate = new Date(schedule_entry.startjob_datetime).setHours(hours );
i want enddate = ISODate("2017-03-15T14:21:12.231Z"),
but its not working please check
and if normal working hours is 8 , than how to change date according to this, because 48 hours means two days, but if 8 hours normal duty time , it is almost 5 days
"startjob_datetime" : ISODate("2017-03-13T14:21:12.231Z"),
var hours = 48 * 60 * 60 * 1000 ; //Since 1hr = 60 mins, 1 min = 60 seconds, 1 second= 1000 milliseconds
var startdate = new Date(schedule_entry.startjob_datetime);
var enddate = new Date(schedule_entry.startjob_datetime).getTime() + hours ;
);
//This will give you endDate in milliseconds
//And replace 48 with whatever hours you want to add to the start date
// Create the prepared statement and use it to
// INSERT the student attributes INTO the Student table.
PreparedStatement pstmt = conn.prepareStatement(
"INSERT INTO Review VALUES (?, ?, ?, ?)");
pstmt.setInt(1, Integer.parseInt(request.getParameter("section_id")));
pstmt.setString(2, request.getParameter("quarter"));
pstmt.setInt(3, Integer.parseInt(request.getParameter("year")));
pstmt.setTime(4, ????)
Can anyone tell me how can i read values with the type Time?? Lets say time like "16:34"? How can I define a pattern and read it?
You need to do this.
public static java.sql.Time getCurrentJavaSqlTime(String time) {
Date date = new SimpleDateFormat("HH:mm", Locale.ENGLISH).parse(time); //Convert to Date
return new java.sql.Time(date.getTime()); //Now to time
}
java.sql.Time time = getCurrentJavaSqlTime("16:34");
System.out.println("time=" + time);
pstmt.setTime(4,time);
Use format patterns to work with yout String.
H Hour in day (0-23) Number 0
k Hour in day (1-24) Number 24
K Hour in am/pm (0-11) Number 0
h Hour in am/pm (1-12) Number 12
m Minute in hour Number 30
To obtain from user try this
java.sql.Time time = getCurrentJavaSqlTime((String)request.getParameter("time"));
pstmt.setTime(4,time);
I want to create a task reminder (which the user add it to the database with a start date spot) every two weeks from the date already entered in the database. Based on the position of the day in the week, I made a try but to no avail, if someone has an idea I would be grateful
cmd5.CommandText = "select * from task where frequence='2W' "
da5.SelectCommand = cmd1
da5.Fill(ds5, "0")
DataGridView6.Columns.Add("fr", "fr")
DataGridView6.Columns.Add("class", "class")
For i As Integer = 0 To ds5.Tables(0).Rows.Count - 1
If Date.Now.DayOfWeek > 3 Then
If CType(ds5.Tables(0).Rows(i).Item(3), Date).DayOfWeek = Date.Now.DayOfWeek Or CType(ds5.Tables(0).Rows(i).Item(3), Date).DayOfWeek - ???? = Date.Now.DayOfWeek Then
DataGridView6.Rows.Add(ds5.Tables(0).Rows(i).Item(4), CType(ds5.Tables(0).Rows(i).Item(3), Date).DayOfWeek)
End If
End If
If Date.Now.DayOfWeek < 4 And Date.Now.DayOfWeek <> 0 Then
If CType(ds5.Tables(0).Rows(i).Item(3), Date).DayOfWeek = Date.Now.DayOfWeek Or CType(ds5.Tables(0).Rows(i).Item(3), Date).DayOfWeek + ???? = Date.Now.DayOfWeek Then
DataGridView6.Rows.Add(ds5.Tables(0).Rows(i).Item(4), CType(ds5.Tables(0).Rows(i).Item(3), Date).DayOfWeek)
End If
End If
Next
in "??????" I don't know what i can put to obtain the correct results !! can someone help me please !
As I understood from your comments, you are interested just in the interval-analysis part, that is, in determining whether today's date is before/after the given conditions as defined in your database (with start_date and frequency). Here you have a sample code to take care of this:
Dim start_date As Date = Now.AddDays(-14) 'start_date value to be taken from the DB
Dim frequency As TimeSpan = TimeSpan.FromDays(14) 'Number of days as a function of the given frequency in your DB; this is for 2W.
Dim elapsedDays As TimeSpan = Now.Subtract(start_date)
If (elapsedDays >= frequency) Then
'NOTIFY USER -> it has passed, at least, "frequency" number of days from "start_date"
If (elapsedDays > frequency) Then
Dim addDays As Integer = elapsedDays.Subtract(frequency).Days
Dim dateWhenTargetMet As Date = Now.AddDays(-addDays)
'Tell user that the target was met "addDays" ago, on "dateWhenTargetMet"
End If
End If
The code above checks whether the current date equals (or is later than) the start_date + frequency number of days.
Currently I'm using Code On Time to develop my system.
I got a default current date and time, after the user selects a completed date from lookup, I want to calculate how many days and hours have been taken by the user.
Is there any way to do this?
Is this what you're after?
declare #dateTimeNow datetime = getutcdate()
, #dateTimeThen datetime = '2012-11-28 12:00:00'
select case when DATEPART(hour,(#dateTimeNow - #dateTimeThen)) >0 then day(#dateTimeNow - #dateTimeThen)-1 else day(#dateTimeNow - #dateTimeThen) end days
, DATEPART(hour,(#dateTimeNow - #dateTimeThen)) hours
or
select DATEDIFF(day,#datetimethen, #datetimenow) - case when (DATEDIFF(Hour,#datetimethen, #datetimenow)) % 24 = 0 then 0 else 1 end days
, DATEDIFF(hour,#datetimethen, #datetimenow) % 24 hours