Skip to content

Where’s MarcoPolo for Windows?

MarcoPolo, “context-aware computing for OS X” appeals to all three great virtues of the programmer: Laziness, Impatience, and Hubris. It makes me want a Mac notebook. Unfortunately, Pro/E, ANSYS, and other necessary tools for my regular work would mean I’d end up dual-booting the Mac all the time. And I’d miss my port replicator and its enabling me to have one connection to the monitor, keyboard, mouse, network, etc.

So, why not build a MarcoPolo for Windows? I’ve not yet found one, but I’d be more than happy to be proven wrong there. In the meantime, I’m working on a Python/Windows proof-of-concept that could be the groundwork for a Windows analogue to MarcoPolo.

# Idea for Win32 version of MarcoPolo (Context-aware computing for Mac OS X)

# Contexts
contexts = {
    'Home': 1,
    'Work': 1,
    'pre-Noon': 1,
    'post-Noon': 1,
    'Unknown': 1,
}

import wmi, pybonjour, time, IP4Range
# wmi: http://tgolden.sc.sabren.com/python/wmi.html
# pybonjour: http://o2s.csail.mit.edu/o2s-wiki/pybonjour
# IP4Range: http://code.activestate.com/recipes/466298/

def main():
    c=wmi.WMI()
    # Evidence sources via WMI (direct from MarcoPolo features, some
    # sources may not be available in Win32)

    # Current audio output device (headphones/speakers) -- may not be
    # discoverable on XP and earlier.

    # Discoverable Bluetooth devices -- can find a Bluetooth adapter via
    # USB, but not a connected end-user device

    # Advertised Bonjour (Zeroconf) services -- 'browse_and_resolve.py
    # _daap._tcp' finds a remote iTunes share, but no idea how to look for
    # random services.

    # Attached FireWire devices -- no FireWire-capable computers on hand

    # Assigned IP addresses
    ipList=[]
    for adapter in c.Win32_NetworkAdapterConfiguration(IPEnabled="True"):
        ipList.append(adapter.IPAddress[0])

    # Ambient light level — may not be any standard sensors available to
    # Windows

    # Attached monitors
    monitorList=[]
    for monitor in c.Win32_DesktopMonitor(Availability=3):
        monitorList.append(monitor.Name)

    # Active network links
    networkAdapterList=[]
    for adapter in c.Win32_NetworkAdapter(NetConnectionStatus=2):
        networkAdapterList.append(adapter.Description)

    # Power source (power adapter/battery) — need to test on laptop

    # Running Applications
    applicationList=[]
    for process in c.Win32_Process():
        applicationList.append(process.Name)

    # Time of day
    timeOfDay=time.strftime("%H:%M")

    # Attached USB devices
    usbDeviceList=[]
    for device in c.Win32_USBControllerDevice():
        usbDeviceList.append(device.Dependent.Description)

    # Visible WiFi networks — need to test on laptop

    # Rules (type, criteria, context, confidence)
    ruleList = [
        ('usb', 'Brother HL-5140 series', 'Home', 0.80),
        ('usb', 'Visioneer OneTouch 7300', 'Home', 0.99),
        ('monitor', 'Plug and Play Monitor', 'Home', 0.60),
        ('ip', '192.168.254.4', 'Home', 0.50),
        ('ip', '149.149.254.0/24', 'Work', 0.99),
        ('ssid', 'mike-and-carolyn', 'Home', 0.99),
        ('time', ['00:00', '11:59'], 'pre-Noon', 0.99),
        ('time', ['12:00', '23:59'], 'post-Noon', 0.99),
        ]

    # Decision
    for rule in ruleList:
        itemFound = -1
        (ruleType, ruleItem, ruleContext, ruleStrength) = rule
        if ruleType=='ip':
            ipRange=IP4Range.IP4Range(ruleItem)
            for ip in ipList:
                currentIP=IP4Range.IP4Range(ip.encode('ascii'))
                if currentIP.issubset(ipRange):
                    itemFound = 1

        elif ruleType=='monitor':
            try:
                itemFound = monitorList.index(ruleItem)
            except ValueError:
                pass
        elif ruleType=='adapter':
            try:
                itemFound = networkAdapterList.index(ruleItem)
            except ValueError:
                pass
        elif ruleType=='application':
            try:
                itemFound = applicationList.index(ruleItem)
            except ValueError:
                pass
        elif ruleType=='usb':
            try:
                itemFound = usbDeviceList.index(ruleItem)
            except ValueError:
                pass
        elif ruleType=='time':
            if cmp(timeOfDay,ruleItem[0])>=0 and cmp(timeOfDay,ruleItem[1])<=0:
                itemFound=1
         else:
            print "Unknown rule type %s" % (ruleType)
            continue

        if itemFound!=-1:
            contexts&#91;ruleContext&#93;=contexts&#91;ruleContext&#93;*(1-ruleStrength)

    myLocation='Unknown'
    myConfidence=1-contexts&#91;'Unknown'&#93;
    for context in contexts:
        if contexts&#91;context&#93;!=1:
            if (1-contexts&#91;context&#93;)>myConfidence:
                myLocation=context
                myConfidence = 1-contexts[context]

    print "Your location: %s (confidence %f)" % (myLocation, myConfidence)
    print

if __name__ == "__main__":
    main()

I know my Python is mediocre at best. But this does work so far in my limited testing (“Unknown rule type ssid, Your location: Home (confidence 0.999600)”). Thanks to David Symonds for his assistance in this thread.

Post a Comment

Your email is never published nor shared. Required fields are marked *