Initial commit of akmon project
This commit is contained in:
34
server/gateway-mqtt-node/scripts/simulate_ack.js
Normal file
34
server/gateway-mqtt-node/scripts/simulate_ack.js
Normal file
@@ -0,0 +1,34 @@
|
||||
import 'dotenv/config'
|
||||
import mqtt from 'mqtt'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
const MQTT_URL = process.env.MQTT_URL
|
||||
if (!MQTT_URL) throw new Error('Missing MQTT_URL')
|
||||
|
||||
const pattern = process.env.ACK_TOPIC_PATTERN || 'device/+/ack'
|
||||
const target = process.env.SIM_ACK_TARGET // e.g. userId or deviceId to fill the '+'
|
||||
const correlationId = process.env.SIM_CORRELATION_ID || uuidv4()
|
||||
|
||||
const topic = (() => {
|
||||
const parts = pattern.split('/')
|
||||
const tParts = []
|
||||
let used = false
|
||||
for (const p of parts) {
|
||||
if (p === '+') { tParts.push(target || 'test'); used = true } else tParts.push(p)
|
||||
}
|
||||
if (pattern.includes('+') && !used) throw new Error('Pattern contains + but could not fill it')
|
||||
return tParts.join('/')
|
||||
})()
|
||||
|
||||
const payload = JSON.stringify({ correlation_id: correlationId, ok: true, t: Date.now() })
|
||||
|
||||
console.log('Publishing ACK', { topic, correlationId })
|
||||
const client = mqtt.connect(MQTT_URL, { clientId: `ack-sim-${Math.random().toString(16).slice(2)}` })
|
||||
client.on('connect', () => {
|
||||
client.publish(topic, payload, { qos: 1 }, (err) => {
|
||||
if (err) console.error('publish error', err)
|
||||
else console.log('ACK published')
|
||||
setTimeout(() => client.end(true, () => process.exit(err ? 1 : 0)), 200)
|
||||
})
|
||||
})
|
||||
client.on('error', (e) => { console.error('mqtt error', e); process.exit(2) })
|
||||
43
server/gateway-mqtt-node/scripts/simulate_chat_downlink.js
Normal file
43
server/gateway-mqtt-node/scripts/simulate_chat_downlink.js
Normal file
@@ -0,0 +1,43 @@
|
||||
import 'dotenv/config'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
async function main() {
|
||||
const SUPABASE_URL = process.env.SUPABASE_URL
|
||||
const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY
|
||||
if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE_KEY) throw new Error('Missing SUPABASE_URL or SUPABASE_SERVICE_ROLE_KEY')
|
||||
|
||||
const conversationId = process.env.SIM_CHAT_CONVERSATION_ID
|
||||
if (!conversationId) throw new Error('SIM_CHAT_CONVERSATION_ID required')
|
||||
|
||||
const targetUserId = process.env.SIM_TARGET_USER_ID || ''
|
||||
const topic = process.env.SIM_TOPIC || (targetUserId ? `device/${targetUserId}/down` : '')
|
||||
if (!topic) throw new Error('Provide SIM_TOPIC or SIM_TARGET_USER_ID to derive topic')
|
||||
|
||||
const correlationId = process.env.SIM_CORRELATION_ID || uuidv4()
|
||||
const payloadObj = process.env.SIM_PAYLOAD
|
||||
? JSON.parse(process.env.SIM_PAYLOAD)
|
||||
: { type: 'ping', t: Date.now(), correlation_id: correlationId }
|
||||
const payload = typeof payloadObj === 'string' ? payloadObj : JSON.stringify(payloadObj)
|
||||
const qos = parseInt(process.env.SIM_QOS || '1', 10)
|
||||
const retain = /^true$/i.test(process.env.SIM_RETAIN || 'false')
|
||||
|
||||
const supa = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, { auth: { autoRefreshToken: false, persistSession: false } })
|
||||
const row = {
|
||||
conversation_id: conversationId,
|
||||
target_user_id: targetUserId || null,
|
||||
topic,
|
||||
payload,
|
||||
payload_encoding: 'utf8',
|
||||
qos,
|
||||
retain,
|
||||
status: 'pending',
|
||||
scheduled_at: new Date().toISOString(),
|
||||
correlation_id: correlationId
|
||||
}
|
||||
const { data, error } = await supa.from('chat_mqtt_downlinks').insert(row).select('*').single()
|
||||
if (error) throw error
|
||||
console.log('Inserted chat downlink:', { id: data.id, correlation_id: correlationId, topic })
|
||||
}
|
||||
|
||||
main().catch((e) => { console.error(e); process.exit(1) })
|
||||
38
server/gateway-mqtt-node/scripts/simulate_downlink.js
Normal file
38
server/gateway-mqtt-node/scripts/simulate_downlink.js
Normal file
@@ -0,0 +1,38 @@
|
||||
import 'dotenv/config'
|
||||
import { createClient } from '@supabase/supabase-js'
|
||||
import { v4 as uuidv4 } from 'uuid'
|
||||
|
||||
const SUPABASE_URL = process.env.SUPABASE_URL
|
||||
const SUPABASE_SERVICE_ROLE_KEY = process.env.SUPABASE_SERVICE_ROLE_KEY
|
||||
if (!SUPABASE_URL || !SUPABASE_SERVICE_ROLE_KEY) throw new Error('Missing SUPABASE_* envs')
|
||||
|
||||
const supa = createClient(SUPABASE_URL, SUPABASE_SERVICE_ROLE_KEY, { auth: { autoRefreshToken: false, persistSession: false } })
|
||||
|
||||
const topic = process.env.SIM_DOWNLINK_TOPIC || 'device/demo-001/down'
|
||||
const payload = process.env.SIM_DOWNLINK_PAYLOAD || JSON.stringify({ cmd: 'beep', duration_ms: 500 })
|
||||
const payloadEncoding = process.env.SIM_DOWNLINK_ENCODING || 'json'
|
||||
const qos = parseInt(process.env.SIM_DOWNLINK_QOS || '1', 10)
|
||||
const retain = /^true$/i.test(process.env.SIM_DOWNLINK_RETAIN || 'false')
|
||||
|
||||
const row = {
|
||||
id: uuidv4(),
|
||||
topic,
|
||||
payload,
|
||||
payload_encoding: payloadEncoding,
|
||||
qos,
|
||||
retain,
|
||||
status: 'pending',
|
||||
scheduled_at: new Date().toISOString(),
|
||||
created_by: null
|
||||
}
|
||||
|
||||
async function main() {
|
||||
const { data, error } = await supa.from('mqtt_downlinks').insert(row).select('id, topic, payload_encoding, qos, retain, status').single()
|
||||
if (error) {
|
||||
console.error('insert error:', error)
|
||||
process.exit(1)
|
||||
}
|
||||
console.log('inserted:', data)
|
||||
}
|
||||
|
||||
main().catch((e) => { console.error(e); process.exit(1) })
|
||||
52
server/gateway-mqtt-node/scripts/simulate_webhook.js
Normal file
52
server/gateway-mqtt-node/scripts/simulate_webhook.js
Normal file
@@ -0,0 +1,52 @@
|
||||
import 'dotenv/config'
|
||||
import http from 'http'
|
||||
|
||||
const HTTP_PORT = parseInt(process.env.HTTP_PORT || '3000', 10)
|
||||
const WEBHOOK_TOKEN = process.env.WEBHOOK_TOKEN || ''
|
||||
|
||||
const conversationId = process.env.SIM_CONVERSATION_ID || '00000000-0000-0000-0000-000000000000'
|
||||
const senderId = process.env.SIM_SENDER_ID || '00000000-0000-0000-0000-000000000001'
|
||||
|
||||
const env = {
|
||||
id: process.env.SIM_MESSAGE_ID || undefined,
|
||||
ts: new Date().toISOString(),
|
||||
type: 'chat.message',
|
||||
source: 'webhook.sim',
|
||||
conversation_id: conversationId,
|
||||
sender_id: senderId,
|
||||
content: process.env.SIM_CONTENT || 'hello from webhook',
|
||||
content_type: 'text',
|
||||
metadata: { sim: true }
|
||||
}
|
||||
|
||||
const body = JSON.stringify({
|
||||
event: 'message.publish',
|
||||
topic: `chat/send/${conversationId}`,
|
||||
// emulate raw string payload
|
||||
payload: JSON.stringify(env)
|
||||
})
|
||||
|
||||
const options = {
|
||||
hostname: '127.0.0.1',
|
||||
port: HTTP_PORT,
|
||||
path: '/webhooks/mqtt',
|
||||
method: 'POST',
|
||||
headers: {
|
||||
'content-type': 'application/json',
|
||||
'content-length': Buffer.byteLength(body),
|
||||
...(WEBHOOK_TOKEN ? { 'x-webhook-token': WEBHOOK_TOKEN } : {})
|
||||
}
|
||||
}
|
||||
|
||||
const req = http.request(options, (res) => {
|
||||
let data = ''
|
||||
res.on('data', (chunk) => data += chunk)
|
||||
res.on('end', () => {
|
||||
console.log('status:', res.statusCode)
|
||||
console.log('body :', data)
|
||||
})
|
||||
})
|
||||
|
||||
req.on('error', (err) => console.error('request error:', err))
|
||||
req.write(body)
|
||||
req.end()
|
||||
Reference in New Issue
Block a user