<commit_before>var util = require('util');
var EventEmitter = require('events').EventEmitter;

function GenieMini(id) {
    this.btServiceIds = ['f000474d04514000b000000000000000'];

    this._id = id;
    this._gmCh = null;
    this._dev = null;
    this._moving = false;
    this._angle = null;
    this._position = 0;
    this._currentMove = null;
    this._stepsPerDegree = 186.56716418;

    this.orientation = null;
}

util.inherits(GenieMini, EventEmitter);

GenieMini.prototype._connectBt = function(btPeripheral, callback) {
    var self = this;
    btPeripheral.connect(function(err1) {
        if (err1) {
            if (callback) callback(false);
            return;
        }
        console.log('GenieMini(' + self._id + '): connecting via BLE');
        setTimeout(function(){
            btPeripheral.discoverServices(self.btServiceIds, function(err2, services) {
                if (services && services[0]) {
                    services[0].discoverCharacteristics([], function(err, characteristics) {
                        //console.log("characteristics:", characteristics);
                        self._gmCh = null;
                        self._dev = null;
                        for (var i = 0; i < characteristics.length; i++) {
                            ch = characteristics[i];
                            console.log("ch.uuid", ch.uuid);
                            if (ch.uuid == "2") {
                                self._gmCh = ch;
                            }
                        }
                        if (self._gmCh) {
                            try {
                                self._gmCh.write(new Buffer("012600", 'hex'));
                                self._gmCh.subscribe(function(){
                                    self._dev = btPeripheral;
                                    self._dev.connected = true;
                                    self.connected = true;
                                    self._dev.type = "bt";
                                    self._gmCh.on('data', function(data, isNotification) {
                                        self._parseIncoming(data);
                                    });
                                    console.log("GenieMini(" + self._id + "): connected!");
                                    self._init();
                                    if (callback) callback(true);
                                });
                            } catch(err3) {
                                btPeripheral.disconnect();
                                console.log("GenieMini(" + self._id + "): exception while connecting: ", err3);
                                if (callback) callback(false);
                            }
                        } else {
                            console.log("GenieMini(" + self._id + "): couldn't locate characteristics, disconnecting... ", err);
                            btPeripheral.disconnect();
                            if (callback) callback(false);
                        }
                    });
                } else {
                    console.log("GenieMini(" + self._id + "): couldn't locate services, disconnecting... ", err2);
                    btPeripheral.disconnect();
                    if (callback) callback(false);
                }

            });
        }, 1000);

        btPeripheral.once('disconnect', function() {
            console.log("GenieMini(" + self._id + "): disconnected");
            self._dev = null;
            self.connected = false;
            self.emit("status", self.getStatus());
        });

    });
}

GenieMini.prototype._init = function() {
    var self = this;
    var dataBuf = new Buffer(4);
    dataBuf.fill(0);
    dataBuf.writeInt32LE(0x000B, 0);
    this._write(0x001E, dataBuf, function(err) { // checks orientation
        var tries = 0;
        var waitForOrientation = function() {
            tries++;
            if(self.orientation || tries > 5) {
                self.emit("status", self.getStatus());
            } else {
                setTimeout(waitForOrientation, 500);
            }
        }
        waitForOrientation();
    });
}

GenieMini.prototype._parseIncoming = function(data) {
    var id = data.readUInt16LE(1);
    if(id == 0x0060 || id == 0x0061) { // moving steps
        var state = data.readUInt8(7);
        var steps = data.readInt16LE(3);
        this._moving = (state == 0x01);
        console.log("GenieMini(" + this._id + "): moving: ", this._moving, ", steps:", steps);
    } else if(id == 0x000B || id == 0x0052) { // current state
        var state = data.readUInt8(4);
        var angle = data.readUInt16LE(12);
        this._angle = angle;
        this._moving = (state == 0x01);
        console.log("GenieMini(" + this._id + "): moving: ", this._moving, ", angle:", angle);
        if(this._currentMove != null && this._lastAngle != null) {
            if(Math.abs(angle - this._lastAngle) < 180) {
                this._currentMove += angle - this._lastAngle;
            } else {
                if(this._lastAngle < angle) {
                    this._currentMove += 359 - (angle - this._lastAngle);
                } else {
                    this._currentMove -= 359 - (this._lastAngle - angle);
                }
            }
            console.log("GenieMini(" + this._id + "): _currentMove", this._currentMove);
        }
        this._lastAngle = angle;
    } else if(id == 0x0025) { // current state
        var orientation = data.readUInt8(3);
        if(orientation == 0x94) this.orientation = 'pan';
        if(orientation == 0x90) this.orientation = 'tilt';
        console.log("GenieMini(" + this._id + "): orientation:", this.orientation);
    } else {
        console.log("GenieMini(" + this._id + "): unknown id", id, "data", data);
    }
}

GenieMini.prototype.connect = function(device, callback) {
    if (device && device.connect) {
        this._moving = false;
        console.log("GenieMini(" + this._id + "): connecting...");
        this._connectBt(device, callback);
    } else {
        console.log("GenieMini(" + this._id + "): invalid device, cannot connect");
        if (callback) callback("invalid device");
    }
}

GenieMini.prototype.disconnect = function() {
    console.log("GenieMini(" + this._id + "): disconnecting...");
    if (this._dev && this._dev.connected) {
        this.connected = false;
        this._dev.connected = false;
        this._dev.disconnect();
    } else {
        this._dev = null;
    }<commit_msg>genie mini auto-detect orientation testing<commit_after>var util = require('util');
var EventEmitter = require('events').EventEmitter;

function GenieMini(id) {
    this.btServiceIds = ['f000474d04514000b000000000000000'];

    this._id = id;
    this._gmCh = null;
    this._dev = null;
    this._moving = false;
    this._angle = null;
    this._position = 0;
    this._currentMove = null;
    this._stepsPerDegree = 186.56716418;

    this.orientation = null;
}

util.inherits(GenieMini, EventEmitter);

GenieMini.prototype._connectBt = function(btPeripheral, callback) {
    var self = this;
    btPeripheral.connect(function(err1) {
        if (err1) {
            if (callback) callback(false);
            return;
        }
        console.log('GenieMini(' + self._id + '): connecting via BLE');
        setTimeout(function(){
            btPeripheral.discoverServices(self.btServiceIds, function(err2, services) {
                if (services && services[0]) {
                    services[0].discoverCharacteristics([], function(err, characteristics) {
                        //console.log("characteristics:", characteristics);
                        self._gmCh = null;
                        self._dev = null;
                        for (var i = 0; i < characteristics.length; i++) {
                            ch = characteristics[i];
                            console.log("ch.uuid", ch.uuid);
                            if (ch.uuid == "2") {
                                self._gmCh = ch;
                            }
                        }
                        if (self._gmCh) {
                            try {
                                self._gmCh.write(new Buffer("012600", 'hex'));
                                self._gmCh.subscribe(function(){
                                    self._dev = btPeripheral;
                                    self._dev.connected = true;
                                    self.connected = true;
                                    self._dev.type = "bt";
                                    self._gmCh.on('data', function(data, isNotification) {
                                        self._parseIncoming(data);
                                    });
                                    console.log("GenieMini(" + self._id + "): connected!");
                                    self._init();
                                    if (callback) callback(true);
                                });
                            } catch(err3) {
                                btPeripheral.disconnect();
                                console.log("GenieMini(" + self._id + "): exception while connecting: ", err3);
                                if (callback) callback(false);
                            }
                        } else {
                            console.log("GenieMini(" + self._id + "): couldn't locate characteristics, disconnecting... ", err);
                            btPeripheral.disconnect();
                            if (callback) callback(false);
                        }
                    });
                } else {
                    console.log("GenieMini(" + self._id + "): couldn't locate services, disconnecting... ", err2);
                    btPeripheral.disconnect();
                    if (callback) callback(false);
                }

            });
        }, 1000);

        btPeripheral.once('disconnect', function() {
            console.log("GenieMini(" + self._id + "): disconnected");
            self._dev = null;
            self.connected = false;
            self.emit("status", self.getStatus());
        });

    });
}

GenieMini.prototype._init = function() {
    var self = this;
    var dataBuf = new Buffer(4);
    dataBuf.fill(0);
    dataBuf.writeInt32LE(0x000B, 0);
    this._write(0x001E, dataBuf, function(err) { // checks orientation
        var tries = 0;
        var waitForOrientation = function() {
            tries++;
            if(self.orientation || tries > 5) {
                self.emit("status", self.getStatus());
            } else {
                setTimeout(waitForOrientation, 500);
            }
        }
        waitForOrientation();
    });
}

GenieMini.prototype._parseIncoming = function(data) {
    var id = data.readUInt16LE(1);
    if(id == 0x0060 || id == 0x0061) { // moving steps
        var state = data.readUInt8(7);
        var steps = data.readInt16LE(3);
        this._moving = (state == 0x01);
        console.log("GenieMini(" + this._id + "): moving: ", this._moving, ", steps:", steps, "id:", id);
    } else if(id == 0x000B || id == 0x0052) { // current state
        var state = data.readUInt8(4);
        var angle = data.readUInt16LE(12);
        this._angle = angle;
        this._moving = (state == 0x01);
        console.log("GenieMini(" + this._id + "): moving: ", this._moving, ", angle:", angle, "id:", id);
        if(this._currentMove != null && this._lastAngle != null) {
            if(Math.abs(angle - this._lastAngle) < 180) {
                this._currentMove += angle - this._lastAngle;
            } else {
                if(this._lastAngle < angle) {
                    this._currentMove += 359 - (angle - this._lastAngle);
                } else {
                    this._currentMove -= 359 - (this._lastAngle - angle);
                }
            }
            console.log("GenieMini(" + this._id + "): _currentMove", this._currentMove);
        }
        this._lastAngle = angle;
    //} else if(id == 0x0025) { // current state
    //    var orientation = data.readUInt8(3);
    //    if(orientation == 0x94) this.orientation = 'pan';
    //    if(orientation == 0x90) this.orientation = 'tilt';
    //    console.log("GenieMini(" + this._id + "): orientation:", this.orientation);
    } else {
        console.log("GenieMini(" + this._id + "): unknown id", id, "data", data);
    }
}

GenieMini.prototype.connect = function(device, callback) {
    if (device && device.connect) {
        this._moving = false;
        console.log("GenieMini(" + this._id + "): connecting...");
        this._connectBt(device, callback);
    } else {
        console.log("GenieMini(" + this._id + "): invalid device, cannot connect");
        if (callback) callback("invalid device");
    }
}

GenieMini.prototype.disconnect = function() {
    console.log("GenieMini(" + this._id + "): disconnecting...");
    if (this._dev && this._dev.connected) {
        this.connected = false;
        this._dev.connected = false;
        this._dev.disconnect();
    } else {
        this._dev = null;
    }
{'fraction_non_alphanumeric': 0.13237421024587046, 'fraction_numerical': 0.021313846388064245, 'mean_word_length': 1.4483786805814387, 'pattern_counts': {'":': 0, '<': 9, '<?xml version=': 0, '>': 5, 'https://': 0, 'lorem ipsum': 0, 'www.': 0, 'xml': 0}, 'pii_count': 0, 'substrings_counts': 2, 'word_list_counts': {'cursed_substrings.json': 22, 'profanity_word_list.json': 0, 'sexual_word_list.json': 0, 'zh_pornsignals.json': 0}}
{'dir': 'git-commits-cleaned', 'id': '898022', 'n_tokens_mistral': 3783, 'n_tokens_neox': 3449, 'n_words': 674}