Difference between revisions of "Install REST"

From xPL
Jump to: navigation, search
(Install a web server)
(Test the REST server)
 
(13 intermediate revisions by one user not shown)
Line 1: Line 1:
Controlling the home from distance is made via a web access.
+
Controlling the home from distance can be made via standard web access methods
 +
such as the [http://en.wikipedia.org/wiki/Representational_state_transfer#RESTful_web_APIs RESTful] API.
  
In this example, the server is <code>harmonia.local</code>: evidently, this has to be replaced by your local server name.
+
Different options are available for the implementation of such a service:
 +
* Installing a web server and writing CGI scipts
 +
* Writing scripts serving a TCP socket and complying to the HTTP scheme
 +
* Using a framework such as:
 +
** [https://metacpan.org/pod/HTTP::Server::Simple HTTP::Server::Simple]
 +
** [https://www.mojolicious.org/ Mojolicious]
 +
I have chosen [https://mojolicious.org/perldoc/Mojolicious/Lite Mojolicious Lite]
 +
for its simplicity and the ease of development.
  
= Install a web server =
+
Before all, make sure you have installed an [[install xpl hub|xPL hub]]
 +
together with the [[install state|xPL state]] monitor.
  
Install the [http://www.lighttpd.net web server]:
+
<!--
 +
= Install a web server =
 +
Install [https://www.lighttpd.net/ lighttpd] and [http://www.php.net/ PHP]:
 
  su
 
  su
  apt-get update
+
  apt install -y lighttpd
apt-get install lighttpd
+
  apt install -y php-common php-cgi php
  apt-get install php5-cgi
+
  lighty-enable-mod fastcgi-php
  lighttpd-enable-mod fastcgi fastcgi-php
+
  service lighttpd force-reload
  service lighttpd reload
+
  cat /etc/lighttpd/lighttpd.conf
  service lighttpd status
+
  
Configure the base directory and modify the line with <code>server.document-root</code>:
+
Edit <code>/etc/lighttpd/lighttpd.conf</code> and modify:
WWW_ROOT=/mnt/storage/www/
+
  index-file.names            = ( "index.html", "index.php" )
nano /etc/lighttpd/lighttpd.conf
+
  service lighttpd reload
+
cp /var/www/index.lighttpd.html $WWW_ROOT
+
  
Navigate to your server within a web browser.
+
Update the changes on the server:
You should discover the default [http://www.lighttpd.net lighttpd] placeholder page.
+
service lighttpd force-reload
 +
mv /var/www/html/index.lighttpd.html var/www/html/index.html
  
= Install the webSocket libraries =
+
Browse to the PC and check the default web page.
  
== jQuery ==
+
Create a PHP test page <code>/var/www/html/index.php</code>:
 +
<?php phpinfo(); ?>
  
Download the [http://jquery.com/download/ latest compressed, production jQuery version].
+
Browse to the PC and check <code>index.php</code>.
wget http://code.jquery.com/jquery-2.1.4.min.js
+
-->
  
== XML::Simple ==
+
= Install Mojolicious Lite =
  
Check if the <code>XML::Simple</code> is already installed:
+
[https://metacpan.org/pod/Mojolicious::Lite Mojolicious::Lite]
perl -MFile::Find=find -MFile::Spec::Functions -Tlw -e 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC' 2> /dev/null | grep -i 'XML/Simple.pm'
+
can be installed with the standard [https://www.cpan.org/ CPAN] method.
 +
For Debian and related distributions such as Ubuntu, a dedicated option is to use:
 +
sudo apt install libmojolicious-perl
  
Install the library:
+
= Test the REST server =
perl -MCPAN -e "install 'XML::Simple'"
+
  
Alternatively, on Ubuntu:
+
Download the [http://www.dspc.ch/xPL/Downloads/xpl-homeStateRest.pl xPL home state REST interface] script.
apt-get install libxml-simple-perl
+
  
== Net::WebSocket::Server ==
+
Start the server:
 +
REST_PORT=13865
 +
REST_SERVICE_DIRECTORY='/home/control/Documents/Controls'
 +
morbo -l <nowiki>http://*:$REST_PORT</nowiki> $REST_SERVICE_DIRECTORY/xpl-homeStateRest.pl
 +
This starts an HTTP service.
 +
Each time the Perl script is updated, the service is updated too.
 +
Interpretor errors are displayed in the terminal in whick the [https://mojolicious.org/perldoc/morbo morbo] runs.
  
Check if the <code> XML::Simple</code> is already installed:
+
Test the service in another terminal window:
  perl -MFile::Find=find -MFile::Spec::Functions -Tlw -e 'find { wanted => sub { print canonpath $_ if /\.pm\z/ }, no_chdir => 1 }, @INC' 2> /dev/null | grep -i 'WebSocket/Server.pm'
+
REST_PORT=13865
 +
curl -X GET localhost:$REST_PORT/state/study/lights/ceiling && echo
 +
  curl -X PUT localhost:$REST_PORT/state/study/lights/ceiling/on
 +
<!--
 +
curl -X GET localhost:$REST_PORT/test/hello/world?'a=b&c=d'
 +
-->
  
Install the library:
+
Check the result in:
  perl -MCPAN -e "install 'Net::WebSocket::Server'"
+
  cat /tmp/xpl-homeStateRest.log
  
= Prepare a home control page =
+
= Install the REST server =
  
Create the home control directory:
+
Once the script works, stop it with <code>ctrl-C</code>.
  WWW_CONTROL=$WWW_ROOT/homeControl
+
Launch it as a daemon:
mkdir -p $WWW_CONTROL
+
  $REST_SERVICE_DIRECTORY/xpl-homeStateRest.pl daemon -l <nowiki>http://*:$REST_PORT</nowiki> 2>/devull &
chmod -R 775 $WWW_CONTROL
+
chown -R control:users $WWW_CONTROL
+
cd $WWW_CONTROL
+
  
In this directory, create a <code>simple.html</code> control page:
+
Stop the daemon:
<pre>
+
pkill -f xpl-homeStateRest
<html>
+
  <head>
+
    <script src="//code.jquery.com/jquery-1.11.0.min.js">
+
    </script>
+
  </head>
+
  <body>
+
    <!-- Light controls .................................................... -->
+
    <br />
+
    <table align="center" border='0px' cellpadding='12px' cellspacing='0px' bgcolor="#CCCCCC">
+
      <tr>
+
        <th width="240px">ceiling</th>
+
        <th width="240px">stand</th>
+
      </tr>
+
      <tr>
+
        <td align="center"><input id="ceiling" type="checkbox" /></td>
+
        <td align="center"><input id="stand" type="checkbox" /></td>
+
      </tr>
+
    </table>
+
  
    <!-- Websocket java script ............................................. -->
+
== Debian with SystemD ==
    <script>
+
      $().ready(function() {
+
        var ws = new WebSocket('ws://harmonia.local:8080/');
+
  
        ws.onopen = function() {
+
On Debian with [https://wiki.debian.org/systemd systemd] (such as [https://www.raspbian.org/ Raspbian]
          console.log("Web socket started");
+
or [https://www.ubuntu.com/ Ubuntu]), the scripts can be defined as services.
        }
+
                                                            // outgoing messages
+
        $('#ceiling').on('change', function() {
+
          ws.send('ceiling ' + $(this).is(':checked'));
+
        });
+
        $('#stand').on('change', function() {
+
          ws.send('stand ' + $(this).is(':checked'));
+
        });
+
                                                              // polling message
+
        window.setInterval(
+
          function() {
+
            ws.send('poll request');
+
          }
+
          , 100
+
        );
+
                                                            // incoming messages
+
        ws.onmessage = function(message) {
+
          console.log(message.data);
+
          var words = message.data.split(' ');
+
  
          if (words[0] === 'ceiling') {
+
Edit <code>/lib/systemd/system/xpl-homeStateRest.service</code>:
              $('#ceiling').prop('checked', words[1] == 'true');
+
[Unit]
          }
+
Description=xPL home state REST interface
          if (words[0] === 'stand') {
+
After=network.target
              $('#stand').prop('checked', words[1] == 'true');
+
          }
+
[Service]
        }
+
Type=simple
      });
+
User=control
    </script>
+
Group=users
 +
ExecStart=/home/control/Documents/Controls/xpl-homeStateRest.pl daemon -m production -l http://*:13865
 +
Restart=always
 +
 +
[Install]
 +
WantedBy=multi-user.target
  
  </body>
+
Activate the service:
</html>
+
su
</pre>
+
systemctl enable xpl-homeStateRest.service
Navigate to the control page: <code>http://harmonia.local/homeControl/simple.html</code>
+
service xpl-homeStateRest start
 
+
= Implement a webserver client =
+
  
 +
Reboot and check:
 +
ps ax | grep -v grep | grep -i xpl
 +
ps aux | grep -i xpl | grep -v grep | sed 's/.*\/Controls\///'
 +
systemctl list-units --type=service --state=running | grep xpl
 +
service xpl-homeStateRest status
  
 
[[Category: all]] [[Category: install]] [[Category: web]]
 
[[Category: all]] [[Category: install]] [[Category: web]]

Latest revision as of 17:30, 26 May 2020

Controlling the home from distance can be made via standard web access methods such as the RESTful API.

Different options are available for the implementation of such a service:

  • Installing a web server and writing CGI scipts
  • Writing scripts serving a TCP socket and complying to the HTTP scheme
  • Using a framework such as:

I have chosen Mojolicious Lite for its simplicity and the ease of development.

Before all, make sure you have installed an xPL hub together with the xPL state monitor.


Install Mojolicious Lite

Mojolicious::Lite can be installed with the standard CPAN method. For Debian and related distributions such as Ubuntu, a dedicated option is to use:

sudo apt install libmojolicious-perl

Test the REST server

Download the xPL home state REST interface script.

Start the server:

REST_PORT=13865
REST_SERVICE_DIRECTORY='/home/control/Documents/Controls'
morbo -l http://*:$REST_PORT $REST_SERVICE_DIRECTORY/xpl-homeStateRest.pl

This starts an HTTP service. Each time the Perl script is updated, the service is updated too. Interpretor errors are displayed in the terminal in whick the morbo runs.

Test the service in another terminal window:

REST_PORT=13865
curl -X GET localhost:$REST_PORT/state/study/lights/ceiling && echo
curl -X PUT localhost:$REST_PORT/state/study/lights/ceiling/on

Check the result in:

cat /tmp/xpl-homeStateRest.log

Install the REST server

Once the script works, stop it with ctrl-C. Launch it as a daemon:

$REST_SERVICE_DIRECTORY/xpl-homeStateRest.pl daemon -l http://*:$REST_PORT 2>/devull &

Stop the daemon:

pkill -f xpl-homeStateRest

Debian with SystemD

On Debian with systemd (such as Raspbian or Ubuntu), the scripts can be defined as services.

Edit /lib/systemd/system/xpl-homeStateRest.service:

[Unit]
Description=xPL home state REST interface
After=network.target

[Service]
Type=simple
User=control
Group=users
ExecStart=/home/control/Documents/Controls/xpl-homeStateRest.pl daemon -m production -l http://*:13865
Restart=always

[Install]
WantedBy=multi-user.target

Activate the service:

su
systemctl enable xpl-homeStateRest.service
service xpl-homeStateRest start

Reboot and check:

ps ax | grep -v grep | grep -i xpl
ps aux | grep -i xpl | grep -v grep | sed 's/.*\/Controls\///'
systemctl list-units --type=service --state=running | grep xpl
service xpl-homeStateRest status