Python COM automation - Controlling Microsoft Agent

Kamilche klachemin at comcast.net
Sat Mar 1 01:47:02 CET 2008


Here's a snippet of code for pythoners to enjoy.
Make the Microsoft genie speak text and dance about!

'''
Requires:
----------
    comtypes from:
        http://starship.python.net/crew/theller/comtypes

    MS Agent from:
        http://www.microsoft.com/msagent

To do:
----------
1. List available animations using self.char.AnimationNames above
2. Get a RequestComplete event when the animation is done playing.
3. Change the voice to something else.

If you can do any of that, please send me a copy at
kamilche at mad.scientist.com. Thanks!

'''
import comtypes
import comtypes.client
import time

class Genie:
    CLSID_AgentServer   = "{D45FD31B-5C6E-11D1-9EC1-00C04FD7081F}"
    IID_IAgentEx        = "{48D12BA0-5B77-11d1-9EC1-00C04FD7081F}"
    CLSCTX_SERVER       = 5
    char                = None
    agent               = None
    animlist            = ['Acknowledge', 'Alert', 'Announce',
'Blink', 'Confused', 'Congratulate',
                           'Congratulate_2', 'Decline', 'DoMagic1',
'DoMagic2', 'DontRecognize',
                           'Explain', 'GestureDown', 'GestureLeft',
'GestureRight', 'GestureUp',
                           'GetAttention', 'GetAttentionContinued',
'GetAttentionReturn',
                           'Greet', 'Hearing_1', 'Hearing_2',
'Hearing_3', 'Hearing_4',
                           'Idle1_1', 'Idle1_2', 'Idle1_3', 'Idle1_4',
'Idle1_5', 'Idle1_6',
                           'Idle2_1', 'Idle2_2', 'Idle2_3', 'Idle3_1',
'Idle3_2',
                           'LookDown', 'LookDownBlink',
'LookDownReturn', 'LookLeft',
                           'LookLeftBlink', 'LookLeftReturn',
'LookRight', 'LookRightBlink',
                           'LookRightReturn', 'LookUp', 'LookUpBlink',
'LookUpReturn',
                           'LookUpLeft', 'LookUpLeftBlink',
'LookUpLeftReturn',
                           'LookUpRight', 'LookUpRightBlink',
'LookUpRightReturn',
                           'MoveDown', 'MoveLeft', 'MoveRight',
'MoveUp', 'Pleased',
                           'Process', 'Processing', 'Read',
'ReadContinued', 'ReadReturn',
                           'Reading', 'RestPose', 'Sad', 'Search',
'Searching',
                           'StartListening', 'StopListening',
'Suggest',
                           'Surprised', 'Think', 'Thinking',
'Uncertain', 'Wave', 'Write',
                           'WriteContinued', 'WriteReturn', 'Writing',
'Hide', 'Show']
    class Curry:
        def __init__(self, fun, *args, **kwargs):
            self.fun = fun
            self.args = args[:]
            self.kwargs = kwargs.copy()
        def __call__(self, *args, **kwargs):
            if kwargs and self.kwargs:
                kw = self.kwargs.copy()
                kw.update(kwargs)
            else:
                kw = kwargs or self.kwargs
            return self.fun(*(self.args + args), **kw)

    def __init__(self):
        self.agent =
comtypes.client.CreateObject(self.CLSID_AgentServer,
self.CLSCTX_SERVER, self.IID_IAgentEx)
        try:
            self.agent.Connected = True
        except comtypes.COMError, args:
            if args[0] == -2147418094:
                self.agent =
comtypes.client.CreateObject(self.CLSID_AgentServer,
self.CLSCTX_SERVER, self.IID_IAgentEx)
                self.agent.Connected = True
            else:
                raise
        self.agent.Characters.Load("mychar")
        self.char = self.agent.Characters("mychar")
        self.char.Show()

        # How do I get the list of names from this?
        print 'List of animations:'
        anims = self.char.AnimationNames
        print anims

    def __getattr__(self, attrname):
        if attrname in self.animlist:
            return self.Curry(self.char.Play, attrname)
        else:
            return object.__getattr__(self, attrname)
    def Move(self, x, y):
        self.char.MoveTo(x, y)
    def Play(self, anim):
        try:
            retval = self.char.Play(anim)
        except:
            print 'animation %s not found' % anim
            return
    def GestureAt(self, x, y):
        self.char.GestureAt(x, y)
    def Speak(self, text):
        retval = self.char.Speak(text)
    def Think(self, text):
        self.char.Think(text)
    def ChooseAgent(self):
        self.agent.ShowDefaultCharacterProperties()
    def GetAnimations(self):
        return self.animlist
    def Stop(self):
        self.char.StopAll()

def main2():
    genie = Genie()
    genie.Move(400, 300)
    genie.Greet()
    genie.GestureAt(400, 600)
    genie.Speak("You killed my father, prepare to die.")
    time.sleep(5)
    genie.Idle2_1()
    genie.Think('Using Python to command me is cool!')
    anims = genie.GetAnimations()
    for i in range(len(anims)):
        genie.Think('%d - %s' % (i, anims[i]))
        genie.Play(anims[i])
        time.sleep(5)
        genie.Stop()

main2()



More information about the Python-list mailing list