Using a remote Raspberry Pi's OS by Node.js

This Smart Pascal program, inspired by James's remote control of the Raspberry Pi, uses Node.js to execute commands on the Raspberry Pi. It has a similar set-up to that described in detail on the previous page. As with the PHP version, the user has the choice of selecting one of the tested commands in the combo box or typing a command into the edit box.

The Smart Pascal code of the server and client and the XML code of the form follow the screenshot of the program in action.

Application in Action

Application in Action

Smart Pascal Code of Server

You can compare this code with a JavaScript version.

unit Unit1;

interface

type
  TServer = class
  public
    procedure Run;
  end;

implementation

uses
  NodeJS.Core, NodeJS.http, Node_Static, socket.io;

procedure TServer.Run;
begin
  var fileserver := TNodeStaticServer.Create('./public');
  //start http server
  var server: JServer := http.createServer(
    procedure(request: JServerRequest; response: JServerResponse)
    begin
      Console.log('http request: ' + request.url);
      if request.url = '/' then
        request.url := '/PiClientExec.html';
      fileserver.serve(request, response);
    end);
  server.listen(8079, '');
  Console.log('Server running at http://192.168.0.6:8079');

  var value := 0;
  var io := socketio().listen(server);
  io.sockets.on('connection',    // waiting for connections
    procedure(socket: JSocketIO)
    begin
      socket.on('requestFromClient',  // waiting for a special request from the client
        procedure(data: Variant; callback: JSocketIODataFunction)
        begin
          Console.log('Received from client: ' + data);
          asm
            var exec = require('child_process').exec;
            exec(data, function(err, stdout, stderr) {
              if (err) {
                @callback('error code ' + err.code);
                return;
              }
              @callback(stdout);
            });
          end;
      end);
    end);
end;

end.    

Smart Pascal Code of Form of Client

unit Form1;

interface

uses 
  SmartCL.System, SmartCL.Graphics, SmartCL.Components, SmartCL.Forms, 
  SmartCL.Fonts, SmartCL.Borders, SmartCL.Application, SmartCL.Controls.Button,
  SmartCL.Controls.Panel, SmartCL.Controls.EditBox, SmartCL.Controls.Memo,
  socketioclient, SmartCL.Controls.ComboBox;

type
  TForm1 = class(TW3Form)
    procedure W3Button1Click(Sender: TObject);
  private
    FSocket: JSocketIO;
    {$I 'Form1:intf'}
  protected
    procedure InitializeObject; override;
  end;

implementation

procedure TForm1.W3Button1Click(Sender: TObject);
begin
  FSocket.emit('requestFromClient', [W3EditBox1.Text],
    procedure(aData: variant)
    begin
      W3Memo1.Text := aData;
    end);
end;

procedure TForm1.InitializeObject;
begin
  inherited;
  {$I 'Form1:impl'}
  FSocket := socketio.connect('http://192.168.0.6:8079');
  W3Combobox1.Add('echo This is fun!');
  W3Combobox1.Add('pwd');
  W3Combobox1.Add('ls');
  W3Combobox1.Add('du -h');
  W3Combobox1.Add('uname -a');
  W3Combobox1.Add('date');
  W3Combobox1.Add('cal 8 2015');
  W3Combobox1.Add('grep "html" index.html');
  W3Combobox1.OnClick := procedure(Sender: TObject)
    begin
      FSocket.emit('requestFromClient', [W3Combobox1.Items[W3Combobox1.SelectedIndex]],
        procedure(aData: variant)
        begin
          W3Memo1.Text := aData;
        end);
    end;
end;

initialization
  Forms.RegisterForm({$I %FILE%}, TForm1);
end.    

XML Code of Form

<SMART>
  <Form version="2" subversion="1">
    <Created>2015-10-09T13:46:42.361</Created>
    <Modified>2015-10-09T19:28:06.278</Modified>
    <object type="TW3Form">
      <Caption>W3Form</Caption>
      <Name>Form1</Name>
      <object type="TW3Panel">
        <Width>536</Width>
        <Top>16</Top>
        <Height>320</Height>
        <Name>W3Panel1</Name>
        <object type="TW3Button">
          <Caption>Send command</Caption>
          <Width>128</Width>
          <Top>30</Top>
          <Left>160</Left>
          <Height>32</Height>
          <Name>W3Button1</Name>
          <OnClick>W3Button1Click</OnClick>
        </object>
        <object type="TW3EditBox">
          <Value></Value>
          <Text>ls -lh</Text>
          <Range></Range>
          <Width>128</Width>
          <Top>30</Top>
          <Left>24</Left>
          <Height>32</Height>
          <Name>W3EditBox1</Name>
        </object>
        <object type="TW3Memo">
          <Text>W3Memo</Text>
          <Width>488</Width>
          <Top>80</Top>
          <Left>24</Left>
          <Height>216</Height>
          <Name>W3Memo1</Name>
        </object>
        <object type="TW3ComboBox">
          <Width>168</Width>
          <Top>32</Top>
          <Left>336</Left>
          <Height>32</Height>
          <Name>W3ComboBox1</Name>
        </object>
      </object>
    </object>
  </Form>
</SMART>
Programming - a skill for life!

Using Node.js for a server that updates connected clients in real time and remote use of a Raspberry Pi's OS