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.

Grid Server : Focus on Python remote run

GridServer is a bus. But it include some advanced capabilities beyon pure sub/unsub classical bus feature, such as microserver deployement, or KeyValue in memory embeded database and…

Python Instant execution feature !

Better code chunk than long story 😉

Show me the code

Here is a delphi (Pascal object) exemple :

Connection :

lconnectResp := lCli.Connect('admin','admin',TGRIDProtocolFormat.Binary); 
 if lConnectResp.Status then
  begin
    Writeln('Connected to GRID admin protocol - Welcome');
    Writeln('Protocol '+lcli.Protocol.ProtocolNameSlashFormat);

You can do many things, such as get server informations :

            lInfoResp := lCli.Infos;
            if lCli.LastStatus then
            begin
              Writeln('GRIDServerName             : '+lInfoResp.GRIDServerName+' '+lInfoResp.GRIDArch+' ('+lInfoResp.GRIDCompiler+')');
              Writeln('ServerGenuineName         -> '+lInfoResp.ServerGenuineName);
              Writeln('ServerHostCPUArchitecture -> '+lInfoResp.ServerHostCPUArchitecture);
              Writeln('ServerHostArchitecture    ->'+lInfoResp.ServerHostArchitecture);
              Writeln('ServerHostOS              ->'+lInfoResp.ServerHostOS);
              Writeln('ServerHostOSBuild         ->'+lInfoResp.ServerHostOSBuild);
            end

But keep focus on python !

Get current Python version Server side :

lCli.instantPythonVersion;
This snapshot is taken from “GRIDClientConsole” binary, which is basicaly just a demo app to access to GRID Server’s services.

And now, run a python code !


lCli.instantPythonRun('def gridmain():'+sLineBreak+' print("hello world".upper())')
delphi “hello world” to “HELLO WORLD” – the most expensive uppercase ever !

Pretty simple ! You will note that the python code is a bit special, because it define a method (python’s function) “gridmain()”. I’ll talk about that later, it is as is for instance to be conforme to “multithread” execution of the stuff. You can execute legacy normal code too.

For sure, that’s work on all other platforme, (c#, python itself, cpp) since GRID Server main protocole can handle json or binary format on the same port. (pure cpp binary protocol is in test, open source delivery soon ;))

the very nice part, is that this execution take inside python env : All the libs you previously installed on your python env will be available (such as PIL, numPi, or whatever) in this interface !

so, the very all power of python is available via GRID Server, on your app (here delphi), without embedded heavy library !

Installation

Ok, just before that, you have juste to enable grid server to run Python :

To do that you must have a python installed (2.x or 3.x as you want, or even many different installation : Grid know how to manage that, and it can manage multi python version.

Now, GS Part : go to the Grid Server command line (on another instance for exemple) and fellow this step :

  • admin mode, by typing “admin” under GS console
the Admin menu in all it’s glory ;/
  • Select python management (2)
    • Enter python version MAJOR.MINOR
    • Enter API Version (not relevant for instance) – enter whatever you want.
    • Enter the name of the lib (without path)
    • Enter the path of the lib (without file name)
  • Select (1) to view the current selection
  • And finaly, select 4 to define default python version for InstantPython feature
  • In our case (above), we put “1” when system asks for “define Default ID”.

Here it is ! Python is now ready to be invoke trought GRID Server’s KissB API. Enjoy !

  • See you soon on the Grid Server GitHub !
  • Remember that you have precompiled binaries here.
  • Linux (x86) and Arm version (with python support !) is comming soon.

GRID Server Open Sourced

The latest version of GRID Server comes with a great news : This software is now open source.

Written in full FPC/Delphi, all code available and presented under MPL 2.0.

If you are interested in this server and its capabilities:

  • MQTT Broker
  • KissB protocol (Bus protocol, like MQTT, but simpler and extended to wider use)
  • Key Value in memory DB
  • Python Proxy

do not hesitate to try it, and if you want to go further, we can deliver it in various forms : native Win service, Nix Daemon, components, customs, licence customization and so on : Do not hesitate to contact us !

Soon here, we’ll have the opportunity to talk more about, through its capabilities !

Grand Opening…

Welcome to our website!
Grid System S.A.S opens today its doors on the web, after having opened them “IRL” few days ago : We start on a journey that (we hope) will be long for a long time, and we hope to meet you, to exchange, to share, and to work together !