Delphi, GridServer and Raspberry’s Sense Hat !

Here is a little demo (half a day written, cosmetics included !) to illustrate the use of GridServer to access to the well known Sense Hat hardware, from a delphi client.

Here is a picture of the final results :

Hay ! We can draw on LED matrix. Oooh, the ghost is not so bad 😉

It is a Delphi Client, which is connected to a raspberry (throught GridServer Arm32 release), and give us easy access to the hardware, without delphi sdk integration, thought *simple* Python call.

You’ll find the demo source code here, as usual. There are a little problem with orientation, but I’ll fix that asap :/ 😉

Fun stuff is that we can draw pixel, via color palette, and get color coded into hardware’s led matrix. It is vers easy : we drive python call and decode it into delphi.

A little bit history, about the why and How

I already present GridServer. In short, it is a Mom, generalist middleware, MQTT compliant, and remote system access facilitator via dedicated protocol KissB. It is written in Object Pascal, available in Delphi/FPC target (actually, win and nix, x86, x64 and Arm32), and open source.

Above all, GridServer’s aims is mainly to facilitate access to “foreign” sdk, such as Home Automation, Connected object, hardware stuffs, Software SDK, High level Enterprise SOA services, and so on.

For sure, you can access to all you want in delphi, but, there are 2 strategics point to keep in mind :

  • SDK are often in c, c++, c#, or python -> Unfortunally, we have to translate them : It is a long and hard task, and unfortunally error prone, and we have, in the worth case, to maintain it on each iteration of the product.
  • Official SDK is not our responsability : I mean, that should work, we have, normally, 0 (zero) work to do on.

When GridServer became enougth stable to be released, I begin to make Service for it, in the language of the SDK is. As GridServer is a classic Bus, It was easy to make the work into the native SDK, and communicate the result to gridserver. In fact, It is the general concept of a middleware : hide the work to the client.

My clients are usually open to all working software solution, but when we have to deal with SDK, I like to work with the native one. Before GridServer, I worked to translate many of them, when it was too hard, I flat them to c++ dll, compatible with delphi, I even tentatively thought to make dedicated rest server (fotunally, I take vacation before doing that :)) : All this solution is long, and, again error prone.

So, scuse me for the long speech : What I’m presenting here is a short demo to show how to interact, in a simplistic way, with a remote computer throught GridServer. this include a build of an app on a hardware stack, which required normally client software support.

The beauty here is we will stand on working, solid, existing stuffs to make a solution that will work with a minimal amount of dev work.

Dependancies

  • [Hardware] You must have a working and connected raspberry, or even another embedded Armv7 device. this release work in our lab with a Synology DS 414, just for example.
  • [Hardware] You must have a wrkoing Sense Hat connected.
  • [Softs] You must pick and run (simply) on your device the Arm32 release of GridServer (Or compile it yourself)
  • [Softs] You have to configure Python access : GridServer is able to manage many Python at the same time, and do not rely on a system configuration. (you’ll find a short doc at the end of this post.
  • [Softs] On the previous configuration, You have to install Python Sense Hat SDK.

And it is all. On your Client (PC, Mobile, or whatever) you need only a network access, and a Delphi App 😉

How it is working

Basicaly, it is working via Python call : Already presented here.

For exemple, here is the code to “clear” the LED matrix, starting from Delphi :

 //Python code to clear the led matrix.
 CST_PYTHONCODE_CLEARLEDMATRIX =
   'from sense_hat import SenseHat' + sLineBreak +
   'def gridmain():' + sLineBreak +
   '  sense = SenseHat()' + sLineBreak +
   '  sense.clear()';

Once this one define, we have only to call it :

MyDelphiGridClient.InstantPythonRun(CST_PYTHONCODE_CLEARLEDMATRIX);

And Voila !

You reconized simplistic Python code, build upen officila Sense SDK. As python is compact, for big result, the code is short : And the call from delphi (synchrone here) is straightforward.

I let you see the demo source, which is volountary simple, to see how, in a matter of hours, we can intereact in a very easy way with a remote hardware.

For sure, I skip here connection code, just to focus on the business side : Here is another exemple for getting sensor data : that is call by a thread, is the demo app :

 //Python code to get temperature, pressure, and humidity. Running in a thread.
 CST_PYTHONCODE_GETSENSORDATA =
      'from sense_hat import SenseHat' + sLineBreak +
      'def gridmain():' + sLineBreak +
      '  sense = SenseHat()' + sLineBreak +
      '  t = round(sense.get_temperature(),2)' + sLineBreak +
      '  print("TEMP:{}".format(t))' + sLineBreak +
      '  print("PRESS:{}".format(round(sense.get_pressure(),1)))' + sLineBreak +
      '  print("HUMID:{}".format(round(sense.get_humidity(),2)))';

And the code of the thread :

{ TDataAcquisitionTask }

procedure TDataAcquisitionTask.Execute;
var busmessage : TBusMessage;
    inf : TGRIDProtocol_KB_SRV_PROCESS_API_INFO;
    t : string;
begin
  FClient := TGRIDClientKissB.Create(TGRIDTransportIndyTCP.Create);
  [...]
  
  //Give sensors informations every second.
  while not(Terminated) do
  begin
    busMessage.FromString('CPU:'+FloatToStr(Round(FClient.InfosCPULevel)));
    Bus.Send(busmessage,'HiMan');

    Sleep(1000);
    t := FClient.instantPythonRun(CST_PYTHONCODE_GETSENSORDATA);
    if Fclient.LastStatus then
      busmessage.FromString(t)
    else
    begin
      busmessage.FromString('ERR:'+Fclient.LastStatusInfo);
      Terminate;
    end;

    Bus.Send(busmessage,'HiMan');
  end;

  FClient.Disconnect;
  FreeAndNil(Fclient);
end;

Note : As I usualy not use thread’s “synchonize” in my code, I use instead my Bus library : That allow me to not “synchronize”, and target the running context’s of my code. you can abstract this in this demo (You just have to know that when we make a bus.send, the result arrive in subscripter… Oh, it is just a standart bus behaviour ;), -> for more information about Bus, go here.

Future

It is just a demo, to do better, and “eat” less ressource (Raspberry is weak, Python is greedy) we have to build a “real” service in Python (or Delphi, or whatever) on server side, and thanks to GridServer, it is possible : GridServer can handle, launch, kill and manage entire Service, on demand, but it will be tell in another article !

Thank you !

P.S : configure raspberry with GridServer :

I consider that you have a “fresh” Raspberry ready to go, connected to SenseHat.

You have previously installed Sense HAT Python SDK with something such as :

sudo apt-get update
sudo apt-get install sense-hat
sudo reboot

More information, and testing stuff (in Python console or cmmand line) here

Once that doing, download and run GridServer :

chmod 777 GRIDServerConsole_FPC_Arm32_Linux
./GRIDServerConsole_FPC_Arm32_Linux
GridServer is running : Type <h> en enter…
… and you’ll obtain basic menu for it. Type admin in this menu, then, choose python configuration…
… 1) Enter the adminmenu, 2) enter python configuration…

And here, I type “1” to get my python conf : Here, we have a python 2.7.

In your case, search on your device the python lib “libpythonx.y.so, by using “locate” or “find” tools. Once done, cut and copy the access path.

Once ready, in python menu, type “2”, in order to add a python configuration, and, in the case of python 2.7, for example, enter

Enter python version
->2.7
Enter python api
->2
Enter python lib name
->libpython2.7.so
Enter python lib path
<copy here the path, without filename.

Once done, if you have no message : all is correct. You can see configuration by typing “1”, and manage configuration with the menu. On demand, I can write better article on that, but since this solution will be replaced by web solution, or a dedicated client binary, it perhaps not worth a dedicated documentation.

Leave a Reply