Return to 9. MATLAB Scripts

Current Weather and Zambretti Forecast

This MATLAB visualization shows current values from your weather station in metric and conventional US units. The barometric pressure and trend are used to make a Zambretti weather prediction good for about 12-hours. The values are taken from your ThingSpeak channel at the time your webpage is opened. You must manually update the chart by refreshing your browser.

% Displays Current Metric & Imperial Values in a Text Box
% Configured for IoT Kits Weather Stations
% https://w4krl.com/iot-kits
% Copyright, 2022, Karl Berger
% Karl Berger
% 2021-10-16
%{
Permission is hereby granted, free of charge, to any person obtaining a copy of this software
and associated documentation files (the "Software"), to deal in the Software without restriction,
including without limitation the rights to use, copy, modify, merge, publish, distribute,
sublicense, and/or sell copies of the Software, and to permit persons to whom the Software is
furnished to do so, subject to the following conditions:

The above copyright notice and this permission notice shall be included in all copies
or substantial portions of the Software.

THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR IMPLIED, INCLUDING 
BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, 
DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
%}

chID = 286120;

fldTempC = 1; % temp C
fldHumid = 2; % humidity
fldAwake = 3; % Time Awake - not used
fldSLP   = 4; % SLP 
fldLux   = 5; % lux
fldVcell = 6; % Vcell      - not used
fldRSSI  = 7; % RSSI       - not used
fldTempF = 8; % temp F

% latest data
[ lastData, lastTime ] = thingSpeakRead( chID, 'Fields',[1 2 4 5 8]);

curTempC = lastData( 1, 1 );
curTempF = lastData( 1, 5 );
curHum   = lastData( 1, 2 );
curSLP   = lastData( 1, 3 );
curSLPin = 0.02953 * curSLP;               % convert mbar to inHg
curLux   = lastData( 1, 4 );

% Calculate dew point
% Specify the constants for water vapor (b) and barometric (c) pressure.
% NOAA constants https://en.wikipedia.org/wiki/Dew_point
b = 17.67;
c = 243.5;

% Calculate the intermediate value 'gamma'
gamma = log(curHum / 100) + b * curTempC ./ (c + curTempC);

% Calculate dew point in Celsius
dewPointC = c * gamma ./ (b - gamma);

% Convert temperatures to Fahrenheit for display
dewPointF = (dewPointC * 1.8) + 32;
%tempF = (tempC * 1.8) + 32;

% read sea level pressure and time for 3 hours (180 minutes)
numMinutes = 185;  % must be a bit longer than 3-hours
[ baro3hr, dataTime ] = thingSpeakRead( chID, 'Fields', fldSLP, 'NumMinutes', numMinutes );
baroLength = length( baro3hr );       % number of barometric data points
deltaBaro = curSLP - baro3hr( 1 );    % most recent minus earliest

baroTrend = 0;
% convert 3-hour trend value to words
% levels are in millibars (hPa)
if deltaBaro > 6.0
    strTrend = "Rising Very Rapidly";
    baroTrend = 4;
elseif deltaBaro > 3.6
    strTrend = "Rising Quickly";
    baroTrend = 3;
elseif deltaBaro > 1.6
    strTrend = "Rising";
    baroTrend = 2;
elseif deltaBaro > 0.1
    strTrend = "Rising Slowly";
    baroTrend = 1;
elseif deltaBaro > -0.1
    strTrend = "Steady";
    baroTrend = 0;
elseif deltaBaro > -1.6
    strTrend = "Falling Slowly";
    baroTrend = -1;
elseif deltaBaro > -3.6
    strTrend = "Falling";
    baroTrend = -2;
elseif deltaBaro > -6.0
    strTrend = "Falling Quickly";
    baroTrend = -3;
else
    strTrend = "Falling Very Rapidly";
    baroTrend = -4;
end

%% Zambretti Forecast based on
%% new parameters by Karl Berger
risingIndex = 1;         % set to baroTrend index for 
fallingIndex = -1;       % determination of rising or falling
zambretti = "Forecast";  % forces zambretti to be a string
if baroTrend <= fallingIndex  %% FALLING %%
    if curSLP > 1046
        zambretti = "A: Settled Weather";
    elseif curSLP > 1027
        zambretti = "B: Fine Weather";
    elseif curSLP > 1021
        zambretti = "D: Fine, Becoming Less Settled";
    elseif curSLP > 1015
        zambretti = "H: Fairly Fine, Showers Later";
    elseif curSLP > 1009
        zambretti = "O: Showery, Becoming More Unsettled";
    elseif curSLP > 1002
        zambretti = "R: Unsettled, Rain Later";
    elseif curSLP > 996
        zambretti = "U: Rain At Times, Worse Later";
    elseif curSLP > 990
        zambretti = "V: Rain At Times, Becoming Very Unsettled";
    elseif curSLP > 977
        zambretti = "X: Very Unsettled";
    else
        zambretti = "Z: Stormy, Much Rain";
    end
elseif baroTrend >= risingIndex  %% RISING %%
    if curSLP > 1027
        zambretti = "A: Settled Weather";
    elseif curSLP > 1013
        zambretti = "B: Fine Weather";
    elseif curSLP > 1008
        zambretti = "C: Becoming Fine";
    elseif curSLP > 1002
        zambretti = "F: Fairly Fine, Improving";
    elseif curSLP > 995
        zambretti = "G: Fairly Fine, Possible Showers Early";
    elseif curSLP > 988
        zambretti = "I: Showers Early, Improving";
    elseif curSLP > 981
        zambretti = "J: Changeable, Mending";
    elseif curSLP > 977
        zambretti = "L: Rather Unsettled, Clearing Later";
    elseif curSLP > 970
        zambretti = "M: Unsettled, Probably Improving";
    elseif curSLP > 963
        zambretti = "Q: Unsettled, Short Fine Intervals";
    elseif curSLP > 961
        zambretti = "T: Very Unsettled, Finer At Times";
    elseif curSLP > 947
        zambretti = "Y: Stormy, Possibly Improving";
    else
        zambretti = "Z: Stormy, Much Rain";
    end
else %% STEADY %%
    if curSLP > 1027
        zambretti = "A: Settled Weather";
    elseif curSLP > 1015
        zambretti = "B: Fine Weather";
    elseif curSLP > 1010
        zambretti = "E: Fine, Possible Showers";
    elseif curSLP > 1003
        zambretti = "K: Fairly Fine, Showers Likely";
    elseif curSLP > 997
        zambretti = "N: Showery, Bright Intervals";
    elseif curSLP > 990
        zambretti = "P: Changeable, Some Rain";
    elseif curSLP > 984
        zambretti = "S: Unsettled, Rain At Times";
    elseif curSLP > 978
        zambretti = "W: Rain At Frequent Intervals";
    elseif curSLP > 965
        zambretti = "X: Very Unsettled, Rain";            
    else
        zambretti = "Z: Stormy, Much Rain";
    end
end

%% display dimensions
%% lower left is 0, 0
%% upper right is 1, 1

textSize = 10;

% width of columns
time_width        = 0.98;
label_width       = 0.28;  % 0.3
value_width       = 0.48;  % 0.3
unit_width        = 0.22;  % 0.2
zambretti_width   = time_width;

%  x left edge of columns
data_left         = 0.01;  % 0.1
label_left        = data_left;   % 0.1
value_left        = label_left + label_width;  % 0.4
unit_left         = value_left + value_width;  % 0.6

% h height of rows
time_height       = 0.15;
data_height       = 0.63; % 0.55
zambretti_height  = 0.15;

% y bottom of rows
zambretti_bottom  = 0.01; % 0.01
data_bottom       = zambretti_bottom + zambretti_height; %0.21;  % 0.2
time_bottom       = data_bottom + data_height; %0.8;

% Time of Data
str = { strcat('Data Date:', {' '}, string( dataTime( baroLength ))),...
       '=>Refresh browser to update<='};
annotation( 'textbox', [ data_left time_bottom time_width time_height ],...
'HorizontalAlignment', 'center',...
'VerticalAlignment', 'bottom',...
'LineStyle', ':' ,...
'String', str,...
'FontSize', 8,...
'Color', 'red','FitBoxToText','off' );

% labels
str = {'Temperature ...',...
       'Humidity .........',...
       'Dew Point ........',...
       'Barometer .......',...
       '     Trend .........',...
       'Light ................'};

annotation('textbox',[label_left data_bottom label_width data_height],...
'HorizontalAlignment','left',...
'VerticalAlignment','bottom',...
'LineStyle','None',...
'String',str,...
'FontSize',textSize);

% values
str = {strcat(num2str(curTempC, '%.1f'),' (',num2str(curTempF, '%.1f'),')'),...
       num2str(curHum, '%.1f'),...
       strcat(num2str(dewPointC, '%.1f'),' (',num2str(dewPointF, '%.1f'),')'),...
       strcat(num2str(curSLP, '%.1f'),' (',num2str(curSLPin, '%.2f'),')'),...
       strcat(strTrend,{' @ '}, num2str(deltaBaro, '%+.2f')),...
       num2str(curLux, '%.0f')};
annotation('textbox',[value_left data_bottom value_width data_height],...
'HorizontalAlignment','right',...
'VerticalAlignment','bottom',...
'LineStyle','None',...
'String',str,...
'FontSize',textSize,...
'Color', 'blue');

% units
str = {'°C(°F)',...
       '%RH',...
       '°C(°F)',...
       'mbar(inHg)',... 
       'mbar/3-hr',...
       'lux'};

annotation('textbox',[unit_left data_bottom unit_width data_height],...
'HorizontalAlignment','left',...
'VerticalAlignment','bottom',...
'LineStyle','None',...
'String',str,...
'FontSize',textSize);

%% Zambretti Forecast
str = strcat('Zambretti 12-hr Forecast', {' '}, zambretti);
annotation('textbox',[data_left zambretti_bottom time_width zambretti_height],...
'HorizontalAlignment','center',...
'VerticalAlignment','bottom',...
'LineStyle',':',...
'String', str,...
'FontSize',textSize,...
'Color', 'blue');

Permanent link to this article: https://w4krl.com/iot-kits/matlab-scripts/current-weather-zambretti-forecast/