From a6bb349f0b010928959154fdc66caa9835426841 Mon Sep 17 00:00:00 2001 From: npentrel Date: Wed, 21 May 2025 11:33:57 +0000 Subject: [PATCH 01/17] Documentation updates from Promptless --- .../operate/reference/module-configuration.md | 62 ++- docs/operate/reference/naming-modules.md | 40 +- docs/operate/reference/single-page-apps.md | 198 +++++++ .../projects/create-single-page-app.md | 502 ++++++++++++++++++ 4 files changed, 800 insertions(+), 2 deletions(-) create mode 100644 docs/operate/reference/single-page-apps.md create mode 100644 docs/tutorials/projects/create-single-page-app.md diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index fba7b1288f..e2c0a735a9 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -179,7 +179,7 @@ The model is configured as a component with the name `myRealsenseCamera1`. ``` {{% /tab %}} -{{% /tabs %}} +{{< /tabs %}} {{% /tab %}} {{< /tabs >}} @@ -227,8 +227,68 @@ For any version type other than **Patch (X.Y.Z)**, the module will upgrade as so If, for example, the module provides a motor component, and the motor is running, it will stop while the module upgrades. {{% /alert %}} +### Module meta.json configuration + +When creating a module, you'll need to configure a `meta.json` file that defines the module's properties. This file includes information about the module's ID, visibility, models, and other features. + +Here's an example of a `meta.json` file: + +```json +{ + "module_id": "your-namespace:your-module", + "visibility": "public", + "url": "https://github.com/your-org/your-repo", + "description": "Your module description", + "models": [ + { + "api": "rdk:component:base", + "model": "your-namespace:your-module:your-model" + } + ], + "entrypoint": "run.sh", + "first_run": "setup.sh" +} +``` + +For modules that include [Single Page Apps](/operate/reference/single-page-apps/), you can add the `applications` field: + +```json +{ + "module_id": "your-namespace:your-module", + "visibility": "public", + "url": "https://github.com/your-org/your-repo", + "description": "Your module description", + "models": [ + { + "api": "rdk:component:base", + "model": "your-namespace:your-module:your-model" + } + ], + "entrypoint": "run.sh", + "applications": [ + { + "name": "your-app-name", + "type": "web", + "entrypoint": "dist/index.html" + } + ] +} +``` + +The `applications` field is an array of application objects with the following properties: + +| Property | Type | Description | +| ------------ | ------ | ------------------------------------------------------------------------------------------------- | +| `name` | string | The name of your application, which will be used in the URL (`name.publicnamespace.viamapps.com`) | +| `type` | string | The type of application (currently only `"web"` is supported) | +| `entrypoint` | string | The path to the HTML entry point for your application | + +For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). + ### Environment variables +#### Environment variables + Each module has access to the following default environment variables. Not all of these variables are automatically available on [local modules](/operate/get-started/other-hardware/#test-your-module-locally); you can manually set variables your module requires if necessary. diff --git a/docs/operate/reference/naming-modules.md b/docs/operate/reference/naming-modules.md index bd544e60e1..9f95098182 100644 --- a/docs/operate/reference/naming-modules.md +++ b/docs/operate/reference/naming-modules.md @@ -95,10 +95,48 @@ More requirements: Determine the model name you want to use based on these requirements, then proceed to the next section. +## Valid application identifiers + +If your module includes [Single Page Apps](/operate/reference/single-page-apps/), you'll need to define application names in your module's `meta.json` file. Application names have the following requirements: + +- Application names must be all-lowercase. +- Application names may only use alphanumeric (`a-z` and `0-9`), hyphen (`-`), and underscore (`_`) characters. +- Application names must be unique within your organization's namespace. + +The application name will be used in the URL for accessing your application: + +``` +https://app-name.your-public-namespace.viamapps.com +``` + +For example, if your organization namespace is `acme` and your application name is `dashboard`, your application will be accessible at: + +``` +https://dashboard.acme.viamapps.com +``` + +Here's an example of how to define applications in your module's `meta.json` file: + +```json +{ + "module_id": "acme:my-module", + "visibility": "public", + "applications": [ + { + "name": "dashboard", + "type": "web", + "entrypoint": "dist/index.html" + } + ] +} +``` + +For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). + ## Create a namespace for your organization When uploading modules to the Viam Registry, you must set a unique namespace for your organization to associate your module with. To create a new namespace for your organization, click on the org's **Settings** in the top right of the navigation bar, then click the **Set a public namespace** button. Enter a name or use the suggested name for your namespace, and then click **Set namespace**. -A namespace may only contain letters, numbers, and the dash (`-`) character. +A namespace may only contain letters, numbers, and the dash (`-`) character. \ No newline at end of file diff --git a/docs/operate/reference/single-page-apps.md b/docs/operate/reference/single-page-apps.md new file mode 100644 index 0000000000..d09e84c51c --- /dev/null +++ b/docs/operate/reference/single-page-apps.md @@ -0,0 +1,198 @@ +--- +title: "Single Page Apps" +linkTitle: "Single Page Apps" +weight: 45 +no_list: true +type: docs +icon: true +description: "Create and deploy single page applications hosted by Viam." +--- + +Viam Single Page Apps allow you to upload a single page application and access it via a dedicated URL (`appname.publicnamespace.viamapps.com`), with hosting, authentication, and boilerplate logic handled for you. This feature enables you to create custom web interfaces for your machines without having to manage the infrastructure for hosting and authentication. + +## Overview + +With Viam Single Page Apps, you can: + +- Host shared logic for users to choose an organization, location, and single machine +- Render your application once a user has selected a machine +- Store robot owner API key and secret in browser storage +- Proxy requests through the viamapps.com domain to maintain same-origin across pages +- Authenticate users via FusionAuth +- Create and upload apps using the modules framework + +## Requirements + +To use Viam Single Page Apps, you need: + +- A module with a public visibility setting +- A properly configured `meta.json` file with application information +- A built single page application with an HTML entry point + +## Creating a Single Page App + +### 1. Build your application + +Build your single page application using your preferred framework (React, Vue, Angular, etc.). Your application should be built and ready for deployment, with all assets compiled into a distributable format. + +### 2. Configure your module's meta.json + +Add the `applications` field to your module's `meta.json` file to define your single page app: + +```json +{ + "module_id": "your-namespace:your-module", + "visibility": "public", + "url": "https://github.com/your-org/your-repo", + "description": "Your module description", + "models": [ + { + "api": "rdk:component:base", + "model": "your-namespace:your-module:your-model" + } + ], + "entrypoint": "run.sh", + "applications": [ + { + "name": "your-app-name", + "type": "web", + "entrypoint": "dist/index.html" + } + ] +} +``` + +The `applications` field is an array of application objects with the following properties: + +| Property | Type | Description | +| --- | --- | --- | +| `name` | string | The name of your application, which will be used in the URL (`name.publicnamespace.viamapps.com`) | +| `type` | string | The type of application (currently only `"web"` is supported) | +| `entrypoint` | string | The path to the HTML entry point for your application | + +#### Entrypoint examples + +The `entrypoint` field specifies the path to your application's entry point. Here are some examples: + +- `"dist/index.html"` - Static content rooted at the `dist` directory +- `"dist/foo.html"` - Static content rooted at the `dist` directory, with `foo.html` as the entry point +- `"dist/"` - Static content rooted at the `dist` directory (assumes `dist/index.html` exists) +- `"dist/bar/foo.html"` - Static content rooted at `dist/bar` with `foo.html` as the entry point + +### 3. Upload your module + +Package your module with your application included and upload it to the Viam Registry: + +```bash +viam module build local +viam module upload module.tar.gz +``` + +## Accessing your Single Page App + +Once your module with the application configuration is uploaded and approved, your application will be available at: + +``` +https://your-app-name.your-public-namespace.viamapps.com +``` + +Users will be prompted to authenticate with their Viam credentials before accessing your application. + +## Application Flow + +1. User navigates to `your-app-name.your-public-namespace.viamapps.com` +2. User authenticates with Viam credentials +3. User selects an organization, location, and machine +4. User is redirected to `your-app-name.your-public-namespace.viamapps.com/machine/{machine-id}` +5. Your application is rendered with access to the selected machine + +## API Changes + +The Single Page Apps feature introduces the following API changes: + +### App Object + +```protobuf +message App { + string name = 1; + string type = 2; + string entrypoint = 3; +} +``` + +### UpdateModuleRequest + +```protobuf +message UpdateModuleRequest { + string module_id = 1; + Visibility visibility = 2; + string url = 3; + string description = 4; + repeated Model models = 5; + string entrypoint = 6; + optional string first_run = 7; + repeated App apps = 8; +} +``` + +### GetAppContentRequest/Response + +```protobuf +message GetAppContentRequest { + string public_namespace = 1; + string name = 2; +} + +message GetAppContentResponse { + string url = 1; +} +``` + +## Limitations + +- Single Page Apps currently only support single-machine applications +- All modules with apps must have public visibility +- There is no versioning or separate deploy step; the page will always render the latest version +- Browsers with cookies disabled are not supported + +## Security Considerations + +- Customer apps are stored in GCS buckets that are publicly available on the internet +- Avoid uploading sensitive information in your application code or assets +- API keys and secrets are stored in the browser's localStorage or sessionStorage + +## Example + +Here's a complete example of creating and uploading a simple React application as a Viam Single Page App: + +```bash +# Create a new React app +npx create-react-app my-viam-app +cd my-viam-app + +# Build the app +npm run build + +# Create a module with the app +viam module create --name my-viam-app --public-namespace your-namespace + +# Edit meta.json to add the application configuration +# Add the following to meta.json: +# "visibility": "public", +# "applications": [ +# { +# "name": "my-app", +# "type": "web", +# "entrypoint": "build/index.html" +# } +# ] + +# Copy the build directory to the module directory +cp -r build/ path/to/module/ + +# Build and upload the module +viam module build local +viam module upload module.tar.gz +``` + +After the module is approved, your application will be available at `https://my-app.your-public-namespace.viamapps.com`. \ No newline at end of file diff --git a/docs/tutorials/projects/create-single-page-app.md b/docs/tutorials/projects/create-single-page-app.md new file mode 100644 index 0000000000..f775f2402e --- /dev/null +++ b/docs/tutorials/projects/create-single-page-app.md @@ -0,0 +1,502 @@ +--- +title: "Create a Single Page App" +linkTitle: "Create a Single Page App" +weight: 45 +type: "docs" +description: "Build and deploy a web application hosted by Viam." +tags: ["web", "single page app", "react", "module"] +difficulty: intermediate +time_to_complete: "1 hour" +--- + +This tutorial guides you through creating and deploying a Single Page App (SPA) with Viam. You'll build a simple React application that allows users to select a machine and view its camera feed. + +## Prerequisites + +- A Viam account with an organization that has a public namespace +- Node.js and npm installed on your development machine +- Basic familiarity with React +- A machine with a camera component configured in your Viam account + +## Step 1: Create a React application + +First, let's create a new React application using Create React App: + +```bash +npx create-react-app viam-camera-viewer +cd viam-camera-viewer +``` + +## Step 2: Install dependencies + +Install the Viam TypeScript SDK and other necessary dependencies: + +```bash +npm install @viamrobotics/sdk react-router-dom +``` + +## Step 3: Create the application structure + +Let's create a simple application with the following pages: + +1. Home page - For selecting organization, location, and machine +2. Machine page - For viewing the selected machine's camera feed + +Create the following folder structure: + +``` +src/ +├── components/ +│ ├── OrganizationSelector.js +│ ├── LocationSelector.js +│ ├── MachineSelector.js +│ └── CameraViewer.js +├── pages/ +│ ├── HomePage.js +│ └── MachinePage.js +├── App.js +└── index.js +``` + +## Step 4: Implement the components + +Let's implement each component: + +### OrganizationSelector.js + +```jsx +import React, { useState, useEffect } from 'react'; + +function OrganizationSelector({ onSelect }) { + const [organizations, setOrganizations] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + // In a real app, you would fetch organizations from the Viam API + // This is a simplified example + setOrganizations([ + { id: 'org1', name: 'My Organization' }, + { id: 'org2', name: 'Another Organization' } + ]); + setLoading(false); + }, []); + + if (loading) return
Loading organizations...
; + if (error) return
Error: {error}
; + + return ( +
+

Select an Organization

+ +
+ ); +} + +export default OrganizationSelector; +``` + +### LocationSelector.js + +```jsx +import React, { useState, useEffect } from 'react'; + +function LocationSelector({ organizationId, onSelect }) { + const [locations, setLocations] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + + useEffect(() => { + if (!organizationId) { + setLocations([]); + setLoading(false); + return; + } + + // In a real app, you would fetch locations from the Viam API + // This is a simplified example + setLocations([ + { id: 'loc1', name: 'Home' }, + { id: 'loc2', name: 'Office' } + ]); + setLoading(false); + }, [organizationId]); + + if (!organizationId) return null; + if (loading) return
Loading locations...
; + if (error) return
Error: {error}
; + + return ( +
+

Select a Location

+ +
+ ); +} + +export default LocationSelector; +``` + +### MachineSelector.js + +```jsx +import React, { useState, useEffect } from 'react'; +import { useNavigate } from 'react-router-dom'; + +function MachineSelector({ locationId }) { + const [machines, setMachines] = useState([]); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const navigate = useNavigate(); + + useEffect(() => { + if (!locationId) { + setMachines([]); + setLoading(false); + return; + } + + // In a real app, you would fetch machines from the Viam API + // This is a simplified example + setMachines([ + { id: 'machine1', name: 'My Robot' }, + { id: 'machine2', name: 'Another Robot' } + ]); + setLoading(false); + }, [locationId]); + + const handleMachineSelect = (machineId) => { + if (machineId) { + navigate(`/machine/${machineId}`); + } + }; + + if (!locationId) return null; + if (loading) return
Loading machines...
; + if (error) return
Error: {error}
; + + return ( +
+

Select a Machine

+ +
+ ); +} + +export default MachineSelector; +``` + +### CameraViewer.js + +```jsx +import React, { useState, useEffect, useRef } from 'react'; + +function CameraViewer({ machineId }) { + const [cameras, setCameras] = useState([]); + const [selectedCamera, setSelectedCamera] = useState(''); + const [loading, setLoading] = useState(true); + const [error, setError] = useState(null); + const imageRef = useRef(null); + + useEffect(() => { + if (!machineId) { + setCameras([]); + setLoading(false); + return; + } + + // In a real app, you would fetch cameras from the Viam API + // This is a simplified example + setCameras([ + { id: 'camera1', name: 'Main Camera' }, + { id: 'camera2', name: 'Secondary Camera' } + ]); + setLoading(false); + }, [machineId]); + + useEffect(() => { + if (!selectedCamera) return; + + // In a real app, you would set up a stream from the Viam API + // This is a simplified example + const interval = setInterval(() => { + // Simulate camera feed with a placeholder + if (imageRef.current) { + imageRef.current.src = `https://picsum.photos/800/600?random=${Date.now()}`; + } + }, 1000); + + return () => clearInterval(interval); + }, [selectedCamera]); + + const handleCameraSelect = (cameraId) => { + setSelectedCamera(cameraId); + }; + + if (!machineId) return null; + if (loading) return
Loading cameras...
; + if (error) return
Error: {error}
; + + return ( +
+

Camera Feed

+
+ +
+ {selectedCamera && ( +
+ Camera feed +
+ )} +
+ ); +} + +export default CameraViewer; +``` + +## Step 5: Create the pages + +### HomePage.js + +```jsx +import React, { useState } from 'react'; +import OrganizationSelector from '../components/OrganizationSelector'; +import LocationSelector from '../components/LocationSelector'; +import MachineSelector from '../components/MachineSelector'; + +function HomePage() { + const [selectedOrg, setSelectedOrg] = useState(''); + const [selectedLocation, setSelectedLocation] = useState(''); + + return ( +
+

Viam Camera Viewer

+

Select your organization, location, and machine to view camera feeds.

+ +
+ +
+ + {selectedOrg && ( +
+ +
+ )} + + {selectedLocation && ( +
+ +
+ )} +
+ ); +} + +export default HomePage; +``` + +### MachinePage.js + +```jsx +import React from 'react'; +import { useParams, Link } from 'react-router-dom'; +import CameraViewer from '../components/CameraViewer'; + +function MachinePage() { + const { machineId } = useParams(); + + return ( +
+
+ ← Back to selection +
+ +

Machine: {machineId}

+ +
+ ); +} + +export default MachinePage; +``` + +## Step 6: Update App.js with routing + +```jsx +import React from 'react'; +import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; +import HomePage from './pages/HomePage'; +import MachinePage from './pages/MachinePage'; + +function App() { + return ( + + + } /> + } /> + + + ); +} + +export default App; +``` + +## Step 7: Build the application + +Build your React application: + +```bash +npm run build +``` + +This will create a production build in the `build` directory. + +## Step 8: Create a Viam module + +Now, let's create a Viam module to host our Single Page App: + +```bash +mkdir viam-camera-viewer-module +cd viam-camera-viewer-module +``` + +Create a `meta.json` file: + +```json +{ + "module_id": "your-namespace:camera-viewer", + "visibility": "public", + "url": "https://github.com/your-username/viam-camera-viewer", + "description": "A simple camera viewer single page application", + "models": [], + "entrypoint": "", + "applications": [ + { + "name": "camera-viewer", + "type": "web", + "entrypoint": "build/index.html" + } + ] +} +``` + +Replace `your-namespace` with your organization's public namespace. + +## Step 9: Package and upload the module + +Copy your React build files to the module directory: + +```bash +cp -r ../viam-camera-viewer/build ./ +``` + +Create a module tarball: + +```bash +tar -czvf module.tar.gz build meta.json +``` + +Upload the module to the Viam Registry: + +```bash +viam module upload module.tar.gz +``` + +## Step 10: Access your Single Page App + +Once your module is approved, you can access your Single Page App at: + +``` +https://camera-viewer.your-namespace.viamapps.com +``` + +Replace `your-namespace` with your organization's public namespace. + +## Integrating with the Viam SDK + +The example above uses placeholder data. In a real application, you would use the Viam TypeScript SDK to interact with your machines. Here's how you might implement the actual API calls: + +### Connecting to Viam + +```jsx +import { createRobotClient, ViamClient } from '@viamrobotics/sdk'; + +// Create a Viam client +const createClient = async () => { + try { + // Get credentials from localStorage + const apiKey = localStorage.getItem('viamApiKey'); + const apiKeyId = localStorage.getItem('viamApiKeyId'); + + if (!apiKey || !apiKeyId) { + throw new Error('API credentials not found'); + } + + const client = await createRobotClient({ + host: 'your-machine-fqdn.viam.cloud', + credential: { + type: 'api-key', + payload: apiKey, + }, + signingAuthority: apiKeyId, + authEntity: 'your-machine-id', + }); + + return client; + } catch (error) { + console.error('Error creating client:', error); + throw error; + } +}; +``` + +### Getting camera data + +```jsx +// Get camera image +const getCameraImage = async (client, cameraName) => { + try { + const camera = await client.camera.fromRobot(cameraName); + const image = await camera.getImage(); + return image; + } catch (error) { + console.error('Error getting camera image:', error); + throw error; + } +}; +``` + +## Conclusion + +You've successfully created and deployed a Single Page App with Viam! This simple application demonstrates how to build a web interface for interacting with Viam machines. You can extend this application to include more features, such as controlling motors, reading sensor data, or implementing more complex machine interactions. + +For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). \ No newline at end of file From aa38d5122c9d9046e1b74b143ab47b32e7470afa Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Wed, 21 May 2025 18:49:43 +0200 Subject: [PATCH 02/17] Update --- docs/operate/control/single-page-apps.md | 200 ++++++++++++++++++ .../get-started/other-hardware/_index.md | 16 +- .../operate/reference/module-configuration.md | 4 +- docs/operate/reference/naming-modules.md | 30 +-- docs/operate/reference/single-page-apps.md | 198 ----------------- 5 files changed, 220 insertions(+), 228 deletions(-) create mode 100644 docs/operate/control/single-page-apps.md delete mode 100644 docs/operate/reference/single-page-apps.md diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md new file mode 100644 index 0000000000..186e06eecd --- /dev/null +++ b/docs/operate/control/single-page-apps.md @@ -0,0 +1,200 @@ +--- +title: "Create a custom web interface" +linkTitle: "Create a custom web interface" +weight: 11 +no_list: true +type: docs +description: "Create and deploy single page applications on the Viam platform." +--- + +With single page apps you can create and deploy custom web interfaces for your machines that use a single HTML page. +Single page apps are accessible from a dedicated URL (`appname.publicnamespace.viamapps.com`) and hosting and authentication is handled for you. + +When opening an app, users log in and then select a machine they have access to. +Then your app is rendered and ready for use. + +TODO: Example GIF + +## Requirements + +{{< expand "Install the Viam CLI and authenticate." >}} +Install the Viam CLI using the option below that matches your system architecture: + +{{< readfile "/static/include/how-to/install-cli.md" >}} + +Then authenticate your CLI session with Viam using one of the following options: + +{{< readfile "/static/include/how-to/auth-cli.md" >}} + +{{< /expand >}} + +## Create a single page app + +{{< table >}} +{{% tablestep number=1 %}} + +**Build your single page application** using your preferred framework like React, Vue, Angular, or others. +Your application should be built and ready for deployment, with all assets compiled into a distributable format. + +TODO: cover dev process +TODO: how do you connect to the machine / how do you access the api key? + +{{% /tablestep %}} +{{% tablestep number=2 %}} + +**Create a meta.json** file using this template: + +{{< tabs >}} +{{% tab name="Template" %}} + +```json +{ + "module_id": "your-namespace:your-module", + "visibility": "public", + "url": "https://github.com/your-org/your-repo", + "description": "Your module description", + "applications": [ + { + "name": "your-app-name", + "type": "web", + "entrypoint": "dist/index.html" + } + ] +} +``` + +{{% /tab %}} +{{% tab name="Example" %}} + +```json +{ + "module_id": "acme:dashboard", + "visibility": "public", + "url": "https://github.com/acme/dashboard", + "description": "An example dashboard for a fictitious company called Acme.", + "applications": [ + { + "name": "dashboard", + "type": "web", + "entrypoint": "dist/index.html" + } + ] +} +``` + +{{% /tab %}} +{{< /tabs >}} + +{{% expand "Click to view" %}} + + +| Name | Type | Inclusion | Description | +|------|------|-----------|-------------| +| `module_id` | string | **Required** | The module ID, which includes the organization name and the module name. `module_id` uniquely identifies your module. | +| `visibility` | string | **Required** | Must be `"public"`. | +| `description` | string | **Required** | A description of your module and what it provides. | +| `url` | string | Optional | The URL of the GitHub repository containing the source code of the module. | +| `applications` | array | Optional | Objects that provide information about the [single page apps](/operate/reference/single-page-apps/) associated with the module. | +| `models` | array | Optional | Empty unless you are shipping the app alongside models. For information on how to add models, see [Integrate other hardware](/operate/get-started/other-hardware/). | + +{{% /expand%}} + +The `applications` field is an array of application objects with the following properties: + + +| Property | Type | Description | +| ------------ | ------ | ------------------------------------------------------------------------------------------------- | +| `name` | string | The name of your application, which will be a part of the app's URL (`name.publicnamespace.viamapps.com`). For more information on valid names see [](/operate/reference/naming-modules). | +| `type` | string | The type of application (currently only `"web"` is supported). | +| `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example: | + +{{% /tablestep %}} +{{% tablestep number=3 %}} + +**Package your app into a module and upload it** to the Viam Registry: + +TODO: first command doesn't make sense + +```sh {class="command-line" data-prompt="$" data-output="3-10"} +viam module build local +viam module upload module.tar.gz +``` + +TODO: the upload command requires platform & version - is that no longer the case? + +For subsequent updates you can use: + +```sh {class="command-line" data-prompt="$" data-output="2-10"} +viam module update +``` + +{{% /tablestep %}} +{{< /table >}} + +## Accessing your Single Page App + +Once your module with the application configuration is uploaded, your application will be available at: + +TODO: any extra steps? + +``` +https://your-app-name.your-public-namespace.viamapps.com +``` + +Users will be prompted to authenticate with their Viam credentials before accessing your application: + +1. User navigates to `your-app-name.your-public-namespace.viamapps.com` +1. User authenticates with Viam credentials +1. User selects an organization, location, and machine +1. User is redirected to `your-app-name.your-public-namespace.viamapps.com/machine/{machine-id}` +1. Your application is rendered with access to the selected machine + +## Limitations + +- Single page apps currently only support single-machine applications +- All modules with apps must have public visibility +- There is no versioning or separate deploy step; the page will always render the latest version +- Browsers with cookies disabled are not supported + +## Security Considerations + +- Customer apps are stored in GCS buckets that are publicly available on the internet +- Avoid uploading sensitive information in your application code or assets +- API keys and secrets are stored in the browser's localStorage or sessionStorage +- Single page apps authenticate users with FusionAuth + +## Example + +Here's a complete example of creating and uploading a simple React application as a Viam Single Page App: + +```bash +# Create a new React app +npx create-react-app my-viam-app +cd my-viam-app + +# Build the app +npm run build + +# Create a module with the app +viam module create --name my-viam-app --public-namespace your-namespace + +# Edit meta.json to add the application configuration +# Add the following to meta.json: +# "visibility": "public", +# "applications": [ +# { +# "name": "my-app", +# "type": "web", +# "entrypoint": "build/index.html" +# } +# ] + +# Copy the build directory to the module directory +cp -r build/ path/to/module/ + +# Build and upload the module +viam module build local +viam module upload module.tar.gz +``` + +After the module is approved, your application will be available at `https://my-app.your-public-namespace.viamapps.com`. diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index efd365648a..7b439f0bca 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -987,16 +987,16 @@ Do not change the module_id.

models -object -Required -

A list of one or more {{< glossary_tooltip term_id="model" text="models" >}} provided by your custom module. You must provide at least one model, which consists of an api and model key pair. If you are publishing a public module ("visibility": "public"), the namespace of your model must match the namespace of your organization.

+array +Optional +

A list of one or more {{< glossary_tooltip term_id="model" text="models" >}} provided by your custom module. You must provide at least one model in the models array or one application in the applications array. A model consists of an api and model key pair. If you are publishing a public module ("visibility": "public"), the namespace of your model must match the namespace of your organization.

You are strongly encouraged to include a markdown_link to the section of the README containing configuration information about each model, so that the section will be displayed alongside the configuration panel when configuring the model. For example, "README.md#configure-your-meteo_pm-sensor". Please also include a short_description describing what hardware the model supports.

entrypoint string -Required -The name of the file that starts your module program. This can be a compiled executable, a script, or an invocation of another program. If you are providing your module as a single file to the upload command, provide the path to that single file. If you are providing a directory containing your module to the upload command, provide the path to the entry point file contained within that directory. +Optional +The name of the file that starts your module program. This can be a compiled executable, a script, or an invocation of another program. If you are providing your module as a single file to the upload command, provide the path to that single file. If you are providing a directory containing your module to the upload command, provide the path to the entry point file contained within that directory. Required if you are shipping a model. build @@ -1016,6 +1016,12 @@ Do not change the module_id.

Optional Enables VS Code hover and autocomplete as you edit your module code. Gets auto-generated when you run viam module generate or viam module create. Has no impact on the module's function. + +applications +array +Optional +Objects that provide information about the [Single Page Apps](/operate/reference/single-page-apps/) associated with the module. + diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index e2c0a735a9..6a1918aa6d 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -179,7 +179,7 @@ The model is configured as a component with the name `myRealsenseCamera1`. ``` {{% /tab %}} -{{< /tabs %}} +{{% /tabs %}} {{% /tab %}} {{< /tabs >}} @@ -285,8 +285,6 @@ The `applications` field is an array of application objects with the following p For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). -### Environment variables - #### Environment variables Each module has access to the following default environment variables. diff --git a/docs/operate/reference/naming-modules.md b/docs/operate/reference/naming-modules.md index 9f95098182..fcf9b68979 100644 --- a/docs/operate/reference/naming-modules.md +++ b/docs/operate/reference/naming-modules.md @@ -9,7 +9,7 @@ description: "Add support for a new component or service model by writing a modu languages: ["c++"] viamresources: [] platformarea: ["registry"] -toc_hide: true +toc_hide: false --- Each modular resource has two associated triplets: an API namespace triplet to indicate which [API](/dev/reference/apis/) it implements, and a model namespace triplet to uniquely identify the modular resource {{< glossary_tooltip term_id="model" text="model" >}}. @@ -97,15 +97,17 @@ Determine the model name you want to use based on these requirements, then proce ## Valid application identifiers -If your module includes [Single Page Apps](/operate/reference/single-page-apps/), you'll need to define application names in your module's `meta.json` file. Application names have the following requirements: +If your module includes a [single page app](/operate/reference/single-page-apps/), you need to define the application name in your module's `meta.json` file. +Application names have the following requirements: - Application names must be all-lowercase. -- Application names may only use alphanumeric (`a-z` and `0-9`), hyphen (`-`), and underscore (`_`) characters. +- Application names may only use alphanumeric (`a-z` and `0-9`) and hyphen (`-`) characters. +- Application names may not start or end with a hyphen. - Application names must be unique within your organization's namespace. -The application name will be used in the URL for accessing your application: +The URL for accessing your single page app will contain your application name: -``` +```txt https://app-name.your-public-namespace.viamapps.com ``` @@ -115,22 +117,6 @@ For example, if your organization namespace is `acme` and your application name https://dashboard.acme.viamapps.com ``` -Here's an example of how to define applications in your module's `meta.json` file: - -```json -{ - "module_id": "acme:my-module", - "visibility": "public", - "applications": [ - { - "name": "dashboard", - "type": "web", - "entrypoint": "dist/index.html" - } - ] -} -``` - For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). ## Create a namespace for your organization @@ -139,4 +125,4 @@ When uploading modules to the Viam Registry, you must set a unique namespace for To create a new namespace for your organization, click on the org's **Settings** in the top right of the navigation bar, then click the **Set a public namespace** button. Enter a name or use the suggested name for your namespace, and then click **Set namespace**. -A namespace may only contain letters, numbers, and the dash (`-`) character. \ No newline at end of file +A namespace may only contain letters, numbers, and the dash (`-`) character. diff --git a/docs/operate/reference/single-page-apps.md b/docs/operate/reference/single-page-apps.md deleted file mode 100644 index d09e84c51c..0000000000 --- a/docs/operate/reference/single-page-apps.md +++ /dev/null @@ -1,198 +0,0 @@ ---- -title: "Single Page Apps" -linkTitle: "Single Page Apps" -weight: 45 -no_list: true -type: docs -icon: true -description: "Create and deploy single page applications hosted by Viam." ---- - -Viam Single Page Apps allow you to upload a single page application and access it via a dedicated URL (`appname.publicnamespace.viamapps.com`), with hosting, authentication, and boilerplate logic handled for you. This feature enables you to create custom web interfaces for your machines without having to manage the infrastructure for hosting and authentication. - -## Overview - -With Viam Single Page Apps, you can: - -- Host shared logic for users to choose an organization, location, and single machine -- Render your application once a user has selected a machine -- Store robot owner API key and secret in browser storage -- Proxy requests through the viamapps.com domain to maintain same-origin across pages -- Authenticate users via FusionAuth -- Create and upload apps using the modules framework - -## Requirements - -To use Viam Single Page Apps, you need: - -- A module with a public visibility setting -- A properly configured `meta.json` file with application information -- A built single page application with an HTML entry point - -## Creating a Single Page App - -### 1. Build your application - -Build your single page application using your preferred framework (React, Vue, Angular, etc.). Your application should be built and ready for deployment, with all assets compiled into a distributable format. - -### 2. Configure your module's meta.json - -Add the `applications` field to your module's `meta.json` file to define your single page app: - -```json -{ - "module_id": "your-namespace:your-module", - "visibility": "public", - "url": "https://github.com/your-org/your-repo", - "description": "Your module description", - "models": [ - { - "api": "rdk:component:base", - "model": "your-namespace:your-module:your-model" - } - ], - "entrypoint": "run.sh", - "applications": [ - { - "name": "your-app-name", - "type": "web", - "entrypoint": "dist/index.html" - } - ] -} -``` - -The `applications` field is an array of application objects with the following properties: - -| Property | Type | Description | -| --- | --- | --- | -| `name` | string | The name of your application, which will be used in the URL (`name.publicnamespace.viamapps.com`) | -| `type` | string | The type of application (currently only `"web"` is supported) | -| `entrypoint` | string | The path to the HTML entry point for your application | - -#### Entrypoint examples - -The `entrypoint` field specifies the path to your application's entry point. Here are some examples: - -- `"dist/index.html"` - Static content rooted at the `dist` directory -- `"dist/foo.html"` - Static content rooted at the `dist` directory, with `foo.html` as the entry point -- `"dist/"` - Static content rooted at the `dist` directory (assumes `dist/index.html` exists) -- `"dist/bar/foo.html"` - Static content rooted at `dist/bar` with `foo.html` as the entry point - -### 3. Upload your module - -Package your module with your application included and upload it to the Viam Registry: - -```bash -viam module build local -viam module upload module.tar.gz -``` - -## Accessing your Single Page App - -Once your module with the application configuration is uploaded and approved, your application will be available at: - -``` -https://your-app-name.your-public-namespace.viamapps.com -``` - -Users will be prompted to authenticate with their Viam credentials before accessing your application. - -## Application Flow - -1. User navigates to `your-app-name.your-public-namespace.viamapps.com` -2. User authenticates with Viam credentials -3. User selects an organization, location, and machine -4. User is redirected to `your-app-name.your-public-namespace.viamapps.com/machine/{machine-id}` -5. Your application is rendered with access to the selected machine - -## API Changes - -The Single Page Apps feature introduces the following API changes: - -### App Object - -```protobuf -message App { - string name = 1; - string type = 2; - string entrypoint = 3; -} -``` - -### UpdateModuleRequest - -```protobuf -message UpdateModuleRequest { - string module_id = 1; - Visibility visibility = 2; - string url = 3; - string description = 4; - repeated Model models = 5; - string entrypoint = 6; - optional string first_run = 7; - repeated App apps = 8; -} -``` - -### GetAppContentRequest/Response - -```protobuf -message GetAppContentRequest { - string public_namespace = 1; - string name = 2; -} - -message GetAppContentResponse { - string url = 1; -} -``` - -## Limitations - -- Single Page Apps currently only support single-machine applications -- All modules with apps must have public visibility -- There is no versioning or separate deploy step; the page will always render the latest version -- Browsers with cookies disabled are not supported - -## Security Considerations - -- Customer apps are stored in GCS buckets that are publicly available on the internet -- Avoid uploading sensitive information in your application code or assets -- API keys and secrets are stored in the browser's localStorage or sessionStorage - -## Example - -Here's a complete example of creating and uploading a simple React application as a Viam Single Page App: - -```bash -# Create a new React app -npx create-react-app my-viam-app -cd my-viam-app - -# Build the app -npm run build - -# Create a module with the app -viam module create --name my-viam-app --public-namespace your-namespace - -# Edit meta.json to add the application configuration -# Add the following to meta.json: -# "visibility": "public", -# "applications": [ -# { -# "name": "my-app", -# "type": "web", -# "entrypoint": "build/index.html" -# } -# ] - -# Copy the build directory to the module directory -cp -r build/ path/to/module/ - -# Build and upload the module -viam module build local -viam module upload module.tar.gz -``` - -After the module is approved, your application will be available at `https://my-app.your-public-namespace.viamapps.com`. \ No newline at end of file From 14fad223fd80dd29da141f94ffbf55bef23dc54a Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Fri, 23 May 2025 10:39:25 +0200 Subject: [PATCH 03/17] Draft --- docs/operate/control/single-page-apps.md | 27 +++++++++++++++++------- 1 file changed, 19 insertions(+), 8 deletions(-) diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index 186e06eecd..9e8537dc51 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -7,8 +7,16 @@ type: docs description: "Create and deploy single page applications on the Viam platform." --- +- Deploy front-end apps +- + +you can have multiple HTML files +files have to all be deployed + With single page apps you can create and deploy custom web interfaces for your machines that use a single HTML page. -Single page apps are accessible from a dedicated URL (`appname.publicnamespace.viamapps.com`) and hosting and authentication is handled for you. +Single page apps are accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`) and hosting and authentication is handled for you. + +google SPA and include what exactly that means When opening an app, users log in and then select a machine they have access to. Then your app is rendered and ready for use. @@ -56,7 +64,7 @@ TODO: how do you connect to the machine / how do you access the api key? "applications": [ { "name": "your-app-name", - "type": "web", + "type": "single_machine", "entrypoint": "dist/index.html" } ] @@ -75,7 +83,7 @@ TODO: how do you connect to the machine / how do you access the api key? "applications": [ { "name": "dashboard", - "type": "web", + "type": "single_machine", "entrypoint": "dist/index.html" } ] @@ -104,8 +112,8 @@ The `applications` field is an array of application objects with the following p | Property | Type | Description | | ------------ | ------ | ------------------------------------------------------------------------------------------------- | -| `name` | string | The name of your application, which will be a part of the app's URL (`name.publicnamespace.viamapps.com`). For more information on valid names see [](/operate/reference/naming-modules). | -| `type` | string | The type of application (currently only `"web"` is supported). | +| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [](/operate/reference/naming-modules). | +| `type` | string | The type of application (currently only `"single_machine"` is supported). | | `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example: | {{% /tablestep %}} @@ -114,10 +122,11 @@ The `applications` field is an array of application objects with the following p **Package your app into a module and upload it** to the Viam Registry: TODO: first command doesn't make sense +don't use module generate ```sh {class="command-line" data-prompt="$" data-output="3-10"} viam module build local -viam module upload module.tar.gz +viam module upload module.tar.gz --platform=any ``` TODO: the upload command requires platform & version - is that no longer the case? @@ -143,10 +152,10 @@ https://your-app-name.your-public-namespace.viamapps.com Users will be prompted to authenticate with their Viam credentials before accessing your application: -1. User navigates to `your-app-name.your-public-namespace.viamapps.com` +1. User navigates to `your-app-name_your-public-namespace.viamapplications.com` 1. User authenticates with Viam credentials 1. User selects an organization, location, and machine -1. User is redirected to `your-app-name.your-public-namespace.viamapps.com/machine/{machine-id}` +1. User is redirected to `your-app-name_your-public-namespace.viamapplications.com/machine/{machine-id}` 1. Your application is rendered with access to the selected machine ## Limitations @@ -198,3 +207,5 @@ viam module upload module.tar.gz ``` After the module is approved, your application will be available at `https://my-app.your-public-namespace.viamapps.com`. + +https://github.com/bashar-515/sample-app From 660da6ec2b9375afe000798abcaf908788853f1e Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Fri, 23 May 2025 22:23:44 +0200 Subject: [PATCH 04/17] Update --- assets/operate/spa.png | Bin 0 -> 37636 bytes .../air-quality-fleet/get-readings.png | Bin 103018 -> 39737 bytes docs/operate/control/single-page-apps.md | 124 +- docs/tutorials/control/air-quality-fleet.md | 1094 +++++++++-------- 4 files changed, 642 insertions(+), 576 deletions(-) create mode 100644 assets/operate/spa.png diff --git a/assets/operate/spa.png b/assets/operate/spa.png new file mode 100644 index 0000000000000000000000000000000000000000..c2f1282bc6ec602c46ed7ceb02dcb9b4ed780c8e GIT binary patch literal 37636 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 NkyN;zb@h(d{{k++)9nBN literal 0 HcmV?d00001 diff --git a/assets/tutorials/air-quality-fleet/get-readings.png b/assets/tutorials/air-quality-fleet/get-readings.png index e637ab5270241d73ba7a0b38c3b941058eafe347..709710c93fb102ab842dd8ed7bb74d458862a12f 100644 GIT binary patch literal 39737 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 literal 103018 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 ?gUlC~kycM}>fuFWaG7n7vofafF1c8y8HIi|Nm& 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 WloucAz#HP1Uo=!Ns1%;P9PmGw->uF7 diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index 9e8537dc51..507d4824a0 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -4,24 +4,16 @@ linkTitle: "Create a custom web interface" weight: 11 no_list: true type: docs -description: "Create and deploy single page applications on the Viam platform." +description: "Create and deploy custom web interfaces for your machines as single-page applications without managing hosting and authentication." --- -- Deploy front-end apps -- - -you can have multiple HTML files -files have to all be deployed - -With single page apps you can create and deploy custom web interfaces for your machines that use a single HTML page. -Single page apps are accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`) and hosting and authentication is handled for you. - -google SPA and include what exactly that means +Create and deploy custom web interfaces for your machines as single-page applications without managing hosting and authentication. +Once deployed, apps are accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`) and hosting and authentication is handled for you. When opening an app, users log in and then select a machine they have access to. Then your app is rendered and ready for use. -TODO: Example GIF +{{}} ## Requirements @@ -41,11 +33,25 @@ Then authenticate your CLI session with Viam using one of the following options: {{< table >}} {{% tablestep number=1 %}} -**Build your single page application** using your preferred framework like React, Vue, Angular, or others. -Your application should be built and ready for deployment, with all assets compiled into a distributable format. +**Build your application** using your preferred framework like React, Vue, Angular, or others. +While you're developing use any machine's credentials. +For deploying your app you must add code to read the machine API key from your browsers local storage: -TODO: cover dev process -TODO: how do you connect to the machine / how do you access the api key? +```ts {class="line-numbers linkable-line-numbers" data-line=""} +import Cookies from "js-cookie"; + +let apiKeyId = ""; +let apiKeySecret = ""; +let hostname = ""; +let machineId = ""; + +machineId = window.location.pathname.split("/")[2]; +({ + id: apiKeyId, + key: apiKeySecret, + hostname: hostname, +} = JSON.parse(Cookies.get(machineId)!)); +``` {{% /tablestep %}} {{% tablestep number=2 %}} @@ -110,44 +116,54 @@ TODO: how do you connect to the machine / how do you access the api key? The `applications` field is an array of application objects with the following properties: -| Property | Type | Description | -| ------------ | ------ | ------------------------------------------------------------------------------------------------- | -| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [](/operate/reference/naming-modules). | +| Property | Type | Description | +| ------------ | ------ | ----------- | +| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [](/operate/reference/naming-modules#valid-application-identifiers). | | `type` | string | The type of application (currently only `"single_machine"` is supported). | | `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example:

  • "dist/index.html": Static content rooted at the `dist` directory
  • "dist/foo.html": Static content rooted at the `dist` directory, with `foo.html` as the entry point
  • "dist/": Static content rooted at the `dist` directory (assumes `dist/index.html` exists)
  • "dist/bar/foo.html": Static content rooted at `dist/bar` with `foo.html` as the entry point
| {{% /tablestep %}} {{% tablestep number=3 %}} +**Register your module** with Viam: + +{{< tabs >}} +{{% tab name="Template" %}} -**Package your app into a module and upload it** to the Viam Registry: +```sh {class="command-line" data-prompt="$" data-output="3-10"} +viam module create --name="app-name" --public-namespace="namespace" +``` -TODO: first command doesn't make sense -don't use module generate +{{% /tab %}} +{{% tab name="Example" %}} ```sh {class="command-line" data-prompt="$" data-output="3-10"} -viam module build local -viam module upload module.tar.gz --platform=any +viam module create --name="air-quality" --public-namespace="naomi" ``` -TODO: the upload command requires platform & version - is that no longer the case? +{{% /tab %}} +{{< /tabs >}} + +{{% /tablestep %}} +{{% tablestep number=4 %}} -For subsequent updates you can use: +**Package your static files and your meta.json file and upload them** to the Viam Registry: -```sh {class="command-line" data-prompt="$" data-output="2-10"} -viam module update +```sh {class="command-line" data-prompt="$" data-output="3-10"} +tar -czvf module.tar.gz meta.json +viam module upload module.tar.gz --platform=any --version=0.0.1 ``` +For subsequent updates run these commands again with an updated version number. + {{% /tablestep %}} {{< /table >}} ## Accessing your Single Page App -Once your module with the application configuration is uploaded, your application will be available at: - -TODO: any extra steps? +After uploading your module with the application configuration, your application will be available at: ``` -https://your-app-name.your-public-namespace.viamapps.com +https://your-app-name_your-public-namespace.viamapplications.com ``` Users will be prompted to authenticate with their Viam credentials before accessing your application: @@ -158,11 +174,15 @@ Users will be prompted to authenticate with their Viam credentials before access 1. User is redirected to `your-app-name_your-public-namespace.viamapplications.com/machine/{machine-id}` 1. Your application is rendered with access to the selected machine +## Example + +For an example see [Monitor Air Quality with a Fleet of Sensors](/tutorials/control/air-quality-fleet/). + ## Limitations - Single page apps currently only support single-machine applications - All modules with apps must have public visibility -- There is no versioning or separate deploy step; the page will always render the latest version +- There is no separate deploy step; the page will always render the latest version - Browsers with cookies disabled are not supported ## Security Considerations @@ -171,41 +191,3 @@ Users will be prompted to authenticate with their Viam credentials before access - Avoid uploading sensitive information in your application code or assets - API keys and secrets are stored in the browser's localStorage or sessionStorage - Single page apps authenticate users with FusionAuth - -## Example - -Here's a complete example of creating and uploading a simple React application as a Viam Single Page App: - -```bash -# Create a new React app -npx create-react-app my-viam-app -cd my-viam-app - -# Build the app -npm run build - -# Create a module with the app -viam module create --name my-viam-app --public-namespace your-namespace - -# Edit meta.json to add the application configuration -# Add the following to meta.json: -# "visibility": "public", -# "applications": [ -# { -# "name": "my-app", -# "type": "web", -# "entrypoint": "build/index.html" -# } -# ] - -# Copy the build directory to the module directory -cp -r build/ path/to/module/ - -# Build and upload the module -viam module build local -viam module upload module.tar.gz -``` - -After the module is approved, your application will be available at `https://my-app.your-public-namespace.viamapps.com`. - -https://github.com/bashar-515/sample-app diff --git a/docs/tutorials/control/air-quality-fleet.md b/docs/tutorials/control/air-quality-fleet.md index 0bea49f7c6..a892e69b1a 100644 --- a/docs/tutorials/control/air-quality-fleet.md +++ b/docs/tutorials/control/air-quality-fleet.md @@ -20,297 +20,137 @@ cost: 200 # 2. The reader can identify when to use fragments and evaluate when it is worth using fragments. # The reader can create their own fragments for their projects and knows what to include and exclude from them. # 3. The reader recognizes how permissions enable the management of data for a business across multiple customers while providing each customer access to their own data. +# 4. The reader can deploy custom frond ends that end users can use to operate their machines. --- -In this tutorial you will use a fleet of devices to collect air quality data from different places and display the most recent readings from each device in a custom viewing dashboard. +In this tutorial you will learn how to set up a fleet of devices for yourself or third parties to collect air quality data. +You will then create a web app that shows the most recent reading for any device a user has access to. {{< alert title="Learning Goals" color="info" >}} By completing this project, you will learn to: -- Configure a fleet of identical machines +- Configure a fleet of machines - Organize your fleet using {{< glossary_tooltip term_id="location" text="locations" >}} - Collect and sync data from multiple machines -- Use the Viam TypeScript SDK to query sensor data and create a custom dashboard -- Use API keys to provide access to different groups of machines +- Use the Viam TypeScript SDK to query sensor data +- Create a custom dashboard that you and third parties can use to view data for their respective machines. {{< /alert >}} -![Air quality dashboard in a web browser with PM2.5 readings from three different sensor machines displayed.](/tutorials/air-quality-fleet/three-sensor-dash-wide.png) +{{}} ## Requirements -You can complete this tutorial using any number of air quality sensing machines. +You can create one or more machines to measure air quality. +For each machine, you need the following hardware: -For each machine, you will need the following hardware: - -- [SDS011 Nova PM sensor](https://www.amazon.com/SDS011-Quality-Detection-Conditioning-Monitor/dp/B07FSDMRR5) +- one or more [SDS011 Nova PM sensors](https://www.amazon.com/SDS011-Quality-Detection-Conditioning-Monitor/dp/B07FSDMRR5) - If you choose to use a different air quality sensor, you may need to [create your own module](/operate/get-started/other-hardware/) implementing the [sensor API](/operate/reference/components/sensor/#api) for your specific hardware. - A single-board computer (SBC) [capable of running `viam-server`](https://docs.viam.com/installation/) - An appropriate power supply -Make sure all of your sensors are wired to your SBC before starting this tutorial. - -## Decide how you will organize your fleet - -Before you start connecting your devices to the Viam app, you'll need to decide how you want to group your devices. - -In the Viam app, {{< glossary_tooltip term_id="machine" text="machines" >}} are grouped into _locations_, and locations are grouped into _organizations_: - -- Each location can represent either a physical location or some other conceptual grouping. -- An organization is the highest level grouping, and often contains all the locations (and machines) of an entire company. - -These groupings allow you to manage permissions; you can grant a user access to an individual machine, to all the machines in a location, or to everything in an entire organization. -You choose how to group your machines. - -{{}} - -
- -For more information, see [Fleet Management](/manage/reference/organize/). - -### Example - -Imagine you create an air quality monitoring company called Pollution Monitoring Made Simple. -Anyone can sign up and order one of your sensing machines. -When a new customer signs up, you assemble a new machine with a sensor, SBC, and power supply. - -Before shipping the sensor machine to your new client, you connect the machine to the Viam app and configure it. -To manage all your company's air quality sensing machines together, you create one organization called Pollution Monitoring Made Simple. -Inside that organization, you create a location for each customer. -You have some individual customers, for example Antonia, who have a sensor machine in their home, or perhaps one inside and one outside. -You have other customers who are businesses, for example RobotsRUs, who have two offices, one in New York and one in Oregon, with multiple sensor machines in each. -RobotsRUs wants to separate their sensor data by physical location, so you create a location for RobotsRUs and then create sub-locations to group their New York sensor machines and their Oregon machines. - -When you grant Antonia access to her location, she will be able to view data from the air sensors at her home. -When you grant RobotsRUs access to their location, they will be able to view data from all of their sub-locations, or they can choose to spin up a dashboard showing data from only one sub-location at a time. -You, as the organization owner, will be able to manage any necessary configuration changes for all air sensing machines in all locations created within the Pollution Monitoring Made Simple organization. - -{{}} - -### Organize your fleet - -For this tutorial, we will walk through how to set up your fleet based on the example above. -You can choose to manage your fleet of machines differently based on what makes sense for your use case; if you're only configuring one or two sensors for personal use, feel free to add all your machines to one location and skip to the [next section](#connect-your-machines-to-the-viam-app). - -1. Navigate to the [Viam app](https://app.viam.com) in a web browser. - Create an account and log in. -1. Click the dropdown in the upper-right corner of the **FLEET** page and use the **+** button to create a new organization for your air quality machine company. - Name the organization and click **Create**. -1. Click **FLEET** in the upper-left corner of the page and click **LOCATIONS**. - A new location called `First Location` is automatically generated for you. - Rename it so you can use it for Antonia's machines: +## Set up one device for development - Use the **...** menu next to edit the location name to `Antonia's Home`, then click **Save**. +In this section we'll set up one air sensing machine as our development device. -1. Now, create a separate location for RobotsRUs: +{{< table >}} +{{% tablestep number=1 %}} - On the left side of the **LOCATIONS** page, click the **Add location** button. - Type in `RobotsRUs` and click **Add**. +Navigate to the [Viam app](https://app.viam.com) in a web browser. +Create an account and log in. -1. Add sub-locations to the RobotsRUs location to group the machines at each of their offices: +{{% /tablestep %}} +{{% tablestep number=2 %}} - Add a new location called `Oregon Office` using the same **Add location** button. - Then, find the **New parent location** dropdown on the Oregon Office page. - Select **RobotsRUs** and click **Change**. +Click the dropdown in the upper-right corner of the **FLEET** page and use the **+** button to create a new organization for your air quality machine company. +Name the organization and click **Create**. - Repeat to add the New York office: Add a new location called `New York Office`, then change its parent location to **RobotsRUs**. +{{% /tablestep %}} +{{% tablestep number=3 %}} - {{}} +Click **FLEET** in the upper-left corner of the page and click **LOCATIONS**. +A new location called `First Location` is automatically generated for you. +Use the **...** menu next to edit the location name to `Development`, then click **Save**. - In the next section, you'll add machines to the locations. +{{% /tablestep %}} +{{% tablestep number=4 %}} -## Connect your machines to the Viam app +Connect a PM sensor to a USB port on the machine's SBC. +Then connect your device to power. -With your organizational structure in place, let's add some machines: +If the computer does not already have a Viam-compatible operating system installed, follow the [operating system setup section of the Quickstart guide](/operate/get-started/setup/) to install a compatible operating system. +You _do not_ need to follow the "Install `viam-server`" section; you will do that in the next step! -1. Connect your first single-board computer to power. - For this tutorial, we'll treat this as the machine for our first customer, Antonia. - If the computer does not already have a Viam-compatible operating system installed, follow the [operating system setup section of the Quickstart guide](/operate/get-started/setup/) to install a compatible operating system. - You _do not_ need to follow the "Install `viam-server`" section; you will do that in the next step! +Enable serial communication so that the SBC can communicate with the air quality sensor. +For example, if you are using a Raspberry Pi, SSH to it and [enable serial communication in `raspi-config`](/operate/reference/prepare/rpi-setup/#enable-communication-protocols). -1. Enable serial communication so that the SBC can communicate with the air quality sensor. - For example, if you are using a Raspberry Pi, SSH to it and [enable serial communication in `raspi-config`](/operate/reference/prepare/rpi-setup/#enable-communication-protocols). +{{% /tablestep %}} +{{% tablestep number=5 %}} -1. Click **Antonia's Home** in the left navigation menu to navigate to that location's page. - In the **New machine** field near the top-right corner of the screen, type in a name for the machine, such as `Home Air Quality Sensor`, and click **Add machine**. - -1. You'll be taken to the machine details page and prompted to set up your machine part. - Click **View setup instructions**. - You can find these instructions later if you need them by clicking the part status indicator (which currently reads **Awaiting setup**). - -1. Follow the **Set up your machine part** instructions to install `viam-server` on the machine and connect it to the Viam app. - `viam-server` is the binary that runs on the single-board computer (SBC), providing functionality including sensor data collection and connection to the Viam app. - - The setup page will indicate when the machine is successfully connected. - -1. If Antonia has more than one air sensing machine, add a new machine to her location and set it up in the same way. - -This is how you set up one machine. -If you are following along for the RobotsRUs business from our example, create additional machines in each sub-location, that is, in the `Oregon Office` location and in the `New York Office` location. - -## Set up your hardware - -{{% alert title="Note" color="note" %}} -If this were a real company and you were shipping air sensing machines to customers, you would have the customer plug in power to the machine wherever they are setting it up. -Since you already installed `viam-server`, once a customer connects the machine to power and sets up wifi, the machine will automatically re-connect to the Viam app and pull any configuration updates. -{{% /alert %}} - -For each sensing machine: - -1. Connect the PM sensor to a USB port on the machine's SBC. - -1. Position your sensing machines in strategic locations, and connect them to power. - Here are some ideas for where to place sensing machines: - - - At home: - - In an outdoor location protected from weather, such as under the eaves of your home - - In the kitchen, where cooking can produce pollutants - - Anywhere you spend lots of time indoors and want to measure exposure to pollutants - - At work: - - At your desk to check your exposure throughout the day - - Near a door or window to see whether pollutants are leaking in - -## Configure your air quality sensors - -You need to [configure](/operate/get-started/supported-hardware/#configure-hardware-on-your-machine) your hardware so that each of your machines can communicate with its attached air quality [sensor](/operate/reference/components/sensor/). - -No matter how many sensing machines you use, you can configure them efficiently by using a reusable configuration block called a _{{< glossary_tooltip term_id="fragment" text="fragment" >}}_. -Fragments are a way to share and manage identical machine configurations across multiple machines. -Instead of going through all the configuration steps for each machine, you'll start by configuring just one machine and create a fragment based on that machine's configuration. -Then, you'll add the fragment to each of your machines. -With all your machines configured using the same fragment, if you need to update the config in the future, you can just update the fragment and all machines will automatically get the update. - -{{< alert title="Note" color="note" >}} -If this was a real company, adding the fragment to each individual machine would quickly become tiring. -We're showing you how to do this manually as a learning device. -Once you understand how to configure machines and use fragments, you can use [Provisioning](/manage/fleet/provision/setup/) to automatically set up your devices. -{{< /alert >}} - -### Configure your first machine - -#### Configure the sensor - -1. Navigate to the **CONFIGURE** tab of the machine details page in the [Viam app](https://app.viam.com) for your first machine. -2. Click the **+** (Create) button and click **Component or service** from the dropdown. - Click **sensor**, then search for `sds011` and click **sds001:v1** from the results. -3. Click **Add module**. - This adds the {{< glossary_tooltip term_id="module" text="module" >}} that provides the sensor model that supports the specific hardware we are using for this tutorial. - - ![The Add Module button that appears after you click the model name.](/tutorials/air-quality-fleet/add-sensor-module.png) - -4. Give the sensor a name like `PM_sensor` and click **Create**. -5. In the newly created **PM_sensor** card, replace the contents of the attributes box (the empty curly braces `{}`) with the following: - - ```json {class="line-numbers linkable-line-numbers"} - { - "usb_interface": "" - } - ``` +Add a new [_{{< glossary_tooltip term_id="machine" text="machine" >}}_](/operate/get-started/basics/#what-is-a-machine) using the button in the top right corner of the **LOCATIONS** tab in the app. +Follow the **Set up your machine part** instructions to install `viam-server` on the machine and connect it to the Viam app. -6. Now you need to figure out which port your sensor is connected to on your board. - SSH to your board and run the following command: +When your machine shows as connected, continue to the next step. - ```sh{class="command-line" data-prompt="$"} - ls /dev/serial/by-id - ``` +{{% /tablestep %}} +{{% tablestep number=6 %}} - This should output a list of one or more USB devices attached to your board, for example `usb-1a86_USB_Serial-if00-port0`. - If the air quality sensor is the only device plugged into your board, you can be confident that the only device listed is the correct one. - If you have multiple devices plugged into different USB ports, you may need to choose one path and test it, or unplug something, to figure out which path to use. +Navigate to the **CONFIGURE** tab of the machine, click the **+** button and select **Component or service**. +Click **sensor**, then search for `sds011` and add the **sds001:v1** {{< glossary_tooltip term_id="module" text="module" >}}. +Name the sensor `PM_sensor` and click **Create**. - Now that you have found the identifier, put the full path to the device into your config, for example: +{{}} - ```json {class="line-numbers linkable-line-numbers"} - { - "usb_interface": "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0" - } - ``` +{{% /tablestep %}} +{{% tablestep number=7 %}} -7. Save the config. - Your machine config should now resemble the following: - - ![Configure tab showing PM sensor and the sensor module configured.](/tutorials/air-quality-fleet/configured-sensor.png) - -#### Configure data capture and sync - -You have configured the sensor so the board can communicate with it, but sensor data is not yet being saved anywhere. -Viam's [data management service](/data-ai/capture-data/capture-sync/) lets you capture data locally from each sensor and then sync it to the cloud where you can access historical sensor data and see trends over time. -Once you configure the rest of your sensing machines, you'll be able to remotely access data from all sensors in all locations, and when you're ready, you can give customers [access](/manage/manage/access/) to the data from the sensors in their locations. - -Configure data capture and sync as follows: - -1. Click the **+** (Create) button and click **Component or service** from the dropdown. -2. Click **data management**. -3. Give your data manager a name such as the auto-populated name `data_manager-1` and click **Create**. -4. Toggle **Syncing** to the on position. - Set the sync interval to `0.05` minutes so that data syncs to the cloud every 3 seconds. - You can change the interval if you like, just don't make it too long or you will have to wait a long time before you see your data! -5. Let's add a tag to all your data so that you can query data from all your air quality sensors more easily in later steps. - In the **Tags** field, type `air-quality` and click **+ Tag: air-quality** when it appears to create a new tag. - This tag will now automatically be applied to all data collected by this data manager. -6. Now the data management service is available to any components on your machine, and you can set up data capture on the sensor: -7. On your **PM_sensor** card, click **Add method**. -8. From the **Type** dropdown, select **Readings**. -9. Set the **Frequency** to `0.1` readings per second. - This will capture air quality data once every ten seconds. - It is useful to capture data frequently for testing purposes, but you can always change this frequency later since you probably don't need to capture data this frequently all day forever. -10. Save the config. - -### Create a fragment - -{{% alert title="Note" color="note" %}} -If you are only using one air quality sensing machine for this tutorial, you do not need to create or use fragments, since fragments are useful only when configuring multiple machines. -You can skip to [Test your sensors](#test-your-sensors). -{{% /alert %}} +In the newly created **PM_sensor** card, replace the contents of the attributes box (the empty curly braces `{}`) with the following: -While you configured your machine with the builder UI, the Viam app generated a JSON configuration file with all your parameters. -This is the file that tells `viam-server` what resources are available to it and how everything is connected. -Click **JSON** in the upper-left corner of the **CONFIGURE** tab to view the generated JSON file. -You can manually edit this file instead of using the builder UI if you are familiar with JSON. +```json {class="line-numbers linkable-line-numbers"} +{ + "usb_interface": "" +} +``` -In any case, now that the JSON is generated, you are ready to create a {{< glossary_tooltip term_id="fragment" text="fragment" >}}: +{{% /tablestep %}} +{{% tablestep number=8 %}} -1. Select and copy the entire contents of the JSON config. -2. Navigate to the **FLEET** page and go to the [**FRAGMENTS** tab](https://app.viam.com/fragments). -3. Click **Create fragment** and change your fragment's name by clicking on it. We used the name `air-sensing-machine`. -4. Replace the empty curly braces `{}` with the config you copied from your machine. -5. Click **Save**. -6. Now, you can actually delete the entire config from your machine! - In the next section, you will replace it with the fragment you just created so that it gets updated alongside all your other machines when you update the fragment in the future. +To figure out which port your sensor is connected to on your board, SSH to your board and run the following command: - Navigate back to your machine's **CONFIGURE** tab, select **JSON** mode, and delete the entire contents of the config. - When you try to save, you'll get an invalid JSON error because it can't be empty. - Put in a set of curly braces `{}` and then save the config successfully. +```sh{class="command-line" data-prompt="$"} +ls /dev/serial/by-id +``` -### Add the fragment to all your machines +This should output a list of one or more USB devices attached to your board, for example `usb-1a86_USB_Serial-if00-port0`. +If the air quality sensor is the only device plugged into your board, you can be confident that the only device listed is the correct one. +If you have multiple devices plugged into different USB ports, you may need to choose one path and test it, or unplug something, to figure out which path to use. -Add the fragment you just created to each of your machines including the first one: +Now that you have found the identifier, put the full path to the device into your config, for example: -1. Click the **+** button, then click **Insert fragment** in the dropdown menu. -2. Search for and click the name of your fragment, for example `air-sensing-machine`. +```json {class="line-numbers linkable-line-numbers"} +{ + "usb_interface": "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0" +} +``` - ![The insert fragment UI.](/tutorials/air-quality-fleet/add-fragment.png) +{{% /tablestep %}} +{{% tablestep number=9 %}} -3. Click **Insert fragment**. - The module, sensor, and data manager will appear in your config. -4. Save the config. -5. Repeat these steps on the machine details page for each of your air quality sensing machines. +Save the config. -## Test your sensors +{{}} -Now that all your hardware is configured, it's a good idea to make sure readings are being gathered by the sensors and sent to the cloud before proceeding with the tutorial. -For each machine: +{{% /tablestep %}} +{{% tablestep number=10 %}} -1. Go to the machine details page in the [Viam app](https://app.viam.com.) and navigate to the **CONTROL** tab. -2. Within the **Sensors** section, click **Get Readings** for the **PM_sensor**. - If the sensor software and hardware is working, you should see values populate the **Readings** column. +On your sensor configuration panel, click on the **TEST** panel to check that you are getting readings from your sensor. - ![The sensor readings on the control tab.](/tutorials/air-quality-fleet/get-readings.png) +{{}} - If you do not see readings, check the **LOGS** tab for errors, double-check that serial communication is enabled on the single board computer, and check that the `usb_interface` path is correctly specified (click below). +If you do not see readings, check the **LOGS** tab for errors, double-check that serial communication is enabled on the single board computer, and check that the `usb_interface` path is correctly specified (click below). - {{< expand "Click here for usb_interface troubleshooting help" >}} +{{< expand "Click here for usb_interface troubleshooting help" >}} If you only have one USB device plugged into each of your boards, the `usb_interface` value you configured in the sensor config is likely (conveniently) the same for all of your machines. If not, you can use [fragment overwrite](/manage/fleet/reuse-configuration/#modify-fragment-settings-on-a-machine) to modify the value on any machine for which it is different: @@ -343,302 +183,338 @@ If not, you can use [fragment overwrite](/manage/fleet/reuse-configuration/#modi {{< /expand >}} -## Test data sync +{{% /tablestep %}} +{{% tablestep number=11 %}} + +Click **+** and add the **data management** service. +Toggle **Syncing** to the on position and set the sync interval to `0.05` minutes so that data syncs to the cloud every 3 seconds. + +Add a tag to all your data so that you can query data from all your air quality sensors more easily in later steps. +In the **Tags** field, type `air-quality` and click **+ Tag: air-quality** when it appears to create a new tag. +This tag will now automatically be applied to all data collected by this data manager. + +{{% /tablestep %}} +{{% tablestep number=12 %}} + +On the **PM_sensor** panel, click **Add method** to add data capture. -Next, check that data is being synced from your sensors to the cloud: +- **Type** :**Readings**. +- **Frequency**: `0.1` -1. Open your [**DATA** page](https://app.viam.com/data). -2. Click the **Sensors** tab within the data page. -3. If you have sensor data coming from machines unrelated to this project, use the filters on the left side of the page to view data from only your air quality sensors. - Click the **Tags** dropdown and select the `air-quality` tag you applied to your data. - You can also use these filters to show the data from one of your air quality sensors at a time by typing a machine name into the **Machine name** box and clicking **Apply** in the lower-left corner. +Save the config. - ![The sensor readings that have synced to the DATA page.](/tutorials/air-quality-fleet/synced-data.png) +You can check that your sensor data is being synced by clicking on the **...** menu and clicking **View captured data**. -Once you've confirmed that data is being collected and synced correctly, you're ready to start building a dashboard to display the data. -If you'd like to graph your data using a Grafana dashboard, try our [Visualize Data with Grafana tutorial](/tutorials/services/visualize-data-grafana/). -If you'd like to create your own customizable dashboard using the Viam TypeScript, continue with this tutorial. +{{% /tablestep %}} +{{< /table >}} -## Code your custom TypeScript dashboard +Congratulations, if you made it this far, you now have a functional air sensing machine. +Let's create a dashboard for its measurements next. + +## Create a dashboard The [Viam TypeScript SDK](https://ts.viam.dev/) allows you to build custom web interfaces to interact with your machines. For this project, you'll use it to build a page that displays air quality sensor data for a given location. -You'll host the website locally on your personal computer, and view the interface in a web browser on that computer. +You'll host the website on Viam Apps. -As you'll find out in the [authentication step](#authenticate-your-code-to-your-viam-app-location), you can set each customer up with credentials to access the data from only their location, or you can create a dashboard showing data from all sensors in your entire organization. +The full code is available for reference on [GitHub](https://github.com/viam-labs/air-quality-fleet/blob/main/main.ts). -![The air quality dashboard you'll build. This one has PM2.5 readings from two different sensor machines displayed, and a key with categories of air quality.](/tutorials/air-quality-fleet/two-sensors.png) +{{< alert title="Tip" color="tip" >}} +If you'd like to graph your data using a Grafana dashboard, try our [Visualize Data with Grafana tutorial](/tutorials/services/visualize-data-grafana/) next. +{{< /alert >}} ### Set up your TypeScript project Complete the following steps on your laptop or desktop. You don't need to install or edit anything else on your machine's single-board computer (aside from `viam-server` which you already did); you'll be running the TypeScript code from your personal computer. -1. Make sure you have the latest version of [Node.JS](https://nodejs.org/en) installed on your computer. -1. Install the Viam TypeScript SDK by running the following command in your terminal: - - ```sh {class="command-line" data-prompt="$"} - npm install --save @viamrobotics/sdk - ``` - -1. Create a directory on your laptop or desktop for your project. - Name it aqi-dashboard. - -1. Create a file in your aqi-dashboard folder and name it package.json. - The package.json file holds necessary metadata about your project. - Paste the following contents into it: - - ```json {class="line-numbers linkable-line-numbers"} - { - "name": "air-quality-dashboard", - "description": "A dashboard for visualizing data from air quality sensors.", - "scripts": { - "start": "esbuild ./main.ts --bundle --outfile=static/main.js --servedir=static --format=esm", - "test": "echo \"Error: no test specified\" && exit 1" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "esbuild": "*" - }, - "dependencies": { - "@viamrobotics/sdk": "^0.13.0", - "bson": "^6.6.0" - } - } - ``` +{{< table >}} +{{% tablestep number=1 %}} + +Make sure you have the latest version of [Node.JS](https://nodejs.org/en) installed on your computer. + +{{% /tablestep %}} +{{% tablestep number=2 %}} + +Create a directory on your laptop or desktop for your project. +Name it aqi-dashboard. + +{{% /tablestep %}} +{{% tablestep number=3 %}} + +Create a file in your aqi-dashboard folder and name it package.json. +The package.json file holds necessary metadata about your project. +Paste the following contents into it: + +```json {class="line-numbers linkable-line-numbers"} +{ + "name": "air-quality-dashboard", + "description": "A dashboard for visualizing data from air quality sensors.", + "scripts": { + "start": "esbuild ./main.ts --bundle --outfile=static/main.js --servedir=static --format=esm", + "build": "esbuild ./main.ts --bundle --outfile=static/main.js --format=esm" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "esbuild": "*" + }, + "dependencies": { + "@viamrobotics/sdk": "^0.42.0", + "bson": "^6.6.0", + "js-cookie": "^3.0.5" + } +} +``` {{% alert title="Fun fact" color="info" %}} + The `--format=esm` flag in the `"start"` script is important because the ECMAScript module format is necessary to support the BSON dependency this project uses for data query formatting. If you don't know what the proceeding sentence means, don't worry about it; just copy-paste the JSON above and it'll work. -{{% /alert %}} -### Authenticate your code to your Viam app location - -Your TypeScript code requires an API key to establish a connection to your machines. -You can set up credentials to access data from all the sensor machines in your organization, or from just one location. -These API keys only need [**Operator** permissions](/manage/manage/rbac/). - -In our example you could create a dashboard for Antonia with an API key to see the data from her location, and create a separate dashboard for RobotsRUs with a different API key to access the data from their location. -If RobotsRUs wanted to separate their dashboards by sub-locations, you could set up API keys for RobotsRUs to access data for each of their sub-locations separately, or you could modify the example code to filter data by location name. - -You can then either deploy each dashboard on a web server you manage, or add a web server on one machine per customer that hosts the dashboard for the respective customer so that they can access their data on their local network. -We leave this step to the reader. +{{% /alert %}} -The following instructions describe how to set up an API key for one location. +{{% /tablestep %}} +{{% tablestep number=4 %}} -1. Create another file inside the aqi-dashboard folder and name it main.ts. - Paste the following code into main.ts: +Install the project's dependencies by running the following command in your terminal: - ```typescript {class="line-numbers linkable-line-numbers"} - // Air quality dashboard +```sh {class="command-line" data-prompt="$"} +npm install +``` - import * as VIAM from "@viamrobotics/sdk"; - import { BSON } from "bson"; +{{% /tablestep %}} +{{< /table >}} - async function main() { - const opts: VIAM.ViamClientOptions = { - credential: { - type: "api-key", - // Key with location operator permissions - // Replace (including angle brackets) - payload: "", - // Replace (including angle brackets) - authEntity: "", - }, - }; +### Authenticate your code to your Viam app location - const orgID: string = ""; // Replace - const locationID: string = ""; // Replace +Your TypeScript code requires an API key to establish a connection to your machines. +In the final dashboard, these will be provided to your webapp through the local storage of your browser. +For development purposes, you will use an API key for your development machine. - // +{{< table >}} +{{% tablestep number=1 %}} - // - } +Create another file inside the aqi-dashboard folder and name it main.ts. +Paste the following code into main.ts: - // +```typescript {class="line-numbers linkable-line-numbers"} +// Air quality dashboard - main().catch((error) => { - console.error("encountered an error:", error); - }); - ``` +import * as VIAM from "@viamrobotics/sdk"; +import { BSON } from "bson"; +import Cookies from "js-cookie"; -1. Now you need to get the API key and the {{< glossary_tooltip term_id="organization" text="organization" >}} and {{< glossary_tooltip term_id="location" text="location" >}} IDs to replace the placeholder strings in the code you just pasted. +let apiKeyId = ""; +let apiKeySecret = ""; +let hostname = ""; +let machineId = ""; - In the [Viam app](https://app.viam.com), navigate to the location page for the location containing your air quality machines. +async function main() { + const opts: VIAM.ViamClientOptions = { + serviceHost: "https://app.viam.com", + credentials: { + type: "api-key", + payload: apiKeySecret, + authEntity: apiKeyId, + }, + }; - ![The location secret with a Copy button next to it.](/tutorials/air-quality-fleet/loc-secret-button.png) + // - Copy the **Location ID** and paste it into your code in place of ``, so that the line resembles `const orgID: string = "abcde12345"`. + // +} -1. Use the dropdown menu in the upper-right corner of the page to navigate to your organization settings page. - Copy the **Organization ID** found under **Details** near the top of the page. - Paste it in place of `` in your code. +// -1. Under the **API Keys** heading, click **Generate Key**. +document.addEventListener("DOMContentLoaded", async () => { + machineId = window.location.pathname.split("/")[2]; + ({ + id: apiKeyId, + key: apiKeySecret, + hostname: hostname, + } = JSON.parse(Cookies.get(machineId)!)); -1. Name your key something such as `air-sensors-key`. + main().catch((error) => { + console.error("encountered an error:", error); + }); +}); +``` -1. Select **Entity** and choose the location you have all your air quality sensing machines in. +{{% /tablestep %}} +{{% tablestep number=2 %}} -1. Set the **Role** to **Owner**, then click **Generate key**. +To test the dashboard with your development machine, you can temporarily set your machine's API key, API key ID and machine ID at the top of the `main()` function. -1. Copy the ID and corresponding key you just created and paste them in place of `` and `` in your code. - For example, you'll now have something of the form +You can obtain your API key and API key ID from your machines **CONNECT** tab. +You can copy the machine ID using the **...** menu at the top right and clicking **Copy machine ID**. - ```json {class="line-numbers linkable-line-numbers"} - authEntity: '1234abcd-123a-987b-1234567890abc', - payload: 'abcdefg987654321abcdefghi' - ``` +{{% snippet "secret-share.md" %}} - {{% snippet "secret-share.md" %}} +{{% /tablestep %}} +{{< /table >}} ### Add functionality to your code -1. Now that you have the API key and org and location IDs, you are ready to add code that establishes a connection from the computer running the code to the Viam Cloud where the air quality sensor data is stored. - You'll create a Viam `dataClient` instance which accesses all the data in your location, and then query this data to get only the data tagged with the `air-quality` tag you applied with your data service configuration. - The following code also queries the data for a list of the machines that have collected air quality data so that later, you can make a dashboard that has a place for the latest data from each of them. - - Paste the following code into the main function of your main.ts script, directly after the `locationID` line, in place of `// `: - - ```typescript {class="line-numbers linkable-line-numbers"} - // Instantiate data_client and get all - // data tagged with "air-quality" from your location - const client = await VIAM.createViamClient(opts); - const myDataClient = client.dataClient; - const query = { - $match: { - tags: "air-quality", - location_id: locationID, - organization_id: orgID, - }, - }; - const match = { $group: { _id: "$robot_id" } }; - // Get a list of all the IDs of machines that have collected air quality data - const BSONQueryForMachineIDList = [ - BSON.serialize(query), - BSON.serialize(match), - ]; - let machineIDs: any = await myDataClient?.tabularDataByMQL( - orgID, - BSONQueryForMachineIDList, - ); - // Get all the air quality data - const BSONQueryForData = [BSON.serialize(query)]; - let thedata: any = await myDataClient?.tabularDataByMQL( - orgID, - BSONQueryForData, - ); - ``` - -1. For this project, your dashboard will display the average of the last five readings from each air sensor. - You need a function to calculate that average. - The data returned by the query is not necessarily returned in order, so this function must put the data in order based on timestamps before averaging the last five readings. - - Paste the following code into main.ts after the end of your main function, in place of `// `: - - ```typescript {class="line-numbers linkable-line-numbers"} - // Get the average of the last few readings from a given sensor - async function getLastFewAv(alltheData: any[], machineID: string) { - // Get just the data from this machine - let thedata = new Array(); - for (const entry of alltheData) { - if (entry.robot_id == machineID) { - thedata.push({ - PM25: entry.data.readings["pm_2_5"], - time: entry.time_received, - }); - } - } - - // Sort the air quality data from this machine - // by timestamp - thedata = thedata.sort(function (a, b) { - let x = a.time.toString(); - let y = b.time.toString(); - if (x < y) { - return -1; - } - if (x > y) { - return 1; - } - return 0; - }); - - // Add up the last 5 readings collected. - // If there are fewer than 5 readings, add all of them. - let x = 5; // The number of readings to average over - if (x > thedata.length) { - x = thedata.length; - } - let total = 0; - for (let i = 1; i <= x; i++) { - const reading: number = thedata[thedata.length - i].PM25; - total += reading; - } - // Return the average of the last few readings - return total / x; - } - ``` - -1. Now that you've defined the function to sort and average the data for each machine, you're done with all the `dataClient` code. - The final piece you need to add to this script is a way to create some HTML to display data from each machine in your dashboard. - - Paste the following code into the main function of main.ts, in place of `// `: - - ```typescript {class="line-numbers linkable-line-numbers"} - // Instantiate the HTML block that will be returned - // once everything is appended to it - let htmlblock: HTMLElement = document.createElement("div"); - - // Display the relevant data from each machine to the dashboard - for (const mach of machineIDs) { - let insideDiv: HTMLElement = document.createElement("div"); - let avgPM: number = await getLastFewAv(thedata, mach._id); - // Color-code the dashboard based on air quality category - let level: string = "blue"; - switch (true) { - case avgPM < 12.1: { - level = "good"; - break; - } - case avgPM < 35.5: { - level = "moderate"; - break; - } - case avgPM < 55.5: { - level = "unhealthy-sensitive"; - break; - } - case avgPM < 150.5: { - level = "unhealthy"; - break; - } - case avgPM < 250.5: { - level = "very-unhealthy"; - break; - } - case avgPM >= 250.5: { - level = "hazardous"; - break; - } - } - // Create the HTML output for this machine - insideDiv.className = "inner-div " + level; - insideDiv.innerHTML = - "

" + - mach._id + - ": " + - avgPM.toFixed(2).toString() + - " μg/m3

"; - htmlblock.appendChild(insideDiv); - } - - // Output a block of HTML with color-coded boxes for each machine - return document.getElementById("insert-readings").replaceWith(htmlblock); - ``` - -The full code is available for reference on [GitHub](https://github.com/viam-labs/air-quality-fleet/blob/main/main.ts). +{{< table >}} +{{% tablestep number=1 %}} + +Now that you have the connection code, you are ready to add code that establishes a connection from the computer running the code to the Viam Cloud where the air quality sensor data is stored. +You'll first create a client to obtain the organization and location ID. Then you'll get a `dataClient` instance which accesses all the data in your location, and then query this data to get only the data tagged with the `air-quality` tag you applied with your data service configuration. +The following code also queries the data for a list of the machines that have collected air quality data so that later, depending on the API key used with the code, your dashboard can show the data from any number of machines. + +Paste the following code into the main function of your main.ts script, directly after the `locationID` line, in place of `// `: + +```typescript {class="line-numbers linkable-line-numbers"} +// Instantiate data_client and get all +// data tagged with "air-quality" from your location +const client = await VIAM.createViamClient(opts); +const machine = await client.appClient.getRobot(machineId); +const locationID = machine?.location; +const orgID = (await client.appClient.listOrganizations())[0].id; + +const myDataClient = client.dataClient; +const query = { + $match: { + tags: "air-quality", + location_id: locationID, + organization_id: orgID, + }, +}; +const match = { $group: { _id: "$robot_id" } }; +// Get a list of all the IDs of machines that have collected air quality data +const BSONQueryForMachineIDList = [ + BSON.serialize(query), + BSON.serialize(match), +]; +let machineIDs: any = await myDataClient?.tabularDataByMQL( + orgID, + BSONQueryForMachineIDList, +); +// Get all the air quality data +const BSONQueryForData = [BSON.serialize(query)]; +let measurements: any = await myDataClient?.tabularDataByMQL( + orgID, + BSONQueryForData, +); +``` + +{{% /tablestep %}} +{{% tablestep number=2 %}} + +For this project, your dashboard will display the average of the last five readings from each air sensor. +You need a function to calculate that average. +The data returned by the query is not necessarily returned in order, so this function must put the data in order based on timestamps before averaging the last five readings. + +Paste the following code into main.ts after the end of your main function, in place of `// `: + +```typescript {class="line-numbers linkable-line-numbers"} +// Get the average of the last five readings from a given sensor +async function getLastFewAv(all_measurements: any[], machineID: string) { + // Get just the data from this machine + let measurements = new Array(); + for (const entry of all_measurements) { + if (entry.robot_id == machineID) { + measurements.push({ + PM25: entry.data.readings["pm_2.5"], + time: entry.time_received, + }); + } + } + + // Sort the air quality data from this machine + // by timestamp + measurements = measurements.sort(function (a, b) { + let x = a.time.toString(); + let y = b.time.toString(); + if (x < y) { + return -1; + } + if (x > y) { + return 1; + } + return 0; + }); + + // Add up the last 5 readings collected. + // If there are fewer than 5 readings, add all of them. + let x = 5; // The number of readings to average over + if (x > measurements.length) { + x = measurements.length; + } + let total = 0; + for (let i = 1; i <= x; i++) { + const reading: number = measurements[measurements.length - i].PM25; + total += reading; + } + // Return the average of the last few readings + return total / x; +} +``` + +{{% /tablestep %}} +{{% tablestep number=3 %}} + +Now that you've defined the function to sort and average the data for each machine, you're done with all the `dataClient` code. +The final piece you need to add to this script is a way to create some HTML to display data from each machine in your dashboard. + +Paste the following code into the main function of main.ts, in place of `// `: + +```typescript {class="line-numbers linkable-line-numbers"} +// Instantiate the HTML block that will be returned +// once everything is appended to it +let htmlblock: HTMLElement = document.createElement("div"); + +// Display the relevant data from each machine to the dashboard +for (let m of machineIDs) { + let insideDiv: HTMLElement = document.createElement("div"); + let avgPM: number = await getLastFewAv(measurements, m._id); + // Color-code the dashboard based on air quality category + let level: string = "blue"; + switch (true) { + case avgPM < 12.1: { + level = "good"; + break; + } + case avgPM < 35.5: { + level = "moderate"; + break; + } + case avgPM < 55.5: { + level = "unhealthy-sensitive"; + break; + } + case avgPM < 150.5: { + level = "unhealthy"; + break; + } + case avgPM < 250.5: { + level = "very-unhealthy"; + break; + } + case avgPM >= 250.5: { + level = "hazardous"; + break; + } + } + let machineName = (await client.appClient.getRobot(m._id))?.name; + // Create the HTML output for this machine + insideDiv.className = "inner-div " + level; + insideDiv.innerHTML = + "

" + + machineName + + ": " + + avgPM.toFixed(2).toString() + + " μg/m3

"; + htmlblock.appendChild(insideDiv); +} + +// Output a block of HTML with color-coded boxes for each machine +return document.getElementById("insert-readings")?.replaceWith(htmlblock); +``` + +{{% /tablestep %}} +{{< /table >}} ### Style your dashboard @@ -773,13 +649,11 @@ If you look at line 5 of package.json, you can see that `./main.ts` } ``` - Feel free to adjust any of the colors, margins, fonts, and other specifications in style.css based on your preferences. - -## Full tutorial code +### Full tutorial code You can find all the code in the [GitHub repo for this tutorial](https://github.com/viam-labs/air-quality-fleet). -## Run the code +### Run the code 1. In a command prompt terminal, navigate to your aqi-dashboard directory. Run the following command to start up your air quality dashboard: @@ -788,7 +662,7 @@ You can find all the code in the [GitHub repo for this tutorial](https://github. npm start ``` - ![Terminal window with the command 'npm start' run inside the aqi-dashboard folder. The output says 'start' and then 'esbuild' followed by the esbuild string from the package.json file you configured. Then there's 'Local:' followed by a URL and 'Network:' followed by a different URL.](/tutorials/air-quality-fleet/terminal-url.png) + {{}} 1. The terminal should output a line such as `Local: http://127.0.0.1:8000/`. Copy the URL the terminal displays and paste it into the address bar in your web browser. @@ -797,28 +671,238 @@ You can find all the code in the [GitHub repo for this tutorial](https://github. ![Air quality dashboard in a web browser with PM2.5 readings from three different sensor machines displayed.](/tutorials/air-quality-fleet/three-sensor-dash.png) - Great work. - You've learned how to configure a fleet of machines, sync their data to one place, and pull that data into a custom dashboard using TypeScript. +Great work. +You've learned how to configure a machine and you can view its data in a custom TypeScript dashboard. + +### Deploy the app to Viam apps + +Let's deploy this dashboard so you don't have to run it locally. +This will also allow others to use the dashboard. + +{{< table >}} +{{% tablestep number=1 %}} + +**Remove any API key or IDs before continuing.** + +{{% /tablestep %}} +{{% tablestep number=2 %}} + +**Create a meta.json** in your project folder using this template: + +```json +{ + "module_id": ":air-quality", + "visibility": "public", + "url": "https://github.com/viam-labs/air-quality-fleet/", + "description": "Display air quality data from a machine", + "applications": [ + { + "name": "air-quality", + "type": "single_machine", + "entrypoint": "static/index.html" + } + ] +} +``` + +In the [Viam app](https://app.viam.com), navigate to your organization settings through the menu in upper right corner of the page. +Find the **Public namespace** and copy that string. +Replace `` with your public namespace. + +{{% /tablestep %}} +{{% tablestep number=3 %}} + +**Register your module** with Viam: + +```sh {class="command-line" data-prompt="$" data-output="3-10"} +viam module create --name="air-quality" --public-namespace="your-namespace" +``` + +{{% /tablestep %}} +{{% tablestep number=4 %}} + +**Package your static files and your meta.json file and upload them** to the Viam Registry: + +```sh {class="command-line" data-prompt="$" data-output="3-10"} +npm run build +tar -czvf module.tar.gz static meta.json +viam module upload module.tar.gz --platform=any --version=0.0.1 +``` + +For subsequent updates run these commands again with an updated version number. + +{{% /tablestep %}} +{{% tablestep number=5 %}} + +**Try your app** by navigating to: + +``` +https://air-quality_your-public-namespace.viamapplications.com +``` + +Log in and select your development machine. +Your dashboard should now load your data. + +{{% /tablestep %}} +{{< /table >}} + +## Organizing devices for third-party usage + +Imagine you create an air quality monitoring company called Pollution Monitoring Made Simple. +Anyone can sign up and order one of your sensing machines. +When a new customer signs up, you assemble a new machine with a sensor, SBC, and power supply. + +Before shipping the sensor machine to your new client, you provision the machine, so that the recipient only needs to connect the machine to their WiFi network for it to work. + +To manage all your company's air quality sensing machines together, you create one organization called Pollution Monitoring Made Simple. +An organization is the highest level grouping, and often contains all the locations (and machines) of an entire company. + +Inside that organization, you create a location for each customer. +A location can represent either a physical location or some other conceptual grouping. +You have some individual customers, for example Antonia, who has one sensor machine in her home and one outside. +You have other customers who are businesses, for example RobotsRUs, who have two offices, one in New York and one in Oregon, with multiple sensor machines in each. + +Organization and locations allow you to manage permissions: + +- When you provision Antonia's machines, you create them inside a new location called `Antonia's Home` and grant Antonia operator access to the location. + This will later allow her to view data from the air sensors at her home. +- When you provision the machines for RobotsRUs, you create a location called `RobotsRUs` and two sub-locations for `New York Office` and `Oregon Office`. + Then you create the machines in the sub-locations and grant RobotsRUs operator access to the `RobotsRUs` machines location. + +You, as the organization owner, will be able to manage any necessary configuration changes for all air sensing machines in all locations created within the Pollution Monitoring Made Simple organization. + +{{}} + +For more information, see [Fleet Management](/manage/reference/organize/) and [provisioning](/manage/fleet/provision/setup/). + +### Organize your fleet + +If you want to follow along, create the following locations: + +- `Antonia's Home` +- `RobotsRUs` + +For `RobotsRUs` crate two sublocations: + +1. Add a new location called `Oregon Office` using the same **Add location** button. +1. Then, find the **New parent location** dropdown on the Oregon Office page. +1. Select **RobotsRUs** and click **Change**. + +Repeat to add the New York office: Add a new location called `New York Office`, then change its parent location to **RobotsRUs**. + +{{}} + +## Getting machines ready for third parties + +Continuing with our ficticious company, let's assume you want to ship air sensing machines to customers as ready-to-go as possible. +In other words, you want to provision devices. + +Before an air sensing machine leaves your factory, you'd complete the following steps: + +1. You'd flash the single-board computer with an operating system +2. You'd install `viam-agent` +3. You'd provide a machine configuration template, a fragment. + +Once a customer receives your machine, they will: + +1. Plug it in and turn it on. +2. `viam-agent` will start a WiFi network +3. The customer uses another device to connect to the machine's WiFi network and the user gives the machine the password for their WiFi network. +4. The machine can now connect to the internet and complete setup based on the fragment it knows about. + +### Create the fragment air sensing machines + +In this section you will create the {{< glossary_tooltip term_id="fragment" text="fragment" >}}, that is the configuration template that all other machines will use. + +1. Navigate to the **FLEET** page and go to the [**FRAGMENTS** tab](https://app.viam.com/fragments). +1. Add the same components that you added to the development machine when you [set up one device for development](#set-up-one-device-for-development). +1. As a shortcut, you can use the JSON mode on the machine you already configured and copy the machine's configuration to the fragment. + +{{< alert title="Tip: Use the fragment on your development machine" color="tip" >}} +To avoid differences between fragment and development machines, we recommend you remove the configured resources from the development machine and add the fragment you just created instead. +{{< /alert >}} + +### Provision your machines + +{{< table >}} +{{% tablestep number=1 %}} + +For each machine, flash the operating system to the device's SD card. +If you are using the Raspberry PI Imager, you **must customize at least the hostname** for the next steps to work. + +Then run the following commands to download the preinstall script and make the script executable: + +```sh {class="command-line" data-prompt="$"} +wget https://storage.googleapis.com/packages.viam.com/apps/viam-agent/preinstall.sh +chmod 755 preinstall.sh +``` + +{{% /tablestep %}} +{{% tablestep number=2 %}} + +Create a file called viam-defaults.json with the following configuration: + +```json {class="line-numbers linkable-line-numbers"} +{ + "network_configuration": { + "manufacturer": "Pollution Monitoring Made Simple", + "model": "v1", + "fragment_id": "", + "hotspot_prefix": "air-quality", + "hotspot_password": "WeLoveCleanAir123" + } +} +``` + +Replace `""` with the fragment ID from your fragment. + +{{% /tablestep %}} +{{% tablestep number=3 %}} + +In [Organize your fleet](#organize-your-fleet) you created several locations. +Navigate to one of the locations and create a machine. +Select the part status dropdown to the right of your machine's name on the top of the page. + +Click the copy icon next to **Machine cloud credentials**. +Paste the machine cloud credentials into a file on your harddrive called FILE>viam.json. + +{{< alert title="Tip: Fleet management API" color="tip" >}} +You can create locations and machines programmatically, with the [Fleet management API](/dev/reference/apis/fleet/). +{{< /alert >}} + +{{% /tablestep %}} +{{% tablestep number=3 %}} + +**Run the preinstall script** + +Run the preinstall script without options and it will attempt to auto-detect a mounted root filesystem (or for Raspberry Pi, bootfs) and also automatically determine the architecture. + +```sh {class="command-line" data-prompt="$"} +sudo ./preinstall.sh +``` + +Follow the instructions and provide the viam-defaults.json file and the machine cloud credentials file when prompted. + +{{% /tablestep %}} +{{< /table >}} + +That's it! Your device is now provisioned and ready for your end user! + +Having trouble? See [Provisioning](/manage/fleet/provision/setup/) for more information and troubleshooting.
## Next steps -Now that you can monitor your air quality, you can try to improve it and see if your efforts are effective. -You might try putting an air filter in your home or office and comparing the air quality data before you start running the filter with air quality after you have run the filter for a while. -Or, try sealing gaps around doors, and check whether your seal is working by looking at your dashboard. +You can now set up one or more air quality sensors for yourself or others and access them with your dashboard. +If you are selling your air quality sensing machines, they can also use your dashboard to view _their_ data. -You could set up a text or email alert when your air quality passes a certain threshold. +If you're wondering what to do next, why not set up a text or email alert when your air quality passes a certain threshold? For instructions on setting up an email alert, see the [Monitor Helmet Usage tutorial](/tutorials/projects/helmet/) as an example. For an example of setting up text alerts, see the [Detect a Person and Send a Photo tutorial](/tutorials/projects/send-security-photo/). -For another example of a custom TypeScript interface, check out the [Claw Game tutorial](/tutorials/projects/claw-game/). -Instead of displaying data, the claw game interface has buttons to control a robotic arm. - -In this tutorial we covered configuring a fleet of machines using fragments, but to automate the setup process further, you can [use the Viam Agent to provision machines](/manage/fleet/provision/setup/). - {{< cards >}} -{{% card link="/manage/fleet/provision/end-user-setup/" %}} -{{% card link="/tutorials/services/visualize-data-grafana/" %}} {{% card link="/tutorials/projects/helmet/" %}} +{{% card link="/tutorials/projects/send-security-photo/" %}} +{{% card link="/tutorials/services/visualize-data-grafana/" %}} {{< /cards >}} From 6b62ff73f6ef133bfe9faa1dc0f36fdd416f433d Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Mon, 26 May 2025 18:57:19 +0200 Subject: [PATCH 05/17] Update SPA instructions --- assets/scss/_styles_project.scss | 4 + docs/operate/control/single-page-apps.md | 109 +++- docs/operate/control/web-app.md | 2 +- .../operate/reference/module-configuration.md | 2 +- docs/tutorials/control/air-quality-fleet.md | 2 +- .../projects/create-single-page-app.md | 502 ------------------ 6 files changed, 99 insertions(+), 522 deletions(-) delete mode 100644 docs/tutorials/projects/create-single-page-app.md diff --git a/assets/scss/_styles_project.scss b/assets/scss/_styles_project.scss index 9e8405e458..672e9f1e9d 100644 --- a/assets/scss/_styles_project.scss +++ b/assets/scss/_styles_project.scss @@ -3365,6 +3365,10 @@ div.tablestep > table td, div.tablestep table td { margin-left: 1.0rem; } +.td-content > ol li { + margin-bottom: 0.5rem; +} + .td-content > ul { padding-left: 1rem; } diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index 507d4824a0..5728b4b246 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -1,9 +1,9 @@ --- title: "Create a custom web interface" linkTitle: "Create a custom web interface" -weight: 11 -no_list: true -type: docs +weight: 5 +layout: "docs" +type: "docs" description: "Create and deploy custom web interfaces for your machines as single-page applications without managing hosting and authentication." --- @@ -13,7 +13,7 @@ Once deployed, apps are accessible from a dedicated URL (`appname_publicnamespac When opening an app, users log in and then select a machine they have access to. Then your app is rendered and ready for use. -{{}} +{{}} ## Requirements @@ -28,14 +28,14 @@ Then authenticate your CLI session with Viam using one of the following options: {{< /expand >}} -## Create a single page app +## Build a custom web interface -{{< table >}} -{{% tablestep number=1 %}} +You can build a custom web interface to access your machines using your preferred framework like React, Vue, Angular, or others. -**Build your application** using your preferred framework like React, Vue, Angular, or others. -While you're developing use any machine's credentials. -For deploying your app you must add code to read the machine API key from your browsers local storage: +### Access machines from your app + +Viam apps provide access to a machine by placing its API key in your local storage. +You can access the data from your browser's local storage as follows: ```ts {class="line-numbers linkable-line-numbers" data-line=""} import Cookies from "js-cookie"; @@ -53,8 +53,82 @@ machineId = window.location.pathname.split("/")[2]; } = JSON.parse(Cookies.get(machineId)!)); ``` -{{% /tablestep %}} -{{% tablestep number=2 %}} +For developing your app on localhost, add the same information to your browsers local storage. + +1. Navigate to [Camera Viewer](https://camera-viewer_naomi.viamapplications.com/). +2. Log in and select the machine you'd like to use for testing. +3. Open Developer tools and go to the console. +4. Execute the following JavaScript to obtain the cookies you need: + + ```js {class="line-numbers linkable-line-numbers" data-line=""} + function generateCookieSetterScript() { + // Get all cookies from current page + const currentCookies = document.cookie.split(";"); + let cookieSetterCode = "// Cookie setter script for localhost\n"; + cookieSetterCode += + "// Copy and paste this entire script into your browser console when on localhost\n\n"; + + // Process each cookie + let cookieCount = 0; + currentCookies.forEach((cookie) => { + if (cookie.trim()) { + // Extract name and value from the cookie + const [name, value] = cookie.trim().split("="); + + // Add code to set this cookie + cookieSetterCode += `document.cookie = "${name}=${value}; path=/";\n`; + cookieCount++; + } + }); + + // Add summary comment + cookieSetterCode += `\nconsole.log("Set ${cookieCount} cookies on localhost");\n`; + + // Display the generated code + console.log(cookieSetterCode); + + // Create a textarea element to make copying easier + const textarea = document.createElement("textarea"); + textarea.value = cookieSetterCode; + textarea.style.position = "fixed"; + textarea.style.top = "0"; + textarea.style.left = "0"; + textarea.style.width = "100%"; + textarea.style.height = "250px"; + textarea.style.zIndex = "9999"; + document.body.appendChild(textarea); + textarea.focus(); + textarea.select(); + } + + // Execute the function + generateCookieSetterScript(); + ``` + +5. Copy the resulting script. It will look like this: + + ```js {class="line-numbers linkable-line-numbers" data-line=""} + // Cookie setter script for localhost + // Copy and paste this entire script into your browser console when on localhost + + document.cookie = "; path=/"; + document.cookie = "machinesWhoseCredentialsAreStored=; path=/"; + + console.log("Set 2 cookies on localhost"); + ``` + +6. Open the app you are building on localhost and run the resulting script. +7. Reload your app. + +### Configure routing + +When using your deployed application, static files will be accessible at `https://your-app-name_your-public-namespace.viamapplications.com/machine//`. +If your HTML file loads other files, use relative paths to ensure your files are accessible. + +## Deploy your web interface + +{{< table >}} +{{% tablestep number=1 %}} **Create a meta.json** file using this template: @@ -123,7 +197,7 @@ The `applications` field is an array of application objects with the following p | `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example:
  • "dist/index.html": Static content rooted at the `dist` directory
  • "dist/foo.html": Static content rooted at the `dist` directory, with `foo.html` as the entry point
  • "dist/": Static content rooted at the `dist` directory (assumes `dist/index.html` exists)
  • "dist/bar/foo.html": Static content rooted at `dist/bar` with `foo.html` as the entry point
| {{% /tablestep %}} -{{% tablestep number=3 %}} +{{% tablestep number=2 %}} **Register your module** with Viam: {{< tabs >}} @@ -144,13 +218,13 @@ viam module create --name="air-quality" --public-namespace="naomi" {{< /tabs >}} {{% /tablestep %}} -{{% tablestep number=4 %}} +{{% tablestep number=3 %}} **Package your static files and your meta.json file and upload them** to the Viam Registry: ```sh {class="command-line" data-prompt="$" data-output="3-10"} tar -czvf module.tar.gz meta.json -viam module upload module.tar.gz --platform=any --version=0.0.1 +viam module upload --upload=module.tar.gz --platform=any --version=0.0.1 ``` For subsequent updates run these commands again with an updated version number. @@ -176,7 +250,8 @@ Users will be prompted to authenticate with their Viam credentials before access ## Example -For an example see [Monitor Air Quality with a Fleet of Sensors](/tutorials/control/air-quality-fleet/). +For a TypeScript example see [Monitor Air Quality with a Fleet of Sensors](/tutorials/control/air-quality-fleet/). +For a Reach app that shows Camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). ## Limitations @@ -187,7 +262,7 @@ For an example see [Monitor Air Quality with a Fleet of Sensors](/tutorials/cont ## Security Considerations -- Customer apps are stored in GCS buckets that are publicly available on the internet +- Customer apps are stored publicly available on the internet - Avoid uploading sensitive information in your application code or assets - API keys and secrets are stored in the browser's localStorage or sessionStorage - Single page apps authenticate users with FusionAuth diff --git a/docs/operate/control/web-app.md b/docs/operate/control/web-app.md index 602a588420..6721b701e1 100644 --- a/docs/operate/control/web-app.md +++ b/docs/operate/control/web-app.md @@ -1,6 +1,6 @@ --- linkTitle: "Create a web app" -title: "Create a web app" +title: "Create a self-hosted web app" weight: 10 layout: "docs" type: "docs" diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index 6a1918aa6d..6e1f2e5687 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -285,7 +285,7 @@ The `applications` field is an array of application objects with the following p For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). -#### Environment variables +### Environment variables Each module has access to the following default environment variables. Not all of these variables are automatically available on [local modules](/operate/get-started/other-hardware/#test-your-module-locally); you can manually set variables your module requires if necessary. diff --git a/docs/tutorials/control/air-quality-fleet.md b/docs/tutorials/control/air-quality-fleet.md index a892e69b1a..e74b91358a 100644 --- a/docs/tutorials/control/air-quality-fleet.md +++ b/docs/tutorials/control/air-quality-fleet.md @@ -726,7 +726,7 @@ viam module create --name="air-quality" --public-namespace="your-namespace" ```sh {class="command-line" data-prompt="$" data-output="3-10"} npm run build tar -czvf module.tar.gz static meta.json -viam module upload module.tar.gz --platform=any --version=0.0.1 +viam module upload --upload=module.tar.gz --platform=any --version=0.0.1 ``` For subsequent updates run these commands again with an updated version number. diff --git a/docs/tutorials/projects/create-single-page-app.md b/docs/tutorials/projects/create-single-page-app.md deleted file mode 100644 index f775f2402e..0000000000 --- a/docs/tutorials/projects/create-single-page-app.md +++ /dev/null @@ -1,502 +0,0 @@ ---- -title: "Create a Single Page App" -linkTitle: "Create a Single Page App" -weight: 45 -type: "docs" -description: "Build and deploy a web application hosted by Viam." -tags: ["web", "single page app", "react", "module"] -difficulty: intermediate -time_to_complete: "1 hour" ---- - -This tutorial guides you through creating and deploying a Single Page App (SPA) with Viam. You'll build a simple React application that allows users to select a machine and view its camera feed. - -## Prerequisites - -- A Viam account with an organization that has a public namespace -- Node.js and npm installed on your development machine -- Basic familiarity with React -- A machine with a camera component configured in your Viam account - -## Step 1: Create a React application - -First, let's create a new React application using Create React App: - -```bash -npx create-react-app viam-camera-viewer -cd viam-camera-viewer -``` - -## Step 2: Install dependencies - -Install the Viam TypeScript SDK and other necessary dependencies: - -```bash -npm install @viamrobotics/sdk react-router-dom -``` - -## Step 3: Create the application structure - -Let's create a simple application with the following pages: - -1. Home page - For selecting organization, location, and machine -2. Machine page - For viewing the selected machine's camera feed - -Create the following folder structure: - -``` -src/ -├── components/ -│ ├── OrganizationSelector.js -│ ├── LocationSelector.js -│ ├── MachineSelector.js -│ └── CameraViewer.js -├── pages/ -│ ├── HomePage.js -│ └── MachinePage.js -├── App.js -└── index.js -``` - -## Step 4: Implement the components - -Let's implement each component: - -### OrganizationSelector.js - -```jsx -import React, { useState, useEffect } from 'react'; - -function OrganizationSelector({ onSelect }) { - const [organizations, setOrganizations] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - useEffect(() => { - // In a real app, you would fetch organizations from the Viam API - // This is a simplified example - setOrganizations([ - { id: 'org1', name: 'My Organization' }, - { id: 'org2', name: 'Another Organization' } - ]); - setLoading(false); - }, []); - - if (loading) return
Loading organizations...
; - if (error) return
Error: {error}
; - - return ( -
-

Select an Organization

- -
- ); -} - -export default OrganizationSelector; -``` - -### LocationSelector.js - -```jsx -import React, { useState, useEffect } from 'react'; - -function LocationSelector({ organizationId, onSelect }) { - const [locations, setLocations] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - - useEffect(() => { - if (!organizationId) { - setLocations([]); - setLoading(false); - return; - } - - // In a real app, you would fetch locations from the Viam API - // This is a simplified example - setLocations([ - { id: 'loc1', name: 'Home' }, - { id: 'loc2', name: 'Office' } - ]); - setLoading(false); - }, [organizationId]); - - if (!organizationId) return null; - if (loading) return
Loading locations...
; - if (error) return
Error: {error}
; - - return ( -
-

Select a Location

- -
- ); -} - -export default LocationSelector; -``` - -### MachineSelector.js - -```jsx -import React, { useState, useEffect } from 'react'; -import { useNavigate } from 'react-router-dom'; - -function MachineSelector({ locationId }) { - const [machines, setMachines] = useState([]); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const navigate = useNavigate(); - - useEffect(() => { - if (!locationId) { - setMachines([]); - setLoading(false); - return; - } - - // In a real app, you would fetch machines from the Viam API - // This is a simplified example - setMachines([ - { id: 'machine1', name: 'My Robot' }, - { id: 'machine2', name: 'Another Robot' } - ]); - setLoading(false); - }, [locationId]); - - const handleMachineSelect = (machineId) => { - if (machineId) { - navigate(`/machine/${machineId}`); - } - }; - - if (!locationId) return null; - if (loading) return
Loading machines...
; - if (error) return
Error: {error}
; - - return ( -
-

Select a Machine

- -
- ); -} - -export default MachineSelector; -``` - -### CameraViewer.js - -```jsx -import React, { useState, useEffect, useRef } from 'react'; - -function CameraViewer({ machineId }) { - const [cameras, setCameras] = useState([]); - const [selectedCamera, setSelectedCamera] = useState(''); - const [loading, setLoading] = useState(true); - const [error, setError] = useState(null); - const imageRef = useRef(null); - - useEffect(() => { - if (!machineId) { - setCameras([]); - setLoading(false); - return; - } - - // In a real app, you would fetch cameras from the Viam API - // This is a simplified example - setCameras([ - { id: 'camera1', name: 'Main Camera' }, - { id: 'camera2', name: 'Secondary Camera' } - ]); - setLoading(false); - }, [machineId]); - - useEffect(() => { - if (!selectedCamera) return; - - // In a real app, you would set up a stream from the Viam API - // This is a simplified example - const interval = setInterval(() => { - // Simulate camera feed with a placeholder - if (imageRef.current) { - imageRef.current.src = `https://picsum.photos/800/600?random=${Date.now()}`; - } - }, 1000); - - return () => clearInterval(interval); - }, [selectedCamera]); - - const handleCameraSelect = (cameraId) => { - setSelectedCamera(cameraId); - }; - - if (!machineId) return null; - if (loading) return
Loading cameras...
; - if (error) return
Error: {error}
; - - return ( -
-

Camera Feed

-
- -
- {selectedCamera && ( -
- Camera feed -
- )} -
- ); -} - -export default CameraViewer; -``` - -## Step 5: Create the pages - -### HomePage.js - -```jsx -import React, { useState } from 'react'; -import OrganizationSelector from '../components/OrganizationSelector'; -import LocationSelector from '../components/LocationSelector'; -import MachineSelector from '../components/MachineSelector'; - -function HomePage() { - const [selectedOrg, setSelectedOrg] = useState(''); - const [selectedLocation, setSelectedLocation] = useState(''); - - return ( -
-

Viam Camera Viewer

-

Select your organization, location, and machine to view camera feeds.

- -
- -
- - {selectedOrg && ( -
- -
- )} - - {selectedLocation && ( -
- -
- )} -
- ); -} - -export default HomePage; -``` - -### MachinePage.js - -```jsx -import React from 'react'; -import { useParams, Link } from 'react-router-dom'; -import CameraViewer from '../components/CameraViewer'; - -function MachinePage() { - const { machineId } = useParams(); - - return ( -
-
- ← Back to selection -
- -

Machine: {machineId}

- -
- ); -} - -export default MachinePage; -``` - -## Step 6: Update App.js with routing - -```jsx -import React from 'react'; -import { BrowserRouter as Router, Routes, Route } from 'react-router-dom'; -import HomePage from './pages/HomePage'; -import MachinePage from './pages/MachinePage'; - -function App() { - return ( - - - } /> - } /> - - - ); -} - -export default App; -``` - -## Step 7: Build the application - -Build your React application: - -```bash -npm run build -``` - -This will create a production build in the `build` directory. - -## Step 8: Create a Viam module - -Now, let's create a Viam module to host our Single Page App: - -```bash -mkdir viam-camera-viewer-module -cd viam-camera-viewer-module -``` - -Create a `meta.json` file: - -```json -{ - "module_id": "your-namespace:camera-viewer", - "visibility": "public", - "url": "https://github.com/your-username/viam-camera-viewer", - "description": "A simple camera viewer single page application", - "models": [], - "entrypoint": "", - "applications": [ - { - "name": "camera-viewer", - "type": "web", - "entrypoint": "build/index.html" - } - ] -} -``` - -Replace `your-namespace` with your organization's public namespace. - -## Step 9: Package and upload the module - -Copy your React build files to the module directory: - -```bash -cp -r ../viam-camera-viewer/build ./ -``` - -Create a module tarball: - -```bash -tar -czvf module.tar.gz build meta.json -``` - -Upload the module to the Viam Registry: - -```bash -viam module upload module.tar.gz -``` - -## Step 10: Access your Single Page App - -Once your module is approved, you can access your Single Page App at: - -``` -https://camera-viewer.your-namespace.viamapps.com -``` - -Replace `your-namespace` with your organization's public namespace. - -## Integrating with the Viam SDK - -The example above uses placeholder data. In a real application, you would use the Viam TypeScript SDK to interact with your machines. Here's how you might implement the actual API calls: - -### Connecting to Viam - -```jsx -import { createRobotClient, ViamClient } from '@viamrobotics/sdk'; - -// Create a Viam client -const createClient = async () => { - try { - // Get credentials from localStorage - const apiKey = localStorage.getItem('viamApiKey'); - const apiKeyId = localStorage.getItem('viamApiKeyId'); - - if (!apiKey || !apiKeyId) { - throw new Error('API credentials not found'); - } - - const client = await createRobotClient({ - host: 'your-machine-fqdn.viam.cloud', - credential: { - type: 'api-key', - payload: apiKey, - }, - signingAuthority: apiKeyId, - authEntity: 'your-machine-id', - }); - - return client; - } catch (error) { - console.error('Error creating client:', error); - throw error; - } -}; -``` - -### Getting camera data - -```jsx -// Get camera image -const getCameraImage = async (client, cameraName) => { - try { - const camera = await client.camera.fromRobot(cameraName); - const image = await camera.getImage(); - return image; - } catch (error) { - console.error('Error getting camera image:', error); - throw error; - } -}; -``` - -## Conclusion - -You've successfully created and deployed a Single Page App with Viam! This simple application demonstrates how to build a web interface for interacting with Viam machines. You can extend this application to include more features, such as controlling motors, reading sensor data, or implementing more complex machine interactions. - -For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). \ No newline at end of file From 79b1fc4017384659b506ea4dae2e17afa27ded54 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Tue, 27 May 2025 13:09:54 +0200 Subject: [PATCH 06/17] Move air quality tutorial to separate PR --- docs/operate/control/single-page-apps.md | 5 +- docs/tutorials/control/air-quality-fleet.md | 1094 +++++++++---------- 2 files changed, 508 insertions(+), 591 deletions(-) diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index 5728b4b246..eb0a0eba63 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -250,8 +250,9 @@ Users will be prompted to authenticate with their Viam credentials before access ## Example -For a TypeScript example see [Monitor Air Quality with a Fleet of Sensors](/tutorials/control/air-quality-fleet/). -For a Reach app that shows Camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). + + +For a React app that shows Camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). ## Limitations diff --git a/docs/tutorials/control/air-quality-fleet.md b/docs/tutorials/control/air-quality-fleet.md index e74b91358a..a0d054f089 100644 --- a/docs/tutorials/control/air-quality-fleet.md +++ b/docs/tutorials/control/air-quality-fleet.md @@ -20,137 +20,297 @@ cost: 200 # 2. The reader can identify when to use fragments and evaluate when it is worth using fragments. # The reader can create their own fragments for their projects and knows what to include and exclude from them. # 3. The reader recognizes how permissions enable the management of data for a business across multiple customers while providing each customer access to their own data. -# 4. The reader can deploy custom frond ends that end users can use to operate their machines. --- -In this tutorial you will learn how to set up a fleet of devices for yourself or third parties to collect air quality data. -You will then create a web app that shows the most recent reading for any device a user has access to. +In this tutorial you will use a fleet of devices to collect air quality data from different places and display the most recent readings from each device in a custom viewing dashboard. {{< alert title="Learning Goals" color="info" >}} By completing this project, you will learn to: -- Configure a fleet of machines +- Configure a fleet of identical machines - Organize your fleet using {{< glossary_tooltip term_id="location" text="locations" >}} - Collect and sync data from multiple machines -- Use the Viam TypeScript SDK to query sensor data -- Create a custom dashboard that you and third parties can use to view data for their respective machines. +- Use the Viam TypeScript SDK to query sensor data and create a custom dashboard +- Use API keys to provide access to different groups of machines {{< /alert >}} -{{}} +![Air quality dashboard in a web browser with PM2.5 readings from three different sensor machines displayed.](/tutorials/air-quality-fleet/three-sensor-dash-wide.png) ## Requirements -You can create one or more machines to measure air quality. -For each machine, you need the following hardware: +You can complete this tutorial using any number of air quality sensing machines. -- one or more [SDS011 Nova PM sensors](https://www.amazon.com/SDS011-Quality-Detection-Conditioning-Monitor/dp/B07FSDMRR5) +For each machine, you will need the following hardware: + +- [SDS011 Nova PM sensor](https://www.amazon.com/SDS011-Quality-Detection-Conditioning-Monitor/dp/B07FSDMRR5) - If you choose to use a different air quality sensor, you may need to [create your own module](/operate/get-started/other-hardware/) implementing the [sensor API](/operate/reference/components/sensor/#api) for your specific hardware. - A single-board computer (SBC) [capable of running `viam-server`](https://docs.viam.com/installation/) - An appropriate power supply -## Set up one device for development +Make sure all of your sensors are wired to your SBC before starting this tutorial. + +## Decide how you will organize your fleet + +Before you start connecting your devices to the Viam app, you'll need to decide how you want to group your devices. + +In the Viam app, {{< glossary_tooltip term_id="machine" text="machines" >}} are grouped into _locations_, and locations are grouped into _organizations_: + +- Each location can represent either a physical location or some other conceptual grouping. +- An organization is the highest level grouping, and often contains all the locations (and machines) of an entire company. + +These groupings allow you to manage permissions; you can grant a user access to an individual machine, to all the machines in a location, or to everything in an entire organization. +You choose how to group your machines. + +{{}} + +
+ +For more information, see [Fleet Management](/manage/reference/organize/). + +### Example + +Imagine you create an air quality monitoring company called Pollution Monitoring Made Simple. +Anyone can sign up and order one of your sensing machines. +When a new customer signs up, you assemble a new machine with a sensor, SBC, and power supply. + +Before shipping the sensor machine to your new client, you connect the machine to the Viam app and configure it. +To manage all your company's air quality sensing machines together, you create one organization called Pollution Monitoring Made Simple. +Inside that organization, you create a location for each customer. +You have some individual customers, for example Antonia, who have a sensor machine in their home, or perhaps one inside and one outside. +You have other customers who are businesses, for example RobotsRUs, who have two offices, one in New York and one in Oregon, with multiple sensor machines in each. +RobotsRUs wants to separate their sensor data by physical location, so you create a location for RobotsRUs and then create sub-locations to group their New York sensor machines and their Oregon machines. + +When you grant Antonia access to her location, she will be able to view data from the air sensors at her home. +When you grant RobotsRUs access to their location, they will be able to view data from all of their sub-locations, or they can choose to spin up a dashboard showing data from only one sub-location at a time. +You, as the organization owner, will be able to manage any necessary configuration changes for all air sensing machines in all locations created within the Pollution Monitoring Made Simple organization. + +{{}} + +### Organize your fleet + +For this tutorial, we will walk through how to set up your fleet based on the example above. +You can choose to manage your fleet of machines differently based on what makes sense for your use case; if you're only configuring one or two sensors for personal use, feel free to add all your machines to one location and skip to the [next section](#connect-your-machines-to-the-viam-app). + +1. Navigate to the [Viam app](https://app.viam.com) in a web browser. + Create an account and log in. +1. Click the dropdown in the upper-right corner of the **FLEET** page and use the **+** button to create a new organization for your air quality machine company. + Name the organization and click **Create**. +1. Click **FLEET** in the upper-left corner of the page and click **LOCATIONS**. + A new location called `First Location` is automatically generated for you. + Rename it so you can use it for Antonia's machines: -In this section we'll set up one air sensing machine as our development device. + Use the **...** menu next to edit the location name to `Antonia's Home`, then click **Save**. -{{< table >}} -{{% tablestep number=1 %}} +1. Now, create a separate location for RobotsRUs: -Navigate to the [Viam app](https://app.viam.com) in a web browser. -Create an account and log in. + On the left side of the **LOCATIONS** page, click the **Add location** button. + Type in `RobotsRUs` and click **Add**. -{{% /tablestep %}} -{{% tablestep number=2 %}} +1. Add sub-locations to the RobotsRUs location to group the machines at each of their offices: -Click the dropdown in the upper-right corner of the **FLEET** page and use the **+** button to create a new organization for your air quality machine company. -Name the organization and click **Create**. + Add a new location called `Oregon Office` using the same **Add location** button. + Then, find the **New parent location** dropdown on the Oregon Office page. + Select **RobotsRUs** and click **Change**. -{{% /tablestep %}} -{{% tablestep number=3 %}} + Repeat to add the New York office: Add a new location called `New York Office`, then change its parent location to **RobotsRUs**. -Click **FLEET** in the upper-left corner of the page and click **LOCATIONS**. -A new location called `First Location` is automatically generated for you. -Use the **...** menu next to edit the location name to `Development`, then click **Save**. + {{}} -{{% /tablestep %}} -{{% tablestep number=4 %}} + In the next section, you'll add machines to the locations. -Connect a PM sensor to a USB port on the machine's SBC. -Then connect your device to power. +## Connect your machines to the Viam app -If the computer does not already have a Viam-compatible operating system installed, follow the [operating system setup section of the Quickstart guide](/operate/get-started/setup/) to install a compatible operating system. -You _do not_ need to follow the "Install `viam-server`" section; you will do that in the next step! +With your organizational structure in place, let's add some machines: -Enable serial communication so that the SBC can communicate with the air quality sensor. -For example, if you are using a Raspberry Pi, SSH to it and [enable serial communication in `raspi-config`](/operate/reference/prepare/rpi-setup/#enable-communication-protocols). +1. Connect your first single-board computer to power. + For this tutorial, we'll treat this as the machine for our first customer, Antonia. + If the computer does not already have a Viam-compatible operating system installed, follow the [operating system setup section of the Quickstart guide](/operate/get-started/setup/) to install a compatible operating system. + You _do not_ need to follow the "Install `viam-server`" section; you will do that in the next step! -{{% /tablestep %}} -{{% tablestep number=5 %}} +1. Enable serial communication so that the SBC can communicate with the air quality sensor. + For example, if you are using a Raspberry Pi, SSH to it and [enable serial communication in `raspi-config`](/operate/reference/prepare/rpi-setup/#enable-communication-protocols). -Add a new [_{{< glossary_tooltip term_id="machine" text="machine" >}}_](/operate/get-started/basics/#what-is-a-machine) using the button in the top right corner of the **LOCATIONS** tab in the app. -Follow the **Set up your machine part** instructions to install `viam-server` on the machine and connect it to the Viam app. +1. Click **Antonia's Home** in the left navigation menu to navigate to that location's page. + In the **New machine** field near the top-right corner of the screen, type in a name for the machine, such as `Home Air Quality Sensor`, and click **Add machine**. + +1. You'll be taken to the machine details page and prompted to set up your machine part. + Click **View setup instructions**. + You can find these instructions later if you need them by clicking the part status indicator (which currently reads **Awaiting setup**). + +1. Follow the **Set up your machine part** instructions to install `viam-server` on the machine and connect it to the Viam app. + `viam-server` is the binary that runs on the single-board computer (SBC), providing functionality including sensor data collection and connection to the Viam app. + + The setup page will indicate when the machine is successfully connected. + +1. If Antonia has more than one air sensing machine, add a new machine to her location and set it up in the same way. + +This is how you set up one machine. +If you are following along for the RobotsRUs business from our example, create additional machines in each sub-location, that is, in the `Oregon Office` location and in the `New York Office` location. + +## Set up your hardware + +{{% alert title="Note" color="note" %}} +If this were a real company and you were shipping air sensing machines to customers, you would have the customer plug in power to the machine wherever they are setting it up. +Since you already installed `viam-server`, once a customer connects the machine to power and sets up wifi, the machine will automatically re-connect to the Viam app and pull any configuration updates. +{{% /alert %}} + +For each sensing machine: + +1. Connect the PM sensor to a USB port on the machine's SBC. + +1. Position your sensing machines in strategic locations, and connect them to power. + Here are some ideas for where to place sensing machines: + + - At home: + - In an outdoor location protected from weather, such as under the eaves of your home + - In the kitchen, where cooking can produce pollutants + - Anywhere you spend lots of time indoors and want to measure exposure to pollutants + - At work: + - At your desk to check your exposure throughout the day + - Near a door or window to see whether pollutants are leaking in + +## Configure your air quality sensors + +You need to [configure](/operate/get-started/supported-hardware/#configure-hardware-on-your-machine) your hardware so that each of your machines can communicate with its attached air quality [sensor](/operate/reference/components/sensor/). + +No matter how many sensing machines you use, you can configure them efficiently by using a reusable configuration block called a _{{< glossary_tooltip term_id="fragment" text="fragment" >}}_. +Fragments are a way to share and manage identical machine configurations across multiple machines. +Instead of going through all the configuration steps for each machine, you'll start by configuring just one machine and create a fragment based on that machine's configuration. +Then, you'll add the fragment to each of your machines. +With all your machines configured using the same fragment, if you need to update the config in the future, you can just update the fragment and all machines will automatically get the update. + +{{< alert title="Note" color="note" >}} +If this was a real company, adding the fragment to each individual machine would quickly become tiring. +We're showing you how to do this manually as a learning device. +Once you understand how to configure machines and use fragments, you can use [Provisioning](/manage/fleet/provision/setup/) to automatically set up your devices. +{{< /alert >}} + +### Configure your first machine + +#### Configure the sensor + +1. Navigate to the **CONFIGURE** tab of the machine details page in the [Viam app](https://app.viam.com) for your first machine. +2. Click the **+** (Create) button and click **Component** from the dropdown. + Click **sensor**, then search for `sds011` and click **sds001:v1** from the results. +3. Click **Add module**. + This adds the {{< glossary_tooltip term_id="module" text="module" >}} that provides the sensor model that supports the specific hardware we are using for this tutorial. + + ![The Add Module button that appears after you click the model name.](/tutorials/air-quality-fleet/add-sensor-module.png) + +4. Give the sensor a name like `PM_sensor` and click **Create**. +5. In the newly created **PM_sensor** card, replace the contents of the attributes box (the empty curly braces `{}`) with the following: + + ```json {class="line-numbers linkable-line-numbers"} + { + "usb_interface": "" + } + ``` -When your machine shows as connected, continue to the next step. +6. Now you need to figure out which port your sensor is connected to on your board. + SSH to your board and run the following command: -{{% /tablestep %}} -{{% tablestep number=6 %}} + ```sh{class="command-line" data-prompt="$"} + ls /dev/serial/by-id + ``` -Navigate to the **CONFIGURE** tab of the machine, click the **+** button and select **Component or service**. -Click **sensor**, then search for `sds011` and add the **sds001:v1** {{< glossary_tooltip term_id="module" text="module" >}}. -Name the sensor `PM_sensor` and click **Create**. + This should output a list of one or more USB devices attached to your board, for example `usb-1a86_USB_Serial-if00-port0`. + If the air quality sensor is the only device plugged into your board, you can be confident that the only device listed is the correct one. + If you have multiple devices plugged into different USB ports, you may need to choose one path and test it, or unplug something, to figure out which path to use. -{{}} + Now that you have found the identifier, put the full path to the device into your config, for example: -{{% /tablestep %}} -{{% tablestep number=7 %}} + ```json {class="line-numbers linkable-line-numbers"} + { + "usb_interface": "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0" + } + ``` -In the newly created **PM_sensor** card, replace the contents of the attributes box (the empty curly braces `{}`) with the following: +7. Save the config. + Your machine config should now resemble the following: + + ![Configure tab showing PM sensor and the sensor module configured.](/tutorials/air-quality-fleet/configured-sensor.png) + +#### Configure data capture and sync + +You have configured the sensor so the board can communicate with it, but sensor data is not yet being saved anywhere. +Viam's [data management service](/data-ai/capture-data/capture-sync/) lets you capture data locally from each sensor and then sync it to the cloud where you can access historical sensor data and see trends over time. +Once you configure the rest of your sensing machines, you'll be able to remotely access data from all sensors in all locations, and when you're ready, you can give customers [access](/manage/manage/access/) to the data from the sensors in their locations. + +Configure data capture and sync as follows: + +1. Click the **+** (Create) button and click **Service** from the dropdown. +2. Click **data management**. +3. Give your data manager a name such as the auto-populated name `data_manager-1` and click **Create**. +4. Toggle **Syncing** to the on position. + Set the sync interval to `0.05` minutes so that data syncs to the cloud every 3 seconds. + You can change the interval if you like, just don't make it too long or you will have to wait a long time before you see your data! +5. Let's add a tag to all your data so that you can query data from all your air quality sensors more easily in later steps. + In the **Tags** field, type `air-quality` and click **+ Tag: air-quality** when it appears to create a new tag. + This tag will now automatically be applied to all data collected by this data manager. +6. Now the data management service is available to any components on your machine, and you can set up data capture on the sensor: +7. On your **PM_sensor** card, click **Add method**. +8. From the **Type** dropdown, select **Readings**. +9. Set the **Frequency** to `0.1` readings per second. + This will capture air quality data once every ten seconds. + It is useful to capture data frequently for testing purposes, but you can always change this frequency later since you probably don't need to capture data this frequently all day forever. +10. Save the config. + +### Create a fragment + +{{% alert title="Note" color="note" %}} +If you are only using one air quality sensing machine for this tutorial, you do not need to create or use fragments, since fragments are useful only when configuring multiple machines. +You can skip to [Test your sensors](#test-your-sensors). +{{% /alert %}} -```json {class="line-numbers linkable-line-numbers"} -{ - "usb_interface": "" -} -``` +While you configured your machine with the builder UI, the Viam app generated a JSON configuration file with all your parameters. +This is the file that tells `viam-server` what resources are available to it and how everything is connected. +Click **JSON** in the upper-left corner of the **CONFIGURE** tab to view the generated JSON file. +You can manually edit this file instead of using the builder UI if you are familiar with JSON. -{{% /tablestep %}} -{{% tablestep number=8 %}} +In any case, now that the JSON is generated, you are ready to create a {{< glossary_tooltip term_id="fragment" text="fragment" >}}: -To figure out which port your sensor is connected to on your board, SSH to your board and run the following command: +1. Select and copy the entire contents of the JSON config. +2. Navigate to the **FLEET** page and go to the [**FRAGMENTS** tab](https://app.viam.com/fragments). +3. Click **Create fragment** and change your fragment's name by clicking on it. We used the name `air-sensing-machine`. +4. Replace the empty curly braces `{}` with the config you copied from your machine. +5. Click **Save**. +6. Now, you can actually delete the entire config from your machine! + In the next section, you will replace it with the fragment you just created so that it gets updated alongside all your other machines when you update the fragment in the future. -```sh{class="command-line" data-prompt="$"} -ls /dev/serial/by-id -``` + Navigate back to your machine's **CONFIGURE** tab, select **JSON** mode, and delete the entire contents of the config. + When you try to save, you'll get an invalid JSON error because it can't be empty. + Put in a set of curly braces `{}` and then save the config successfully. -This should output a list of one or more USB devices attached to your board, for example `usb-1a86_USB_Serial-if00-port0`. -If the air quality sensor is the only device plugged into your board, you can be confident that the only device listed is the correct one. -If you have multiple devices plugged into different USB ports, you may need to choose one path and test it, or unplug something, to figure out which path to use. +### Add the fragment to all your machines -Now that you have found the identifier, put the full path to the device into your config, for example: +Add the fragment you just created to each of your machines including the first one: -```json {class="line-numbers linkable-line-numbers"} -{ - "usb_interface": "/dev/serial/by-id/usb-1a86_USB_Serial-if00-port0" -} -``` +1. Click the **+** button, then click **Insert fragment** in the dropdown menu. +2. Search for and click the name of your fragment, for example `air-sensing-machine`. -{{% /tablestep %}} -{{% tablestep number=9 %}} + ![The insert fragment UI.](/tutorials/air-quality-fleet/add-fragment.png) -Save the config. +3. Click **Insert fragment**. + The module, sensor, and data manager will appear in your config. +4. Save the config. +5. Repeat these steps on the machine details page for each of your air quality sensing machines. -{{}} +## Test your sensors -{{% /tablestep %}} -{{% tablestep number=10 %}} +Now that all your hardware is configured, it's a good idea to make sure readings are being gathered by the sensors and sent to the cloud before proceeding with the tutorial. +For each machine: -On your sensor configuration panel, click on the **TEST** panel to check that you are getting readings from your sensor. +1. Go to the machine details page in the [Viam app](https://app.viam.com.) and navigate to the **CONTROL** tab. +2. Within the **Sensors** section, click **Get Readings** for the **PM_sensor**. + If the sensor software and hardware is working, you should see values populate the **Readings** column. -{{}} + ![The sensor readings on the control tab.](/tutorials/air-quality-fleet/get-readings.png) -If you do not see readings, check the **LOGS** tab for errors, double-check that serial communication is enabled on the single board computer, and check that the `usb_interface` path is correctly specified (click below). + If you do not see readings, check the **LOGS** tab for errors, double-check that serial communication is enabled on the single board computer, and check that the `usb_interface` path is correctly specified (click below). -{{< expand "Click here for usb_interface troubleshooting help" >}} + {{< expand "Click here for usb_interface troubleshooting help" >}} If you only have one USB device plugged into each of your boards, the `usb_interface` value you configured in the sensor config is likely (conveniently) the same for all of your machines. If not, you can use [fragment overwrite](/manage/fleet/reuse-configuration/#modify-fragment-settings-on-a-machine) to modify the value on any machine for which it is different: @@ -183,338 +343,302 @@ If not, you can use [fragment overwrite](/manage/fleet/reuse-configuration/#modi {{< /expand >}} -{{% /tablestep %}} -{{% tablestep number=11 %}} - -Click **+** and add the **data management** service. -Toggle **Syncing** to the on position and set the sync interval to `0.05` minutes so that data syncs to the cloud every 3 seconds. - -Add a tag to all your data so that you can query data from all your air quality sensors more easily in later steps. -In the **Tags** field, type `air-quality` and click **+ Tag: air-quality** when it appears to create a new tag. -This tag will now automatically be applied to all data collected by this data manager. - -{{% /tablestep %}} -{{% tablestep number=12 %}} - -On the **PM_sensor** panel, click **Add method** to add data capture. +## Test data sync -- **Type** :**Readings**. -- **Frequency**: `0.1` +Next, check that data is being synced from your sensors to the cloud: -Save the config. +1. Open your [**DATA** page](https://app.viam.com/data). +2. Click the **Sensors** tab within the data page. +3. If you have sensor data coming from machines unrelated to this project, use the filters on the left side of the page to view data from only your air quality sensors. + Click the **Tags** dropdown and select the `air-quality` tag you applied to your data. + You can also use these filters to show the data from one of your air quality sensors at a time by typing a machine name into the **Machine name** box and clicking **Apply** in the lower-left corner. -You can check that your sensor data is being synced by clicking on the **...** menu and clicking **View captured data**. + ![The sensor readings that have synced to the DATA page.](/tutorials/air-quality-fleet/synced-data.png) -{{% /tablestep %}} -{{< /table >}} +Once you've confirmed that data is being collected and synced correctly, you're ready to start building a dashboard to display the data. +If you'd like to graph your data using a Grafana dashboard, try our [Visualize Data with Grafana tutorial](/tutorials/services/visualize-data-grafana/). +If you'd like to create your own customizable dashboard using the Viam TypeScript, continue with this tutorial. -Congratulations, if you made it this far, you now have a functional air sensing machine. -Let's create a dashboard for its measurements next. - -## Create a dashboard +## Code your custom TypeScript dashboard The [Viam TypeScript SDK](https://ts.viam.dev/) allows you to build custom web interfaces to interact with your machines. For this project, you'll use it to build a page that displays air quality sensor data for a given location. -You'll host the website on Viam Apps. +You'll host the website locally on your personal computer, and view the interface in a web browser on that computer. -The full code is available for reference on [GitHub](https://github.com/viam-labs/air-quality-fleet/blob/main/main.ts). +As you'll find out in the [authentication step](#authenticate-your-code-to-your-viam-app-location), you can set each customer up with credentials to access the data from only their location, or you can create a dashboard showing data from all sensors in your entire organization. -{{< alert title="Tip" color="tip" >}} -If you'd like to graph your data using a Grafana dashboard, try our [Visualize Data with Grafana tutorial](/tutorials/services/visualize-data-grafana/) next. -{{< /alert >}} +![The air quality dashboard you'll build. This one has PM2.5 readings from two different sensor machines displayed, and a key with categories of air quality.](/tutorials/air-quality-fleet/two-sensors.png) ### Set up your TypeScript project Complete the following steps on your laptop or desktop. You don't need to install or edit anything else on your machine's single-board computer (aside from `viam-server` which you already did); you'll be running the TypeScript code from your personal computer. -{{< table >}} -{{% tablestep number=1 %}} - -Make sure you have the latest version of [Node.JS](https://nodejs.org/en) installed on your computer. - -{{% /tablestep %}} -{{% tablestep number=2 %}} - -Create a directory on your laptop or desktop for your project. -Name it aqi-dashboard. - -{{% /tablestep %}} -{{% tablestep number=3 %}} - -Create a file in your aqi-dashboard folder and name it package.json. -The package.json file holds necessary metadata about your project. -Paste the following contents into it: - -```json {class="line-numbers linkable-line-numbers"} -{ - "name": "air-quality-dashboard", - "description": "A dashboard for visualizing data from air quality sensors.", - "scripts": { - "start": "esbuild ./main.ts --bundle --outfile=static/main.js --servedir=static --format=esm", - "build": "esbuild ./main.ts --bundle --outfile=static/main.js --format=esm" - }, - "author": "", - "license": "ISC", - "devDependencies": { - "esbuild": "*" - }, - "dependencies": { - "@viamrobotics/sdk": "^0.42.0", - "bson": "^6.6.0", - "js-cookie": "^3.0.5" - } -} -``` +1. Make sure you have the latest version of [Node.JS](https://nodejs.org/en) installed on your computer. +1. Install the Viam TypeScript SDK by running the following command in your terminal: -{{% alert title="Fun fact" color="info" %}} + ```sh {class="command-line" data-prompt="$"} + npm install --save @viamrobotics/sdk + ``` + +1. Create a directory on your laptop or desktop for your project. + Name it aqi-dashboard. + +1. Create a file in your aqi-dashboard folder and name it package.json. + The package.json file holds necessary metadata about your project. + Paste the following contents into it: + ```json {class="line-numbers linkable-line-numbers"} + { + "name": "air-quality-dashboard", + "description": "A dashboard for visualizing data from air quality sensors.", + "scripts": { + "start": "esbuild ./main.ts --bundle --outfile=static/main.js --servedir=static --format=esm", + "test": "echo \"Error: no test specified\" && exit 1" + }, + "author": "", + "license": "ISC", + "devDependencies": { + "esbuild": "*" + }, + "dependencies": { + "@viamrobotics/sdk": "^0.13.0", + "bson": "^6.6.0" + } + } + ``` + +{{% alert title="Fun fact" color="info" %}} The `--format=esm` flag in the `"start"` script is important because the ECMAScript module format is necessary to support the BSON dependency this project uses for data query formatting. If you don't know what the proceeding sentence means, don't worry about it; just copy-paste the JSON above and it'll work. - {{% /alert %}} -{{% /tablestep %}} -{{% tablestep number=4 %}} +### Authenticate your code to your Viam app location -Install the project's dependencies by running the following command in your terminal: +Your TypeScript code requires an API key to establish a connection to your machines. +You can set up credentials to access data from all the sensor machines in your organization, or from just one location. +These API keys only need [**Operator** permissions](/manage/manage/rbac/). -```sh {class="command-line" data-prompt="$"} -npm install -``` +In our example you could create a dashboard for Antonia with an API key to see the data from her location, and create a separate dashboard for RobotsRUs with a different API key to access the data from their location. +If RobotsRUs wanted to separate their dashboards by sub-locations, you could set up API keys for RobotsRUs to access data for each of their sub-locations separately, or you could modify the example code to filter data by location name. -{{% /tablestep %}} -{{< /table >}} +You can then either deploy each dashboard on a web server you manage, or add a web server on one machine per customer that hosts the dashboard for the respective customer so that they can access their data on their local network. +We leave this step to the reader. -### Authenticate your code to your Viam app location +The following instructions describe how to set up an API key for one location. -Your TypeScript code requires an API key to establish a connection to your machines. -In the final dashboard, these will be provided to your webapp through the local storage of your browser. -For development purposes, you will use an API key for your development machine. +1. Create another file inside the aqi-dashboard folder and name it main.ts. + Paste the following code into main.ts: + + ```typescript {class="line-numbers linkable-line-numbers"} + // Air quality dashboard + + import * as VIAM from "@viamrobotics/sdk"; + import { BSON } from "bson"; + + async function main() { + const opts: VIAM.ViamClientOptions = { + credential: { + type: "api-key", + // Key with location operator permissions + // Replace (including angle brackets) + payload: "", + // Replace (including angle brackets) + authEntity: "", + }, + }; -{{< table >}} -{{% tablestep number=1 %}} + const orgID: string = ""; // Replace + const locationID: string = ""; // Replace -Create another file inside the aqi-dashboard folder and name it main.ts. -Paste the following code into main.ts: + // -```typescript {class="line-numbers linkable-line-numbers"} -// Air quality dashboard + // + } + + // -import * as VIAM from "@viamrobotics/sdk"; -import { BSON } from "bson"; -import Cookies from "js-cookie"; + main().catch((error) => { + console.error("encountered an error:", error); + }); + ``` -let apiKeyId = ""; -let apiKeySecret = ""; -let hostname = ""; -let machineId = ""; +1. Now you need to get the API key and the {{< glossary_tooltip term_id="organization" text="organization" >}} and {{< glossary_tooltip term_id="location" text="location" >}} IDs to replace the placeholder strings in the code you just pasted. -async function main() { - const opts: VIAM.ViamClientOptions = { - serviceHost: "https://app.viam.com", - credentials: { - type: "api-key", - payload: apiKeySecret, - authEntity: apiKeyId, - }, - }; + In the [Viam app](https://app.viam.com), navigate to the location page for the location containing your air quality machines. - // + ![The location secret with a Copy button next to it.](/tutorials/air-quality-fleet/loc-secret-button.png) - // -} + Copy the **Location ID** and paste it into your code in place of ``, so that the line resembles `const orgID: string = "abcde12345"`. -// +1. Use the dropdown menu in the upper-right corner of the page to navigate to your organization settings page. + Copy the **Organization ID** found under **Details** near the top of the page. + Paste it in place of `` in your code. -document.addEventListener("DOMContentLoaded", async () => { - machineId = window.location.pathname.split("/")[2]; - ({ - id: apiKeyId, - key: apiKeySecret, - hostname: hostname, - } = JSON.parse(Cookies.get(machineId)!)); +1. Under the **API Keys** heading, click **Generate Key**. - main().catch((error) => { - console.error("encountered an error:", error); - }); -}); -``` +1. Name your key something such as `air-sensors-key`. -{{% /tablestep %}} -{{% tablestep number=2 %}} +1. Select **Entity** and choose the location you have all your air quality sensing machines in. -To test the dashboard with your development machine, you can temporarily set your machine's API key, API key ID and machine ID at the top of the `main()` function. +1. Set the **Role** to **Owner**, then click **Generate key**. -You can obtain your API key and API key ID from your machines **CONNECT** tab. -You can copy the machine ID using the **...** menu at the top right and clicking **Copy machine ID**. +1. Copy the ID and corresponding key you just created and paste them in place of `` and `` in your code. + For example, you'll now have something of the form -{{% snippet "secret-share.md" %}} + ```json {class="line-numbers linkable-line-numbers"} + authEntity: '1234abcd-123a-987b-1234567890abc', + payload: 'abcdefg987654321abcdefghi' + ``` -{{% /tablestep %}} -{{< /table >}} + {{% snippet "secret-share.md" %}} ### Add functionality to your code -{{< table >}} -{{% tablestep number=1 %}} - -Now that you have the connection code, you are ready to add code that establishes a connection from the computer running the code to the Viam Cloud where the air quality sensor data is stored. -You'll first create a client to obtain the organization and location ID. Then you'll get a `dataClient` instance which accesses all the data in your location, and then query this data to get only the data tagged with the `air-quality` tag you applied with your data service configuration. -The following code also queries the data for a list of the machines that have collected air quality data so that later, depending on the API key used with the code, your dashboard can show the data from any number of machines. - -Paste the following code into the main function of your main.ts script, directly after the `locationID` line, in place of `// `: - -```typescript {class="line-numbers linkable-line-numbers"} -// Instantiate data_client and get all -// data tagged with "air-quality" from your location -const client = await VIAM.createViamClient(opts); -const machine = await client.appClient.getRobot(machineId); -const locationID = machine?.location; -const orgID = (await client.appClient.listOrganizations())[0].id; - -const myDataClient = client.dataClient; -const query = { - $match: { - tags: "air-quality", - location_id: locationID, - organization_id: orgID, - }, -}; -const match = { $group: { _id: "$robot_id" } }; -// Get a list of all the IDs of machines that have collected air quality data -const BSONQueryForMachineIDList = [ - BSON.serialize(query), - BSON.serialize(match), -]; -let machineIDs: any = await myDataClient?.tabularDataByMQL( - orgID, - BSONQueryForMachineIDList, -); -// Get all the air quality data -const BSONQueryForData = [BSON.serialize(query)]; -let measurements: any = await myDataClient?.tabularDataByMQL( - orgID, - BSONQueryForData, -); -``` - -{{% /tablestep %}} -{{% tablestep number=2 %}} - -For this project, your dashboard will display the average of the last five readings from each air sensor. -You need a function to calculate that average. -The data returned by the query is not necessarily returned in order, so this function must put the data in order based on timestamps before averaging the last five readings. - -Paste the following code into main.ts after the end of your main function, in place of `// `: - -```typescript {class="line-numbers linkable-line-numbers"} -// Get the average of the last five readings from a given sensor -async function getLastFewAv(all_measurements: any[], machineID: string) { - // Get just the data from this machine - let measurements = new Array(); - for (const entry of all_measurements) { - if (entry.robot_id == machineID) { - measurements.push({ - PM25: entry.data.readings["pm_2.5"], - time: entry.time_received, - }); - } - } - - // Sort the air quality data from this machine - // by timestamp - measurements = measurements.sort(function (a, b) { - let x = a.time.toString(); - let y = b.time.toString(); - if (x < y) { - return -1; - } - if (x > y) { - return 1; - } - return 0; - }); - - // Add up the last 5 readings collected. - // If there are fewer than 5 readings, add all of them. - let x = 5; // The number of readings to average over - if (x > measurements.length) { - x = measurements.length; - } - let total = 0; - for (let i = 1; i <= x; i++) { - const reading: number = measurements[measurements.length - i].PM25; - total += reading; - } - // Return the average of the last few readings - return total / x; -} -``` - -{{% /tablestep %}} -{{% tablestep number=3 %}} - -Now that you've defined the function to sort and average the data for each machine, you're done with all the `dataClient` code. -The final piece you need to add to this script is a way to create some HTML to display data from each machine in your dashboard. - -Paste the following code into the main function of main.ts, in place of `// `: - -```typescript {class="line-numbers linkable-line-numbers"} -// Instantiate the HTML block that will be returned -// once everything is appended to it -let htmlblock: HTMLElement = document.createElement("div"); - -// Display the relevant data from each machine to the dashboard -for (let m of machineIDs) { - let insideDiv: HTMLElement = document.createElement("div"); - let avgPM: number = await getLastFewAv(measurements, m._id); - // Color-code the dashboard based on air quality category - let level: string = "blue"; - switch (true) { - case avgPM < 12.1: { - level = "good"; - break; - } - case avgPM < 35.5: { - level = "moderate"; - break; - } - case avgPM < 55.5: { - level = "unhealthy-sensitive"; - break; - } - case avgPM < 150.5: { - level = "unhealthy"; - break; - } - case avgPM < 250.5: { - level = "very-unhealthy"; - break; - } - case avgPM >= 250.5: { - level = "hazardous"; - break; - } - } - let machineName = (await client.appClient.getRobot(m._id))?.name; - // Create the HTML output for this machine - insideDiv.className = "inner-div " + level; - insideDiv.innerHTML = - "

" + - machineName + - ": " + - avgPM.toFixed(2).toString() + - " μg/m3

"; - htmlblock.appendChild(insideDiv); -} - -// Output a block of HTML with color-coded boxes for each machine -return document.getElementById("insert-readings")?.replaceWith(htmlblock); -``` - -{{% /tablestep %}} -{{< /table >}} +1. Now that you have the API key and org and location IDs, you are ready to add code that establishes a connection from the computer running the code to the Viam Cloud where the air quality sensor data is stored. + You'll create a Viam `dataClient` instance which accesses all the data in your location, and then query this data to get only the data tagged with the `air-quality` tag you applied with your data service configuration. + The following code also queries the data for a list of the machines that have collected air quality data so that later, you can make a dashboard that has a place for the latest data from each of them. + + Paste the following code into the main function of your main.ts script, directly after the `locationID` line, in place of `// `: + + ```typescript {class="line-numbers linkable-line-numbers"} + // Instantiate data_client and get all + // data tagged with "air-quality" from your location + const client = await VIAM.createViamClient(opts); + const myDataClient = client.dataClient; + const query = { + $match: { + tags: "air-quality", + location_id: locationID, + organization_id: orgID, + }, + }; + const match = { $group: { _id: "$robot_id" } }; + // Get a list of all the IDs of machines that have collected air quality data + const BSONQueryForMachineIDList = [ + BSON.serialize(query), + BSON.serialize(match), + ]; + let machineIDs: any = await myDataClient?.tabularDataByMQL( + orgID, + BSONQueryForMachineIDList, + ); + // Get all the air quality data + const BSONQueryForData = [BSON.serialize(query)]; + let thedata: any = await myDataClient?.tabularDataByMQL( + orgID, + BSONQueryForData, + ); + ``` + +1. For this project, your dashboard will display the average of the last five readings from each air sensor. + You need a function to calculate that average. + The data returned by the query is not necessarily returned in order, so this function must put the data in order based on timestamps before averaging the last five readings. + + Paste the following code into main.ts after the end of your main function, in place of `// `: + + ```typescript {class="line-numbers linkable-line-numbers"} + // Get the average of the last few readings from a given sensor + async function getLastFewAv(alltheData: any[], machineID: string) { + // Get just the data from this machine + let thedata = new Array(); + for (const entry of alltheData) { + if (entry.robot_id == machineID) { + thedata.push({ + PM25: entry.data.readings["pm_2_5"], + time: entry.time_received, + }); + } + } + + // Sort the air quality data from this machine + // by timestamp + thedata = thedata.sort(function (a, b) { + let x = a.time.toString(); + let y = b.time.toString(); + if (x < y) { + return -1; + } + if (x > y) { + return 1; + } + return 0; + }); + + // Add up the last 5 readings collected. + // If there are fewer than 5 readings, add all of them. + let x = 5; // The number of readings to average over + if (x > thedata.length) { + x = thedata.length; + } + let total = 0; + for (let i = 1; i <= x; i++) { + const reading: number = thedata[thedata.length - i].PM25; + total += reading; + } + // Return the average of the last few readings + return total / x; + } + ``` + +1. Now that you've defined the function to sort and average the data for each machine, you're done with all the `dataClient` code. + The final piece you need to add to this script is a way to create some HTML to display data from each machine in your dashboard. + + Paste the following code into the main function of main.ts, in place of `// `: + + ```typescript {class="line-numbers linkable-line-numbers"} + // Instantiate the HTML block that will be returned + // once everything is appended to it + let htmlblock: HTMLElement = document.createElement("div"); + + // Display the relevant data from each machine to the dashboard + for (const mach of machineIDs) { + let insideDiv: HTMLElement = document.createElement("div"); + let avgPM: number = await getLastFewAv(thedata, mach._id); + // Color-code the dashboard based on air quality category + let level: string = "blue"; + switch (true) { + case avgPM < 12.1: { + level = "good"; + break; + } + case avgPM < 35.5: { + level = "moderate"; + break; + } + case avgPM < 55.5: { + level = "unhealthy-sensitive"; + break; + } + case avgPM < 150.5: { + level = "unhealthy"; + break; + } + case avgPM < 250.5: { + level = "very-unhealthy"; + break; + } + case avgPM >= 250.5: { + level = "hazardous"; + break; + } + } + // Create the HTML output for this machine + insideDiv.className = "inner-div " + level; + insideDiv.innerHTML = + "

" + + mach._id + + ": " + + avgPM.toFixed(2).toString() + + " μg/m3

"; + htmlblock.appendChild(insideDiv); + } + + // Output a block of HTML with color-coded boxes for each machine + return document.getElementById("insert-readings").replaceWith(htmlblock); + ``` + +The full code is available for reference on [GitHub](https://github.com/viam-labs/air-quality-fleet/blob/main/main.ts). ### Style your dashboard @@ -649,11 +773,13 @@ If you look at line 5 of package.json, you can see that `./main.ts` } ``` -### Full tutorial code + Feel free to adjust any of the colors, margins, fonts, and other specifications in style.css based on your preferences. + +## Full tutorial code You can find all the code in the [GitHub repo for this tutorial](https://github.com/viam-labs/air-quality-fleet). -### Run the code +## Run the code 1. In a command prompt terminal, navigate to your aqi-dashboard directory. Run the following command to start up your air quality dashboard: @@ -662,7 +788,7 @@ You can find all the code in the [GitHub repo for this tutorial](https://github. npm start ``` - {{}} + ![Terminal window with the command 'npm start' run inside the aqi-dashboard folder. The output says 'start' and then 'esbuild' followed by the esbuild string from the package.json file you configured. Then there's 'Local:' followed by a URL and 'Network:' followed by a different URL.](/tutorials/air-quality-fleet/terminal-url.png) 1. The terminal should output a line such as `Local: http://127.0.0.1:8000/`. Copy the URL the terminal displays and paste it into the address bar in your web browser. @@ -671,238 +797,28 @@ You can find all the code in the [GitHub repo for this tutorial](https://github. ![Air quality dashboard in a web browser with PM2.5 readings from three different sensor machines displayed.](/tutorials/air-quality-fleet/three-sensor-dash.png) -Great work. -You've learned how to configure a machine and you can view its data in a custom TypeScript dashboard. - -### Deploy the app to Viam apps - -Let's deploy this dashboard so you don't have to run it locally. -This will also allow others to use the dashboard. - -{{< table >}} -{{% tablestep number=1 %}} - -**Remove any API key or IDs before continuing.** - -{{% /tablestep %}} -{{% tablestep number=2 %}} - -**Create a meta.json** in your project folder using this template: - -```json -{ - "module_id": ":air-quality", - "visibility": "public", - "url": "https://github.com/viam-labs/air-quality-fleet/", - "description": "Display air quality data from a machine", - "applications": [ - { - "name": "air-quality", - "type": "single_machine", - "entrypoint": "static/index.html" - } - ] -} -``` - -In the [Viam app](https://app.viam.com), navigate to your organization settings through the menu in upper right corner of the page. -Find the **Public namespace** and copy that string. -Replace `` with your public namespace. - -{{% /tablestep %}} -{{% tablestep number=3 %}} - -**Register your module** with Viam: - -```sh {class="command-line" data-prompt="$" data-output="3-10"} -viam module create --name="air-quality" --public-namespace="your-namespace" -``` - -{{% /tablestep %}} -{{% tablestep number=4 %}} - -**Package your static files and your meta.json file and upload them** to the Viam Registry: - -```sh {class="command-line" data-prompt="$" data-output="3-10"} -npm run build -tar -czvf module.tar.gz static meta.json -viam module upload --upload=module.tar.gz --platform=any --version=0.0.1 -``` - -For subsequent updates run these commands again with an updated version number. - -{{% /tablestep %}} -{{% tablestep number=5 %}} - -**Try your app** by navigating to: - -``` -https://air-quality_your-public-namespace.viamapplications.com -``` - -Log in and select your development machine. -Your dashboard should now load your data. - -{{% /tablestep %}} -{{< /table >}} - -## Organizing devices for third-party usage - -Imagine you create an air quality monitoring company called Pollution Monitoring Made Simple. -Anyone can sign up and order one of your sensing machines. -When a new customer signs up, you assemble a new machine with a sensor, SBC, and power supply. - -Before shipping the sensor machine to your new client, you provision the machine, so that the recipient only needs to connect the machine to their WiFi network for it to work. - -To manage all your company's air quality sensing machines together, you create one organization called Pollution Monitoring Made Simple. -An organization is the highest level grouping, and often contains all the locations (and machines) of an entire company. - -Inside that organization, you create a location for each customer. -A location can represent either a physical location or some other conceptual grouping. -You have some individual customers, for example Antonia, who has one sensor machine in her home and one outside. -You have other customers who are businesses, for example RobotsRUs, who have two offices, one in New York and one in Oregon, with multiple sensor machines in each. - -Organization and locations allow you to manage permissions: - -- When you provision Antonia's machines, you create them inside a new location called `Antonia's Home` and grant Antonia operator access to the location. - This will later allow her to view data from the air sensors at her home. -- When you provision the machines for RobotsRUs, you create a location called `RobotsRUs` and two sub-locations for `New York Office` and `Oregon Office`. - Then you create the machines in the sub-locations and grant RobotsRUs operator access to the `RobotsRUs` machines location. - -You, as the organization owner, will be able to manage any necessary configuration changes for all air sensing machines in all locations created within the Pollution Monitoring Made Simple organization. - -{{}} - -For more information, see [Fleet Management](/manage/reference/organize/) and [provisioning](/manage/fleet/provision/setup/). - -### Organize your fleet - -If you want to follow along, create the following locations: - -- `Antonia's Home` -- `RobotsRUs` - -For `RobotsRUs` crate two sublocations: - -1. Add a new location called `Oregon Office` using the same **Add location** button. -1. Then, find the **New parent location** dropdown on the Oregon Office page. -1. Select **RobotsRUs** and click **Change**. - -Repeat to add the New York office: Add a new location called `New York Office`, then change its parent location to **RobotsRUs**. - -{{}} - -## Getting machines ready for third parties - -Continuing with our ficticious company, let's assume you want to ship air sensing machines to customers as ready-to-go as possible. -In other words, you want to provision devices. - -Before an air sensing machine leaves your factory, you'd complete the following steps: - -1. You'd flash the single-board computer with an operating system -2. You'd install `viam-agent` -3. You'd provide a machine configuration template, a fragment. - -Once a customer receives your machine, they will: - -1. Plug it in and turn it on. -2. `viam-agent` will start a WiFi network -3. The customer uses another device to connect to the machine's WiFi network and the user gives the machine the password for their WiFi network. -4. The machine can now connect to the internet and complete setup based on the fragment it knows about. - -### Create the fragment air sensing machines - -In this section you will create the {{< glossary_tooltip term_id="fragment" text="fragment" >}}, that is the configuration template that all other machines will use. - -1. Navigate to the **FLEET** page and go to the [**FRAGMENTS** tab](https://app.viam.com/fragments). -1. Add the same components that you added to the development machine when you [set up one device for development](#set-up-one-device-for-development). -1. As a shortcut, you can use the JSON mode on the machine you already configured and copy the machine's configuration to the fragment. - -{{< alert title="Tip: Use the fragment on your development machine" color="tip" >}} -To avoid differences between fragment and development machines, we recommend you remove the configured resources from the development machine and add the fragment you just created instead. -{{< /alert >}} - -### Provision your machines - -{{< table >}} -{{% tablestep number=1 %}} - -For each machine, flash the operating system to the device's SD card. -If you are using the Raspberry PI Imager, you **must customize at least the hostname** for the next steps to work. - -Then run the following commands to download the preinstall script and make the script executable: - -```sh {class="command-line" data-prompt="$"} -wget https://storage.googleapis.com/packages.viam.com/apps/viam-agent/preinstall.sh -chmod 755 preinstall.sh -``` - -{{% /tablestep %}} -{{% tablestep number=2 %}} - -Create a file called viam-defaults.json with the following configuration: - -```json {class="line-numbers linkable-line-numbers"} -{ - "network_configuration": { - "manufacturer": "Pollution Monitoring Made Simple", - "model": "v1", - "fragment_id": "", - "hotspot_prefix": "air-quality", - "hotspot_password": "WeLoveCleanAir123" - } -} -``` - -Replace `""` with the fragment ID from your fragment. - -{{% /tablestep %}} -{{% tablestep number=3 %}} - -In [Organize your fleet](#organize-your-fleet) you created several locations. -Navigate to one of the locations and create a machine. -Select the part status dropdown to the right of your machine's name on the top of the page. - -Click the copy icon next to **Machine cloud credentials**. -Paste the machine cloud credentials into a file on your harddrive called FILE>viam.json. - -{{< alert title="Tip: Fleet management API" color="tip" >}} -You can create locations and machines programmatically, with the [Fleet management API](/dev/reference/apis/fleet/). -{{< /alert >}} - -{{% /tablestep %}} -{{% tablestep number=3 %}} - -**Run the preinstall script** - -Run the preinstall script without options and it will attempt to auto-detect a mounted root filesystem (or for Raspberry Pi, bootfs) and also automatically determine the architecture. - -```sh {class="command-line" data-prompt="$"} -sudo ./preinstall.sh -``` - -Follow the instructions and provide the viam-defaults.json file and the machine cloud credentials file when prompted. - -{{% /tablestep %}} -{{< /table >}} - -That's it! Your device is now provisioned and ready for your end user! - -Having trouble? See [Provisioning](/manage/fleet/provision/setup/) for more information and troubleshooting. + Great work. + You've learned how to configure a fleet of machines, sync their data to one place, and pull that data into a custom dashboard using TypeScript.
## Next steps -You can now set up one or more air quality sensors for yourself or others and access them with your dashboard. -If you are selling your air quality sensing machines, they can also use your dashboard to view _their_ data. +Now that you can monitor your air quality, you can try to improve it and see if your efforts are effective. +You might try putting an air filter in your home or office and comparing the air quality data before you start running the filter with air quality after you have run the filter for a while. +Or, try sealing gaps around doors, and check whether your seal is working by looking at your dashboard. -If you're wondering what to do next, why not set up a text or email alert when your air quality passes a certain threshold? +You could set up a text or email alert when your air quality passes a certain threshold. For instructions on setting up an email alert, see the [Monitor Helmet Usage tutorial](/tutorials/projects/helmet/) as an example. For an example of setting up text alerts, see the [Detect a Person and Send a Photo tutorial](/tutorials/projects/send-security-photo/). +For another example of a custom TypeScript interface, check out the [Claw Game tutorial](/tutorials/projects/claw-game/). +Instead of displaying data, the claw game interface has buttons to control a robotic arm. + +In this tutorial we covered configuring a fleet of machines using fragments, but to automate the setup process further, you can [use the Viam Agent to provision machines](/manage/fleet/provision/setup/). + {{< cards >}} -{{% card link="/tutorials/projects/helmet/" %}} -{{% card link="/tutorials/projects/send-security-photo/" %}} +{{% card link="/manage/fleet/provision/end-user-setup/" %}} {{% card link="/tutorials/services/visualize-data-grafana/" %}} +{{% card link="/tutorials/projects/helmet/" %}} {{< /cards >}} From c12df6720fa812d03d762bd69e1f89bc65da2d66 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Tue, 27 May 2025 13:11:02 +0200 Subject: [PATCH 07/17] Cleanup --- assets/operate/spa.png | Bin 37636 -> 0 bytes docs/operate/control/single-page-apps.md | 10 +++++----- .../get-started/other-hardware/_index.md | 2 +- docs/operate/reference/naming-modules.md | 6 +++--- docs/tutorials/control/air-quality-fleet.md | 4 ++-- netlify.toml | 2 +- static/spa.mp4 | Bin 0 -> 105488 bytes static/spa.webm | Bin 0 -> 67150 bytes 8 files changed, 12 insertions(+), 12 deletions(-) delete mode 100644 assets/operate/spa.png create mode 100644 static/spa.mp4 create mode 100644 static/spa.webm diff --git a/assets/operate/spa.png b/assets/operate/spa.png deleted file mode 100644 index c2f1282bc6ec602c46ed7ceb02dcb9b4ed780c8e..0000000000000000000000000000000000000000 GIT binary patch literal 0 HcmV?d00001 literal 37636 zcmc$`WmuGL7dA@AAc9B;2#ktS64K28lF~4ADcwkSil_)8DGkz%bdR9YT|+p8fW*+< zd^gWy%=3Of_CEHX?QwwPeP6ZKRp&a_Ilfj=k|6|9fzZ&<2<2oStD&J`0-rIw@Nj@9 zuk5Nc(9l3tR+5q`a*~o@6(Bwgz7^Jhm;p@L zO;2MBIX@aCgOS0hf}fHx?Xhd}JyJ8wfZH3qxpb>Z2Rx?tfm6KWLE;&XG@-K8&6=CT& zqb<5JHkg^3I;q-APTbnR@llvE?fp?af2V&~0%LfmIl~iAFLrf_t)CY7!xJnQ{Z3~N zow5}DMNeNa3rH={MMM->_Fl+#UyCURKjJridHkK}l1b^tsZ1{iLpO`x%Zj0U+FU(m z-njDfS-7~pjwCZ$t6%!frTRG7yBVInluDQza*cj$*h6U^X6{U!DXD@Hs zb8TrWGdR00TMDc1#6xcV?(})%087_*AcieR5!8wML>v8L-&h@8)W$!ro${| z&;T9HV{{>7Y})`HJj_QEjf)e}N!wkdCB)m&>g6j6dtbMgAELKEV?(rcwb2H2?h2iI z_|%HIvfVLjEwYQo3h*qrdGlswMRh<88g~Q+gf*p#^2gxiCYmMt(km%}Vcwnv?6BsW z3judkBxi`cKHvI~Sto!-F&k)p8%+X2{|Yk<9XBiB8W^MdGjkd3La;;`<{El-I>v1* zna_^~@Df`n9ntl1;4O-d6v7xJ9B77tPdPwsV7yjI(pNb7;**i+rZ^LjYaN6;fkEkx zjMwD@qVAy6ztj|`&XCB%V-8`?pjxI_=5|4^2kk?M(nT%tyoh{5ZhW}L(wbOy#}=Q< z_`z*FnbxpbQxB$Of~A(JS&~|iD2T6xVivh&pp5|wk|7T00C&B*{w#unn4KQ$wM-Q8 zjdC0&$eZ`fS+rJCg72qZVR?r8w9ImFU!yUJc;0ek@{!|qk6I5^kER0CPrMxb;lR4^ zl`q#!noXFr35zJlD7#zRo<)D^E;}B7X3KLxdO&i(=7uKp=F42nb7_8=WHGku@o)5A zPraFXXY;vg&dc$<_J%NR=}W#Z4L>BeY<+k|>0m_ur2e%21Y!Y~3Xyj#Z`$HDzwihO zC<|0k$h)6>@B7_G@Y@^tk1;=TJ$lh`zXWX0Kzp~E#DN(1l?lCP)Q!$qQaSni#SF2L zt8($O@8sxAO-)_Ql1*Dpk2sO0@}?2p`tMhwk0mt0Nl{H51f9=zcz2#UQ6HlpV}?jP z%JNY8!88$L7em!0)urBLp_5n?^6*Ih_=XOY}c|$FHMy zD$RdfaA!2EE2ktQPE}dmJOADex2Mf9@$t3e;+?7;twmh2EznEA@%kacA;BODvJ)#j z#dklY<_CC(t`D*e;*dUnBmL&#H;r!+-%Q>h-h7b<$-Bu9%6G?h#q=@D#oREHG>dbp z-*H=%Ui9uVf^tJYFbl`BGVe3jXo%+bsqU*R=9A~~=1oJ-3#7GnRiCI&<&PB|Jf_LC zFQCn7RyYqhxxWv0CS9uSnd@QtFwDP{fm8If;6}+OwfS`E__kL$aXD!@D$Z#?rF!AI zUAnZo`MM2NeO824!XaPgu?vOgH9y1pG`)v91dYu3D7xkKuix^uR$xK=e;*h{^A zu*bF~new5GQtv}UncGgR73hooDE4a4HIJAaf}YkxtHKrh4;#OMsX z5ttp=AEXfcSiE?5?ihX7z1RP?E%8G<`|Id;iXsi}C`*J(#J{|tdPzV)$U@*vYfsb6 z+{hI~{)zr0?=$WpE+_AWOvZV}=NjIX`g^U*iOb55rXNW?iqh^LAN>TMADKUT&bobc zw0yLB^d4K3;NamcZA%!3|6G%lbXXjFeZ98t^OGMHPZr|J;*(`RKln;N^5AWS4s%rpe@tctcn;3Azd0T;4CtTYWN2^LK|to`gyTeq4RXXrrq6 zr26h8qwDMNZ%JQ$1?&aP1k&QA*o8jn`_&nH!a>7idYX+L`@QF$_s#EHn4L1GK#^Me z#pWd?`k2LX`oqnd4tCR%fv$eYh$4n!WxdNOoI*k=YEk>Q6XS`w2{mk`{?Riz^*$3m zs(zd1@x5eX#(uMx15MxDx|>;N2x_t6pkh!ML3@o;wc+XDNqZC>L-l<-|* zrgP3((a^;DlI+q>pJH;qh}h5rTW{Yx#}fXhQ3o;OZmKGzBNl#||z8g;~Vgd*QS8sZy;H}zerU-a+r zwK*s??|V$~+!hkvQrffsaXv<5O?TbD@^oC3L~zH2+r(u}y~U!cU#6L(*~KsX_~e=G z1ixS7LQ-eV*k<4iowBKd0^Y>k0}YmdbP&UR^sNgHv>1LgOFnck>xYffT&%>42OsWk zrFqojrjg*HMR=nT2d$b?Yt>vw3+6>zP$87Edrym2T@|~kz%D#mqYT<-6eO}(GA7%L z*)_X$CYj@X0$Vumzag7>VRuHsX-ov0tfYwoaIB`8ww$@5A{sOB84nFT)Cvs?_=FDp zPys&xzVGc$WaLF>z z)R>iqwu`o+f}n|m9oth=hi7JN9(ImbRnUYz1c8rsW-d>`9(K0&&Vn8ycmF9N2zJ1WH5XKSEd8rG@Gp_OmM$)ig6!<> z?(S^vTxm{}Svk5`IoN}* z+I{-W!PQ0N?%k`7{`~oOoMs+Ye|xfb{$&|r#6_6kFRu3C+_@I0_TZ}3(7lUJgoBaa#9BE zYCSy7ioeYRpD5WQ;du~v=G#khG?W*RMhIJ=gfRZ*jXxa_LjuULn=w&`7pV+(;Bans zEkY@T7I=*!9jW@#ADvMYWz4U!EmdXLT6IxI#i<(rxs%B*79#W824V;}5HejsibqOP zTL$`N7+_-HTk;NXL9RdvX@5*cVU$+!v4BH3%RNQMklW@k4n?f;aFn5-kLZ zGI-N^G*(c;1!4Lb%0qf`V-DwM6k~V)x+1a;!$qX)yNz-uiYpjZz@e4o1F)01h?(J=|KL&y+ zF&H#-9730{@e@9flJfLSJPTd0tsL}hX)UBKcoL=9vNwOwPf+kV4DR7cNXMj0sKWGcY?XT%Und`kt1 z95+7ZH!5s9OuI2=SRk{AF7&^Kc4InoThp2J zR7U@Vo@WgGx)MB-zQsxVPv?QMAk#$+HjWvcSSQe#0v&0!!$+Dz9{V^;SL>o~>K=U$ zEA@Lx3mAW#h!&Uy;ucuNvT>7`Y19mjsNR4d^Dd?)*$sx?LkNtTKZ7Zz zTH5#}*cV!y+j6D)43rmYd?G*Zt9c-kV#!nOup*jvc35aTx|ctewbVJb&|!G6f8PSj zbCdfA%jwU43*F%02JOre8J&$BMa^P4=OmXe*)6>J<)8QR@}2H?;QsYW2p%_oZDCd2 zieb`uD{TE-sbQkX;=;@uah^5$y{-ysH}dtM-lnXVMzlw?Z8N+PX~xxiwo6XHZoDEzs>{hUZhO=P*x=)fCCc+P0|^O_XlJ zOe#{(wYsqJ>pT$=G3DnH3iuwue~zaB$V)u#PHI@0%XfzAt)?2=?h{wu)9hTk-Zjdx zh2@*Y7w9Rr&eQcqFGZ}9;Kfw}rNT+@j~w?RRUIK{7idaQQ3GUu-Tu`t_uQreV#!b9Na5`ae^Lj>QR0_Zp_L9sHpB=$nz~(`2aK__!;f?(w|)qqO1= zdsW`0kMN)(#!oM|2XKfVQ4(&7k?ApfpGqd1ftTA>&%c`k0 zGW9jVb;0pf%3<4;_%xjqk%KO|5?rAG?FgOmTBy&&x=)=8HKxww<=+>af$4vOU*bJdl`af zhl5ldY9A4-+Q+2uJ;?Z$Kr#6;`-$!1NN2Tui*VuKGlm*pO}FYQe&2wZ-X?q9imn1~ z%NRcMJNrK=)Jii)x}n$T9R6Mu#EjJFy-Hay$CJjxxoR-G%D8#1LGk>omhJ8;)Lx<0 z9d2OB^1yeVcl4oD!{wrz&2etnP8+9>Z8yW)8dhrF+Ws67kEE)mV?!a+Ba56jm-X1r z>)nA2b)T+N9hMypANpU~E`pN8e(>mV*?2jg+)wj2_5OZQHfmj!x+sPSd@+Q5&XEro3YrqHfFf`?5y@hnf9^ z(QT{3{PB>{$4aJBo{aP?w7c%=;%S;|UTusTMPe3zuP@oBfvnVglP|h2Oh>8ssx&Fi z(`A;VKC| zHFsXjx-C?I8yl)0^&YrzUoy8p{&Qu^zWF@sI%=tNlvbomvhcp=>t0^x$m00lM$DMg zg_h@eq18&UeA-C)q~fPzahxK4%ybGB)K;_QZS?e+4XU+k6B84{GIy@Ea{e(5vPzH_ zC2Z^Kw3(CJEaBu_Yt~JkBcsUnNanA{Az&{I9i0g*&|rh@!mU51p#_=}ERZnLCw-Xz zduf7+r2@;-TzKAq7AXIgM90DiEGl}aONv2AjAw9bL_Xq$7K#D%+C??^NK9lnZ{k!7PFaWz9!yQm@ z1Rgyxa2;YX7D@c^G6WorU2Qud0nb#pz)*2R>5K$_>vPp(<|4_zWzo=eNsq3h_WhX- z!|P>`jp_gfKB_&$kpV$i6pYJs|3#g%*dCk}@w0#N3D7hKIz~u95H?E3#CQZ-w?oQs zx>3Cm$q@OiNXCcgKc3Vy{_=7k3-pP;5p|G(MQgSg*v&Yo)rnckfJw#((I%Pxd&dK= zn~nxB;Sm+8NsuB)$s!5k*Ql-Qs3uve&IVEaMYYojpY(_XwS9;vdTLMdyBB0A zW|=mk5$Sgyl>)Kv-=Yfu#cp$~_}`9!CAj&wOW+f*1ieQ7X9-qd-|9)8fTs4)9zO-~4+W!?4y(g6C;FU+O@*J2o^~0px4uy9qi}s zp)^WQ3RaQrXq88qG)_Gr8mTB1%SJt10?~pKZl?by6zL%!;DQ57YHbtkKSk3ZC4(O$ zi9-J4|9Xh#bY_B;YR8@f`XXw>N0NI5N?)(R87Wr zK()yuu;^hMqv=^Z8XAfTJNOH|@4AeC`Y`_|AVUXs+5d!XfT?u&EU23_0227$1+Z`v ztn$D62CVXbZ7w|0o%dxZh#4IV*r@+q=c2&T;Y0ubG$b&?43#EWMI!JeA+;`WQQQ6O zNvQVR{YkQ6aP%{l8S2!2pm%;S-xgkRy3x=-R$`Fk z-%e68;R-ic--jC!9jp%LzVqE5)oSr3f5Wa)sLATy>vgzcC$v#((i0Iz!CtLp5As{xOWr zsrcG4@7viom_)(@eZspv;3X{s*Vtm+DrS$gRf2}~>Lihq<;<~0&)pX~(6U?`ualMB zDIU1KNv3qTd@T*juY~}123*a#q#G|MR|>oELc&Xp93MjC{Li*!^qRb?RyJVu6^vHL zE4gXaeJMhE_V)H=z8VyXymr=zdRKySqdKQWV}Vf$-D+Da_QtKC(LB|A4+>Y?s?2+- zY`)h%FY`;XtN!GFv75%$;eCj358i+H>kNVX#OL@Ruv_Ap|3p7miAEhxm)3mzlUmDD zbiH!e_HzKb+xXMai4^zg6)|3D$>D@W+N=n{B70;?ikAFQI ztydn6bI+rL@6P?$3Ef>?<$4ZHqpR>zx+0U`S1+eBuvvNhS{~Ig}l?!d5*bj!R=|2RNM9bH~)Zs9*H7$GkT&c8h;iqUvzkd#d?#19_pr zl*<47<0-X(lPO1SjcTTJNg=eGoYf@4d03Gzq0O{$yN&vwlOgS^Pu#L%f2s)LShvRB z4#2k+R>L`Uaktj##2!ElssW$iy5GV!=@+|fr19MwbnCbi`k|}VaZW;gBGqd(|1Pdu zVfRR?_Xee@oQW)3^U*VS)U1|L0_QjTx<&Hg^gUV;uiDYB%r;KposN4OO}el81eR{Y z!U*uLd@8h(6|GQ8Vd#;em?nzwEh(`8QIWl1Tpsuk<$sPe%6UX`HIcz4c`PwFpQC^6 zdvFz&k3-~bSfuX6J-&R#GTVvr54Nt$11-}&yS*P=y)ykauo+V4+RxAK9TSiM1|=M%ruAK5VX^J7XiV}sy+}DF0BLl^3va0kCeR;u|N2o14rBO`Fsu2w+IUcqAI=7iYVlawvUbM%I5`oNl@oQ(btRG|xP5r+Fma z3Y=|0zLhCEheJ=;6LfEq+FBkwu)C>*94mH4^4U$28m2fLw^2L1#U~k|B5n>Vfk?Ex z-}uQOZ@pdn;|bnuQ*ZjmIWAGz)0AWBfWIvzh@&qIOA@t#RG8hF||F^e_YP zOgG}j<=JjO0^wYBeObxFr~YiG+klU(SPS_gM|+gUr^ygF7+ZeUBN03P2Ju0$_~aYF z{5A?*RDEYy{aA5%ajJKDajt-{bE(ml>&I8Q@KJ*&-c;gmfw>0zxKbEYa5HUfyHB}l zo#$mnI3cViYaAR3wnC%3iuZy2XY1kGQ;v~Ii}1!ma_hzDVnp!&c=drYhIC-r<8>7C zxC89GIzLw2Q{#y&zw7!W&l&HG6F-_NQbv_YG*YE3hLOi+tf#KPOv>}Qa?^go z^K84_z%$mNO5q6Y(crfBZ|t29;Pyx_IDNMBUKdO0ha4P(Iw!Mcp8~!2Cq+cG!sFQ2 zR})EgDOHvr( z3z3*D2rEY^#hS|GqfY6FYj^J9jQ4k)Ot67QIDp ze-MuO86@w$_9>K_5h(^+hzUzF)~xkM=V42y`2x2I`An0X$=x%|;nu(au{eK3?ek0| zZFVjPiyiFz;35;lXg;l?%;$LL#T4@ZK7+yKmOCU+!e^)!M@(Drf@}I00EMjL6EkK_ z^Spi>F=FArkoSH=nR1NA+x2*GRu}psRzrN$r66%%w&LeeVCjiM#mP~E@1Ce=$fi=e zf6if|4ny+U?2oPbt@4OmHetJ|vrk56h~2FNv#O%qg8j#sMNgths=gm>sD2YjZHqb5 z40TM`9BAI2%Hsj6zA@VDpQ}+crMAc4p4xu%3xeje0Bfoq{yY;WSI7c{s`XrsCN)H>R==h)y{;C-!G=8pZc;IB9yP z0_X#9R*+ZPTB_`ge=@PVI6JmK86{w=1t;XXw`+#IDE(U4sLN*Ar5(OB5MY{CnL^v8 znM}GNowM$%Rl3#udMrfD;&+s*_5{FtRV6a=OVWr}+&JQLv4}uS+@Hve%o1S$1abL? z&bWK4elv>oz9co?*P2NbMQ-=&4RFzbRv+Ay9`$RUiqIAK5skx3=l=b}|pF6K0nbrM<;xg%aA*GVQTt)ln9;>YL9neV=TLHJCM zc5T1&Kf8w)S82#~Z{?0{ZmL(oOi$HX<5nv{%ju7YN87h1HHk)qE{^6Aq*YGP0gdrp zo;S`u)#CrggMm9_=~5X!P4|3xu|Wmtr=PG3^jDvnu1u0J6ePX7_%X~{^ZiGv$8DJC#d+pCQEM;b1alR&A?~ab0)|CN z6Lg=jfclQSsFGYsq*8so^f$34ZS~A)w<$Yu$Bg;&tuI9OWAsLv`-||I^_m$&wT5NZ(m>E z{8C6@F!oSvwKYo<3qXvE8Z-Xkn|SV0%zF^Ct&AY<@FowZt>}%X?%San6FfN(6BTZ> zhRT(u!|4i1B9W1cop>0(e=M{mrp?0gnk4`6ENf$g*{|SGmL{;MQK;-H!6=_{`+c-5 z{&Iv*p=R;-;3gLt0sUikC2?-Myp5tlBL6ck!Z#KE9@MVIR*3p4q*5ks%u1leH#ut^ zmH1nWF#gj#GD&3x%^f0YmQ`Wq%v6)~iHufsMb*>$^UjLug>g4x#gB&&7v&xC^;%Z8 zucCrJZDB4}DzyYVoDX77a!bE37U%p$>#IG1G(F(%i!PDLcQv>hPmLgh-wGMZSsBia zcZ2(!=8O4xKKDP>DAaj3eFb0I5G)(QT}yF``@Xi7YEKk{Jh&FfeNIzggwfV5VGpC z1=(^YG$i-270mYckdNCfXnw(?m~a3db+x_E1V?UTP^CF7yqBrpW_evty7JV^x@|;3 zCx56uYMX-aR{##W0nib5_YQo9H8Z> z{O(UTIvml%g9p%D&)@%sON4=!xjy`NOKBVaSmI zrX|9|^-=nW)ByU(+HrD3G4131$fP7BXYxA5$5>ydu)m$7VRRCAbagp}_8t&)^5diM z(m>YO5;U;S`2VJLCV;~2MM{^TSRh*fSfJ)9z>ng%L4Y-S_5XQtBBMt#owq8<^Po0b zHqGZ&nx)g|nwf3atqe3l|A11J+RuqRu<@a66T7~(r`1l2BdvTt)v<_Qy#R(n&!)a= z<`i#GS{cXMuhjJR{k<#q1cGi15Z*iIaquhXO+JoMO!86=SqP548vvOAkWoyES=;UW z^VGu$w<%ZmMT5#^Y`x|+U%du5-L{ytpnu4x1&TaFUy8y8J1v{>vYLkX8ckl#Nk{98 z$9$%Q7IiCu6<)cpkL4^PQND&EOGtor4@DfEwU^Y*LP8J_$J(<;gmL zR3X2XDKkBssAo9s)Ibc2lW$}Q5Ff#dzntLRa4AB7Leh-+fFD*%}SlkWo zquS^r|J^%`3ZE}Ek7goTs~5Sjh-I%9>PRCSQv!<^HghpPlc#3~DKM3hY8V$at(R_D z8b3R(Vc?Mh$S6Zw!4}xHzgH#19Ppg!*nUps?a4ZetSc901#nQ$Woa7eEYjg6Un$= z2NYW1m6SpS;~_7rP#}=bm;^{HW1+RO;3fbeu^HDM|4dqk8~Ink&et7sz(E?7pP6!# zpIx3UiP#* z>;iJ7!9=2#)O_}pVwcDL)n5D7?yYJ57Zak#3pc%i$WuT2u$6$l5}+RF`M7R~dI6X7 z8W6tL)J%JI;}BAj#yl?OyeIv(?26~xsGYwqbokv_5h?q7Y9Vp}hbI5=TeaEUbT-b_ zC;p>QEo|{1v8{Snq<&bC?rl<)A|u$euST{!SpyJ(ua$kd?u-;Yn#F`mG4b)ieNzEa ziy_UYoCcuXazJ}M30&&{-&OU5fOF~D!s061ncoNszr_c=gxIHU-<10G(T0Kzv1&Xw^` znWw@R{yaehh zYe&4k$xtu!17J#|sk#RmJ)OOOyk@Wk(!C{N;q{24tT#te6b7bren%Myr*77RVP&xi z0NdHi(747-J;wC81VFfUJez?&T86yXU4isBM5zjFl>@exqQI(yTen$1MHS?hc`ke%REhXj5G;Ml^&59~_A zG?vJ#!|misd?X6z|cEWo`h7 z7etDeZ^?$L4ZOs43W=*yi~)j7`<>d=C@pyc`);kMqR%Ptl^*4ZjORd#&*D1l^1Sr) zaq%5a%Nm)6fw-R=TP*&~v5x~k1FV(9mzRWL6MZn%*{t;ZvaAh#QI)MJrhewkC|%;c z`HQ{C+~D23s`>1A!)FKdL~Q`;&W~P2z6=XKQ8#w%ydPh?uRA7K#Z5XgiFOCLMV@?y zOF5lMRF*5-XFg1i!+@r{#=~l7VE8v5e06CVG&oLio9ukFY~N^pstP-E96G%h!Qbk7 z2oR{@Ncn|eEW2DbkxZF))u|%h^$0(J;O4{A7V`pOiJq=;QFEHUI#sw_4plkrNfClW z_s(%AOAQ*v^z z9IghDiuK()lib+lv_Gpg7F#?9)}(8Tc3Bkm)pex|X$d5{wpRcQg^s^A_6*3`y(iyN zFJ3wdk&S=ZBO?z%1d%c>Pv9pmGK%Ia!|Jh*#rsb54NP0*$QI;dnd_ib%IP4tGv14F zL1h4he;*IndQ@3tw>nmgi~#ZsMiU0^2s2EaYh}oihCZ6zZg!XplG{)`)(4xON|`wA zOgs2!->bAllM0?rP8_R;9$+}S&yYOQMWV!P^7Qg@8X%t_d!9|hA6~B zXY`k(aX@zXYu;c)7dxAPUHDlihK6lm(Yesc!|&D z4E!`YwP3#Y6~zlm!wv%RhzIviXe~Q z@Q1M%K6DSXGrF2|u}Jam%X{&L=<5Bz#5U4gpI?uGIqta4xjwuCg@%y8z)kDNk+V<_ zDeyUPS`Td|=J>qUkW1yYOEmC1UM%@Y+gG+xc_@-uS~yNIdO5wByGVsHU^k5|yAC=8rlC6^&NhPpA_-V^7JjL=%JBrASmmE~M( z$i@WrRjy@9+H(Vu>)u=dyQUSy$QpkHc7k$2zq)8{F1c z`JQvhht%MU{*g}Hy@J=B-Q?#A{b^z|P$wSWCE$)+OudsHS_)A2sT{ZcF2tY97v>7s zsC-HlN`F(zJOCm&^S}tlRUvqp>bnK7uMP4rUE<0#*nA0_;5)I4+7yo;uS<~8sUqoT zc{_z!4ZB)~p4kmyrML-AyM02Q;(gCco{89hrwb1Jatt*y!W}b0_3_Yds*>1AbIV>FB+n>#fH_Tnr=FaxFMlq7KGl z$f?MTdqcC(>boRRwg~wtaP=JHTk^_;Pi0AEob?E(-@zytcd(00|AJ)mcq$%LtxA#A z8iZw+*-ro>*{c&}v5!n&A3c{n25GfbH9w3NlX)JDm7>=YpsTv~5Sx|7sxc^)B4df^ z7vP3~ov}S;b$=Rq%SQwxeOqb4rK=P>Us1NVeOWJMRj)1L*eeFU{@@p^>remyc~9d; z3{@ZmA|BYLv{sKSvF~}&W^K8}`&*RqHwXV2Kd&JQC-^r>h=$Jo`4%>N%kT8=Kbc4@ zAf80W{_XyML?5$2DB6fs`WxO|p?YFGVn!^|-?__waDD(lUu}^zq9)%VU|@}^l>J9J zVi*8vd9tOObrqG>+7)QcWOvw2{0mVlu+JPqF4sG33FY6R1TRnGBV3n?8|>g90WpSu z$g)=v0hh&FFq*+m0Ri9vAlsh3@4>2O3C^c(pc<0O2*AtVZD zm>&!D7D5FKJ*!3PVd>o>eSuN)KA)}>`%rQ|l7}%A!b?|-<6Zi6usH07{7LVC11{ji zk4%v_du^kUZ%97y?x!}QWz+%LF!w1lc)RW3M+)2H@?&K&>QnJ8F%VhY9i_Kd4g`WIYdNs2Z2l7ob7IC= zAUe$-AD0tDBlrn>+FK*myE-cL*?MFgo%Cw%1Fw+}tVsi5-6MP#zOGqz3@K$6U@27A zCok&VIwwBkIF8#9VY2wE3}U1}$Ki@6;9~g2sa`P>VBITzqTX-;MK%)XbOT@^Da@6E z{+ZN&egUdsfbVc^>R|m7&!J%~-i4&Au=ONkp>P|PK#=zs>Gd8}w$&vC1cUk?1pX?S z(J%&yJ9>LvDFJq2u!Fbmuj&o3%M@g4W>)vb;xxoG^{ojCfe`?VV%dwd7%63sLMQ-c zVT3q6{Yj6qI3HgT^Sbb`?IuzLvcm*SI>lNhA zN>B1%js@U6@J%f&ZUVMN{l~T_VC6;nnDn76aL57{uid0Vn8ZQ}6(uT9(}_`6rw33v zwmowwd&3#!1WC*Oo^G+PUPAx`#aPHQ- zW75E{7>EY<8g*rn(aCB%8$v2>N9tlAF!VcFVE}^DWFYqOtpm>~v)>n#* zGMO|{-?hThX3(@nS8IYrs#O8Usmsw^=u`o;@NBBm7hzX}SbM`#;<#u7AYI?B7F=LL zDl1vpvH#r-;82@y%Jx zP4k-+blsj0^_qb6V&~ z4|@V|5&Bw%ajd#+x0iB~>^Z|bJ?6vt-auckPgLXz839RuK*Z!#lGddAtnxBh!1-B( z!I*>fNZ!-a^_nymi}nZ_1Fh66J{$QF9@G{!0w@`PAvK@swEGH80^Eyj>kIrG8*b|n zMmQOxs$rPk7_~#=-~u)9ecR_RPcN3K3Z$$HgUX}RgO+)E@>Ot`+{&p#Q+^aPM7b;-=dMAcW!`_ zByhP3e+VtiNETUF6|{)@iTh3gf$xtG!bmPCIUSI2hNpaUp!S10W^Ax|*#Qwda);zX zxUoon35ZuWw+cR(0h*C_ICKp1tIqxtX7OZ{wt0)vCXzmCkrhsh@|V@0;Q)6t3CLaO z;H(b^rB5!K>!ZFAz15t}LM~u7ANh)%ZAmul4LvaldK(o7ZOI7Ad3=>baV~~}E)2a^ zvW;&-m%m&#O`5zDQJ9g$=6O9tz}{#KWE~}mA8O>QeZ$7_)5B(2J#hghx}?@CRgMdm^n#HKX#mj9i|fd?@?!1=U^UiuWV8a9rvm!OvcNq$&^ z`r5nP<)a9pjaT?2ytd=SYnkh$U-O&_8W12}mv)1x7sG%DzI!3e*dONKrMgZ+&Zd8h z>$6_04drTyhYo`$%d0_;8)>8;USM834}~mg6$UGJMQ{8J4aQn$FiPV-FztxEb5ZQg zYNcbA2Xl<7XdKm5*BIK@I&KvY^7#VKa^IZJdCr4?>dU0#gA{KbZ^NnOz-dZj`gU1`cx zq=gMbqAL*<^^2Bq53og>Ig2d#Zo7`C^7@{**vvFH<&)f2Vy+nzJ6)@o8-3JWkaxH| zeNQ`=JW%qwz*iJ$iCM}8z)&V(pr^T57)Uca)SiaxGV}>;3d0g?=2R${(liFg{7xEx zH0ilDJXSu|HG3!qI&+gUH2UpAK_f-1ivigPqZP+Fz;*ucfi?r=Bg?o!1vFnz^<&m^ zZue==Tx7M&6)QF60Hd+ZK}O|e-x&}1wO)p_A+TUTw!e+7Bt2;8xkxrVl0MfkbRoQ| zc@@k}%(es@%%)%bn9Bm?E7uQS0_4C^P0ob<2-U3mS+if0KlGbRyn)-c!#Z%zhSv#Q z(R8@(*`u84pbRyBA}Z?i67>R8W^2v#%!Y;fh9a0f;yO`;Q6hHLhrNyAsjAvM5-LC1 z7j4RC0IAgSlxMl2Nd4$T0e>OO`<*PIjryCHgEDm3xz`-1d58Q!^_6KG7lqm4{hzj^ zo2#-KyX$*-r?mM$9Jh;I%(W@!K~C%qf$4r!{CI8$JETufMN2TeP&Mpz+gnCrPz@XD zh!mU8wYY!pcUi5#vl`#ws;rp89xRPHD6EPtr9r#j#H+sH(?y2O1^w!LiTolEE3V`8 zY63jm8N$LYlTDgR_O=o(tp{XF(|6biP$SLyo&}xcgr?oUVxGQgY*jX;B4?u`_#CE% zr=0sm&Y9I&9{W&Gh%hSoo4p?q%m^%(r>ZO-yC%|7{~u*ao4;lv++*{T$t7Ov**58| zW1*irBjbcspI@-dPCgI~v1r~&i*?s=rTGFEYxe2t2X_4ujx@`=`is|UXJ1aqS#=k1 z5>El)n(VKu$TTqkW)(M2!ATgfW1kXm5@n-#ON{I7#&}`3GQff>#wy+KeP1e{og)MN z_Jm9|jXNp)0wmuYrY4?-%&?!!N^k=`5lpR*t+d;1_oH%tzm|2SOW~4^wTN=(Ka$lL z+Y$^{RdHvBzWoAcYE)D`X74Y530&;dFZMP3sCTuhL2wzstczGciF0jyrOU0{B;z2Y=6z^6F#t9|9FOg# ztgbo%xGLsgKx!k``9-v@#}D<|vjSTia9L1;Bgo;VAstMA+KdnY0(=T4@@HVTv>M0h zd66^T-=P`g8M^qK=%Fc@{#~b(OQn-l^fD6sJP@^rB&X51>`Rh2d*#@x{ z?Nu*QKl8wU1uRkZ1B@QKCR~7H(Tq~K^!>u)RU&i57J1HI*ooW_NFI@2z?HKp3emOh zYA9OeC0Am8;*(CyW^{IVzmfg-*B~N|Ag;nVTubgxffQ6ha{f-X*uEWH_+-wWc~a50 z-52KGlqTp}V5kq$8XJ*f`pzRwZK;`hMW(?j`UH`ODWD@Q1I5x=Nv`zUn>Tu^W2QSu!fhcizL06@&xvXpCh|FKn6s(H-$U#lRNT#f5?*>% zKxP7{hsCpXhzzMkyeb>QN`zlv25f00pom*?6cVC1!l)RLxr-W}JYS;PY&zt~wutkub)Tom~|D8?-`?^XqXm@B^!;#7AoC8P{`sor#q#!;KoXEh9xEz_R&c zB6*7NGCjC`i#=#aw8tBA`!{As4xPS0HjN^!4PD}i#7VDU%kw3;o z!kr3<6?feoH1ermjMMwB5xb3?pAiF;BKEYtz3Ew5xUd!W@D{a=p*QT12Pkl z1%+5Mgzt3*o+`w@x|n`|VGaFIBE0IADJJqRJsl!G&oSck1YD0(nuif#`Q+5GKa~gqz~c!Z#lL`Gp@+GiEWFd~?o6bhGTW>Xp1c82T9R z0yk701H&oqU~F{}2t>Ab+jHSPn_gFD^Sy#C3Nps!&d$UKa4}4Y3Z4)P+adI&z7%BF zZF^rQh9AGbp!&?;=Ju#kPUOSZ%0L{?4s5Zil9S zv@~y41V47wZQLzi}Hcum1}G0g$^J6S&NhI7Ys7RhsMZ83Ybw!go&W3J=rZtTpU znD_!4_-^w60;yT7TW7_?Lwo1DLnA-#NM%NSMG46Jx7Y^31E(=_eLa|BDuPwSFULyY zb^XPTQL^tIxABaFQA-r>aC;mkL#TfUhrEfUkJxsCXy%$;KSbZN*nsu$Si zps5~T&B^lB270Zgf(C8=GNzp@PwKpV$$1NIOGD+02frnuD_A2o5`3iir1DGchA1I) zR(1de_C7Q4?R{NCLr@3`t+IkW5)F_edwy%E-}BK0+3%G;Ca77Bmxf69C7sH(#5T@<#Ugn_gm5{iTf2ujCBMM7dzB5lx0mvq^5 ziS(8Z0R`zsL8PTaLTQlhK66{_@Aus??muVTJH|Qw;lSlu>#g~|YtCmr&jhG4953*Q zl5+3=CC6Yq=r&AYfJ`o~CkLPq5r35}nyd+}`7qmpM$G4Gar2$eIbF{2NsN#*I9vdU6biTa*^4 z|9+u=*+}I)V%qK#2qTYS858g{(7IBBmmWOwMiSzst6LbZ(%R-|=4onmrXRccjwR}s zc_c`nlx3Sd8WzefNCr~-vH9NevXIAqW(30!@@9yfd z1=O1V9vlNINmeC8Be$$G%O({VFG;4ZQG)j^g~WFyUb}5GnRy5EaQGEA+3v56^Ww8wwIv@95NFcf_`Xpm8O`oVBca53%I&eR`Shm0^Fm$DAB;^bB) zYN>)QE!JoWR^~kd()j05&zZmL+(kqVNXy(O{j)IS=ZD=d>{v+M?Z;?>6Jx>l(;VcL zg{0hwR5i(zw|IgC!LS&Z@qXde(l6wK2q9IF54Y7M-@Arob39TQkxfxoC^^<%xCcT$ z)I)YYEZmbJ7cYl5qc9W;h{eTwNm|$3Y}l0$AGm={Qj;UYn2YDtWF6ajEY22E3APeB z^QQ?cYtcs|&CNM45}kT9z;>Vj#z9CDalbB-X5wQ#;VEP{eH&yo4I`@2hyL{uO@I;a zHn82J6}!P;f&lVrPL@td9|Xt707ThMXnZgZ!eoRnz{Zh@-Tt9HLk!yj1UOPv#kP7q z5WWBOmPHJyjlkAr$;8>BAUV#ftXNrb0U6Mh0&BD>Ya%KFcYNoTk2|1dT!W~+a97Q-dkCTy zxqb|*#9wU7SiQINy{-CAv`w>Bn4zD;Yfzfy8Go%lF1}+)B?sBWK8$Qkc;;>HH>3Nt zzE%_M6GU=`&CyfMHscXSk+mmMS4VPN!~lqlELu+YIzzv*;k7!|{uv{x!GM^qfU$7m zDDSD2d%0PvnRJWY|LmWqmT_zIT21L3P`$F`>Z9rtaWHgQ&bkNyHv98ot+RZ>Yu!@g zv(S>9@Mdezz$Gj2jZ1hMXB6 zD;{*ceGd`OrOD>bTqDJh0gR&V4sD((P}f~4NLcHX8eRr#-XWJWUdRdd;=sQTP(ES( zPcedBm1q}Z8#^{7PDfP<(=?m=(CWpdl)v#U3y zj-Ny_=pxImKprW(dOMLgbt#kR!`#w#)-}l(+gjgKmvmHDbSW&E)dW@z{ORvxtYf5% zGqs6b2s`Gbi--CYb#%$E+y3lPve4mYvQumeh@DH`2QK}bLfJO=JpF*A%7scGhiFR< zWvf#qd$I2l@ywO2>lUQdXOt`#pM_YASkWY8=Q4@*Kt{EU!zMW^t9bh8j5ct#?mqg( zyhE%{#JP)Yyan59R@Ny96~7`#*?BRwaI;m$4UoR!Qm2YXi}%zIUxXYk0}X=cxXT^1 zIy3#bjY>uuX2x&=2GnUt&ir6~FCRgay8V*=CffYQqKw0bRjRrA1oJE36YpFL(_kK8 zRDU^CORq(tr`Fo}OkB()hP_Ux3!~lzG}v87o#|Netu`HpOqIYluZYc3_SP0<211Br zA&Mz`kk>lkyt=B6uR-z9u7b_1jrw@f2G1ACOd|GWzW#?Jdp~rlt297%`%N{)lL}M>bGrr416l+MM z-{rmhsdo=|VCt6XU};g*@hf{c)07F0TNsk1N`t3zp*3wqS++;|l}fG$v}!J49SC%N z?p)<(mSfVlkl#OFGd}G(- z+pvM12D<`m%pEJDlBaI8x?oi_2(jBJb3)R1tEM_;1TzIH=Eu5L4)Z|B?8zP?+&tDv zMb~~;gF$+Qu%2eekz=awx#k$u#i{k0hQ24RryqTACx*R}h#bHNy1`FZBDOUG)_~}O z(VuF!qB&(T0=*fh#FFv!z!{Nr+YGG$|C#;E&oy(2m}Tp|*OUU$<_bVIa2GjttLuSD zh<^f_xxCRduhojeH_c8$B3ScswajK2NI;{Xh_x3UKNk5aD0se&!d!`f>sf$Ww9DfH zjH;n}@@(r?C8hJTBOt$qq_}tJmnk8mB(#- z)U)_z+Kwc%9bub*&q7>RnjHPOpD4;l>e+F+Z|@BrRTHulR(%%R_}c#V%C#Uv3uUSc z&|zfaFcP?4q?#!n^7qeoL?%Ss40UPn);u5T5T>ztBIU>U*-}M`2A;N~azf$3x~sY~ zu5D!{P746w3B5`h8Cd=*4<3qfQG{@@I z@OLmGblTMHGB3P5B9JW#KU%oMpEsnpw?tK-a3B9eoFTEYvVr?(T@a_D=`5-ZX)q=w z<2t?i^N5=6HV9(7*q*lvlBb@NHElu_obmfI*_W5me|;co5Hv4TmaILj57$x_$bxnk z?G!|xNl19Gx0~XBC4XBVx3u`fhwE^AGdoh*1C5qep=Dvn$-Jl8gp zRe%Wc3TB^3zcb_SBq8$|Riou78`=>g?JzuYgp8%{*362#fH=B1HR3Um&<%;1Rd;ChI@+|*WBvt22!)OD z^(cWU9ZlJ1Kn9(Rkagnb@Q!Goh`dpJ?upvZo66j3b3Q`1?m8^&77-CMeegp(_wpie z_g%=C8>9-$URYz+xK&e@dVkwQhgitm3K1Ls?PW-SS96QgUw8B(Zl?~ok(%9)zhTA4 zsPBlZZKWp@UPrMmdLZiwfsbk({`e?%EVu}94~6@&I_&BbY%D+;_@6hv2f1F>ZTDtu zm5D5oYP#wRjR57P`am|Upn@HRY%z?VQNq{7QNT{~vlBrNUaCJ4!R|p7L zsNXsO(z)hw_{bc*HJszjNRD<%^PBN`a>>l2qg0q6f?@L?=SF%@L+}uSAT$qn4h@=@ z{Q?T?XSKKOz8kAoKlR%p;YeJ}OE!j(1!;m$ehyo_u!5J9n|qPPsrUS63N~(tM{hwy znW0tSeZ|Z^XgB}IeXTsxc(WevY^L0rqF@&V&Ao}b@O#Ds*?)6y!ZIYpNLXVa3`w%NpDlvBi^HMC z*F4QXsh?+>m!Gai`{NfaCa?+(b zZ`{J-aj>3%&;1f={PaOX1lQ%z%1N>xSg-$#4AQ}}n_$j&j?0Fi0=i&>T~~+cJo-r1 zr5lX*sQi9ngG&!RAr2s8Jx3ccf(4F{Tmc@D)a=V3J*+p^%RsrBF}x-dEWqS>FtBSv zvnU<0*)?Af)Aos>vsA$@V#oiYdcS&p@|WJIsBw+>WF4;tR%DFhX-x{ynV^IX4OWBk z=U^(5G9=;C`wNM|{Kd)wQ(^5jei?fzWB~J$RrkRLR!|BUCd2=GXVKBXov0^_Y{%N> zB+SqTtIoxxzuIJI3n_>Z1(97&!Dd#;LK{lOnxk0No?sxrtYR@%z^YAz48<_3Z1d`{ zDR^TrIFv$b^g&%c98XpZvuesT=ucsVU-JyJj(ii1Zr{9&iIRc*(aR1o(LWnUkScQLYAwen_p~!4%Ih1F^=FIrT33S8Fumqoaj55}QMiR-A>7zQYJx z3}Qt6|DtF3upP*8K2Co^q`N>WH;m76xYC7IHB++_|2WZ^<6;|kN+#od9ztoG&3vC9 zzbe3}YOGJCXJqAI!m|4AfLCKh0=JoDuVm98-`eTpB*Q(rMv z4fVM;_}iGDN5jS$< zt%6_rnGYuI+BbdI;&_b|;&onXr;HfCn+Nh)h=msZN%s3z!KZDTLJR2Zd#c8yo?=8W z7(|Hhgi@}dJj5-#4=Y^PbN#pNKgdV%^*$yflj~M=*y}V)eV1r;5eQhNX*a{`FU|Q_ z@!cCGaPVDlgDn(g^46;j3g;MLK!UMiD3j#fbh&2}f(rgHjiCZMhi_l)9BKFZENKNz z_220{dUJUwVqx!ZLYNSYCc-kTA=MW^79T-na8-XoHrQ7qg@2k|8KsQB2*eG3wGJ0$ zoOrQySw&z=y%{js5!=fHIDzjsl}CJQaOM$)@o(0fQ-i5qg8^T5$LG{2CLvW{>9jI= zGS>|*6%3X+_d|;C!9=u;KQRx45oUmO-D|XWN_bfjT&zPu$;!&Ayv_g|91|clyazgb zU(5tR6&F^hzwiDC?<`|gLZhP1rK|%3YJ*d+)Uh<(Nt&@5be!k~4&JPn_gh3XW| z)}2=ONeex zCV?g?KTm`TRo|y;%U=@x@%${%HqO`>v zR+ZB4QZea`z_GKh+VY}2;P*^s<<8x1!SH(|DQwlWeL^6KS5W$Lctj%b9aLKaLD&0y zh?NVR?d|gi-1m3qICI5g**`(C1u3~ebg##bSf7GK<4vwIeN%bVyEna2ALIqV)|xZB zV^*r$0Q;gQ0|swl>%i>VHftctGBN9FjePO_Y)V4rV>A|BZ#5dTz!co?>_mKdk!Tr;LC!YR2cMYg=I`)wL9776I3<1cR7MlP>*~QQXJk<(Ur3Zpt+VYgBnB$-%!rWGS?r|4o zhx2OnWXyIJ#hB_mp()lITN&cT{8LWs&sk;KZoh_2-)_e!yw-Dn7MOd-?ZeFqlQ4U4 z_|6|bdf;8yd#CKH3i1noNfS(4!!D?g3x^g{OmXHFhouVp7oUF;!X6+trLfOcvGZdH zC_ZK5num5?Zn*9`?WfBY7Kd-xg1RdbupwI@{*+w8bIN{&t9CxD+Of6A1H+j!uRWi4 znzi+7jHTMA)$UBKhYpMm9;7=7lp%wzPEnfLs-DNhPh1^g`GwjTm-j2Yi+_&qXyW@g zn0?1h#7mRaB|IG?qsbD&r<;DIWp3rDvZwlGeT1l^7<_E7qOMy)}Etz9d+NcO7;mxKll|hhMh}$5K&v3YH&@bN|kb~ie;!N^TW_7_tSq| zqq@tU(Q+5K#|E5m)gDO!D6Avo@ILnQimik7?zQfnublxp6rVAH{V~H^6)OvLhIW_Q zkUuPi7Ag;U70|rina;>QJU>FE8nL2dxDw$`t?{U2f%lLtlu;WmD(P{fg&H;W`Fbfw zYNoO|f;Cw#*WHrw&R6qP-{0@cGu3L+yfTm@t{6{Ay{{3kuJ-cEq~=8&q5Rkg^m|;V z`G!o1a$x^VQj1y8JbTlHm$%lDsl}fimYh#}dTxEuu|4-Rm<`d}A1aS-z1?Wp+1@xZ zJ|(oX)?bgdOBERC*?GT0<6a7%pQ0>{y;G!nFPf8fn;*CQh3+H3j|!AgFFD$fF18)1 zR0~2o;kD_d_5zEcVgGmRuhIofomAEOc62NZt_>)zsH2v2LW#CS%AH@*YiqZz0Y@ki zI6_hdlzv6h_HB-xPVu;11~DC((w?4>T4F1`1py)Ie01D%?;A$`v@j~uvd7!0m|NZK-n8n9z#xjoneIGYx3hPOlC~ zy*N<&i4&aQSo@rn+TG@6#Liw3{VOWP@qCGi!6fxO31akIzo-dz#2E&E)!zJ`#mZif zsS(H9;5%Nv&Ze!TLd86^KH%>5@fd$$$+zP6%*_?zn=}Ma5vMwrz(joD67YxUZn{r< zXOlO3YYJEMZW%v4ea!3DI^Awsb~#jy5$9}vEBAd)#Z;8=2q8e$z0(X5jw%=YSy=+h)`dFibK}(eFw#-=P z(VH~cj4Wz74NOo&utOBZx%1Y0e{a1)Vgc1ESbfNYg8Em9y}1f^)BHGQb~ksOYj##` zS5z62Cgkf>FS0DPJ2Cswvi_8?UHp78dp&8hIaGa6;Kc8Ie;U)Uv+wA}6V)%&o6=^u zqDSSuZCt}osj-r&vD@))g6PR6%u zgOhwJH1u*)${v8Bt+#Q8n9y^)>4`H%xK4Eu#Wzf*+brAmSuhd?hQd}OCz6QTyBj&_ z&VGC5fL0<7;ro3=HN2Q_$R3t-myNVawH~V{ED|d`Aq_g~Z*P&HjGO7sbU5S$btN9h3EPL=*7iu$C(nt za1%98)%{u7F~-0!ha-HLs^w!=oXtT`5yfYRAko)8tnMd8puXp$qAgFGE?onW7oEv)0iw#c*0z6Tt!^87SQ1+W$ zf?UF=e=HhLVPiADL(EhEAyC?cHoowWAH{}G6kur9;l4+)0H8n@Xk(Pt<}lXKn3yrl z7U*KJzCIR(!E=;&bbK5NhQ~$xM=wR8l6Jg9Q{5%3QOjUPEp&+md(=+Qqpu}~|51TF z5i{zT*JRkE7KI*7>hM})kGc&rYK2BZ>`});+`E!>N)TJ~GzD$Qu#97ut-h`Zqju`{ zJ&iqTTWBMZ>_33Bc$Pr2GLDcD)sw03<#`{p6^3;7+Vf}VW=iPh=O{Bj82v@4Kx^Y$ zo6Q#2+G(y<*w)dooo&wQx4EYCj8cIvi z-Z+-&6!NsI@XH%Mhq)3yo7#+;-XJqTHSzJSZESS1K>SZM9>kH9ikulZeB1l5bIG@h zx+1l1T9>|dWyOTY7cp!7TFfy;QTcfhqGy>om+fkpR2~KOq-!Hw*g0B z*s3#E(CG?P?dJ(g6L$0~JbXghF0On*n^+d4bo-3ldyG*B6HPu1+Ou6wbzBCD&OO&b zi^CU*nZxv*@sy=Jsv6U5E-H($(1Z+^(4IV(xHHD&4UHq85bU@+JDfSEt~QUmvm$p3 zpUJB(`JurJuh1tC2$|vwEeh|Y8Ea@xlkK**8Epo*i-e1F?4vlsl)s8wes=vx;mDbq zO30d8N6L3ijzG&JaEgEE0)OXJQAlIs&GQ3-aVl3L=GqJ9MJH^`lUwFvZOmD2*BM<` z7UNy&Wjx8i9g9FbS$tR^syxl1tx#`!R>f~knoNKd7lBuMl_Bor=38k~apBtdVImoi zN_)6>RzRdT2svjS8hY2@1rFRs@KYMS`_@=o*#1LiHvtK?Jg#T8aejmJt7-89kAJI~m;P3}D8~?C$MUy3p_Rcw?0(g% z%$BVZN5a|_gflS$kTHo9PAHXiE%Txzm;LP_E=Zql^7*VoI5fs0zA3X=!{zq=qJ@RK z+D2sF`6|S@Ui%8))R{%Q!Y@4Jre{M^g;a!r@TjxbT~8yF7f~ zwp2C&n$*KM1WPZ~OXCxHwVk&n#P>CLin*gP$`>9%!Ct{O?$X&TH*kIS%Uot3==FD& z4@raOvO z)!fuw3LaJMuyc8@mbinRWcU#Mi3v1vkdFv>;uYc^5 zP3&^?QmT|_I)_&NTWtVo$ApJA6^fvQP=T2Z6pVQVa?3pZPiNa*G3p%t?Nc0|b7NQE zCZ9g>sPa&xtILemkg0!x8Oya3%9s)|WrF5w&H${0UC1hohglbAO`G>uuHXMbRZ;j8 zAYpl&PV?>8pGA@*V#7S{avPLTl@8;NeLvy;XgL;;((s|ZwSqAyjkB8Hq#WDv9T*uG zfyHIPvAl(eqRsk0Ekv}q7z#r5W!h)HTOSe#0$hLIZvY%cRcvoDfWN3-NYvsym`<`jI~9`QUI zI>Agg4zaXz|K$|hEWOoq^{|Yr;&j4WISNd4(?B#!5|ztsc}u*}ptq-7zSWt{r{bLx zVDDFxf9%Ma(xtF$4n>zAWDWHD8=sfJq>Hpch9lpr@+>AP)BqT*V_yT@R`TUl!aMGB z6V&^hy8Gy}@Zi^u2{1s%&079)r8)3}&sWwzbB@Z%XN+0HJ0cEyqWDnZGtb@v=G{P5zVKxH5NFJiFNuC4Q}z&Og!;3#CJu3{ zf6uiPAbuWV9nCQ<&(MB_j>P~|4?Zdf##v!Hmt<8Cb}ranMMt*_6( zhAV#q!GmwiZ4k%i;1wh{CR^`31ZT~avxka^9*wRLRE@wI1b>YNCSXqQd5KOSIIbm& zq**BYk{O>fD1pw3Hd*l!wTJQO`~;SniGN)83Bl38r8+6G9BtdLl1hB(3OP~#NZ8KUXuCyiqsoNCG4}W)Wuc@9rw#=_ll8EPi1Q&Pa#Pwy>`Juf z^rL=q%`mlDDaf)2w1+Ic2}d%-{QPE?CJ*?r+!yjhxvw%QrSgtL4`cS^E^a|j+a5-4 z&4B{2sdFQgKW4Wm(Kbd``glkoS&)srO?(OX^t~Ryth7@<|fbMyZDUlIslW?|5BV zmWSJM=@h0$$Bis^ua2*tNVW~`uW620kGotdUowB1CFUC-`N!ts9ivO-lD?F;2{wl& z%JJ8$MkZ?KDe8Lp`fBT!G=8C1@NQ3hs^{GE@l2Pm=BVjjThh&&LSLr}Q$C7?hhEqs zG_`&r<|!}KJ+w2k3tjuaG#Vqf1+ph(?UZle@TgamRS)P7?kiHB zOF24wZ%l69B!$mFr!pjVC2=X4zbwsV<0HL!vMlqXO*oDV2PSKW_ny)lSy>In)pTmK z2VR(;N;PtG(<=YIepFl$73#Q8NJ6Tg80)^>KlGIU0pi8mi*=gMIYOH!WxRr1PDn;A zxj<#Q*>exCQ^g5eBKofA6#!p1oO;ZkoaLqbLP}3w*hc{Zz!UVQ7ZFDR8Qsw zke=*OLy(o2O08YHlZBY#7-vy`{YTWWRaGRI8apa zwQG~I>g(>@spp&33COABCpIU$oEQ@Gq%^`QlucwRdO~1I-zZXPt$$A+kIBcOM0qW4 z{hV~2G1BX?c7*%nHTvR@7gj!Q*RLdS2#I}vOcsfLlVKB6dET>)s$!$Y&{WCG%Qs)Y zPf?gAP)HvyiSEf4tG2@$MnS@2v;H0ViuK)*V-C|xZQMlX04teXD5SPT1gQvBjn^P8Vw#NA*8l;i1#%< z$1QCnw*5tWOPiu4Y|B?n|HE0Igk1UhXokD_7MINDe}*bp)rXyYYU|&wq_{f~nWM`z zuh^SIU3_8e_SA~eOJ!PLeY0!I&TmWk?ds~TAp+!5>b>SiliW(q8jznW$ff(x^j>cz zp6beHGw)dHvYjz5i|GjK(dfG69di{*zX>U(->#H>g-4oH$xzQpAv~UmeVe##?e@hc zI;*}5yG5?!P+Yv5qign2|67fsmvG|D4Tji$rgOL~arFj%u(jPTrkX=h(?rS8?%a7U zx}H)l2Yy*uBk=+~d85)8#W?&zHbv#}feCYosnS@eCM~b)_55_g19lW&o$(EGiO4Ib zQex~imt*BDw&olv`teQ^^7W+&Hu>c4ge)1AU8htnaJWD-czH+%%Dlm8g=SKpwfXtl z@REbF&{*2F(>%=VY%`aw`Qz=k)Iy4U_P@}*A*C)|c*6DYA#YCb(s5487EOQOX&10| z^ZE#e^DXUSv$lD7=7e5{hYEarOdWoCVjh*dh_WfJ_tPb!ZHtU=dfOpuNIK97nNx1z5Pg2SQ z&y`{O*^xDWsb05*Ir-U{k|hUW>mVgBx=gydE#Ho_{j<#sci)+_X?a!Sp@iA{hn+>h zS#iPl7v6J^tlpom*}qaAhO$Ob5RDS6+KiB&C8FTlW4+}lMYp{Pr}K8q>;q2q1qbr$ zi6VpyhQv(8^-&6o&GntDG-qEWGu z=Ev#c*qqv zf14-%UD*qxgRALObwY-oS65T2TyVCQdwcSK`^=h^M$g(kDhr7S$ZPY)){sT~LuKWH z)AeD`<~$RG&;1IYLXg`UU)}6|ReHmqaE|gTP94+hRWHC#k*Ccz<{Px=B(!l4xriAp zTGn$dH-7hLDyc*gq3`=jaINu(?tgRh(Oro$FHaR5_dF7-+;>6JN0;CTChqVIqJnr* z>_Tu~i+>Q;2Lvet_qEE7gj45u49N;-nrZ8g@oV>#x@>$mBBC_(4pxLGUgDFU8|7tU zi#xUX6Xu6n(UW;Z<6+XE3Zh%vRYIeD$7AY(B+ILW0Kt;CdhSX^X6@5Cj>~?|>C*l; zF)MbKArObL-LEg`@#+lM#mz>{JMN6Jt z4`JrJQkqczoJ1hEvV1%@9wqn@w@IS-#}3^YD85D9r*1Y2iaNYj8CXbvXUK=K6~a`AGM<-W#u1#OeGS(!)Mvve_x0U2V&7p$uocdjpJF5k4F?1hm(GA6Z$3+-I~M{aPZI=oGJgK zMP>%nq;indzc-_;aXqh&v3N`$91oMEB&@b+b!Yz_7pNj=e2EOXdSEQJgaqWps^DY& zy(v{27*d;r=&gg16vGVYurK|cQal1xP6kx!4j#(&V4iiLhny6S2M@7Rk+7<|AyVOY zY5lqA$q79Se<||!-?)e{Vghn@aa`57gOUE%^hDx2kx8Oa%Y^8;gO>~8Igufr{Ks?? zP%Bv;KUgG&cQMG8j)Yke5yrnG!z?a(XkIH}Snl6w;hHpBoEb&Uv>5uY6F9gk0nvvJ zS|eyA=Uz2Ve(`U&;vy)B^w1LUw9*r0lS#|q7paa^D_9ZcCbuGWIr zy+sFo@c>KU(w_OhVF_R2zv7yr@Vr{X;*pMRos;W6NZ?#z?FCqDQO~PQv)Nc{ZAbx= ze~X6eU~N;?!9*?kGXRnQYg!7PQ_MtNthV)ae*i6*c@%tsGUuFBt(G%{4({y5+qyw+ zm=J`u-EMhKMV%oeH#KuvJ^yckxT7jZS7Z%+B8=Lx?^X6>(<{7X(vZP-@Jc!YxsB>P zI{1Y@|4ay(1p7gjRyXfpr~Q<^lRlp%CA_pqbMPoT40tF3W$-cM^1;Oz!or!a&5uj} z_!uy7G?VAv%7=t;XYwWFA2;)tX(91=W?6%(uP=KL{(BsLn4>Cm@TqB3IQ(~h;M!C0 zM(b#vFp?`Cbcuw7Rp7{hjgm}~aL2cLGWi?~V-|+d*MhTpVB@WfaPT05Bo7WAd)U^q zMjl&OOA9ZyMb{nl6jcHT&l)ds_n>WC___(9^sx>e9az=vQ|P^eT_Xes4;^dHK@U4H z2hZ+Nl>5QJ=%9zk$+6B|Q#g1!+zzLT|C6Rk&5a<7>Zu{NQcVaLRYa zA#e`H(g^-Q`h2NUT8-CRwVU5bN)pCxl$LiNA8W{SVH>lP6m%|YhKaIhQrHdABjR6Aa6HZ7ll#A+;a0GWN&BE*uKureK$}8u|F^74B=YXPtEH$_4K&sYC*vO; z@p=JT;(`??QSO742M;L_c^8bieX;7g3F66@FJJ0qu-qIRPduVoWc4Q?mTN#jCHn+x zD(dkeZn{NEFDIuE!1}P~-5X2-$(j_)+eF?0P|4t9t)Ib{;3R_|z;I)OdSNXqA2SI04`MQspr8bH>DjHAO&A@$n#6u-w+33;3jm z^ox~lkY;I>*E}foY zy9ZP2+XkjigTdFa&c_V`eM<(toM<-52&K@H*z?F9o`HS6Tqk+n;CHrLU8%527VKeW z1^7f?WJm%n?%k{m{Qk`QxKJvlgq!?AAe~|2UG+q~)62VjlTS*G@^d)#^@tqv{LQ(ALg92FgqTHkkPd`0YdV&B~J$!$)|6^A`8 z%tNOP_E(mdZ9cE8pL_W2-TSv%1zF#KVk>X??qP9U9Dbvjtlrc<&bY9;vQbvs3=aH} NkyN;zb@h(d{{k++)9nBN diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index eb0a0eba63..ae942223f2 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -182,7 +182,7 @@ If your HTML file loads other files, use relative paths to ensure your files are | `visibility` | string | **Required** | Must be `"public"`. | | `description` | string | **Required** | A description of your module and what it provides. | | `url` | string | Optional | The URL of the GitHub repository containing the source code of the module. | -| `applications` | array | Optional | Objects that provide information about the [single page apps](/operate/reference/single-page-apps/) associated with the module. | +| `applications` | array | Optional | Objects that provide information about the [apps](/operate/reference/single-page-apps/) associated with the module. | | `models` | array | Optional | Empty unless you are shipping the app alongside models. For information on how to add models, see [Integrate other hardware](/operate/get-started/other-hardware/). | {{% /expand%}} @@ -232,11 +232,11 @@ For subsequent updates run these commands again with an updated version number. {{% /tablestep %}} {{< /table >}} -## Accessing your Single Page App +## Access your app After uploading your module with the application configuration, your application will be available at: -``` +```txt https://your-app-name_your-public-namespace.viamapplications.com ``` @@ -256,7 +256,7 @@ For a React app that shows Camera feeds for a machine, see [Viam Camera Viewer]( ## Limitations -- Single page apps currently only support single-machine applications +- Apps currently only support single-machine applications - All modules with apps must have public visibility - There is no separate deploy step; the page will always render the latest version - Browsers with cookies disabled are not supported @@ -266,4 +266,4 @@ For a React app that shows Camera feeds for a machine, see [Viam Camera Viewer]( - Customer apps are stored publicly available on the internet - Avoid uploading sensitive information in your application code or assets - API keys and secrets are stored in the browser's localStorage or sessionStorage -- Single page apps authenticate users with FusionAuth +- Authenticate users with FusionAuth diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index 7b439f0bca..e8c0e283b8 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -1020,7 +1020,7 @@ Do not change the module_id.

applications array Optional -Objects that provide information about the [Single Page Apps](/operate/reference/single-page-apps/) associated with the module. +Objects that provide information about the [apps](/operate/reference/single-page-apps/) associated with the module. diff --git a/docs/operate/reference/naming-modules.md b/docs/operate/reference/naming-modules.md index fcf9b68979..69d976356f 100644 --- a/docs/operate/reference/naming-modules.md +++ b/docs/operate/reference/naming-modules.md @@ -108,13 +108,13 @@ Application names have the following requirements: The URL for accessing your single page app will contain your application name: ```txt -https://app-name.your-public-namespace.viamapps.com +https://app-name_your-public-namespace.viamapps.com ``` For example, if your organization namespace is `acme` and your application name is `dashboard`, your application will be accessible at: -``` -https://dashboard.acme.viamapps.com +```txt +https://dashboard_acme.viamapps.com ``` For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). diff --git a/docs/tutorials/control/air-quality-fleet.md b/docs/tutorials/control/air-quality-fleet.md index a0d054f089..0bea49f7c6 100644 --- a/docs/tutorials/control/air-quality-fleet.md +++ b/docs/tutorials/control/air-quality-fleet.md @@ -192,7 +192,7 @@ Once you understand how to configure machines and use fragments, you can use [Pr #### Configure the sensor 1. Navigate to the **CONFIGURE** tab of the machine details page in the [Viam app](https://app.viam.com) for your first machine. -2. Click the **+** (Create) button and click **Component** from the dropdown. +2. Click the **+** (Create) button and click **Component or service** from the dropdown. Click **sensor**, then search for `sds011` and click **sds001:v1** from the results. 3. Click **Add module**. This adds the {{< glossary_tooltip term_id="module" text="module" >}} that provides the sensor model that supports the specific hardware we are using for this tutorial. @@ -240,7 +240,7 @@ Once you configure the rest of your sensing machines, you'll be able to remotely Configure data capture and sync as follows: -1. Click the **+** (Create) button and click **Service** from the dropdown. +1. Click the **+** (Create) button and click **Component or service** from the dropdown. 2. Click **data management**. 3. Give your data manager a name such as the auto-populated name `data_manager-1` and click **Create**. 4. Toggle **Syncing** to the on position. diff --git a/netlify.toml b/netlify.toml index 731a04e3d0..4b243e4c04 100644 --- a/netlify.toml +++ b/netlify.toml @@ -57,7 +57,7 @@ [plugins.inputs] # change this key to a new one any time you need to restart from scratch - cacheKey = ["May022025"] + cacheKey = ["May272025"] # either "warn" or "error" failBuildOnError = true diff --git a/static/spa.mp4 b/static/spa.mp4 new file mode 100644 index 0000000000000000000000000000000000000000..8704d06d6cb5a300105b12660e19ea2a732f60c6 GIT binary patch literal 105488 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%0DTlUorh)fC`-2MlpW?@3 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 literal 0 HcmV?d00001 diff --git a/static/spa.webm b/static/spa.webm new file mode 100644 index 0000000000000000000000000000000000000000..49caed05ed3be021bb7771cff52e558da32b51ce GIT binary patch literal 67150 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 Date: Tue, 27 May 2025 16:45:29 +0200 Subject: [PATCH 08/17] Fix links --- docs/operate/control/single-page-apps.md | 2 +- docs/operate/get-started/other-hardware/_index.md | 2 +- docs/operate/reference/module-configuration.md | 4 ++-- docs/operate/reference/naming-modules.md | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index ae942223f2..348b0f4439 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -182,7 +182,7 @@ If your HTML file loads other files, use relative paths to ensure your files are | `visibility` | string | **Required** | Must be `"public"`. | | `description` | string | **Required** | A description of your module and what it provides. | | `url` | string | Optional | The URL of the GitHub repository containing the source code of the module. | -| `applications` | array | Optional | Objects that provide information about the [apps](/operate/reference/single-page-apps/) associated with the module. | +| `applications` | array | Optional | Objects that provide information about the [apps](/operate/control/single-page-apps/) associated with the module. | | `models` | array | Optional | Empty unless you are shipping the app alongside models. For information on how to add models, see [Integrate other hardware](/operate/get-started/other-hardware/). | {{% /expand%}} diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index e8c0e283b8..2102b66d7c 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -1020,7 +1020,7 @@ Do not change the module_id.

applications array Optional -Objects that provide information about the [apps](/operate/reference/single-page-apps/) associated with the module. +Objects that provide information about the [apps](/operate/control/single-page-apps/) associated with the module. diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index 6e1f2e5687..a094072466 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -250,7 +250,7 @@ Here's an example of a `meta.json` file: } ``` -For modules that include [Single Page Apps](/operate/reference/single-page-apps/), you can add the `applications` field: +For modules that include [Single Page Apps](/operate/control/single-page-apps/), you can add the `applications` field: ```json { @@ -283,7 +283,7 @@ The `applications` field is an array of application objects with the following p | `type` | string | The type of application (currently only `"web"` is supported) | | `entrypoint` | string | The path to the HTML entry point for your application | -For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). +For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/control/single-page-apps/). ### Environment variables diff --git a/docs/operate/reference/naming-modules.md b/docs/operate/reference/naming-modules.md index 69d976356f..46d38d6b1a 100644 --- a/docs/operate/reference/naming-modules.md +++ b/docs/operate/reference/naming-modules.md @@ -97,7 +97,7 @@ Determine the model name you want to use based on these requirements, then proce ## Valid application identifiers -If your module includes a [single page app](/operate/reference/single-page-apps/), you need to define the application name in your module's `meta.json` file. +If your module includes a [single page app](/operate/control/single-page-apps/), you need to define the application name in your module's `meta.json` file. Application names have the following requirements: - Application names must be all-lowercase. @@ -117,7 +117,7 @@ For example, if your organization namespace is `acme` and your application name https://dashboard_acme.viamapps.com ``` -For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/reference/single-page-apps/). +For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/control/single-page-apps/). ## Create a namespace for your organization From cc31474eb5da0a3093d01d8fddc41edd78d7d9c7 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Tue, 27 May 2025 16:46:06 +0200 Subject: [PATCH 09/17] Fix more links --- docs/operate/control/single-page-apps.md | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/single-page-apps.md index 348b0f4439..cc0acafc69 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/single-page-apps.md @@ -192,7 +192,7 @@ The `applications` field is an array of application objects with the following p | Property | Type | Description | | ------------ | ------ | ----------- | -| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [](/operate/reference/naming-modules#valid-application-identifiers). | +| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [](/operate/reference/naming-modules/#valid-application-identifiers). | | `type` | string | The type of application (currently only `"single_machine"` is supported). | | `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example:
  • "dist/index.html": Static content rooted at the `dist` directory
  • "dist/foo.html": Static content rooted at the `dist` directory, with `foo.html` as the entry point
  • "dist/": Static content rooted at the `dist` directory (assumes `dist/index.html` exists)
  • "dist/bar/foo.html": Static content rooted at `dist/bar` with `foo.html` as the entry point
| From aedca96340e47d48590cfb63374fe757a48f47c9 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Tue, 27 May 2025 20:15:12 +0200 Subject: [PATCH 10/17] Change name --- docs/operate/control/{single-page-apps.md => viam-app.md} | 2 +- docs/operate/get-started/other-hardware/_index.md | 2 +- docs/operate/reference/module-configuration.md | 4 ++-- docs/operate/reference/naming-modules.md | 6 +++--- 4 files changed, 7 insertions(+), 7 deletions(-) rename docs/operate/control/{single-page-apps.md => viam-app.md} (99%) diff --git a/docs/operate/control/single-page-apps.md b/docs/operate/control/viam-app.md similarity index 99% rename from docs/operate/control/single-page-apps.md rename to docs/operate/control/viam-app.md index cc0acafc69..40eccfd6fd 100644 --- a/docs/operate/control/single-page-apps.md +++ b/docs/operate/control/viam-app.md @@ -182,7 +182,7 @@ If your HTML file loads other files, use relative paths to ensure your files are | `visibility` | string | **Required** | Must be `"public"`. | | `description` | string | **Required** | A description of your module and what it provides. | | `url` | string | Optional | The URL of the GitHub repository containing the source code of the module. | -| `applications` | array | Optional | Objects that provide information about the [apps](/operate/control/single-page-apps/) associated with the module. | +| `applications` | array | Optional | Objects that provide information about the [apps](/operate/control/viam-app/) associated with the module. | | `models` | array | Optional | Empty unless you are shipping the app alongside models. For information on how to add models, see [Integrate other hardware](/operate/get-started/other-hardware/). | {{% /expand%}} diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index 2102b66d7c..ee74542520 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -1020,7 +1020,7 @@ Do not change the module_id.

applications array Optional -Objects that provide information about the [apps](/operate/control/single-page-apps/) associated with the module. +Objects that provide information about the [apps](/operate/control/viam-app/) associated with the module. diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index a094072466..f594e99d2a 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -250,7 +250,7 @@ Here's an example of a `meta.json` file: } ``` -For modules that include [Single Page Apps](/operate/control/single-page-apps/), you can add the `applications` field: +For modules that include [Viam apps](/operate/control/viam-app/), you can add the `applications` field: ```json { @@ -283,7 +283,7 @@ The `applications` field is an array of application objects with the following p | `type` | string | The type of application (currently only `"web"` is supported) | | `entrypoint` | string | The path to the HTML entry point for your application | -For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/control/single-page-apps/). +For more information about Viam apps, see the [Viam apps documentation](/operate/control/viam-app/). ### Environment variables diff --git a/docs/operate/reference/naming-modules.md b/docs/operate/reference/naming-modules.md index 46d38d6b1a..d1ef3cbcf8 100644 --- a/docs/operate/reference/naming-modules.md +++ b/docs/operate/reference/naming-modules.md @@ -97,7 +97,7 @@ Determine the model name you want to use based on these requirements, then proce ## Valid application identifiers -If your module includes a [single page app](/operate/control/single-page-apps/), you need to define the application name in your module's `meta.json` file. +If your module includes a [Viam app](/operate/control/viam-app/), you need to define the application name in your module's `meta.json` file. Application names have the following requirements: - Application names must be all-lowercase. @@ -105,7 +105,7 @@ Application names have the following requirements: - Application names may not start or end with a hyphen. - Application names must be unique within your organization's namespace. -The URL for accessing your single page app will contain your application name: +The URL for accessing your Viam app will contain your application name: ```txt https://app-name_your-public-namespace.viamapps.com @@ -117,7 +117,7 @@ For example, if your organization namespace is `acme` and your application name https://dashboard_acme.viamapps.com ``` -For more information about Single Page Apps, see the [Single Page Apps documentation](/operate/control/single-page-apps/). +For more information about Viam apps, see the [Viam apps documentation](/operate/control/viam-app/). ## Create a namespace for your organization From d587cff87b6d01c2060fc35373db4054a8b7679d Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Tue, 27 May 2025 20:17:19 +0200 Subject: [PATCH 11/17] Minor update --- docs/operate/control/viam-app.md | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/docs/operate/control/viam-app.md b/docs/operate/control/viam-app.md index 40eccfd6fd..5cfe857a30 100644 --- a/docs/operate/control/viam-app.md +++ b/docs/operate/control/viam-app.md @@ -1,6 +1,6 @@ --- -title: "Create a custom web interface" -linkTitle: "Create a custom web interface" +title: "Create a Viam app" +linkTitle: "Create a Viam app" weight: 5 layout: "docs" type: "docs" From 939bd61bf1d3221648815f181f6b090f6273f952 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Tue, 27 May 2025 20:19:56 +0200 Subject: [PATCH 12/17] update cachekey --- netlify.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/netlify.toml b/netlify.toml index 4b243e4c04..3ab1fbab1a 100644 --- a/netlify.toml +++ b/netlify.toml @@ -57,7 +57,7 @@ [plugins.inputs] # change this key to a new one any time you need to restart from scratch - cacheKey = ["May272025"] + cacheKey = ["May282025"] # either "warn" or "error" failBuildOnError = true From 503826aecde8c22764f02ac50649d7a9523c20c4 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Wed, 28 May 2025 13:57:56 +0200 Subject: [PATCH 13/17] Update based on Bashar's feedback --- docs/dev/reference/changelog.md | 6 ++++++ docs/operate/control/viam-app.md | 14 +++++++------- 2 files changed, 13 insertions(+), 7 deletions(-) diff --git a/docs/dev/reference/changelog.md b/docs/dev/reference/changelog.md index 185af21680..47dcc40794 100644 --- a/docs/dev/reference/changelog.md +++ b/docs/dev/reference/changelog.md @@ -42,6 +42,12 @@ date: "2024-09-18" # updated: "" # When the content was last entirely checked --- +{{% changelog color="changed" title="Deprecated explicit dependencies" date="2025-05-30" %}} + +You can now create and use Viam apps to build custom applications that interact with your Viam-powered machines through the Viam SDKs. For more information, see [Viam apps](/operate/control/viam-app/). + +{{% /changelog %}} + {{% changelog color="changed" title="Deprecated explicit dependencies" date="2025-05-05" %}} Some older modules use "explicit dependencies" which require users to list the names of dependencies in the `depends_on` field of the resource's configuration, for example: diff --git a/docs/operate/control/viam-app.md b/docs/operate/control/viam-app.md index 5cfe857a30..9f14d3897b 100644 --- a/docs/operate/control/viam-app.md +++ b/docs/operate/control/viam-app.md @@ -4,10 +4,10 @@ linkTitle: "Create a Viam app" weight: 5 layout: "docs" type: "docs" -description: "Create and deploy custom web interfaces for your machines as single-page applications without managing hosting and authentication." +description: "Create and deploy custom web interfaces for your machines without managing hosting and authentication." --- -Create and deploy custom web interfaces for your machines as single-page applications without managing hosting and authentication. +Create and deploy custom web interfaces for your machines without managing hosting and authentication. Once deployed, apps are accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`) and hosting and authentication is handled for you. When opening an app, users log in and then select a machine they have access to. @@ -34,8 +34,8 @@ You can build a custom web interface to access your machines using your preferre ### Access machines from your app -Viam apps provide access to a machine by placing its API key in your local storage. -You can access the data from your browser's local storage as follows: +Viam apps provide access to a machine by placing its API key in your cookies. +You can access the data from your browser's cookies as follows: ```ts {class="line-numbers linkable-line-numbers" data-line=""} import Cookies from "js-cookie"; @@ -53,7 +53,7 @@ machineId = window.location.pathname.split("/")[2]; } = JSON.parse(Cookies.get(machineId)!)); ``` -For developing your app on localhost, add the same information to your browsers local storage. +For developing your app on localhost, add the same information to your browser's cookies. 1. Navigate to [Camera Viewer](https://camera-viewer_naomi.viamapplications.com/). 2. Log in and select the machine you'd like to use for testing. @@ -192,7 +192,7 @@ The `applications` field is an array of application objects with the following p | Property | Type | Description | | ------------ | ------ | ----------- | -| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [](/operate/reference/naming-modules/#valid-application-identifiers). | +| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [Valid application identifiers](/operate/reference/naming-modules/#valid-application-identifiers). | | `type` | string | The type of application (currently only `"single_machine"` is supported). | | `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example:
  • "dist/index.html": Static content rooted at the `dist` directory
  • "dist/foo.html": Static content rooted at the `dist` directory, with `foo.html` as the entry point
  • "dist/": Static content rooted at the `dist` directory (assumes `dist/index.html` exists)
  • "dist/bar/foo.html": Static content rooted at `dist/bar` with `foo.html` as the entry point
| @@ -265,5 +265,5 @@ For a React app that shows Camera feeds for a machine, see [Viam Camera Viewer]( - Customer apps are stored publicly available on the internet - Avoid uploading sensitive information in your application code or assets -- API keys and secrets are stored in the browser's localStorage or sessionStorage +- API keys and secrets are stored in the browser's cookies - Authenticate users with FusionAuth From 3102de79529c6a6f0b6d1be99bb5a6968752e4d4 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Fri, 30 May 2025 21:50:24 +0200 Subject: [PATCH 14/17] Apply suggestions from code review Co-authored-by: Jessamy Taylor <75634662+JessamyT@users.noreply.github.com> --- docs/dev/reference/changelog.md | 3 +- docs/operate/control/viam-app.md | 45 +++++++++---------- .../get-started/other-hardware/_index.md | 2 +- .../operate/reference/module-configuration.md | 2 +- 4 files changed, 26 insertions(+), 26 deletions(-) diff --git a/docs/dev/reference/changelog.md b/docs/dev/reference/changelog.md index 47dcc40794..1d672dd805 100644 --- a/docs/dev/reference/changelog.md +++ b/docs/dev/reference/changelog.md @@ -44,7 +44,8 @@ date: "2024-09-18" {{% changelog color="changed" title="Deprecated explicit dependencies" date="2025-05-30" %}} -You can now create and use Viam apps to build custom applications that interact with your Viam-powered machines through the Viam SDKs. For more information, see [Viam apps](/operate/control/viam-app/). +You can now create and use Viam apps to build custom applications that interact with your Viam-powered machines through the Viam SDKs. +For more information, see [Viam apps](/operate/control/viam-app/). {{% /changelog %}} diff --git a/docs/operate/control/viam-app.md b/docs/operate/control/viam-app.md index 9f14d3897b..6e91c3e2eb 100644 --- a/docs/operate/control/viam-app.md +++ b/docs/operate/control/viam-app.md @@ -4,14 +4,14 @@ linkTitle: "Create a Viam app" weight: 5 layout: "docs" type: "docs" -description: "Create and deploy custom web interfaces for your machines without managing hosting and authentication." +description: "Create and deploy a custom web interface for your machines without managing hosting and authentication." --- -Create and deploy custom web interfaces for your machines without managing hosting and authentication. -Once deployed, apps are accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`) and hosting and authentication is handled for you. +Create and deploy a custom web interface for your machines without managing hosting and authentication. +Once deployed, your app is accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`), and hosting and authentication is handled for you. -When opening an app, users log in and then select a machine they have access to. -Then your app is rendered and ready for use. +Users log into your app and select a machine they have access to. +The app then renders your custom interface for interacting with the user's machine. {{}} @@ -34,7 +34,7 @@ You can build a custom web interface to access your machines using your preferre ### Access machines from your app -Viam apps provide access to a machine by placing its API key in your cookies. +When logging into a Viam app and selecting a machine to use it with, the machine's API key is stored as a cookie. You can access the data from your browser's cookies as follows: ```ts {class="line-numbers linkable-line-numbers" data-line=""} @@ -53,11 +53,11 @@ machineId = window.location.pathname.split("/")[2]; } = JSON.parse(Cookies.get(machineId)!)); ``` -For developing your app on localhost, add the same information to your browser's cookies. +For developing your app on localhost, add the same information to your browser's cookies: 1. Navigate to [Camera Viewer](https://camera-viewer_naomi.viamapplications.com/). 2. Log in and select the machine you'd like to use for testing. -3. Open Developer tools and go to the console. +3. Open Developer Tools and go to the console. 4. Execute the following JavaScript to obtain the cookies you need: ```js {class="line-numbers linkable-line-numbers" data-line=""} @@ -242,28 +242,27 @@ https://your-app-name_your-public-namespace.viamapplications.com Users will be prompted to authenticate with their Viam credentials before accessing your application: -1. User navigates to `your-app-name_your-public-namespace.viamapplications.com` -1. User authenticates with Viam credentials -1. User selects an organization, location, and machine -1. User is redirected to `your-app-name_your-public-namespace.viamapplications.com/machine/{machine-id}` -1. Your application is rendered with access to the selected machine +1. User navigates to `your-app-name_your-public-namespace.viamapplications.com`. +1. User authenticates with Viam credentials. +1. User selects an organization, location, and machine. +1. User is redirected to `your-app-name_your-public-namespace.viamapplications.com/machine/{machine-id}`. +1. Your application is rendered with access to the selected machine. ## Example -For a React app that shows Camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). +For a React app that shows camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). ## Limitations -- Apps currently only support single-machine applications -- All modules with apps must have public visibility -- There is no separate deploy step; the page will always render the latest version -- Browsers with cookies disabled are not supported +- Apps currently only support single-machine applications. +- All modules with apps must have public visibility. +- The page will always render the latest version. +- Browsers with cookies disabled are not supported. -## Security Considerations +## Security considerations -- Customer apps are stored publicly available on the internet -- Avoid uploading sensitive information in your application code or assets -- API keys and secrets are stored in the browser's cookies -- Authenticate users with FusionAuth +- Customer apps are stored publicly on the internet, so avoid uploading sensitive information in your application code or assets. +- API keys and secrets are stored in the browser's cookies. +- Users authenticate with FusionAuth. diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index ee74542520..5755037200 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -1020,7 +1020,7 @@ Do not change the module_id.

applications array Optional -Objects that provide information about the [apps](/operate/control/viam-app/) associated with the module. +Objects that provide information about the [apps](/operate/control/viam-app/) provided by the module. diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index f594e99d2a..b876f8f52a 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -229,7 +229,7 @@ If, for example, the module provides a motor component, and the motor is running ### Module meta.json configuration -When creating a module, you'll need to configure a `meta.json` file that defines the module's properties. This file includes information about the module's ID, visibility, models, and other features. +When creating a module, you'll need to create a `meta.json` file that defines the module's properties. This file includes information about the module's ID, visibility, models, and other features. Here's an example of a `meta.json` file: From 36f207b93c45a8fb4a9016ced2f55a4953a87979 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Mon, 2 Jun 2025 13:12:04 +0200 Subject: [PATCH 15/17] Updates --- docs/operate/control/viam-app.md | 35 +++++++++++++++++++++++++++++--- docs/operate/control/web-app.md | 7 ++++++- 2 files changed, 38 insertions(+), 4 deletions(-) diff --git a/docs/operate/control/viam-app.md b/docs/operate/control/viam-app.md index 6e91c3e2eb..51a3b3dba6 100644 --- a/docs/operate/control/viam-app.md +++ b/docs/operate/control/viam-app.md @@ -125,12 +125,14 @@ For developing your app on localhost, add the same information to your browser's When using your deployed application, static files will be accessible at `https://your-app-name_your-public-namespace.viamapplications.com/machine//`. If your HTML file loads other files, use relative paths to ensure your files are accessible. -## Deploy your web interface +## Deploy your web interface as a Viam app + +To deploy your app with Viam you must package it as a module and upload it using the Viam CLI. {{< table >}} {{% tablestep number=1 %}} -**Create a meta.json** file using this template: +**Create a meta.json** file for your module using this template: {{< tabs >}} {{% tab name="Template" %}} @@ -173,7 +175,10 @@ If your HTML file loads other files, use relative paths to ensure your files are {{% /tab %}} {{< /tabs >}} -{{% expand "Click to view" %}} +This file specifies the contents of the module. +It is required for your module. + +{{% expand "Click to view more information on attributes." %}} | Name | Type | Inclusion | Description | @@ -260,9 +265,33 @@ For a React app that shows camera feeds for a machine, see [Viam Camera Viewer]( - All modules with apps must have public visibility. - The page will always render the latest version. - Browsers with cookies disabled are not supported. +- Viam apps serve static files. + If you are building an app with server-side rendering or need other back-end capabilites, Viam apps is not the right choice. ## Security considerations - Customer apps are stored publicly on the internet, so avoid uploading sensitive information in your application code or assets. - API keys and secrets are stored in the browser's cookies. - Users authenticate with FusionAuth. + +## FAQ + +### Can I use a custom domain? + +If you want to serve your side from a domain other than `your-app-name_your-public-namespace.viamapplications.com`, you can set this up with your DNS provider. + +To configure an apex domain (`example.com`) and the `www` subdomain, set the following values: + + +| Domain | DNS record type | DNS record name | DNS record value | +| ------ | --------------- | --------------- | ---------------- | +| `example.com` | `A` | `@` | `34.8.79.17` | +| `example.com` | `ANAME` or `ALIAS` | `@` | `your-app-name_your-public-namespace.viamapplications.com` | +| `www.examples.com` | `CNAME` | `SUBDOMAIN.example.com` | `your-app-name_your-public-namespace.viamapplications.com` | + +To configure a subdomain, set the following values: + + +| Domain | DNS record type | DNS record name | DNS record value | +| ------ | --------------- | --------------- | ---------------- | +| Subdomain (`www.examples.com` or `app.example.com`) | `CNAME` | `SUBDOMAIN.example.com` | `your-app-name_your-public-namespace.viamapplications.com` | diff --git a/docs/operate/control/web-app.md b/docs/operate/control/web-app.md index 6721b701e1..d49c377d79 100644 --- a/docs/operate/control/web-app.md +++ b/docs/operate/control/web-app.md @@ -1,6 +1,6 @@ --- linkTitle: "Create a web app" -title: "Create a self-hosted web app" +title: "Create a web app" weight: 10 layout: "docs" type: "docs" @@ -13,6 +13,11 @@ The TypeScript SDK includes: - Implementation of the standard component and service APIs to control your hardware and software - Authentication tools so users can log in securely +{{< alert title="Tip: Host your app on Viam" color="tip" >}} +You can host most apps by [deploying them as Viam apps](/operate/control/viam-app/). +If your app requires server-side rendering or other back-end functionality, self-host your app instead. +{{< /alert >}} + ## Install the TypeScript SDK Run the following command in your terminal to install the Viam TypeScript SDK: From c0bb95fc365e73ac82e850d3bbe66ac1a4c6cec5 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Thu, 26 Jun 2025 20:38:25 +0200 Subject: [PATCH 16/17] Update docs/operate/control/viam-app.md Co-authored-by: Julia Ruddy --- docs/operate/control/viam-app.md | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/docs/operate/control/viam-app.md b/docs/operate/control/viam-app.md index 51a3b3dba6..ed0a279115 100644 --- a/docs/operate/control/viam-app.md +++ b/docs/operate/control/viam-app.md @@ -45,13 +45,13 @@ let apiKeySecret = ""; let hostname = ""; let machineId = ""; -machineId = window.location.pathname.split("/")[2]; +machineCookie = window.location.pathname.split("/")[2]; ({ id: apiKeyId, key: apiKeySecret, hostname: hostname, -} = JSON.parse(Cookies.get(machineId)!)); -``` + machineId: machineId +} = JSON.parse(Cookies.get(machineCookie)!)); For developing your app on localhost, add the same information to your browser's cookies: From 6875ce3263c76eac114d326f6c0c4f64c2cbf836 Mon Sep 17 00:00:00 2001 From: Naomi Pentrel <5212232+npentrel@users.noreply.github.com> Date: Fri, 4 Jul 2025 16:05:08 +0200 Subject: [PATCH 17/17] rename --- docs/dev/reference/changelog.md | 4 +- .../{viam-app.md => viam-applications.md} | 48 +++++++++---------- docs/operate/control/web-app.md | 6 +-- .../get-started/other-hardware/_index.md | 2 +- .../operate/reference/module-configuration.md | 4 +- netlify.toml | 2 +- 6 files changed, 33 insertions(+), 33 deletions(-) rename docs/operate/control/{viam-app.md => viam-applications.md} (82%) diff --git a/docs/dev/reference/changelog.md b/docs/dev/reference/changelog.md index 1d672dd805..7db752194f 100644 --- a/docs/dev/reference/changelog.md +++ b/docs/dev/reference/changelog.md @@ -44,8 +44,8 @@ date: "2024-09-18" {{% changelog color="changed" title="Deprecated explicit dependencies" date="2025-05-30" %}} -You can now create and use Viam apps to build custom applications that interact with your Viam-powered machines through the Viam SDKs. -For more information, see [Viam apps](/operate/control/viam-app/). +You can now create and use Viam applications to build custom applications that interact with your Viam-powered machines through the Viam SDKs. +For more information, see [Viam applications](/operate/control/viam-applications/). {{% /changelog %}} diff --git a/docs/operate/control/viam-app.md b/docs/operate/control/viam-applications.md similarity index 82% rename from docs/operate/control/viam-app.md rename to docs/operate/control/viam-applications.md index ed0a279115..abc943c0dc 100644 --- a/docs/operate/control/viam-app.md +++ b/docs/operate/control/viam-applications.md @@ -1,6 +1,6 @@ --- -title: "Create a Viam app" -linkTitle: "Create a Viam app" +title: "Create a Viam application" +linkTitle: "Create a Viam application" weight: 5 layout: "docs" type: "docs" @@ -8,12 +8,12 @@ description: "Create and deploy a custom web interface for your machines without --- Create and deploy a custom web interface for your machines without managing hosting and authentication. -Once deployed, your app is accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`), and hosting and authentication is handled for you. +Once deployed, your application is accessible from a dedicated URL (`appname_publicnamespace.viamapplications.com`), and hosting and authentication is handled for you. -Users log into your app and select a machine they have access to. -The app then renders your custom interface for interacting with the user's machine. +Users log into your application and select a machine they have access to. +The application then renders your custom interface for interacting with the user's machine. -{{}} +{{}} ## Requirements @@ -32,12 +32,12 @@ Then authenticate your CLI session with Viam using one of the following options: You can build a custom web interface to access your machines using your preferred framework like React, Vue, Angular, or others. -### Access machines from your app +### Access machines from your application -When logging into a Viam app and selecting a machine to use it with, the machine's API key is stored as a cookie. +When logging into a Viam application and selecting a machine to use it with, the machine's API key is stored as a cookie. You can access the data from your browser's cookies as follows: -```ts {class="line-numbers linkable-line-numbers" data-line=""} +````ts {class="line-numbers linkable-line-numbers" data-line=""} import Cookies from "js-cookie"; let apiKeyId = ""; @@ -53,7 +53,7 @@ machineCookie = window.location.pathname.split("/")[2]; machineId: machineId } = JSON.parse(Cookies.get(machineCookie)!)); -For developing your app on localhost, add the same information to your browser's cookies: +For developing your application on localhost, add the same information to your browser's cookies: 1. Navigate to [Camera Viewer](https://camera-viewer_naomi.viamapplications.com/). 2. Log in and select the machine you'd like to use for testing. @@ -103,7 +103,7 @@ For developing your app on localhost, add the same information to your browser's // Execute the function generateCookieSetterScript(); - ``` +```` 5. Copy the resulting script. It will look like this: @@ -117,17 +117,17 @@ For developing your app on localhost, add the same information to your browser's console.log("Set 2 cookies on localhost"); ``` -6. Open the app you are building on localhost and run the resulting script. -7. Reload your app. +6. Open the application you are building on localhost and run the resulting script. +7. Reload your application. ### Configure routing When using your deployed application, static files will be accessible at `https://your-app-name_your-public-namespace.viamapplications.com/machine//`. If your HTML file loads other files, use relative paths to ensure your files are accessible. -## Deploy your web interface as a Viam app +## Deploy your web interface as a Viam application -To deploy your app with Viam you must package it as a module and upload it using the Viam CLI. +To deploy your application with Viam you must package it as a module and upload it using the Viam CLI. {{< table >}} {{% tablestep number=1 %}} @@ -187,7 +187,7 @@ It is required for your module. | `visibility` | string | **Required** | Must be `"public"`. | | `description` | string | **Required** | A description of your module and what it provides. | | `url` | string | Optional | The URL of the GitHub repository containing the source code of the module. | -| `applications` | array | Optional | Objects that provide information about the [apps](/operate/control/viam-app/) associated with the module. | +| `applications` | array | Optional | Objects that provide information about the [applications](/operate/control/viam-applications/) associated with the module. | | `models` | array | Optional | Empty unless you are shipping the app alongside models. For information on how to add models, see [Integrate other hardware](/operate/get-started/other-hardware/). | {{% /expand%}} @@ -197,7 +197,7 @@ The `applications` field is an array of application objects with the following p | Property | Type | Description | | ------------ | ------ | ----------- | -| `name` | string | The name of your application, which will be a part of the app's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [Valid application identifiers](/operate/reference/naming-modules/#valid-application-identifiers). | +| `name` | string | The name of your application, which will be a part of the application's URL (`name_publicnamespace.viamapplications.com`). For more information on valid names see [Valid application identifiers](/operate/reference/naming-modules/#valid-application-identifiers). | | `type` | string | The type of application (currently only `"single_machine"` is supported). | | `entrypoint` | string | The path to the HTML entry point for your application. The `entrypoint` field specifies the path to your application's entry point. For example:
  • "dist/index.html": Static content rooted at the `dist` directory
  • "dist/foo.html": Static content rooted at the `dist` directory, with `foo.html` as the entry point
  • "dist/": Static content rooted at the `dist` directory (assumes `dist/index.html` exists)
  • "dist/bar/foo.html": Static content rooted at `dist/bar` with `foo.html` as the entry point
| @@ -237,7 +237,7 @@ For subsequent updates run these commands again with an updated version number. {{% /tablestep %}} {{< /table >}} -## Access your app +## Access your application After uploading your module with the application configuration, your application will be available at: @@ -257,20 +257,20 @@ Users will be prompted to authenticate with their Viam credentials before access -For a React app that shows camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). +For a React application that shows camera feeds for a machine, see [Viam Camera Viewer](https://github.com/viam-labs/viam-camera-viewer). ## Limitations -- Apps currently only support single-machine applications. -- All modules with apps must have public visibility. +- Applications currently only support single-machine applications. +- All modules with applications must have public visibility. - The page will always render the latest version. - Browsers with cookies disabled are not supported. -- Viam apps serve static files. - If you are building an app with server-side rendering or need other back-end capabilites, Viam apps is not the right choice. +- Viam applications serve static files. + If you are building an application with server-side rendering or need other back-end capabilites, Viam applications is not the right choice. ## Security considerations -- Customer apps are stored publicly on the internet, so avoid uploading sensitive information in your application code or assets. +- Customer applications are stored publicly on the internet, so avoid uploading sensitive information in your application code or assets. - API keys and secrets are stored in the browser's cookies. - Users authenticate with FusionAuth. diff --git a/docs/operate/control/web-app.md b/docs/operate/control/web-app.md index d49c377d79..500c72a2ad 100644 --- a/docs/operate/control/web-app.md +++ b/docs/operate/control/web-app.md @@ -13,9 +13,9 @@ The TypeScript SDK includes: - Implementation of the standard component and service APIs to control your hardware and software - Authentication tools so users can log in securely -{{< alert title="Tip: Host your app on Viam" color="tip" >}} -You can host most apps by [deploying them as Viam apps](/operate/control/viam-app/). -If your app requires server-side rendering or other back-end functionality, self-host your app instead. +{{< alert title="Tip: Host your application on Viam" color="tip" >}} +You can host most apps by [deploying them as Viam applications](/operate/control/viam-applications/). +If your application requires server-side rendering or other back-end functionality, self-host your application instead. {{< /alert >}} ## Install the TypeScript SDK diff --git a/docs/operate/get-started/other-hardware/_index.md b/docs/operate/get-started/other-hardware/_index.md index 5755037200..0381b23d3f 100644 --- a/docs/operate/get-started/other-hardware/_index.md +++ b/docs/operate/get-started/other-hardware/_index.md @@ -1020,7 +1020,7 @@ Do not change the module_id.

applications array Optional -Objects that provide information about the [apps](/operate/control/viam-app/) provided by the module. +Objects that provide information about the [applications](/operate/control/viam-applications/) provided by the module. diff --git a/docs/operate/reference/module-configuration.md b/docs/operate/reference/module-configuration.md index b876f8f52a..7314146bab 100644 --- a/docs/operate/reference/module-configuration.md +++ b/docs/operate/reference/module-configuration.md @@ -250,7 +250,7 @@ Here's an example of a `meta.json` file: } ``` -For modules that include [Viam apps](/operate/control/viam-app/), you can add the `applications` field: +For modules that include [Viam applications](/operate/control/viam-applications/), you can add the `applications` field: ```json { @@ -283,7 +283,7 @@ The `applications` field is an array of application objects with the following p | `type` | string | The type of application (currently only `"web"` is supported) | | `entrypoint` | string | The path to the HTML entry point for your application | -For more information about Viam apps, see the [Viam apps documentation](/operate/control/viam-app/). +For more information about Viam applications, see the [Viam applications documentation](/operate/control/viam-applications/). ### Environment variables diff --git a/netlify.toml b/netlify.toml index 3ab1fbab1a..05f81d62a3 100644 --- a/netlify.toml +++ b/netlify.toml @@ -57,7 +57,7 @@ [plugins.inputs] # change this key to a new one any time you need to restart from scratch - cacheKey = ["May282025"] + cacheKey = ["Jul042025"] # either "warn" or "error" failBuildOnError = true