{"id":13341713,"url":"https://github.com/eclipse-thingweb/test-things","last_synced_at":"2026-02-27T22:42:36.446Z","repository":{"id":198706914,"uuid":"670047185","full_name":"eclipse-thingweb/test-things","owner":"eclipse-thingweb","description":"Collection of Things that can be used for testing different IoT protocols, security mechanisms and interaction styles","archived":false,"fork":false,"pushed_at":"2025-09-01T21:28:12.000Z","size":1382,"stargazers_count":7,"open_issues_count":16,"forks_count":7,"subscribers_count":10,"default_branch":"main","last_synced_at":"2025-09-01T23:27:51.258Z","etag":null,"topics":["iot","protocols","testing","web-of-things","wot"],"latest_commit_sha":null,"homepage":"https://thingweb.io","language":"JavaScript","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"other","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/eclipse-thingweb.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE.md","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,"notice":null,"maintainers":null,"copyright":null,"agents":null,"dco":null,"cla":null}},"created_at":"2023-07-24T07:17:13.000Z","updated_at":"2025-09-01T21:28:19.000Z","dependencies_parsed_at":null,"dependency_job_id":"2deff58d-3d3e-4682-8a48-ecfc23b61bc6","html_url":"https://github.com/eclipse-thingweb/test-things","commit_stats":null,"previous_names":["eclipse-thingweb/test-things"],"tags_count":0,"template":false,"template_full_name":null,"purl":"pkg:github/eclipse-thingweb/test-things","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-thingweb%2Ftest-things","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-thingweb%2Ftest-things/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-thingweb%2Ftest-things/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-thingweb%2Ftest-things/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/eclipse-thingweb","download_url":"https://codeload.github.com/eclipse-thingweb/test-things/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/eclipse-thingweb%2Ftest-things/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29917941,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-27T19:37:42.220Z","status":"ssl_error","status_checked_at":"2026-02-27T19:37:41.463Z","response_time":57,"last_error":"SSL_read: 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":["iot","protocols","testing","web-of-things","wot"],"created_at":"2024-07-29T19:25:43.511Z","updated_at":"2026-02-27T22:42:36.441Z","avatar_url":"https://github.com/eclipse-thingweb.png","language":"JavaScript","funding_links":[],"categories":[],"sub_categories":[],"readme":"\u003ch1\u003e\n  \u003cpicture\u003e\n  \u003csource media=\"(prefers-color-scheme: dark)\" srcset=\"https://raw.githubusercontent.com/eclipse-thingweb/thingweb/master/brand/logos/test-things_for_dark_bg.svg\"\u003e\n  \u003csource media=\"(prefers-color-scheme: light)\" srcset=\"https://raw.githubusercontent.com/eclipse-thingweb/thingweb/master/brand/logos/test-things.svg\"\u003e\n  \u003cimg title=\"Eclipse Thingweb Test Things\" alt=\"Thingweb logo with Test Things\" src=\"https://raw.githubusercontent.com/eclipse-thingweb/thingweb/master/brand/logos/test-things.svg\" width=\"300\"\u003e\n\u003c/picture\u003e\n\u003c/h1\u003e\n\n## Test Things\n\nCollection of IoT device simulators that can be used for testing and exploration purposes of different protocols and other Web of Things mechanisms.\nThe devices are implemented via various programming languages and frameworks.\nThe protocols you can currently test are:\n\n-   HTTP\n-   CoAP\n-   MQTT\n-   Modbus\n\n## How It Works\n\n-   External applications —known as WoT Consumer Stacks— send requests to the Things. Traefik, which handles inbound HTTP requests, or an MQTT broker allow them to communicate with the internal services (\"Things\") in two main methods.\n-   The primary application services, the \"Things\" (A, B, C, D) reflect several functionalities like those of a Coffee Machine or Elevator. Every service is specified by a Thing Description (TD), a standardized metadata file that explains the service's capabilities and how to interact with it.\n-   **Monitoring and Observability:** The system is built up comprehensively for monitoring.\n    -   Promtail collects logs from the services and sends them to Loki, a log aggregation system.\n    -   cAdvisor analyzes and collects overall metrics from docker containers\n    -   Prometheus, a time-series database, stores container performance measurements that cAdvisor gathers.\n    -   Grafana, a central dashboard, shows Loki's logs and Prometheus's metrics to give a whole picture of the system's condition.\n\n![Architecture Diagram](./architecture-diagram.jpg)\n\n## Dependencies\n\nThe project has several dependencies. Currently, `JavaScript` and `Python` are used for simulating different devices. Every device has its own dependencies and they should be handled separately. For that reason, `Node.js` is used for JS code, and `poetry` is used for Python code to run the scripts and handle the dependencies.\n\n## Testing\n\nFor testing JavaScript Testing Framework `mocha` is used. Therefore, the tests are written in JavaScript.\nEvery Thing should have its Thing Model and Thing Description validation test.\nThing Model validation test should be put under Thing's main directory and named as `tm.test.json`.\nThe Thing Description validation test should be put under the protocol and programming language/framework's test directory and named `td.test.json`.\nFor the Thing Description validation test, the device should boot up and to understand the device booted up without any error, a message `\"ThingIsReady\"` is expected to be prompted to the console by the device.\n\n## Port Configuration\n\nIt is possible to run several Things at the same time in a container, which requires a container to expose that many ports.\nTraefik helps with this issue and routes the requests on one exposed port to relevant services inside the container.\nTraefik configuration can be seen inside `docker-compose.yml`.\nIt is not possible to route using a path prefix with UDP, therefore port must be exposed for new Things that use UDP.\n\n## Adding a new Thing\n\nIf you are going to add a different protocol for an existing Thing:\n\n1. Create a directory such as `things/\u003cexisting_thing\u003e/\u003cyour_protocol\u003e/\u003cyour_programming_language/your_framework\u003e/`.\n2. Create your project files and write your code inside this directory.\n3. If you are adding a new programming language, please use a tidy dependency management tool for the programming language. Otherwise use already used tools and frameworks not to overcomplicate the project.\n4. Create your `test/` directory under your Thing's directory and add your test files there.\n\nIf you are going to add a different programming language/framework for an existing protocol:\n\n1. Create a directory such as `things/\u003cexisting_thing\u003e/\u003cexisting_protocol\u003e/\u003cyour_programming_language/your_framework\u003e/`.\n2. Create your project files and write your code inside this directory.\n3. Please use a tidy dependency management tool for the programming language/framework. Otherwise use already used tools and frameworks not to overcomplicate the project.\n\nIf you are going to add a completely new Thing:\n\n1. Create a directory such as `things/\u003cyour_thing_name\u003e/`.\n2. Add your Thing Model under the previously created directory and name it such as `\u003cyour_thing_name\u003e.tm.json`.\n3. Follow the steps above to add your protocol and programming language/framework.\n\n**TypeScript Tracing Integration:**\nWrap your WoT Thing with auto-tracing to get detailed OpenTelemetry spans for validation, processing, and database operations:\n\n```typescript\nimport { createAutoTracedThing, TracedBusinessLogic } from \"../../util/dist/auto-tracing\";\nconst tracedThing = createAutoTracedThing(thing);\n\n// Property writes get \".read\" suffix\ntracedThing.setPropertyReadHandler(\"allAvailableResources\", async (options) =\u003e {\n    return getResources(); // Span: \"allAvailableResources.read\"\n});\n\n// Property writes get \".write\" suffix\ntracedThing.setPropertyWriteHandler(\"servedCounter\", async (value) =\u003e {\n    updateCounter(value); // Span: \"servedCounter.write\"\n});\n```\n\n## Current Devices\n\nThe table below contains the public base URIs of the Things used for protocol testing.\nFor HTTP and CoAP Things, the base URL also contains the TD.\nAlso see [Mashup Things](./mashups/smart-home/README.md), which are useful when combined together and are not necessarily developed for protocol testing.\n\n| Thing Title                                 | Base URI                                                                  |\n| ------------------------------------------- | ------------------------------------------------------------------------- |\n| http-advanced-coffee-machine                | `http://plugfest.thingweb.io/http-advanced-coffee-machine`                |\n| coap-calculator-simple                      |                                                                           |\n| coap-calculator-content-negotiation         |                                                                           |\n| http-express-calculator-simple              | `http://plugfest.thingweb.io/http-express-calculator-simple`              |\n| http-express-calculator-content-negotiation | `http://plugfest.thingweb.io/http-express-calculator-content-negotiation` |\n| http-flask-calculator                       | `http://plugfest.thingweb.io/http-flask-calculator`                       |\n| mqtt-calculator                             |                                                                           |\n| modbus-elevator                             |                                                                           |\n| http-data-schema-thing                      | `http://plugfest.thingweb.io/http-data-schema-thing`                      |\n\n### Advanced Coffee Machine\n\nThe advanced coffee machine is a device that simulates a behavior of a coffee machine. `allAvailableResources` property consists of the remaining values for its properties `water`, `milk`, `chocolate` and `coffeeBeans`. `possibleDrinks` property holds a list of possible drinks, a user can order, such as espresso, americano, etc. After certain amount of uses of the coffee machine, `maintenanceNeeded` property becomes true and let users know the coffee machine requires a maintenance. `schedules` property stores the users' schedules to brew a coffee at the scheduled time.\n\n### Calculator\n\nThe calculator is a simple device, that has a read-only `result` variable, and depending on the action selected by the user, it adds or subtracts user input from the `result`. There is also a read-only `lastChange` variable, which indicates the last time `result` variable has changed. Additionally, the device publishes an event, when `result` is changed.\n\n### Elevator\n\nThe elevator is a simple device, that has three variables `lightSwitch`, `floorNumber`, and `onTheMove`. `lightSwitch` is a boolean that represents whether the light on the elevator is turned on or not. `floorNumber` is an integer and represents the floor number of the elevator. `onTheMove` is a boolean and represents whether the elevator is on the move or not.\n\n### Test Thing\n\nThe Test Thing is a total toy device that users can try different types of properties and actions.\n\n#### Supported Protocols and Programming Languages\n\n-   HTTP\n    -   TypeScript node-wot\n    -   JavaScript Express framework\n    -   Python Flask framework\n-   CoAP\n    -   JavaScript\n-   MQTT\n    -   JavaScript\n-   Modbus\n    -   JavaScript\n\n## Current Mashups\n\n### Smart Home Mashup\n\nSee the mashup's [readme](./mashups/smart-home/README.md).\n\n## How to Run\n\nYou can either start all the devices at [the same time](#using-docker-compose) or start them [individually](#running-separately).\n\n### Using docker-compose\n\n1. Clone the [infrastructure](https://github.com/eclipse-thingweb/infrastructure) repository\n2. Start the infrastructure services via `docker-compose up -f docker-compose-services.yml`\n3. Start the Things via `docker-compose up -f docker-compose-things.yml`\n\n**Local Development Option:**\n\nIf you want to build and run the Things from your local source code (for development or debugging), you can use the `docker-compose-things-local.yml` file instead. This will build the images from your local codebase.\n\n1. Make sure you have Docker and Docker Compose installed.\n2. From the project root, run:\n    ```sh\n    docker-compose -f docker-compose-things-local.yml build\n    docker-compose -f docker-compose-things-local.yml up\n    ```\n3. The Things will be accessible at the same local URLs as below (e.g., `http://localhost/http-advanced-coffee-machine`).\n\nThis is useful for local development, debugging, or when you want to test changes before pushing to a remote repository.\n\nAfter the run, as default, the devices are accessible at:\n\n| Thing Title                                 | Local Access URL                                               |\n| ------------------------------------------- | -------------------------------------------------------------- |\n| http-advanced-coffee-machine                | `http://localhost/http-advanced-coffee-machine`                |\n| coap-calculator-simple                      | `coap://localhost:5683/coap-calculator-simple`                 |\n| coap-calculator-content-negotiation         | `coap://localhost:5684/coap-calculator-content-negotiation`    |\n| http-express-calculator-simple              | `http://localhost/http-express-calculator-simple`              |\n| http-express-calculator-content-negotiation | `http://localhost/http-express-calculator-content-negotiation` |\n| http-flask-calculator                       | `http://localhost/http-flask-calculator`                       |\n| mqtt-calculator                             | `mqtt://test.mosquitto.org:1883/mqtt-calculator`               |\n| modbus-elevator                             | `modbus+tcp://localhost:3179/1`                                |\n| http-data-schema-thing                      | `http://localhost/http-data-schema-thing`                      |\n\nFor custom configuration, take a look at the `Dockerfile` of each device or `docker-compose-things.yml`.\n\nDocker-compose (non-local) file uses the images from Docker Hub. If you make any changes in the code build and push the new image with the changes. The command below allows you to create the Docker image for two different platforms you can use (Need permission to be able to push them to the thingweb organization):\n\n```\ndocker buildx build \\\n--push \\\n--platform linux/amd64, linux/arm64 \\\n--tag thingweb/\u003cIMAGE_NAME\u003e \\\n--filename \u003cDOCKERFILE_NAME\u003e \\\n\u003cBUILD_CONTEXT\u003e\n```\n\n### Running separately\n\nFor running the things separately, using their `Dockerfile`'s, `docker build -t \u003cimage-tag\u003e -f ./Dockerfile ../../` command must be used to give the context to be able to copy `tm.json` into the container.\n\nFor Node.js-based devices, we use npm workspaces and running `npm install` at the root directory installs all the packages needed for every device. After packages are installed, running `node main.js` would run the thing. For port configuration, running either `node main.js -p 1000` or `node main.js --port 1000` would start the thing on port 1000.\n\n## Tracing\n\nDistributed tracing is enabled using OpenTelemetry and Jaeger. To view all traces and logs, open [http://localhost:8084](http://localhost:8084) in your browser (Jaeger UI). Traces are sent to the Jaeger collector on port 8085.\n\nEnhanced auto-tracing automatically injects `TracedBusinessLogic` for detailed span creation without redundancy. Function signatures determine tracing mode.\n\nAlso, there is comprehensive test suites that are also traced and visible in Jaeger:\n\n-   **Thing Description (TD) validation tests** - Test if the exposed TD is valid according to W3C WoT standards\n-   **Thing Model (TM) validation tests** - Validate the Thing Model against the schema\n-   **Integration tests** - Test actual interactions with the Things\n\nWhen tests run, they appear in Jaeger with clear span names like `td.test` or `tm.test`. Failed tests show up as **error spans** with red highlighting in the Jaeger UI, making it easy to:\n\n-   **Debug test failures** by examining the error details and stack traces in span logs\n-   **Track test performance** and identify slow validation steps\n-   **Monitor CI/CD pipelines** by observing test execution patterns\n-   **Correlate test failures** with specific Thing operations or configurations\n\nTest spans include detailed attributes about what was validated, error messages for failures, and timing information for performance analysis.\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feclipse-thingweb%2Ftest-things","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Feclipse-thingweb%2Ftest-things","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Feclipse-thingweb%2Ftest-things/lists"}