A dated project report

Just found a draft of an electronics project report of mine, made in 2009:

After the construction of the Smapler, I came away with no soldering station. Dlade kept it, he liked it that much. So a few days after that, I went and bought a station kind of like it, at Electrokit in Malmö. I went there primarily to pick up a Motor Shield circuit board.

The kind shop clerk helped me understand and pick up all the components on the partlist I had included in my order. He was there on overtime, and still helped me. Note to non-electronics folk: A partlist is the textfile exported from the circuit construction application. It tells you what the component labeled R3 in the diagram should be in real life. They look cryptic at first glance, but they’re the very essence of informational economy. Tufte would be pleased.

Me and Dlade had been violent to an old inkjet printer, and gutted it for 2 motors, one DC and one stepper. The stepper motor I have here on my desk. Found its datasheet today! Sometimes it’s a gamble finding Asian manufacturers’ documentation, but it went well. Now I know that it’s a 24v stepper motor.

This was some time ago. I fixed a bug in the partlist (one component was listed with a wrong character in the name…)

The world has moved on since this report.

Dlade and I were not working together at that point, but we have worked together as colleagues for a full year between this report and now. We are no longer colleagues.

The local electronics shop, Electrokit, is no longer in the middle of a residential area, but in a far-away industrial zone. That’s sad; people I know used to come there many times a week. This past year I have been to their new shop exactly once. Freezing headwind bike rides discourage even the most motivated buyers.

My town needs more old-fashioned hardware stores. This image evokes the fantasy of a small-business shop. Morguefile user jari snapped this:

A fantasy. OK. Nostalgia-for-times-I-didn’t-have-to-live-through now put aside.

As I built the motor control board, I ran into a circuit description problem. Some of the values were wrong, and I never got that board to run my motors. I was told my the constructor of the circuit board that my version was an in-between one, and that it could never work. That deflated my enthusiasm for motor control.

As I said, the world has moved on, and now there are new versions of that circuit board.

Close and re-open tickets from tests: Fogbugz PHPUnit TicketListener

When working with unit testing in PHP, you might already be using my favorite PHP unit testing tool PHPUnit. If you are, perhaps you’ve heard of the TicketListener interface. No? Then read on.

Raphael Stolt closes GitHub issues from his PHPUnit tests. Which is cool. He inspired me.

I wrote some code. You can now do the same from FogBugz. (FogBugz is a commercial project management system that includes bug tracking.)

To install this, you can now just head over to the PHPUnit PEAR channel:

pear install phpunit/PHPUnit_TicketListener_Fogbugz

Steps to do it

Have a nice failing test that can re-open your ticket.


< ?
class ExampleClassTest extends PHPUnit_Framework_TestCase
{
    /**
     * @ticket 2
     * @test
     */
    function example() {
        $this->assertTrue(FALSE);
    }

}

Please note the annotation documentation block above the test method: it denotes that the method is a test, and that the issue with ID 2 should be re-opened if this test should ever fail.

Then, set up a continuous integration-specific PHPUnit configuration file (oh, why? Well, this extra checking against the bugs system takes time, and we don’t want to burden our test suite with that):


<phpunit>
  <listeners>
    <listener class="PHPUnit_Extensions_TicketListener_Fogbugz" 
              file="../olleolleolle-phpunit/PHPUnit/Extensions/TicketListener/Fogbugz.php">
      <arguments>
        <string>username@xstream.dk</string>
        <string>secretpassword</string>
        <string>http://fogbugz.example.org/api.php</string>
        <boolean>false</boolean>
        <boolean>true</boolean>
        <string>Fixed</string>
        <string>Started</string>
      </arguments>
    </listener>
  </listeners>
</phpunit>

Run the PHPUnit test (or, more realistically, your whole test suite) with the specific configuration, like so:

phpunit -ddisplay_errors=1 --configuration fogbugzlistener.xml ExampleClassTest

A found list of reserved words for SQL

ABS ABSOLUTE ACCESS ACQUIRE ACTION ADA ADD ADMIN AFTER AGGREGATE ALIAS
ALL ALLOCATE ALLOW ALTER AND ANY ARE ARRAY AS ASC ASENSITIVE ASSERTION
ASUTIME ASYMMETRIC AT ATOMIC AUDIT AUTHORIZATION AUX AUXILIARY AVG
BACKUP BEFORE BEGIN BETWEEN BIGINT BINARY BIT BIT_LENGTH BLOB BOOLEAN
BOTH BREADTH BREAK BROWSE BUFFERPOOL BULK BY
CALL CALLED CAPTURE CARDINALITY CASCADE CASCADED CASE CAST CATALOG
CCSID CEIL CEILING CHAR CHAR_LENGTH CHARACTER CHARACTER_LENGTH CHECK
CHECKPOINT CLASS CLOB CLOSE CLUSTER CLUSTERED COALESCE COLLATE
COLLATION COLLECT COLLECTION COLLID COLUMN COMMENT COMMIT COMPLETION
COMPRESS COMPUTE CONCAT CONDITION CONNECT CONNECTION CONSTRAINT
CONSTRAINTS CONSTRUCTOR CONTAINS CONTAINSTABLE CONTINUE CONVERT CORR
CORRESPONDING COUNT COUNT_BIG COVAR_POP COVAR_SAMP CREATE CROSS CUBE
CUME_DIST CURRENT CURRENT_COLLATION CURRENT_DATE
CURRENT_DEFAULT_TRANSFORM_GROUP CURRENT_LC_PATH CURRENT_PATH
CURRENT_ROLE CURRENT_SERVER CURRENT_TIME CURRENT_TIMESTAMP
CURRENT_TIMEZONE CURRENT_TRANSFORM_GROUP_FOR_TYPE CURRENT_USER CURSOR
CYCLE
DATA DATABASE DATALINK DATE DAY DAYS DB2GENERAL DB2SQL DBA DBCC DBINFO DBSPACE
DEALLOCATE DEC DECIMAL DECLARE DEFAULT DEFERRABLE DEFERRED DELETE
DENSE_RANK DENY DEPTH DEREF DESC DESCRIBE DESCRIPTOR DESTROY
DESTRUCTOR DETERMINISTIC DIAGNOSTICS DICTIONARY DISALLOW DISCONNECT
DISK DISTINCT DISTRIBUTED DLNEWCOPY DLPREVIOUSCOPY DLURLCOMPLETE
DLURLCOMPLETEONLY DLURLCOMPLETEWRITE DLURLPATH DLURLPATHONLY
DLURLPATHWRITE DLURLSCHEME DLURLSERVER DLVALUE DO DOMAIN DOUBLE DROP
DSSIZE DUMMY DUMP DYNAMIC
EACH EDITPROC ELEMENT ELSE ELSEIF END END-EXEC EQUALS ERASE ERRLVL
ESCAPE EVERY EXCEPT EXCEPTION EXCLUSIVE EXEC EXECUTE EXISTS EXIT EXP
EXPLAIN EXTERNAL EXTRACT
FALSE FENCED FETCH FIELDPROC FILE FILLFACTOR FILTER FINAL FIRST FLOAT
FLOOR FOR FOREIGN FORTRAN FOUND FREE FREETEXT FREETEXTTABLE FROM FULL
FUNCTION FUSION
GENERAL GENERATED GET GLOBAL GO GOTO GRANT GRAPHIC GROUP GROUPING
HANDLER HAVING HOLD HOLDLOCK HOST HOUR HOURS
IDENTIFIED IDENTITY IDENTITY_INSERT IDENTITYCOL IF
IGNORE IMMEDIATE IMPORT IN INCLUDE INCREMENT INDEX INDICATOR INITIAL
INITIALIZE INITIALLY INNER INOUT INPUT INSENSITIVE INSERT INT INTEGER
INTEGRITY INTERSECT INTERSECTION INTERVAL INTO IS ISOBID ISOLATION
ITERATE
JAR JAVA JOIN
KEY KILL
LABEL LANGUAGE LARGE LAST LATERAL LC_CTYPE LEADING LEAVE LEFT LESS
LEVEL LIKE LIMIT LINENO LINKTYPE LN LOAD LOCAL LOCALE LOCALTIME
LOCALTIMESTAMP LOCATOR LOCATORS LOCK LOCKSIZE LONG LOOP LOWER
MAP MATCH MAX MAXEXTENTS MEMBER MERGE METHOD MICROSECOND MICROSECONDS
MIN MINUS MINUTE MINUTES MOD MODE MODIFIES MODIFY MODULE MONTH MONTHS
MULTISET
NAME NAMED NAMES NATIONAL NATURAL NCHAR NCLOB NEW NEXT NHEADER NO
NOAUDIT NOCHECK NOCOMPRESS NODENAME NODENUMBER NONCLUSTERED NONE
NORMALIZE NOT NOWAIT NULL NULLIF NULLS NUMBER NUMERIC NUMPARTS
OBID OBJECT OCTET_LENGTH OF OFF OFFLINE OFFSETS OLD ON ONLINE ONLY
OPEN OPENDATASOURCE OPENQUERY OPENROWSET OPENXML OPERATION
OPTIMIZATION OPTIMIZE OPTION OR ORDER ORDINARILITY OUT OUTER OUTPUT
OVER OVERLAPS OVERLAY
PACKAGE PAD PAGE PAGES PARAMETER PARAMETERS PART PARTIAL PARTITION
PASCAL PATH PCTFREE PCTINDEX PERCENT PERCENT_RANK PERCENTILE_CONT
PERCENTILE_DISC PIECESIZE PLAN POSITION POSTFIX POWER PRECISION PREFIX
PREORDER PREPARE PRESERVE PRIMARY PRINT PRIOR PRIQTY PRIVATE
PRIVILEGES PROC PROCEDURE PROGRAM PSID PUBLIC
QUERYNO
RAISERROR RANGE RANK RAW READ READS READTEXT REAL RECONFIGURE RECOVERY
RECURSIVE REF REFERENCES REFERENCING REGR_AVGX REGR_AVGY REGR_COUNT
REGR_INTERCEPT REGR_R2 REGR_SLOPE REGR_SXX REGR_SXY REGR_SYY RELATIVE
RELEASE RENAME REPEAT REPLICATION RESET RESIGNAL RESOURCE RESTORE
RESTRICT RESULT RETURN RETURNS REVOKE RIGHT ROLE ROLLBACK ROLLUP
ROUTINE ROW ROW_NUMBER ROWCOUNT ROWGUIDCOL ROWID ROWNUM ROWS RRN RULE
RUN
SAVE SAVEPOINT SCHEDULE SCHEMA SCOPE SCRATCHPAD SCROLL SEARCH SECOND
SECONDS SECQTY SECTION SECURITY SELECT SENSITIVE SEQUENCE SESSION
SESSION_USER SET SETS SETUSER SHARE SHUTDOWN SIGNAL SIMILAR SIMPLE
SIZE SMALLINT SOME SOURCE SPACE SPECIFIC SPECIFICTYPE SQL SQLCA
SQLCODE SQLERROR SQLEXCEPTION SQLSTATE SQLWARNING SQRT STANDARD START
STATE STATEMENT STATIC STATISTICS STAY STDDEV_POP STDDEV_SAMP STOGROUP
STORES STORPOOL STRUCTURE STYLESUBPAGES SUBSTRING SUCCESSFUL SUM
SYMMETRIC SYNONYM SYSDATE SYSTEM SYSTEM_USER
TABLE TABLESPACE TEMPORARY TERMINATE TEXTSIZE THAN THEN TIME TIMESTAMP
TIMEZONE_HOUR TIMEZONE_MINUTE TO TOP TRAILING TRAN TRANSACTION
TRANSLATE TRANSLATION TREAT TRIGGER TRIM TRUE TRUNCATE TSEQUAL TYPE
UID UNDER UNDO UNION UNIQUE UNKNOWN UNNEST UNTIL UPDATE UPDATETEXT
UPPER USAGE USE USER USING
VALIDATE VALIDPROC VALUE VALUES VAR_POP VAR_SAMP VARCHAR VARCHAR2
VARIABLE VARIANT VARYING VCAT VIEW VOLUMES
WAITFOR WHEN WHENEVER WHERE WHILE WIDTH_BUCKET WINDOW WITH WITHIN
WITHOUT WLM WORK WRITE WRITETEXT
YEAR YEARS
ZONE

Howto: Remove the 3 ring tone that plays to people calling your number

Removing the 3 ring tone that plays to people calling your number:

  • Log in to Mitt Tre
  • Click on the “Abbonnemang” tab
  • Find the Settings tab, and click on the ad-like box that says “FriendTones” (or use this direct link to it)
  • This will launch another web site, at which you can find the left-hand side link to deactivate this “service”.

The “Three is the Magic Number” ring tone is the default one.

Vintage tools: ffmpeg

There is a Swiss army knife of video handling that’s called ffmpeg. A real workhorse. See examples of what it can do. Those are 19 real-world use-cases for this command-line tool.

ffmpeg’s website says:

FFmpeg is a complete, cross-platform solution to record, convert and stream audio and video.

It might sound smug, but it’s quite true. “Complete.” Here is a short, reconstructed snapshot of how me and some friends used it, a few weeks ago.

One night, a while ago, me and friends at recreational programming collective Forskningsavdelningen got a very well-defined and fun problem to solve. “Send a video to this custom-built screen over the Net.” And the inventor added “I’ll be done receiving the bytes you send me in, say 10 minutes.”

Frantic activity on our side. Us? Yes, me and Jonas.

Should we build a video player plugin? We looked at building plugins for VLC. Hmm. Would take us more than one night. Hard. Then ffmpeg came on the table; my friend was right in just assuming that there’d be some option to extract frames from a video. So, we went to the documentation. A flag “-f” meant “apply a filter”.

An aside: Creating a film from a series of images

ffmpeg -f image2 -i foo-%03d.jpeg -r 28 -s 96x54 foo.avi

  • Use the image2 filter to create a video from a bunch of still images
  • The existing images have names that match the form foo-001.jpeg, foo-002.jpeg, and so forth
  • The framerate of the created video should be 28 frames per second
  • The resulting video should be 96 pixels wide and 54 pixels tall
  • The output video is named foo.avi

Pretty soon we were using Ruby to factor out configuration. When we knew that ffmpeg was able to do the video frame-grabbing, we said “let’s create random data, to have something to send over the Net”. Borrowing code from a snippet website, we skipped reading the API for the UDP Socket library.

Trying it, we actually got pixels sent to the screen. “But we don’t know if it’s our noise.”

Then, the task of reading the image files began. We had begun with JPEG. Difficult format, much compression. Then, PNG. Hmm. Still compressed. RAW didn’t exist. But, snooping around at the Cats Who Code article about ffmpeg tricks, we found this pearl of wisdom:

The following image formats are also availables : PGM, PPM, PAM, PGMYUV, JPEG, GIF, PNG, TIFF, SGI.

Wikipedia explains PPM. Wonderful format. From there on out, it was a walk in the park – apart from wrangling with Ruby strings for a confusing bit.

Well, this was an incomplete and belated recap – I am not the BBC. – but I wanted to share it with you, anyway. The kind of fast-paced fun Forskningsavdelningen can provide is hard to get elsewhere.

Web tools link dump from last night

Yesterday, at Forskningsavdelningen (geeking every Tuesday night!) we had a blazingly fast run-through of web tools. This link-dump will probably be amended.

I had time to set up a Redis, and do a test run with Rediska – a PHP interface to Redis. It worked, and it’s in PHP. I was more impressed with the redis-cli experience. There are many atomic commands in Redis, and the datatypes are quite helpful.

We spent some time walking through a BDD tool for async web framework Node.js: VowsJS. When that was done, we looked at kyuri, the library that can transform a Cucumber feature spec into a skeleton VowsJS “vow”. kyuri was used for prenup, a web tool to create Cucumber specs for Node.js projects. prenup was quite alpha, but we sympathized with the concept.

Joel pointed to PHP-based web frameworks “like Sinatra“, and found a few that he rejected. The last man standing was named GluePHP. He can list his gripes with all the others. We looked at Troels’ Konstrukt, as well, and it got good reactions. It’s good, but it’s nothing like Sinatra.

Flask is a web microframework which was used at Forskningsavdelningen last night. “I don’t know how to use this, so let’s begin.” And we begun, and had a website up and running pretty soon. A roadblock in the form of “convert a regular font file to a PIL-font format” appeared, and a hell-of-Portfiles ensued. I should start using Homebrew

Oskar had referenced Windows hacker Scott Hanselman, and we praised his article on changing default web browser in Visual Studio for it’s complete hacker attitude. Here is a link to his PowerShell category on his blog.

Oh, Hanselman lists Windows tools he uses.

Other stuff, that should be mentioned, so as not to forget:

Whiskey Disk is embarrasingly fast deployments – their videos, presentations, etc, are very convincing, and “keep it easy.” Someone who takes Capistrano down a notch for “not being simple enough” should be listened to. The system seems quite capable.

Inspiration: This morning I saw that some Drupal folks were using a Phing task to automate fetching and building a customized version of Drupal, for their deployment. They included two useful tasks: help and explain, where help informed about the available options, and explain printed all the variables that would be used when running a phing build. Also, they informed the user of how to change those variables right on the commandline, and gave the tip that they should run the explain task with changed command-line settings. This would verify that Phing had understood the user’s invocation correctly.

Usage of Phing explain