Jump to content

Sky Slate Blueberry Blackcurrant Watermelon Strawberry Orange Banana Apple Emerald Chocolate
Photo

Support for the Griffin Powermate


  • Please log in to reply
5 replies to this topic
TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
Hello,
I've made a script for the Griffin Powermate. Therefore, this post might be interesting for Powermate users only :(.

For those of you who don't know, the Powermate is simply a knob that you can... turn... and press. You can assign actions to it using the program provided (tho most common action being volume control).
However, I really don't like the program. It is buggy (some functions don't even work), written in .NET (which means that you need the .NET framework), and just too "bloated." in my opinion.
After seeing Micha's post on a script for HID devices, I decided to try and adapt it for the Powermate.

Pros:
- much simpler/less ressources
- much more possibilities since you can map actions to autohotkey scripts

Cons:
- can't control the light
- can't control two different Powermates (although I'm sure someone could adapt the script for it)

How to use it:
- This script uses Micha's DLL (thank you!), so you'll need to download it and put it in the same directory as the script.
- The different events are at the complete end of the script. So all you have to do is put the commands you want for each event there.

#singleinstance force
detecthiddenwindows on

;SETTINGS

iRescanRate := 1000			;Set the delay between each time the script looks for a Powermate
iCriticalPoint := 1000		;Set the duration (in ms) from which the press duration is considered a Long Press 

/*
For reference only.
This is the HID data (for my Powermate).
Vendor:1917
Product:1040
VersionNr:1024
UsagePage:12
Usage:1
Name:\??\HID#Vid_077d&Pid_0410#6&22bb5480&0&0000#{4d1e55b2-f16f-11cf-88cb-001111000030}
*/

;GLOBAL VARIABLES

bTriggerPressEvent := 0		;Checks whether turns occurred while pressed
t1 := 0						;Initial press point
t2 := 0						;Final press point
iDuration := 0				;Press duration

/*
For reference only.
This is the data that comes out of InputMsg after the loop (the value of Vals):
C_DOWN = 0x00010000000000
C_UP = 0x00000000000000
C_CLOCKWISE = 0x00000100000000
C_COUNTERCLOCKWISE = x0000ff00000000
C_CLOCKWISEPRESSED = 0x00010100000000
C_COUNTERCLOCKWISEPRESSED = 0x0001ff00000000
*/

;Path to DLL
DLLName = AutohotkeyRemoteControl.dll

;Load DLL
hModule := DllCall("LoadLibrary", "str", DLLName)

;Check for error
if (hModule = 0) {
	msgbox API call to LoadLibrary failed.
	exitapp
}

;Set sub to call when a message comes in
OnMessage(0x00FF, "InputMsg")

;Create window to receive msgs
gui show, x0 y0 h0 w0, Powermate Receiver
winhide Powermate Receiver

;get handle
HWND := WinExist("Powermate Receiver")

RESCAN:

;Get device count
ret := DllCall("AutohotkeyRemoteControl\GetDeviceCount", "Cdecl UInt")

;Check for error
if (errorlevel <> 0) {
	msgbox GetDeviceCount failed. Errorcode: %errorlevel%
	goto cleanup
}

loop %ret%
{
	;Get device type
	sType :=  DllCall("AutohotkeyRemoteControl\GetDeviceType", Int, A_Index - 1, "Cdecl Str")	
	
	;Check for error
	if (errorlevel <> 0) {
		msgbox GetDeviceType failed. Errorcode: %errorlevel%
		goto cleanup
	}
	
	;Check if it's HID type
	if (sType = "HID") {
		
		;Set variables
		iVendorId = 0
		iProductId = 0
		iVersionNumber = 0
		iUsagePage = 0
		iUsage = 0
		iNameSize = 400
		VarSetCapacity(sName, 500)
		
		;Get info
		ret := DllCall("AutohotkeyRemoteControl\GetHIDDeviceInfo", INT, A_Index, "INT *", iVendorId, "INT *", iProductId, "INT *", iVersionNumber, "INT *", iUsagePage, "INT *", iUsage, INT, iNameSize, Str, sName, "Cdecl Int")	
		
		;check for error
		if ((errorlevel <> 0) OR (ret = -1)) {
			msgbox GetHIDDeviceInfo failed.`nErrorlevel: %errorlevel%`nReturn value: %ret%
			goto cleanup
		}
		
		;check if it's a Powermate
		if ((iVendorId = 1917) AND (iProductId = 1040)) {
			
			;it is a match. we can register it
			ret := DllCall("AutohotkeyRemoteControl\RegisterDevice", INT, iUsage, INT, iUsagePage, INT, HWND, "Cdecl UInt")
			
			if ((errorlevel <> 0) || (ret = -1)) {
				msgbox RegisterDevice failed. Errorcode: %errorlevel%
				goto cleanup
			}
			
			;we have registered
			bRegistered := 1
			break
			
		}
	}
}

if (bRegistered = 1)
	return
else {
	sleep iRescanRate
	goto RESCAN
}

InputMsg(wParam, lParam, msg, hwnd) {
	DataSize = 5000
	VarSetCapacity(RawData, %DataSize%)
	RawData = 1
	nRC := DllCall("AutohotkeyRemoteControl\GetWM_INPUTHIDData", UINT, wParam, UINT, lParam, "UINT *" , DataSize, "UINT", &RawData, "Cdecl UInt")    
	if ((errorlevel <> 0) || (nRC == -1)) {
	  	MsgBox GetWM_INPUTHIDData failed. Errorcode: %errorlevel%
		goto cleanup
	}

	loop %DataSize% {
    ret := NumGet(RawData, a_index - 1, "UChar")
    ret := Dec2Hex(ret)    
    Vals = %Vals%%ret%
	}
	
	;SEE NOTE ABOUT Vals AT THE TOP OF THE SCRIPT FOR INFO ON ITS VALUES
	
	;Trim zeros
	Vals := SubStr(Vals,1,6)
	
	ifequal vals, 000100, gosub KnobDown
	ifequal vals, 000000, gosub KnobUp
	ifequal vals, 000001, gosub KnobClock
	ifequal vals, 0000ff, gosub KnobCounter
	ifequal vals, 000101, gosub KnobClockPressed
	ifequal vals, 0001ff, gosub KnobCounterPressed
	
	return
}

Dec2Hex(Number) {
    format = %A_FormatInteger%    ; save original integer format
    SetFormat Integer, Hex        ; for converting bytes to hex
    Number += 0
    SetFormat Integer, %format%   ; restore original format
    StringTrimLeft, Number, Number, 2
    Stringlen := StrLen(Number)
    if Stringlen < 2
    Number = 0%Number%
    return Number
}

cleanup:
DllCall("FreeLibrary", "UInt", hModule)  ; It is best to unload the DLL after using it (or before the script exits).
exitapp

;;;;;;;;;;; POWERMATE EVENT CREATOR ;;;;;;;;;;;

KnobDown:

;Enable event on knobup
bTriggerPressEvent := 1

t1 := dllcall("GetTickCount", "UInt")

return

KnobUp:

;Get time
t2 := dllcall("GetTickCount", "UInt")
iDuration := t2 - t1

if (bTriggerPressEvent) {
	
	if (iDuration < iCriticalPoint)
		gosub eShortPress
	else
		gosub eLongPress
}

return

KnobClock:
gosub eClockwise
return

KnobCounter:
gosub eCounterclockwise
return

KnobClockPressed:

;Discard event on KnobUp
bTriggerPressEvent := 0

gosub eClockwisePressed
return

KnobCounterPressed:

;Discard event on KnobUp
bTriggerPressEvent := 0

gosub eCounterclockwisePressed
return

;;;;;;;;;;; POWERMATE EVENTS ;;;;;;;;;;;

eShortPress:
sendinput This is a short press.{Enter}
return

eLongPress:
sendinput This is a long press.{Enter}
return

eClockwise:
sendinput This is a clockwise turn.{Enter}
return

eCounterclockwise:
sendinput This is a counter-clockwise turn.{Enter}
return

eClockwisePressed:
sendinput This is a clockwise turn while pressed.{Enter}
return

eCounterclockwisePressed:
sendinput This is a counter-clockwise turn while pressed.{Enter}
return

I hope you guys like it!

Seung-Young
  • Guests
  • Last active:
  • Joined: --
I was searching for a controlling program for my powermate.
Your script goes well along with my purpose.
Didn't you find solutions to control the LED yet?
I hope you solve the problem soon.
Thanks.

TheGood
  • Members
  • 589 posts
  • Last active: Mar 22 2014 03:22 PM
  • Joined: 30 Jul 2007
I'm glad you like it!
Unfortunately no, I never found a way to control the LED. I don't mind it anyways, since for me it was more of a cool factor, than actually having any use.

le-mec
  • Members
  • 51 posts
  • Last active: Dec 15 2011 02:30 AM
  • Joined: 24 Dec 2006
Sorry for reviving this old thread, but I found some stuff that might help us out, like a Powermate.dll that autohotkey might be able to tap into.

<!-- m -->http://www.conceptua... ... ode/page/2<!-- m -->

I was able to download the source code for it and to compile the DLL (I also had to download the WDK from microsoft's site), but the only problem is that the TestApp won't load because the project file is too old for my currently installed MSVC Express version to convert.

Still, it seems like it's worth pursuing.

EDIT: Looks like I need to get C# - I only have C++.

EDIT2: I was able to compile the TestApp. Unfortunately there are no Win7x64 drivers, so I can't test it

beeski
  • Members
  • 158 posts
  • Last active: Mar 06 2016 08:21 PM
  • Joined: 22 Sep 2011

this is good news, i too share the OP's sentiment (griffin's native frontend software is buggy, and officially not even supported on windows 7 and later).

 

i am planning on trying the script; i do however use two griffins at once...

 

anyone has tried to adapt it for two units?



beeski
  • Members
  • 158 posts
  • Last active: Mar 06 2016 08:21 PM
  • Joined: 22 Sep 2011

(double post)