newspaint

Documenting Problems That Were Difficult To Find The Answer To

Monthly Archives: January 2012

Nissan Primera P12 2.0 Driver’s Door Locking Problem

The Problem

I had a scare this evening. I parked my car – and I closed my door at the same time as I pressed “lock” on my car key fob.

Locking a Nissan Primera using a Key Fob

Locking a Nissan Primera using a Key Fob

Because I’m a paranoid person I always double check the door is actually locked – and I pulled on my driver’s door handle and the door opened (and the car began to emit a high pitch tone from within the cabin until I pressed the “unlock” button on my key fob).

I thought, “okay, that happens”, and I closed my driver’s side car door again, and pressed “lock” on my key fob.

Again, I tried pulling on the driver’s side door handle, expecting the door to be locked, but it opened! And the cabin emitted the high pitch tone again until I pressed “unlock” on the key fob.

I repeated this process several times until I realised the driver’s side door simply was not going to lock.

I tried the process with my spare key (which had a fresh battery in comparison). Still no luck.

With the driver’s door open I tried locking and unlocking several times with the key fob. Each time I heard the mechanical “thud” that one expects when the door locks – so I was puzzled – the door sounded like it was mechanically locking.

In summary the problem was (for search engine purposes):

  • driver’s door won’t lock
  • driver’s door wouldn’t lock
  • driver’s door would not lock

The Solution

Time to try something more drastic. I unlocked the car and jumped in the driver’s seat. I started the engine and left it idling in neutral (my Primera is a manual 2.0L P12). I opened the driver’s side door window using the electric switch.

I pressed the centre console (between the front driver’s and front passenger’s seats, just below the gear stick) lock switch. Then I reached out the driver’s window and pulled on the door handle – the door opened – drat!

I shut the driver’s door again, pressed the “lock” switch in the centre console again (engine still running), reached out the window, and tried opening the door – I couldn’t! It was locked this time! Success!

So I tried unlocking from the centre console, reached out the window, and the door opened! Shut the door again, pressed “lock” on the centre console, and reached out the window – door wouldn’t open, it was locked! Okay – everything good now.

I closed the window, turned off the engine, got out of the car, closed the door. Then I pressed “lock” on my key fob. Finally yanked on the door handle – it was locked. Tried pressing “unlock” and yanked on the door handle – it was unlocked. Pressed “lock” on the key fob and yanked on the door handle – it was locked. Problem appears to be solved.

So I think the following caused the issue:

  • Closing the door while attempting to lock using the key fob simultaneously (car computer got confused?)

I think the following is the solution:

  • Get in the car
  • Close the door
  • Start the engine
  • Wind down the driver’s door window
  • Lock using the centre console (next to the gear lever)
  • Reach out the window, try and open from outside
  • — is door locked? No? Close the door, press unlock and lock on the central console, and repeat
  • Door is now locked, wind up window, turn off engine, get out
  • Test to ensure key fob successfully locks/unlocks

Update

Turns out the door lock was faulty. It seems to fail maybe 1 out of every 5 attempts to lock. Well, not surprising, given that the driver’s door is typically the only one that unlocks when you first press the “unlock” button on the key fob (you have to press unlock a second time to unlock the other doors and boot). I got a quote from the local Nissan dealer and it will cost me around £210 to have the driver’s door mechanism replaced (parts and labour).


Update (2014-12-23): please note I’ve moved the diagnostic tips to this page.

ZeroMQ – What I Want

Goal

I have begun experimenting with the Perl CPAN module ZeroMQ-0.20 with a locally compiled zeromq-2.1.11 C library on Ubuntu 11.04 (natty).

This is my first attempt to delve into the world of ZeroMQ.

In my mind I have a goal of a design like the following:

  clients                        workers
   _____       ________           _____
  | REQ |---->| SWITCH |-------->| REP |
  |_____|     |        |       ->|_____|
         \ -->|        |-     /
          X   |        | \   /
         | \->|________|  \ /
   _____/  /           \   X      _____
  | REQ | ||            \ / ---->| REP |
  |_____| ||             X   --->|_____|
         \| \   ________/ \ /
          X  ->| SWITCH |  X
         / \   |        | / \
   _____/   -->|        |-   \    _____
  | REQ |      |        |     -->| REP |
  |_____|----->|________|------->|_____|

.. where I can have an arbitrary number of clients and workers. Workers can connect and disconnect at any time (as can clients). This requirement for dynamic connections and disconnections appears to cause the ZeroMQ library enormous grief as it has no way of informing the user program that a connection has been lost (and that a message may never be successfully processed).

Switch Implementation

Implementation of the switch is done by using ROUTER sockets. Why? Because only ROUTER sockets record who sent the message – and pass it onto the user program. The REP socket actually records who sent a message but does not make this information available to the user program.

How is sender information passed to the user program for a ROUTER socket? It is done through sub-parts of the request. A message coming from a ROUTER socket appears as follows:

  1. sender from which THIS message was received
  2. sender before that
  3. sender before that
  ...
  n. "" (empty message)
  n+1. first data part
  n+2. second data part
  ...

For other sockets (except DEALER) the sender information is hidden from the user program. Only the data parts are handed to the user program.

Note that sender information does not contain an IP address or anything like that – it is a unique code that the ZeroMQ internal library uses to track connections.

Perl Code to Fetch Message Parts

I wrote the following code to fetch an entire message and split it up into its parts from a ROUTER socket in Perl:

use Exporter; # ZeroMQ complains if this isn't included

use ZeroMQ;
use ZeroMQ::Constants;

sub get_msg {
    my ( $zsock ) = @_;

    my @addr = (); # stack of sender info
    my $header = 1;
    my @data = (); # data parts of message (at least 1)

    while ( 1 ) {
        my $msg = $zsock->recv();
        my $optval = $zsock->getsockopt(
            ZeroMQ::Constants::ZMQ_RCVMORE
        );
        my $str = $msg->data();
        if ( length( $str ) == 0 ) {
            $header = 0; # data follows
            next;
        }

        if ( $header ) {
            push( @addr, $str );
        } else {
            push( @data, $str );
        }

        last if ( ! $optval ); # no more parts
    }
    return( \@addr, \@data );
}

ZeroMQ Suggested LRU (Least Recently Used) Method

In the ZeroMQ Guide about Message Broking it is suggested the workers use REQ sockets to initiate a “READY” message to the switch/router/broker and have the broker track which workers are ready to receive messages.

Problems

What if a worker is killed (deliberately, though a software bug, or a hardware issue such as loss of network or power failure)? Well – the switch/router/broker will never know. There is no technique in ZeroMQ to inform the user program that a connection has been terminated.

A heartbeat could be used – but this also has problems. For one – a separate heartbeat connection will appear to have a different source header – making it impossible to associate the heartbeat with a currently connected REQ socket.

In short ZeroMQ has serious short comings. Besides being unable to detect connection failure ZeroMQ additionally kills an entire program if a bind() attempt fails – every other known socket library politely informs the user program when this happens.

Another annoyance is that a ROUTER socket is the only way to track routing information for a received message. There may be situations where a REP socket may wish to know where the request came from.

Solutions

Perhaps there needs to be another library written. I would want the following features:

  • ability to poll for ZMQ_POLLERR (detect connection failure)
  • error code instead of crash for bind error
  • ability to extract sender information from ANY socket type

This is not a fully considered list but I may update this entry from time to time.