Create Twins

Digital Twins are used to structure, publish and follow data from and to other Digital Twins and/or external data sources and data consumers. The Create Twins function is the first step towards setting up a fully-fledged Digital Twin with metadata properties and data feeds.

This page details how to create Digital Twins and introduces the concept of Digital Twin Models.

Please note that parts of this page can also be executed through the IOTICSpace user interface.

This page covers:


Introduction to Create Digital Twins

IOTICS distinguishes between three different types of Digital Twins:

  1. Digital Twin: the virtual representation or an "instance" of a real asset, person or concept.
  2. Digital Twin Model: the template or structure of a Digital Twin from Model.
  3. Host Twin: the virtual representation of your IOTICSpace (Host).

All Digital Twins have specific metadata and data feeds. The Digital Twins from Model contain data about the real asset, concept or person, whereas the Digital Twin Model serves as the template or structure of Digital Twins from Model. The Model is used to describe the properties and fields the Digital Twins associated to that Model should have.

A Digital Twin Model has the same structure as a Digital Twin and can be managed and manipulated in the same way. You can distinguish Models from Digital Twins by their property type = Model.

πŸ“˜

Go to Create Twin Models for more details on how to create a Digital Twin Model.

Create Digital Twins

Digital Twins can be created through the IOTICSpace user interface and the IOTICS API. This sections details both options.

πŸ“˜

Please note that best practice is to create a Digital Twin Model first, and then create a Digital Twin from that Model. This enables a unified structure and semantic description across all Twins of the same type of real asset, person or concept. Only exceptionally should a Twin be created without a Model, for example when only one single Digital Twin of one type is required, or if the Digital Twins are and will only be automatically created from a connector.

Create a Digital Twin with the IOTICSpace User Interface

Navigate to the _Twins _section on your IOTICSpace user interface to create a new Digital Twin from an existing Digital Twin Model. Follow this step-by-step guide for more details.

Please note that in line with our best practices, Digital Twins can only be created from a Digital Twin Model through the IOTICSpace interface. Follow these steps to see how to create a Digital Twin Model.

Create a Digital Twin with the IOTICS API

Creating a fully fledged Digital Twin with metadata properties and data feeds requires the execution of a chain of functions. Create Twin and Create Feed are part of it, as well as Update Twin and Update Feed.

Click here to see the prerequisites.

Follow these steps to create the outline of a Digital Twin with its Identity (DID) and number of data feeds:

  1. Use Create Twin with Control Delegation to get its DID
  2. Use the Create Twin API to finish creating the Twin
  3. Use Create Feed for adding one or more data feeds (optional)

1. Use Create Twin with Control Delegation to get its DID

As a first step, we need to set up the Control Delegation to the Agent. This allows the Agent to create and control a new Digital Twin Identity.

By calling this function you create and receive the so-called twin_registered_id (= Digital Twin DID).

twin_registered_id = api.create_twin_with_control_delegation(
    twin_seed=AGENT_SEED,  # Generated in the "User Credentials" step
    twin_key_name="",  # Key Name of the twin to be created
    agent_registered_identity=agent_registered_id,  # Generated in the "User Delegation" step
    delegation_name="#ControlDeleg",
)

twin_did = twin_registered_id.did
print("Twin DID", twin_did)

2. Use the Create Twin API to finish creating the Twin

The Create Twin call finalises the creation of the Twin.

1.	Create Twin with control delegation and get a new "twin_registered_id" (DID)
2.	Use the Create Twin API call
from requests import request

response = request(
    method="POST",
    url=f"{HOST}/qapi/twins",
    headers=headers,
    json={"id": twin_did},
)

3. Use Create Feed for adding one or more data feeds (optional)

An IOTICS Digital Twin may have none, one or more data feeds. Use this call for each data feed you would like to add to the Twin. Skip this step if no data feed is required.

More details about Feeds and a step-by-step guide on how to share data through a Feed can be found here.

1.	Create Twin with control delegation and get a new "twin_registered_id" (DID)
2.	Use the Create Twin API call
3.  Use the Create Feed API call
from requests import request

response = request(
    method="POST",
    url=f"{HOST}/qapi/hosts/{host_id}/twins/{twin_did}/feeds",
    headers=headers,
    json={"id": feed_id},
)

response.raise_for_status()

Create Twin Tutorial

Click to see the entire code on how to create a Twin and a Feed

from iotics.lib.identity.api.high_level_api import get_rest_high_level_identity_api
from requests import request

RESOLVER_URL = "resolver_url"
HOST = "host_url"

USER_KEY_NAME = "user_key_name"
AGENT_KEY_NAME = "agent_key_name"
USER_SEED = bytes.fromhex("user_seed")
AGENT_SEED = bytes.fromhex("agent_seed")


class IoticsRest:
    def __init__(self):
        self._high_level_api = get_rest_high_level_identity_api(
            resolver_url=RESOLVER_URL
        )

        (
            self._user_registered_id,
            self._agent_registered_id,
        ) = self._high_level_api.create_user_and_agent_with_auth_delegation(
            user_seed=USER_SEED,
            user_key_name=USER_KEY_NAME,
            agent_seed=AGENT_SEED,
            agent_key_name=AGENT_KEY_NAME,
            delegation_name="#AuthDeleg",
        )

        token = self._high_level_api.create_agent_auth_token(
            agent_registered_identity=self._agent_registered_id,
            user_did=self._user_registered_id.did,
            duration=10,
        )

        self._headers = {
            "accept": "application/json",
            "Iotics-ClientAppId": "example_code",
            "Authorization": f"Bearer {token}",
            "Content-Type": "application/json",
        }

    def _make_api_call(self, method: str, url: str, json: dict = None):
        response = request(method=method, url=url, headers=self._headers, json=json)
        response.raise_for_status()

        return response.json()

    def create_twin_identity(self, twin_key_name: str):
        twin_registered_id = self._high_level_api.create_twin_with_control_delegation(
            twin_seed=AGENT_SEED,
            twin_key_name=twin_key_name,
            agent_registered_identity=self._agent_registered_id,
            delegation_name="#ControlDeleg",
        )

        return twin_registered_id.did

    def create_twin(self, twin_did: str):
        twin = self._make_api_call(
            method="POST", url=f"{HOST}/qapi/twins", json={"id": twin_did}
        )

        return twin

    def create_feed(self, twin_did: str, host_id: str, feed_id: str):
        feed = self._make_api_call(
            method="POST",
            url=f"{HOST}/qapi/hosts/{host_id}/twins/{twin_did}/feeds",
            json={"id": feed_id},
        )

        return feed


def main():
    iotics_rest = IoticsRest()
    twin_did = iotics_rest.create_twin_identity(twin_key_name="SensorTwin")
    twin = iotics_rest.create_twin(twin_did=twin_did)
    host_id = twin["twinId"]["hostId"]
    iotics_rest.create_feed(twin_did=twin_did, host_id=host_id, feed_id="temperature")


if __name__ == "__main__":
    main()