Archive for the 'Tech Stuff' Category

I was on-site with a client at a pharamacutical production facility last week and they they showed me a strange problem that they were having with .NET Remoting running on a sub-network configured with a multihomed host that sits on both the sub-net and the factory ethernet.

 

The sub-network consisted of 11 Machine Vision inspection station PCs that happily inspect product on the production line and report their results and status asynchronously to a single ‘dashboard’ system running on the multi-homed host. We had developed the inspection stations with vanilla C++ and the ‘dashboard’ system in C# .NET, they all communicate via .NET Remoting.

 

The dashboard system connects to each of the inspection stations in turn and passes a remoting object of a shared interface, the inspection stations raise events across the sub-net by calling back on this shared interface.

 

All was well with tonnes of nice events being raised and received, until one day they all just stopped! The client was sure that nothing could have changed to cause this as the whole system was under qualification and therefore everything (software/configuration etc.) must stay static. However on further investigation it turned out that the dashboard PC had recently been added to the factory ethernet - and sure enough, once the factory network was whipped out and the dashboard restarted the events came flooding back!

 

Anyway it seems that when the dashboard system was connected to the factory network it communicated to the inspection stations using its factory NIC identity and IP address.  When the stations tried to callback they used this factory IP address and the callback events were lost as the PC knew of no  way to route the traffic onto the factory network (and hence back to the dashboard system).  On further investigation we found that the inspection station PCs (which were given static IP addresses) did not have a default gateway configured so we configured the dashboard’s local IP address as the gateway for each and the problem was solved!  This change ment that any network traffic destined for any network other than the local sub-net would be automatically sent to the dashboard system.

So, to cut a long and boring story short, if you’re having .NET remoting callback problems with a multihomed host take a look at the network configuration and make sure that t he PCs that raise the events are able to route them back to the receiver PC no matter which network it initially calls on..

Here’s something I was googling last week - How do you change the text of Drupal’s ‘Home’ breadcrumb to something else? Well, it turns out that a small mod to your theme may be required…

 

While using Drupal 6 to develop a web application we ran into a little snag with Drupal’s breadcrumbs, the app is to integrate in with our client’s existing web site, it will look and feel the same and the visitor should not really know that it is separate from the main website (which is not implemented with drupal).  With drupal this was all easy enough to achieve, but we hit a speed bump when it came to the web app’s breadcrumbs.  Breadcrumb navigation is very important for the new web application, but Drupal always calls the first breadcrumb ‘Home’ - this was a problem as ‘Home’ did not refer to the larger web site’s home page as would be expected, but instead to the first page of the web application.

 

So how do we change the ‘Home’ breadcrumb text to something else, say the title of our web application?  It turns out that there’s no easy way to do this through settings, but thanks to this thread we can see that it is possible via a small change to the active theme. The modification hooks into phptemplate_breadcrumb(), it removes the existing primary breadcrimb (’Home’) and then inserts a replacement with the new text.

 

So to make the change, edit your theme’s template.php file, and search for the function called:

 

phptemplate_breadcrumb()

rename it to:

original_phptemplate_breadcrumb()

Then paste in the following, changing ‘New Home Text’ to what ever you want your ‘Home’ breadcrumb to be called.

function phptemplate_breadcrumb($breadcrumb) {   if (!empty($breadcrumb))   {     // remove the exisitng Home link     $old_home_link = array_shift($breadcrumb);     // insert the new link     array_unshift($breadcrumb,                    l(t(‘New Home Text’), ‘<front>’));     // Get the original function to     // output the breadcrumb     return original_phptemplate_breadcrumb($breadcrumb);   } }

With this theme modification in place the breadcrumbs should display with the new text in place, bit of a pain but at least it’s do-able!

 

 

Hats off to gwen for the tip & code!

If you’re using the TinyMCE wsywig editor in drupal then you may find that the editor’s background color gets set to that of your website rather than being the more normal white-ish color - this can cause the wysiwyg editor look like the proverbial dog’s dinner and depending on your websites background color/image, can make reading the text very difficult.

 

Well, the good news is that it’s easily fixed - in Drupal, go to Adminsiter/Wysiwyg menu and for each import format with which you are using TinyMCE, click ‘edit’. Once in the settings editor click on the ‘CSS’ section and in the ‘Editor CSS’ drop-down choose ‘Editor default CSS’ and save. Do this for each import format and the editor’s background should revert to a calming white.

I ran into a problem while attempting to get an Auxiliary display to work on a Machine Vision system I was developing with a Matrox Solios Frame Grabber and a (dual head) Matrox Millenium P650 graphics card.  The plan was to have each vision station (in a Parmacutical AOI setup) output all of the images it acquired from its cameras to a massive 15 input digital video recorder (DVR) via its Auxiliary display port - in this way the client would have a record of all image acquired and processed on each of their 11 inspection stations   Anyway, while trying to initialise the display from code via a call to:

MdispAlloc(milSys, M_DEFAULT, "M_PAL", M_AUXILIARY,&milAuxDisplay);

Matrix Mil always reported that no system capable of supporting an Auxiliary display could be found - no matter how I changed the millions of possible settings, the auxiliary display would always fail to initialise - loads of hours later I became seriously worried that the Millenium P-Series graphics cards do not provide Auxiliary display support to Matrox Mil!

 

Mil Auxiliary Display Error

 

Well, it turns out that the P-Series graphics cards do provide Auxiliary display support to Mil, but in order to get it to work (in my case) an update needed to be applied to the Matrox graphics card driver - In my case I installed the update contained within m800du09.zip, once applied the Auxiliary display worked just fine!

 

So anyway the moral of this story is that if you’re trying to get an Auxiliary display to work with Mil and you’re getting this error message no matter what you do - get on to Matrox and ask if there are any updates for your graphics card drivers and install them straight away!

 

PS  As the Mil documentation says, in order to get the Auxiliary display to work you will first have to disable the ‘dual-head’ functionality of your Matrox graphics card.  Now, with the newer Matrox graphics software ‘dual-head support’ is no longer called ‘dual-head support’, instead go into the Matrox ‘Power Desktop’ settings, and set the ‘Multi-Display Setup’ option to ‘1 Display (no feature display)’.

 

PPS It seems that where the Auxiliary display is concerned, the Matrox drivers are not very good at cleaning up their resources when the calling process ends - it is very important that you call MdispFree() on the Aux. display when your process is shutting down otherwise when you try to re-launch the process you will get the above error message every time you try to allocate the display until you reboot your system!

Have you ever noticed that sometimes no debug output whatsoever appears when you call a debug output function like dprint_r() from the PHP code that you’re working on?  For example, if you call one of the debug dump functions from the default argument handler for a block view (see earlier post) you won’t see a blessed thing! It seems that there are plenty of situations in the drupal processing lifecycle where output debug information will not get through for display on a page…

 

So what’s to be done? life without debug information can get very difficult and frustrating, but not to worry as in these difficult cases we can always log our debug info to a file using file_put_contents() (as suggested here), for example if you wanted to dump information about a variable called $my_variable you could call:

file_put_contents("./drupal.debug",                  print_r($my_variable, TRUE),                  FILE_APPEND);

Then simply read the contents of the file drupal.debug, not pretty and not perfect but a whole lot better than nothing!

With newer versions of Matrox Mil (>= Mil 8 ) it is possible to grab images from firewire cameras without the need for any Matrox hardware, Mil will just use your PC’s normal Firewire/1394 adaptor(s) to acquire the images. When setup correctly you should be able to grab from either code or from intellicam.

 

However in typical Matrox fashion finding out how to set Mil up this way is quite difficult as there isn’t much information ‘out there’ or in the Mil documentation on how to do it,  and (again in typical Matrox fashion) the procedure is a tad non-intuitive.

 

So to add 1394 support - Install Mil, and when you get to the stage where it asks you which drivers it should install for the various possible frame grabber cards choose ‘Meteor II 1394′ remember though that you don’t  actually need a Meteor II frame grabber - Mil will use your existing Firewire adaptor(s) instead!

 

The next thing to note is that whenever you want to see or use any of the Mil 1394 features from Intellicam or from code you must have your camera(s) plugged in - otherwise Mil will deny all knlowedge!

 

For example if you start up Intellicam without your firewire camera plugged in then you may get an error message like the following, plugging the camera in and restarting Intellicam will fix things:

 

ooops camera is unplugged!
 

To grab images from Intellicam, first plug in your camera and then launch Intellicam and make sure the ‘Meteor-II /1394′ system is selected.

 

 Choose the 1394 System

 

With firewire Mil does not use DCF files like it does for other frame-grabber and camera combinations, instead the required camera and digitiser format is specified by a string.  To see the available formats hit the ‘New DCF’ toolbar button or choose the ‘File/New…’ menu option,  this will display a list of format strings:  

 

 

Choose your digitiser format

 

Once you select a suitable format you should be able to grab from the camera!

Windows can be programmatically shutdown using the ExitWindowsEx() Win32 function.  However it turns out that the trick to getting it to work is to first grant shutdown priviliges to the calling process via some rather ugly security functions - this type of faffing around can never me remembered so I will post some sample code here in the hopes that it might help me (in the future) or maybe someone else:

bool ShutdownPC(const bool reboot) {   HANDLE hToken = NULL;   if(!OpenProcessToken(GetCurrentProcess(),                        TOKEN_ADJUST_PRIVILEGES |                        TOKEN_QUERY, &hToken))   {     cerr << "OpenProcessToken() " << GetLastError();     return false;   }   TOKEN_PRIVILEGES tkp;   if (!LookupPrivilegeValue(NULL,                             SE_SHUTDOWN_NAME,                             &tkp.Privileges[0].Luid))   {     cerr << "LookupPrivilegeValue() " << GetLastError();     return false;   }   tkp.PrivilegeCount = 1;   tkp.Privileges[0].Attributes = SE_PRIVILEGE_ENABLED;   if(!AdjustTokenPrivileges(hToken, false,                          &tkp, 0, NULL, NULL))   {     cerr << "AdjustTokenPrivileges() " << GetLastError();     return false;   }   // And shutdown… with force!   bool ret = ExitWindowsEx((reboot ? EWX_REBOOT : EWX_SHUTDOWN)                            | EWX_FORCE | EWX_FORCEIFHUNG,                            SHTDN_REASON_MAJOR_APPLICATION |                            SHTDN_REASON_MINOR_MAINTENANCE) == TRUE;   if (!ret)   {     cerr << "ExitWindowsEx() " << GetLastError();   }   return ret; }

Some time ago (!) I wrote about an investigation that I had carried out into how a literal value could be mapped to and stored as a lambda expression/delegate in C#.  This was important for me at the time because I needed to find some way to have a ‘value’ and a ‘value rule’ appear the same to callers.  I wanted to define a type whose value when queried could either come from the evaluation of a previously specified ‘rule’ or could simply be retrieved from a real, previously stored value - without the caller knowing the difference at all.

 

This type of concept is common in functional and logic programming languages - in these languages the separation between functionality (code) and data is very blurry, what is data one minute can become code the next, and visa verse.  It is harder to achieve (at a high level) in procedural languages but the addition of lambda expressions in .NET 3.0 brings us a a lot closer (in .NET 3.0)!

 

The following might help to demonstrate how such a type might work, imagine a generic class called DualProp whose job is to yield a typed value when requested, this value could have been previously stored as a real value or could be obtaind by evaluating a previously specified lambda expression:

 

// Create an integer property     var speed = new DualProp();     // set it to 3     speed = 3;     // Create an bool property, whose value depends     // on the speed’s value.     var visible = new DualProp();     // visible only true if speed &gt; 5     visible.Lambda = () =&gt; speed &gt; 5;     // Check visible’s value ( this results in the     // stored delegated being evaluated)     if (visible == true)         Console.WriteLine("It is visible");     else         Console.WriteLine("It is invisible");     // Set speed to 8, sould now be visible     speed = 8;     // Try again, it should be visible now     if (visible == true)         Console.WriteLine("It is visible");     else         Console.WriteLine("It is invisible");     // now just set visible’s value to false     visible = false;     // And check it’s value again, should be invisible     if (visible == true)         Console.WriteLine("It is visible");     else         Console.WriteLine("It is invisible");

 

Two properties are defined, an integer property called ’speed’ and a bool property called ‘visible’.  Visible’s value depends on the evaluation of the delegate compiled from the lambda expression that was assigned to it:

visible.Lambda = () =&gt; speed &gt; 5;

So when queried, visible’s value is ‘true’ if speed’s current value is greater than 5.

This scheme should allow us to build up whole sets of properties some of whose values are real and others whose are dynamically computed based on the values of others.  The values on which the lambda expressions depend can themselves be real or computed.

 

This type of set-up could be very handy, especially when used as part of a data driven user interface.  A data driven user interface is typically laid out and behaves in accordance with some specified meta-data, this meta-data is usually static (no meta-rules, just meta-data!).  Employing a scheme such as this should allow us to specify meta-data which can be dynamic, in that some of the meta-data can dynamically change based on applying ‘rules’ to some of the real data.

 

Imagine a CAD/CAM system for a laser drilling machine, it will have various logical tools defined that represent the different laser cutting tools onm the laser cutting machine. The laser tool’s various parameters can be viewed and changed on the CAD/CAM interface via a data driven property-page type interface. As usual the meta-data for this interface will specify a list of parameters along with some other data like:

 

  • Name - Attribute’s Name
  • Type - Attribute’s Type (Number/Boolean/String etc.)
  • Visibility - Is this Attribute visible for editing
  • ReadOnly - Can the attribute’s value be changed?
  • Min - Attribute’s Minimum allowed value
  • Max - Attribute’s Maximum allowed value
  • HelpString - Some help text for the attribute

 

Rule based properties should allow us to do things like set the min & max values based on another parameter’s value or force a parameter to be read-only based on the value of yet another parameter (by specifying a rule for the visibility attribute).  Anyway, I hope to expand on this in a future post.

 

Meanwhile, Here is the code for the DualProp class:

using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Linq.Expressions; // (c) 2009 Kevin Godden, Ridge Solutions. public class DualProp {     // The property’s delegate, which will     // be evaluated whenever the property’s value     // is queried.     private Func _lambda = null;     // Map the passed value (of type T) to a lambda and     // then compile to a delegate.     private Func ToLambda(T val)     {         var body = Expression.Constant(val);         var exp = Expression.Lambda&gt;(body, null);         return (Func)exp.Compile();     }     // Given a value of type T, convert it     // to a corresponding lambda delegate     // and store it.     private void SetValue(T val)     {         _lambda = ToLambda(val);     }     // Set for _lambda, used when we want     // to specify a property ‘rule’ rather     // than a literal value.     public Func Lambda     {         set { _lambda = value; }     }     // Constructors     public DualProp()     {     }     // Construct with value     public DualProp(T val)     {         SetValue(val);     }     // Construct with a ‘rule’ (lambda/delegate)     public DualProp(Func lambda)     {         _lambda = lambda;     }     // Allows us to assign a value directly to     // a DualProp i.e. –&gt;     // DualProp dualProperty = new DualProp();     // dualProperty = 10;     public static implicit operator DualProp(T val)     {         return new DualProp(val);     }     // Allows us to query a DualProp’s value directly     // i.e. –&gt;     // DualProp dualProperty = new DualProp(10);     // int value = dualProp;     public static implicit operator T(DualProp sp)     {         return sp._lambda();     } }

In drupal there are many ways to go about putting together teasers for custom content types created with the Content Creation Kit (CCK). The quickest to get up and running with is often to use the Content Templates (Contemplate) module, this allows you to specify in-line markup and PHP with code to get at and display the node’s data fields - formatted just as you require.

 

Often when putting together a teaser you may want to neatly truncate some long text to a summary and append ‘…’ or the like to the end - well there’s a great little PHP function which does just this called neat_trim() it is provided by Justin Cook and does the job  nicely!

 

One thing to note however is that HTML mark-up as well as newlines and carriage-returns in the input string can confuse this function.  To get around this problem you can arrange to remove the offending material either by modifying the function or by stripping it out of the input string before calling the function.  Use can use strip_tags() to remove HTML mark-up.

Q: How can I pass an argument to a ‘block view’ in Drupal 6?

A: There is no way to pass an argument to a block view in Drupal 6, but don’t panic as there is a way to achieve the same result through some slight-of-hand.

The use of arguments with Drupal views are vital for getting the most out of the views functionality. How are the arguments normal passed to a view?  Well, if a view is configured to produce a page then the arguments are easily passed as part of the requesting URL,  while if a view is embedded using code, then the arguments are passed in as part of the call to embed the view.  But if a view is configured to produce a block, how do you pass arguments to it?  The bad news is you can’t - the good news is that there is a way fake it and achieve the same result.

The trick involves providing a PHP handler within the view which will be called when the view is invoked without an expected argument (this is what happens when the block is displayed!).  We just arrange for this handler to retrieve and return the argument’s value and then the view will behave as required - just as if the argument had been passed to it in the first place.

To do this create the block view as normal and configure the required argument(s).  For each argument we choose the ‘Provide default argument’ option, and select the ‘PHP code’ sub-option.  We then provide some PHP code which will ‘get’ and return the argument’s value, it doesn’t really matter where or how the PHP code gets the argument once it returns the correct value.   Have a look at screen shot below:

Adding a default parameter

The example above is a bit simplistic as the PHP code just returns a static value - not very useful at all!  A more realistic or useful example  (inspired by one of the posts referenced below) would be to return the argument that was passed to the page that contains and displays the block.  Consider the mythical paths:

www.somedomain.com/content/projects/web-design

and

www.somedomain.com/content/projects/illustration

Here things are set-up so that ‘web-design’ and ‘illustration’ are arguments to the ‘projects’ page, they result in only the projects of that type being displayed.   Assuming we are using the pathauto module for nice clean URLs (as we almost always are!) then the following PHP code when provided as the default argument handler will get the URL, parse it and return the argument part to the view.

$path = drupal_get_path_alias($_GET["q"]); //get URL alias $path = explode("/", $path); //break path into an array if ($path[0] == "projects" &amp;&amp; $path[1] != "") {   return $path[1]; }

So there is is, it’s definitely not the easiest method in the world but at least it does provide a mechanism of getting those arguments to the view…

Sources: http://drupalsn.com/learn-drupal/drupal-questions/question-2650, http://drupal.org/node/332521

You are currently browsing the archives for the Tech Stuff category.

Quick Contact

Contact us to chat about how we can help you with your software needs