//
// Scilab ( http://www.scilab.org/ ) - This file is part of Scilab
// Copyright (C) 2013-2013 - Scilab Enterprises - Bruno JOFRET
//
// This file must be used under the terms of the CeCILL.
// This source file is licensed as described in the file COPYING, which
// you should have received as part of this distribution.  The terms
// are also available at
// http://www.cecill.info/licences/Licence_CeCILL_V2-en.txt
//
//

global %MaxTemp
%MaxTemp = 29;
global %MinTemp
%MinTemp = 27;
global %RegulationEnable
%RegulationEnable = 1;

// National Instruments configuration
global DOport;
global AIport;
DOport = "port0";
AIport = "ai0";

// Create GUI
f = scf();
f.tag = "mainWindow";
bar(0.5, 0, 'blue');
e = gce();
e = e.children(1);
e.tag = "instantSensor";
plot([0, 1], [%MinTemp, %MinTemp]);
e = gce();
e = e.children(1);
e.tag = "instantMinTemp";
e.line_style = 5;
e.thickness = 1;
e.foreground = color("orange");
plot([0, 3], [%MaxTemp, %MaxTemp]);
e = gce();
e = e.children(1);
e.tag = "instantMaxTemp";
e.line_style = 5;
e.thickness = 1;
e.foreground = color("red");
a = gca();
a.data_bounds = [0, 0; 1, 45];
a.grid = [-1, color("lightgrey")];
a.axes_bounds = [0.1, 0.2, 0.1, 0.85];
a.axes_visible(1) = "off";
a.tag = "liveAxes";

f.figure_position = [0 0];
f.figure_size = [1000 700];
f.background = color("darkgrey")

top_axes_bounds = [0.25 0 0.8 0.5];
bottom_axes_bounds = [0.25 0.5 0.8 0.5];

minTempDisplay = 20;
maxTempDisplay = 45;
minRegulationDisplay = -0.2;
maxRegulationDisplay = 1.2;

// 5 Minute
timeBuffer = 300;
subplot(222);
a = gca();
a.axes_bounds = top_axes_bounds;
a.tag = "minuteAxes";
plot2d(0:timeBuffer, zeros(1,timeBuffer + 1), color("red"));
a.data_bounds = [0, minTempDisplay; timeBuffer, maxTempDisplay];
e = gce();
e = e.children(1);
e.tag = "minuteSensor";

a = newaxes();
a.y_location = "right";
a.filled = "off" 
a.axes_bounds = top_axes_bounds;
plot2d(0:timeBuffer, zeros(1,timeBuffer + 1), color("blue"));
a.data_bounds = [0, minRegulationDisplay; timeBuffer, maxRegulationDisplay];
a.axes_visible(1) = "off";
a.foreground=color("blue");
a.font_color=color("blue");
e = gce();
e = e.children(1);
e.tag = "minuteRegulation";

// 1 hour
timeBuffer = 4000;
subplot(224);
a = gca();
a.axes_bounds = bottom_axes_bounds;
a.tag = "hourAxes";
plot2d(0:timeBuffer, zeros(1,timeBuffer + 1), color("red"));
a.data_bounds = [0, minTempDisplay; timeBuffer, maxTempDisplay];
e = gce();
e = e.children(1);
e.tag = "hourSensor";

a = newaxes();
a.y_location = "right";
a.filled = "off" 
a.axes_bounds = bottom_axes_bounds;
a.axes_visible = "off";
plot2d(0:timeBuffer, zeros(1,timeBuffer + 1), color("blue"));
a.data_bounds = [0, minRegulationDisplay; timeBuffer, maxRegulationDisplay];
a.axes_visible(1) = "off";
a.foreground=color("blue");
a.font_color=color("blue");
e = gce();
e = e.children(1);
e.tag = "hourRegulation";

// Buttons
mainFrame = uicontrol(f, "style", "frame", "position", [10 410 260 150], ...
"tag", "mainFrame");
startButton = uicontrol(f, "style", "pushbutton", "position", [20 520 100 30], ..
"callback", "launchSensor", "string", "Start Acquisition", ...
"tag", "startButton");
stopButton = uicontrol(f, "style", "pushbutton", "position", [20 470 100 30], ..
"callback", "stopSensor", "string", "Stop Acquisition", ...
"tag", "stopButton");
resetButton = uicontrol(f, "style", "pushbutton", "position", [160 420 100 30], ..
"callback", "resetDisplay", "string", "Reset", ...
"tag", "resetButton");
quitButton = uicontrol(f, "style", "pushbutton", "position", [20 420 100 30], ..
"callback", "closeFigure", "string", "Quit", ...
"tag", "quitButton");

enableRegulation = uicontrol(f, "style", "checkbox", "position", [160 520 100 30], ...
"string", "Regulation", "value", %RegulationEnable, ...
"callback", "changeRegulationStatus", "tag", "enableRegulationCBO");

minTempSlider = uicontrol("style", "slider", "position", [60 30 20 365], ...
"min", 0, "max", 45, "sliderstep", [1 5], "value" , 45 - %MinTemp, ...
"callback", "changeMinTemp", "tag", "minTempSlider");
maxTempSlider = uicontrol("style", "slider", "position", [20 30 20 365], ...
"min", 0, "max", 45, "sliderstep", [1 5], "value" , 45 - %MaxTemp, ...
"callback", "changeMaxTemp", "tag", "maxTempSlider");

deviceName = DAQ_SystemInfoAttribute('DAQmx_Sys_DevNames')

if deviceName <> [] then
    xinfo("NI Device "+deviceName+" detected: Ready for acquisition...");
else
    xinfo("No NI Device detected...");
    messagebox("Unable to detect any National Instruments device...", "Error: No device detected", "error", "Close Apllication", "modal");
    delete(f);
end
function closeFigure()
    stopSensor();
    sleep(500);
    f = findobj("tag", "mainWindow");
    delete(f);
endfunction

function stopSensor()
    global %dataAcquisition
    %dataAcquisition = %f;
    deviceName = DAQ_SystemInfoAttribute('DAQmx_Sys_DevNames');
    xinfo("NI Device "+deviceName+" detected: Ready for acquisition...");
endfunction

function resetDisplay()
    e = findobj("tag", "instantSensor");
    e.data(:, 2) = 0;
    e = findobj("tag", "minuteSensor");
    e.data(:, 2) = 0;
    e = findobj("tag", "hourSensor");
    e.data(:, 2) = 0;
    e = findobj("tag", "minuteRegulation");
    e.data(:, 2) = 0;
    e = findobj("tag", "hourRegulation");
    e.data(:, 2) = 0;
endfunction

function updateSensorValue(data)
    global %MaxTemp
    global %MinTemp
    e = findobj("tag", "instantSensor");
    e.data(2) = data;
    if data > %MaxTemp then
        e.background = color("red");
    else
        if data > %MinTemp  then
            e.background = color("orange");
        else
            e.background = color("green");
        end
    end
    e = findobj("tag", "minuteSensor");
    lastPoints = e.data(:, 2);
    e.data(:, 2) = [lastPoints(2:$) ; data];
    e = findobj("tag", "hourSensor");
    lastPoints = e.data(:, 2);
    e.data(:, 2) = [lastPoints(2:$) ; data];
endfunction

function changeRegulationStatus()
    global %RegulationEnable
    e = findobj("tag", "enableRegulationCBO");
    %RegulationEnable = e.value;
    if %RegulationEnable == 0 then
        disableFan();
    end
endfunction

function changeMinTemp()
    global %MinTemp
    e = findobj("tag", "minTempSlider");
    %MinTemp = 45 - e.value;
    e = findobj("tag", "instantMinTemp");
    e.data(:,2) = %MinTemp;
endfunction

function changeMaxTemp()
    global %MaxTemp
    e = findobj("tag", "maxTempSlider");
    %MaxTemp = 45 - e.value;
    e = findobj("tag", "instantMaxTemp");
    e.data(:,2) = %MaxTemp;
endfunction

function updateFanValue(data)
    e = findobj("tag", "minuteRegulation");
    lastPoints = e.data(:, 2);
    e.data(:, 2) = [lastPoints(2:$) ; data];
    e = findobj("tag", "hourRegulation");
    lastPoints = e.data(:, 2);
    e.data(:, 2) = [lastPoints(2:$) ; data];
endfunction

function enableFan()
    setDIO(1);
endfunction

function disableFan()
    setDIO(0);
endfunction

function setDIO(value)
    // Channel parameters
    global DOport;
    deviceName = DAQ_SystemInfoAttribute('DAQmx_Sys_DevNames');
    chan    = deviceName+"/"+DOport;
    // Data write parameters
    pointsToWrite = 1;
    timeout       = 10.0;
    data          = uint32(value);
    [task,err] = DAQ_CreateTask("");
    DAQ_ErrChk(task,err);

    [err] = DAQ_CreateDOChan(task,chan);
    DAQ_ErrChk(task,err);

    [err] = DAQ_StartTask(task);
    DAQ_ErrChk(task,err);

    [pointsWritten,err] = DAQ_WriteDigitalU32(task,1,%t,timeout, DAQ("Val_GroupByChannel"),data);
    DAQ_ErrChk(task, err);

    DAQ_StopTask( task );
    DAQ_ClearTask( task );
endfunction

function launchSensor()
    global AIport;
    deviceName = DAQ_SystemInfoAttribute('DAQmx_Sys_DevNames')
    xinfo("Starting/Reseting device "+deviceName);
    DAQ_ResetDevice(deviceName);
    xinfo("Done !");
    // Channel parameters
    chan_ai0    = deviceName+"/"+AIport;
    minVal  = -10.0;
    maxVal  = +10.0;

    // Timing parameters
    source         = "OnboardClock";
    samplesPerChan = 1000;
    rate           = 10000.0;

    // Data read parameters
    bufferSize   = 1000;
    pointsToRead = -1;
    timeout      = 100.0;

    [task_ai0,err] = DAQ_CreateTask("");
    DAQ_ErrChk(task_ai0,err);

    [err] = DAQ_CreateAIVoltageChan(task_ai0, chan_ai0, DAQ("Val_Cfg_Default"), minVal, maxVal);
    DAQ_ErrChk(task_ai0,err);

    [err] = DAQ_CfgSampClkTiming(task_ai0, source, rate, DAQ("Val_Rising"), DAQ("Val_FiniteSamps"),samplesPerChan);
    DAQ_ErrChk(task_ai0,err);

    global %dataAcquisition
    %dataAcquisition = %t;
    fanStatus = 0;
    while %dataAcquisition
        // READ AI0
        [err] = DAQ_StartTask(task_ai0);
        DAQ_ErrChk(task_ai0,err);
        [data_ai0,pointsRead,err] = DAQ_ReadAnalogF64(task_ai0,pointsToRead,timeout, DAQ("Val_GroupByChannel"), bufferSize);
        DAQ_ErrChk(task_ai0, err);
        DAQ_StopTask(task_ai0);

        // Mean data
        data_ai0 = 100 * mean(data_ai0);
        if %dataAcquisition then
            xinfo("Temperature = "+string(data_ai0)+"°C");
            updateSensorValue(data_ai0);
            global %MaxTemp;
            global %MinTemp
            global %RegulationEnable
            if %RegulationEnable == 1 & data_ai0 > %MaxTemp then
                enableFan();
                fanStatus = 1;
            end
            if %RegulationEnable == 0 | data_ai0 < %MinTemp then
                disableFan();
                fanStatus = 0;
            end
            updateFanValue(fanStatus);
        end
    end
    DAQ_ClearTask(task_ai0);
endfunction



