150 lines
4.3 KiB
TypeScript
150 lines
4.3 KiB
TypeScript
import * as mqtt from 'mqtt'
|
|
|
|
let mqttClient: mqtt.MqttClient
|
|
function startServer(): Promise<mqtt.MqttClient> {
|
|
return new Promise(async resolve => {
|
|
mqttClient = await connectMqtt()
|
|
generateData(mqttClient)
|
|
resolve(mqttClient)
|
|
})
|
|
}
|
|
|
|
function connectMqtt(): Promise<mqtt.MqttClient> {
|
|
return new Promise(resolve => {
|
|
const client = mqtt.connect('mqtt://127.0.0.1:1883', {
|
|
username: 'thomas',
|
|
password: 'bierbier',
|
|
})
|
|
client.once('connect', () => {
|
|
resolve(client)
|
|
})
|
|
})
|
|
}
|
|
|
|
function temperature(base = 18, sineCoefficient = 2, offset = 0, speed = 1) {
|
|
const temp = base + Math.sin((Date.now() * speed) / 1000 / 5 + offset) * sineCoefficient + Math.random()
|
|
|
|
return String(Math.round(temp * 100) / 100)
|
|
}
|
|
|
|
export function stopUpdates() {
|
|
for (const interval of intervals) {
|
|
clearInterval(interval)
|
|
}
|
|
intervals = []
|
|
}
|
|
|
|
export function stop() {
|
|
stopUpdates()
|
|
try {
|
|
mqttClient && mqttClient.end()
|
|
} catch {
|
|
// ignore
|
|
}
|
|
}
|
|
|
|
let intervals: any = []
|
|
|
|
function generateData(client: mqtt.MqttClient) {
|
|
client.publish('livingroom/lamp/state', 'on', { retain: true, qos: 0 })
|
|
client.publish('livingroom/lamp/brightness', '128', { retain: true, qos: 0 })
|
|
client.publish('livingroom/thermostat/targetTemperature', '20°C', {
|
|
retain: true,
|
|
qos: 0,
|
|
})
|
|
intervals.push(setInterval(() => client.publish('livingroom/temperature', temperature()), 1000))
|
|
intervals.push(setInterval(() => client.publish('livingroom/humidity', temperature(60, -2, 0)), 1000))
|
|
|
|
client.publish('livingroom/lamp-1/state', 'on', { retain: true, qos: 0 })
|
|
client.publish('livingroom/lamp-1/brightness', '48', {
|
|
retain: true,
|
|
qos: 0,
|
|
})
|
|
client.publish('livingroom/lamp-2/state', 'off', { retain: true, qos: 0 })
|
|
client.publish('livingroom/lamp-2/brightness', '48', {
|
|
retain: true,
|
|
qos: 0,
|
|
})
|
|
|
|
client.publish('kitchen/lamp/state', 'off', { retain: true, qos: 0 })
|
|
client.subscribe('kitchen/lamp/set')
|
|
client.on('message', (topic, payload) => {
|
|
if (topic === 'kitchen/lamp/set') {
|
|
setTimeout(
|
|
() =>
|
|
client.publish('kitchen/lamp/state', payload, {
|
|
retain: true,
|
|
qos: 0,
|
|
}),
|
|
500
|
|
)
|
|
}
|
|
})
|
|
|
|
const coffeeMaker = {
|
|
heater: 'on',
|
|
temperature: 92.5,
|
|
waterLevel: 0.5,
|
|
update: new Date(),
|
|
}
|
|
intervals.push(
|
|
setInterval(() => {
|
|
const newTemp = parseFloat(temperature(90.3, -5, 0, 3))
|
|
coffeeMaker.heater = newTemp > coffeeMaker.temperature ? 'on' : 'off'
|
|
coffeeMaker.temperature = newTemp
|
|
client.publish('kitchen/coffee_maker', JSON.stringify(coffeeMaker), { retain: true, qos: 2 })
|
|
}, 1500)
|
|
)
|
|
|
|
intervals.push(setInterval(() => client.publish('kitchen/temperature', temperature()), 1500))
|
|
intervals.push(setInterval(() => client.publish('kitchen/humidity', temperature(60, -5, 0)), 1800))
|
|
|
|
client.publish('garden/pump/state', 'off', { retain: true, qos: 0 })
|
|
client.publish('garden/water/level', '70%', { retain: true, qos: 0 })
|
|
client.publish('garden/lamps/state', 'off', { retain: true, qos: 0 })
|
|
client.publish('garden/lamps/state', 'off', { retain: true, qos: 0 })
|
|
|
|
client.publish('zigbee2mqtt/bridge/state', 'online', {
|
|
retain: true,
|
|
qos: 0,
|
|
})
|
|
client.publish('ble2mqtt/bridge/state', 'online', { retain: true, qos: 0 })
|
|
|
|
// Used for demonstrating "clean up"
|
|
client.publish('test 123', 'Hello world', { retain: true, qos: 0 })
|
|
client.publish('hello', 'sunshine', { retain: true, qos: 0 })
|
|
|
|
// Just stuff
|
|
client.publish('01-80-C2-00-00-0F/LWT', 'offline', { retain: true, qos: 0 })
|
|
|
|
intervals.push(
|
|
setInterval(() => {
|
|
client.publish('3d-printer/OctoPrint/temperature/bed', '{"_timestamp":1548589083,"actual":25.9,"target":0}')
|
|
client.publish('3d-printer/OctoPrint/temperature/tool0', '{"_timestamp":1548589093,"actual":26.4,"target":0}')
|
|
}, 3333)
|
|
)
|
|
|
|
let state = true
|
|
intervals.push(
|
|
setInterval(() => {
|
|
state = !state
|
|
const js = {
|
|
tags: {
|
|
entityId: 33512,
|
|
entityType: 'person',
|
|
host: 'd44ad81e10f9',
|
|
server: 'http://localhost/dataActuality',
|
|
status: state ? 'live' : 'inactive',
|
|
},
|
|
timestamp: Date.now(),
|
|
}
|
|
client.publish('actuality/showcase', JSON.stringify(js), {
|
|
retain: true,
|
|
qos: 0,
|
|
})
|
|
}, 2102)
|
|
)
|
|
}
|
|
|
|
export default startServer
|