@viamrobotics/test-widgets 0.7.0 → 0.8.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/client-map.d.ts +30 -30
- package/dist/client-map.js +32 -29
- package/dist/components/index.d.ts +20 -0
- package/dist/components/index.js +20 -0
- package/dist/components/is-moving.svelte +1 -4
- package/dist/components/mutation-section.svelte +1 -1
- package/dist/components/widgets/arm/arm.svelte +8 -5
- package/dist/components/widgets/arm/get-joint-positions-widget.svelte +36 -0
- package/dist/components/widgets/arm/get-joint-positions-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/arm/is-moving-widget.svelte +20 -0
- package/dist/components/widgets/arm/is-moving-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/arm/move-to-joint-positions-widget.svelte +9 -5
- package/dist/components/widgets/arm/move-to-position.svelte +31 -3
- package/dist/components/widgets/audio-input/get-properties-widget.svelte +43 -0
- package/dist/components/widgets/audio-input/get-properties-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/audio-output/get-properties-widget.svelte +43 -0
- package/dist/components/widgets/audio-output/get-properties-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/base/is-moving-widget.svelte +20 -0
- package/dist/components/widgets/base/is-moving-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/base/quick-move.svelte +12 -5
- package/dist/components/widgets/camera/live-or-polling-video.svelte +8 -1
- package/dist/components/widgets/encoder/encoder-position-type.d.ts +8 -0
- package/dist/components/widgets/encoder/encoder-position-type.js +20 -0
- package/dist/components/widgets/encoder/encoder.svelte +3 -20
- package/dist/components/widgets/encoder/get-position-widget.svelte +54 -0
- package/dist/components/widgets/encoder/get-position-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/gantry/get-position-widget.svelte +43 -0
- package/dist/components/widgets/gantry/get-position-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/gantry/is-moving-widget.svelte +20 -0
- package/dist/components/widgets/gantry/is-moving-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/gripper/gripper.svelte +1 -1
- package/dist/components/widgets/gripper/is-holding-something.svelte +1 -4
- package/dist/components/widgets/gripper/is-moving-widget.svelte +20 -0
- package/dist/components/widgets/gripper/is-moving-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/motor/is-moving-widget.svelte +20 -0
- package/dist/components/widgets/motor/is-moving-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/motor/motor.svelte +2 -8
- package/dist/components/widgets/movement-sensor/get-accuracy-widget.svelte +38 -0
- package/dist/components/widgets/movement-sensor/get-accuracy-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/movement-sensor/get-compass-heading-widget.svelte +38 -0
- package/dist/components/widgets/movement-sensor/get-compass-heading-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/movement-sensor/get-orientation-widget.svelte +38 -0
- package/dist/components/widgets/movement-sensor/get-orientation-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/movement-sensor/get-position-widget.svelte +38 -0
- package/dist/components/widgets/movement-sensor/get-position-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/power-sensor/get-current-widget.svelte +38 -0
- package/dist/components/widgets/power-sensor/get-current-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/power-sensor/get-power-widget.svelte +38 -0
- package/dist/components/widgets/power-sensor/get-power-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/power-sensor/get-voltage-widget.svelte +38 -0
- package/dist/components/widgets/power-sensor/get-voltage-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/servo/is-moving-widget.svelte +20 -0
- package/dist/components/widgets/servo/is-moving-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/slam/get-position-widget.svelte +38 -0
- package/dist/components/widgets/slam/get-position-widget.svelte.d.ts +7 -0
- package/dist/components/widgets/vision-service/vision-service.svelte +9 -10
- package/dist/index.d.ts +4 -1
- package/dist/index.js +5 -1
- package/dist/pip/context.svelte.d.ts +2 -0
- package/dist/pip/context.svelte.js +48 -20
- package/dist/resource-triplet.d.ts +37 -0
- package/dist/resource-triplet.js +37 -0
- package/dist/resource-widget.js +187 -0
- package/dist/resource.d.ts +0 -9
- package/dist/resource.js +0 -72
- package/package.json +3 -3
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PowerSensorClient } from '@viamrobotics/sdk'
|
|
3
|
+
import { createResourceClient, createResourceQuery } from '@viamrobotics/svelte-sdk'
|
|
4
|
+
|
|
5
|
+
import ApiSection from '../../api-section.svelte'
|
|
6
|
+
import Query from '../../query.svelte'
|
|
7
|
+
|
|
8
|
+
import PowerReading from './power-reading.svelte'
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
partID: string
|
|
12
|
+
resourceName: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { partID, resourceName }: Props = $props()
|
|
16
|
+
|
|
17
|
+
const client = createResourceClient(
|
|
18
|
+
PowerSensorClient,
|
|
19
|
+
() => partID,
|
|
20
|
+
() => resourceName
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const query = createResourceQuery(client, 'getPower', { refetchInterval: 500 })
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<ApiSection
|
|
27
|
+
title="GetPower"
|
|
28
|
+
class="grow"
|
|
29
|
+
>
|
|
30
|
+
<Query
|
|
31
|
+
{query}
|
|
32
|
+
contentCx="h-6"
|
|
33
|
+
>
|
|
34
|
+
{#if query.data !== undefined}
|
|
35
|
+
<PowerReading data={query.data} />
|
|
36
|
+
{/if}
|
|
37
|
+
</Query>
|
|
38
|
+
</ApiSection>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { PowerSensorClient } from '@viamrobotics/sdk'
|
|
3
|
+
import { createResourceClient, createResourceQuery } from '@viamrobotics/svelte-sdk'
|
|
4
|
+
|
|
5
|
+
import ApiSection from '../../api-section.svelte'
|
|
6
|
+
import Query from '../../query.svelte'
|
|
7
|
+
|
|
8
|
+
import VoltageReading from './voltage-reading.svelte'
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
partID: string
|
|
12
|
+
resourceName: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { partID, resourceName }: Props = $props()
|
|
16
|
+
|
|
17
|
+
const client = createResourceClient(
|
|
18
|
+
PowerSensorClient,
|
|
19
|
+
() => partID,
|
|
20
|
+
() => resourceName
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const query = createResourceQuery(client, 'getVoltage', { refetchInterval: 500 })
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<ApiSection
|
|
27
|
+
title="GetVoltage"
|
|
28
|
+
class="grow"
|
|
29
|
+
>
|
|
30
|
+
<Query
|
|
31
|
+
{query}
|
|
32
|
+
contentCx="h-6"
|
|
33
|
+
>
|
|
34
|
+
{#if query.data !== undefined}
|
|
35
|
+
<VoltageReading data={query.data} />
|
|
36
|
+
{/if}
|
|
37
|
+
</Query>
|
|
38
|
+
</ApiSection>
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { ServoClient } from '@viamrobotics/sdk'
|
|
3
|
+
|
|
4
|
+
import IsMoving from '../../is-moving.svelte'
|
|
5
|
+
import { ResourceTriplets } from '../../../resource-triplet'
|
|
6
|
+
|
|
7
|
+
interface Props {
|
|
8
|
+
partID: string
|
|
9
|
+
resourceName: string
|
|
10
|
+
}
|
|
11
|
+
|
|
12
|
+
const { partID, resourceName }: Props = $props()
|
|
13
|
+
</script>
|
|
14
|
+
|
|
15
|
+
<IsMoving
|
|
16
|
+
client={ServoClient}
|
|
17
|
+
api={ResourceTriplets.Servo}
|
|
18
|
+
{partID}
|
|
19
|
+
{resourceName}
|
|
20
|
+
/>
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
<script lang="ts">
|
|
2
|
+
import { SlamClient } from '@viamrobotics/sdk'
|
|
3
|
+
import { createResourceClient, createResourceQuery } from '@viamrobotics/svelte-sdk'
|
|
4
|
+
|
|
5
|
+
import ApiSection from '../../api-section.svelte'
|
|
6
|
+
import Query from '../../query.svelte'
|
|
7
|
+
|
|
8
|
+
import Position from './position.svelte'
|
|
9
|
+
|
|
10
|
+
interface Props {
|
|
11
|
+
partID: string
|
|
12
|
+
resourceName: string
|
|
13
|
+
}
|
|
14
|
+
|
|
15
|
+
const { partID, resourceName }: Props = $props()
|
|
16
|
+
|
|
17
|
+
const client = createResourceClient(
|
|
18
|
+
SlamClient,
|
|
19
|
+
() => partID,
|
|
20
|
+
() => resourceName
|
|
21
|
+
)
|
|
22
|
+
|
|
23
|
+
const query = createResourceQuery(client, 'getPosition', { refetchInterval: 1000 })
|
|
24
|
+
</script>
|
|
25
|
+
|
|
26
|
+
<ApiSection
|
|
27
|
+
title="GetPosition"
|
|
28
|
+
class="grow"
|
|
29
|
+
>
|
|
30
|
+
<Query
|
|
31
|
+
{query}
|
|
32
|
+
contentCx="h-6"
|
|
33
|
+
>
|
|
34
|
+
{#if query.data !== undefined}
|
|
35
|
+
<Position position={query.data} />
|
|
36
|
+
{/if}
|
|
37
|
+
</Query>
|
|
38
|
+
</ApiSection>
|
|
@@ -147,16 +147,15 @@
|
|
|
147
147
|
</Select>
|
|
148
148
|
</Label>
|
|
149
149
|
</div>
|
|
150
|
-
<
|
|
151
|
-
|
|
152
|
-
|
|
153
|
-
|
|
154
|
-
|
|
155
|
-
|
|
156
|
-
|
|
157
|
-
|
|
158
|
-
|
|
159
|
-
</Label>
|
|
150
|
+
<div class="w-fit">
|
|
151
|
+
<Label position="top">
|
|
152
|
+
Is remote?
|
|
153
|
+
<Switch
|
|
154
|
+
slot="input"
|
|
155
|
+
bind:on={isRemote}
|
|
156
|
+
/>
|
|
157
|
+
</Label>
|
|
158
|
+
</div>
|
|
160
159
|
</div>
|
|
161
160
|
|
|
162
161
|
<h6 class="text-subtle-1 font-semibold">Detections/Classifications</h6>
|
package/dist/index.d.ts
CHANGED
|
@@ -4,4 +4,7 @@ export { clientForResource } from './client-map';
|
|
|
4
4
|
export * from './components';
|
|
5
5
|
export { getResourceAPI } from './get-resource-api';
|
|
6
6
|
export { providePip, usePip } from './pip/context.svelte';
|
|
7
|
-
export {
|
|
7
|
+
export { ResourceTriplets } from './resource-triplet';
|
|
8
|
+
export { apiWidgetsForResource, availableAPIWidgets, isKnownResource,
|
|
9
|
+
/** @deprecated use `isKnownResource` instead. Will be deleted in the next release */
|
|
10
|
+
isKnownResource as hasWidget, type ResourceAPIWidget, showResourceWidget, widgetForResource, } from './resource-widget';
|
package/dist/index.js
CHANGED
|
@@ -4,4 +4,8 @@ export { clientForResource } from './client-map';
|
|
|
4
4
|
export * from './components';
|
|
5
5
|
export { getResourceAPI } from './get-resource-api';
|
|
6
6
|
export { providePip, usePip } from './pip/context.svelte';
|
|
7
|
-
export {
|
|
7
|
+
export { ResourceTriplets } from './resource-triplet';
|
|
8
|
+
export { apiWidgetsForResource, availableAPIWidgets, isKnownResource,
|
|
9
|
+
// TODO: Delete `hasWidget`
|
|
10
|
+
/** @deprecated use `isKnownResource` instead. Will be deleted in the next release */
|
|
11
|
+
isKnownResource as hasWidget, showResourceWidget, widgetForResource, } from './resource-widget';
|
|
@@ -2,6 +2,8 @@ interface PipContext {
|
|
|
2
2
|
/** Called by PictureInPictureButton to start or stop PiP. */
|
|
3
3
|
toggle(resourceName: string): Promise<void>;
|
|
4
4
|
setRate(rate: 'live' | number | false): void;
|
|
5
|
+
/** Register the media stream from the main camera view when its card is open. */
|
|
6
|
+
setStream(resourceName: string, stream: MediaStream | null): void;
|
|
5
7
|
error: Error | undefined;
|
|
6
8
|
/** Whether the PictureInPicture is active */
|
|
7
9
|
readyState: 'inactive' | 'loading' | 'active';
|
|
@@ -14,12 +14,21 @@ export function providePip(partID) {
|
|
|
14
14
|
const canvasCtx = canvas.getContext('2d');
|
|
15
15
|
const canvasStream = canvas.captureStream();
|
|
16
16
|
const img = document.createElement('img');
|
|
17
|
+
const externalStreams = new Map();
|
|
18
|
+
let externalStreamVersion = $state(0);
|
|
17
19
|
let error = $state();
|
|
18
20
|
let readyState = $state('inactive');
|
|
19
21
|
let rate = $state('live');
|
|
20
22
|
let activeName = $state();
|
|
21
|
-
const
|
|
22
|
-
|
|
23
|
+
const externalStream = $derived.by(() => {
|
|
24
|
+
void externalStreamVersion;
|
|
25
|
+
return activeName ? externalStreams.get(activeName) : undefined;
|
|
26
|
+
});
|
|
27
|
+
const needsOwnedStream = $derived(activeName !== undefined && !externalStream);
|
|
28
|
+
const cameraClient = $derived(needsOwnedStream && activeName
|
|
29
|
+
? createResourceClient(CameraClient, partID, () => activeName ?? '')
|
|
30
|
+
: undefined);
|
|
31
|
+
const streamClient = $derived(needsOwnedStream && activeName ? createStreamClient(partID, () => activeName ?? '') : undefined);
|
|
23
32
|
const imageQuery = $derived(cameraClient?.current
|
|
24
33
|
? createResourceQuery(cameraClient, 'getImages', () => ({
|
|
25
34
|
enabled: rate !== 'live',
|
|
@@ -27,22 +36,39 @@ export function providePip(partID) {
|
|
|
27
36
|
refetchIntervalInBackground: activeName === cameraClient?.current?.name,
|
|
28
37
|
}))
|
|
29
38
|
: undefined);
|
|
30
|
-
const
|
|
39
|
+
const ownedMediaStream = $derived(needsOwnedStream ? ((rate === 'live' ? streamClient?.mediaStream : canvasStream) ?? null) : null);
|
|
40
|
+
const playbackStream = $derived(externalStream ?? ownedMediaStream);
|
|
41
|
+
const setStream = (resourceName, stream) => {
|
|
42
|
+
if (stream) {
|
|
43
|
+
externalStreams.set(resourceName, stream);
|
|
44
|
+
}
|
|
45
|
+
else {
|
|
46
|
+
externalStreams.delete(resourceName);
|
|
47
|
+
}
|
|
48
|
+
externalStreamVersion++;
|
|
49
|
+
};
|
|
31
50
|
$effect(() => {
|
|
32
51
|
document.body.append(video);
|
|
52
|
+
const handleLeave = () => {
|
|
53
|
+
readyState = 'inactive';
|
|
54
|
+
activeName = undefined;
|
|
55
|
+
error = undefined;
|
|
56
|
+
};
|
|
57
|
+
video.addEventListener('leavepictureinpicture', handleLeave);
|
|
33
58
|
return () => {
|
|
59
|
+
video.removeEventListener('leavepictureinpicture', handleLeave);
|
|
34
60
|
video.remove();
|
|
35
61
|
};
|
|
36
62
|
});
|
|
37
63
|
$effect(() => {
|
|
38
|
-
video.srcObject =
|
|
64
|
+
video.srcObject = playbackStream;
|
|
39
65
|
return () => {
|
|
40
66
|
video.srcObject = null;
|
|
41
67
|
};
|
|
42
68
|
});
|
|
43
69
|
$effect(() => {
|
|
44
70
|
const currentRate = rate;
|
|
45
|
-
if (currentRate === 'live')
|
|
71
|
+
if (!needsOwnedStream || currentRate === 'live')
|
|
46
72
|
return;
|
|
47
73
|
const image = imageQuery?.data?.images[0];
|
|
48
74
|
if (!image)
|
|
@@ -64,12 +90,11 @@ export function providePip(partID) {
|
|
|
64
90
|
img.removeEventListener('load', drawImage);
|
|
65
91
|
};
|
|
66
92
|
});
|
|
67
|
-
const toggle = async () => {
|
|
68
|
-
if (activeName ===
|
|
69
|
-
readyState === 'active' &&
|
|
70
|
-
document.pictureInPictureElement === video) {
|
|
93
|
+
const toggle = async (resourceName) => {
|
|
94
|
+
if (activeName === resourceName && document.pictureInPictureElement === video) {
|
|
71
95
|
try {
|
|
72
96
|
await document.exitPictureInPicture();
|
|
97
|
+
activeName = undefined;
|
|
73
98
|
readyState = 'inactive';
|
|
74
99
|
error = undefined;
|
|
75
100
|
}
|
|
@@ -78,28 +103,31 @@ export function providePip(partID) {
|
|
|
78
103
|
}
|
|
79
104
|
return;
|
|
80
105
|
}
|
|
106
|
+
activeName = resourceName;
|
|
81
107
|
readyState = 'loading';
|
|
82
|
-
// Wait for the new stream's metadata to load before requesting PiP,
|
|
83
|
-
// otherwise the browser throws InvalidStateError.
|
|
84
|
-
if (video.readyState < 1 /* HAVE_METADATA */) {
|
|
85
|
-
await new Promise((resolve) => {
|
|
86
|
-
video.addEventListener('loadedmetadata', () => resolve(), { once: true });
|
|
87
|
-
});
|
|
88
|
-
}
|
|
89
108
|
try {
|
|
109
|
+
const stream = ownedMediaStream;
|
|
110
|
+
video.srcObject = stream;
|
|
111
|
+
// Wait for the stream's metadata to load before requesting PiP,
|
|
112
|
+
// otherwise the browser throws InvalidStateError.
|
|
113
|
+
if (video.readyState < 1 /* HAVE_METADATA */) {
|
|
114
|
+
await new Promise((resolve) => {
|
|
115
|
+
video.addEventListener('loadedmetadata', () => resolve(), { once: true });
|
|
116
|
+
});
|
|
117
|
+
}
|
|
90
118
|
await video.requestPictureInPicture();
|
|
91
119
|
readyState = 'active';
|
|
92
120
|
error = undefined;
|
|
93
121
|
}
|
|
94
122
|
catch (nextError) {
|
|
123
|
+
readyState = 'inactive';
|
|
124
|
+
activeName = undefined;
|
|
95
125
|
error = nextError;
|
|
96
126
|
}
|
|
97
127
|
};
|
|
98
128
|
const context = {
|
|
99
|
-
|
|
100
|
-
|
|
101
|
-
await toggle();
|
|
102
|
-
},
|
|
129
|
+
toggle,
|
|
130
|
+
setStream,
|
|
103
131
|
setRate(newRate) {
|
|
104
132
|
rate = newRate;
|
|
105
133
|
},
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** The canonical set of Viam resource API triplets. */
|
|
2
|
+
export declare const ResourceTriplets: {
|
|
3
|
+
readonly Arm: "rdk:component:arm";
|
|
4
|
+
readonly AudioInput: "rdk:component:audio_in";
|
|
5
|
+
readonly AudioOutput: "rdk:component:audio_out";
|
|
6
|
+
readonly Base: "rdk:component:base";
|
|
7
|
+
readonly Board: "rdk:component:board";
|
|
8
|
+
readonly Button: "rdk:component:button";
|
|
9
|
+
readonly Camera: "rdk:component:camera";
|
|
10
|
+
readonly Encoder: "rdk:component:encoder";
|
|
11
|
+
readonly Gantry: "rdk:component:gantry";
|
|
12
|
+
readonly GenericComponent: "rdk:component:generic";
|
|
13
|
+
readonly Gripper: "rdk:component:gripper";
|
|
14
|
+
readonly InputController: "rdk:component:input_controller";
|
|
15
|
+
readonly Motor: "rdk:component:motor";
|
|
16
|
+
readonly MovementSensor: "rdk:component:movement_sensor";
|
|
17
|
+
readonly PoseTracker: "rdk:component:pose_tracker";
|
|
18
|
+
readonly PowerSensor: "rdk:component:power_sensor";
|
|
19
|
+
readonly Sensor: "rdk:component:sensor";
|
|
20
|
+
readonly Servo: "rdk:component:servo";
|
|
21
|
+
readonly Switch: "rdk:component:switch";
|
|
22
|
+
readonly BaseRemoteControl: "rdk:service:base_remote_control";
|
|
23
|
+
readonly DataManager: "rdk:service:data_manager";
|
|
24
|
+
readonly Discovery: "rdk:service:discovery";
|
|
25
|
+
readonly GenericService: "rdk:service:generic";
|
|
26
|
+
readonly MLModel: "rdk:service:mlmodel";
|
|
27
|
+
readonly Motion: "rdk:service:motion";
|
|
28
|
+
readonly Navigation: "rdk:service:navigation";
|
|
29
|
+
readonly Slam: "rdk:service:slam";
|
|
30
|
+
readonly Sensors: "rdk:service:sensors";
|
|
31
|
+
readonly Shell: "rdk:service:shell";
|
|
32
|
+
readonly Video: "rdk:service:video";
|
|
33
|
+
readonly Vision: "rdk:service:vision";
|
|
34
|
+
readonly WorldStateStore: "rdk:service:world_state_store";
|
|
35
|
+
};
|
|
36
|
+
/** A Viam resource API triplet, e.g. `'rdk:component:arm'`. */
|
|
37
|
+
export type ResourceTriplet = (typeof ResourceTriplets)[keyof typeof ResourceTriplets];
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/** The canonical set of Viam resource API triplets. */
|
|
2
|
+
export const ResourceTriplets = {
|
|
3
|
+
// components
|
|
4
|
+
Arm: 'rdk:component:arm',
|
|
5
|
+
AudioInput: 'rdk:component:audio_in',
|
|
6
|
+
AudioOutput: 'rdk:component:audio_out',
|
|
7
|
+
Base: 'rdk:component:base',
|
|
8
|
+
Board: 'rdk:component:board',
|
|
9
|
+
Button: 'rdk:component:button',
|
|
10
|
+
Camera: 'rdk:component:camera',
|
|
11
|
+
Encoder: 'rdk:component:encoder',
|
|
12
|
+
Gantry: 'rdk:component:gantry',
|
|
13
|
+
GenericComponent: 'rdk:component:generic',
|
|
14
|
+
Gripper: 'rdk:component:gripper',
|
|
15
|
+
InputController: 'rdk:component:input_controller',
|
|
16
|
+
Motor: 'rdk:component:motor',
|
|
17
|
+
MovementSensor: 'rdk:component:movement_sensor',
|
|
18
|
+
PoseTracker: 'rdk:component:pose_tracker',
|
|
19
|
+
PowerSensor: 'rdk:component:power_sensor',
|
|
20
|
+
Sensor: 'rdk:component:sensor',
|
|
21
|
+
Servo: 'rdk:component:servo',
|
|
22
|
+
Switch: 'rdk:component:switch',
|
|
23
|
+
// services
|
|
24
|
+
BaseRemoteControl: 'rdk:service:base_remote_control',
|
|
25
|
+
DataManager: 'rdk:service:data_manager',
|
|
26
|
+
Discovery: 'rdk:service:discovery',
|
|
27
|
+
GenericService: 'rdk:service:generic',
|
|
28
|
+
MLModel: 'rdk:service:mlmodel',
|
|
29
|
+
Motion: 'rdk:service:motion',
|
|
30
|
+
Navigation: 'rdk:service:navigation',
|
|
31
|
+
Slam: 'rdk:service:slam',
|
|
32
|
+
Sensors: 'rdk:service:sensors',
|
|
33
|
+
Shell: 'rdk:service:shell',
|
|
34
|
+
Video: 'rdk:service:video',
|
|
35
|
+
Vision: 'rdk:service:vision',
|
|
36
|
+
WorldStateStore: 'rdk:service:world_state_store',
|
|
37
|
+
};
|
|
@@ -0,0 +1,187 @@
|
|
|
1
|
+
import { ArmGetJointPositionsWidget, ArmIsMovingWidget, ArmMoveToJointPositionsWidget, ArmMoveToPositionWidget, ArmQuickMoveWidget, ArmWidget, AudioInputGetPropertiesWidget, AudioInputWidget, AudioOutputGetPropertiesWidget, AudioOutputWidget, BaseIsMovingWidget, BaseMoveStraightWidget, BaseQuickMoveWidget, BaseSetPowerWidget, BaseSetVelocityWidget, BaseSpinWidget, BaseWidget, BoardWidget, ButtonWidget, CameraWidget, DiscoveryWidget, EncoderGetPositionWidget, EncoderWidget, GantryGetPositionWidget, GantryHomeWidget, GantryIsMovingWidget, GantryMoveToPositionWidget, GantryQuickMoveWidget, GantryWidget, GripperGrabWidget, GripperIsHoldingSomethingWidget, GripperIsMovingWidget, GripperOpenWidget, GripperWidget, InputControllerWidget, MLModelServiceWidget, MotorGoForWidget, MotorGoToWidget, MotorIsMovingWidget, MotorQuickMoveWidget, MotorSetPowerWidget, MotorSetRPMWidget, MotorWidget, MovementSensorGetAccuracyWidget, MovementSensorGetCompassHeadingWidget, MovementSensorGetOrientationWidget, MovementSensorGetPositionWidget, MovementSensorWidget, NavigationServiceWidget, PowerSensorGetCurrentWidget, PowerSensorGetPowerWidget, PowerSensorGetVoltageWidget, PowerSensorWidget, SensorWidget, ServoIsMovingWidget, ServoMoveWidget, ServoQuickMoveWidget, ServoWidget, SlamGetPositionWidget, SlamWidget, SwitchWidget, VisionServiceWidget, } from "./components/index.js";
|
|
2
|
+
import { getResourceAPI } from "./get-resource-api.js";
|
|
3
|
+
import { ResourceTriplets } from "./resource-triplet.js";
|
|
4
|
+
const resourceWidgetRegistry = {
|
|
5
|
+
// components
|
|
6
|
+
[ResourceTriplets.Arm]: {
|
|
7
|
+
widget: ArmWidget,
|
|
8
|
+
apis: [
|
|
9
|
+
{
|
|
10
|
+
id: 'move-to-joint-positions',
|
|
11
|
+
label: 'MoveToJointPositions',
|
|
12
|
+
widgets: [ArmMoveToJointPositionsWidget],
|
|
13
|
+
},
|
|
14
|
+
{ id: 'move-to-position', label: 'MoveToPosition', widgets: [ArmMoveToPositionWidget] },
|
|
15
|
+
{ id: 'quick-move', label: 'Quick move', widgets: [ArmQuickMoveWidget] },
|
|
16
|
+
{
|
|
17
|
+
id: 'get-joint-positions',
|
|
18
|
+
label: 'GetJointPositions',
|
|
19
|
+
widgets: [ArmGetJointPositionsWidget],
|
|
20
|
+
},
|
|
21
|
+
{ id: 'is-moving', label: 'IsMoving', widgets: [ArmIsMovingWidget] },
|
|
22
|
+
],
|
|
23
|
+
},
|
|
24
|
+
[ResourceTriplets.AudioInput]: {
|
|
25
|
+
widget: AudioInputWidget,
|
|
26
|
+
apis: [
|
|
27
|
+
{ id: 'get-properties', label: 'GetProperties', widgets: [AudioInputGetPropertiesWidget] },
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
[ResourceTriplets.AudioOutput]: {
|
|
31
|
+
widget: AudioOutputWidget,
|
|
32
|
+
apis: [
|
|
33
|
+
{
|
|
34
|
+
id: 'get-properties',
|
|
35
|
+
label: 'GetProperties',
|
|
36
|
+
widgets: [AudioOutputGetPropertiesWidget],
|
|
37
|
+
},
|
|
38
|
+
],
|
|
39
|
+
},
|
|
40
|
+
[ResourceTriplets.Base]: {
|
|
41
|
+
widget: BaseWidget,
|
|
42
|
+
apis: [
|
|
43
|
+
{ id: 'quick-move', label: 'Quick move', widgets: [BaseQuickMoveWidget] },
|
|
44
|
+
{ id: 'move-straight', label: 'MoveStraight', widgets: [BaseMoveStraightWidget] },
|
|
45
|
+
{ id: 'spin', label: 'Spin', widgets: [BaseSpinWidget] },
|
|
46
|
+
{ id: 'set-power', label: 'SetPower', widgets: [BaseSetPowerWidget] },
|
|
47
|
+
{ id: 'set-velocity', label: 'SetVelocity', widgets: [BaseSetVelocityWidget] },
|
|
48
|
+
{ id: 'is-moving', label: 'IsMoving', widgets: [BaseIsMovingWidget] },
|
|
49
|
+
],
|
|
50
|
+
},
|
|
51
|
+
[ResourceTriplets.Board]: { widget: BoardWidget, apis: [] },
|
|
52
|
+
[ResourceTriplets.Button]: { widget: ButtonWidget, apis: [] },
|
|
53
|
+
[ResourceTriplets.Camera]: { widget: CameraWidget, apis: [] },
|
|
54
|
+
[ResourceTriplets.Encoder]: {
|
|
55
|
+
widget: EncoderWidget,
|
|
56
|
+
apis: [{ id: 'get-position', label: 'GetPosition', widgets: [EncoderGetPositionWidget] }],
|
|
57
|
+
},
|
|
58
|
+
[ResourceTriplets.Gantry]: {
|
|
59
|
+
widget: GantryWidget,
|
|
60
|
+
apis: [
|
|
61
|
+
{ id: 'home', label: 'Home', widgets: [GantryHomeWidget] },
|
|
62
|
+
{ id: 'move-to-position', label: 'MoveToPosition', widgets: [GantryMoveToPositionWidget] },
|
|
63
|
+
{ id: 'quick-move', label: 'Quick move', widgets: [GantryQuickMoveWidget] },
|
|
64
|
+
{ id: 'get-position', label: 'GetPosition', widgets: [GantryGetPositionWidget] },
|
|
65
|
+
{ id: 'is-moving', label: 'IsMoving', widgets: [GantryIsMovingWidget] },
|
|
66
|
+
],
|
|
67
|
+
},
|
|
68
|
+
[ResourceTriplets.Gripper]: {
|
|
69
|
+
widget: GripperWidget,
|
|
70
|
+
apis: [
|
|
71
|
+
{ id: 'open-grab', label: 'Open / Grab', widgets: [GripperOpenWidget, GripperGrabWidget] },
|
|
72
|
+
{
|
|
73
|
+
id: 'is-holding-something',
|
|
74
|
+
label: 'IsHoldingSomething',
|
|
75
|
+
widgets: [GripperIsHoldingSomethingWidget],
|
|
76
|
+
},
|
|
77
|
+
{ id: 'is-moving', label: 'IsMoving', widgets: [GripperIsMovingWidget] },
|
|
78
|
+
],
|
|
79
|
+
},
|
|
80
|
+
[ResourceTriplets.InputController]: { widget: InputControllerWidget, apis: [] },
|
|
81
|
+
[ResourceTriplets.Motor]: {
|
|
82
|
+
widget: MotorWidget,
|
|
83
|
+
apis: [
|
|
84
|
+
{ id: 'quick-move', label: 'Quick move', widgets: [MotorQuickMoveWidget] },
|
|
85
|
+
{ id: 'set-power', label: 'SetPower', widgets: [MotorSetPowerWidget] },
|
|
86
|
+
{ id: 'set-rpm', label: 'SetRPM', widgets: [MotorSetRPMWidget] },
|
|
87
|
+
{ id: 'go-for', label: 'GoFor', widgets: [MotorGoForWidget] },
|
|
88
|
+
{ id: 'go-to', label: 'GoTo', widgets: [MotorGoToWidget] },
|
|
89
|
+
{ id: 'is-moving', label: 'IsMoving', widgets: [MotorIsMovingWidget] },
|
|
90
|
+
],
|
|
91
|
+
},
|
|
92
|
+
[ResourceTriplets.MovementSensor]: {
|
|
93
|
+
widget: MovementSensorWidget,
|
|
94
|
+
apis: [
|
|
95
|
+
{ id: 'get-position', label: 'GetPosition', widgets: [MovementSensorGetPositionWidget] },
|
|
96
|
+
{
|
|
97
|
+
id: 'get-orientation',
|
|
98
|
+
label: 'GetOrientation',
|
|
99
|
+
widgets: [MovementSensorGetOrientationWidget],
|
|
100
|
+
},
|
|
101
|
+
{
|
|
102
|
+
id: 'get-compass-heading',
|
|
103
|
+
label: 'GetCompassHeading',
|
|
104
|
+
widgets: [MovementSensorGetCompassHeadingWidget],
|
|
105
|
+
},
|
|
106
|
+
{ id: 'get-accuracy', label: 'GetAccuracy', widgets: [MovementSensorGetAccuracyWidget] },
|
|
107
|
+
],
|
|
108
|
+
},
|
|
109
|
+
[ResourceTriplets.PowerSensor]: {
|
|
110
|
+
widget: PowerSensorWidget,
|
|
111
|
+
apis: [
|
|
112
|
+
{ id: 'get-voltage', label: 'GetVoltage', widgets: [PowerSensorGetVoltageWidget] },
|
|
113
|
+
{ id: 'get-current', label: 'GetCurrent', widgets: [PowerSensorGetCurrentWidget] },
|
|
114
|
+
{ id: 'get-power', label: 'GetPower', widgets: [PowerSensorGetPowerWidget] },
|
|
115
|
+
],
|
|
116
|
+
},
|
|
117
|
+
[ResourceTriplets.Sensor]: { widget: SensorWidget, apis: [] },
|
|
118
|
+
[ResourceTriplets.Servo]: {
|
|
119
|
+
widget: ServoWidget,
|
|
120
|
+
apis: [
|
|
121
|
+
{ id: 'move', label: 'Move', widgets: [ServoMoveWidget] },
|
|
122
|
+
{ id: 'quick-move', label: 'Quick move', widgets: [ServoQuickMoveWidget] },
|
|
123
|
+
{ id: 'is-moving', label: 'IsMoving', widgets: [ServoIsMovingWidget] },
|
|
124
|
+
],
|
|
125
|
+
},
|
|
126
|
+
[ResourceTriplets.Switch]: { widget: SwitchWidget, apis: [] },
|
|
127
|
+
// services
|
|
128
|
+
[ResourceTriplets.Discovery]: { widget: DiscoveryWidget, apis: [] },
|
|
129
|
+
[ResourceTriplets.MLModel]: { widget: MLModelServiceWidget, apis: [] },
|
|
130
|
+
[ResourceTriplets.Navigation]: { widget: NavigationServiceWidget, apis: [] },
|
|
131
|
+
[ResourceTriplets.Slam]: {
|
|
132
|
+
widget: SlamWidget,
|
|
133
|
+
apis: [{ id: 'get-position', label: 'GetPosition', widgets: [SlamGetPositionWidget] }],
|
|
134
|
+
},
|
|
135
|
+
[ResourceTriplets.Vision]: { widget: VisionServiceWidget, apis: [] },
|
|
136
|
+
};
|
|
137
|
+
/**
|
|
138
|
+
* Returns a resource's individual API widgets. Each entry carries a stable `id`, a
|
|
139
|
+
* display `label`, and the `widgets` to render with `{ partID, resourceName }`.
|
|
140
|
+
*
|
|
141
|
+
* Returns `[]` for a resource with a card but no standalone API widgets, and for
|
|
142
|
+
* unrecognized resources.
|
|
143
|
+
*
|
|
144
|
+
* @example
|
|
145
|
+
* apiWidgetsForResource(gripperResourceName)
|
|
146
|
+
* // [{ id: 'open-grab', label: 'Open / Grab', widgets: [GripperOpenWidget, GripperGrabWidget] }, ...]
|
|
147
|
+
*/
|
|
148
|
+
export const apiWidgetsForResource = (resource) => {
|
|
149
|
+
const api = getResourceAPI(resource);
|
|
150
|
+
return api in resourceWidgetRegistry
|
|
151
|
+
? resourceWidgetRegistry[api].apis
|
|
152
|
+
: [];
|
|
153
|
+
};
|
|
154
|
+
/**
|
|
155
|
+
* Returns every resource triplet that has a test card, mapped to its API widgets.
|
|
156
|
+
* Use this to enumerate the full catalog, e.g. a menu spanning every resource type;
|
|
157
|
+
* for a single resource, prefer `apiWidgetsForResource`.
|
|
158
|
+
*
|
|
159
|
+
* @example
|
|
160
|
+
* availableAPIWidgets()[ResourceTriplets.Gripper]
|
|
161
|
+
* // [{ id: 'open-grab', label: 'Open / Grab', widgets: [GripperOpenWidget, GripperGrabWidget] }, ...]
|
|
162
|
+
*/
|
|
163
|
+
export const availableAPIWidgets = () => {
|
|
164
|
+
const result = {};
|
|
165
|
+
for (const triplet of Object.keys(resourceWidgetRegistry)) {
|
|
166
|
+
result[triplet] = resourceWidgetRegistry[triplet].apis;
|
|
167
|
+
}
|
|
168
|
+
return result;
|
|
169
|
+
};
|
|
170
|
+
/** Returns the full composite test card for a resource, or `undefined` if none exists. */
|
|
171
|
+
export const widgetForResource = (resource) => {
|
|
172
|
+
const api = getResourceAPI(resource);
|
|
173
|
+
return api in resourceWidgetRegistry
|
|
174
|
+
? resourceWidgetRegistry[api].widget
|
|
175
|
+
: undefined;
|
|
176
|
+
};
|
|
177
|
+
const knownResources = new Set(Object.values(ResourceTriplets));
|
|
178
|
+
/** Whether a resource's API is a recognized Viam resource triplet. */
|
|
179
|
+
export const isKnownResource = (resource) => knownResources.has(getResourceAPI(resource));
|
|
180
|
+
const hiddenResources = new Set([
|
|
181
|
+
ResourceTriplets.DataManager,
|
|
182
|
+
ResourceTriplets.Motion,
|
|
183
|
+
ResourceTriplets.Sensors,
|
|
184
|
+
ResourceTriplets.Shell,
|
|
185
|
+
]);
|
|
186
|
+
/** Whether the control view should surface a card for this resource. */
|
|
187
|
+
export const showResourceWidget = (resource) => resource.namespace !== 'rdk-internal' && !hiddenResources.has(getResourceAPI(resource));
|
package/dist/resource.d.ts
CHANGED
|
@@ -1,13 +1,8 @@
|
|
|
1
1
|
import type { ResourceStatus } from '@viamrobotics/svelte-sdk';
|
|
2
|
-
import type { Component } from 'svelte';
|
|
3
2
|
import { type ResourceName } from '@viamrobotics/sdk';
|
|
4
3
|
export type NamedResourceStatus = ResourceStatus & {
|
|
5
4
|
name: ResourceName;
|
|
6
5
|
};
|
|
7
|
-
interface ResourceWidget {
|
|
8
|
-
partID: string;
|
|
9
|
-
resourceName: string;
|
|
10
|
-
}
|
|
11
6
|
export declare const ResourceStatusText: {
|
|
12
7
|
0: string;
|
|
13
8
|
3: string;
|
|
@@ -17,7 +12,3 @@ export declare const ResourceStatusText: {
|
|
|
17
12
|
4: string;
|
|
18
13
|
};
|
|
19
14
|
export declare const sortResourceNames: (names: ResourceName[]) => ResourceName[];
|
|
20
|
-
export declare const hasWidget: (resource: ResourceName) => boolean;
|
|
21
|
-
export declare const widgetForResource: (resource: ResourceName) => Component<ResourceWidget> | undefined;
|
|
22
|
-
export declare const showResourceWidget: (resource: ResourceName) => boolean;
|
|
23
|
-
export {};
|