+%chktex-file 17
\documentclass[../thesis.tex]{subfiles}
\input{subfilepreamble}
-\setcounter{chapter}{5}
+\setcounter{chapter}{6}
\begin{document}
\input{subfileprefix}
\item an architectural overview of \gls{MTASK} applications;
\item the interface for connecting devices;
\item the interface for lifting \gls{MTASK} tasks to \gls{ITASK} tasks;
- \item a interface for lowering \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS};
+ \item the interface for lowering \gls{ITASK} \glspl{SDS} to \gls{MTASK} \glspl{SDS};
\item and a non-trivial home automation example application using all integration mechanisms;
\end{itemize}
\end{chapterabstract}
Devices are connected to the system using the \cleaninline{withDevice} function (see \cref{sec:withdevice}).
Using \cleaninline{liftmTask}, \gls{MTASK} tasks are lifted to a device (see \cref{sec:liftmtask}).
\glspl{SDS} from \gls{ITASK} are lowered to the \gls{MTASK} device using \cleaninline{lowerSds} (see \cref{sec:liftsds}).
+\todo[inline]{mTask device\textsubscript{n} naar hfstk 5? Uitleg over taken en sensoren en \ldots? evt.\ zelfs naar intro hmmm?}
+\todo[inline]{Benoem dat er meerdere devices kunnen zijn en meerdere tasks op één device, en verwijs naar 6.5}
\begin{figure}
\centering
The first \gls{SDS} is the information about the \gls{RTS} of the device, i.e.\ metadata on the tasks that are executing, the hardware specification and capabilities, and a list of fresh task identifiers.
The second \gls{SDS} is a map storing downstream \gls{SDS} updates.
When a lowered \gls{SDS} is updated on the device, a message is sent to the server.
-This message is initially queued in the map in order to properly handly multiple updates asychronously.
+This message is initially queued in the map in order to properly handle multiple updates asynchronously.
Finally, the \cleaninline{MTDevices} type contains the communication channels.
The \cleaninline{withDevice} task itself first constructs the \glspl{SDS} using the \gls{ITASK} function \cleaninline{withShared}.
\end{enumerate}
\begin{lstClean}[caption={Pseudocode for the \texttt{withDevice} function in \gls{MTASK}.},label={lst:pseudo_withdevice}]
+withDevice :: a (MTDevice -> Task b) -> Task b | ...
withDevice spec deviceTask =
- withShared default \dev->parallel
+ withShared default \dev->
withShared newMap \sdsupdates->
withShared ([], [MTTSpecRequest], False) \channels->
- [ channelSync spec channels
- , watchForShutdown channels
- , watchChannelMessages dev channels
- , waitForSpecification
- >>| deviceTask (MTDevice dev sdsupdates channels)
- >>* [ifStable: issueShutdown]
- ]
+ parallel
+ [ channelSync spec channels
+ , watchForShutdown channels
+ , watchChannelMessages dev channels
+ , waitForSpecification
+ >>| deviceTask (MTDevice dev sdsupdates channels)
+ >>* [OnValue $ ifStable $ \_->issueShutdown]
+ ]
\end{lstClean}
If at any stage an unrecoverable device error occurs, an \gls{ITASK} exception is thrown in the \cleaninline{withDevice} task.
For example, if a device fails, the task can be sent to another device as can be seen in \cref{lst:failover}.
This function executes an \gls{MTASK} task on a pool of devices connected through \gls{TCP}.
If a device error occurs during execution, the next device in the pool is tried until the pool is exhausted.
-If another type of error occurs, it is rethrown for a parent task to catch.
+If another type of error occurs, it is re-thrown for a parent task to catch.
\begin{lstClean}[caption={An \gls{MTASK} failover combinator.},label={lst:failover}]
failover :: [TCPSettings] (Main (MTask BCInterpret a)) -> Task a
failover [] _ = throw "Exhausted device pool"
failover [d:ds] mtask = try (withDevice d (liftmTask mtask)) except
where except MTEUnexpectedDisconnect = failover ds mtask
- except _ = throw e
+ except e = throw e
\end{lstClean}
\section{Lifting mTask tasks}\label{sec:liftmtask}
\end{enumerate}
\begin{lstClean}[label={lst:liftmTask_pseudo},caption={Pseudocode implementation for \texttt{liftmTask}.}]
+liftmTask :: (Main (MTask BCInterpret a)) MTDevice -> Task a | iTask a
liftmTask task (MTDevice dev sdsupdates channels)
= freshTaskId dev
>>= \tid->withCleanupHook (sendmessage [MTTTaskDel tid] channels) (
compile task \mrefs msgs->
- sendMessage msgs channels
+ sendMessage msgs channels
>>| waitForReturnAndValue tid dev
-|| watchSharesDownstream mrefs tid sdsupdates
-|| watchSharesUpstream mrefs channels tid)
Preloading means that the task is compiled and integrated into the device firmware.
On receiving a \cleaninline{TaskPrep}, a hashed value of the task to be sent is included.
The device then checks the preloaded task registry and uses the local preloaded version if the hash matches.
-Of course this only works for tasks that are not tailor made for the current work specification and not depend on run time information.
+Of course this only works for tasks that are not tailor-made for the current work specification and not depend on run time information.
The interface for task preloading can be found in \cref{lst:preload}.
Given an \gls{MTASK} task, a header file is created that should be placed in the source code directory of the \gls{RTS} before building to include it in the firmware.
mtask :: (Shared sds Bool) -> Main (MTask v Bool)
| mtask, lowerSds v & RWShared sds
mtask sh =
- declarePin D13 PMOutput \d13->
+ declarePin D13 PMOutput \ledPin->
lowerSds \ls=sh
In fun \f=(\st->
getSds ls
- >>*. [IfValue (\v->v !=. st) (\v->writeD d13 v)]
- >>|. f (Not st))
- In {main=f true}
+ >>*. [IfValue (\v->v !=. st) (writeD ledPin)]
+ >>=. f)
+ In {main=getSds ls >>~. f}
\end{lstClean}
\section{Conclusion}
-When \gls{IOT} edge devices run the \gls{MTASK} \gls{RTS}, they become little \gls{TOP} engines of their own.
+This chapter explained the integration of \gls{MTASK} programs with \gls{ITASK}.
Using just three \gls{ITASK} functions, \gls{MTASK} devices are integrated in \gls{ITASK} seamlessly.
Devices, using any supported type of connection, are integrated in \gls{ITASK} using the \cleaninline{withDevice} function.
Once connected, \gls{MTASK} tasks are sent to the device for execution using \cleaninline{liftmTask}, lifting them to full-fledged \gls{ITASK} tasks.
Furthermore, the \gls{MTASK} tasks interact with \gls{ITASK} \glspl{SDS} using the \cleaninline{lowerSds} construct.
All of this together allows programming all layers of an \gls{IOT} system from a single source and in a single paradigm.
All details regarding interoperation are automatically taken care of.
-The following section contains an elaborate example using all integration functions that has deliberately been placed after the conclusion so that the code listing and description are on facing pages.
+The following section contains an elaborate example using all integration functions that has deliberately been placed after the conclusion.
+
+\newpage
+\vspace*{\fill}
+\hfill
+\begin{center}
+ \cleaninline[basewidth=0pt,columns=flexible,basicstyle=\tt\footnotesize]{let p = [['This page would be intentionally blank if I were not telling you that ']:p] in p} % chktex 10
+\end{center}
+\vspace{\fill}
+\newpage
-\begin{figure}[p]
- \begin{fullpage}
-% \begin{leftfullpage}
- \vspace{\headsep}
\section{Home automation}
+\todo[inline]{Meer uitleg over de applicatie? ADT ipv strings voor keuze?}
This section presents an interactive home automation program (\cref{lst:example_home_automation}) to illustrate the integration of the \gls{MTASK} language and the \gls{ITASK} system.
-It consists of a web interface for the user to control which tasks are executed on either one of two connected devices: an \gls{ARDUINO} UNO, connected via a serial port; and an ESP8266 based prototyping board called NodeMCU, connected via \gls{TCP} over \gls{WIFI}.
-
+It consists of a web interface for the user to control which tasks are executed on either one of two connected devices: an \gls{ARDUINO} UNO, connected via a serial port; and an ESP8266 based prototyping board called NodeMCU, connected via \gls{TCP}\slash{}\gls{WIFI}.
\Crefrange{lst:example:spec1}{lst:example:spec2} show the specification for the devices.
-The UNO is connected via serial using the unix filepath \path{/dev/ttyACM0} and the default serial port settings.
+The UNO is connected via serial using the UNIX filepath \path{/dev/ttyACM0} and the default serial port settings.
The NodeMCU is connected via \gls{WIFI} and hence the \cleaninline{TCPSettings} record is used.
-Both types have \cleaninline{channelSync} instances.
+%Both types have \cleaninline{channelSync} instances.
The code consists of an \gls{ITASK} part and several \gls{MTASK} parts.
\Crefrange{lst:example:task1}{lst:example:task2} contains the \gls{ITASK} task that coordinates the \gls{IOT} application.
-First the devices are connected (\crefrange{lst:example:conn1}{lst:example:conn2}) followed by launching a \cleaninline{parallel} task, visualized as a tabbed window, and a shutdown button to terminate the program (\crefrange{lst:example:par1}{lst:example:par2}).
+First the devices are connected (\crefrange{lst:example:conn1}{lst:example:conn2}) followed by launching a \cleaninline{parallel} task, visualised as a tabbed window, and a shutdown button to terminate the program (\crefrange{lst:example:par1}{lst:example:par2}).
This parallel task is the controller of the tasks that run on the edge devices.
It contains one task that allows adding new tasks (using \cleaninline{appendTask}) and all other tasks in the process list will be \gls{MTASK} tasks once they are added by the user.
The controller task, \cleaninline{chooseTask} as shown in \crefrange{lst:example:ct1}{lst:example:ct2}, allows the user to pick a task, and sending it to the specified device.
Using \cleaninline{lowerSds}, the status of the light switch is synchronised with the user.
Finally, a task that calculates the factorial of a user-provided number is shown in the list.
- \vspace{4ex}
- \begin{center}
- \begin{subfigure}[b]{.3\linewidth}
- \includegraphics[width=\linewidth]{home_auto1}
- \caption{Select task.}%
- \label{fig:example_screenshots1}
- \end{subfigure}
- \begin{subfigure}[b]{.3\linewidth}
- \includegraphics[width=\linewidth]{home_auto2}
- \caption{Select device.}%
- \label{fig:example_screenshots2}
- \end{subfigure}
- \begin{subfigure}[b]{.3\linewidth}
- \includegraphics[width=\linewidth]{home_auto3}
- \caption{View result.}%
- \label{fig:example_screenshots3}
- \end{subfigure}
- \caption{Screenshots of the home automation example program in action.}%
- \label{fig:example_screenshots}
- \end{center}
- %\end{leftfullpage}
- \end{fullpage}
+\begin{figure}[!ht]
+ \centering
+ \begin{subfigure}[b]{.3\linewidth}
+ \includegraphics[width=\linewidth]{home_auto1}
+ \caption{Select task.}%
+ \label{fig:example_screenshots1}
+ \end{subfigure}
+ \begin{subfigure}[b]{.3\linewidth}
+ \includegraphics[width=\linewidth]{home_auto2}
+ \caption{Select device.}%
+ \label{fig:example_screenshots2}
+ \end{subfigure}
+ \begin{subfigure}[b]{.3\linewidth}
+ \includegraphics[width=\linewidth]{home_auto3}
+ \caption{View result.}%
+ \label{fig:example_screenshots3}
+ \end{subfigure}
+ \caption{Screenshots of the home automation example program in action.}%
+ \label{fig:example_screenshots}
\end{figure}
\begin{figure}[p]