Table of Contents
The ActiveHome Component
Once the package is installed in Delphi, an ActiveHome component is
added to its IDE's
ActiveX palette. The TActiveHome component is
pretty sparse. It has an
overloaded function, SendAction, which is
used to send messages to the
CM15A with different numbers of parameters :
while it's not quite obvious which to use, it turns out
that the second, two strings, version is the one most used. So, to turn
on an
appliance module at address B9 on, the syntax would be SendAction("sendplc",
"B9 ON").
Of course, you will probably want to change the address B9 to the
address of a nearby device to easily verify that the command was send
over the power line.
To test this, drop the TActiveHome
component (make it invisible), a memo, and a button on a form and in the button's OnClick
event handler add this:
The helper function ovtoint,
that
converts an OleVariant to an integer, is
needed because Format does not know how to
handle an OleVariant directly.
If your device is wireless, then the CM15A will need to send a message
on a specific radio frequency. You need to change Action
:= 'sendplc' to Action :=
'sendrf'.
If you are using Delphi 2010 and the application will not compile
because ActiveHomeScriptLib_TLB.dcu has not
been found, you can
move the file from the folder C:\Users\{user}\Documents\RAD
Studio\7.0\Imports to the folder C:\Program
Files (x86)\Embarcadero\RAD
Studio\7.0\Imports which contains many other imported type
library
units and which is in Delphi 2010's default search path.
Problems with errors
If you run this small application with the USB cable connected to the CM15A and the device is turned on, the result will be a 0. However, if you run the application with the cable not connected to the X10 transceiver, the result will again be 0 even though, obviously, no command was sent over the power line.
You would think that not being connected to the
interface would constitute an error worth reporting,
unfortunately that it is not the case. So what kind of errors are
reported by SendFunction? Strictly speaking
none it would seem. Change Param := 'B9 ON'
to 'B9 ONF' and run
the example again. You will get a rather lengthy generic
syntax error
message :

But you will also notice that nothing is written to the memo in that
case. So SendFunction does not
return an error code when it cannot parse 'ONF', instead it raises an
exception. Furthermore, SendFunction
will not report a syntax
error when Param := 'B9ON'
while
that is clearly an error since the device will not be turned on.
Similarly, using the 3 strings version of SendAction('sendplc',
'A9', 'on') will not work and yet will neither raise an
exception nor return an error code. On the other hand, the 4 strings
version SendAction('sendplc', 'A', '9', 'on')
will raise an exception.
It's all very strange and someone might be tempted to further study how the dll handles errors. I have decided it was not worth the effort, the obvious solution is to do all error checking in your application and reporting them to the user.
The more important question of finding out if the CM15A is connected or not will be addresses a little further on.
Small Application
A small application capable of sending most commands including dim/bright commands is easily built. Here's a screen shot of the main and only form of such a program.

The source consisting of only 4 files
cm15_test.dpr
cm15_test.res
Unit1.pas
Unit1.dfm
can be downloaded here (cm15_test.zip, 3003 bytes, 2013-07-12). To compile this application, the ActiveHome type library must have been imported and the TActiveHome component must be installed on the component palette.
Looking at the imported type library for ahscript.dll, it is easy to spot a likely event to use to listen to the CM15A. Called OnRecvAction
it is of type TActiveHomeRecvAction which has the following declaration:
So if you check Try to
listen to CM15A in the application, a handler is installed
for that event. It simply translates all these OleVariant
results to strings and concatenates them all to a single string that is
copied to the memo. There's only one problem. It does not work.
The next part looks at the solution.

Part 1 - Importing the SDK's Type Library