There are a lot of different ways to count the pulses. After trying a number of different approaches I ended up using two threaded callback functions, one to catch the falling edge of a pulse, and one to catch the rising (end) of the pulse. This made it simple to time the pulses and the gaps, so that the program can filter out noise (pulses that are too short, or too long) and catch the 220ms gap between the letters and numbers. I'm using the soco library functions to control the sonos.
I had to learn Python for this project, apologies for my hacky code. The code is on github. I still have a lot of print statements for debugging the code. I also wrote a few programs just to figure out what was coming out of the wallbox, to get the timings right on reading the pulses (not on github yet).
The current version is not object based - there is a fork called OOPS that is a development version that I am converting to OOP, along with a bunch of improvements, such as running the volume control in a seperate thread.