perryn / blinky

blinky helps you see the light - plug and play set up for build lights
MIT License
67 stars 27 forks source link

Webmail Notifier knock-off #3

Open Aupajo opened 11 years ago

Aupajo commented 11 years ago

Hey there. I have a Webmail Notifier that I think might be a knock-off, and I was wondering if you could help me add support for it.

1.9.3-p362 :002 > blinky = Blinky.new
Blinky::NoSupportedDevicesFound: Blinky was unable to find a supported device 
The devices I did find were:
[#<LIBUSB::Device 250/1 05ac:8006 ? ? ? (Hi-speed Hub with single TT)>,
 #<LIBUSB::Device 253/1 05ac:8006 ? ? ? (Hi-speed Hub with single TT)>,
 #<LIBUSB::Device 253/2 0424:2513 ? ? ? (Hi-speed Hub with multiple TTs)>,
 #<LIBUSB::Device 250/2 0424:2513 ? ? ? (Hi-speed Hub with multiple TTs)>,
 #<LIBUSB::Device 250/3 05ac:850a ? ? ? (Interface Association Descriptor)>,
 #<LIBUSB::Device 253/3 05ac:8404 ? ? ? (MassStorage SCSI Bluk-Only)>,
 #<LIBUSB::Device 250/5 05ac:024c Apple Inc. Apple Internal Keyboard / Trackpad ? (HID (01,01), HID (00,00), HID (01,02))>,
 #<LIBUSB::Device 253/4 1294:1320 MAIL MAIL ? (HID (00,00))>]

    from /Users/pete/.rvm/gems/ruby-1.9.3-p362/gems/blinky-0.0.10/lib/blinky/light_factory.rb:14:in `detect_lights'

Had a bit of a poke about:

1.9.3-p362 :007 > mail = USB.devices[7]
 => #<LIBUSB::Device 253/4 1294:1320 MAIL MAIL ? (HID (00,00))> 
1.9.3-p362 :008 > mail.id
mail.idProduct  mail.idVendor 
1.9.3-p362 :008 > mail.idVendor
 => 4756 
1.9.3-p362 :009 > mail.idProduct
 => 4896 

The idVendor and idProduct don't match inside recipes.rb:

recipe DreamCheeky::WebmailNotifier,  {:usb_vendor_id => 0x1d34, 
                                       :usb_product_id => 0x0004, 
                                       :description => "Dream Cheeky Webmail Notifier"}

I don't have any idea how to do this, but I'm willing to invest time to find out how. If you could give me a couple of tips, it would be much appreciated.

Aupajo commented 11 years ago

Found a driver in Python: http://svn3.xp-dev.com/svn/USBEmailNotifier/

Might see if I can get this to work and submit a PR.

Aupajo commented 11 years ago

In the Python code, this is all that appears to be needed:

import sys
from pywinusb import hid

COLORS = {
        'BLANK': 0,
        'GREEN': 1,
        'RED': 2,
        "BLUE": 3,
        "AQUA": 4,
        "YELLOW": 5,
        "VIOLET": 6,
        "WHITE": 7}

# color is passed in as-is
def setLEDColor(color):
    global Device
    report = Device.find_output_reports()[ 0 ]
    report[ 0xff000001 ][ 0 ] = color
    report.send()

My module looks like this at the moment:

module Blinky
  module DX
    module WebmailNotifier
      COLOURS = { off: 0,
               green: 1,
                 red: 2,
                blue: 3,
                aqua: 4,
              yellow: 5,
              violet: 6,
               white: 7 }

      def success!
        colour!(:green) 
      end

      def failure!
        colour!(:red) 
      end

      def building! 
        colour!(:yellow) 
      end

      def warning!
        colour!(:violet) 
      end

      def off!
        colour!(:off)
      end

      def init
      end

      def colour!(key)
        colour_value = COLOURS[key]
        # @handle.usb_control_msg(request_type, request, value, index, bytes, timeout) 
      end

    end     
  end
end

How do you go about finding what values to pass into the @handle.usb_control_msg?

perryn commented 11 years ago

figuring out what values to pass can be a bit of an arcane art - I'd try leaving the values as they are in the Dream Cheeky plugin and just change what you pass as 'data'. For the 'data' try passing your colour number as hex (eg '\x01' etc) and padding out the rest with 0's

let me know how you get on.

Aupajo commented 11 years ago

Thanks. I sat down with someone more knowledgeable than me the other night to start to go through it. No luck yet, but I've got some starting points to go on.

If you're like me, you probably have an aversion to indefinitely open issues on GitHub, so if I haven't posted in a week, feel free to close this issue.

perryn commented 11 years ago

If you do get it working, please contribute the recipe back! :)

Aupajo commented 11 years ago

@perryn Will do. Have successfully managed to get it working on Windows. Keep running into issues with Mac OS X, but I think they're related to my setup rather than the code.

perryn commented 11 years ago

Hey

I ordered one of your knock offs so I can help check that it works on OSX if you send a pull request with the recipe :)

cheers Perryn

Aupajo commented 11 years ago

Awesome, thank you! I'll send a PR when I can. I left the working code uncommitted on a friend's computer, so it might be a few days until I can retrieve it.

perryn commented 11 years ago

Hey - did you manage to get that code? I'm trying to do it myself now, so anything you have would be a help. Don't worry about a PR, just paste it here if you like.

Aupajo commented 11 years ago

I think my work-in-progress Ruby script got accidentally scrapped, but what I basically used was something similar to https://gist.github.com/Aupajo/0627e30ac436bd1af5f0, just translated into RubyUSB.

Aupajo commented 11 years ago

Also worth noting that this script works in Windows, but I could only get one colour: blue, to varying degrees.

Aupajo commented 11 years ago

Actually, sorry, I think I've linked to the wrong script there. Let me see if I can find the proper one...

Edit: Just spent 45 minutes looking to no avail. Sorry :/

maks commented 11 years ago

@Aupajo I'm afraid you may have the same crappy knock off as me, mine has the same 1294:1320 MAIL MAIL USB ID that you posted. If thats the case, what you will find is that the board bizarrely has three blue leds on it instead of a blue/red/green set so you will only ever be able to get blue, just varying brightness depending on how many of the 3 are on at once. Apparently these knock-offs are pretty rife on ebay.

On the plus side the code to make them work is pretty straight forward and you will find the c code from: https://github.com/andmarios/ledcontroller-3bit works fine, except of course that instead of getting different colours all you will get is 1,2 or 3 blue leds light up at the same time. BTW if you look in that code, the only important bits are: https://github.com/andmarios/ledcontroller-3bit/blob/master/main.c#L132-L137 and https://github.com/andmarios/ledcontroller-3bit/blob/master/main.c#L141

though I've actually found on the units I have that the only the first byte is used and the remaining bytes don't need to be ox4, their values are ignored. Of course the guy who wrote that code must have had a unit which did actually have 3 diff coloured LEDs on his board, so maybe with his micro-controller those values do need to be 0x4. One last thing for posterity, I was able to make out the model of micro controller to be a: Sonix SN8P2203 though I doubt thats much use as reading its manual suggests its the firmware implementation burned in its ROM that actuallt determines most of how it responds over usb.

Aupajo commented 11 years ago

@maks Thanks, this is awesome!

maks commented 11 years ago

@Aupajo I found it rather less than awesome after wasting several hours on this yesterday, but I wanted to post it here so that at least others might benefit and save themselves some aggravation with these. For the record this is the defective all-Blue units that I got stuck with.

Aupajo commented 11 years ago

I tried running ledcontroller-3bit on OS X, but I get the output:

$  ./ledcontroller blue
error: Operation timed out

I've ported the code over to Ruby at Aupajo/blinky webmail_notifier.rb, but I get:

$  irb
1.9.3-p362 :001 > require './lib/blinky'; Blinky.new.light.success!
LIBUSB::ERROR_NOT_FOUND: LIBUSB::ERROR_NOT_FOUND in libusb_submit_transfer
    from /Users/pete/.rvm/gems/ruby-1.9.3-p362/gems/libusb-0.2.2/lib/libusb/constants.rb:46:in `raise_error'
    from /Users/pete/.rvm/gems/ruby-1.9.3-p362/gems/libusb-0.2.2/lib/libusb/transfer.rb:135:in `submit!'
    from /Users/pete/.rvm/gems/ruby-1.9.3-p362/gems/libusb-0.2.2/lib/libusb/transfer.rb:162:in `submit_and_wait!'
    from /Users/pete/.rvm/gems/ruby-1.9.3-p362/gems/libusb-0.2.2/lib/libusb/dev_handle.rb:338:in `interrupt_transfer'
    from /Users/pete/.rvm/gems/ruby-1.9.3-p362/gems/libusb-0.2.2/lib/libusb/compat.rb:331:in `usb_interrupt_write'
    from /Users/pete/Workspace/forkful/blinky/lib/device_recipes/dx/webmail_notifier.rb:41:in `change!'
    from /Users/pete/Workspace/forkful/blinky/lib/device_recipes/dx/webmail_notifier.rb:14:in `success!'
    from (irb):1

Not sure where to go from here. Might play around a bit more.

maks commented 11 years ago

Sorry @Aupajo I should have said I only got it working on Linux.

I don't know anything about how USB device permissions are handled on OSX, but in Linux desktop distros, udev is is sued to manage devices and in order to be able to write to the device without having to be root I needed to add a udev rule (in /etc/udev/rules.d/80-usblights.rules):

SUBSYSTEM=="usb", ATTR{idVendor}=="1294", ATTR{idProduct}=="1320", MODE="0600", OWNER="maks"

Also in Linux there is a handy utility lsusb with a -v option to give you detailed information about the usb devices attached. Using that I was able to confirm that the device had a second "interrupt" end point that took a max of 5 bytes, here's the snippet from that output:

Endpoint Descriptor:
        bLength                 7
        bDescriptorType         5
        bEndpointAddress     0x02  EP 2 OUT
        bmAttributes            3
          Transfer Type            Interrupt
          Synch Type               None
          Usage Type               Data
        wMaxPacketSize     0x0005  1x 5 bytes
        bInterval              10

Hopefully you will be able to translate this across to whatever equivalent tools OSX has for this and it might help you track down why its not working for you.

Aupajo commented 11 years ago

Thanks again, @maks. I'm new to all this, so it's really helpful.

maks commented 11 years ago

@Aupajo happy to help where I can, just don't know anything at all about system level things on OSX. Perhaps @perryn can help you more with the OSX specific side of things, based on the information in the original ledcontroller C code and what I posted above.

perryn commented 11 years ago

Unfortunately I don't actually know a huge amount about USB. Perhaps together we can figure this out.

@maks, the python code seems to be sending data via an 'output report', whereas your code is using an 'out interrupt'. I'm having trouble finding something that explains the difference?