@vention/vention-skills 0.10.27 → 0.10.29
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/.claude-plugin/plugin.json +1 -1
- package/README.md +1 -1
- package/package.json +1 -1
- package/plugin.json +1 -1
- package/skills/vention-design/SKILL.md +1 -1
- package/skills/vention-machine-logic/SKILL.md +3 -2
- package/skills/vention-machine-logic-hmi/SKILL.md +6 -6
- package/skills/vention-machine-logic-hmi/examples/indexing-station-hmi/customui/package.json +3 -3
- package/skills/vention-machine-logic-hmi/examples/indexing-station-hmi/customui/src/app.tsx +45 -6
- package/skills/vention-machine-logic-hmi/examples/indexing-station-hmi/proto/app.proto +12 -48
- package/skills/vention-machine-logic-hmi/examples/indexing-station-hmi/requirements.txt +3 -3
- package/skills/vention-machine-logic-hmi/examples/indexing-station-hmi/server.py +17 -2
- package/skills/vention-monitoring/SKILL.md +1 -1
package/README.md
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
# Vention skills
|
|
2
2
|
|
|
3
|
-
Version 0.10.
|
|
3
|
+
Version 0.10.29. Skills for coding agents that work with Vention machines, packaged as one plugin, `vention`, in the `vention-skills` marketplace.
|
|
4
4
|
|
|
5
5
|
| Skill | What it does |
|
|
6
6
|
| --------------------------- | ------------------------------------------------------------------------------------------------------------------------------------ |
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@vention/vention-skills",
|
|
3
|
-
"version": "0.10.
|
|
3
|
+
"version": "0.10.29",
|
|
4
4
|
"description": "Vention skills for coding agents: write MachineLogic applications, build machine designs, and diagnose deployed machines.",
|
|
5
5
|
"license": "MIT",
|
|
6
6
|
"type": "module",
|
package/plugin.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"$schema": "https://agent-plugins.org/schemas/1.0.0/plugin.schema.json",
|
|
3
3
|
"name": "vention",
|
|
4
|
-
"version": "0.10.
|
|
4
|
+
"version": "0.10.29",
|
|
5
5
|
"description": "Vention skills for coding agents: write MachineLogic applications, build machine designs, and diagnose deployed machines.",
|
|
6
6
|
"author": {
|
|
7
7
|
"name": "Vention"
|
|
@@ -3,7 +3,7 @@ name: vention-design
|
|
|
3
3
|
description: Create, build and edit Vention machine designs and design graphs for agentic layout. Use when the user wants to start a new design, lay out an automation cell, add or reposition components in a Vention design, generate a machine layout from a description, add or place a floor plan image under a design, list a design's versions, or inspect an existing design graph. Trigger on MachineBuilder designs, design graphs, assembly graphs, extrusions, actuators, robot mounting, cell footprints, floor plans, or a machine-builder URL.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.10.
|
|
6
|
+
version: "0.10.29"
|
|
7
7
|
author: Vention
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -3,7 +3,7 @@ name: vention-machine-logic
|
|
|
3
3
|
description: Write, edit, validate, and deploy MachineLogic Python applications for Vention machines with the machine-logic-sdk and the Vention CLI. Load it before writing or changing any Python that talks to a Vention machine, however short, since device names and version-specific SDK calls come from here. Use to program a Vention machine or MachineMotion controller, drive actuators, conveyors, robots, pneumatics, or digital I/O, change an existing application, build a state machine, debug from logs, or pull, push, or link with the Vention CLI (vention or vn). Trigger on MachineLogic, machine-logic-sdk, MachineMotion, MachineBuilder applications, the Vention CLI, or a directory holding .machine-code-app-directory-info.json. Printing what the machine or robot holds now (positions, taught targets, calibration, I/O) is a program: files on disk hold only as-designed values. Not for explaining an existing machine or its configuration in words when no program is asked for, nor for Python that never touches the machine.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.10.
|
|
6
|
+
version: "0.10.29"
|
|
7
7
|
machine-logic-sdk: ">=3.0,<4"
|
|
8
8
|
author: Vention
|
|
9
9
|
---
|
|
@@ -175,8 +175,9 @@ async def feed_board(conveyor: IActuator, line: LineState, travel_mm: float) ->
|
|
|
175
175
|
line.boards_out += 1 # quick calls and shared state stay on the loop
|
|
176
176
|
```
|
|
177
177
|
|
|
178
|
-
|
|
178
|
+
Any other blocking call goes through `asyncio.to_thread` too. Home once, before the tasks start: `await asyncio.to_thread(axis.home, 30)`, or, on SDK releases after 3.1.0, `axis.home_async()` followed by the same wait, which leaves the axis free for a fault path to `stop()` mid-home.
|
|
179
179
|
|
|
180
|
+
- An actuator's `state.position`, `state.speed` and `state.output_torque` each make a blocking HTTP request to the controller. Inside `async def`, read them with `await asyncio.to_thread(lambda: axis.state.position)`.
|
|
180
181
|
- Start the tasks with `asyncio.gather` or `asyncio.wait`; the target runs Python 3.10, which has no `TaskGroup`.
|
|
181
182
|
- SDK callbacks (`on_state_change`, `machine.on_system_state_change`, MQTT) run on SDK threads. Hand their work to the loop with `loop.call_soon_threadsafe`, never by touching shared state from the callback.
|
|
182
183
|
- Cancelling a task does not stop a move a worker thread is waiting on. The shutdown path stops every device it started, in a `finally`.
|
|
@@ -3,7 +3,7 @@ name: vention-machine-logic-hmi
|
|
|
3
3
|
description: Build or edit the custom operator HMI of a MachineLogic application, the React touch screen in customui/ that runs in MachineBuilder and on the MachineMotion pendant, wired to the application's Python process through vention-communication. Use when the user asks for an operator screen, a custom HMI or UI, a touch panel, start and stop buttons, live machine state on screen, or recipes an operator picks, for a Vention machine or inside a directory holding .machine-code-app-directory-info.json. Uses @vention/machine-ui, @vention/machine-apps-components and @vention/machine-logic-ui-sdk. Do not use for the no-code HMI Builder, or for the Python motion logic alone (that is vention-machine-logic).
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.10.
|
|
6
|
+
version: "0.10.29"
|
|
7
7
|
author: Vention
|
|
8
8
|
---
|
|
9
9
|
|
|
@@ -66,15 +66,15 @@ async def start(request: StartRequest) -> CommandResponse:
|
|
|
66
66
|
|
|
67
67
|
|
|
68
68
|
app.register_rpc_plugin(build_state_machine_rpc_bundle(station, triggers=[Triggers.stop.name, BaseTriggers.RESET.value]))
|
|
69
|
-
app.register_rpc_plugin(build_storage_rpc_bundle(accessors=[recipe_accessor], max_records_per_model=None))
|
|
69
|
+
app.register_rpc_plugin(build_storage_rpc_bundle(accessors=[recipe_accessor], max_records_per_model=None, enable_db_actions=False))
|
|
70
70
|
app.finalize()
|
|
71
71
|
```
|
|
72
72
|
|
|
73
73
|
- Create `Machine()` in the FastAPI `lifespan`, through `asyncio.to_thread`, never at import. Importing `server.py` must work with no machine attached: that is how the proto is emitted. When it fails, show the failure as a fault the operator can read.
|
|
74
74
|
- `@action("Start")` names the RPC `Start`. Without the name the RPC takes the function's name as written.
|
|
75
|
-
- The state machine bundle adds `GetState`, `GetHistory` and one `Trigger_<Name>` per trigger
|
|
75
|
+
- The state machine bundle adds `GetState`, `GetHistory` and one `Trigger_<Name>` per trigger. Always pass `triggers=` with only the ones the operator may fire: without it the bundle exposes every trigger, `to_fault` included, and the HMI can fire them around the checks your `@action` handlers make.
|
|
76
76
|
- The storage bundle adds `Recipe_ListRecords`, `Recipe_CreateRecord`, `Recipe_UpdateRecord` and `Recipe_DeleteRecord` among others, named after the accessor. `max_records_per_model=None` lifts its default cap of 5 records.
|
|
77
|
-
-
|
|
77
|
+
- Pass `enable_db_actions=False` unless the HMI has a backup or restore screen. Otherwise the bundle adds `Database_*` RPCs the app never uses, including a whole-database restore.
|
|
78
78
|
- Give every storage model field a zero-value default (`dwell_ms: int = 0`). The client leaves zero values out of the JSON it sends, and a field with no default then fails as NULL.
|
|
79
79
|
- Every storage write takes a non-empty `actor`, the name recorded in the audit log.
|
|
80
80
|
|
|
@@ -101,7 +101,7 @@ async def publish_event(level: str, message: str, detail: str) -> Event:
|
|
|
101
101
|
return Event(timestamp=datetime.now(timezone.utc).isoformat(), level=level, message=message, detail=detail)
|
|
102
102
|
```
|
|
103
103
|
|
|
104
|
-
Awaiting the function publishes its result. Publish status from an `@on_state_change` method on the state machine (`self.spawn(publish_status())`) and after every count or fault change. `replay=True` hands a new subscriber the last status at once; the event log uses `replay=False` so a reconnect does not repeat old events. Also republish status every `STATUS_HEARTBEAT_S` from a task the `lifespan` starts, as the example does: a connection can hang without closing, and the HMI only notices when the heartbeat stops.
|
|
104
|
+
Awaiting the function publishes its result. Publish status from an `@on_state_change` method on the state machine (`self.spawn(publish_status())`) and after every count or fault change. `replay=True` hands a new subscriber the last status at once; the event log uses `replay=False` so a reconnect does not repeat old events. Keep the last events in a `deque(maxlen=RECENT_EVENT_COUNT)` that `publish_event` appends to and an `@action("RecentEvents")` returns: the HMI loads them each time it connects, so the Logs page is not empty after a reload. Also republish status every `STATUS_HEARTBEAT_S` from a task the `lifespan` starts, as the example does: a connection can hang without closing, and the HMI only notices when the heartbeat stops.
|
|
105
105
|
|
|
106
106
|
## The generated client
|
|
107
107
|
|
|
@@ -190,7 +190,7 @@ The HMI drives physical machinery that can injure someone.
|
|
|
190
190
|
|
|
191
191
|
`examples/indexing-station-hmi/` indexes a part on a conveyor, clamps it, proves the clamp closed, dwells and releases, for the cycle count of the recipe the operator picked.
|
|
192
192
|
|
|
193
|
-
- `server.py`: the state machine, the streams, the Start
|
|
193
|
+
- `server.py`: the state machine, the streams and recent-event buffer, the Start and RecentEvents actions, both bundles, `Machine()` in the `lifespan`, the emergency stop routed to fault, and every device stopped on shutdown.
|
|
194
194
|
- `models.py`: the `Recipe` storage model, every field with a zero default.
|
|
195
195
|
- `project.json`, `requirements.txt`: the one process and the exact pins.
|
|
196
196
|
- `proto/app.proto`: what `finalize()` emits.
|
package/skills/vention-machine-logic-hmi/examples/indexing-station-hmi/customui/package.json
CHANGED
|
@@ -15,9 +15,9 @@
|
|
|
15
15
|
"@emotion/styled": "11.14.1",
|
|
16
16
|
"@mui/material": "5.16.7",
|
|
17
17
|
"@tabler/icons-react": "3.44.0",
|
|
18
|
-
"@vention/machine-apps-components": "1.30.
|
|
19
|
-
"@vention/machine-logic-ui-sdk": "0.47.
|
|
20
|
-
"@vention/machine-ui": "6.7.
|
|
18
|
+
"@vention/machine-apps-components": "1.30.26",
|
|
19
|
+
"@vention/machine-logic-ui-sdk": "0.47.5",
|
|
20
|
+
"@vention/machine-ui": "6.7.1",
|
|
21
21
|
"react": "17.0.2",
|
|
22
22
|
"react-dom": "17.0.2",
|
|
23
23
|
"react-router-dom": "6.30.3",
|
|
@@ -28,29 +28,68 @@ function toLogLevel(level: string): LogType {
|
|
|
28
28
|
return "info"
|
|
29
29
|
}
|
|
30
30
|
|
|
31
|
+
function eventKey(entry: LogEntry): string {
|
|
32
|
+
return `${entry.date}|${entry.message}|${entry.description}`
|
|
33
|
+
}
|
|
34
|
+
|
|
35
|
+
// The stream and RecentEvents can both deliver an event published while the HMI connects, in either order.
|
|
36
|
+
function mergeNewestFirst(previous: LogEntry[], incoming: LogEntry[]): LogEntry[] {
|
|
37
|
+
const shown = new Set(previous.map(eventKey))
|
|
38
|
+
const merged = [...previous, ...incoming.filter(entry => !shown.has(eventKey(entry)))]
|
|
39
|
+
return merged.sort((left, right) => right.date.localeCompare(left.date)).slice(0, MAX_LOG_ENTRIES)
|
|
40
|
+
}
|
|
41
|
+
|
|
31
42
|
/** The server's events, plus the HMI's own command failures, newest first. */
|
|
32
|
-
function useEventLog(
|
|
43
|
+
function useEventLog(connected: boolean): {
|
|
44
|
+
entries: LogEntry[]
|
|
45
|
+
addEntry: (level: LogType, message: string, description: string) => string
|
|
46
|
+
} {
|
|
33
47
|
const { value: latestEvent } = useStream<Event>(openEvents)
|
|
34
48
|
const [entries, setEntries] = useState<LogEntry[]>([])
|
|
35
49
|
const nextId = useRef(0)
|
|
36
50
|
|
|
37
|
-
const
|
|
51
|
+
const toLogEntry = useCallback((level: LogType, message: string, description: string, date: string): LogEntry => {
|
|
38
52
|
nextId.current += 1
|
|
39
|
-
|
|
40
|
-
setEntries(previous => [entry, ...previous].slice(0, MAX_LOG_ENTRIES))
|
|
41
|
-
return entry.id
|
|
53
|
+
return { id: String(nextId.current), date, level, code: level.toUpperCase(), message, description }
|
|
42
54
|
}, [])
|
|
43
55
|
|
|
56
|
+
const addEntry = useCallback(
|
|
57
|
+
(level: LogType, message: string, description: string, date = new Date().toISOString()) => {
|
|
58
|
+
const entry = toLogEntry(level, message, description, date)
|
|
59
|
+
setEntries(previous => mergeNewestFirst(previous, [entry]))
|
|
60
|
+
return entry.id
|
|
61
|
+
},
|
|
62
|
+
[toLogEntry]
|
|
63
|
+
)
|
|
64
|
+
|
|
44
65
|
useEffect(() => {
|
|
45
66
|
if (latestEvent !== undefined) addEntry(toLogLevel(latestEvent.level), latestEvent.message, latestEvent.detail, latestEvent.timestamp)
|
|
46
67
|
}, [latestEvent, addEntry])
|
|
47
68
|
|
|
69
|
+
// The Events stream does not replay, so each (re)connect loads what the server kept.
|
|
70
|
+
useEffect(() => {
|
|
71
|
+
if (!connected) return
|
|
72
|
+
const controller = new AbortController()
|
|
73
|
+
client
|
|
74
|
+
.recentEvents({}, { signal: controller.signal })
|
|
75
|
+
.then(({ events }) =>
|
|
76
|
+
setEntries(previous =>
|
|
77
|
+
mergeNewestFirst(
|
|
78
|
+
previous,
|
|
79
|
+
events.map(event => toLogEntry(toLogLevel(event.level), event.message, event.detail, event.timestamp))
|
|
80
|
+
)
|
|
81
|
+
)
|
|
82
|
+
)
|
|
83
|
+
.catch(() => undefined)
|
|
84
|
+
return () => controller.abort()
|
|
85
|
+
}, [connected, toLogEntry])
|
|
86
|
+
|
|
48
87
|
return { entries, addEntry }
|
|
49
88
|
}
|
|
50
89
|
|
|
51
90
|
export function App() {
|
|
52
91
|
const { value: status, connected } = useStream(openStatus, STATUS_STALL_MS)
|
|
53
|
-
const { entries: logEntries, addEntry } = useEventLog()
|
|
92
|
+
const { entries: logEntries, addEntry } = useEventLog(connected)
|
|
54
93
|
const navigate = useNavigate()
|
|
55
94
|
const isOnLogsPage = useLocation().pathname === "/logs"
|
|
56
95
|
// The latest error shows as a banner on every page until it fades; View opens the whole entry on the Logs page.
|
|
@@ -4,6 +4,17 @@ package vention.app.v1;
|
|
|
4
4
|
import "google/protobuf/empty.proto";
|
|
5
5
|
|
|
6
6
|
|
|
7
|
+
message Event {
|
|
8
|
+
string timestamp = 1;
|
|
9
|
+
string level = 2;
|
|
10
|
+
string message = 3;
|
|
11
|
+
string detail = 4;
|
|
12
|
+
}
|
|
13
|
+
|
|
14
|
+
message EventHistory {
|
|
15
|
+
repeated Event events = 1;
|
|
16
|
+
}
|
|
17
|
+
|
|
7
18
|
message StartRequest {
|
|
8
19
|
int32 recipe_id = 1;
|
|
9
20
|
}
|
|
@@ -117,42 +128,6 @@ message RecipeRestoreResponse {
|
|
|
117
128
|
Recipe record = 1;
|
|
118
129
|
}
|
|
119
130
|
|
|
120
|
-
message HealthResponse {
|
|
121
|
-
string status = 1;
|
|
122
|
-
}
|
|
123
|
-
|
|
124
|
-
message AuditQueryRequest {
|
|
125
|
-
string component = 1;
|
|
126
|
-
int32 record_id = 2;
|
|
127
|
-
string actor = 3;
|
|
128
|
-
string operation = 4;
|
|
129
|
-
string since = 5;
|
|
130
|
-
string until = 6;
|
|
131
|
-
int32 limit = 7;
|
|
132
|
-
int32 offset = 8;
|
|
133
|
-
}
|
|
134
|
-
|
|
135
|
-
message AuditListResponse {
|
|
136
|
-
repeated string records = 1;
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
message FileResponse {
|
|
140
|
-
string filename = 1;
|
|
141
|
-
bytes bytes = 2;
|
|
142
|
-
}
|
|
143
|
-
|
|
144
|
-
message DatabaseRestoreRequest {
|
|
145
|
-
bytes bytes = 1;
|
|
146
|
-
string filename = 2;
|
|
147
|
-
bool integrity_check = 3;
|
|
148
|
-
bool dry_run = 4;
|
|
149
|
-
}
|
|
150
|
-
|
|
151
|
-
message DatabaseRestoreResponse {
|
|
152
|
-
bool ok = 1;
|
|
153
|
-
string message = 2;
|
|
154
|
-
}
|
|
155
|
-
|
|
156
131
|
message StationStatus {
|
|
157
132
|
string state = 1;
|
|
158
133
|
string recipe_name = 2;
|
|
@@ -165,14 +140,8 @@ message StationStatus {
|
|
|
165
140
|
string fault = 9;
|
|
166
141
|
}
|
|
167
142
|
|
|
168
|
-
message Event {
|
|
169
|
-
string timestamp = 1;
|
|
170
|
-
string level = 2;
|
|
171
|
-
string message = 3;
|
|
172
|
-
string detail = 4;
|
|
173
|
-
}
|
|
174
|
-
|
|
175
143
|
service IndexingStationService {
|
|
144
|
+
rpc RecentEvents (google.protobuf.Empty) returns (EventHistory);
|
|
176
145
|
rpc Start (StartRequest) returns (CommandResponse);
|
|
177
146
|
rpc GetState (google.protobuf.Empty) returns (StateResponse);
|
|
178
147
|
rpc GetHistory (google.protobuf.Empty) returns (HistoryResponse);
|
|
@@ -185,11 +154,6 @@ service IndexingStationService {
|
|
|
185
154
|
rpc Recipe_UpdateRecord (RecipeUpdateRequest) returns (RecipeUpdateResponse);
|
|
186
155
|
rpc Recipe_DeleteRecord (CrudDeleteRequest) returns (RecipeStatusResponse);
|
|
187
156
|
rpc Recipe_RestoreRecord (CrudRestoreRequest) returns (RecipeRestoreResponse);
|
|
188
|
-
rpc Database_Health (google.protobuf.Empty) returns (HealthResponse);
|
|
189
|
-
rpc Database_ReadAudit (AuditQueryRequest) returns (AuditListResponse);
|
|
190
|
-
rpc Database_ExportZip (google.protobuf.Empty) returns (FileResponse);
|
|
191
|
-
rpc Database_BackupSqlite (google.protobuf.Empty) returns (FileResponse);
|
|
192
|
-
rpc Database_RestoreSqlite (DatabaseRestoreRequest) returns (DatabaseRestoreResponse);
|
|
193
157
|
rpc Status (google.protobuf.Empty) returns (stream StationStatus);
|
|
194
158
|
rpc Events (google.protobuf.Empty) returns (stream Event);
|
|
195
159
|
}
|
|
@@ -6,6 +6,7 @@ An emergency stop sends the station to fault, and shutting the server down stops
|
|
|
6
6
|
|
|
7
7
|
import asyncio
|
|
8
8
|
import time
|
|
9
|
+
from collections import deque
|
|
9
10
|
from contextlib import asynccontextmanager
|
|
10
11
|
from datetime import datetime, timezone
|
|
11
12
|
from pathlib import Path
|
|
@@ -33,6 +34,8 @@ CLAMP_PROOF_TIMEOUT_S = 2.0
|
|
|
33
34
|
CLAMP_POLL_S = 0.05
|
|
34
35
|
# The HMI treats a Status stream that stays silent for three heartbeats as dropped.
|
|
35
36
|
STATUS_HEARTBEAT_S = 2.0
|
|
37
|
+
# The Events stream does not replay, so the HMI loads these each time it connects.
|
|
38
|
+
RECENT_EVENT_COUNT = 100
|
|
36
39
|
ACCELERATION_MM_S2 = 400.0
|
|
37
40
|
DATA_DIR = Path(__file__).parent / "data"
|
|
38
41
|
|
|
@@ -79,6 +82,10 @@ class Event(BaseModel):
|
|
|
79
82
|
detail: str
|
|
80
83
|
|
|
81
84
|
|
|
85
|
+
class EventHistory(BaseModel):
|
|
86
|
+
events: list[Event]
|
|
87
|
+
|
|
88
|
+
|
|
82
89
|
class StartRequest(BaseModel):
|
|
83
90
|
recipe_id: int
|
|
84
91
|
|
|
@@ -224,6 +231,7 @@ DATA_DIR.mkdir(exist_ok=True)
|
|
|
224
231
|
bootstrap(database_url=f"sqlite:///{DATA_DIR / 'recipes.db'}")
|
|
225
232
|
recipe_accessor = ModelAccessor(Recipe, "recipe")
|
|
226
233
|
station = IndexingStation()
|
|
234
|
+
recent_events: deque[Event] = deque(maxlen=RECENT_EVENT_COUNT)
|
|
227
235
|
|
|
228
236
|
|
|
229
237
|
async def repeat_status() -> None:
|
|
@@ -266,7 +274,14 @@ async def publish_status() -> StationStatus:
|
|
|
266
274
|
|
|
267
275
|
@stream(name="Events", payload=Event, replay=False, queue_maxsize=100, policy="fifo")
|
|
268
276
|
async def publish_event(level: str, message: str, detail: str) -> Event:
|
|
269
|
-
|
|
277
|
+
event = Event(timestamp=datetime.now(timezone.utc).isoformat(), level=level, message=message, detail=detail)
|
|
278
|
+
recent_events.append(event)
|
|
279
|
+
return event
|
|
280
|
+
|
|
281
|
+
|
|
282
|
+
@action("RecentEvents")
|
|
283
|
+
async def get_recent_events() -> EventHistory:
|
|
284
|
+
return EventHistory(events=list(recent_events))
|
|
270
285
|
|
|
271
286
|
|
|
272
287
|
@action("Start")
|
|
@@ -286,5 +301,5 @@ async def start(request: StartRequest) -> CommandResponse:
|
|
|
286
301
|
|
|
287
302
|
|
|
288
303
|
app.register_rpc_plugin(build_state_machine_rpc_bundle(station, triggers=[Triggers.stop.name, BaseTriggers.RESET.value]))
|
|
289
|
-
app.register_rpc_plugin(build_storage_rpc_bundle(accessors=[recipe_accessor], max_records_per_model=None))
|
|
304
|
+
app.register_rpc_plugin(build_storage_rpc_bundle(accessors=[recipe_accessor], max_records_per_model=None, enable_db_actions=False))
|
|
290
305
|
app.finalize()
|
|
@@ -3,7 +3,7 @@ name: vention-monitoring
|
|
|
3
3
|
description: Diagnose deployed Vention machines from controller state, history, health, and activity data. Use when the user reports a machine that is down, faulted, offline, slow, or underperforming, asks why a cycle time regressed, wants to interpret MachineMotion event data or drive and brake status, asks about OEE or uptime, or wants to know which machine in a fleet needs attention. Trigger on a MachineMotion serial number plus any complaint.
|
|
4
4
|
license: MIT
|
|
5
5
|
metadata:
|
|
6
|
-
version: "0.10.
|
|
6
|
+
version: "0.10.29"
|
|
7
7
|
author: Vention
|
|
8
8
|
---
|
|
9
9
|
|