= Deploy OpenEMS Edge on Debian Linux
:sectnums:
:sectnumlevels: 4
:toclevels: 4
:experimental:
:keywords: AsciiDoc
:source-highlighter: highlight.js
:icons: font
:imagesdir: ../../../assets/images

This chapter explains how OpenEMS can be deployed on a Debian Linux Internet-of-Things Gateway. Similar techniques will work for other operating systems as well.

This guide covers a simple, manual approach. For productive systems it is required to automate deployment to IoT devices. Good approaches include a Debian package repository that provides *.deb-files and third-party tools like http://www.eclipse.org/hawkbit/[Eclipse Hawkbit]. This is out-of-scope for this small guide.

Prerequisites:

* A target device running Debian Linux like a Raspberry Pi, Beaglebone Black or an IoT gateway. You need the IP address and SSH access.
* Create a JAR-file that should be deployed. See xref:edge/build.adoc[Build OpenEMS Edge] for details. Alternatively you may download the latest release `openems-edge.jar` file from https://github.com/OpenEMS/openems/releases[GitHub] under _Assets_.
* Setup an SSH client to connect to the Linux console, e.g. http://www.9bis.net/kitty/[KiTTY]
* Setup an SCP client to copy the JAR file via SSH, e.g. https://winscp.net/eng/docs/lang:de[WinSCP]

== Connect via SSH and SCP

. Connect via SSH using KiTTY
.. Open KiTTY and connect to the target device.
+
Make sure to select SSH with port 22 and enter the IP address of the target device. Press the btn:[Open] button.
+
.KiTTY Configuration
image::deploy-kitty.png[KiTTY Configuration]

.. Gain root permissions either by logging in as user *root* or by login in as a default user and executing *sudo -s*.
+
.KiTTY Configuration
image::deploy-ssh-root.png[KiTTY Configuration]
+
NOTE: As an example, for the FENECON Energy Management System (FEMS) it is required to: +
_login as:_ `fems` +
_fems@192.168.178.38's password:_ `device specific password` +
... +
_fems@femsXXX:~$_ `sudo -s` +
_[sudo] password for fems:_ `device specific password` +
_root@femsXXX:/home/fems#_

. Connect via SCP using WinSCP

.. If you are lucky and have a fully configured system, right-click on the KiTTY window bar and select btn:[Start WinSCP].
+
.Start WinSCP from KiTTY
image::deploy-kitty-start-winscp.png[Start WinSCP from KiTTY]

.. Otherwise open WinSCP separately, create a new connection, select *SCP* as protocol and enter again the IP address and port 22. Click btn:[Connect] once finished.
+
.Start WinSCP from KiTTY
image::deploy-winscp.png[Start WinSCP from KiTTY]

== Prepare operating system environment

=== Check JAVA version

Ensure that a JRE version 21 or later is installed. We recommend using `temurin-21-jre`

For detailed installation instructions, visit https://adoptium.net/de/installation/linux/[Adoptium Installation Guide].

NOTE: If you are using an *ARM32* device, download https://openems.io/download/temurin-21-jre-armhf_21.0.6+2.deb[temurin-21-jre-armhf_21.0.6+2.deb] directly from OpenEMS.

=== Create an application directory

Create the directory */usr/lib/openems*. This is going to be the place, where we put the JAR file.

Execute `mkdir /usr/lib/openems`.

=== Create a config directory

Create the directory */etc/openems.d*. This is going to be the place, where all the bundle configurations are held.

Execute `mkdir /etc/openems.d`.

=== Create a systemd service definition

The systemd 'Service Manager' manages system processes in a Debian Linux. We will create a systemd service definition file, so that systemd takes care of managing (starting/restarting/...) the OpenEMS Edge service.

. Create and open the service definition file.
+
Execute `nano /etc/systemd/system/openems.service`

. Paste the following content:
+
[source,ini]
----
[Unit]
Description=OpenEMS Edge <1>
After=network.target <2>

[Service]
User=root <3>
Group=root
Type=notify <4>
WorkingDirectory=/usr/lib/openems
ExecStart=/usr/bin/java -Dfelix.cm.dir=/etc/openems.d/ -jar /usr/lib/openems/openems-edge.jar <5>
SuccessExitStatus=143 <6>
Restart=always <7>
RestartSec=10 <8>
WatchdogSec=60 <9>

[Install]
WantedBy=multi-user.target
----
<1> The name of the service.
<2> The service is allowed to start after network is available (e.g. to be able to access devices via ethernet connection)
<3> It is run as user 'root' to have access to all devices. It is recommended to change this for productive systems.
<4> OpenEMS notifies systemd once it is started up properly.
<5> The start command executes Java, sets the config directory to `/etc/openems.d` and runs the jar file at `/usr/lib/openems/openems-edge.jar`
<6> In contrast to what systemd expects, Java exits with status 143 on success.
<7> Systemd _always_ tries to restart OpenEMS once it was quit.
<8> Systemd waits _10_ seconds till the next restart.
<9> Systemd expects OpenEMS to trigger its watchdog once every 60 seconds. OpenEMS is doing that by default if it detects that it is run by systemd.

. Press btn:[Ctrl] + btn:[x] to exit and btn:[y] to save the file.

. Activate the service definition:
+
Execute `systemctl daemon-reload`

=== Update OpenEMS Edge JAR file

To update the OpenEMS JAR file at the target device, it is required to copy the JAR file from your build directory (see xref:edge/build.adoc[Build OpenEMS Edge]) to `/usr/lib/openems/openems.jar` on the target device. Afterwards it is required to restart the systemd service

. Copy JAR file via SCP.
+
In WinSCP open your local build directory on the left side and */usr/lib/openems/* on the right side. Then drag and drop the file from left to right.
+
.WinSCP copy file
image::deploy-winscp-copy.png[WinSCP copy file]

. Restart OpenEMS systemd service.
+
Execute `systemctl restart openems --no-block; journalctl -lfu openems`
+
The command restarts the service (_systemctl restart openems_) while not waiting for the OpenEMS startup notification (_--no-block_). Then it directly prints the OpenEMS system log (_journalctl -lfu openems_).
+
.OpenEMS Edge start-up
image::deploy-openems-start.png[OpenEMS Edge start-up]
