• Rdio and Linux Part II

    For whatever reason, my original rdio work-around (from this post) didn't work when I upgraded to Fedora 22. I'm sure it has something to do with the way Gnome 3.16 is handling window events, but I'm not spending the time to actually figure it out, because I've got a functiong work-around that is actually kind of cooler anyway.

    I changed my .xbindkeys to this

    "$(grep '^Exec' rdio.desktop | tail -1 | sed 's/^Exec=//' | sed 's/%.//')"
            Mod2 + XF86AudioMedia
    "sleep 0.3 && ~/bin/mediacon play"
            Mod2 + XF86AudioPlay
    "sleep 0.3 && ~/bin/mediacon prev"
            Mod2 + XF86AudioPrev
    "sleep 0.3 && ~/bin/mediacon next"
            Mod2 + XF86AudioNext

    All of the events have been moved into a script file that controls the actual events. This was done because I added a bit more logic to the events, and it was difficult to keep all that readable in the file. The other important thing to note is that all of the commands here are prefixed with a sleep. I had to do this because the events were firing too quickly and I had to slow that down just a tiny bit. I started with sleep 0.1, which worked when I used windowactivate in the script, but needed an additional time when I used windowfocus. I'm not really sure how the timing here differed when the commands in the script were called, but for whatever reason, this version is working.

    The only other thing is my new mediacon script which is this:

    CUR=$(xdotool getactivewindow)
    xdotool windowfocus --sync $(xdotool search --limit 1 --name Rdio)
    if [ $1 == "play" ]; then
            xdotool key space
    elif [ $1 == "prev" ]; then
            xdotool key Left
    elif [ $1 == "next" ]; then
            xdotool key Right
    xdotool windowfocus $CUR

    This is grabbing the id of the current window, activating the rdio window, sending whatever command you bound the key to, and then returning focus back to the window you started from.

  • Relay Update

    I am now waiting for the 5-gang box from homedepot to get started on the actual build. I'm a little concerned with the overall size of the project with the box I've got, but I already tried a 4-gang box and it wasn't really big enough for the guts plus the switch, fuse, and signal cables.

    I wired up a test circuit and was able to verify that I know how to wire this thing for mains power. The test was a success.

    I ran the following in an interactive python session:

    import Adafruit_BBIO.GPIO as GPIO
    GPIO.setup("P8_10", GPIO.OUT)
    GPIO.output("P8_10", GPIO.HIGH
    GPIO.output("P8_10", GPIO.LOW)

    Something else

  • Aquarium Controller Update


    It's been a while since I've updated this blog, but there has actually been quite a bit happening and hopefully I'll be able to actually detail out the steps of the things I've worked on, but I'll talk about the things I have accomplished so far

    Overall Design

    My design is going to use a single control module that expands with extra pods to handle the other tasks. So there will be probes, power, and possibly motors (for auto feeders or dosing). This made sense to me because I'm not going to be able to afford to do everything at once, and it will also allow me to deploy portions of it while I'm designing the rest.

    As it turns out (though I didn't know it when I started down this path) Neptune Systems has a similar design in their Apex line. So I guess I'm on the right path since someone else has already done it :)

    Temperature Sensing

    One of the key, basic things I wanted was temperature sensing. I was able to get the Dallas 1-wire (DS18B20) working, though at this point just in a test capacity. You can see my temps.py code.

    The 1-wire interface generates a unique ID for each temperature sensor. In the code linked above, they are hard-coded. I am rewriting the code now to scan through the directory and pick up whatever is attached so that it will eventually just be a process like:

    1. Plug in a device
    2. Assign it to a location

    The 1-wire temperature modules (in parasitic mode) need 3 wires (2 for power and one for data). Due to this, I decided to use rj11 phone wires. The connectors are small, readily available, and can be split so that I can use one connector on the controller side and have many sensors on the front side. Though I only plan on using 2 for my installation, it should be extendable up to whatever 1-wire protocol supports.

    In the process of moving my breadboard design over to a soldered perfboard, I managed to miss a connection. So I need to fix that and then I should have temperature measurements working.


    Another key component of this whole solution is controlling power, so getting a bunch of relays to control outlets was the best option here. I was looking at components and was prepared to build the circuits myself, especially because I thought I was limited to 3V coil relays. As it turns out, the BeagleBone does have 5V on the board, so I ended up getting this SainSmart 8 Channel Relay.

    As soon as I figure out how to make fancy diagrams I'll show how I got this connected. In the mean time, I do have a youtube video showing my relaytest.py in action.

  • A New Year...New Projects

    So it's been quite a while since I have posted anything here. I've been quite busy with "life" things, and also a side project or two. For Christmas, I got new lights for my aquarium. So that has spun up a new project of restocking the aquarium and breathing life back into my love of saltwater tanks.

    For a really long time, I have wanted to get an aquarium controller. These are things that can control whatever aspect of the aquarium you need. Things like lighting and temperature are simple ones, but you can get even more complicated with wave generators, pH metering, dosing, top off, etc. In my system administrator mind, anything that can do the work for me is that much better.

    Basic controllers cost around $100 and go up to many hundreds of dollars, and then that doesn't include the additional probes or devices you need to buy. So it can get really expensive really quickly. So I thought "hey! I can program stuff, I just need some way to interact with the hardware". And that brings me to my new project.

    The Beaglebone

    Why did I choose this over arduino, or rasberry pi, or any of the other similar controllers on the market? Price was a factor, I got this for $40 at my friendly neighborhood Microcenter. It is also built with the open source mentality at heart. The biggest factor is that, out of the box, this just runs linux. Adafruit provides some python libraries that make interacting with the pins through Python pretty easy too. So I am looking forward to getting going with this. So far I have only booted the thing. I still need to acquire some basic breadboard tools and random electronics to start experimenting with it. Definitely looking forward to posting more stuff as I discover it.

  • Python Printer Peril

    I remembered a while back that there was this little PERL utility to set the status message on HP printers using the printer's job language. I decided that I wanted to try to do that with Python, and this is what I came up with:

    #!/usr/bin/env python
    import socket
    import sys
    def sendcmd(MESSAGE, IP, PORT=9100):
        """Opens the socket to the printer and sends the strings"""
        s = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
        s.connect((IP, PORT))
        s.send("@PJL RDYMSG DISPLAY=\""+MESSAGE+"\"\n")
    if len(sys.argv) < 2 or len(sys.argv) > 3:
        sys.exit('Usage: %s "MESSAGE" IPADDRESS [PORT]' % sys.argv[0])
    elif len(sys.argv) == 3:
        sendcmd(sys.argv[1], sys.argv[2])
        sendcmd(sys.argv[1], sys.argv[2], sys.argv[3])

    This actually turned out to be pretty simple. There are really only 2 parts: The socket part that sends the commands, and the sys.argv stuff that grabs the command line options and passes it to the sendcmd() function. I added an option to specify a port, but if none is specificed, it will default to 9100. So then all you need to do is:

    ./hpprint.py "Your crafty message"

  • Hosting Experiment

    I am experimenting with Pelican to create the web page content. I was using wordpress, and while it is amazingly simple to setup and is also amazingly powerful in the things it can do; it is also a pain to maintain and is written in PHP. That became a problem when I tried to serve it behind PHP-FPM on nginx. I couldn't get all the pieces to work. So in true sysadmin style I said "screw it!" and tried something completely different :)

  • More office365 Annoyances

    I have been using IQTell as my todo list management and email client.  Within the past month or so, they added the ability to handle calendar invites, which I thought was completely awesome.  Except it didn't work on Office365.  Well, it worked as long as the appointment was sent from Gmail or a phone, but not from outlook.  Instead I got a link that forced me to login to Office365 to download the iCal content.

    When the account was added to IQTell, it was added as an Exchange account.  Which, by default, checks via IMAP.  It turns out if you override the default and instead connect via Exchange Web Services the calendar appointments would work.  Awesome!  Except, it didn't always work, because this utilizes API calls, of which there is some arbitrary, unpublished limit.  So IQTell was intelligently adding wait time to the requests so the API calls would work.  That worked, but made the connections horribly slow.

    IQTell support then linked me to some seemingly useful documentation: And after fiddling around with an expired password and the insanity that is PowerShell, I managed to get the settings set.  Except, according to the documentation "ImapForceICalForCalendarRetrievalOption=False means all meeting requests are in iCal format".  Which is incorrect.  ...ForceIcal...=True, does in fact force iCal as it sounds contrary to what the docs say.

    So I get that far and it still didn't work.  In Microsoft wisdom,  setting these options doesn't mean anything until you tell it to "ignore the defaults"

    I went ahead and set the values for pop and IMAP.  The whole string that actually worked was:

    Set-CASMailbox –identity user@domain.com –PopUseProtocolDefaults:$FALSE –ImapUseProtocolDefaults:$FALSE –PopForceICalForCalendarRetrievalOption:$TRUE –ImapForceICalForCalendarRetrievalOption:$TRUE

    While it wasn't actually their problem, IQTell support was able to get me to answer that worked.

  • Rdio and Linux

    I have been using Rdio for about a year now.  While it has some holes with older music, all-in-all I am very happy with the service.

    Rdio uses a very capable web player so you can play your music in your browser.  That's perfect, however the one thing missing is support for multimedia keys.  After searching around for a Linux app that supported multimedia keys, I discovered that I could roll my own very easily using chrome, xbindkeys, and xdotool.

    xbindkeys and xdotool

    These two apps are the heart of what makes this work.  xbindkeys grabs the input keys, and executes xdotool which let's us operate on specific windows and send key strokes to them.  So they both need to be installed first.  I am using Fedora, but I presume these exist as packages in whatever Linux you are using.

    sudo yum -y install xbindkeys xdotool


    The first thing is to create an "application shortcut" for chrome.  Do this by doing the following:

    1. Open Chrome
    2. Browse to http://rdio.com
    3. Click the tool icon thingy (three lines in the upper-right)
    4. Click Tools
    5. Click "Create Application Shortcuts"
    6. Choose where you want the shortcut to go.  Really we are just looking for it to create the .desktop entry so that it will show up in Gnome's overlay mode so the default Desktop is all that's needed.

    At this point there is a perfectly functional webpage acting like an application.  It should run if you hit the SUPER key and type rdio.

    Xbindkeys Config

    Below is my current config file.  In order to get the keys to send, you need to run

    xbindkeys -mk

    This will run xbindkeys in a window, make sure that window is active and hit the key you want to bind.  The code for that key will then show in the console.  Then you just write the config with the command that you want to be run, followed by the key (that we grabbed before).  This is where xdotool comes in.  We are going to search for a window named Rdio, and send the keys that perform the multimedia functions.  So for example, when we hit the media key Play/Pause, it will send a space to the window named Rdio.

    #keystate_numlock = enable
    #keystate_capslock = enable
    #keystate_scrolllock= enable
    #Media keys for my fake rdio app (chrome --app)
    "$(grep '^Exec' rdio.desktop | tail -1 | sed 's/^Exec=//' | sed 's/%.//')"
        Mod2 + XF86AudioMedia
    "xdotool key --window $(xdotool search --limit 1 --name Rdio) space"
        Mod2 + XF86AudioPlay
    "xdotool key --window $(xdotool search --limit 1 --name Rdio) Left"
        Mod2 + XF86AudioPrev
    "xdotool key --window $(xdotool search --limit 1 --name Rdio) Right"
        Mod2 + XF86AudioNext

    Gnome Configuration

    By default, Gnome is going to have the keys bound to some multimedia key default.  And they are probably the same ones you are trying to bind.  So you have to disable the Gnome keybindings so xbindkeys can grab them instead.  To do this:

    • Go to settings
      • Either by clicking the icons in the upper-right hand side and clicking the tools icon
      • or...hit the SUPER key to go to overlay mode and search for settings
    • Choose the keyboard under Hardware
    • Click the Shortcuts tab
    • Click "Sound and Media"
    • Go to each key you want to grab from xbindkeys and when it prompts you for "new accelerator" you can either hit Backspace to clear the setting.

    Success! (hopefully)

    At this point you should have a fully functional web app that responds to multimedia keys.

  • MySQL Multi-source part II

    There seems to be a major issue with what I was planning to do using multi-source replication and what the developers seem to expect people to do.  I believe the problem is summed up in "This feature does not do any additional conflict detection and resolution" (https://dev.mysql.com/worklog/task/?id=1697)

    The basic problem is that the expectation is replicated databases will all have different names.  Which would have certainly been the case in previous replication methods because master/slave was one to one and there could only be one master per host.  However multi-source has the implication that there may be overlapping database names.  But thanks to what I believe is encompassed in the above quote, there is no consideration on the slave side to deal with that.

    There is a concept of rewriting database names, but that is a global configuration which still won't work in this scenario.  It would need to support the "for channel=" command, which currently it does not.

    So multi-source replication is pretty cool, but doesn't work for my use case.  At least not at this point.

  • MySQL Multi-source replication

    Following this post (http://www.mysqlperformanceblog.com/2013/10/02/mysql-5-7-multi-source-replication/) I was able to get multi-sourced replication working.  And the concept is pretty cool.  The plan was to have a bunch of MySQL instances replicated to a single box for backup and reporting purposes.  The problem is that multi-source replication works basically like regular replication and each table needs to be unique.

    The setup I'm working with has multiple instances that are all identical as far as layout goes, only the data is different.

    Next step is checking out MariaDB replication.

Page 1 / 2 »