classdef WindSpeedAppExample < matlab.apps.AppBase

    % Properties that correspond to app components
    properties (Access = public)
        WindSpeedUIFigure           matlab.ui.Figure
        MeasuredEvery5SecondsLabel  matlab.ui.control.Label
        StartButton                 matlab.ui.control.Button
        StopButton                  matlab.ui.control.Button
        WindSpeedinNatickMALabel    matlab.ui.control.Label
        UIAxes                      matlab.ui.control.UIAxes
    end


    properties (Access = private)
        WindSpeedTimer % Timer object
    end

    methods (Access = private)
    
       function WindSpeedTimerFcn(app, ~, event)
            % get current time from timer's event data
            tnow = datetime(event.Data.time);
            
            % Get wind speed data from MathWorks weather station
            weatherdata = webread('https://api.thingspeak.com/channels/12397/feeds/last.json');
            y = str2double(weatherdata.field2);
            
            % Plot data and adjust XLim if current time is out of bounds
            xLL = app.UIAxes.XLim(1);
            xUL = app.UIAxes.XLim(2);
            if(tnow > xUL)
               xtra = seconds(15);
               app.UIAxes.XLim = [xLL+xtra tnow+xtra];
               app.UIAxes.XTick = linspace(xLL+xtra, tnow+xtra, 5);
            end
            plot(app.UIAxes, tnow, y, 'ob');
            
            % Adjust YLim to show variations better
            yLL = max(y-10, 0); 
            yUL = y + 10;
            app.UIAxes.YLim = [yLL yUL];
            app.UIAxes.YTick = round(linspace(yLL, yUL, 5), 2, 'significant');
       end        
        
    end


    % Callbacks that handle component events
    methods (Access = private)

        % Code that executes after component creation
        function startupFcn(app)
            % Plot invisible data point to initialize datetime ruler
            plot(app.UIAxes, datetime('now'), 50, 'MarkerEdgeColor', 'none');
           
            % Set x limits and ticks
            t = datetime('now') + seconds(1:60);
            xLL = t(1) - seconds(5);
            xUL = t(length(t));
            app.UIAxes.XLim = [xLL xUL];
            app.UIAxes.XAxis.TickLabelFormat = 'hh:mm:ss';
            app.UIAxes.XTick = linspace(xLL, xUL, 5);
            
            % Set y limits and ticks
            app.UIAxes.YLim = [0 50];
            app.UIAxes.YTick = round(linspace(0, 50, 5), 2, 'significant');
            grid(app.UIAxes,'on');
            hold(app.UIAxes,'on');
            
            % Create timer object
            app.WindSpeedTimer = timer(...
            'ExecutionMode', 'fixedRate', ...      % Run timer repeatedly
            'Period', 5, ...                       % Period is 5 seconds
            'BusyMode', 'queue',...                % Queue timer callbacks when busy
            'TimerFcn', @app.WindSpeedTimerFcn);   % Callback that runs every period
        end

        % Button pushed function: StartButton
        function StartButtonPushed(app, event)
            % If timer is not running, start it
            if strcmp(app.WindSpeedTimer.Running, 'off')
               % Start timer
               start(app.WindSpeedTimer);
            end
        end

        % Button pushed function: StopButton
        function StopButtonPushed(app, event)
            % Stop timer
            stop(app.WindSpeedTimer);
        end

        % Close request function: WindSpeedUIFigure
        function UIFigureCloseRequest(app, event)
            % Stop timer, then delete timer and figure
            stop(app.WindSpeedTimer);
            delete(app.WindSpeedTimer);
            delete(app);
        end
    end

    % Component initialization
    methods (Access = private)

        % Create UIFigure and components
        function createComponents(app)

            % Create WindSpeedUIFigure and hide until all components are created
            app.WindSpeedUIFigure = uifigure('Visible', 'off');
            app.WindSpeedUIFigure.Position = [100 100 640 480];
            app.WindSpeedUIFigure.Name = 'Wind Speed';
            app.WindSpeedUIFigure.CloseRequestFcn = createCallbackFcn(app, @UIFigureCloseRequest, true);

            % Create MeasuredEvery5SecondsLabel
            app.MeasuredEvery5SecondsLabel = uilabel(app.WindSpeedUIFigure);
            app.MeasuredEvery5SecondsLabel.Position = [245 415 153 22];
            app.MeasuredEvery5SecondsLabel.Text = 'Measured Every 5 Seconds';

            % Create StartButton
            app.StartButton = uibutton(app.WindSpeedUIFigure, 'push');
            app.StartButton.ButtonPushedFcn = createCallbackFcn(app, @StartButtonPushed, true);
            app.StartButton.Position = [197 59 100 22];
            app.StartButton.Text = 'Start';

            % Create StopButton
            app.StopButton = uibutton(app.WindSpeedUIFigure, 'push');
            app.StopButton.ButtonPushedFcn = createCallbackFcn(app, @StopButtonPushed, true);
            app.StopButton.Position = [348 59 100 22];
            app.StopButton.Text = 'Stop';

            % Create WindSpeedinNatickMALabel
            app.WindSpeedinNatickMALabel = uilabel(app.WindSpeedUIFigure);
            app.WindSpeedinNatickMALabel.FontSize = 16;
            app.WindSpeedinNatickMALabel.Position = [225 436 192 22];
            app.WindSpeedinNatickMALabel.Text = 'Wind Speed in Natick, MA';

            % Create UIAxes
            app.UIAxes = uiaxes(app.WindSpeedUIFigure);
            xlabel(app.UIAxes, 'Time')
            ylabel(app.UIAxes, 'Speed (mph)')
            app.UIAxes.XGrid = 'on';
            app.UIAxes.YGrid = 'on';
            app.UIAxes.Box = 'on';
            app.UIAxes.Position = [67 106 508 300];

            % Show the figure after all components are created
            app.WindSpeedUIFigure.Visible = 'on';
        end
    end

    % App creation and deletion
    methods (Access = public)

        % Construct app
        function app = WindSpeedAppExample

            % Create UIFigure and components
            createComponents(app)

            % Register the app with App Designer
            registerApp(app, app.WindSpeedUIFigure)

            % Execute the startup function
            runStartupFcn(app, @startupFcn)

            if nargout == 0
                clear app
            end
        end

        % Code that executes before app deletion
        function delete(app)

            % Delete UIFigure when app is deleted
            delete(app.WindSpeedUIFigure)
        end
    end
end