MontiThings — Modeling the Internet of Things

MontiThings [KRS+22] is an ecosystem for the model-driven development of IoT applications. It provides an end-to-end solution to modeling [KRS+22], deploying [KKR+22], and analyzing [KMR21] failure-tolerant [KRS+22] IoT applications and connecting them to digital twins [KMR+20]. Further, MontiThings provides a model-driven app store concept to decouple hard- and software developement [BKK+22].

MontiThings IoT Modelling Language

The core of MontiThings is a domain-specific language for the specification of IoT applications. Like MontiArc [BKRW17a] [HRR12], this underlying language describes IoT applications as a component-and-connector (C&C) architecture. Applications consist of components that can exchange data with other components via (directed and typed) ports that are linked by connectors. Via sensor/actuator ports (shown by black filling), ports can also interact with the hardware of the IoT devices and, for example, accept a sensor value. The behavior of components can be described in one of four ways:

  • using statecharts
  • using an IoT-focussed Java-like language
  • using handwritten C++ Code
  • by instantiating and connecting other components in hierarchical compositions

Ecosystem Overview

At design time, developers model several aspects of their IoT application:

  • MontiThings models describe the business logic, i.e., functionality and data flow
  • Class diagrams [Rum16] describe the data structures used by components to exchange data
  • Handwritten code describes the behavior of components (C++) or the interaction with hardware (C++, Python)
  • Tagging [GLRR15] is used for various purposes, e.g., tagging components with hardware requirements or connecting IoT applications to digital twins [KMR+20]

In addition to this, there can also be platform dependent artifacts such as different libraries that are used to allow the generated code to interact with specific platforms. The project’s artifacts are uploaded to an online repository such as GitLab or GitHub. There, a CI/CD pipline transforms the models (if necessary [KMR21]), generates C++ code from the models, (cross-)compiles the code, and finally packages the applications as Docker images. If not specified otherwise by the developers, there is one Docker image per component type.

At runtime, IoT devices download these Docker images to execute parts of the application and, together, execute the full IoT application. The IoT devices may interact with numerous services that provide, e.g., communication between the components, digital twins [KMR+20], monitoring [KMR21], or deployment [KKR+22] decisions.

Adaptive Device-Owner-Controlled Deployment

IoT applications can be very dynamic. New devices may join the system at runtime and others may fail or otherwise leave the system.
Accordingly, deployment decisions must be made at runtime. Since IoT systems can also be very heterogeneous (both in terms of single IoT devices and the set of a devices present in a system), IoT applications should be developed as product lines that can adapt to varying environments. Therefore, MontiThings offers a deployment algorithm [KKR+22] that can decide at runtime which device runs which functional components.

For this purpose, the developers (which we call global managers in this context) define the hardware requirements of the individual components. On the one hand, the deployment algorithm takes into account the technical requirements of the functional components and the technical capabilities of the IoT devices so that software is only ever run on compatible devices. On the other hand, the algorithm also considers the requirements of the device owners (which we call local managers). Device owners can express their local requirements in the form of rules. For example, you can prohibit recording software from running in the bedroom or require that smoke detector componenets are executed in each room.

Unfortunately, not all requirements of the device owners can always be met. For example, if they request that smoke detector software be run in every room, even though the necessary hardware is not available in every room, the rule cannot be met. In these cases, MontiThings automatically makes modification proposals according to which either new hardware is purchased (“buy a new smoke detector for the living room”) or rules are weakened (“run the smoke detector software in all rooms except the living room”). The device owners always have the final say on whether a proposal is accepted. If a valid deployment could be found, the IoT devices are automatically informed about which software they have to run.

Technically, MontiThings’ deployment supports four different ecosystems for deploying the Docker images to IoT devices:

Failure Detection, Analysis and Recovery

Even if developers take great care in modeling their application, unfortunately not all errors are always predictable. Some errors are not visible due to the higher abstraction level of the models. In practice, it can therefore happen that an application does not behave as expected, even if no error is visible in the model. For example, the hardware on which the software is running may fail due to harsh environmental conditions (vibrations, humidity, …) or a network may not be available.

MontiThings provides tools and methods to analyze such errors [KMR21] as well as to fix them automatically (within certain limits) [KRS+22]. At runtime, log messages of components can be traced within the architecture similar to a “stack trace” to find the root cause of their occurrence. For this purpose, the messages exchanged by components are traced back to find the component that first exhibited the unexpected behavior. Furthermore, Architectures can be observed at runtime and then modified by model-to-model transformations to make their behavior reproducible for developers retrospectively [KMR21].

If a component fails because the IoT device running it is no longer functional, one possible automatic troubleshooting strategy is for MontiThings to transfer the component to another suitable device [KRS+22]. This automatically restores the state of the failed component. In order to put the replacement component in the state of the failed component, the messages that the failed component processed are played back to the replacement component. The connectors of the replacement component are not yet connected to other components, so that messages generated during this recovery process do not affect the other components. The connectors are connected only after the recovery. To handle non-deterministic behavior and to reduce the complexity of this procedure to O(1) (instead of O(n) if all messages have to be restored, where n is the number of messages), components can also serialize their state directly (usually after a constant number of processed messages) and store it in a central system. Thus, in the event of a failure, only a constant number of messages, namely the messages since the last state storage, need to be restored. To bridge short-term downtimes, e.g., of a power saving mode, without causing network overhead, components can also store their serialized state locally.

App Store Concept

MontiThings includes an app store concept [BKK+22] that separates hardware and software development. In addition to the software itself, software developers specify the hardware requirements of each component using OCL expressions. These OCL expressions are written against a class diagram provided by the app store. This class diagram serves as a hardware ontology specifying which types of hardware are covered by the app store. For example, it could specify that IoT devices of the app store can provide a camera and that a camera has certain properties (such as a resolution given in megapixels). The hardware developers on the other hand develop the drivers necessary to connect software components to their hardware. Additionally, they specify the hardware of each device using an object diagram conforming to the same class diagram provided by the app store. Since both the OCL expressions (hardware requirements of software components) and the object diagram (hardware specification) are conforming to the same app store-provided class diagram (hardware ontology), MontiThings can match the software components to IoT devices fulfilling their requirements. This is done by generating Prolog code from both the OCL expressions and the object diagrams and integrating them in the Prolog-based deployment algorithm.

Key Statements

  1. IoT software architectures can be modeled in hierarchically decomposed systems using message passing.
  2. To achieve the flexibility required by future IoT app stores, the connection between high-level application software and low-level hardware drivers shall be established at runtime.
  3. By generating Prolog code to compute the deployment, device owners can not only set rules for the deployment, but also be given modification proposals (such as buying new hardware) in the case of unfulfillable rules.
  4. When IoT applications are developed using model-driven techniques (such as with C&C architectures), the reliability of the application can be increased by providing error analysis and handling systematically by the code generator.

Selected Topic-Specific Publications

  1. [BKK+22]
    A. Butting, J. C. Kirchhof, A. Kleiss, J. Michael, R. Orlov, B. Rumpe:
    In: Proceedings of the 21th ACM SIGPLAN International Conference on Generative Programming: Concepts and Experiences (GPCE 22), pp. 108-121, ACM, Dec. 2022.
  2. [KKR+22]
    J. C. Kirchhof, A. Kleiss, B. Rumpe, D. Schmalzing, P. Schneider, A. Wortmann:
    In: ACM Transactions on Internet of Things, Association for Computing Machinery, Nov. 2022.
  3. [KRS+22]
    J. C. Kirchhof, B. Rumpe, D. Schmalzing, A. Wortmann:
    In: Journal of Systems and Software, W.- K. Chan (Eds.), Volume 183, pp. 1-21, Elsevier, Jan. 2022.
  4. [KMR21]
    J. C. Kirchhof, L. Malcher, B. Rumpe:
    In: Proceedings of the 20th ACM SIGPLAN International Conference on Generative Programming: Concepts and Experiences (GPCE 21), E. Tilevich, C. De Roover (Eds.), pp. 197-209, ACM SIGPLAN, Oct. 2021.
  5. [KMR+20]
    J. C. Kirchhof, J. Michael, B. Rumpe, S. Varga, A. Wortmann:
    In: Proceedings of the 23rd ACM/IEEE International Conference on Model Driven Engineering Languages and Systems, pp. 90-101, ACM, Oct. 2020.
  6. [BKRW17a]
    A. Butting, O. Kautz, B. Rumpe, A. Wortmann:
    In: In 12th International Conference on Software Engineering Advances (ICSEA 2017), pp. 213-218, IARIA XPS Press, May 2017.
  7. [Rum16]
    B. Rumpe:
    Springer International, Jul. 2016.
  8. [GLRR15]
    T. Greifenberg, M. Look, S. Roidl, B. Rumpe:
    In: Conference on Model Driven Engineering Languages and Systems (MODELS’15), pp. 34-43, ACM/IEEE, 2015.
  9. [HRR12]
    A. Haber, J. O. Ringert, B. Rumpe:
    RWTH Aachen University, AIB-2012-03, Technical Report, Feb. 2012.