Calculating seconds in MATLAB - matlab

I have a code that calculates power consumption of devices in Watts. I need to calculate the KWH usage of that device in that month and i have a formula that looks like this
( Watt Usage * Hours/Day * Days/Mo. ) / 1000 = Kilowatt Hours used that month
I have the Watt Usage,but having trouble with tracking time.So is there a way to calculate seconds so that i can use it to calculate hours,days and unit consumption.

MATLAB has some tools for manipulating with time:
clock:
t=clock; % returns a six-element vector containing the current date and time in decimal form, ( i.e. [year month day hour minute seconds] )
date :
d=date; returns a string containing the date (in dd-mmm-yyyy format).
also , you can use tic and toc to measure elapsed time between two moments.(like a stopwatch)
tic;% starts the stopwatch
% after some time
toc % returns elapsed time

Related

Hour conversion in Tableau

I have a data-set that has time (hours) data in it.
The time data is given as 0.1123, 3.1565, 0.2951 etc (all in hours).
How do I convert it into standard hours and minute format?
We can achieve this using two methods
1.Change to Date & Time
Once the data has been imported in Tableau. Change the data type of the column to "Date & Time". Tableau data engine automatically understand the time format and change the decimal time to Actual time
Refer this Image
2. Using Calculated Field "MAKETIME"
MAKETIME Requires three argument(hour, minute, second).Below code parse decimal number "3.1545" as
3 hrs, 9 min (0.15*60) and 16 sec (0.0045*3600)
MAKETIME(INT([DecimalTime]),
int(INT(([DecimalTime]100)%100).6),
int(INT(([DecimalTime]10000)%100).36))
Floor([value]) = the number of hours
Floor([value] * 60) % 60 = the number of minutes
Floor([value] * 3600) % 3600 = the number of seconds

UTC to GPS time for finding TOW in Simulink

for my project, I need to calculate TOW (Time of week) in Simulink. I know this can be achieved through conversion of UTC time to GPS time.
I have written a simple m-file in Matlab which does the action for me in Matlab as follow:
date_gps_int = 10000*y + 100*m + d
date_gps_str = int2str(date_gps_int)
date_gps_str_to_serial = datenum(date_gps_str,'yyyymmdd')
date_str_format = datestr(date_gps_str_to_serial,'dd-mmmm-yyyy')
Num_Days = daysact('06-jan-1980',date_str_format)
Num_Weeks = Num_Days/7
TOW = Num_Weeks - 1024
My first intention was to use this as a function in simulink. But apparently because of 'datenum' and 'datestr' it is not possible, since simulink does not handle strings.
Now I am wondering if anyone can help me with this issue. Is there any way to calculate TOW from the UTC date in Matlab without using those predefined functions?
I also tried to write an algorithm for calculating number of days since '6 January 1980' and then calculating number of weeks by dividing that by 7. But since I am not very familiar with leap year calculation and I don't really know the formula for these kinds of calculations, my result differs from real TOW.
I would appreciate if anybody can help me on this.
There are three formats handled by Matlab for time: formatted date strings - what datestr outputs -, serial date - scalar double, what datenum outputs - and date vectors (see datevec). Conversion functions work with these three, and the most convenient way to convert individual variables (year, month, etc) to a date is to build a date vector [yyyy mm dd HH MM SS].
date_gps_str_to_serial = datenum([y m d 0 0 0]); % midnight on day y-m-d
date_Jan_6_1980 = datenum([1980 01 06 0 0 0]); % midnight on Jan 6th, 1980
Num_Days = date_gps_str_to_serial - date_Jan_6_1980;
Now, beware of leap seconds...
GPS time is computed form the time elapsed since Jan 6th 1980. Take the number of seconds elapsed since that day, as measured by the satellites' atomic clocks, divide by (24*3600) to get a number of days, the remainder is the time of the day (in seconds since midnight).
But, once in a while, the International Earth Rotation and Reference Systems Service will decide that a day will last one second longer to accommodate for the slowing of Earth rotation. It may happen twice a year, on June 30th or December 31st. The calculation of GPS time is wrong, because it does not take into account that some days last 86401 seconds (so dividing by 24*3600 does not work) and will advance by 1 second with respect to UTC each time this happens. There has been 18 such days since Jan 6th 1980, so one should subtract 18 seconds from GPS time to find UTC time. The next time a leap second may be added is June 2019.

Plotting with respect to minutes as formatted time (min.sec)

I'm trying to plot some data with respect to minutes instead of seconds in Matlab as formatted time, i.e. min.sec.
I have real time data streaming in where with every sample received, its time in seconds is also sent. I then plot them with respect to time. Now, since my session is around 15 minutes long, I can't be plotting with respect to time. Therefore I wanted to plot it with respect to time (min.sec). I tried dividing the received time by 60 but this gives me minutes with 100 subdivisions instead of 60 (the minutes increment after 0.9999 instead of 0.59). How do I convert it so that I'm able to plot with respect to time in minutes?
Here is what I mean by 0.99 fractions of a minute instead of 0.59. A normal minute has 60 divisions not 100.
EDIT:
I tried m7913d's suggestions and here is what I got.
first I plot the signal with respect to time in seconds without changing the ticks ( A normal plot(t,v))
The I added datetick('x', 'mm:ss'); to the plot (Xtick format is not supported in Matlab 2015b)
Here is a screenshot of the results
The time in seconds was up to 80 seconds, when translated into minutes, it should give me 1 minutes and 20 seconds as the maximum x axis limit. But this is not the case. I tried to construct a t vector (i.e like t=0:seconds(3):minutes(3)) but I couldn't link it to my seconds vector which will be constantly updating as new samples are received from the serial port.
Thanks
You can use xtickformat to specify the desired format of your x labels as follows:
% generate a random signal (in seconds)
t = 0:5:15*60;
y = rand(size(t));
plot(seconds(t),y) % plot your signal, making it explicit that the t is expressed in seconds
xtickformat('mm:ss') % specify the desired format of the x labels
Note that I used the seconds methods, which returns a duration object, to indicate to Matlab that t is expressed in seconds.
The output of the above script is (the right image is a zoomed version of the left image):
Pre R2016b
One can use datetime instead of xtickformat as follows:
datetimes = datetime(0,0,0,0,0,t); % convert seconds to datetime
plot(datetimes,y)
datetick('x', 'MM:SS'); % set the x tick format (Note that you should now use capital M and S in the format string
xlim([min(datetimes) max(datetimes)])

Iterate for loop by hour in MATLAB

I am writing a for loop to average 10 years of hourly measurements made on the hour. The dates of the measurements are recorded as MATLAB datenums.
I am trying to iterate through using 0.0417 as it is the datenum for 1AM 00/00/00 but it is adding in a couple of seconds of error each time I iterate.
Can anyone recommend a better way for me to iterate by hour?
date = a(:,1);
load = a(:,7);
%loop for each hour of the year
for i=0:0.0417:366
%set condition
%condition removes year from current date
c = date(:)-datenum(year(date(:)),0,0)==i;
%evaluate condition on load vector and find mean
X(i,2)=mean(load(c==1));
end
An hour has a duration of 1/24 day, not 0.0417. Use 1/24 and the precision is sufficient high for a year.
For an even higher precision, use something like datenum(y,1,1,1:24*365,0,0) to generate all timestamps.
To avoid error drift entirely, specify the index using integers, and divide the result down inside the loop:
for hour_index=1:365*24
hour_datenum = (hour_index - 1) / 24;
end

Timestamp Processing Brain Teaser

I am processing 1Hz timestamps (variable 'timestamp_1hz') from a logger which doesn't log exactly at the same time every second (the difference varies from 0.984 to 1.094, but sometimes 0.5 or several seconds if the logger burps). The 1Hz dataset is used to build a 10 minute averaged dataset, and each 10 minute interval must have 600 records. Because the logger doesn't log exactly at the same time every second, the timestamp slowly drifts through the 1 second mark. Issues come up when the timestamp cross the 0 mark, as well as the 0.5 mark.
I have tried various ways to pre-process the timestamps. The timestamps with around 1 second between them should be considered valid. A few examples include:
% simple
% this screws up around half second and full second values
rawseconds = raw_1hz_new(:,6)+(raw_1hz_new(:,7)./1000);
rawsecondstest = rawseconds;
rawsecondstest(:,1) = floor(rawseconds(:,1))+ rawseconds(1,1);
% more complicated
% this screws up if there is missing data, then the issue compounds because k+1 timestamp is dependent on k timestamp
rawseconds = raw_1hz_new(:,6)+(raw_1hz_new(:,7)./1000);
A = diff(rawseconds);
numcheck = rawseconds(1,1);
integ = floor(numcheck);
fract = numcheck-integ;
if fract>0.5
rawseconds(1,1) = rawseconds(1,1)-0.5;
end
for k=2:length(rawseconds)
rawsecondstest(k,1) = rawsecondstest(k-1,1)+round(A(k-1,1));
end
I would like to pre-process the timestamps then compare it to a contiguous 1Hz timestamp using 'intersect' in order to find the missing, repeating, etc data such as this:
% pull out the time stamp (round to 1hz and convert to serial number)
timestamp_1hz=round((datenum(raw_1hz_new(:,[1:6])))*86400)/86400;
% calculate new start time and end time to find contig time
starttime=min(timestamp_1hz);
endtime=max(timestamp_1hz);
% determine the contig time
contigtime=round([floor(mean([starttime endtime])):1/86400:ceil(mean([starttime endtime]))-1/86400]'*86400)/86400;
% find indices where logger time stamp matches real time and puts
% the indices of a and b
clear Ia Ib Ic Id
[~,Ia,Ib]=intersect(timestamp_1hz,contigtime);
% find indices where there is a value in real time that is not in
% logger time
[~,Ic] = setdiff(contigtime,timestamp_1hz);
% finds the indices that are unique
[~,Id] = unique(timestamp_1hz);
You can download 10 days of the raw_1hz_new timestamps here. Any help or tips would be much appreciated!
The problem you have is that you can't simply match these stamps up to a list of times, because you could be expecting a set of datapoints at seconds = 1000, 1001, 1002, but if there was an earlier blip you could have entirely legitimate data at 1000.5, 1001.5, 1002.5 instead.
If all you want is a list of valid times/their location in your series, why not just something like (times in seconds):
A = diff(times); % difference between times
n = find(abs(A-1)<0.1) % change 0.1 to whatever your tolerance is
times2 = times(n+1);
times2 should then be a list of all your timestamps where the previous timestamp was approximately 1 second ago - works on a small set of fake data I constructed, didn't try it on yours. (For future reference: it would be more help to provide a small subset of your data, e.g. just a few minutes worth, that you know contains a blip).
I would then take the list of valid timestamps and split it up into 10 minute sections for averaging, counting how many valid timestamps were obtained in each section. If it's working, you should end up with no more than 600 - but not much less if the blips are occasional.