{"id":28730039,"url":"https://github.com/eshanjayasundara/opentwindocumentation","last_synced_at":"2026-04-20T19:32:24.558Z","repository":{"id":244138881,"uuid":"814378070","full_name":"EshanJayasundara/OpenTwinDocumentation","owner":"EshanJayasundara","description":"Perspicuous documentation for OpenTwins platform by Eshan Jayasundara. I was documented this because there was no clear documentation can be found on the internet even the quickstart guid in the opentwins repository is somewhat confusing for a beginner.","archived":false,"fork":false,"pushed_at":"2024-06-13T16:15:38.000Z","size":5171,"stargazers_count":1,"open_issues_count":0,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-10-14T20:35:16.868Z","etag":null,"topics":["ditto","eclipse","grafana","influxdb","kafka","mosquitto","telegraf"],"latest_commit_sha":null,"homepage":"","language":"Python","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":null,"status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/EshanJayasundara.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":null,"code_of_conduct":null,"threat_model":null,"audit":null,"citation":null,"codeowners":null,"security":null,"support":null,"governance":null,"roadmap":null,"authors":null,"dei":null,"publiccode":null,"codemeta":null,"zenodo":null}},"created_at":"2024-06-12T22:33:58.000Z","updated_at":"2025-01-20T11:13:12.000Z","dependencies_parsed_at":null,"dependency_job_id":"37b17582-8279-4d7d-a7f3-60077378b505","html_url":"https://github.com/EshanJayasundara/OpenTwinDocumentation","commit_stats":null,"previous_names":["eshanjayasundara/opentwindocumentation"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/EshanJayasundara/OpenTwinDocumentation","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EshanJayasundara%2FOpenTwinDocumentation","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EshanJayasundara%2FOpenTwinDocumentation/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EshanJayasundara%2FOpenTwinDocumentation/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EshanJayasundara%2FOpenTwinDocumentation/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/EshanJayasundara","download_url":"https://codeload.github.com/EshanJayasundara/OpenTwinDocumentation/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/EshanJayasundara%2FOpenTwinDocumentation/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":32062365,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-04-20T11:35:06.609Z","status":"ssl_error","status_checked_at":"2026-04-20T11:34:48.899Z","response_time":94,"last_error":"SSL_connect returned=1 errno=0 peeraddr=140.82.121.6:443 state=error: unexpected eof while reading","robots_txt_status":"success","robots_txt_updated_at":"2025-07-24T06:49:26.215Z","robots_txt_url":"https://github.com/robots.txt","online":false,"can_crawl_api":true,"host_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub","repositories_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories","repository_names_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repository_names","owners_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners"}},"keywords":["ditto","eclipse","grafana","influxdb","kafka","mosquitto","telegraf"],"created_at":"2025-06-15T17:30:32.147Z","updated_at":"2026-04-20T19:32:24.531Z","avatar_url":"https://github.com/EshanJayasundara.png","language":"Python","funding_links":[],"categories":[],"sub_categories":[],"readme":"### Perspicuous documentation for [`OpenTwins`](https://github.com/ertis-research/opentwins/tree/main) platform by [Eshan Jayasundara](https://www.linkedin.com/in/eshan-jayasundara/).\u003c/br\u003e\n\nWhat is a digital twin in a high-level view? [Watch This](https://www.youtube.com/watch?v=60eCpw0Toy4)\n# 1. Quick Deployment\n\n## Simplified Architecture of the Essential Functionality\n![opentwins](./embedded-images/opentwins.png)\n\n## Prerequisits\n+ [Minikube single node kubernetes cluster](https://minikube.sigs.k8s.io/docs/start/?arch=%2Flinux%2Fx86-64%2Fstable%2Fbinary+download) (for container ocaustration)\n+ [Kubctl](https://kubernetes.io/docs/tasks/tools/install-kubectl-linux/#install-using-native-package-management) (kubernetes command line interface for intract with minikube cluster)\n+ [Docker](https://docs.docker.com/engine/install/ubuntu/#install-using-the-repository) (for containarization)\n+ [Helm](https://helm.sh/docs/intro/install/) (to copy charts from the helm repository)\n+ Linux base Operating System (tested on ubuntu)\n\n## Steps to follow\n\n### Start minikube cluster\n```\nminikube start --cpus 4 --disk-size 40gb --memory 8192 -p \u003cname-of-the-profile\u003e\n```\nchange `name-of-the-profile` field as you need but keep it remember for later steps.\n\n### Create a namespace in Kubernetes\n```\nkubectl create namespace \u003cyour-own-name-space\u003e\n```\nreplace `your-own-name-space` with as you wish but keep it remembered for future use.\n\n### Add helm repository into the charts\n```\nhelm repo add ertis https://ertis-research.github.io/Helm-charts/\n```\n\n### Install OpenTwins (https://ertis-research.github.io/opentwins/docs/installation/using-helm)\n```\nhelm upgrade --install opentwins ertis/OpenTwins -n \u003cyour-own-name-space\u003e --dependency-update --debug\n```\n\n### Wait until all the services, pods, and deployments are up and running after installation\n+ To check the status of pods\n```\nkubectl get pods -n \u003cyour-own-name-space\u003e\n```\n+ To check the status of services\n```\nkubectl get services -n \u003cyour-own-name-space\u003e\n```\n+ To check the deployments\n```\nkubectl get deployments -n \u003cyour-own-name-space\u003e\n```\n_you may need to check those with executing the above commands repeatedly in another terminal_\n\n### If some pods are in the Completed state\n```\nkubectl delete pod \u003cpod-name\u003e -n \u003cyour-own-name-space\u003e\n```\nTake a note of them. Run the above command by replacing `pod_name` with the actual pod name and `your-own-name-space` with the namespace that you have noted before.\n\n### Access Grafana from the browser\n```\nminikube service -n \u003cyour-own-name-space\u003e opentwins-grafana --url -p \u003cname-of-the-profile\u003e\n```\nThe default username and password both are “admin”\n\n### At this point the cluster needs a restart to detect the OpenTwins GUI (maybe optional)\n```\nminikube stop -p \u003cname-of-the-profile\u003e\nminikube start -p \u003cname-of-the-profile\u003e\n```\nEnsure everything is back up and running\n\n### Log into Grafana and access the OpenTwins plugin \n`Home -\u003e Administration -\u003e Plugins -\u003e OpenTwins`\n\n__The plugin needs some configuration. The default ditto _username_ and _password_ both are `ditto`. For the developer account _username_ is `devops` and _password_ is `foobar`. As for the URLs use the outputs of the following commands.__\n```\nminikube service -n \u003cyour-own-name-space\u003e opentwins-ditto-nginx --url -p \u003cname-of-the-profile\u003e\n\nminikube service -n \u003cyour-own-name-space\u003e opentwins-ditto-extended-api --url -p \u003cname-of-the-profile\u003e\n```\nMake sure to replace `name-of-the-profile` and `your-own-name-space`.\n\n### Types and Twins Creation\n\nHere I'm going to create a digital twin for a sensor that measures the temperature, humidity, and CO2 level.\n\n#### Creating a Type\nclick on `create new type` button\n![newtype](./embedded-images/newtype.png)\nprovide the necessary details and fill the form. __Don't forget to use the `default_policy` as the policy.__\n![typesensor1](./embedded-images/typesensor1.png)\nAdd features\n![typesensor2](./embedded-images/typesensor2.png)\nfinally, the preview of the type in Ditto protocol looks like this\n![typesensorditto](./embedded-images/typesensorditto.png)\n\n#### Creating a Twin Using Type Template\nclick on `create new twin` button\n![newtwin](./embedded-images/newtwin.png)\nprovide the necessary namespace and id. __Don't use the same names used for creating twins because they are the instances of the type which we have created above.__\n![twinmysensor1](./embedded-images/twinmysensor1.png)\nfrom `existing types` choose the one just created before as the `type of twin`.\n![twinmysensor2](./embedded-images/twinmysensor2.png)\n##### Finally the preview of the twin in the Ditto protocol looks like this\n![twinmysensorditto](./embedded-images/twinmysensorditto.png)\n\n### Establish mqtt-5 connection in ditto\n__`Important:`__\u003c/br\u003e\n__Replace uri s with actual ones in your cluster including the curl command url.__\u003c/br\u003e\n__Python script and this connection request both should have the same topic.__\n```\ncurl -i -u devops:foobar -X POST http://192.168.49.2:30525/api/2/connections -H 'Content-Type: application/json' -d '{\n  \"name\": \"mymqtt_connection\",\n  \"connectionType\": \"mqtt-5\",\n  \"connectionStatus\": \"open\",\n  \"uri\": \"tcp://192.168.49.2:30511\",\n  \"sources\": [\n    {\n      \"addresses\": [\n        \"telemetry/#\"\n      ],\n      \"consumerCount\": 1,\n      \"qos\": 1,\n      \"authorizationContext\": [\n        \"nginx:ditto\"\n      ],\n      \"headerMapping\": {\n        \"correlation-id\": \"{{header:correlation-id}}\",\n        \"namespace\": \"{{ entity:namespace }}\",\n        \"content-type\": \"{{header:content-type}}\",\n        \"connection\": \"{{ connection:id }}\",\n        \"id\": \"{{ entity:id }}\",\n        \"reply-to\": \"{{header:reply-to}}\"\n      },\n      \"replyTarget\": {\n        \"address\": \"{{header:reply-to}}\",\n        \"headerMapping\": {\n          \"content-type\": \"{{header:content-type}}\",\n          \"correlation-id\": \"{{header:correlation-id}}\"\n        },\n        \"expectedResponseTypes\": [\n          \"response\",\n          \"error\"\n        ],\n        \"enabled\": true\n      }\n    }\n  ],\n  \"targets\": [],\n  \"clientCount\": 1,\n  \"failoverEnabled\": true,\n  \"validateCertificates\": true,\n  \"processorPoolSize\": 1,\n  \"tags\": []\n}'\n```\n\nfind ditto url with,\n```\nminikube service -n \u003cyour-own-namespace\u003e opentwins-ditto-nginx --url -p \u003cname-of-the-profile\u003e\n```\n\nfind mosquitto url with,\n```\nminikube service -n \u003cyour-own-namespace\u003e opentwins-mosquitto --url -p \u003cname-of-the-profile\u003e\n```\n\n```\n# check connections with\ncurl -i -X GET -u devops:foobar http://192.168.49.2:30525/api/2/connections\n\n# delete a connection\ncurl -i -X DELETE -u devops:foobar http://192.168.49.2:30525/api/2/connections/\u003cconnection-name\u003e\n```\n\n### Testing with a Python Script\n\n__You may use ditto [protocol preview of digital twin](#finally-the-preview-of-the-twin-in-Ditto-protocol-looks-like-this) to assign necessary values to the variables in this python file.__\n\n```\nimport paho.mqtt.client as mqtt\nimport random\nimport time\nimport json\n\n# Digital twin info\nnamespace = \"airquality\"\nsensor_name = \"mysensor\"\n\n# MQTT info\nbroker = \"192.168.49.2\"  # Replace with your MQTT broker address\nport = 30511  # Replace with your MQTT broker port\ntopic = \"telemetry/\"  # Topic where data will be published\n\n# Authentication info (replace with actual username and password)\nusername = \"\"\npassword = \"\"\n\n# MQTT connection\ndef on_connect(client, userdata, flags, rc):\n    if rc == 0:\n        print(\"Successful connection\")\n    else:\n        print(f\"Connection failed with code {rc}\")\n\nclient = mqtt.Client()\nclient.on_connect = on_connect\nclient.username_pw_set(username, password)\nclient.connect(broker, port, 60)\n\ndef generate_air_data():\n    temperature = random.uniform(15, 45)\n    humidity = random.uniform(0, 100)\n    co2 = random.uniform(0, 5)\n    return temperature, humidity, co2\n\ndef get_ditto_protocol_value_air(time, temperature, humidity, co2):\n    return {\n        \"temperature\": {\n            \"properties\": {\n                \"value\": temperature,\n                \"time\": time\n            }\n        },\n        \"humidity\": {\n            \"properties\": {\n                \"value\": humidity,\n                \"time\": time\n            }\n        },\n        \"co2\": {\n            \"properties\": {\n                \"value\": co2,\n                \"time\": time\n            }\n        }\n    }\n\ndef get_ditto_protocol_msg(name, value):\n    return {\n        \"topic\": f\"{namespace}/{name}/things/twin/commands/merge\",\n        \"headers\": {\n            \"content-type\": \"application/merge-patch+json\"\n        },\n        \"path\": \"/features\",\n        \"value\": value\n    }\n\n# Send data\ntry:\n    client.loop_start()  # Start the MQTT loop\n\n    while True:\n        t = round(time.time() * 1000)  # Unix time in ms\n\n        # Sensor twin\n        temperature, humidity, co2 = generate_air_data()\n        msg = get_ditto_protocol_msg(sensor_name, get_ditto_protocol_value_air(t, temperature, humidity, co2))\n        client.publish(topic + namespace + \"/\" + sensor_name, json.dumps(msg))\n        print(f\"{sensor_name} data published\")\n\n        time.sleep(5)\n\nexcept KeyboardInterrupt:\n    client.loop_stop()  # Stop the MQTT loop\n    client.disconnect()\n```\n\nAfter configuring all, run the Python script. Twin should show the published information as shown in the image below,\n![twindatamqtt](./embedded-images/twindatamqtt.png)\n\n### Deploying the kafka pod into the same minikube cluster\nFor Kafka to work, it is necessary to install ZooKeeper beforehand. In addition, CMAK, a tool to manage Apache Kafka, will be used to make it easier to use. Then, for the deployment, the pod-zookeeper.yaml, svc-zookeeper.yaml, pod-kafka.yaml, svc-kafka.yaml, deploy-kafka-manager.yaml and svc-kafka-manager.yaml files will be needed. Once you have them, you only need to apply them to the chosen namespace.\n\n```\n# envirinment variable\nexport NS = \u003cyour-own-name-space\u003e # replace this with your namespace\n\nkubectl apply -f pod-zookeeper.yaml -n $NS\nkubectl apply -f svc-zookeeper.yaml -n $NS\n\nkubectl apply -f pod-kafka.yaml -n $NS\nkubectl apply -f svc-kafka.yaml -n $NS\n\nkubectl apply -f deploy-kafka-manager.yaml -n $NS\nkubectl apply -f svc-kafka-manager.yaml -n $NS\n```\n\nAfter manual deployment all services may look like this,\n```\nkafka-cluster                  LoadBalancer\nkafka-manager                  NodePort\nopentwins-ditto-extended-api   NodePort\nopentwins-ditto-gateway        ClusterIP\nopentwins-ditto-nginx          NodePort\nopentwins-grafana              NodePort\nopentwins-influxdb2            NodePort  \nopentwins-mongodb              NodePort    \nopentwins-mosquitto            NodePort  \nzookeeper                      NodePort  \n```\nIf there is a service type different from the above, please use the command below and edit the service type,\n```\nkubectl edit service \u003cservice-name\u003e -n \u003cyour-own-namespace\u003e\n```\nreplace `\u003cservice-name\u003e` and `\u003cyour-own-namespace\u003e` with actual names.\n\n### Establishing Kafka connection in Ditto\n\n__`Important:`__\u003c/br\u003e\n__Replace uri s with actual ones in your cluster including the curl command URL.__\u003c/br\u003e\n\nThere are two methods, please use only one from below.\u003c/br\u003e\n\n+ 1st method\n```\ncurl -i -X POST -u devops:foobar -H 'Content-Type: application/json' --data '{\n  \"targetActorSelection\": \"/system/sharding/connection\",\n  \"headers\": {\n    \"aggregate\": false\n  },\n  \"piggybackCommand\": {\n    \"type\": \"connectivity.commands:createConnection\",\n    \"connection\": {\n        \"id\": \"kafka-connection\",\n        \"connectionType\": \"kafka\",\n        \"connectionStatus\": \"open\",\n        \"failoverEnabled\": true,\n        \"uri\": \"tcp://192.168.49.2:31102\",\n        \"specificConfig\": {\n            \"bootstrapServers\": \"192.168.49.2:31102\",\n            \"saslMechanism\": \"plain\"\n        },\n        \"sources\": [],\n        \"targets\": [\n            {\n            \"address\": \"digitaltwins\",\n            \"topics\": [\n                \"_/_/things/twin/events\",\n                \"_/_/things/live/messages\"\n            ],\n            \"authorizationContext\": [\n                \"nginx:ditto\"\n            ]\n            }\n        ]\n    }\n  }\n}' http://192.168.49.2:30525/devops/piggyback/connectivity\n```\n\n+ 2nd method\n```\ncurl -i -u devops:foobar -X POST http://192.168.49.2:30525/api/2/connections -H 'Content-Type: application/json' -d '{\n\t\"name\": \"new-connetion\",\n        \"connectionType\": \"kafka\",\n        \"connectionStatus\": \"open\",\n        \"failoverEnabled\": true,\n        \"uri\": \"tcp://192.168.49.2:31102\",\n        \"specificConfig\": {\n            \"bootstrapServers\": \"192.168.49.2:31102\",\n            \"saslMechanism\": \"plain\"\n        },\n        \"sources\": [],\n        \"targets\": [\n            {\n            \"address\": \"digitaltwins\",\n            \"topics\": [\n                \"_/_/things/twin/events\",\n                \"_/_/things/live/messages\"\n            ],\n            \"authorizationContext\": [\n                \"nginx:ditto\"\n            ]\n            }\n        ]\n}'\n```\n\nfind ditto url with,\n```\nminikube service -n \u003cyour-own-namespace\u003e opentwins-ditto-nginx --url -p \u003cname-of-the-profile\u003e\n```\n\nfind kafka url with,\n```\nminikube service -n \u003cyour-own-namespace\u003e kafka-cluster --url -p \u003cname-of-the-profile\u003e\n```\n\nEnsure the connections were configured in ditto\n\n```\n# check connections with\ncurl -i -X GET -u devops:foobar http://192.168.49.2:30525/api/2/connections\n\n# delete a connection\ncurl -i -X DELETE -u devops:foobar http://192.168.49.2:30525/api/2/connections/\u003cconnection-name\u003e\n```\n\n### Telegraf + Influxdb configuration\nInfluxdb pod comes default with the minikube cluster which you have just created initially,\n\naccess influxdb + telegraf URL with\n```\nkubectl get services -n \u003cyour-own-name-space\u003e # list all services\n\nminikube service -n \u003cyour-own-name-space\u003e \u003cinfluxdb-service-name\u003e --url -p \u003cname-of-the-profile\u003e\n```\n__`user name: admin`__\u003c/br\u003e\n__`password: password`__\n\n![influxdbui](./embedded-images/influxdbui.png)\n\ngenerate an API token with all permissions and copy it to chipboard using Influxdb UI\n![influxapikey1](./embedded-images/influxapikey1.png)\n![influxapikey2](./embedded-images/influxapikey2.png)\ncopy the apikey/token by selecting and right clicking on it.\n![influxapikey3](./embedded-images/influxapikey3.png)\n\nClick Create a configuration\n![influxinputplugin1](./embedded-images/influxinputplugin1.png)\nChoose \"default\" bucket and kafka-consumer plugin\n![influxinputplugin2](./embedded-images/influxinputplugin2.png)\ndownload the configuration which already displays kafka-consumer as input plugin and influxdb_v2 as output plugin after replacing the token, ClusterIP, relevent ports of kafka broker and influxdb services\n![influxinputpluginconfig](./embedded-images/influxinputpluginconfig.png)\n\n### Update ConfigMaps in the Cluster\naccessing configmaps\n```\nkubectl get configmaps -n \u003cyour-own-namespace\u003e\n```\nediting them one by one\n```\nkubectl edit configmap \u003ctelegraf\u003e -n \u003cyour-own-namespace\u003e\n```\n__`telegraf`__ - __represents the name of any configmap including the substring \"telegraf\"__\u003c/br\u003e\n\nedit all configmaps one by one using the downloaded file (most of the time it may look like the below example)\n\u003c/br\u003e\n\nfor example:\n```\ndata:\n  telegraf.conf: |\n    [agent]\n      collection_jitter = \"0s\"\n      debug = true\n      flush_interval = \"10s\"\n      flush_jitter = \"0s\"\n      hostname = \"\" #\n      interval = \"10s\"\n      metric_batch_size = 1000\n      metric_buffer_limit = 10000\n      omit_hostname = false\n      precision = \"\"\n\n    [[outputs.influxdb_v2]]\n      bucket = \"default\"\n      organization = \"opentwins\"\n      token = \u003cyour-token-extracted\u003e\n      urls = [\"\u003cinfluxdb-url\u003e\"]\n\n    [[inputs.kafka_consumer]]\n      brokers = [\"\u003ckafka-broker-url\u003e\"]\n      topics = [\"digitaltwins\"]\n      consumer_group = \"telegraf_metrics_consumers\"\n      offset = \"oldest\"\n      data_format = \"json\"\n```\n\n__dont forget to replace `\u003cyour-token-extracted\u003e`__ with actual token.\n\nfind the relevent influxdb, kafka urls with,\n```\nminikube service -n \u003cyour-own-namespace\u003e opentwins-influxdb2 --url -p \u003cname-of-the-profile\u003e\n\nminikube service -n \u003cyour-own-namespace\u003e kafka-cluster --url -p \u003cname-of-the-profile\u003e\n```\n\nredeploy the telegraf deployment\n```\nkubectl rollout restart deployment telegraf -n opentwins\n```\n\n### visualising in grafana\n\n`Home -\u003e Connections -\u003e Connect data -\u003e Search for InfluxDB`\n![grafanainfluxsearch](./embedded-images/grafanainfluxsearch.png)\ncreate a new InfluxDB data source\n![grafanacreatenewinflux](./embedded-images/grafanacreatenewinflux.png)\nConfigure it as sown in the images below\n```\nminikube service -n \u003cyour-own-namespace\u003e opentwins-influxdb2 --url -p \u003cname-of-the-profile\u003e\n```\nfind the URL with the above command\n\n![grafanainfluxconfig1.png](./embedded-images/grafanainfluxconfig1.png)\n![grafanainfluxconfig2.png](./embedded-images/grafanainfluxconfig2.png)\n\nSave and test the connection\n![influxtestconnection](./embedded-images/influxtestconnection.png)\n\ncreate a new dashboard\u003c/br\u003e\n`Home -\u003e Dashboards`\n\nchoose InfluxDB as the data source for querying and `gauge` as the visualization. Add a title. Then, apply some overrides to change the `display names` of the gauges. __Don't forget to save the changes.__\n![queryinfluxdb](./embedded-images/queryinfluxdb.png)\n\nexample query:\n```\nimport \"strings\"\n\nfrom(bucket: \"default\")\n  |\u003e range(start: v.timeRangeStart, stop: v.timeRangeStop)\n  |\u003e filter(fn: (r) =\u003e r[\"_measurement\"] == \"kafka_consumer\")\n  |\u003e filter(fn: (r) =\u003e r[\"host\"] == \"telegraf-57cfdcb85c-dgflc\")\n  |\u003e filter(fn: (r) =\u003e r[\"_field\"] == \"value_co2_properties_value\" or r[\"_field\"] == \"value_humidity_properties_value\" or r[\"_field\"] == \"value_temperature_properties_value\")\n\n```\n`filter(fn: (r) =\u003e r[\"host\"] == \"telegraf-57cfdcb85c-dgflc\")`\u003c/br\u003e\n\n`telegraf-57cfdcb85c-dgflc` is the name of telegraf pod. I had to change this wehenever restarting the minikube cluster because I got different telegraf pod names after restarting the minikube cluster using `minikube stop -p \u003cname-of-the-profile\u003e` and `minikube start -p \u003cname-of-the-profile\u003e` and the pod name also includes with the time series data.\n\n___`This issue was fixed by setting the number of replicas in telegraf deployment to 1`___\n\n### The final dashboard should look like this\n![Dashboard](./embedded-images/dashboard.png)\n\n#### Congratulations you're all set.\n\n## References\n1. https://github.com/ertis-research/opentwins/blob/main/docs/docs/quickstart.mdx\n2. https://github.com/ertis-research/opentwins/blob/main/docs/docs/installation/manual-deploy/core.md\n3. https://github.com/ertis-research/opentwins/tree/main/files_for_manual_deploy\n\n# 2. Deployment in Detail\n### #To Do\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feshanjayasundara%2Fopentwindocumentation","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feshanjayasundara%2Fopentwindocumentation","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feshanjayasundara%2Fopentwindocumentation/lists"}