aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--ParrotZikMac.py98
-rw-r--r--ParrotZikTrayMac214
2 files changed, 312 insertions, 0 deletions
diff --git a/ParrotZikMac.py b/ParrotZikMac.py
new file mode 100644
index 0000000..a4b536c
--- /dev/null
+++ b/ParrotZikMac.py
@@ -0,0 +1,98 @@
+#!/usr/bin/env python
+
+import lightblue
+import ParrotProtocol
+import struct
+from BeautifulSoup import BeautifulSoup
+
+class ParrotZik(object):
+ def __init__(self,addr=None):
+ uuid = "0ef0f502-f0ee-46c9-986c-54ed027807fb"
+
+ service_matches = lightblue.findservices( name = "RFCOMM", addr = addr )
+
+ if len(service_matches) == 0:
+ print "Couldn't find Parrot Zik"
+ return
+
+ first_match = service_matches[0]
+ port = first_match["port"]
+ name = first_match["name"]
+ host = first_match["host"]
+
+ print "Connecting to \"%s\" on %s" % (name, host)
+
+ self.sock=lightblue.lightblueSocket( lightblue.RFCOMM )
+ self.sock.connect((host, port))
+
+ self.sock.send('\x00\x03\x00')
+ data = self.sock.recv(3)
+
+ self.BatteryLevel = 100
+ print "Connected"
+
+ def getBatteryState(self):
+ data = self.sendGetMessage("/api/system/battery/get")
+ return data.answer.system.battery["state"]
+
+ def getBatteryLevel(self):
+ data = self.sendGetMessage("/api/system/battery/get")
+ try:
+ if data.answer.system.battery["level"] <> '':
+ self.BatteryLevel = data.answer.system.battery["level"]
+ except:
+ pass
+
+ try:
+ print "notification received" + data.notify["path"]
+ except:
+ pass
+
+ return self.BatteryLevel
+
+ def getVersion(self):
+ data = self.sendGetMessage("/api/software/version/get")
+ return data.answer.software["version"]
+
+ def getFriendlyName(self):
+ data = self.sendGetMessage("/api/lightblue/friendlyname/get")
+ return data.answer.lightblue["friendlyname"]
+
+ def getAutoConnection(self):
+ data = self.sendGetMessage("/api/system/auto_connection/enabled/get")
+ return data.answer.system.auto_connection["enabled"]
+
+ def setAutoConnection(self,arg):
+ data = self.sendSetMessage("/api/system/auto_connection/enabled/set",arg)
+ return data
+
+ def getAncPhoneMode(self):
+ data = self.sendGetMessage("/api/system/anc_phone_mode/enabled/get")
+ return data.answer.system.anc_phone_mode["enabled"]
+
+ def getNoiseCancel(self):
+ data = self.sendGetMessage("/api/audio/noise_cancellation/enabled/get")
+ return data.answer.audio.noise_cancellation["enabled"]
+
+ def setNoiseCancel(self,arg):
+ data = self.sendSetMessage("/api/audio/noise_cancellation/enabled/set",arg)
+ return data
+
+ def sendGetMessage(self,message):
+ message = ParrotProtocol.getRequest(message)
+ return self.sendMessage(message)
+
+ def sendSetMessage(self,message,arg):
+ message = ParrotProtocol.setRequest(message,arg)
+ return self.sendMessage(message)
+
+ def sendMessage(self,message):
+ self.sock.send(str(message))
+ data = self.sock.recv(7)
+ len = struct.unpack('B', data[1])[0]
+ data = self.sock.recv(1024)
+ data=BeautifulSoup(data)
+ return data
+
+ def Close(self):
+ self.sock.close()
diff --git a/ParrotZikTrayMac b/ParrotZikTrayMac
new file mode 100644
index 0000000..7179386
--- /dev/null
+++ b/ParrotZikTrayMac
@@ -0,0 +1,214 @@
+#!/usr/bin/env python
+
+import sys
+import re
+import os
+import ParrotZikMac
+import rumps
+from binplist import binplist
+import BluetoothPairedDevices
+
+
+UPDATE_FREQUENCY = 30 # seconds
+
+class ParrotZikIndicator:
+ def __init__(self):
+
+ self.menu_setup()
+
+ self.connected=False
+
+ self.p = re.compile('00\-88\-[0-9A-Fa-f]{2}\-[0-9A-Fa-f]{2}\-[0-9A-Fa-f]{2}\-[0-9A-Fa-f]{2}')
+
+ if sys.platform=="darwin":
+ self.icon_directory = os.path.dirname(os.path.realpath(sys.argv[0])) + os.path.sep+ 'share' + os.path.sep+'icons' + os.path.sep+'zik'+ os.path.sep
+ self.app = rumps.App("Parrot Zik Tray", icon= self.icon_directory+ os.path.sep + "zik-audio-headset.png")
+ self.app.menu = self.menu
+
+ return
+
+ def pos(menu, ignore, icon):
+ return (Gtk.StatusIcon.position_menu(menu, icon))
+
+ def setIcon(self, name):
+ if sys.platform=="linux2":
+ self.statusicon.set_icon(name)
+ else:
+ self.statusicon.set_from_file(self.icon_directory+name+'.png')
+
+ def gtk_right_click_event(self, icon, button, time):
+ if not self.menu_shown:
+ self.menu_shown=True
+ self.menu.popup(None, None, gtk.status_icon_position_menu, button, time, self.statusicon)
+ else:
+ self.menu_shown=False
+ self.menu.popdown()
+
+
+ def menu_setup(self):
+ self.menu = []
+
+ self.info_item = rumps.MenuItem("Parrot Zik Not connected..")
+ self.menu.append(self.info_item)
+
+ self.check = rumps.MenuItem("Noise Cancellation")
+ self.menu.append(self.check)
+
+ self.check2 = rumps.MenuItem("Auto Connection")
+ self.menu.append(self.check2)
+
+ self.check3 = rumps.MenuItem("Lou Reed Mode")
+ self.menu.append(self.check3)
+
+ self.check4 = rumps.MenuItem("Concert Hall Mode")
+ self.menu.append(self.check4)
+
+
+ def EstablishConnection(self):
+ if self.connected:
+ if not self.parrot.sock:
+ print "Lost connection"
+ self.connected = False
+ else:
+ print "Connection already established"
+ else:
+ mac=BluetoothPairedDevices.ParrotZikMac()
+ if mac:
+ self.parrot = ParrotZik.ParrotZik(mac)
+ if not self.parrot.sock:
+ print "Failed to connect to Parrot Zik %s" % mac
+ return False
+
+ self.connected = True
+ self.name = self.parrot.getFriendlyName()
+ self.version = self.parrot.getVersion()
+
+ self.check.set_sensitive(True)
+ self.check2.set_sensitive(True)
+ self.check3.set_sensitive(True)
+ self.check4.set_sensitive(True)
+
+ if self.parrot.getNoiseCancel() == "true":
+ self.check.set_active(True)
+ else:
+ self.check.set_active(False)
+
+ if self.parrot.getAutoConnection() == "true":
+ self.check2.set_active(True)
+ else:
+ self.check2.set_active(False)
+
+ if self.parrot.getLouReedMode() == "true":
+ self.check3.set_active(True)
+ else:
+ self.check3.set_active(False)
+
+ if self.parrot.getParrotConcertHall() == "true":
+ self.check4.set_active(True)
+ else:
+ self.check4.set_active(False)
+
+ self.CheckBattery()
+ return True
+
+ def toggleANC(self,widget):
+ if self.connected:
+ if self.check.get_active():
+ self.parrot.setNoiseCancel("true")
+ else:
+ self.parrot.setNoiseCancel("false")
+
+ def toggleAuto(self,widget):
+ if self.connected:
+ if self.check2.get_active():
+ self.parrot.setAutoConnection("true")
+ else:
+ self.parrot.setAutoConnection("false")
+
+ def toggleLouReedMode(self,widget):
+ if self.connected:
+ if self.check3.get_active():
+ self.parrot.setLouReedMode("true")
+ else:
+ self.parrot.setLouReedMode("false")
+ if self.parrot.getLouReedMode() == "true":
+ self.check3.set_active(True)
+ else:
+ self.check3.set_active(False)
+
+ if self.parrot.getParrotConcertHall() == "true":
+ self.check4.set_active(True)
+ else:
+ self.check4.set_active(False)
+
+ def toggleParrotConcertHall(self,widget):
+ if self.connected:
+ if self.check4.get_active():
+ self.parrot.setParrotConcertHall("true")
+ else:
+ self.parrot.setParrotConcertHall("false")
+
+ if self.parrot.getLouReedMode() == "true":
+ self.check3.set_active(True)
+ else:
+ self.check3.set_active(False)
+
+ if self.parrot.getParrotConcertHall() == "true":
+ self.check4.set_active(True)
+ else:
+ self.check4.set_active(False)
+
+ def CheckBattery(self):
+ if self.connected:
+ print "Updating battery"
+ self.batteryLevel = int(self.parrot.getBatteryLevel())
+
+ if self.parrot.BatteryCharging:
+ self.batteryLevel = "Charging"
+ self.setIcon("zik-battery-charging")
+ self.batteryLevel="Unknown"
+ self.batteryState="Charging"
+ elif self.batteryLevel>80:
+ self.setIcon("zik-battery-100")
+ self.batteryState="In Use"
+ elif self.batteryLevel>60:
+ self.setIcon("zik-battery-080")
+ self.batteryState="In Use"
+ elif self.batteryLevel>40:
+ self.setIcon("zik-battery-060")
+ self.batteryState="In Use"
+ elif self.batteryLevel>20:
+ self.setIcon("zik-battery-040")
+ self.batteryState="In Use"
+ else:
+ self.setIcon("zik-battery-low")
+ self.batteryState="In Use"
+
+ self.info_item.set_label("Connected to: "+self.name+
+ "\nFirmware version: "+self.version+
+ "\nState: "+self.batteryState+
+ "\nBattery Level: "+str(self.batteryLevel))
+ else:
+ self.setIcon("zik-audio-headset")
+ self.info_item.set_label("Parrot Zik Not connected..")
+ self.check.set_sensitive(False)
+ self.check2.set_sensitive(False)
+ self.check3.set_sensitive(False)
+ self.check4.set_sensitive(False)
+ return True
+
+ # def show_about_dialog(self, widget):
+ # about_dialog = gtk.AboutDialog()
+
+ # about_dialog.set_destroy_with_parent(True)
+ # about_dialog.set_name("Parrot Zik Tray")
+ # about_dialog.set_version("0.1")
+ # about_dialog.set_authors(["Dmitry Moiseev m0sia@m0sia.ru"])
+ # about_dialog.run()
+ # about_dialog.destroy()
+
+
+if __name__ == "__main__":
+ indicator = ParrotZikIndicator()
+ indicator.EstablishConnection()
+ indicator.app.run() \ No newline at end of file