Пример #1
0
def _process_packet(data):
    ev = aiobs.HCI_Event()
    xx = ev.decode(data)
    xx = EddyStone().decode(ev)
    if xx:
        if xx['url'][:24] == 'https://wilshireliu.com/':
            #print("Google beacon: {}".format(xx['url'][:24]))
            print("Steps: {}".format(xx['url'][24:]))
            global actualsteps
            actualsteps = int(xx['url'][24:]) * 1000
            print("actual steps:", actualsteps)
            print("today goal:", today_goal)
            print("tomorrow goal:", tmr_goal)
            client = mqtt.Client("P1")
            client.on_message = on_message
            client.connect(broker_address)
            client.loop_start()
            client.subscribe(subscribetopic)
            time.sleep(3)
            if actualsteps < today_goal:
                message_goal = "GET UP!"
                client.publish(
                    publishtopic,
                    "Friend, the world is so beautiful so go outside and explore the world. Btw the goal of tomorrow is {}"
                    .format(tmr_goal))
                client.loop_stop()
            if actualsteps >= today_goal:
                message_goal = "GREAT JOB! You beat your goal"
                print(today_goal)
                client.publish(
                    publishtopic,
                    "Nice! You beat the goal and the goal of tomorrow is {}".
                    format(tmr_goal))
                client.loop_stop()
Пример #2
0
def my_process(data):
    global opts

    ev = aiobs.HCI_Event()
    xx = ev.decode(data)
    if opts.mac:
        goon = False
        mac = ev.retrieve("peer")
        for x in mac:
            if x.val in opts.mac:
                goon = True
                break
        if not goon:
            return

    if opts.raw:
        print("Raw data: {}".format(ev.raw_data))
    if opts.eddy:
        xx = EddyStone().decode(ev)
        if xx:
            print("Google Beacon {}".format(xx))
    elif opts.ruuvi:
        xx = RuuviWeather().decode(ev)
        if xx:
            print("Weather info {}".format(xx))
    elif opts.pebble:
        xx = BlueMaestro().decode(ev)
        if xx:
            print("Pebble info {}".format(xx))
    elif opts.atcmi:
        xx = ATCMiThermometer().decode(ev)
        if xx:
            print("Temperature info {}".format(xx))
    else:
        ev.show(0)
def _process_packet(data):
    global steps
    ev = aiobs.HCI_Event()  # event is passed to HCI in between the BT controller and host stack
    xx = ev.decode(data)  # decode the signal
    xx = EddyStone().decode(ev)  # run our decoded packet through the EddyStone protocol
    if xx:
        match = re.match(r'.*(group3p).*steps=(\d*).*', xx['url'])
        # if we match, we parse the steps and publish it to the broker
        if match:
            print('Received Eddystone Beacon Steps. Processing...')
            today = datetime.datetime.now().date()
            steps = int(match.groups()[1])
            print('Publishing steps...')
            client.publish(publish_topic, _determine_goal_met())
            with open(history_file, 'r') as inf:
                lines = inf.read().strip()
            with open(history_file, 'w') as outf:
                new_entry = '{},{},{}'.format(str(today),steps,goal)
                found = False
                for line in lines.split('\n'):
                    line = line.strip()
                    entry = [item.strip() for item in line.split(',')]
                    if entry[0] == str(today):
                        found = True
                        outf.write(new_entry)
                    else:
                        outf.write(line)
                    outf.write('\n')

                if not found:
                    outf.write(new_entry)
Пример #4
0
def my_process(data):
    global opts

    ev = aiobs.HCI_Event()
    xx = ev.decode(data)
    if opts.mac:
        goon = False
        mac = ev.retrieve("peer")
        for x in mac:
            if x.val in opts.mac:
                goon = True
                break
        if not goon:
            return

    if opts.raw:
        print("Raw data: {}".format(ev.raw_data))
    if opts.eddy:
        xx = EddyStone().decode(ev)
        if xx:
            print("Google Beacon {}".format(xx))
    elif opts.ruuvi:
        xx = RuuviWeather().decode(ev)
        if xx:
            print("Weather info {}".format(xx))
    elif opts.bbw200:
        xx = Bbw200().decode(ev)
        if xx:
            print("{}".format(xx))
    else:
        ev.show(0)
Пример #5
0
def _process_packet(data):
    ev = aiobs.HCI_Event()
    xx = ev.decode(data)
    xx = EddyStone().decode(ev)
    if xx:
        if xx['url'][:24] == 'https://wilshireliu.com/':
            #print("Google beacon: {}".format(xx['url'][:24]))
            print("Steps: {}".format(xx['url'][24:]))
            global actualsteps
            actualsteps = int(xx['url'][24:])  #*1000
            print("actual steps:", actualsteps)
            print("today goal:", today_goal)
            print("tomorrow goal:", tmr_goal)
            client = mqtt.Client("P1")
            client.on_message = on_message
            client.connect(broker_address)
            client.loop_start()
            client.subscribe(subscribetopic)
            time.sleep(3)
            if actualsteps < today_goal:
                #client.publish(publishtopic, "You have only walked " + str(actualsteps) + " steps. You need to walk " + str(today_goal) + " steps.")
                client.publish(
                    publishtopic, "{\"actualSteps\": " + str(actualsteps) +
                    ", \"todayGoal\": " + str(today_goal) + "}")
                client.loop_stop()
            if actualsteps >= today_goal:
                print(today_goal)
                client.publish(
                    publishtopic,
                    "Nice! You beat the goal for today and the goal for tomorrow is {}"
                    .format(tmr_goal))
                client.loop_stop()
Пример #6
0
def _process_packet(data):
    ev = aiobs.HCI_Event()
    xx = ev.decode(data)
    xx = EddyStone().decode(ev)
    if xx:
        if "team8" in xx['url']:
            value = format(xx['url'][13:21])
            print(value)
            print("sending pulication")
            client.publish(publishtopic, value)
Пример #7
0
def _process_packet(data):
    ev=aiobs.HCI_Event()
    xx = ev.decode(data)
    xx = EddyStone().decode(ev)
    if xx:
        if (xx['url'][:24] == "https://IoTexasSteps.com"):
                numOfSteps = xx['url'][25:]
                stepMessage = "IoTaxes steps:{}".format(numOfSteps)
                saveSteps(numOfSteps)
                print(stepMessage)
                event_loop.stop()
                btctrl.stop_scan_request()  
Пример #8
0
def my_process(data):
    global current_x
    global current_y
    global direction
    global time_for_segment
    global current_segment_time
    global number_of_measurements_this_segment

    ev = aiobs.HCI_Event()
    xx = ev.decode(data)

    #print(xx)
    #return

    beacon = EddyStone().decode(ev)
    if beacon:
        #print("Google Beacon {}".format(beacon))
        rssi = beacon['rssi']
        #print(rssi)

        rssi_measurements[current_y][current_x] += rssi
        number_of_measurements_this_segment += 1
        # TODO SAVE RSSI

    if time.time() - current_segment_time > time_for_segment:

        print('MOVE')

        for i in range(0, 6):
            os.system('echo 1 >/sys/class/leds/led0/brightness')
            time.sleep(0.1)
            os.system('echo 0 >/sys/class/leds/led0/brightness')
            time.sleep(0.1)

        rssi_measurements[current_y][
            current_x] /= number_of_measurements_this_segment
        number_of_measurements_this_segment = 0

        current_x += direction
        if current_x == -1 or current_x == x_dim:
            current_x -= direction
            direction *= -1
            current_y += 1

        current_segment_time = time.time()

        print('moving to sector', current_x, current_y)

    if current_y == y_dim:
        print('ALL DONE')
        np.savetxt("foo.csv", rssi_measurements, delimiter=",")
        exit(0)
Пример #9
0
 def test_eddystone_url(self):
     pckt = aioblescan.HCI_Event()
     pckt.decode(
         b'\x04>)\x02\x01\x03\x01\xdc)e\x90U\xf1\x1d\x02\x01\x06\x03\x03\xaa\xfe\x15\x16\xaa\xfe\x10\xf6\x03makecode\x00#about\xb5'
     )
     result = EddyStone().decode(pckt)
     self.assertDictEqual(
         result, {
             'mac address': 'f1:55:90:65:29:dc',
             'tx_power': -10,
             'url': 'https://makecode.com/#about',
             'rssi': -75
         })
Пример #10
0
def _process_packet(data):
  ev = aiobs.HCI_Event()
  xx = ev.decode(data)
  xx = EddyStone().decode(ev)
  if xx:
    if "http://cmd?" in xx['url']:
      global step_count
      step_count = xx['url'][11:]
      print(step_count)
      client.loop_start()
      client.subscribe(subscribetopic)
      time.sleep(4)
      client.loop_stop()
Пример #11
0
 def test_eddystone_uid(self):
     pckt = aioblescan.HCI_Event()
     pckt.decode(
         b'\x04>)\x02\x01\x03\x01\xdc)e\x90U\xf1\x1d\x02\x01\x06\x03\x03\xaa\xfe\x15\x16\xaa\xfe\x00\xf6\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x00\x00\x00\x00\x00X\xb6'
     )
     result = EddyStone().decode(pckt)
     self.assertDictEqual(
         result, {
             'tx_power': -10,
             'rssi': -74,
             'name space': (0x63).to_bytes(10, byteorder="big"),
             'instance': (0x58).to_bytes(6, byteorder="big"),
             'mac address': 'f1:55:90:65:29:dc'
         })
Пример #12
0
def _process_packet(data):
    """
    Filter BLE packets to only show Eddystone data
    before calling packet_callback
    :param data: BLE Packet data
    :return: None
    """
    logging.debug('Packet found')
    ev = aioblescan.HCI_Event()
    ev.decode(data)
    logging.debug('Using the following callback %s', packet_callback)
    if packet_callback is not None:
        eddystone_data = EddyStone().decode(ev)
        if eddystone_data:
            packet_callback(eddystone_data)
Пример #13
0
 def test_eddystone_url(self):
     pckt = aioblescan.HCI_Event()
     pckt.decode(
         b"\x04>)\x02\x01\x03\x01\xdc)e\x90U\xf1\x1d\x02\x01\x06\x03\x03\xaa\xfe\x15\x16\xaa\xfe\x10\xf6\x03makecode\x00#about\xb5"
     )
     result = EddyStone().decode(pckt)
     self.assertDictEqual(
         result,
         {
             "mac address": "f1:55:90:65:29:dc",
             "tx_power": -10,
             "url": "https://makecode.com/#about",
             "rssi": -75,
         },
     )
Пример #14
0
 def test_eddystone_uid(self):
     pckt = aioblescan.HCI_Event()
     pckt.decode(
         b"\x04>)\x02\x01\x03\x01\xdc)e\x90U\xf1\x1d\x02\x01\x06\x03\x03\xaa\xfe\x15\x16\xaa\xfe\x00\xf6\x00\x00\x00\x00\x00\x00\x00\x00\x00c\x00\x00\x00\x00\x00X\xb6"
     )
     result = EddyStone().decode(pckt)
     self.assertDictEqual(
         result,
         {
             "tx_power": -10,
             "rssi": -74,
             "name space": (0x63).to_bytes(10, byteorder="big"),
             "instance": (0x58).to_bytes(6, byteorder="big"),
             "mac address": "f1:55:90:65:29:dc",
         },
     )
Пример #15
0
def _process_packet(data):
    #global val
    ev = aiobs.HCI_Event()
    xx = ev.decode(data)
    xx = EddyStone().decode(ev)

    if xx is not None:
        check = xx['url']
        if 'werock' in str(xx['url']):
            val = xx['url'][26:]
            print("{}".format(xx['url'][26:]))
            client.on_message = on_message
            client.loop_start()
            client.subscribe(subscribetopic)
            client.publish(publishtopic, val)
            #time.sleep(10)
            client.loop_stop()
Пример #16
0
#create a connection with the raw socket
#This used to work but now requires a STREAM socket.
#fac=event_loop.create_connection(aiobs.BLEScanRequester,sock=mysocket)
#Thanks to martensjacobs for this fix
fac=event_loop._create_connection_transport(mysocket,aiobs.BLEScanRequester,None,None)
#Start it
conn,btctrl = event_loop.run_until_complete(fac)
#Attach your processing
btctrl.process=my_process
if opts.advertise:
    command = aiobs.HCI_Cmd_LE_Advertise(enable=False)
    btctrl.send_command(command)
    command = aiobs.HCI_Cmd_LE_Set_Advertised_Params(interval_min=opts.advertise,interval_max=opts.advertise)
    btctrl.send_command(command)
    command = aiobs.HCI_Cmd_LE_Set_Advertised_Msg(msg=EddyStone())
    btctrl.send_command(command)
    command = aiobs.HCI_Cmd_LE_Advertise(enable=True)
    btctrl.send_command(command)

#Probe
btctrl.send_scan_request()
try:
    # event_loop.run_until_complete(coro)
    event_loop.run_forever()
except KeyboardInterrupt:
    print('keyboard interrupt')
finally:
    print('closing event loop')
    btctrl.stop_scan_request()
    command = aiobs.HCI_Cmd_LE_Advertise(enable=False)
Пример #17
0
#fac=event_loop.create_connection(aiobs.BLEScanRequester,sock=mysocket)
#Thanks to martensjacobs for this fix
fac = event_loop._create_connection_transport(mysocket, aiobs.BLEScanRequester,
                                              None, None)
#Start it
conn, btctrl = event_loop.run_until_complete(fac)
#Attach your processing
btctrl.process = my_process
if opts.advertise:
    command = aiobs.HCI_Cmd_LE_Advertise(enable=False)
    btctrl.send_command(command)
    command = aiobs.HCI_Cmd_LE_Set_Advertised_Params(
        interval_min=opts.advertise, interval_max=opts.advertise)
    btctrl.send_command(command)
    if opts.url:
        myeddy = EddyStone(param=opts.url)
    else:
        myeddy = EddyStone()
    if opts.txpower:
        myeddy.power = opts.txpower
    command = aiobs.HCI_Cmd_LE_Set_Advertised_Msg(msg=myeddy)
    btctrl.send_command(command)
    command = aiobs.HCI_Cmd_LE_Advertise(enable=True)
    btctrl.send_command(command)

#Probe
btctrl.send_scan_request()
try:
    # event_loop.run_until_complete(coro)
    event_loop.run_forever()
except KeyboardInterrupt:
Пример #18
0
    def decode(self, packet):
        #Look for Ruuvi tag URL and decode it
        result = {}
        url = EddyStone().decode(packet)
        if url is None:
            url = packet.retrieve("Payload for mfg_specific_data")
            if url:
                val = url[0].val
                if val[0] == 0x99 and val[1] == 0x04 and val[2] == 0x03:
                    #Looks just right
                    result["mac address"] = packet.retrieve("peer")[0].val
                    val = val[2:]
                    result["humidity"] = val[1] / 2.0
                    result["temperature"] = unpack(
                        ">b",
                        int(val[2]).to_bytes(1, "big"))[0]
                    result["temperature"] += val[3] / 100.0
                    result["pressure"] = int.from_bytes(val[4:6],
                                                        "big") + 50000
                    dx = int.from_bytes(val[6:8], "big", signed=True)
                    dy = int.from_bytes(val[8:10], "big", signed=True)
                    dz = int.from_bytes(val[10:12], "big", signed=True)
                    length = sqrt(dx**2 + dy**2 + dz**2)
                    result["accelerometer"] = (dx, dy, dz, length)
                    result["voltage"] = int.from_bytes(val[12:14], "big")
                    return result

            else:
                return None
        rssi = packet.retrieve("rssi")
        if rssi:
            result["rssi"] = rssi[-1].val
        power = packet.retrieve("tx_power")
        if power:
            result["tx_power"] = power[-1].val
        try:
            if "//ruu.vi/" in url["url"]:
                #We got a live one
                result["mac address"] = packet.retrieve("peer")[0].val
                url = url["url"].split("//ruu.vi/#")[-1]
                if len(url) > 8:
                    url = url[:-1]
                val = b64decode(url + '=' * (4 - len(url) % 4), "#.")
                if val[0] in [2, 4]:
                    result["humidity"] = val[1] / 2.0
                    result["temperature"] = unpack(
                        ">b",
                        int(val[2]).to_bytes(1, "big"))[0]  #Signed int...
                    result["pressure"] = int.from_bytes(val[4:6],
                                                        "big") + 50000
                    if val[0] == 4:
                        try:
                            result["id"] = val[6]
                        except:
                            pass
                    return result
                elif val[0] == 3:
                    result["humidity"] = val[1] / 2.0
                    result["temperature"] = unpack(
                        ">b",
                        int(val[2]).to_bytes(1, "big"))[0]
                    result["temperature"] += val[3] / 100.0
                    result["pressure"] = int.from_bytes(val[4:6],
                                                        "big") + 50000
                    dx = int.from_bytes(val[6:8], "big", signed=True)
                    dy = int.from_bytes(val[8:10], "big", signed=True)
                    dz = int.from_bytes(val[10:12], "big", signed=True)
                    length = sqrt(dx**2 + dy**2 + dz**2)
                    result["accelerometer"] = (dx, dy, dz, length)
                    result["voltage"] = int.from_bytes(val[12:14], "big")
                    return result
        except:
            print("\n\nurl oops....")
            packet.show()
        return None
Пример #19
0
class Decoder:
    all_decoders = {
        "pebble": BlueMaestro().decode,
        "ruuviraw": RuuviTagRaw().decode,
        "ruuviurl": RuuviTagUrl().decode,
        "eddy": EddyStone().decode,
    }

    def __init__(self):
        self.use_fixed_decoders = False
        self.fixed_decoders = []
        self.mac_decoders = {}

    def enable_fixed_decoders(self, decoders=[]):
        # if enabled, uses fixed decoders-list
        self.use_fixed_decoders = True
        print("Setting fixed_decoders = {}".format(decoders))
        if "all" in decoders:
            self.fixed_decoders = list(self.all_decoders.keys())
        else:
            self.fixed_decoders = decoders

    def enable_per_mac_decoders(self, sources=[]):
        # Enable per mac decoders as defined in sources configuration
        self.use_fixed_decoders = False
        print("Setting per_mac_decoders = {}".format(sources))
        for mac, mac_config in sources.items():
            _d = mac_config.get("decoders", [])
            if "all" in _d:
                self.mac_decoders[mac] = list(self.all_decoders.keys())
            else:
                self.mac_decoders[mac] = _d

    def get_decoders(self, mac):
        if self.use_fixed_decoders:
            return self.fixed_decoders
        else:
            if mac in self.mac_decoders:
                return self.mac_decoders.get(mac)
            else:
                return self.mac_decoders.get("*", None)

    def run(self, data, simulator=0):
        if simulator > 0:
            # data is from BLE simulator, just return the data
            return data

        base_mesg = {"decoder": "none"}
        ev = aiobs.HCI_Event()
        ev.decode(data)
        mesg = packet_info(ev)
        if "mac" not in mesg:  # invalid packet if no mac (peer) address
            print("Decoder: invalid message, no mac.")
            return base_mesg

        decoders = self.get_decoders(mesg["mac"])
        if not decoders:
            return base_mesg

        # Try actually decode the message
        for decoder in decoders:
            func = self.all_decoders.get(decoder, None)
            if func:
                mesg.update(func(ev))
            if mesg:
                mesg["decoder"] = decoder
                return {**base_mesg, **mesg}

        return base_mesg
Пример #20
0
 def decode(self, packet):
     # Look for Ruuvi tag URL and decode it
     result = {}
     rssi = packet.retrieve("rssi")
     if rssi:
         result["rssi"] = rssi[-1].val
     url = EddyStone().decode(packet)
     if url is None:
         data = packet.retrieve("Manufacturer Specific Data")
         if data:
             val = data[0].payload
             if val[0].val == 0x0499:
                 val = val[1].val
                 if val[0] == 0x03:
                     # print("RAWv1")
                     # Looks just right RAWv1
                     result["mac address"] = packet.retrieve("peer")[0].val
                     result["humidity"] = val[1] / 2.0
                     result["temperature"] = get_temp(val[2], val[3])
                     result["pressure"] = int.from_bytes(val[4:6],
                                                         "big") + 50000
                     dx = int.from_bytes(val[6:8], "big", signed=True)
                     dy = int.from_bytes(val[8:10], "big", signed=True)
                     dz = int.from_bytes(val[10:12], "big", signed=True)
                     length = sqrt(dx**2 + dy**2 + dz**2)
                     result["accelerometer"] = (dx, dy, dz, length)
                     result["voltage"] = int.from_bytes(val[12:14], "big")
                     return result
                 elif val[0] == 0x05:
                     # print("RAWv2")
                     result["mac address"] = packet.retrieve("peer")[0].val
                     result["temperature"] = (
                         int.from_bytes(val[1:3], "big", signed=True) *
                         0.005)
                     result["humidity"] = int.from_bytes(val[3:5],
                                                         "big") * 0.0025
                     result["pressure"] = (int.from_bytes(val[5:7], "big") +
                                           50000) / 100.0
                     dx = int.from_bytes(val[7:9], "big", signed=True)
                     dy = int.from_bytes(val[9:11], "big", signed=True)
                     dz = int.from_bytes(val[11:13], "big", signed=True)
                     length = sqrt(dx**2 + dy**2 + dz**2)
                     result["accelerometer"] = (dx, dy, dz, length)
                     result["voltage"] = (
                         int.from_bytes(val[13:15], "big") >> 5) + 1600
                     result["tx_power"] = (
                         int.from_bytes(val[13:15], "big") & 0x1F) * 2 - 40
                     result["move count"] = val[15]
                     result["sequence"] = int.from_bytes(val[16:18], "big")
                     return result
                 else:
                     # packet.show()
                     return None
         else:
             # print("No data")
             return None
     else:
         # print("URL")
         power = packet.retrieve("tx_power")
         if power:
             result["tx_power"] = power[-1].val
         try:
             if "//ruu.vi/" in url["url"]:
                 # We got a live one
                 result["mac address"] = packet.retrieve("peer")[0].val
                 url = url["url"].split("//ruu.vi/#")[-1]
                 if len(url) > 8:
                     url = url[:-1]
                 val = b64decode(url + "=" * (4 - len(url) % 4), "#.")
                 if val[0] in [2, 4]:
                     result["humidity"] = val[1] / 2.0
                     result["temperature"] = unpack(
                         ">b",
                         int(val[2]).to_bytes(1, "big"))[0]  # Signed int...
                     result["pressure"] = int.from_bytes(val[4:6],
                                                         "big") + 50000
                     if val[0] == 4:
                         try:
                             result["id"] = val[6]
                         except:
                             pass
                     return result
                 elif val[0] == 3:
                     result["humidity"] = val[1] / 2.0
                     result["temperature"] = unpack(
                         ">b",
                         int(val[2]).to_bytes(1, "big"))[0]
                     result["temperature"] += val[3] / 100.0
                     result["pressure"] = int.from_bytes(val[4:6],
                                                         "big") + 50000
                     dx = int.from_bytes(val[6:8], "big", signed=True)
                     dy = int.from_bytes(val[8:10], "big", signed=True)
                     dz = int.from_bytes(val[10:12], "big", signed=True)
                     length = sqrt(dx**2 + dy**2 + dz**2)
                     result["accelerometer"] = (dx, dy, dz, length)
                     result["voltage"] = int.from_bytes(val[12:14], "big")
                     return result
         except:
             pass
             # print ("\n\nurl oops....")
             # packet.show()
     return None
Пример #21
0
def main(args=None):
    global opts

    parser = argparse.ArgumentParser(
        description="Track BLE advertised packets")
    parser.add_argument(
        "-e",
        "--eddy",
        action="store_true",
        default=False,
        help="Look specificaly for Eddystone messages.",
    )
    parser.add_argument(
        "-m",
        "--mac",
        type=check_mac,
        action="append",
        help="Look for these MAC addresses.",
    )
    parser.add_argument(
        "-r",
        "--ruuvi",
        action="store_true",
        default=False,
        help="Look only for Ruuvi tag Weather station messages",
    )
    parser.add_argument(
        "-p",
        "--pebble",
        action="store_true",
        default=False,
        help="Look only for Pebble Environment Monitor",
    )
    parser.add_argument(
        "-A",
        "--atcmi",
        action="store_true",
        default=False,
        help="Look only for ATC_MiThermometer tag messages",
    )
    parser.add_argument(
        "-R",
        "--raw",
        action="store_true",
        default=False,
        help="Also show the raw data.",
    )
    parser.add_argument(
        "-a",
        "--advertise",
        type=int,
        default=0,
        help=
        "Broadcast like an EddyStone Beacon. Set the interval between packet in millisec",
    )
    parser.add_argument(
        "-u",
        "--url",
        type=str,
        default="",
        help="When broadcasting like an EddyStone Beacon, set the url.",
    )
    parser.add_argument(
        "-t",
        "--txpower",
        type=int,
        default=0,
        help="When broadcasting like an EddyStone Beacon, set the Tx power",
    )
    parser.add_argument(
        "-D",
        "--device",
        type=int,
        default=0,
        help="Select the hciX device to use (default 0, i.e. hci0).",
    )
    try:
        opts = parser.parse_args()
    except Exception as e:
        parser.error("Error: " + str(e))
        sys.exit()

    event_loop = asyncio.get_event_loop()

    # First create and configure a raw socket
    mysocket = aiobs.create_bt_socket(opts.device)

    # create a connection with the raw socket
    # This used to work but now requires a STREAM socket.
    # fac=event_loop.create_connection(aiobs.BLEScanRequester,sock=mysocket)
    # Thanks to martensjacobs for this fix
    fac = event_loop._create_connection_transport(mysocket,
                                                  aiobs.BLEScanRequester, None,
                                                  None)
    # Start it
    conn, btctrl = event_loop.run_until_complete(fac)
    # Attach your processing
    btctrl.process = my_process
    if opts.advertise:
        command = aiobs.HCI_Cmd_LE_Advertise(enable=False)
        event_loop.run_until_complete(btctrl.send_command(command))
        command = aiobs.HCI_Cmd_LE_Set_Advertised_Params(
            interval_min=opts.advertise, interval_max=opts.advertise)
        event_loop.run_until_complete(btctrl.send_command(command))
        if opts.url:
            myeddy = EddyStone(param=opts.url)
        else:
            myeddy = EddyStone()
        if opts.txpower:
            myeddy.power = opts.txpower
        command = aiobs.HCI_Cmd_LE_Set_Advertised_Msg(msg=myeddy)
        event_loop.run_until_complete(btctrl.send_command(command))
        command = aiobs.HCI_Cmd_LE_Advertise(enable=True)
        event_loop.run_until_complete(btctrl.send_command(command))

    # Probe
    event_loop.run_until_complete(btctrl.send_scan_request())
    try:
        # event_loop.run_until_complete(coro)
        event_loop.run_forever()
    except KeyboardInterrupt:
        print("keyboard interrupt")
    finally:
        print("closing event loop")
        event_loop.run_until_complete(btctrl.stop_scan_request())
        command = aiobs.HCI_Cmd_LE_Advertise(enable=False)
        event_loop.run_until_complete(btctrl.send_command(command))
        conn.close()
        event_loop.close()
Пример #22
0
 def decode(self, packet):
     #Look for Ruuvi tag URL and decode it
     result = {}
     rssi = packet.retrieve("rssi")
     if rssi:
         result["rssi"] = rssi[-1].val
     url = EddyStone().decode(packet)
     if url is None:
         url = packet.retrieve("Payload for mfg_specific_data")
         if url:
             val = url[0].val
             if val[0] == 0x99 and val[1] == 0x04 and val[2] == 0x03:
                 #Looks just right
                 result["mac address"] = packet.retrieve("peer")[0].val
                 val = val[2:]
                 result["humidity"] = val[1] / 2.0
                 result["temperature"] = s8(val[2])
                 result["temperature"] += val[3] / 100.0
                 result["pressure"] = int.from_bytes(val[4:6],
                                                     "big") + 50000
                 dx = int.from_bytes(val[6:8], "big", signed=True)
                 dy = int.from_bytes(val[8:10], "big", signed=True)
                 dz = int.from_bytes(val[10:12], "big", signed=True)
                 length = sqrt(dx**2 + dy**2 + dz**2)
                 result["accelerometer"] = (dx, dy, dz, length)
                 result["voltage"] = int.from_bytes(val[12:14], "big")
                 return result
             elif val[0] == 0x99 and val[1] == 0x04 and val[2] == 0x05:
                 #Looks just right
                 result["mac address"] = packet.retrieve("peer")[0].val
                 val = val[2:]
                 result["temperature"] = "{:.1f}".format(
                     int.from_bytes(val[1:3], "big", signed=True) * 0.005)
                 result["humidity"] = "{:.1f}".format(
                     int.from_bytes(val[3:5], "big") * 0.0025)
                 result["pressure"] = int.from_bytes(val[5:7],
                                                     "big") + 50000
                 dx = int.from_bytes(val[7:9], "big", signed=True)
                 dy = int.from_bytes(val[9:11], "big", signed=True)
                 dz = int.from_bytes(val[11:13], "big", signed=True)
                 length = "{:.1f}".format(sqrt(dx**2 + dy**2 + dz**2))
                 result["accelerometer"] = (dx, dy, dz, length)
                 p = int.from_bytes(val[13:15], "big")
                 result["voltage"] = 1600 + (
                     p >> (16 - 11)
                 )  #power bat (1st 11bits (so shift 5 places right) of p (unsigned) mV over 1600) (1.6V to 3.647V range)
                 result["tx"] = -40 + (
                     (p & 31) * 2
                 )  #power tx  (last 5 bits (31 = 11111 for bitwise and) of p (unsigned) dBm over -40 in 2dBm steps (-40 - +24)
                 result["movement"] = val[15]
                 result["sequence"] = int.from_bytes(val[16:18], "big")
                 #result["payloadmac"]=val[18:24]             #FIXME(maybe, for completeness)
                 return result
             elif val[0] == 0x99 and val[1] == 0x04:
                 #BLE Manufacturer specific data + Ruuvi manufacturer ID
                 #But not a known data/packet type.
                 print("DEBUG: Unknown Ruuvi Data Format")
                 return None
             else:
                 #                    print("DEBUG: Unknown BLE Manufacturer specific data")
                 return None
         else:
             return None
     power = packet.retrieve("tx_power")
     if power:
         result["tx_power"] = power[-1].val
     try:
         if "//ruu.vi/" in url["url"]:
             #We got a live one
             result["mac address"] = packet.retrieve("peer")[0].val
             url = url["url"].split("//ruu.vi/#")[-1]
             if len(url) > 8:
                 url = url[:-1]
             val = b64decode(url + '=' * (4 - len(url) % 4), "#.")
             if val[0] in [2, 4]:
                 result["humidity"] = val[1] / 2.0
                 result["temperature"] = unpack(
                     ">b",
                     int(val[2]).to_bytes(1, "big"))[0]  #Signed int...
                 result["pressure"] = int.from_bytes(val[4:6],
                                                     "big") + 50000
                 if val[0] == 4:
                     try:
                         result["id"] = val[6]
                     except:
                         pass
                 return result
             elif val[0] == 3:
                 result["humidity"] = val[1] / 2.0
                 result["temperature"] = unpack(
                     ">b",
                     int(val[2]).to_bytes(1, "big"))[0]
                 result["temperature"] += val[3] / 100.0
                 result["pressure"] = int.from_bytes(val[4:6],
                                                     "big") + 50000
                 dx = int.from_bytes(val[6:8], "big", signed=True)
                 dy = int.from_bytes(val[8:10], "big", signed=True)
                 dz = int.from_bytes(val[10:12], "big", signed=True)
                 length = sqrt(dx**2 + dy**2 + dz**2)
                 result["accelerometer"] = (dx, dy, dz, length)
                 result["voltage"] = int.from_bytes(val[12:14], "big")
                 return result
     except:
         print("\n\nurl oops....")
         packet.show()
     return None