Add Cross-Project Integration API for RemoteTurtle system
This commit is contained in:
@@ -966,6 +966,78 @@ wss.on('close', () => {
|
|||||||
clearInterval(WS_PING_INTERVAL);
|
clearInterval(WS_PING_INTERVAL);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
// ========== Cross-Project Integration API ==========
|
||||||
|
// These endpoints allow the RemoteTurtle system to query inventory state
|
||||||
|
|
||||||
|
const TURTLE_SERVER_URL = process.env.TURTLE_SERVER_URL || ''; // e.g. http://turtle-server:3001
|
||||||
|
|
||||||
|
// Find where a specific item is stored (for turtles to pick up items)
|
||||||
|
app.get('/api/integration/locate-item', (req, res) => {
|
||||||
|
const { name, minCount } = req.query;
|
||||||
|
if (!name) return res.status(400).json({ error: 'Item name required (?name=minecraft:diamond)' });
|
||||||
|
|
||||||
|
const items = inventoryState.itemList || [];
|
||||||
|
const match = items.find(i => i.name === name);
|
||||||
|
if (!match || match.count < (parseInt(minCount) || 1)) {
|
||||||
|
return res.json({ found: false, available: match ? match.count : 0 });
|
||||||
|
}
|
||||||
|
res.json({ found: true, name: match.name, count: match.count, displayName: match.displayName });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Search items by partial name (for turtle autocomplete/fuzzy matching)
|
||||||
|
app.get('/api/integration/search-items', (req, res) => {
|
||||||
|
const { q, limit } = req.query;
|
||||||
|
if (!q) return res.status(400).json({ error: 'Search query required (?q=diamond)' });
|
||||||
|
|
||||||
|
const items = inventoryState.itemList || [];
|
||||||
|
const query = q.toLowerCase();
|
||||||
|
const results = items
|
||||||
|
.filter(i => i.name.toLowerCase().includes(query) || (i.displayName || '').toLowerCase().includes(query))
|
||||||
|
.sort((a, b) => b.count - a.count)
|
||||||
|
.slice(0, parseInt(limit) || 20);
|
||||||
|
|
||||||
|
res.json({ results });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get storage summary (available space, total items) for turtle decision-making
|
||||||
|
app.get('/api/integration/storage-status', (req, res) => {
|
||||||
|
res.json({
|
||||||
|
grandTotal: inventoryState.grandTotal || 0,
|
||||||
|
chestCount: inventoryState.chestCount || 0,
|
||||||
|
totalSlots: inventoryState.totalSlots || 0,
|
||||||
|
usedSlots: inventoryState.usedSlots || 0,
|
||||||
|
freeSlots: (inventoryState.totalSlots || 0) - (inventoryState.usedSlots || 0),
|
||||||
|
lastUpdate,
|
||||||
|
bridgeConnected: bridgeClients.size > 0,
|
||||||
|
});
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get full item list (for turtle dump target selection)
|
||||||
|
app.get('/api/integration/items', (req, res) => {
|
||||||
|
const items = inventoryState.itemList || [];
|
||||||
|
res.json({ items: items.map(i => ({ name: i.name, count: i.count })) });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Get alerts (so turtles know what items are running low)
|
||||||
|
app.get('/api/integration/low-stock', (req, res) => {
|
||||||
|
const triggered = (alertsState || []).filter(a => a.triggered !== false);
|
||||||
|
res.json({ alerts: triggered });
|
||||||
|
});
|
||||||
|
|
||||||
|
// Proxy to turtle server for combined dashboard info
|
||||||
|
app.get('/api/integration/turtle-status', async (req, res) => {
|
||||||
|
if (!TURTLE_SERVER_URL) {
|
||||||
|
return res.json({ configured: false, message: 'TURTLE_SERVER_URL not configured' });
|
||||||
|
}
|
||||||
|
try {
|
||||||
|
const resp = await fetch(`${TURTLE_SERVER_URL}/api/turtles`);
|
||||||
|
const data = await resp.json();
|
||||||
|
res.json({ configured: true, ...data });
|
||||||
|
} catch (err) {
|
||||||
|
res.status(502).json({ configured: true, error: `Cannot reach turtle server: ${err.message}` });
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
// ========== Start Server ==========
|
// ========== Start Server ==========
|
||||||
|
|
||||||
server.listen(PORT, HOST, () => {
|
server.listen(PORT, HOST, () => {
|
||||||
@@ -973,6 +1045,9 @@ server.listen(PORT, HOST, () => {
|
|||||||
console.log(`\nBridge HTTP endpoint: http://localhost:${PORT}/api/bridge/state`);
|
console.log(`\nBridge HTTP endpoint: http://localhost:${PORT}/api/bridge/state`);
|
||||||
console.log(`Bridge WebSocket: ws://localhost:${PORT}/ws/bridge`);
|
console.log(`Bridge WebSocket: ws://localhost:${PORT}/ws/bridge`);
|
||||||
console.log(`Web client WebSocket: ws://localhost:${PORT}/ws`);
|
console.log(`Web client WebSocket: ws://localhost:${PORT}/ws`);
|
||||||
|
if (TURTLE_SERVER_URL) {
|
||||||
|
console.log(`🐢 Turtle server integration: ${TURTLE_SERVER_URL}`);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
// Graceful shutdown
|
// Graceful shutdown
|
||||||
|
|||||||
Reference in New Issue
Block a user