Skip to content

Commit 7d2bc17

Browse files
authored
Update examples to d5fc156f6fd9df0dfe9cce66c0e1dc083bf448d2 (#17)
Signed-off-by: Michael Carroll <[email protected]>
1 parent 5c3cf8a commit 7d2bc17

File tree

8 files changed

+233
-28
lines changed

8 files changed

+233
-28
lines changed

.gitignore

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,3 +5,4 @@ bazel-**
55
compile_commands.json
66
MODULE.bazel.lock
77
.env
8+
package-lock.json

MODULE.bazel

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -11,13 +11,13 @@ archive_override(
1111
)
1212

1313
# Direct dependencies
14-
bazel_dep(name = "abseil-cpp", version = "20250127.1", repo_name = "com_google_absl")
14+
bazel_dep(name = "abseil-cpp", version = "20250512.1", repo_name = "com_google_absl")
1515
bazel_dep(name = "abseil-py", version = "2.1.0", repo_name = "com_google_absl_py")
1616
bazel_dep(name = "bazel_skylib", version = "1.8.0")
1717
bazel_dep(name = "googletest", version = "1.17.0", repo_name = "com_google_googletest")
1818
bazel_dep(name = "grpc", version = "1.73.1", repo_name = "com_github_grpc_grpc")
1919
bazel_dep(name = "platforms", version = "1.0.0")
20-
bazel_dep(name = "protobuf", version = "30.1", repo_name = "com_google_protobuf")
20+
bazel_dep(name = "protobuf", version = "31.1", repo_name = "com_google_protobuf")
2121
bazel_dep(name = "rules_go", version = "0.55.1", repo_name = "io_bazel_rules_go")
2222
bazel_dep(name = "rules_pkg", version = "1.1.0")
2323
bazel_dep(name = "rules_python", version = "1.4.1")
@@ -31,10 +31,10 @@ llvm.toolchain(
3131
)
3232

3333
non_module_deps = use_extension("@ai_intrinsic_sdks//bazel:non_module_deps.bzl", "non_module_deps_ext")
34-
use_repo(non_module_deps, "com_googleapis_storage_chrome_linux_amd64_sysroot")
34+
use_repo(non_module_deps, "intrinsic_llvm_sysroot")
3535

3636
llvm.sysroot(
37-
label = "@com_googleapis_storage_chrome_linux_amd64_sysroot//:all_files",
37+
label = "@intrinsic_llvm_sysroot//:all_files",
3838
targets = ["linux-x86_64"],
3939
)
4040
use_repo(llvm, "llvm_toolchain")

services/angular-hmi/README.md

Lines changed: 1 addition & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This example implements a service-based HMI for Flowstate.
44

55
> [!IMPORTANT]
6-
> This HMI service is based on the ["Create an HMI service"](https://flowstate.intrinsic.ai/docs/guides/build_with_code/develop_a_service/implement_service_scenarios/create_hmi_service/) guide in the Flowstate documentation.
6+
> This HMI service is based on the ["Create an HMI service"](https://flowstate.intrinsic.ai/docs/assets/create_new_assets/create_services/implement_service_scenarios/create_hmi_service/) guide in the Flowstate documentation.
77
88
## Features
99

@@ -70,5 +70,3 @@ It should generate a `.tar` ready to be deployed, take note of the output locati
7070
```sh
7171
inctl service install bazel-bin/services/angular-hmi/hmi_angular_service.bundle.tar --org=ORGANIZATION_NAME --address="workcell.lan:17080"
7272
```
73-
74-

services/hmi/BUILD

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@ go_binary(
1414
srcs = ["server.go"],
1515
data = [":frontend_files"],
1616
deps = [
17+
"@ai_intrinsic_sdks//intrinsic/assets/services/proto/v1:system_service_state_go_grpc_proto",
1718
"@ai_intrinsic_sdks//intrinsic/executive/proto:behavior_tree_go_proto",
1819
"@ai_intrinsic_sdks//intrinsic/executive/proto:executive_execution_mode_go_proto",
1920
"@ai_intrinsic_sdks//intrinsic/executive/proto:executive_service_go_grpc_proto",

services/hmi/README.md

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3,7 +3,7 @@
33
This example implements a service-based HMI for Flowstate.
44

55
> [!IMPORTANT]
6-
> This HMI service is based on the ["Create an HMI service"](https://flowstate.intrinsic.ai/docs/guides/build_with_code/develop_a_service/implement_service_scenarios/create_hmi_service/) guide in the Flowstate documentation.
6+
> This HMI service is based on the ["Create an HMI service"](https://flowstate.intrinsic.ai/docs/assets/create_new_assets/create_services/implement_service_scenarios/create_hmi_service/) guide in the Flowstate documentation.
77
> Follows the steps in the guide to install the HMI service in your solution.
88
99
## Features
@@ -12,6 +12,7 @@ This example implements a service-based HMI for Flowstate.
1212
* stop execution
1313
* pause/resume execution
1414
* view execution status (inluding errors)
15+
* query and modify the state of service instances in a solution
1516

1617
## Test locally
1718

services/hmi/frontend/index.html

Lines changed: 101 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -19,34 +19,45 @@ <h1 class="title">HMI</h1>
1919
<div class="box">
2020
Select a behavior tree to execute:
2121
<select id="bt-list">
22-
<option value="">Select an option</option>
22+
<option value="">Select an option</option>
2323
</select>
2424
</div>
2525
<button disabled class="button is-success" id="start">
2626
Start Process
2727
</button>
2828
<button disabled class="button is-danger" id="stop">Stop</button>
29+
<div class="box" style="margin-top: 32px">
30+
<button class="button" id="states-list" style="margin-bottom: 16px">
31+
List/refresh service states
32+
</button>
33+
<div id="service-states" class="content"></div>
34+
</div>
35+
<div style="display: none" class="notification" id="state-result"></div>
2936
</div>
3037
</section>
3138

3239
<script>
3340
let operationId = "";
3441
let behaviorTreeName = "";
3542
let showStatus = false;
43+
let states = [];
3644

3745
const startEl = document.getElementById("start");
3846
const stopEl = document.getElementById("stop");
3947
const statusEl = document.getElementById("status");
4048
const resultEl = document.getElementById("result");
4149
const btListEl = document.getElementById("bt-list");
50+
const serviceStatesEl = document.getElementById("service-states");
51+
const listStatesEl = document.getElementById("states-list");
4252
refreshStatus();
4353

54+
4455
btListEl.addEventListener('mousedown', async () => {
4556
// Clear existing options.
46-
btListEl.innerHTML = '<option value="">Select an option</option>';
57+
btListEl.innerHTML = '<option value="">Select an option</option>';
4758

4859
// Add all currently saved behavior trees in solution.
49-
const options = await getBehaviorTrees();
60+
const options = await getBehaviorTrees();
5061
options.forEach(optionText => {
5162
const option = document.createElement('option');
5263
option.value = optionText;
@@ -66,6 +77,10 @@ <h1 class="title">HMI</h1>
6677
start(behaviorTreeName);
6778
});
6879

80+
listStatesEl.addEventListener("click", async () => {
81+
states = await listServiceStates();
82+
});
83+
6984
async function refreshStatus() {
7085
if (!behaviorTreeName){
7186
statusEl.textContent = "UNSPECIFIED";
@@ -87,7 +102,7 @@ <h1 class="title">HMI</h1>
87102
stopEl.disabled = true;
88103
}
89104
} else {
90-
startEl.disabled = true;
105+
startEl.disabled = false;
91106
stopEl.disabled = true;
92107
}
93108

@@ -110,8 +125,87 @@ <h1 class="title">HMI</h1>
110125
operationId = "";
111126
}
112127
}
113-
// Refresh the current status every second.
114-
setTimeout(refreshStatus, 1000);
128+
129+
if (states.length > 0) {
130+
let str = `
131+
<table>
132+
<thead>
133+
<tr>
134+
<th>Name</th>
135+
<th>State</th>
136+
<th>Enable</th>
137+
<th>Disable</th>
138+
<th>Restart</th>
139+
</tr>
140+
</thead>
141+
<tbody>
142+
`;
143+
states.forEach(function(state) {
144+
let row = '<tr>'
145+
row += '<td>' + state.name + '</td>';
146+
row += '<td>' + state.state.stateCode + '</td>';
147+
row += `<td><button class="button" id="enable-${state.name}">Enable</button></td>`;
148+
row += `<td><button class="button" id="disable-${state.name}">Disable</button></td>`;
149+
row += `<td><button class="button" id="restart-${state.name}">Restart</button></td>`;
150+
row += '</tr>';
151+
str += row;
152+
});
153+
str += `
154+
</tbody>
155+
</table>
156+
`;
157+
serviceStatesEl.innerHTML = str;
158+
states.forEach(function(state) {
159+
addStateManagementHandlers(state.name);
160+
})
161+
}
162+
163+
// Refresh the current status every second.
164+
setTimeout(refreshStatus, 1000);
165+
}
166+
167+
function addStateManagementHandlers(name) {
168+
const notificationEl = document.getElementById("state-result");
169+
stateHandler(document.getElementById(`enable-${name}`), "enable", name, notificationEl);
170+
stateHandler(document.getElementById(`disable-${name}`), "disable", name, notificationEl);
171+
stateHandler(document.getElementById(`restart-${name}`), "restart", name, notificationEl);
172+
}
173+
174+
function stateHandler(buttonEl, stateMethod, name, notificationEl) {
175+
buttonEl.addEventListener("click", async () => {
176+
try {
177+
notificationEl.style.display = "none";
178+
const req = new Request(`api/serviceStates/${name}/${stateMethod}`, {
179+
method: 'POST',
180+
});
181+
const res = await fetch(req);
182+
const s = await res.json();
183+
if (s.error) {
184+
notificationEl.classList.add('is-danger');
185+
notificationEl.classList.remove('is-success');
186+
notificationEl.textContent = s.error;
187+
} else {
188+
notificationEl.classList.remove('is-danger');
189+
notificationEl.classList.add('is-success');
190+
notificationEl.textContent = `"${stateMethod}" successful.`;
191+
}
192+
notificationEl.style.display = "block";
193+
} catch (e) {
194+
notificationEl.classList.add('is-danger');
195+
notificationEl.classList.remove('is-success');
196+
notificationEl.textContent = `Failed to ${stateMethod} ${name}`;
197+
notificationEl.style.display = "block";
198+
}
199+
})
200+
}
201+
202+
async function listServiceStates() {
203+
const res = await fetch("api/serviceStates");
204+
const s = await res.json();
205+
if(Array.isArray(s['states'])) {
206+
return s['states'];
207+
}
208+
return [];
115209
}
116210

117211
async function getBehaviorTrees() {
@@ -121,7 +215,7 @@ <h1 class="title">HMI</h1>
121215
s = await res.json();
122216
if(Array.isArray(s['names']) && s['names'].length > 0) {
123217
return s['names'];
124-
}
218+
}
125219
} catch (e) {
126220
console.log(s.error);
127221
}

0 commit comments

Comments
 (0)