diff --git a/docs/10-introduction.md b/docs/10-introduction.md index 0d150c35..58b2959d 100644 --- a/docs/10-introduction.md +++ b/docs/10-introduction.md @@ -6,7 +6,7 @@  -The core of the OpenRemote system is the [Manager](https://github.com/openremote/core/tree/main/manager), a headless Java application that forms an IoT context broker which captures the current asset state of the system. You can create a dynamic schema of your assets and their attributes in the manager, modelling the problem domain. For example, you would create Building, Vehicle, Battery, Streetlight, and Sensor assets to model an IoT system for a smart city, an energy management system, or fleet telematics. +The core of the OpenRemote system is the [Manager](https://github.com/openremote/core/tree/main/manager), a headless Java application that forms an IoT context broker which captures the current asset state of the system. You can create a dynamic schema of your assets and their attributes in the manager, modeling the problem domain. For example, you would create Building, Vehicle, Battery, Streetlight, and Sensor assets to model an IoT system for a smart city, an energy management system, or fleet telematics. Rules can be written in Groovy, a Rules JSON, or Flow model, and dynamically deployed. Rules execute actions when matching asset state or sequence of events are detected. For example, when a mobile asset enters a geographic fence, or when your sensor is not updating anymore, you can notify a group of users via email and on their mobile devices. @@ -26,7 +26,7 @@ The OpenRemote [Frontend](./developer-guide/110-working-on-ui-and-apps.md) simpl * Home automation control panel * Smart city monitoring dashboard -We support the latest HTML standards and provide [web components](https://github.com/openremote/core/tree/main/ui/component) to build applications quickly, utilising the OpenRemote asset model and APIs: you can easily show all your assets on a map, for example. [Full web applications](https://github.com/openremote/core/tree/main/ui/app) are also bundled with OpenRemote, these can be used as templates for building custom web applications. +We support the latest HTML standards and provide [web components](https://github.com/openremote/core/tree/main/ui/component) to build applications quickly, utilizing the OpenRemote asset model and APIs: you can easily show all your assets on a map, for example. [Full web applications](https://github.com/openremote/core/tree/main/ui/app) are also bundled with OpenRemote, these can be used as templates for building custom web applications. The OpenRemote [Android](https://github.com/openremote/console-android) and [iOS](https://github.com/openremote/console-ios) Consoles are native mobile applications that act as a shell for web applications built with the OpenRemote web components; a web browser is also considered to be a console and we automatically integrate native console features like push notifications and geofencing on each platform. If you have an existing website, add OpenRemote web components and wrap it in the OpenRemote console to connect your mobile users to your IoT network. diff --git a/docs/20-quick-start.md b/docs/20-quick-start.md index fce798b9..3c9f850e 100644 --- a/docs/20-quick-start.md +++ b/docs/20-quick-start.md @@ -1,6 +1,6 @@ # Quick Start -Welcome to OpenRemote; an intuitive user-friendly 100% open source IoT platform. You can build a complete IoT device management solution including: device management and auto provisioning, customisation of asset types, automation via When-Then, Flow and Groovy rules, data analytics, connectivity via several protocol agents and manager APIs (e.g. MQTT broker, HTTP/REST, WS), Multi-tenancy (realms), Users and roles management, Edge gateway, Front-end UI web components and consoles, and an Insights dashboard builder. +Welcome to OpenRemote; an intuitive user-friendly 100% open source IoT platform. You can build a complete IoT device management solution including: device management and auto provisioning, customization of asset types, automation via When-Then, Flow and Groovy rules, data analytics, connectivity via several protocol agents and manager APIs (e.g. MQTT broker, HTTP/REST, WS), Multi-tenancy (realms), Users and roles management, Edge gateway, Front-end UI web components and consoles, and an Insights dashboard builder. As the code base is 100% open source, applications are limitless. Here's an architecture overview: diff --git a/docs/architecture/20-manager-endpoints-and-file-paths.md b/docs/architecture/20-manager-endpoints-and-file-paths.md index 9b777ac8..1868604c 100644 --- a/docs/architecture/20-manager-endpoints-and-file-paths.md +++ b/docs/architecture/20-manager-endpoints-and-file-paths.md @@ -13,7 +13,7 @@ The OpenRemote Manager exposes the following endpoints: * `/auth` - Keycloak reverse proxy endpoint * `/websocket` - WebSocket endpoint * `/*` - Any other path is resolved against `$CUSTOM_APP_DOCROOT` (see paths below) -* `/manager_config.json` - File that is loaded by the Manager UI to apply custom configuration to the Manager UI (white labelling, menu config, etc.) (loaded from `$CUSTOM_APP_DOCROOT`) (see [here](../user-guide/010-deploying/20-configuring-the-manager-ui.md) for more details) +* `/manager_config.json` - File that is loaded by the Manager UI to apply custom configuration to the Manager UI (white labeling, menu config, etc.) (loaded from `$CUSTOM_APP_DOCROOT`) (see [here](../user-guide/010-deploying/20-configuring-the-manager-ui.md) for more details) * `/locales` - Path used by Manager UI to find custom `i18n` locale files, each locale should be in it's own directory with a file named `app.json` (e.g. `/locales/en/app.json`) (loaded from `$CUSTOM_APP_DOCROOT`) ### App Realm @@ -23,7 +23,7 @@ e.g. `/manager/?realm=smartcity` ## File paths -The following list shows the file paths used by our Docker containers; these can be customised by changing environment variable values (where a file path is controlled by an environment variable) and/or by using volume mapping, this is how we provide customised instances of our system for specific projects. The default values shown below are the defaults as used by our Docker containers. +The following list shows the file paths used by our Docker containers; these can be customized by changing environment variable values (where a file path is controlled by an environment variable) and/or by using volume mapping, this is how we provide customized instances of our system for specific projects. The default values shown below are the defaults as used by our Docker containers. ### Manager diff --git a/docs/architecture/40-asset-validation.md b/docs/architecture/40-asset-validation.md index 7fa43141..69ffc9ef 100644 --- a/docs/architecture/40-asset-validation.md +++ b/docs/architecture/40-asset-validation.md @@ -1,6 +1,6 @@ # Asset Validation -This document summarises how asset validation is performed and how it relates to the asset type model. +This document summarizes how asset validation is performed and how it relates to the asset type model. ## AssetTypeInfo Model Structure diff --git a/docs/architecture/50-asset-location-tracking.md b/docs/architecture/50-asset-location-tracking.md index de9c9f13..086e0bd2 100644 --- a/docs/architecture/50-asset-location-tracking.md +++ b/docs/architecture/50-asset-location-tracking.md @@ -51,10 +51,10 @@ How geofences are 'pushed' to assets is handled by GeofenceAdapters that are loa ### Unsupported assets/rules If there are rules with location predicates but they cannot be implemented using geofence APIs on the asset and/or the asset doesn't support geofence APIs then the location attribute is expected to be updated using some other mechanism (asset pushes location, protocol polling, manual, etc.) -### Geofence trigger behaviour +### Geofence trigger behavior When a geofence is triggered on an asset then the asset should update its own location by posting to the public endpoint `asset/public/{assetId}/updateLocation`, the location value sent should be as follows: -* Geofence Enter - Send geofence centre point as location (centre point should have been provided in the geofence definition retrieved from the backend) +* Geofence Enter - Send geofence center point as location (center point should have been provided in the geofence definition retrieved from the backend) * Geofence Exit - Send null (this will clear the devices location and indicate that the asset has left the geofence) **By using geofence triggers in this way the handling of all location tracked assets can be processed in the same way i.e. the manager rules can compare location asset state changes irrespective of how the asset provides the location data.** diff --git a/docs/architecture/60-apps-and-consoles.md b/docs/architecture/60-apps-and-consoles.md index 1678c2df..e57ec360 100644 --- a/docs/architecture/60-apps-and-consoles.md +++ b/docs/architecture/60-apps-and-consoles.md @@ -22,12 +22,12 @@ openremote.init(...).then(()=> { Apps should be built and deployed within the OR manager web server using the standard tooling e.g. `gradle clean installDist` (refer to the developer guide). Console build and deployment will depend on the specific tools and platform used but where possible the standard tooling and deployment process should be used. -## Runtime behaviour +## Runtime behavior 1. Console is 'launched' (e.g. typing URL in browser or opening the app) 1. Console then displays a splash screen indicating that the client is loading 1. App is loaded and the URL should include query parameters to instruct the `@openremote/core` component what functionality they wish to provide to the client (see the Console/app API below) -1. The app will initialise the console and the console must reply to the app as required by the API (see the Console/app API below) -1. If the app has set `consoleAutoEnable: false` when initialising the `@openremote/core` component then the console must listen for the `OREvent.CONSOLE_INIT` event and then it can enable each `provider` that it is providing to the app; once all `providers` are enabled (excluding those that have been explicitly `disabled` by the user or some other mechanism) then the `OREvent.CONSOLE_READY` event is raised +1. The app will initialize the console and the console must reply to the app as required by the API (see the Console/app API below) +1. If the app has set `consoleAutoEnable: false` when initializing the `@openremote/core` component then the console must listen for the `OREvent.CONSOLE_INIT` event and then it can enable each `provider` that it is providing to the app; once all `providers` are enabled (excluding those that have been explicitly `disabled` by the user or some other mechanism) then the `OREvent.CONSOLE_READY` event is raised Once the console is ready it is automatically registered with the manager backend by sending a `ConsoleRegistration` object, for example: ```json @@ -73,15 +73,15 @@ Console loads app with the following query parameters in the URL to override des * consoleProviders [string] - Space delimited list of providers that this console supports (see below for currently supported/standard providers) * consoleAutoEnable [boolean] - Whether `@openremote/core` should try and auto enable each provider (note that auto enabling cannot send any custom data to each provider during enabling and it also cannot do any processing on the responses received), for this reason it only really works on providers that don't require data during enabling. -#### Initialise -For each provider the `@openremote/core` component sends a message asking the console to initialise the provider: +#### Initialize +For each provider the `@openremote/core` component sends a message asking the console to initialize the provider: ```json { action: "PROVIDER_INIT", provider: "PROVIDER_NAME" } ``` -The console then does any required initialisation and sends a message back to the app: +The console then does any required initialization and sends a message back to the app: ```json { action: "PROVIDER_INIT", @@ -94,10 +94,10 @@ The console then does any required initialisation and sends a message back to th success: true|false [true=init success; false=init failure] } ``` -If a provider initialisation call returns `success: false` then it is automatically marked as `disabled`, once all `providers` are initialised the `OREvent.CONSOLE_INIT` event is raised. The app can retrieve the `console` instance as described above and it can check the status of each `provider` and take appropriate action if desired. +If a provider initialization call returns `success: false` then it is automatically marked as `disabled`, once all `providers` are initialized the `OREvent.CONSOLE_INIT` event is raised. The app can retrieve the `console` instance as described above and it can check the status of each `provider` and take appropriate action if desired. #### Enable -Once all providers are initialised then the app is free to decide when to enable each provider (if `consoleAutoEnable: false` otherwise they will be auto enabled); where a provider returned `requiresPermission=true && hasPermission=false` then the client is best placed to decide when and how to ask for permissions and should use good UX principles to avoid users denying such permission requests (see [permission-ux](https://developers.google.com/web/fundamentals/push-notifications/permission-ux)). Providers that don't require permissions or already have permissions could be enabled immediately. The enable message structure is: +Once all providers are initialized then the app is free to decide when to enable each provider (if `consoleAutoEnable: false` otherwise they will be auto enabled); where a provider returned `requiresPermission=true && hasPermission=false` then the client is best placed to decide when and how to ask for permissions and should use good UX principles to avoid users denying such permission requests (see [permission-ux](https://developers.google.com/web/fundamentals/push-notifications/permission-ux)). Providers that don't require permissions or already have permissions could be enabled immediately. The enable message structure is: ```json { action: "PROVIDER_ENABLE", @@ -196,7 +196,7 @@ Called for both types when a push notification is received: ``` ### Geofence Provider (provider: "geofence") -Use platform geofence APIs (Android and iOS); the provider expects a public endpoint on the OR manager at `rules/geofences/{consoleId}` which it can call to get the geofences for this console. The geofence definitions returned by this endpoint and the behaviour of this provider should match the definitions in the asset location tracking documentation. +Use platform geofence APIs (Android and iOS); the provider expects a public endpoint on the OR manager at `rules/geofences/{consoleId}` which it can call to get the geofences for this console. The geofence definitions returned by this endpoint and the behavior of this provider should match the definitions in the asset location tracking documentation. #### Enabled message request data (App-> Console) ``` diff --git a/docs/developer-guide/020-setting-up-an-ide.md b/docs/developer-guide/020-setting-up-an-ide.md index 9be5fe27..1c9c1543 100644 --- a/docs/developer-guide/020-setting-up-an-ide.md +++ b/docs/developer-guide/020-setting-up-an-ide.md @@ -41,7 +41,7 @@ For formatter plugins and IDE settings, see [Code formatting with Spotless](./02 ##### Grep Console Styling -The log messages of the running application can be colour-highlighted with the [GrepConsole plugin](https://plugins.jetbrains.com/plugin/7125-grep-console) and our [configuration](https://github.com/openremote/core/tree/main/tools/intellij). +The log messages of the running application can be color-highlighted with the [GrepConsole plugin](https://plugins.jetbrains.com/plugin/7125-grep-console) and our [configuration](https://github.com/openremote/core/tree/main/tools/intellij). - Locate XML style config for Grep Console in openremote/tools/intellij - Choice the default or dark styling config @@ -114,7 +114,7 @@ If you are using the custom project repository as starting point the run configu - Module/Classpath: `custom-project.setup.main` for custom projects - Working directory: *Must be set to OpenRemote main project directory!* - Main class: `org.openremote.manager.Main` -- Any environment variables that customise deployment (usually custom projects have some) +- Any environment variables that customize deployment (usually custom projects have some) ### Accessing the Manager UI diff --git a/docs/developer-guide/025-code-formatting.md b/docs/developer-guide/025-code-formatting.md index 1ce1686f..6787b527 100644 --- a/docs/developer-guide/025-code-formatting.md +++ b/docs/developer-guide/025-code-formatting.md @@ -623,7 +623,7 @@ Projects that still use the previous `ci_cd.yml` workflow commonly reference it uses: openremote/core/.github/workflows/ci_cd.yml@main ``` -Because this follows `main`, new workflow behaviour is inherited automatically. This includes the Spotless formatting checks, which `ci_cd.yml` runs from release 1.29.0 onwards. +Because this follows `main`, new workflow behavior is inherited automatically. This includes the Spotless formatting checks, which `ci_cd.yml` runs from release 1.29.0 onwards. #### Temporarily pinning the workflow diff --git a/docs/developer-guide/040-creating-a-custom-project.md b/docs/developer-guide/040-creating-a-custom-project.md index 5cbcd166..28cd998c 100644 --- a/docs/developer-guide/040-creating-a-custom-project.md +++ b/docs/developer-guide/040-creating-a-custom-project.md @@ -23,7 +23,7 @@ The guide consists of the following sections and you will need to have a working ## Project Structure -It is recommended to put custom project code in directory/module called `deployment` this can then be built as a Docker image and used as a Docker volume to map into our `manager` and `keycloak` containers to override/enhance their behaviour; if there is a large amount of code then multiple directories/modules might be desired to logically separate the code, in this case it is advised to follow the same naming convention as the main OpenRemote repo and to ensure the `gradle` build `installDist` task is configured in order to copy the compiled code into the `deployment` `build` directory in preparation for building the `deployment` Docker image. +It is recommended to put custom project code in directory/module called `deployment` this can then be built as a Docker image and used as a Docker volume to map into our `manager` and `keycloak` containers to override/enhance their behavior; if there is a large amount of code then multiple directories/modules might be desired to logically separate the code, in this case it is advised to follow the same naming convention as the main OpenRemote repo and to ensure the `gradle` build `installDist` task is configured in order to copy the compiled code into the `deployment` `build` directory in preparation for building the `deployment` Docker image. ## OpenRemote Dependencies @@ -52,7 +52,7 @@ The [custom-project](https://github.com/openremote/custom-project) repo acts as ### Deployment directory/module -This module is used to generate a `deployment` Docker image which can be volume mapped into the manager and/or Keycloak containers to customize their behaviour. The `installDist` Gradle task of this module will generate output in the `/deployment/build` directory in particular: +This module is used to generate a `deployment` Docker image which can be volume mapped into the manager and/or Keycloak containers to customize their behavior. The `installDist` Gradle task of this module will generate output in the `/deployment/build` directory in particular: * `/deployment/build/image` - Content to be added to the deployment Docker image at `/deployment` * `/deployment/build/Dockerfile` - Docker build file used to build `deployment` Docker image (copied from `/deployment` during `installDist`) diff --git a/docs/developer-guide/100-system-administration.md b/docs/developer-guide/100-system-administration.md index 59b0fa4a..6df0e270 100644 --- a/docs/developer-guide/100-system-administration.md +++ b/docs/developer-guide/100-system-administration.md @@ -125,7 +125,7 @@ You can then explore the thread dump with an IDE or other tool. ## Database -This document summarises the database performance, storage footprint, and system efficiency of the OpenRemote instance before and after enabling **TimescaleDB Hypercore** compression features. It serves as a reference for System Administrators to understand the expected baselines, trade-offs, and critical maintenance thresholds. +This document summarizes the database performance, storage footprint, and system efficiency of the OpenRemote instance before and after enabling **TimescaleDB Hypercore** compression features. It serves as a reference for System Administrators to understand the expected baselines, trade-offs, and critical maintenance thresholds. --- @@ -170,7 +170,7 @@ Prior to compression, the database footprint vastly exceeded the allocated Docke --- ### Query performance benchmarks -Query execution times were fundamentally transformed. Heavy historical aggregations that previously choked the database are now highly optimised, with a minor architectural trade-off for ultra-fast, single-point queries. +Query execution times were fundamentally transformed. Heavy historical aggregations that previously choked the database are now highly optimized, with a minor architectural trade-off for ultra-fast, single-point queries. | Query Type | Example | Before (ms) | After (ms) | Change | | :--- | :--- | :--- | :--- | :--- | @@ -245,7 +245,7 @@ services: * **The 25% Rule:** The largest uncompressed chunk should never exceed 25% of the total Docker container RAM limit. * For a 2GB container limit, the `pg_datapoint_largest_uncompressed_chunk` metric must stay below **512 MB**. * If chunks grow too large, the background compression worker will exhaust RAM during the sorting phase and trigger the Linux OOM killer. If this occurs, reduce the hypertable's `chunk_time_interval` via `set_chunk_time_interval()`. -* The asset table is constantly being updated (whenever an attribute event is written to the attributes JSONB column) this can cause excessive autovacuum executions and can be a significant bottleneck for large asset tables due to the way row updates are handled by PostgreSQL; HOT updates is an optimisation PostgreSQL uses to minimise this overhead and the asset table `fillfactor` can be tweaked to optimise this (default: 90%) +* The asset table is constantly being updated (whenever an attribute event is written to the attributes JSONB column) this can cause excessive autovacuum executions and can be a significant bottleneck for large asset tables due to the way row updates are handled by PostgreSQL; HOT updates is an optimization PostgreSQL uses to minimize this overhead and the asset table `fillfactor` can be tweaked to optimize this (default: 90%) ### Backup/Restore * Create backup: `docker exec or-postgresql-1 pg_dump -Fc openremote -f /tmp/db.bak` @@ -270,7 +270,7 @@ For more details related to TimescaleDB backup/restore see [here](https://docs.t The `openremote/postgresql` container should handle automatic updates to the latest TimescaleDB version in the image and also auto migration to the major version of PostgreSQL in the image (note: you must incrementally go through each major version of the `openremote/postgresql` images i.e. you cannot go from 14.x to 17.x but must go `14.x` -> `15.x` -> `17.x` \[there is no `16.x` image so this can be skipped\]). -The PostgreSQL auto migration process will move `PGDATA` to a sub directory called `old` and create a `new` directory for the initialisation of the new major version DB, if the upgrade fails then you will need to manually handle the issue and move files back to the `PGDATA` folder like so: +The PostgreSQL auto migration process will move `PGDATA` to a sub directory called `old` and create a `new` directory for the initialization of the new major version DB, if the upgrade fails then you will need to manually handle the issue and move files back to the `PGDATA` folder like so: ```bash docker exec --rm -it -v or_postgresql-data:/var/lib/postgresql/data --entrypoint=bash openremote/postgresql:latest-slim mv -v data/old/* $PGDATA @@ -317,7 +317,7 @@ When executing the automation, AWS will perform several actions under the hood. openremote/postgresql:latest ``` 7. Wait for the DB to be ready. When starting from a large snapshot, this can take a while; check the Docker container logs for the DB-ready message. -8. Extract/Analyse the data as required either by: +8. Extract/Analyze the data as required either by: * Exec'ing into the container `docker exec -it temp_recovery_db psql -U postgres -d openremote` * Modifying the Manager and Keycloak DB settings to connect to the temporary DB on port 5433. diff --git a/docs/developer-guide/110-working-on-ui-and-apps.md b/docs/developer-guide/110-working-on-ui-and-apps.md index 9c602a79..661d50f9 100644 --- a/docs/developer-guide/110-working-on-ui-and-apps.md +++ b/docs/developer-guide/110-working-on-ui-and-apps.md @@ -91,7 +91,7 @@ backend webpack_backend * Start the webpack dev server in the `ui/app/manager`: `npm run serve "--" --env managerUrl=https://demo.openremote.app` ### Components -Components can be developed and tested in isolation (with dependencies on other components and/or public npm modules as required). Some components have no visuals and provide standard OpenRemote functionality e.g. `@openremote/core`, whilst others provide visuals that allow interaction with the Manager backend. +Components can be developed and tested in isolation (with dependencies on other components and/or public npm modules as required). Some components have no visuals and provide standard OpenRemote functionality e.g. `@openremote/core`, while others provide visuals that allow interaction with the Manager backend. ### Maps If you are working on a map component then please refer to the [working on maps](./130-working-on-maps.md). diff --git a/docs/developer-guide/170-ci-cd-pipeline.md b/docs/developer-guide/170-ci-cd-pipeline.md index ff17e72a..df2416af 100644 --- a/docs/developer-guide/170-ci-cd-pipeline.md +++ b/docs/developer-guide/170-ci-cd-pipeline.md @@ -81,7 +81,7 @@ The `!failure() && !cancelled()` condition on the calling job is explained in [S You will often see special conditionals used in the pipeline: -- `if: ${{ !failure() && !cancelled() }}`: Used on most jobs in the environment workflows. By default, a job is skipped when a job it needs was skipped. This condition lets it run anyway, unless a job it needs failed or the workflow run was cancelled. +- `if: ${{ !failure() && !cancelled() }}`: Used on most jobs in the environment workflows. By default, a job is skipped when a job it needs was skipped. This condition lets it run anyway, unless a job it needs failed or the workflow run was canceled. - `if: always()`: Ensures a step or job runs regardless of whether previous steps or jobs failed. This is typically used to ensure test results and coverage reports are uploaded even when tests fail, and for the `UI App Tests Status` job. - `if: failure()`: Runs a step only when a previous step in the job failed, or a job only when a job it needs failed. Use it to clean up environments or post error notifications. @@ -89,7 +89,7 @@ You will often see special conditionals used in the pipeline: To speed up the UI app tests, `ui-app-tests.yml` splits them into shards using a matrix job (`shardIndex` and `shardCount`). Each shard runs a part of the tests in parallel using the Playwright `--shard` option and uploads its own test report. `fail-fast: false` lets the other shards finish when one fails, so you see all failing tests at once. -A matrix job reports a check for each shard, but when the job is skipped it reports a single check without the matrix values. The checks of the individual shards therefore can't be required by branch protection. Instead, the `UI App Tests Status` job runs after the shards with `if: always()` and combines their results: it fails when a shard failed or was cancelled, and succeeds when the shards succeeded or were skipped. Branch protection requires this check instead of the shard checks. +A matrix job reports a check for each shard, but when the job is skipped it reports a single check without the matrix values. The checks of the individual shards therefore can't be required by branch protection. Instead, the `UI App Tests Status` job runs after the shards with `if: always()` and combines their results: it fails when a shard failed or was canceled, and succeeds when the shards succeeded or were skipped. Branch protection requires this check instead of the shard checks. ### Deployments diff --git a/docs/tutorials/010-white-label-multi-tenant-iot-platform.md b/docs/tutorials/010-white-label-multi-tenant-iot-platform.md index ead466c2..2b9d65f1 100644 --- a/docs/tutorials/010-white-label-multi-tenant-iot-platform.md +++ b/docs/tutorials/010-white-label-multi-tenant-iot-platform.md @@ -1,16 +1,16 @@ # White-label your IoT platform with multi-tenant realms -This tutorial shows how to turn OpenRemote into a **white-label, multi-tenant IoT platform**: you will brand the Manager with your own logo and colours, give each customer (or distributor) their own isolated **realm**, and optionally serve it on a custom URL. This is exactly what device manufacturers (OEMs) and system integrators need when they want to resell an IoT solution under their own brand. +This tutorial shows how to turn OpenRemote into a **white-label, multi-tenant IoT platform**: you will brand the Manager with your own logo and colors, give each customer (or distributor) their own isolated **realm**, and optionally serve it on a custom URL. This is exactly what device manufacturers (OEMs) and system integrators need when they want to resell an IoT solution under their own brand. :::tip Why this matters for OEMs and integrators -White-labeling and multi-tenancy are part of the open-source core of OpenRemote - there is no separate "enterprise" edition or paid add-on to unlock branding, custom realms or role-based access. You can ship a fully branded, multi-customer platform without a per-feature licence. +White-labeling and multi-tenancy are part of the open-source core of OpenRemote - there is no separate "enterprise" edition or paid add-on to unlock branding, custom realms or role-based access. You can ship a fully branded, multi-customer platform without a per-feature license. ::: ## Prerequisites - A running OpenRemote instance - see the [Quick Start](../20-quick-start.md). - Superuser (`admin`) access to the **master** realm. -- Your brand assets: a `logo.png`, a `logo-mobile.png`, a `favicon.png`, and your brand colour hex codes. +- Your brand assets: a `logo.png`, a `logo-mobile.png`, a `favicon.png`, and your brand color hex codes. ## Step 1 - Create a realm per customer @@ -30,7 +30,7 @@ You can brand each realm independently from the UI. 1. Switch to the realm you want to brand (realm picker, top-right). 2. Go to **Settings → Appearance**. -3. Upload your **logo**, **mobile logo** and **favicon**, set the **app title** (e.g. `ACME IoT`), and configure the colour variables to match your brand. +3. Upload your **logo**, **mobile logo** and **favicon**, set the **app title** (e.g. `ACME IoT`), and configure the color variables to match your brand. 4. Configure map defaults, navigation items and default language for that realm. 5. Save the configuration @@ -65,7 +65,7 @@ Your customer's realm is now available at its own URL (e.g. `iot.acme.com/manage ## Step 4 - Verify isolation 1. Create a test user in the `acme` realm and log in as that user in a separate browser session. -2. Confirm the branded login page, logo and colours appear. +2. Confirm the branded login page, logo and colors appear. 3. Confirm the user can only see `acme` assets - not those of other realms. ## Next steps diff --git a/docs/tutorials/050-connect-modbus-devices.md b/docs/tutorials/050-connect-modbus-devices.md index b22bfc38..73728c59 100644 --- a/docs/tutorials/050-connect-modbus-devices.md +++ b/docs/tutorials/050-connect-modbus-devices.md @@ -31,7 +31,7 @@ For each attribute, add the **Agent Link** configuration item and select your Mo - the **register type** (coil, discrete input, input register, holding register), - the **address**, - the **data type** (e.g. `INT16`, `UINT32`, `FLOAT32`), -- the **read/write** behaviour and a **polling interval**, +- the **read/write** behavior and a **polling interval**, - the **unit ID** :::note diff --git a/docs/tutorials/060-enterprise-identity-sso-rbac.md b/docs/tutorials/060-enterprise-identity-sso-rbac.md index f3c974fc..3d802435 100644 --- a/docs/tutorials/060-enterprise-identity-sso-rbac.md +++ b/docs/tutorials/060-enterprise-identity-sso-rbac.md @@ -34,7 +34,7 @@ Because identity is managed by Keycloak, you can federate to an external Identit 2. Add an **Identity Provider** (OIDC or SAML) for your IdP and map claims/roles. 3. Users now sign in with corporate credentials; access maps to OpenRemote roles automatically. -To synchronise users/groups from a directory, follow [Linking to Active Directory](../user-guide/070-identity-and-security/30-linking-to-active-directory.md). +To synchronize users/groups from a directory, follow [Linking to Active Directory](../user-guide/070-identity-and-security/30-linking-to-active-directory.md). ## Step 4 - Create OAuth2 service users for devices and integrations diff --git a/docs/tutorials/100-simulating-data-in-attribute.md b/docs/tutorials/100-simulating-data-in-attribute.md index 906173e7..8988f30e 100644 --- a/docs/tutorials/100-simulating-data-in-attribute.md +++ b/docs/tutorials/100-simulating-data-in-attribute.md @@ -1,6 +1,6 @@ # Simulating data in attribute -If you don't have a data connection running yet or want to simulate the behaviour of an attribute, you can use the Simulator Agent to replay data. To do that, take the following steps: +If you don't have a data connection running yet or want to simulate the behavior of an attribute, you can use the Simulator Agent to replay data. To do that, take the following steps: 1. Add the 'Simulator Agent' to your system. 2. Add the configuration 'Agent link' to the attribute you want to replay data for. 3. Select the 'SimulatorAgentLink'. diff --git a/docs/tutorials/120-configure-mobile-app-behaviour.md b/docs/tutorials/120-configure-mobile-app-behavior.md similarity index 99% rename from docs/tutorials/120-configure-mobile-app-behaviour.md rename to docs/tutorials/120-configure-mobile-app-behavior.md index 636d55cf..99e4445f 100644 --- a/docs/tutorials/120-configure-mobile-app-behaviour.md +++ b/docs/tutorials/120-configure-mobile-app-behavior.md @@ -1,4 +1,4 @@ -# Configure mobile app behaviour +# Configure mobile app behavior Here we will explain how to configure your apps to be used in the OpenRemote mobile app. diff --git a/docs/user-guide/010-deploying/10-custom-deployment.md b/docs/user-guide/010-deploying/10-custom-deployment.md index d1e36e20..c3d27585 100644 --- a/docs/user-guide/010-deploying/10-custom-deployment.md +++ b/docs/user-guide/010-deploying/10-custom-deployment.md @@ -29,7 +29,7 @@ Now you can make customizations to your custom deployment. Each section will hav - [Custom domain](#custom-domain) ### Manager app configuration (/deployment/manager/app) -The manager app can be customised to fit your brand. You can for example change the colours and logos (white labeling), exclude asset types from the Add asset dialog and Rules page, make map markers react to attribute changes, and rearrange attributes in separate panels on the Assets page. These settings are also available directly in the manager app, under 'settings/appearance'. For more details view ['Configuring the Manager UI'](./20-configuring-the-manager-ui.md). +The manager app can be customized to fit your brand. You can for example change the colors and logos (white labeling), exclude asset types from the Add asset dialog and Rules page, make map markers react to attribute changes, and rearrange attributes in separate panels on the Assets page. These settings are also available directly in the manager app, under 'settings/appearance'. For more details view ['Configuring the Manager UI'](./20-configuring-the-manager-ui.md). :::note @@ -38,7 +38,7 @@ Most of the changes made in the manager_config.json will not be visible to the d ::: ### Asset type (/model) -Create your own asset type that fits your product. In the asset type you define its name, icon, and colour, and set its attributes with configuration items (called meta items in the code). If you need some inspiration, you can look at OpenRemote's [default asset types](https://github.com/openremote/core/tree/main/model/src/main/java/org/openremote/model/asset/impl). +Create your own asset type that fits your product. In the asset type you define its name, icon, and color, and set its attributes with configuration items (called meta items in the code). If you need some inspiration, you can look at OpenRemote's [default asset types](https://github.com/openremote/core/tree/main/model/src/main/java/org/openremote/model/asset/impl). ### Agents & Protocols (/agent) Protocols are a main extension point of OpenRemote, they translate the messages from and to external systems into reads and writes of the assets and attribute values used by OpenRemote. When creating an [agent asset](../../developer-guide/050-agent-protocol-spi.md), you can create protocol configurations, which are a special type of attribute. Each agent attribute that is a protocol configuration then automatically gets its own instance of the protocol you have selected. diff --git a/docs/user-guide/010-deploying/30-aws-cloudformation.md b/docs/user-guide/010-deploying/30-aws-cloudformation.md index 4c1e3ab3..e5d9897a 100644 --- a/docs/user-guide/010-deploying/30-aws-cloudformation.md +++ b/docs/user-guide/010-deploying/30-aws-cloudformation.md @@ -2,7 +2,7 @@ The CloudFormation template can be found at [cloudformation-create-vpc.yml](https://github.com/openremote/core/blob/main/.ci_cd/aws/cloudformation-create-vpc.yml). -At OpenRemote we use AWS for hosting our deployments, this guide explains how to create and configure AWS EC2 hosts using CloudFormation for running the OpenRemote started with Docker Compose; it is written from the OpenRemote organisation perspective but can be used to assist in setting up your own AWS hosted infrastructure. Please refer to the AWS documentation for more details on the services/tools mentioned (we don't generally offer AWS support but some kind person may be able to help on the [forum](https://forum.openremote.io)). +At OpenRemote we use AWS for hosting our deployments, this guide explains how to create and configure AWS EC2 hosts using CloudFormation for running the OpenRemote started with Docker Compose; it is written from the OpenRemote organization perspective but can be used to assist in setting up your own AWS hosted infrastructure. Please refer to the AWS documentation for more details on the services/tools mentioned (we don't generally offer AWS support but some kind person may be able to help on the [forum](https://forum.openremote.io)). ## AWS services/tools used To manage the OpenRemote deployments we use the following AWS services/tools: @@ -15,10 +15,10 @@ To manage the OpenRemote deployments we use the following AWS services/tools: * S3 - For backups ## AWS management console vs CLI -Interaction with AWS can be done either through the management console UI or using the CLI tool; the UI can be convenient for visualising data or for beginners but the CLI can be more efficient; this guide only discusses the use of the UI to cater for all user levels, it is assumed more advanced users know how to use the CLI to perform the same tasks. +Interaction with AWS can be done either through the management console UI or using the CLI tool; the UI can be convenient for visualizing data or for beginners but the CLI can be more efficient; this guide only discusses the use of the UI to cater for all user levels, it is assumed more advanced users know how to use the CLI to perform the same tasks. ## AWS Signing In -For interactive (UI login) it is recommended to use the [single sign on portal](https://openremote.awsapps.com/start#/), root users should not be used and user accounts should be configured for UI login with the minimal permissions to fulfil their tasks. +For interactive (UI login) it is recommended to use the [single sign on portal](https://openremote.awsapps.com/start#/), root users should not be used and user accounts should be configured for UI login with the minimal permissions to fulfill their tasks. For CLI login then an AWS access key ID and secret is needed. diff --git a/docs/user-guide/020-manager-ui/10-manager-ui.md b/docs/user-guide/020-manager-ui/10-manager-ui.md index 6d2b02ba..ad408085 100644 --- a/docs/user-guide/020-manager-ui/10-manager-ui.md +++ b/docs/user-guide/020-manager-ui/10-manager-ui.md @@ -14,7 +14,7 @@ If you open the application you will get four main pages: [Map](#map), [Assets]( The `Map` page will show your map. You can pan, zoom, and tilt the map. On the map all assets are shown which have a location (disable it by setting the configuration item `show on dashboard` to `false`). Assets can have static or dynamic locations (e.g. a car, boat or plane). You will see the direction an asset is facing or moving to if the asset includes an attribute called 'direction'. When selecting an asset, a panel will show its attributes and values. The `Asset details` button in this panel will bring you to the respective Asset page. -As part of the [configuring the manager UI](../010-deploying/20-configuring-the-manager-ui.md) you can also configure assets to change their colour based on an attribute value (number, boolean, or string) and show a label with or without units. +As part of the [configuring the manager UI](../010-deploying/20-configuring-the-manager-ui.md) you can also configure assets to change their color based on an attribute value (number, boolean, or string) and show a label with or without units.  _Figure 1. The Map view, here with the Demo Smart City, showing the map with different assets across the city as well as an additional map layer showing primary and secondary highways (GeoJSON). The ship is also showing its direction_ @@ -162,7 +162,7 @@ OpenRemote includes a [ML forecasting service](../100-services/20-service-ml-for ## Insights The Insights page (see figure 11) allows you to create multiple dashboards within the manager UI. You can: -* Define the dashboard behaviour for different screen sizes and optimise the design for a specific screen. +* Define the dashboard behavior for different screen sizes and optimize the design for a specific screen. * Share dashboards with other users even as standalone app, or keep your dashboard private. * Make dashboards public. Note this requires assets to be set as 'public' and attributes as 'public read'. * Share via the [iOS or Android console](./20-on-mobile.md) and benefit push notifications (see figure 12). @@ -206,7 +206,7 @@ Admin users of the 'Master' realm see the Realm selector on the top right to swi ### Manager interconnect -You can link multiple instances of OpenRemote (as Gateways) to a single Central instance of OpenRemote by creating a Gateway asset in the central instance and linking the Gateway instance of OpenRemote, using the 'Manager interconnect' function. The Gateway in the central instances will show the assets of the linked Gateway instance of OpenRemote, as children of the Gateway asset and will enable bidirectional communication with its attributes. Moreover, to limit traffic, you can select and limit the attributes shown as well as the rate at which they are synchronised with the Central instance. +You can link multiple instances of OpenRemote (as Gateways) to a single Central instance of OpenRemote by creating a Gateway asset in the central instance and linking the Gateway instance of OpenRemote, using the 'Manager interconnect' function. The Gateway in the central instances will show the assets of the linked Gateway instance of OpenRemote, as children of the Gateway asset and will enable bidirectional communication with its attributes. Moreover, to limit traffic, you can select and limit the attributes shown as well as the rate at which they are synchronized with the Central instance. See the [Edge Gateway documentation](../080-gateways-and-devices/10-edge-gateway.md) for more details.  @@ -228,10 +228,10 @@ OpenRemote currently supports 9 languages: English, German, French, Spanish, Por ### Logs -The logs page shows information, warnings and errors of the different activities of OpenRemote. You can use it to understand the behaviour of the whole platform or debug issues, e.g. errors connecting agent with device. +The logs page shows information, warnings and errors of the different activities of OpenRemote. You can use it to understand the behavior of the whole platform or debug issues, e.g. errors connecting agent with device.  -_Figure 18. The Logs page to evaluate system behaviour._ +_Figure 18. The Logs page to evaluate system behavior._ ### Account @@ -284,7 +284,7 @@ _Figure 23. Auto provisioning of devices_ You can restyle any realm in OpenRemote as well as adjust the map views (go to settings/appearance). -You can change the logo's, use different colours, change the title and default language, set and change the menu items, and use multiple languages for notifications to support personal language preferences. +You can change the logo's, use different colors, change the title and default language, set and change the menu items, and use multiple languages for notifications to support personal language preferences. For adding map layers you can add GeoJSON files (created e.g. with https://geojson.io/). More advanced settings like visible asset and agent types on the asset and rules page, can be configured directly in a JSON file. For the options available in the JSON file and an example, check out [Configuring the Manager UI](../010-deploying/20-configuring-the-manager-ui.md). For the maps you can set the center point, zoom levels and boundaries. diff --git a/docs/user-guide/020-manager-ui/20-on-mobile.md b/docs/user-guide/020-manager-ui/20-on-mobile.md index 8d361c77..16d3c4df 100644 --- a/docs/user-guide/020-manager-ui/20-on-mobile.md +++ b/docs/user-guide/020-manager-ui/20-on-mobile.md @@ -30,4 +30,4 @@ As part of building your own app, using our library of web components, you can u ## See Also - [Working on the mobile consoles](../../developer-guide/140-working-on-the-mobile-consoles.md) - [Architecture: Apps and consoles](../../architecture/60-apps-and-consoles.md) -- [Configure the mobile app behaviour](../../tutorials/120-configure-mobile-app-behaviour.md) +- [Configure the mobile app behavior](../../tutorials/120-configure-mobile-app-behavior.md) diff --git a/docs/user-guide/020-manager-ui/30-appearance.md b/docs/user-guide/020-manager-ui/30-appearance.md index 290af1ef..70998108 100644 --- a/docs/user-guide/020-manager-ui/30-appearance.md +++ b/docs/user-guide/020-manager-ui/30-appearance.md @@ -560,8 +560,8 @@ You can set the attributes to exclude (or include) on the top right card of the #### Marker Configuration This configures how map markers behave. -Markers can change colour based on an attribute value, show an attribute value as a label with or without units, and optionally hide the asset direction. -Marker colours can be configured using numeric ranges, string values, or boolean values. +Markers can change color based on an attribute value, show an attribute value as a label with or without units, and optionally hide the asset direction. +Marker colors can be configured using numeric ranges, string values, or boolean values. Note that this part of the config is not yet configured in the manager_config of the manager demo. ```json @@ -618,15 +618,15 @@ The `attributeName` property specifies the asset attribute used by the marker co When `showLabel` is `true`, the current attribute value is shown next to the marker. By default, units are included when available. Set `showUnits` to `false` to hide them. -The `colours` property changes the marker colour based on the current attribute value: +The `colours` property changes the marker color based on the current attribute value: -* `range` selects a colour based on the configured numeric ranges. -* `string` selects the colour whose key exactly matches the string representation of the attribute value. -* `boolean` selects either the `"true"` or `"false"` colour. +* `range` selects a color based on the configured numeric ranges. +* `string` selects the color whose key exactly matches the string representation of the attribute value. +* `boolean` selects either the `"true"` or `"false"` color. Set `hideDirection` to `true` to hide the direction indicator for assets that have a direction attribute. -Colours are specified as hexadecimal RGB values without the `#` prefix. +Colors are specified as hexadecimal RGB values without the `#` prefix. #### Clustering Configuration diff --git a/docs/user-guide/030-assets-agents-and-attributes.md b/docs/user-guide/030-assets-agents-and-attributes.md index 58c04aa6..8074f681 100644 --- a/docs/user-guide/030-assets-agents-and-attributes.md +++ b/docs/user-guide/030-assets-agents-and-attributes.md @@ -24,7 +24,7 @@ Predicted datapoints are automatically removed when their time has passed (clean If in addition, you set the `applyPredictedDataPoints` meta item on the attribute, then the predicted value is automatically applied as the current value when the time matches. ## Configuration items -As well as having a value an attribute can have configuration items (called 'meta items' in the code) which control the behaviour of the attribute (link it to an agent for read/write from/to external systems, link to another attribute, configure historical value storage, and much more). Each attribute can have one or more meta items which is essentially a well known named value (metadata) that can be used in various parts of the system to control behaviour of the associated attribute (e.g. an `agentLink` meta item is used to connect an attribute to an agent/protocol). +As well as having a value an attribute can have configuration items (called 'meta items' in the code) which control the behavior of the attribute (link it to an agent for read/write from/to external systems, link to another attribute, configure historical value storage, and much more). Each attribute can have one or more meta items which is essentially a well known named value (metadata) that can be used in various parts of the system to control behavior of the associated attribute (e.g. an `agentLink` meta item is used to connect an attribute to an agent/protocol). ## Agents Agents are a special type of asset which link external services/devices with your OpenRemote system via protocols (HTTP/TCP/...). The agent itself holds the configuration parameters as attributes and this configuration is passed to an instance of the corresponding protocol; there is a one-to-one relationship between an agent and a protocol instance. [Read more about agents](./040-agents-protocols/010-overview.md) @@ -33,7 +33,7 @@ Agents are a special type of asset which link external services/devices with you Assets can be structured in a hierarchical tree to define some logical hierarchy for a particular use case (e.g. A city has buildings, which has floors, which have presence sensors). ## Asset Type Model -Our asset type model is configurable which allows it to be modelled on the domain objects relevant for the specific use case (energy domain, smart city, etc.). At present it is only possible to configure the asset model in Java code with the long term aim of allowing configuration via the `Manager UI`. You can [find the default asset type models here](https://github.com/openremote/core/tree/main/model/src/main/java/org/openremote/model/asset/impl) and use them as examples to create your own. +Our asset type model is configurable which allows it to be modeled on the domain objects relevant for the specific use case (energy domain, smart city, etc.). At present it is only possible to configure the asset model in Java code with the long term aim of allowing configuration via the `Manager UI`. You can [find the default asset type models here](https://github.com/openremote/core/tree/main/model/src/main/java/org/openremote/model/asset/impl) and use them as examples to create your own. The asset model available for a given OpenRemote instance can be interrogated using the [Asset Model HTTP API](https://demo.openremote.io/swagger/#/Asset%20Model). @@ -54,7 +54,7 @@ An asset descriptor defines the following information for a specific asset type: * `name` - this must be unique within a given OpenRemote instance and should be the simple Java class name * `icon` - an optional icon that can be used by frontend UI to represent assets of this type on maps etc. -* `colour` - an optional colour that can be used by frontend UI to represent assets of this type on maps etc. +* `colour` - an optional color that can be used by frontend UI to represent assets of this type on maps etc. ### Attribute descriptor An attribute descriptor has a name which refers to the name of the attribute and this must be unique within the asset type hierarchy, it also contains the following information: @@ -78,7 +78,7 @@ For details on the built-in meta item descriptors available see [here](https://g for asset/agent specific configuration items check their documentation pages and/or Javadoc. ### Value descriptors -A value descriptor has a name which must be unique within the OpenRemote instance, it ultimately describes the shape of the data for serialisation/deserialisation purposes and it also contains the following information: +A value descriptor has a name which must be unique within the OpenRemote instance, it ultimately describes the shape of the data for serialization/deserialization purposes and it also contains the following information: * `type` - the simple class name of the data type this value descriptor describes * `jsonType` - the `JSON` type of data type diff --git a/docs/user-guide/040-agents-protocols/010-overview.md b/docs/user-guide/040-agents-protocols/010-overview.md index fe13fda0..331b863e 100644 --- a/docs/user-guide/040-agents-protocols/010-overview.md +++ b/docs/user-guide/040-agents-protocols/010-overview.md @@ -2,7 +2,7 @@ [Agents](https://github.com/openremote/core/blob/main/model/src/main/java/org/openremote/model/asset/agent/Agent.java) are a special type of asset which link external services/devices with your OpenRemote system via protocols; agents can be put into the following categories: -* Specialised agents (Velbus, Z-Wave, KNX, etc.) +* Specialized agents (Velbus, Z-Wave, KNX, etc.) * Generic agents (HTTP, TCP, UDP, WS, MQTT, etc.) ## Agent <-> Protocol relationship @@ -14,8 +14,8 @@ Each agent type has a corresponding [Protocol](https://github.com/openremote/cor | `agentStatus` | The current status of the agent | [Connection Status](https://github.com/openremote/core/blob/main/model/src/main/java/org/openremote/model/value/ValueType.java#L174) | -## Specialised agents -Specialised agents are ones that understand the message structure of the underlying devices/service and therefore generally require much less configuration in order to link attributes to them. +## Specialized agents +Specialized agents are ones that understand the message structure of the underlying devices/service and therefore generally require much less configuration in order to link attributes to them. ## Generic agents (IO Agents) Generic agents understand nothing about the underlying devices/service and therefore generally require more configuration in order to use them. This gives a lot of flexibility in terms of what devices/services you can communicate with and the `Agent` attributes and `Agent Link` configuration options make it possible to easily configure generic inbound/outbound value processing (convert data type, insert value into bigger message payload etc.), the following attributes can be used on generic IO agents: diff --git a/docs/user-guide/040-agents-protocols/160-velbus.md b/docs/user-guide/040-agents-protocols/160-velbus.md index d6e3b7fd..7d0591d9 100644 --- a/docs/user-guide/040-agents-protocols/160-velbus.md +++ b/docs/user-guide/040-agents-protocols/160-velbus.md @@ -45,9 +45,9 @@ To understand discovery and import refer to [Agent and Asset Discovery/Import](. ## Hardware compatibility table -'x' indicates a colour option that does not affect the capability of the module. +'x' indicates a color option that does not affect the capability of the module. -Modules are queried for their module type during initialisation, non-compatible modules will **not work in any way**. +Modules are queried for their module type during initialization, non-compatible modules will **not work in any way**.