{"id":44332393,"url":"https://github.com/bringauto/virtual-fleet-management","last_synced_at":"2026-02-11T10:09:57.328Z","repository":{"id":243815907,"uuid":"805339371","full_name":"bringauto/virtual-fleet-management","owner":"bringauto","description":"Virtual Fleet Management for testing purposes","archived":false,"fork":false,"pushed_at":"2025-05-16T07:13:30.000Z","size":151,"stargazers_count":0,"open_issues_count":1,"forks_count":0,"subscribers_count":2,"default_branch":"main","last_synced_at":"2025-05-16T07:38:35.961Z","etag":null,"topics":[],"latest_commit_sha":null,"homepage":null,"language":"Go","has_issues":true,"has_wiki":null,"has_pages":null,"mirror_url":null,"source_name":null,"license":"gpl-3.0","status":null,"scm":"git","pull_requests_enabled":true,"icon_url":"https://github.com/bringauto.png","metadata":{"files":{"readme":"README.md","changelog":null,"contributing":null,"funding":null,"license":"LICENSE","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":"2024-05-24T11:19:27.000Z","updated_at":"2024-07-13T13:40:35.000Z","dependencies_parsed_at":"2026-02-11T10:03:46.374Z","dependency_job_id":null,"html_url":"https://github.com/bringauto/virtual-fleet-management","commit_stats":null,"previous_names":["bringauto/virtual-fleet-management"],"tags_count":5,"template":false,"template_full_name":null,"purl":"pkg:github/bringauto/virtual-fleet-management","repository_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fvirtual-fleet-management","tags_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fvirtual-fleet-management/tags","releases_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fvirtual-fleet-management/releases","manifests_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fvirtual-fleet-management/manifests","owner_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/owners/bringauto","download_url":"https://codeload.github.com/bringauto/virtual-fleet-management/tar.gz/refs/heads/main","sbom_url":"https://repos.ecosyste.ms/api/v1/hosts/GitHub/repositories/bringauto%2Fvirtual-fleet-management/sbom","scorecard":null,"host":{"name":"GitHub","url":"https://github.com","kind":"github","repositories_count":286080680,"owners_count":29331747,"icon_url":"https://github.com/github.png","version":null,"created_at":"2022-05-30T11:31:42.601Z","updated_at":"2026-02-11T06:13:03.264Z","status":"ssl_error","status_checked_at":"2026-02-11T06:12:55.843Z","response_time":97,"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":[],"created_at":"2026-02-11T10:09:56.563Z","updated_at":"2026-02-11T10:09:57.316Z","avatar_url":"https://github.com/bringauto.png","language":"Go","funding_links":[],"categories":[],"sub_categories":[],"readme":"# Virtual Fleet Management\n\nThis project simulates creating orders for cars. This can be used for integration testing of the Fleet Protocol stack.\n\n## Behavior\n\nThe application reads all scenarios from the directory specified in the configuration.\nEach scenario is a JSON file that describes a sequence of missions for a car.\nThe application creates a simulation for each scenario.\n\nThe application creates an HTTP client. It checks if the fleet management HTTP API is available.\nIf it's not, it tries again after some time. The sleep time and number of retries are constants in the code. The sleep\ntime is increasing with each retry.\n\nThen it creates routes and stops from the scenario files. If they already exist and are the same, this step is skipped.\nIf they exist with different data (e.g. different coordinates), the application logs an error and stops.\n\nThe application then starts to monitor the cars.\nIt periodically retrieves the list of cars from the fleet management HTTP API and checks if each car is communicating.\nIf a car is communicating and there is an available scenario that is not active, the application starts a simulation for\nthat car in a new goroutine.\n\nEach simulation first orders the car to the starting station of the scenario, so the simulations are deterministic.\nThen, it runs the missions in its scenario in sequence.\nIf the loop configuration value is set to `true` the simulation repeats the missions infinitely.\nOtherwise, it runs the missions once and then stops once they are all done.\n\n## Requirements\n\n- [golang](https://golang.org/)\n- [protobuff compiler v3.17.3](https://github.com/protocolbuffers/protobuf/releases/tag/v3.17.3)\n\n## Arguments\n\n- --broker-ip=\\\u003cipv4\u003e - IP address of the MQTT broker\n- --broker-port=\\\u003cport\u003e - port of the MQTT broker\n\n## Tests\n\n## Scenarios\n\nFiles are distributed into folders depending on the company and car name they will be used for.\n\nFor example scenario for company `BringAuto` with car name `CAR1` will be stored in `/bringauto/car1/scenario.json`.\nEach car folder can contain multiple scenario files, but right now one scenario per car is supported, the first correct\nfile\nwill be run and the other files will be ignored\n\nAll scenarios from the company directory will be played in parallel. The application gets the company folder from a\nconfig.\n\nExample scenarios are stored in [virtual-fleet scenarios folder](resources/scenarios/) in JSON format.\n\n### Directory structure\n\n```\nscenarios/\n├── companyA/    \u003c-- company folder, passed to the app in config\n│   ├── car1/\n│   │   └── scenario.json\n│   └── car2/\n│   │   └── scenario.json\n└── companyB/\n    ├── car1/\n    │   └── scenario.json\n    └── car2/\n        └── scenario.json\n```\n\n### JSON format\n\nJSON files contain the information about the map file that is used for missions (name or path to it), starting station\nand list of missions.\n\nThe starting station defines in which station the simulation will start.\nOrder with starting_station is sent to the car as an initial mission. Once this initial mission is completed, the first\nmission is started.\n\nEach mission contains a delay, the mission's name, and a list of stops.\nDelay sets the time, after which the mission is started. This time is counted since the previous mission started.\nExample with comments:\n\n```\n{\n    \"map\": \"London.osm\",  -- name of the map of the vehicle, has no effect on the simulation, only informative\n    \"starting_station\": \"London National Theatre\",  -- first order for the car, missions are started when the car is in this station\n    \"missions\": [         -- mission list\n        {\n            \"delay_seconds\": 0,   -- delay after the previous mission is started\n            \"name\": \"mission1\",\n            \"stops\": [    -- stop list\n                {\n                    \"name\": \"London National Theatre\"\n                },\n                {\n                    \"name\": \"Cross Station\"\n                }\n            ],\n            \"route\": \"Short\"  -- route containing the stops\n        },\n        {\n            \"delay_seconds\": 150, -- delay after the previous mission is started. This mission will start 150 seconds after 'mission1'\n            \"name\": \"mission2\",\n            \"stops\": [\n                {\n                    \"name\": \"Oasis Academy\"\n                },\n                {\n                    \"name\": \"London Waterloo\"\n                }\n            ],\n            \"route\": \"Long\"\n        }\n    ],\n    \"routes\": [\n        {\n            \"name\": \"Short\",\n            \"stations\": [\n                {\n                    \"name\": \"London National Theatre\",\n                    \"position\": {\n                        \"latitude\": 51.50719991926,\n                        \"longitude\": -0.11572123647,\n                        \"altitude\": 0\n                    }\n                },\n                {\n                    \"name\": \"Cross Station\",\n                    \"position\": {\n                        \"latitude\": 51.50847034843,\n                        \"longitude\": -0.12557298213,\n                        \"altitude\": 0\n                    }\n                },\n            ]\n        },\n        {\n            \"name\": \"Long\",\n            \"stations\": [\n                {\n                    \"name\": \"London Waterloo\",\n                    \"position\": {\n                        \"latitude\": 51.50423320901,\n                        \"longitude\": -0.11283786178,\n                        \"altitude\": 0\n                    }\n                },\n                {\n                    \"name\": \"London National Theatre\",\n                    \"position\": {\n                        \"latitude\": 51.50719991926,\n                        \"longitude\": -0.11572123647,\n                        \"altitude\": 0\n                    }\n                },\n                {\n                    \"name\": \"Oasis Academy\",\n                    \"position\": {\n                        \"latitude\": 51.50031457906,\n                        \"longitude\": -0.11135928467,\n                        \"altitude\": 0\n                    }\n                }\n            ]\n        }\n    ]\n}\n```\n\nThis scenario will create the order [\"London National Theatre\"], then play the\nmission [\"London National Theatre\", \"Cross Station\" ] from map London.osm from timestamp 0 to 150 (calculated from\nreaching the starting station of the given scenario)\nand after that time interval, it will switch to the second mission  [ \"Oasis Academy\", \"London Waterloo\" ]\n\n## Build and run the project locally\n\nRun the build script from the project folder:\n\n```\nbash build.sh\n```\n\nRun the app:\n\n```\n./virtual-fleet-management -config \u003cconfig.json\u003e\n```\n\n### Config values\n\n* **host** - address of the server where the virtual fleet will be running\n* **api-key** - API key for the Fleet Management HTTP API\n* **company** - Company name that will be used as tenant in request authorization\n* **scenario-dir** - path to the directory with scenarios. `\u003cscenario_dir\u003e/\u003ccar_name\u003e/scenario.json`\n    * common approach is to name the scenario directory as company\n    * inside the `scenario-dir`, there can be directories for multiple cars, all of them can be played at same time.\n* **log-path** - path to the log directory\n* **loop** - optional argument, if set to `true` the scenarios will be looped infinitely. If `false` each scenario will\n  be played only once.\n\n\u003e Arguments `api-key` and `scenario-dir` can be overridden by the command line arguments.\n\n## Build and run docker image\n\nBuild the image using:\n\n```\ndocker build --tag bringauto/virtual-fleet-management .\n```\n\nRun the image using:\n\n```\ndocker run -ti --rm -v \u003clocal/path/to/config\u003e:\u003cconfig_path\u003e bringauto/virtual-fleet-management -config=\u003cconfig_path\u003e\n```\n","project_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbringauto%2Fvirtual-fleet-management","html_url":"https://awesome.ecosyste.ms/projects/github.com%2Fbringauto%2Fvirtual-fleet-management","lists_url":"https://awesome.ecosyste.ms/api/v1/projects/github.com%2Fbringauto%2Fvirtual-fleet-management/lists"}