<commit_before>'use strict';

const tools = require('../tools.js');
const dgram = require('dgram');

function listen(ip, cb) {
    let timer = null;
    let socket;
    try {
        socket = dgram.createSocket('udp4');

        socket.on('message', msgBuffer => {
            let msg;
            try {
                msg = JSON.parse(msgBuffer.toString());
            }
            catch (e) {
                return;
            }
            options.log.debug(msg);

            if (msg.model === 'gateway') {
                options.log.debug("mihome: " + ip);
                options.log.debug("mihome: " + JSON.stringify(msg));
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                }
                try {
                    socket.close();
                } catch (e) {

                }

                if (cb) {
                    cb(null, ip);
                    cb = null;
                }
            }
        });

        socket.on('error', err => {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            try {
                socket.close();
            } catch (e) {

            }

            if (cb) {
                cb(err);
                cb = null;
            }
        });

        socket.on('listening', () => {
            const whoIsCommand = '{"cmd": "whois"}';
            socket.send(whoIsCommand, 0, whoIsCommand.length, 4321, ip);
        });
        socket.bind(19898);
    } catch (e) {
        if (cb) {
            cb(e);
            cb = null;
            return;
        }
    }

    timer = setTimeout(() => {
        socket && socket.close();
        timer = null;
        if (cb) {
            cb();
            cb = null;
        }
    }, 500);
}

function addInstance(ip, device, options, callback) {
    options.log.debug("mihome: found one");
    let instance = tools.findInstance(options, 'mihome');

    if (!instance) {
        const id = tools.getNextInstanceID('mihome', options);
        instance = {
            _id: id,
            common: {
                name: 'mihome'
            },
            native: {
                bind: tools.getOwnAddress(ip)
            },
            comment: {
                add: 'Xiaomi Mi Home - ' + ip,
                inputs: [
                    {
                        name: 'native.key',
                        def: '',
                        type: 'text', // text, checkbox, number, select, password. Select requires
                        title: 'Key' // see translation in words.js
                    },
                    {
                        def: 'https://github.com/ioBroker/ioBroker.mihome#requirements',
                        type: 'link',
                        title: tools.translate(options.language, 'See description of key here ') // see translation in words.js
                    }
                ]
            }
        };
        options.newInstances.push(instance);
        return callback(true);
    }
    callback(false);
}

function detect(ip, device, options, callback) {

    function cb(err, is, ip) {
        if (callback) {
            callback(err, is, ip);
            callback = null;
        }
    }

    if (device._type === 'ip') {
        listen(ip, (err, ipAddr) => {
			if (!err && ipAddr) {
                options.log.debug("mihome: found one");
                addInstance (ipAddr, device, options, isAdded => cb(null, isAdded, ip));
			} else {
                err && options.log.warn('Mihome err: ' + err);
                cb (null, false, ip);
            }
        });
    } else {
        cb(null, false, ip);
    }
}

exports.detect = detect;
exports.type = ['udp']; // TODO check if udp
<commit_msg>fix mihome<commit_after>'use strict';

const tools = require('../tools.js');
const dgram = require('dgram');

function listen(ip, cb) {
    tools.udpScan(ip, 4321, "0.0.0.0", 19898, '{"cmd": "whois"}', 1500, (err, msg) => {
        options.log.debug(msg);
        msg = JSON.parse(msg);

        if (msg.model === 'gateway') {
            options.log.debug("mihome: " + ip);
            options.log.debug("mihome: " + JSON.stringify(msg));
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            try {
                socket.close();
            } catch (e) {

            }

            if (cb) {
                cb(null, ip);
                cb = null;
            }
        }
    });





    return;

    let timer = null;
    let socket;
    try {
        socket = dgram.createSocket('udp4');

        socket.on('message', msgBuffer => {
            let msg;
            try {
                msg = JSON.parse(msgBuffer.toString());
            }
            catch (e) {
                return;
            }
            options.log.debug(msg);

            if (msg.model === 'gateway') {
                options.log.debug("mihome: " + ip);
                options.log.debug("mihome: " + JSON.stringify(msg));
                if (timer) {
                    clearTimeout(timer);
                    timer = null;
                }
                try {
                    socket.close();
                } catch (e) {

                }

                if (cb) {
                    cb(null, ip);
                    cb = null;
                }
            }
        });

        socket.on('error', err => {
            if (timer) {
                clearTimeout(timer);
                timer = null;
            }
            try {
                socket.close();
            } catch (e) {

            }

            if (cb) {
                cb(err);
                cb = null;
            }
        });

        socket.on('listening', () => {
            const whoIsCommand = '{"cmd": "whois"}';
            socket.send(whoIsCommand, 0, whoIsCommand.length, 4321, ip);
        });
        socket.bind(19898);
    } catch (e) {
        if (cb) {
            cb(e);
            cb = null;
            return;
        }
    }

    timer = setTimeout(() => {
        socket && socket.close();
        timer = null;
        if (cb) {
            cb();
            cb = null;
        }
    }, 500);
}

function addInstance(ip, device, options, callback) {
    options.log.debug("mihome: found one");
    let instance = tools.findInstance(options, 'mihome');

    if (!instance) {
        const id = tools.getNextInstanceID('mihome', options);
        instance = {
            _id: id,
            common: {
                name: 'mihome'
            },
            native: {
                bind: tools.getOwnAddress(ip)
            },
            comment: {
                add: 'Xiaomi Mi Home - ' + ip,
                inputs: [
                    {
                        name: 'native.key',
                        def: '',
                        type: 'text', // text, checkbox, number, select, password. Select requires
                        title: 'Key' // see translation in words.js
                    },
                    {
                        def: 'https://github.com/ioBroker/ioBroker.mihome#requirements',
                        type: 'link',
                        title: tools.translate(options.language, 'See description of key here ') // see translation in words.js
                    }
                ]
            }
        };
        options.newInstances.push(instance);
        return callback(true);
    }
    callback(false);
}

function detect(ip, device, options, callback) {

    function cb(err, is, ip) {
        if (callback) {
            callback(err, is, ip);
            callback = null;
        }
    }

    if (device._type === 'ip') {
        listen(ip, (err, ipAddr) => {
			if (!err && ipAddr) {
                options.log.debug("mihome: found one");
                addInstance (ipAddr, device, options, isAdded => cb(null, isAdded, ip));
			} else {
                err && options.log.warn('Mihome err: ' + err);
                cb (null, false, ip);
            }
        });
    } else {
        cb(null, false, ip);
    }
}

exports.detect = detect;
exports.type = ['udp']; // TODO check if udp

{'fraction_non_alphanumeric': 0.13309002433090025, 'fraction_numerical': 0.005474452554744526, 'mean_word_length': 1.0775840283042708, 'pattern_counts': {'":': 3, '<': 3, '<?xml version=': 0, '>': 16, 'https://': 2, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 1, 'substrings_counts': 0, 'word_list_counts': {'cursed_substrings.json': 0, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '4402738', 'n_tokens_mistral': 2345, 'n_tokens_neox': 2203, 'n_words': 490}