示例#1
0
def scan(*, interface=0, delegate=None, timeout=10, passive=False):
    """Scan for Bluetooth devices.

    This function can only be called if the `bluepy` package is installed.

    Parameters
    ----------
    interface : :class:`int`, optional
        The Bluetooth interface to use (where 0 is /dev/hci0).
    delegate : :ref:`DefaultDelegate <delegate>`, optional
        Receives a callback when broadcasts from devices are received.
    timeout : :class:`float`, optional
        Scan for devices for the given timeout in seconds. During this period,
        callbacks to the `delegate` object will be called.
    passive : :class:`bool`, optional
        Use active (to obtain more information when connecting) or passive scanning.

    Returns
    -------
    A `view` of :ref:`ScanEntry <scanentry>` objects.
    """
    from bluepy.btle import Scanner
    scanner = Scanner(interface)
    if delegate:
        scanner.withDelegate(delegate)
    return scanner.scan(timeout=timeout, passive=passive)
示例#2
0
 def run(self) -> None:
     scanner = Scanner()
     handler = BluetoothProximityHandler(self.flick_light_switch, self._threshold_rssi)
     scanner.withDelegate(handler)
     continue_loop = True
     while continue_loop:
         sleep(1)
         scanner.scan(60, passive=True)
示例#3
0
def main():
    print ("Running Server!")
    sys.stdout = MyLogger(logger, logging.INFO)
    sys.stderr = MyLogger(logger, logging.ERROR)

    sc = Scanner()
    scd = MiBand2ScanDelegate(sc)
    sc.withDelegate(scd)

    scan_thread = threading.Thread(target=scan_miband2, args=(sc,scd,))
    scan_thread.start()

    for i in range(max_connections):
         t = threading.Thread(target=worker)
         t.daemon = True
         t.start()

    old_stats_registered = 0
    old_stats_visible = 0
    old_stats_outcd = 0
    old_stats_incd = 0

    while True:
        out_of_cd = []
        for mb in scd.mibands.keys():
            if mb in devices_last_sync.keys():
                m = re.search("(\d+)-(\d+)-(\d+)\s+(\d+):(\d+)", devices_last_sync[mb])
                if m.groups() != None:
                    date = list(map(lambda x: int(x), m.groups()))
                    ls = MiBand2Time(None, date[0], date[1], date[2], date[3], date[4])
                    if ls.minutesUntilNow() >= activity_fetch_cooldown:
                        out_of_cd += [mb]
            else:
                out_of_cd += [mb]

        stats_registered = len(registered_devices)
        stats_visible = len(scd.visible_devices)
        stats_outcd = len(out_of_cd)
        stats_incd = len(scd.mibands.keys())-len(out_of_cd)

        if (stats_registered != old_stats_registered or stats_visible != old_stats_visible or stats_outcd != old_stats_outcd or stats_incd != old_stats_incd):
            print("Registered: {0} // Visible: {1} // Out of cooldown: {2} // In Cooldown: {3}".format(
                len(registered_devices), len(scd.visible_devices),
                len(out_of_cd), len(scd.mibands.keys())-len(out_of_cd)))

        for item in out_of_cd:
            q.put(item)

        q.join()
        if len(out_of_cd) > 0:
            save_sync(devices_last_sync)

        old_stats_registered = stats_registered
        old_stats_visible = stats_visible
        old_stats_outcd = stats_outcd
        old_stats_incd = stats_incd
示例#4
0
    def scan(timeout=5):
        scanner = Scanner()
        scanner.withDelegate(ScanAPI.ScanDelegate())
        devices = scanner.scan(timeout)

        for dev in devices:
            print(
                "Device {} RSSI={} db, addrType={}, iface={}, connectable={}".
                format(dev.addr, dev.rssi, dev.addrType, dev.iface,
                       dev.connectable))
示例#5
0
    def scan(timeout=5):
        scanner = Scanner()
        scanner.withDelegate(ScanAPI.ScanDelegate())
        devices = scanner.scan(timeout)

        for dev in devices:
            print("Device {} ({}) ({}), RSSI={} db ".format(
                dev.addr, dev.addrType, dev.iface, dev.rssi))
            for (adtype, desc, value) in dev.getScanData():
                print(" {} = {}".format(desc, value))
示例#6
0
def main():
    scanthresh = -75
    sc = Scanner()
    scd = MiBand2ScanDelegate(scanthresh)
    sc.withDelegate(scd)

    mibands = []

    scan_thread = threading.Thread(target=scan_miband2, args=(sc,scanthresh))
    scan_thread.start()

    while True:
        os.system('clear')
        mibands = copy.deepcopy(scd.tmp_devices)
        print "Mi Band 2 Scanner"
        print "Near Mi Bands 2: \t{0}".format(len(mibands))
        print "------------------------------"
        for idx, mb in enumerate(mibands.values()):
            print "[{0}] {1}-{2} <{3}> ({4}dB) REP: {5}".format(idx, mb["device"].getValueText(9),
                mb["device"].getValueText(2), mb["device"].addr, mb["device"].rssi, mb["reputation"])
        time.sleep(2)

    scan_thread.do_start = False
示例#7
0
@app.route('/config/<endpoint>/', methods=["GET", "PUT"])
def server_config_detail(endpoint):
    if env.has_option('SERVER', endpoint):
        if request.method == "PUT":
            newval = request.form.get('config_value')
            env.set('SERVER', endpoint, str(newval))
        return json.dumps({endpoint: env.get('SERVER', endpoint)})
    else:
        abort(404)


devices_keys = read_json(base_route + '/localdata/devices_keys.json')

sc = Scanner()
scd = MiBandScanDelegate(rssithreshold)
sc.withDelegate(scd)

scan_thread = threading.Thread(target=scan_miband2, args=(
    sc,
    rssithreshold,
))
scan_thread.start()

#ping_thread = threading.Thread(target=ping_connected, args=(pingtimer,))
#ping_thread.start()

for i in range(max_connections):
    t = threading.Thread(target=worker)
    t.daemon = True
    t.start()
示例#8
0
        "addr": "dc:00:62:95:62:67",
        "type": "ambient"
    }
}

INFLUX_SERVER = os.environ.get("INFLUX_SERVER", None) or "raspberrypi.local"
INFLUX_DATABASE = os.environ.get("INFLUX_DB", None) or "sensors"
INFLUX_USER = os.environ.get("INFLUX_USER", None) or "root"
INFLUX_PASSWORD = os.environ.get("INFLUX_PASSWORD", None) or "root"

if __name__ == "__main__":
    print "Creating Scanner"
    delegate = DeviceForwardingDelegate()
    delegate.handlers.append(IGrillHandler(device_settings))
    delegate.handlers.append(TokenCubeHandler(device_settings))

    scanner = Scanner()
    scanner.withDelegate(delegate)

    print "Connecting to InfluxDB server"
    persistence = DataPersistence(INFLUX_SERVER, INFLUX_DATABASE, INFLUX_USER,
                                  INFLUX_PASSWORD)

    while True:
        print "Scanning..."
        scanner.scan(30)

        print "Persisting..."
        for handler in delegate.handlers:
            handler.persist_stats(persistence)
示例#9
0
class MiBandCMD(cmd.Cmd):
    """Command Processor for intercating with many MiBands at a time"""
    def __init__(self):
        cmd.Cmd.__init__(self)
        threshold = -70
        strikes = 5
        pingtimer = 1
        self.sc = Scanner()
        self.scd = MiBandScanDelegate(threshold)
        self.sc.withDelegate(self.scd)

        self.mibands = []

        self.scan_thread = threading.Thread(target=scan_miband2, args=(self.sc,strikes,threshold))
        self.scan_thread.start()

        #self.ping_thread = threading.Thread(target=ping_connected, args=(pingtimer,))
        #self.ping_thread.start()

        for i in range(max_connections):
             t = threading.Thread(target=worker, args=(self,))
             t.daemon = True
             t.start()

        self.prompt =  'MBS => '

    def exit_safely(self):
        self.scan_thread.do_scan = False
        #self.ping_thread.do_ping = False
        self.scan_thread.join()
        print ("Disconnecting from %s devices" % len(connected_devices.values()))
        for con in connected_devices.values():
            con.disconnect()
        return True

    def do_devices(self, line):
        tmp_mibands = copy.deepcopy(self.scd.tmp_devices)
        self.mibands = {k: v["device"] for k, v in tmp_mibands.items()}
        self.models = {k: v["model"] for k, v in tmp_mibands.items()}
        tmp_strikes = {k: v["strikes"] for k, v in tmp_mibands.items()}
        for idx,mb in enumerate(self.mibands.keys()):
            name = "Someone"
            uid = 0
            udata = None
            if args.mode == "db":
                devid = mbdb.get_device_id(cnxn_string, mb.upper())
                devuser = mbdb.get_device_user(cnxn_string, devid)
                if devuser != -1:
                    udata = mbdb.get_user_data(cnxn_string,devuser)
                else:
                    udata = None
            else:
                # TODO: User Data on local storage???
                pass
            if udata:
                name = udata["alias"]
                uid = udata["id"]
            model = self.models[self.mibands.keys()[idx]].upper()
            str = "[%s]%10s's %s <U:%05d> (%s) %sdB S:%s " % (idx, name, model, uid, mb, self.mibands[self.mibands.keys()[idx]].rssi, "X"*tmp_strikes[self.mibands.keys()[idx]])
            if (args.mode == "db" and mbdb.is_device_registered(cnxn_string, mb)) or (args.mode == "json" and mb in self.registered_devices):
                str += "[R]"
            if mb in connected_devices:
                mb_dev = connected_devices[mb]
                if args.mode == "db":
                    mbdb.update_battery(cnxn_string, mb_dev.addr, mb_dev.battery_info['level'])
                str += "[C] [B:{0:03d}%]".format(mb.battery_info["level"])
            print str

    def do_reboot(self, params):
        try:
           dev_id = int(params)
        except ValueError:
           print "*** arguments should be numbers"
           return
        except IndexError:
           print "*** alert takes at least one parameter"
           return
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or (args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices)):
            if self.mibands.keys()[dev_id] in connected_devices.keys():
                try:
                    mb = connected_devices[self.mibands.keys()[dev_id]]
                    mb.reboot()
                except BTLEException:
                    print("There was a problem rebooting this MiBand, try again later")
            else:
                print("That MiBand is not connected!")
        else:
            print("That MiBand is not registered")

    def do_alert(self, params):
        l = params.split()
        if len(l)!=2:
           print "*** invalid number of arguments"
           return
        try:
           l = [int(i) for i in l]
        except ValueError:
           print "*** arguments should be numbers"
           return
        except IndexError:
           print "*** alert takes at least one parameter"
           return
        dev_id = int(l[0])
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        alert_int = int(l[1])
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
            if self.mibands.keys()[dev_id] in connected_devices.keys():
                try:
                    mb = connected_devices[self.mibands.keys()[dev_id]]
                    data = struct.pack('B', alert_int)
                    mb.send_alert(data)
                    print "Sending Notification: " + binascii.hexlify(data)
                except BTLEException:
                    print("There was a problem alerting this MiBand, try again later")
            else:
                print("That MiBand is not connected!")
        else:
            print("That MiBand is not registered")

    def do_configure(self, params):
        l = params.split()
        try:
           dev_id = int(l[0])
           command = ""
           if len(l) > 1:
               command = l[1]
        except ValueError:
           print "*** argument 1 should be number"
           return
        except IndexError:
           print "*** configure takes at least one parameter"
           return
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if command == "":
            print("Using default configuration preset [%s]" % CONFIG_MODE)
            command = CONFIG_MODE
        if not config.has_section(command):
           print "*** invalid configuration preset '%s'" % command
           return
        self.configure_miband(dev_id, command)

    def configure_miband(self, dev_id, preset):
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
            if self.mibands.keys()[dev_id] in connected_devices.keys():
                try:
                    mb = connected_devices[self.mibands.keys()[dev_id]]
                    print("Configuring MiBand to [%s] presets" % preset)
                    if config.has_option(preset, "MonitorHRSleep"):
                        mb.monitorHeartRateSleep(config.getint(preset, "MonitorHRSleep"))
                    if config.has_option(preset, "MonitorHRInterval"):
                        mb.setMonitorHeartRateInterval(config.getint(preset, "MonitorHRInterval"))
                    if config.has_option(preset, "DisplayTimeFormat"):
                        mb.setDisplayTimeFormat(config.get(preset, "DisplayTimeFormat"))
                    if config.has_option(preset, "DisplayTimeHours"):
                        mb.setDisplayTimeHours(config.getint(preset, "DisplayTimeHours"))
                    if config.has_option(preset, "DistanceUnit"):
                        mb.setDistanceUnit(config.get(preset, "DistanceUnit"))
                    if config.has_option(preset, "LiftWristActivate"):
                        mb.setLiftWristToActivate(config.getint(preset, "LiftWristActivate"))
                    if config.has_option(preset, "RotateWristSwitch"):
                        mb.setRotateWristToSwitchInfo(config.getint(preset, "RotateWristSwitch"))
                    if config.has_option(preset, "DisplayItems"):
                        disp = [x.strip() for x in config.get(preset, 'DisplayItems').split(',')]
                        steps = True if 'steps' in disp else False
                        distance = True if 'distance' in disp else False
                        calories = True if 'calories' in disp else False
                        heartrate = True if 'heartrate' in disp else False
                        battery = True if 'battery' in disp else False
                        mb.setDisplayItems(steps=steps, distance=distance, calories=calories, heartrate=heartrate, battery=battery)
                    if config.has_option(preset, "DoNotDisturb"):
                        enableLift = config.getint(preset, "DoNotDisturbLift") if config.has_option(preset, "DoNotDisturbLift") else 1
                        mb.setDoNotDisturb(config.get(preset, "DoNotDisturb"), enableLift=enableLift)
                    if config.has_option(preset, "InactivityWarnings"):
                        start = config.getint(preset, "InactivityWarningsStart") if config.has_option(preset, "InactivityWarningsStart") else 8
                        end = config.getint(preset, "InactivityWarningsEnd") if config.has_option(preset, "InactivityWarningsEnd") else 19
                        threshold = config.getint(preset, "InactivityWarningsThresholdHours") if config.has_option(preset, "InactivityWarningsThresholdHours") else 1
                        mb.setInactivityWarnings(config.getint(preset, "InactivityWarnings"), threshold=threshold*60, start=(start, 0), end=(end, 0))
                    if config.has_option(preset, "DisplayCaller"):
                        mb.setDisplayCaller(config.getint(preset, "DisplayCaller"))

                except BTLEException as e:
                    print("There was a problem configuring this MiBand, try again later")
                    print e
            else:
                print("That MiBand is not connected, please connect it before configuring.")
        else:
            print("That MiBand is not registered, please register it before configuring.")

    def do_setuser(self, params):
        try:
           l = params.split()
           dev_id = int(l[0])
           if args.mode == "db":
               user_id = int(l[1])
           else:
               # TODO: Not persisted
               user_alias = l[1]
               if l[2] == "M":
                   user_gender = 0
               elif l[2] == "F":
                   user_gender = 1
               else:
                   user_gender = 2
               user_bd_year = int(l[3])
               user_bd_month = int(l[4])
               user_bd_day = 0
               user_weight = float(l[5])
               user_height = int(l[6])
           position = None
           if l[2] == "left":
               position = (0, "left")
           elif l[2] == "right":
               position = (1, "right")
           else:
               print("*** only left and right supported")
               return
        except ValueError:
           print "*** argument should be number"
           return
        except IndexError:
           print "*** setuser takes at least one parameter"
           return
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if args.mode == "db":
            udata = mbdb.get_user_data(cnxn_string, user_id)
        if udata or args.mode == "json":
            if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
                or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
                if self.mibands.keys()[dev_id] in connected_devices.keys():
                    mb = connected_devices[self.mibands.keys()[dev_id]]
                    if args.mode == "db":
                        if mbdb.set_device_user(cnxn_string, mb.addr, user_id, position[0]):
                            mb.setUserInfo(udata["alias"], udata["sex"], udata["height"], udata["weight"], udata["birth"])
                    else:
                        mb.setUserInfo(user_alias, user_gender, user_height, user_weight, (user_bd_year, user_bd_month, user_bd_day))
                    mb.setWearLocation(position[1])
                else:
                    print("MiBand should be connected before setting user data")
            else:
                print("MiBand should be registered before setting user data")
        else:
            print("*** user with id %s doesn't exist" % user_id)

    def do_reluser(self, params):
        if args.mode == "db":
            try:
               l = params.split()
               dev_id = int(l[0])
               user_id = int(l[1])
            except ValueError:
               print "*** argument should be number"
               return
            except IndexError:
               print "*** reluser takes at least one parameter"
               return
            if dev_id >= len(self.mibands.keys()):
                print "*** device not in the device list"
                return
            udata = mbdb.get_user_data(cnxn_string, user_id)
            if udata:
                if mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]):
                    if self.mibands.keys()[dev_id] in connected_devices.keys():
                        mb = connected_devices[self.mibands.keys()[dev_id]]
                        if mbdb.release_device_user(cnxn_string, mb.addr, user_id):
                            print "MiBand Released from user"
                        else:
                            print "There was a problem releasing this MiBand"
                    else:
                        print("MiBand should be connected before releasing user data")
                else:
                    print("MiBand should be registered before releasing user data")
            else:
                print("*** user with id %s doesn't exist" % user_id)
        else:
            # TODO: If storage, release properly
            print("This operation is only available for DB mode")

    def do_connect(self, params):
        try:
           l = int(params)
        except ValueError:
           print "*** argument should be number"
           return
        except IndexError:
           print "*** connect takes at least one parameter"
           return
        dev_id = l
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if len(connected_devices.keys()) >= 5:
            print("Can't connect to more than 5 devices at the same time, disconnect some")
        else:
            if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
                or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
                if self.mibands.keys()[dev_id] in connected_devices.keys():
                    print("That MiBand is already connected")
                else:
                    try:
                        addr = self.mibands.keys()[dev_id]
                        model = self.models[addr]
                        if not addr in self.devices_keys.keys():
                            self.devices_keys[addr] = random_key()
                        if model.upper() == "MB2":
                            mb = MiBand2(addr, self.devices_keys[addr], initialize=False)
                        elif model.upper() == "MB3":
                            mb = MiBand3(addr, self.devices_keys[addr], initialize=False)
                        connected_devices[self.mibands.keys()[dev_id]] = mb
                        if args.mode == "db":
                            alarms = mbdb.get_device_alarms(cnxn_string, mb.addr)
                            mbdb.update_battery(cnxn_string, mb.addr, mb.battery_info['level'])
                        else:
                            if mb.addr in self.devices_alarms.keys():
                                alarms = self.devices_alarms[mb.addr]
                            else:
                                alarms = []
                        for a in alarms:
                            mb.alarms += [MiBandAlarm(a["hour"], a["minute"], enabled=a["enabled"], repetitionMask=a["repetition"])]
                    except BTLEException as e:
                        print("There was a problem connecting to this MiBand, try again later")
                        print e
            else:
                print("You have to register the MiBand before connecting to it")

    def do_disconnect(self, params):
        try:
           l = int(params)
        except ValueError:
           print "*** argument should be number"
           return
        except IndexError:
           print "*** disconnect takes at least one parameter"
           return
        dev_id = l
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if self.mibands.keys()[dev_id] in connected_devices.keys():
            try:
                mb = connected_devices[self.mibands.keys()[dev_id]]
                mb.disconnect()
                del connected_devices[self.mibands.keys()[dev_id]]
                del mb
                print ("MiBand disconnected!")
            except BTLEException as e:
                print("There was a problem disconnecting this MiBand, try again later")
                print e
        else:
            print("That MiBand isn't connected!")

    def do_register(self, params):
        try:
           l = int(params)
        except ValueError:
           print "*** argument should be number"
           return
        except IndexError:
           print "*** register takes at least one parameter"
           return
        dev_id = l
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
            print("That MiBand is already registered")
        else:
            mb = None
            try:
                addr = self.mibands.keys()[dev_id]
                model = self.models[addr]
                if not addr in self.devices_keys.keys():
                    self.devices_keys[addr] = random_key()
                if model.upper() == "MB2":
                    mb = MiBand2(addr, self.devices_keys[addr], initialize=False)
                elif model.upper() == "MB3":
                    mb = MiBand3(addr, self.devices_keys[addr], initialize=False)
                mb.cleanAlarms()
                if args.mode == "db":
                    dev_id = mbdb.get_device_id(cnxn_string, mb.addr)
                    mbdb.delete_all_alarms(cnxn_string, dev_id)
                    mbdb.register_device(cnxn_string, mb.addr)
                    mbdb.update_battery(cnxn_string, mb.addr, mb.battery_info['level'])
                else:
                    self.registered_devices += [mb.addr]
                # Device stays connected after initialize, but we don't want that
                mb.disconnect()
            except BTLEException as e:
                print("There was a problem registering this MiBand, try again later")
                print e
            except KeyError as e:
                print("Device was kicked out")
                print e

    def do_unregister(self, params):
        try:
           l = int(params)
        except ValueError:
           print "*** argument should be number"
           return
        except IndexError:
           print "*** unregister takes at least one parameter"
           return
        dev_id = l
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
            if not self.mibands.keys()[dev_id] in connected_devices.values():
                try:
                    if args.mode == "db":
                        mbdb.unregister_device(cnxn_string, self.mibands.keys()[dev_id])
                        mbdb.delete_all_alarms(cnxn_string, self.mibands.keys()[dev_id])
                    else:
                        self.registered_devices.remove(self.mibands.keys()[dev_id])
                        del self.devices_keys[self.mibands.keys()[dev_id]]
                    print("MiBand unregistered!")
                except BTLEException:
                    print("There was a problem unregistering this MiBand, try again later")
            else:
                print("Disconnect the miBand2 first!")
        else:
            print("That MiBand is not registered")


    def do_activity(self, params):
        try:
           l = int(params)
        except ValueError:
            print "*** argument should be number"
            return
        except IndexError:
           print "*** activity takes at least one parameter"
           return
        dev_id = l
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
            if self.mibands.keys()[dev_id] in connected_devices.keys():
                q.put(self.mibands.keys()[dev_id])
                q.join()
            else:
                print("MiBand should be connected before fetching activity data")
        else:
            print("MiBand should be registered before fetching activity data")

    def do_alarms(self, params):
        l = params.split()
        try:
           dev_id = int(l[0])
           command = "list"
           if len(l) > 1:
               command = l[1]
        except ValueError:
           print "*** argument 1 should be number"
           return
        except IndexError:
           print "*** alarms takes at least one parameter"
           return
        if command not in ['list', 'queue', 'set', 'toggle', 'toggleday', 'delete', 'clear']:
           print "*** invalid alarm command, see help"
           return
        if dev_id >= len(self.mibands.keys()):
            print "*** device not in the device list"
            return
        if ((args.mode == "db" and mbdb.is_device_registered(cnxn_string, self.mibands.keys()[dev_id]))
            or args.mode == "json" and self.mibands.keys()[dev_id] in self.registered_devices):
            if self.mibands.keys()[dev_id] in connected_devices.keys():
                mb = connected_devices[self.mibands.keys()[dev_id]]
                if args.mode == "db":
                    alarms = mbdb.get_device_alarms(cnxn_string, self.mibands.keys()[dev_id])
                else:
                    if self.mibands.keys()[dev_id] in self.devices_alarms.keys():
                        alarms = self.devices_alarms[self.mibands.keys()[dev_id]]
                    else:
                        alarms = []
                if command == 'list':
                    if len(alarms) > 0:
                        for idx,a in enumerate(mb.alarms):
                            print "[%s]" % idx + str(a)
                if command == 'clear':
                    if len(alarms) > 0:
                        mb.cleanAlarms()
                        if args.mode == "db":
                            mbdb.delete_all_alarms(cnxn_string, mb.addr)
                        else:
                            self.devices_alarms[self.mibands.keys()[dev_id]] = []
                elif command == 'queue':
                    try:
                        hour, minute = map(lambda x: int(x), l[2].split(":"))
                        alarm_id = mb.queueAlarm(hour, minute)
                        if args.mode == "db":
                            mbdb.set_alarm(cnxn_string, mb.addr, mb.alarms[alarm_id], alarm_id)
                        else:
                            if len(alarms) > 0:
                                self.devices_alarms[self.mibands.keys()[dev_id]] += [{"enabled": True, "repetition": 128, "hour": hour, "minute": minute}]
                            else:
                                self.devices_alarms[self.mibands.keys()[dev_id]] = [{"enabled": True, "repetition": 128, "hour": hour, "minute": minute}]
                    except IndexError:
                        print "*** queue takes an hour parameter in format HH:MM"
                    except ValueError:
                        print "*** queue takes an hour parameter in format HH:MM"
                elif command == 'delete':
                    try:
                        alarm_id = int(l[2])
                        mb.deleteAlarm(alarm_id)
                        if len(alarms) > 0:
                            if args.mode == "db":
                                mbdb.delete_alarm(cnxn_string, mb.addr, alarm_id)
                            else:
                                del self.devices_alarms[self.mibands.keys()[dev_id]][alarm_id]
                    except IndexError:
                        print "*** delete takes an alarm_id parameter"
                    except ValueError:
                        print "*** delete's alarm_id should be a number"
                elif command == 'toggle':
                    try:
                        alarm_id = int(l[2])
                        mb.toggleAlarm(alarm_id)
                        if args.mode == "db":
                            mbdb.set_alarm(cnxn_string, mb.addr, mb.alarms[alarm_id], alarm_id)
                        else:
                            self.devices_alarms[self.mibands.keys()[dev_id]][alarm_id]["enabled"] = mb.alarms[alarm_id].enabled
                    except IndexError:
                        print "*** toggle takes an alarm_id parameter"
                    except ValueError:
                        print "*** toggle's alarm_id should be a number"
                elif command == 'toggleday':
                    try:
                        alarm_id = int(l[2])
                        day_id = int(l[3])
                        if day_id not in range(1,8):
                            print "*** day_id should be between 1 (Monday) and 7 (Sunday)"
                            return
                        else:
                            mb.toggleAlarmDay(alarm_id, day_id-1)
                            if args.mode == "db":
                                mbdb.set_alarm(cnxn_string, mb.addr, mb.alarms[alarm_id], alarm_id)
                            else:
                                self.devices_alarms[self.mibands.keys()[dev_id]][alarm_id]["repetition"] = mb.alarms[alarm_id].repetitionMask

                    except IndexError:
                        print "*** toggleday takes an alarm_id parameter and a day_id parameter (1-7)"
                    except ValueError:
                        print "*** toggleday's alarm_id and day_id should be both numbers"
                elif command == "set":
                    try:
                        alarm_id = int(l[2])
                        hour, minute = map(lambda x: int(x), l[3].split(":"))
                        mb.changeAlarmTime(alarm_id, hour, minute)
                        if args.mode == "db":
                            mbdb.set_alarm(cnxn_string, mb.addr, mb.alarms[alarm_id], alarm_id)
                        else:
                            self.devices_alarms[self.mibands.keys()[dev_id]][alarm_id]["hour"] = mb.alarms[alarm_id].hour
                            self.devices_alarms[self.mibands.keys()[dev_id]][alarm_id]["minute"] = mb.alarms[alarm_id].minute
                    except IndexError:
                        print "*** set takes an alarm_id parameter and an hour parameter in format HH:MM"
                    except ValueError:
                        print "*** toggleday's alarm_id and hour (HH:MM) should be both numbers"
            else:
                print("MiBand should be connected before viewing/changing alarms")
        else:
            print("MiBand should be registered before viewing/changing alarms")

    def do_save(self, line):
        if args.mode == "json":
            print("Saving local data")
            save_local(self)
        else:
            print("This command is only available to local mode")


    def do_exit(self, line):
        print("Saving local data before exiting")
        save_local(self)
        return self.exit_safely()

    def do_EOF(self, line):
        print("Saving local data before exiting")
        save_local(self)
        return self.exit_safely()
示例#10
0
    def connect(self):
        if self.target_address is None:
            sys.stdout.write("Searching for devices....")
            sys.stdout.flush()

            scanner = Scanner(self.port)
            scanner.withDelegate(ScanDelegate())
            nearby_devices = scanner.scan(10)

            if len(nearby_devices) > 0:
                for dev in nearby_devices:
                    #look for a device name that starts with the specified target name
                    for (adtype, desc, value) in dev.getScanData():
                        #one of the data points returned by getScanData is the device's
                        #human-readable name. This is what we want to match against to see
                        #if we have discovered a Sphero device.
                        if value.startswith(self.target_name):
                            self.found_device = True
                            self.target_address = dev.addr
                            break
                        if self.found_device:
                            break

            if self.target_address is not None:
                sys.stdout.write("\nFound Sphero device with address: %s\n" %
                                 (self.target_address))
                sys.stdout.flush()
            else:
                sys.stdout.write("\nNo Sphero devices found.\n")
                sys.stdout.flush()
                sys.exit(1)
        else:
            sys.stdout.write("Connecting to device: " + self.target_address +
                             "...")

        try:
            #Connect to sphero and populate services and characteristics
            self.peripheral = btle.Peripheral(self.target_address,
                                              addrType=btle.ADDR_TYPE_RANDOM)
            sys.stdout.write("Connected!\nFinding services...")
            sys.stdout.flush()
            self.peripheral.getServices()
            self.ble_service = self.peripheral.getServiceByUUID(
                btle.UUID(self.UUIDs['BLE_SVC']))
            self.anti_dos_characteristic = self.ble_service.getCharacteristics(
                self.UUIDs['ANTI_DOS_CHAR'])[0]
            self.robot_control_service = self.peripheral.getServiceByUUID(
                self.UUIDs['BOT_CTRL_SVC'])
            self.wake_characteristic = self.ble_service.getCharacteristics(
                self.UUIDs['WAKE_CHAR'])[0]
            self.tx_power_characteristic = self.ble_service.getCharacteristics(
                self.UUIDs['TX_PWR_CHAR'])[0]
            self.anti_dos_characteristic = self.ble_service.getCharacteristics(
                self.UUIDs['ANTI_DOS_CHAR'])[0]
            self.commands_characteristic = self.robot_control_service.getCharacteristics(
                self.UUIDs['CMD_CHAR'])[0]
            self.response_characteristic = self.robot_control_service.getCharacteristics(
                self.UUIDs['RESP_CHAR'])[0]
            sys.stdout.write("Services found!\nEnabling dev mode...")
            sys.stdout.flush()
            self._enable_dev_mode()
        except btle.BTLEException as error:
            sys.stdout.write(error.strerror)
            sys.stdout.flush()
            time.sleep(5.0)
            sys.exit(1)
        sys.stdout.write("Done.\n")
        sys.stdout.flush()
        return True
示例#11
0
文件: main.py 项目: kvantetore/igrill
        "device": "TokenCube 1",
        "addr": "dc:00:62:95:62:67",
        "type": "ambient"
    }
}

INFLUX_SERVER = os.environ.get("INFLUX_SERVER", None) or "raspberrypi.local"
INFLUX_DATABASE = os.environ.get("INFLUX_DB", None) or "sensors"
INFLUX_USER = os.environ.get("INFLUX_USER", None) or "root"
INFLUX_PASSWORD = os.environ.get("INFLUX_PASSWORD", None) or "root"

if __name__ == "__main__":
    print "Creating Scanner"
    delegate = DeviceForwardingDelegate()
    delegate.handlers.append(IGrillHandler(device_settings))
    delegate.handlers.append(TokenCubeHandler(device_settings))

    scanner = Scanner()
    scanner.withDelegate(delegate)

    print "Connecting to InfluxDB server"
    persistence = DataPersistence(INFLUX_SERVER, INFLUX_DATABASE, INFLUX_USER, INFLUX_PASSWORD)

    while True:
        print "Scanning..."
        scanner.scan(30)

        print "Persisting..."
        for handler in delegate.handlers:
            handler.persist_stats(persistence)
示例#12
0
class CarControl:
    scanner = None
    devices = []
    devicetext = ""
    isConnected = False
    carAddr = None
    carName = None
    carDevice = None
    carPeripheral = None

    def __repr__(self):
        return "devices: {}, address: {}, carName: {}".format(
            len(self.devices), self.carAddr, self.carName)
        #return "devices: {}".format(len(self.devices))

    def scan(self, timeout=10):
        foundDevices = 0
        self.devices = []
        self.devicetext = ""

        newdevices = []
        scansuccess = False
        try:
            self.scanner = Scanner()
            self.scanner.withDelegate(MainDelegate())
            newdevices = self.scanner.scan(timeout)
            scansuccess = True
        except Exception as e:
            scansuccess = False

        if scansuccess:
            for dev in newdevices:
                if dev.addrType == btle.ADDR_TYPE_PUBLIC:
                    foundDevices = foundDevices + 1
                    self.devices.append({
                        "name": dev.getValueText(9),
                        "addr": dev.addr
                    })
                    self.devicetext = self.devicetext + "> Device #{} {} ({}), [{}], [{}]\n".format(
                        foundDevices, dev.addr, dev.addrType,
                        dev.getValueText(9), dev.getValueText(8))

        # add known cars
        for k in KNOWN_CARS:
            foundDevices = foundDevices + 1
            self.devices.append({"name": k["name"], "addr": k["addr"]})
            self.devicetext = self.devicetext + "> Device #{} {} ({}), [{}]\n".format(
                foundDevices, k["addr"], "Known Device", k["name"])

        return scansuccess

    def connect(self, carnum):

        if len(self.devices) == 0:
            print("connect: Nothing scanned")
            return

        if carnum < 0 or carnum > len(self.devices):
            print("connect: Car number invalid, {}".format(carnum))
            return

        try:
            self.carAddr = self.devices[carnum]["addr"]
            self.carName = self.devices[carnum]["name"]
            self.carPeripheral = Peripheral()
            self.carPeripheral.withDelegate(MainDelegate())
            self.carPeripheral.connect(self.carAddr)
            self.isConnected = True
            return True

        except Exception as e:
            self.carPeripheral = None
            print("connect: Error,", e)
            return False

    def listdescriptors(self):
        try:
            print("listdescriptors: ...")
            print("listdescriptors: listing descriptors")
            descriptors = self.carPeripheral.getDescriptors()
            for desc in descriptors:
                print("   --  DESCRIPTORS: {}, [{}], Handle: {} (0x{:04x})".
                      format(desc.uuid,
                             UUID(desc.uuid).getCommonName(), desc.handle,
                             desc.handle))
        except Exception as e:
            print("listdescriptors: Error,", e)

    def listservices(self):
        try:
            print("listservices: listing services")
            services = self.carPeripheral.getServices()
            for serv in services:
                print("   -- SERVICE: {} [{}]".format(
                    serv.uuid,
                    UUID(serv.uuid).getCommonName()))
                characteristics = serv.getCharacteristics()
                for chara in characteristics:
                    print(
                        "   --   --> CHAR: {}, Handle: {} (0x{:04x}) - {} - [{}]"
                        .format(chara.uuid, chara.getHandle(),
                                chara.getHandle(), chara.propertiesToString(),
                                UUID(chara.uuid).getCommonName()))
        except Exception as e:
            print("listservices: Error,", e)

    def disconnectcar(self):
        self.isConnected = False

        if self.carPeripheral is None:
            print("disconnectcar: No car connected")
            return False

        try:
            self.carPeripheral.disconnect()
            self.carPeripheral = None
            return True
        except Exception as e:
            print("disconnectcar: Error,", e)
            return False

    def readcharacteristics(self):
        try:
            if self.carPeripheral is None:
                print("readcharacteristics: No car connected")
                return
            print("readcharacteristics: reading the readables")

            chars = self.carPeripheral.getCharacteristics()
            for c in chars:
                if c.supportsRead():
                    print(
                        "  -- READ: {} [{}] (0x{:04x}), {}, Value: {}".format(
                            c.uuid,
                            UUID(c.uuid).getCommonName(), c.getHandle(),
                            c.descs,
                            c.read() if c.supportsRead() else ""))
        except Exception as e:
            print("readcharacteristics: Error,", e)

    def writevalue(self, handle, value, wait=False):
        try:
            if self.carPeripheral is None:
                #print("writevalue: No car connected")
                return
            #print("writevalue: writing to handle 0x{:04x} value {}".format(handle, value))

            self.carPeripheral.writeCharacteristic(handle, value, wait)

        except Exception as e:
            print("writevalue: Error,", e)

    def readvalue(self, handle):
        try:
            if self.carPeripheral is None:
                print("readvalue: No car connected")
                return
            print("readvalue: reading handle 0x{:04x}".format(handle))
            value = self.carPeripheral.readCharacteristic(handle)
            print("readvalue: Handle 0x{:04x} = {}".format(handle, value))

        except Exception as e:
            print("readvalue: Error,", e)

    def sendhandshake(self):
        # handshake...
        for finger in BTCMD_HANDSHAKE:
            self.writevalue(BTDRIVE_HANDLE, finger, True)

    def carfiregun(self, intensity=0.5):
        self.writevalue(BTDRIVE_HANDLE, BTCMD_FIREGUN)

    def carforward(self, intensity=0.5):
        if intensity < 0.1 or intensity > 1:
            return
        scale = 0x1F
        actual_intensity = 0x00 + round(scale * intensity)

        # pull value list
        tx_list = [BTCMD_DRIVE, actual_intensity, 0x00]
        tx_data = bytes(tx_list)
        self.writevalue(BTDRIVE_HANDLE, tx_data, True)

    def carreverse(self, intensity=0.5):
        if intensity < 0.1 or intensity > 1:
            return
        scale = 0x1F
        actual_intensity = 0x20 + round(scale * intensity)

        # pull value list
        tx_list = [BTCMD_DRIVE, actual_intensity, 0x00]
        tx_data = bytes(tx_list)
        self.writevalue(BTDRIVE_HANDLE, tx_data, True)

    def carright(self, intensity=0.5):
        if intensity < 0.1 or intensity > 1:
            return
        scale = 0x1F
        actual_intensity = 0x40 + round(scale * intensity)

        # pull value list
        tx_list = [BTCMD_DRIVE, 0x00, actual_intensity]
        tx_data = bytes(tx_list)
        self.writevalue(BTDRIVE_HANDLE, tx_data, True)

    def carleft(self, intensity=0.5):
        if intensity < 0.1 or intensity > 1:
            return
        scale = 0x1F
        actual_intensity = 0x60 + round(scale * intensity)

        # pull value list
        tx_list = [BTCMD_DRIVE, 0x00, actual_intensity]
        tx_data = bytes(tx_list)
        self.writevalue(BTDRIVE_HANDLE, tx_data, True)
示例#13
0
 def start(self, notify):
     scanner = Scanner()
     scanner.withDelegate(ScanDelegate(scanner, notify))
     scanner.scan(10.0)
示例#14
0
def main():
    sc = Scanner()
    scd = MiBand2ScanDelegate()
    sc.withDelegate(scd)

    scan_thread = threading.Thread(target=scan_miband2, args=(sc,))
    scan_thread.start()

    for i in range(max_connections):
         t = threading.Thread(target=worker)
         t.daemon = True
         t.start()

    while True:
        try:
            s = raw_input('> ')
        except:
            break

        try:
            command = s.strip().lower()
            if command == "exit":
                scan_thread.do_scan = False
                scan_thread.join()
                print ("Disconnecting from %s devices" % len(connected_devices.values()))
                for con in connected_devices.values():
                    con.disconnect()
                print("Saving changes to Registered Devices storage")
                save_registered(registered_devices, devices_last_sync)
                break

            elif command == "save":
                print("Saving changes to Registered Devices storage")
                save_registered(registered_devices, devices_last_sync)
            elif command == "devices":
                mibands = scd.tmp_devices
                for idx,mb in enumerate(mibands.keys()):
                    str = "[%s] Mi Band 2 (%s) %sdB " % (idx,mb,mibands[mibands.keys()[idx]].rssi)
                    if mb in registered_devices:
                        str += "[R]"
                    if mb in connected_devices:
                        str += "[C]"
                    print str
            elif "alert" in command:
                arg = re.search("\w+\s+(\d+)\s+(\d+)", command)
                if arg != None and len(arg.groups()) == 2:
                    dev_id = int(arg.groups()[0])
                    alert_int = int(arg.groups()[1])
                    if mibands.keys()[dev_id] in registered_devices:
                        if mibands.keys()[dev_id] in connected_devices.keys():
                            try:
                                mb2 = connected_devices[mibands.keys()[dev_id]]
                                data = struct.pack('B', alert_int)
                                mb2.send_alert(data)
                                print "Sending Notification: " + binascii.hexlify(data)
                            except BTLEException:
                                print("There was a problem alerting this MiBand2, try again later")
                        else:
                            print("That MiBand2 is not connected!")
                    else:
                        print("That MiBand2 is not registered")
                else:
                    print("'alert' takes two parameters")
            elif "unregister" in command:
                arg = re.search("\w+\s+(\d+)", command)
                if arg != None and len(arg.groups()) == 1:
                    dev_id = int(arg.groups()[0])
                    if mibands.keys()[dev_id] in registered_devices:
                        if not mibands.keys()[dev_id] in connected_devices.values():
                            try:
                                registered_devices.remove(mibands.keys()[dev_id])
                                print("MiBand2 unregistered!")
                            except BTLEException:
                                print("There was a problem unregistering this MiBand2, try again later")
                        else:
                            print("Disconnect the miBand2 first!")
                    else:
                        print("That MiBand2 is not registered")
                else:
                    print("'unregister' takes only one parameter")

            elif "register" in command:
                arg = re.search("\w+\s+(\d+)", command)
                if arg != None and len(arg.groups()) == 1:
                    dev_id = int(arg.groups()[0])
                    if mibands.keys()[dev_id] in registered_devices:
                        print("That MiBand2 is already registered")
                    else:
                        try:
                            mb2 = MiBand2(mibands.keys()[dev_id], initialize=True)
                            registered_devices.append(mibands.keys()[dev_id])
                        except BTLEException as e:
                            print("There was a problem disconnecting this MiBand2, try again later")
                            print e
                else:
                    print("'register' takes only one parameter")

            elif "disconnect" in command:
                arg = re.search("\w+\s+(\d+)", command)
                if arg != None and len(arg.groups()) == 1:
                    dev_id = int(arg.groups()[0])
                    if len(connected_devices.keys()) >= max_connections:
                        print("Can't connect to more than 5 devices at the same time, disconnect some")
                    else:
                        if mibands.keys()[dev_id] in connected_devices.keys():
                            try:
                                mb2 = connected_devices[mibands.keys()[dev_id]]
                                mb2.disconnect()
                                del connected_devices[mibands.keys()[dev_id]]
                                del mb2
                                print ("MiBand2 disconnected!")
                            except BTLEException as e:
                                print("There was a problem disconnecting this MiBand2, try again later")
                                print e
                        else:
                            print("That MiBand2 isn't connected!")
                else:
                    print("'connect' takes only one parameter")

            elif "connect" in command:
                arg = re.search("\w+\s+(\d+)", command)
                if arg != None and len(arg.groups()) == 1:
                    dev_id = int(arg.groups()[0])
                    if len(connected_devices.keys()) >= 5:
                        print("Can't connect to more than 5 devices at the same time, disconnect some")
                    else:
                        if mibands.keys()[dev_id] in registered_devices:
                            if mibands.keys()[dev_id] in connected_devices.keys():
                                print("That MiBand2 is already connected")
                            else:
                                try:
                                    mb2 = MiBand2(mibands.keys()[dev_id], initialize=False)
                                    connected_devices[mibands.keys()[dev_id]] = mb2
                                except BTLEException as e:
                                    print("There was a problem connecting to this MiBand2, try again later")
                                    print e
                        else:
                            print("You have to register the MiBand2 before connecting to it")
                else:
                    print("'connect' takes only one parameter")

            elif "alarms" in command:
                pass
                # TODO:  load JSON alarms into device representation
                #        let the user view, queue, toggle and toggle days of each alarm
                #        save and persist alarms in JSON form, key should be mac
                #        and elements arrays of alarm parameters (hour, min, enabledness and daymasks)        

            elif "activity" in command:
                arg = re.search("\w+\s+(\w+)", command)
                if arg != None and len(arg.groups()) == 1:
                    if arg.groups()[0] == 'all':
                        print("Fetching all registered and in range Miband2's activity data")
                        # Check that the registered device is present on the scanned mibands list
                        for item in filter(lambda x: x in registered_devices, mibands.keys()):
                            q.put(item)
                    else:
                        dev_id = int(arg.groups()[0])
                        if mibands.keys()[dev_id] in registered_devices:
                            q.put(mibands.keys()[dev_id])
                        else:
                            print("MiBand2 should be registered before fetching activity data")
                else:
                    print("'activity' takes only one parameter")
            elif command == '':
                pass
            else:
                print ("Unknown command %s, try using 'help'" % command)

        except OSError:
            print 'Invalid command'