【记录】一个简单的定时任务调用mqtt接口

背景:客户要求。

留作记录。

const express = require('express');
const Vue = require('vue');
const app = express();
const port = 9090;
const fs = require('fs');
const configFile = "config.json";
const scheduleFile = Vue.ref();
const times = Vue.ref();
const heatingdevicelist = Vue.ref([]);
const mqtt = require('mqtt');

const getMQTTClient = (mydevice) => {
    
    const client = mqtt.connect(mydevice.serveraddress, {
        username: mydevice.account,
        password: mydevice.password
    });

    client.on('connect', () => {

        client.subscribe(mydevice.subtopic, (err) => {
            if (err) {
                console.error('Error subscribing to topic', err);
            } else {
                //console.log('Subscribed to topic');
            }
        });
    });

    client.on('message', (topic, message) => {

        const messageString = message.toString()

        const messageObject = JSON.parse(messageString)
        if (messageObject.rs4853h !== undefined) {
            for (let j = 0; j < mydevice.Time_strategy_data.length; j++) {
                const range = mydevice.Time_strategy_data[j].timeRange

                const [startStr, endStr] = range.split('-');
                const now = new Date();
                const start = new Date();
                const end = new Date();

                // 设置开始时间
                const [startHour, startMinute] = startStr.split(':');
                start.setHours(parseInt(startHour, 10));
                start.setMinutes(parseInt(startMinute, 10));

                // 设置结束时间
                const [endHour, endMinute] = endStr.split(':');
                end.setHours(parseInt(endHour, 10));
                end.setMinutes(parseInt(endMinute, 10));

                if (end < start) {
                    end.setDate(now.getDate() + 1);
                }

                // 检查当前时间是否在开始时间和结束时间之间
                if (now >= start && now <= end) {
                    const valvePositionModbus = generateDirectives(mydevice.Time_strategy_data[j].valvePosition);
                    const actValvePosition = modbusToValvePosition(messageObject.rs4853h)
                    console.log("actValvePosition           "+actValvePosition)
                    console.log("valvePosition            "+mydevice.Time_strategy_data[j].valvePosition)
                    if (Math.abs(mydevice.Time_strategy_data[j].valvePosition - actValvePosition) >= 1) {
                        const msg = {
                            rs4853h: valvePositionModbus
                        };
                        client.publish(mydevice.pubtopic, JSON.stringify(msg))
                    }

                }
            }
        }

    });

    // 处理错误
    client.on('error', (err) => {
        console.error('Error with MQTT client:', err);
    });

    return client;
}

const calculateCRC = (data) => {
    let crc = 0xffff // Initial CRC value

    for (let i = 0; i < data.length; i += 2) {
        const byte = parseInt(data.substr(i, 2), 16)
        crc ^= byte

        for (let j = 0; j < 8; j++) {
            if (crc & 0x0001) {
                crc = (crc >> 1) ^ 0xa001
            } else {
                crc >>= 1
            }
        }
    }

    // Swap bytes
    const crcHigh = (crc & 0xff00) >> 8
    const crcLow = crc & 0x00ff
    const crcSwapped = (crcLow << 8) | crcHigh

    return crcSwapped.toString(16).toUpperCase().padStart(4, '0')
}

const generateDirectives = (value) => {
    if (value < 0 || value > 100) {
        throw new Error('Value must be between 0 and 100')
    }

    const multipliedValue = value * 10
    const hexValue = `03060001${multipliedValue.toString(16).toUpperCase().padStart(4, '0')}`
    const crcChecksum = calculateCRC(hexValue)
    const directives = `${hexValue}${crcChecksum}`

    // return `拼接后的HEX字符串: ${hexValue}, CRC校验码: ${crcChecksum},最终指令:${directives}`;
    return directives
}


const modbusToValvePosition = (modbusData) => {
    // Extract the 7th to 10th characters (4 characters) which represent the valve position in hex
    const fourthChar = modbusData.charAt(3)
    let hexString
    if (fourthChar === '6') {
        hexString = modbusData.slice(8, 12)
    } else {
        hexString = modbusData.slice(6, 10)
    }

    // Convert the hex string to a decimal number
    const decimalValue = parseInt(hexString, 16) / 10

    return decimalValue
}

const initialize = async () => {
    const data = fs.readFileSync(configFile, "utf-8");
    const mydata = JSON.parse(data);
    scheduleFile.value = mydata.filePath

    getSchedule();
}

const getSchedule = () => {
    fs.readFile(scheduleFile.value, 'utf8', (err, data) => {
        if (err) {
            console.error("设备配置文件路径错误。"+err);
            heatingdevicelist.value = [];
            return;
        }else{
            heatingdevicelist.value = JSON.parse(data).devices;
        }

    });
}

// 定义一个定时任务函数
function myScheduleTask() {
    for (let i = 0; i < heatingdevicelist.value.length; i++) {
        const device = heatingdevicelist.value[i];

        const client = getMQTTClient(device);

        const msg = {
            rs4853h: device.refresh_command
        };
        // console.log(JSON.stringify(msg))
        client.publish(device.pubtopic, JSON.stringify(msg))
    }
    // process.exit(0);  // 优雅地关闭应用
}

setInterval(myScheduleTask, 6000);

app.get('/reload', (req, res) => {
    res.send('重新加载配置文件。');
    initialize()
});

app.get('/', (req, res) => {
    res.send('定时任务正在运行...');
});

initialize();

app.listen(port, () => {
    console.log("程序运行中,请勿关闭窗口...")
});

  • 1
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值