\subsection{Framework}
Systems built with support for \gls{mTask} are often following the same design
pattern. First the devices are created --- with or without the interaction of
the user --- and they are then connected. When all devices are registered, the
\gls{mTask}-\glspl{Task} can be sent and \gls{iTasks}-\glspl{Task} can be
started to monitor the output. When everything is finished, the devices are
removed and the system is shut down.

\begin{lstlisting}[language=Clean,label={lst:framework},
	caption={\gls{mTask} framework for building applications}]
w :: Task ()
w =         makeDevice "dev1" (...) >>= connectDevice
	>>= \dev1->makeDevice "dev2" (...) >>= connectDevice
	>>= \dev2->...
	...
	>>* [OnAction (Action "Shutdown") $ always
		$   deleteDevice dev1 >>| deleteDevice dev2
		>>| ...
		>>| shutDown 0
	]
\end{lstlisting}

\subsection{Thermostat}
The thermostat is a classic example program for showing interactions between
peripherals. The following program shows a system containing two devices. The
first device --- the sensor --- contains a temperature sensor that measures the
room temperature. The second device --- the actor --- contains a heater,
connected to the digital pin \CI{D5}. Moreover, this device contains a led to
indicate whether the heater is on. The following code shows an implementation
for this. The code fully uses the framework. Note that a little bit of type
twiddling is required to fully us the result from the \gls{SDS}. This approach
is still type safe due to the type safety of \CI{Dynamic}s.

\begin{lstlisting}[caption={Thermostat example}]
thermos :: Task ()
thermos =           makeDevice "nodeM" nodeMCU >>= connectDevice
	>>= \nod->      makeDevice "stm32" stm32   >>= connectDevice
	>>= \stm->      sendTaskToDevice "sensing" sensing (nod, OnInterval 1000)
	>>= \(st, [t])->sendTaskToDevice "acting" acting (stm, OnInterval 1000)
			(\(BCValue s)->set (BCValue $ dynInt (dynamic s) > 0) (shareShare nod a))
	>>| treturn ()
where
	dynInt :: Dynamic -> Int
	dynInt (a :: Int) = a

	sensing = sds \x=0 In {main=
			x =. analogRead A0 :. pub x
		}
	acting = sds \cool=False In {main=
			IF cool (ledOn LED1) (ledOff LED1) :.
			digitalWrite D5 cool
		}
	nodeMCU = TCP
\end{lstlisting}

\subsection[Lifting mTasks to iTasks-Tasks]%
	{Lifting \gls{mTask}-\glspl{Task} to \gls{iTasks}-\glspl{Task}}
If the user does not want to know where and when a \gls{mTask} is actually
executed and is just interested in the results it can lift the \gls{mTask} to
an \gls{iTasks}-\gls{Task}. The function is called with a name, \gls{mTask},
device and interval specification and it will return a \gls{Task} that finishes
if and only if the \gls{mTask} has returned.

\begin{lstlisting}[caption={Lifting \gls{mTask}-\glspl{Task} to \gls{iTasks}}]
liftmTask :: String (Main (ByteCode () Stmt)) (MTaskDevice, MTaskInterval) -> Task [MTaskShare]
liftmTask wta mTask c=:(dev, _)= sendTaskToDevice wta mTask c
	>>= \(t, shs)->wait "Waiting for mTask to return" (taskRemoved t) (deviceShare dev)
	>>| viewInformation "Done!" [] ()
	>>| treturn shs
where
	taskRemoved t d = isNothing $ find (\t1->t1.ident==t.ident) d.deviceTasks
\end{lstlisting}

The factorial function example from Chapter~\ref{chp:mtaskcont} can then be
lifted to a real \gls{iTasks}-\gls{mTask} with the following code:
\begin{lstlisting}[caption={Lifting the factorial \gls{Task} to \gls{iTasks}}]
factorial :: MTaskDevice -> Task BCValue
factorial dev = enterInformation "Factorial of ?" []
	>>= \fac->liftmTask "fact" (fact fac) (dev, OnInterval 100)
	@         fromJust o find (\x->x.humanName == "result")
	@         \s->s.MTaskShare.value
where
	fact i = sds \y=i
		In namedsds \x=(1 Named "result")
		In {main = IF (y <=. lit 1)
			( pub x :. retrn                  )
			( x =. x *. y :.  y =. y -. lit 1 )}
\end{lstlisting}

\subsection{Heartbeat \& Oxygen Saturation Sensor}
As an example, the addition of a new sensor will be demonstrated. The heartbeat
and oxygen saturation sensor add-on is a \textsc{PCB} the size of a fingernail
with a red \gls{LED} and a light sensor on it. Moreover, it contains an
\textsc{I2C} chip to communicate. The company producing the chip provides the
programmer with example code for \gls{Arduino} and \textsc{mbed}. The sensor
emits red light and measures the returning light intensity. The microcontroller
hosting the device has to keep track of four seconds of samples to determine
the heartbeat. In the \gls{mTask}-system, an abstraction is made. The current
implementation runs on \textsc{mbed} supported devices.

\subsubsection{\gls{mTask} Classes}
First, a class has to be devised to store the functionality of the sensor. The
heartbeat sensor updates four values continuously, namely the heartbeat, the
validity of the reading, the oxygen saturation and the validity of it. For
every value a function is added to the new \CI{hb} class. Moreover, the
introduced datatype housing the values should implement the \CI{mTaskType}
classes. The definition is as follows:

\begin{lstlisting}[caption={The \texttt{hb} class}]
:: Heartbeat = HB Int
:: SP02      = SP02 Int

instance toByteCode Heartbeat, SP02
instance fromByteCode Heartbeat, SP02
derive class iTask Heartbeat, SP02

class hb v where
	getHb     :: (v Heartbeat Expr)
	validHb   :: (v Bool Expr)
	getSp02   :: (v SP02 Expr)
	validSp02 :: (v Bool Expr)
\end{lstlisting}

\subsubsection{Bytecode Implementation}
The class is available now, and the implementation can be created. The
implementation is trivial since the functionality is limited to retrieving
single values and no assignment is possible. The following code shows the
implementation. Dedicated bytecode instructions have been added to support the
functionality.

\begin{lstlisting}[caption={The \texttt{hb} bytecode instance}]
:: BC
	= BCNop
	| ...
	| BCGetHB
	| BCValidHB
	| BCGetSP02
	| BCValidSP02
	| ...

instance hb ByteCode where
	getHb = tell` [BCGetHB]
	validHb = tell` [BCValidHB]
	getSp02 = tell` [BCGetSP02]
	validSp02 = tell` [BCValidSP02]
\end{lstlisting}

\subsubsection{Device Interface}
The bytecode instructions are added but still the functionality needs to be
added to the device interface to be implemented by clients. The following
addition to \CI{interface.h} and the interpreter shows the added instructions.

\begin{lstlisting}[caption={Adding the device interface}]
// interface.h
...
#if HAVEHB == 1
uint16_t get_hb();
bool     valid_hb();
uint16_t get_spo2();
bool     valid_spo2();
#endif
...

// interpret.c
	while(pc < plen){
		switch(program[pc++]){
		...
#if HAVEHB == 1
		case BCGETHB:
			stack[sp++] = get_hb();
			break;
		case BCVALIDHB:
			stack[sp++] = valid_hb();
			break;
		case BCGETSP02:
			stack[sp++] = get_spo2();
			break;
		case BCVALIDSP02:
			stack[sp++] = valid_spo2();
			break;
#endif
		...
\end{lstlisting}

\subsubsection{Client Software}
The device client software always executes the \CI{real\_setup} in which the
client software can setup the connection and peripherals. In the case of the
heartbeat peripheral it starts a thread running the calculations. The thread
started in the setup will set the global heartbeat and oxygen level variables
so that the interface functions for it can access it. The code is then as
follows:

\begin{lstlisting}[language=C,caption={}]
Serial pc;
Thread thread;

void heartbeat_thread(void) {
	// Constant heartbeat calculations
}

void real_setup(void) {
	pc.baud(19200);
	thread.start(heartbeat_thread);
}
\end{lstlisting}

\subsubsection{Example Program}
% todo
