Metadata-Version: 2.1
Name: productionserver
Version: 0.8.5
Summary: Server (JSON-RPC) with production-tools for edge-device (Leaflet HEMS 1u0022).
Home-page: https://gitlab.consolinno-it.de/leafletfirmware/cls-firmware/leaflet-production-test
Author: Christian Ohnesorg, Stefan Bauer
Author-email: c.ohnesorg@consolinno.de
Project-URL: homepage, https://www.consolinno.de
Classifier: Programming Language :: Python :: 3
Classifier: Operating System :: OS Independent
License-File: LICENSE

include::attributes.inc.adoc[]


= Production Server 1u0022 HEMS (JSON-RPC-Server)
:toc:

== Introduction

JSON-RPC-Server running on Leaflet HEMS 1u0022 for testing HW-Interfaces. 
It includes also some methods for public key infrastructure (PKI).
The default network-interface for starting the server is eth0 (HW-naming: LAN1).
The counterpart for testing can be any Linux machine with a 
JSON-RPC-Client (see https://gitlab.consolinno-it.de/leafletfirmware/cls-firmware/testsoftware_gegenspieler[Testsoftware Gegenspieler]).
The JSON-RPC-connection is SSL-secured.


== Dependencies

See requirements.txt.

For JSON-RPC-Server, CAN, serial, Server, GPIOs
```
pip3 install jsonrpclib python-can pyserial 
```

for productionserver/-test < v0.5
```
apt install python3-libgpiod 
```
(all together ~ 1 MB)

== HowTo

=== Start Server

Start server on Leaflet:
```
sudo python3 JSON_RPC_Server_SSL.py [optional: IP-adress]
```

=== Development

TODO document: how to run untagged/unpackaged versions on leaflet for development purposes/how to debug.

== update version
```
 dch -v 0.4.1-0 -D unstable "release message..."
 (push changelog)
 git tag release/0.4.1-0
 git push --tags
```

- Update `/etc/apt/preferences.d/leaflet-production-test.pref` in 
https://gitlab.consolinno-it.de/leafletfirmware/1u0022-product-software/1u0022-system-builder/1-u-0022-base[Systembuilder]
```
Pin: version 0.4.1-0
Pin-Priority: 1000
```

== running productionserver and testsoftware_gegenspieler in docker-compose

For development, you want to have both json-rpc-server and -client up and running in an environment, where you can play around with it. Of course, this has to work without an actual leaflet.
Therefore, we have a docker-compose file, which will setup both parts.

How to use:

1. Go to testsoftware_gegenspieler repository and docker-build the image there according to docs. This will register the "testsoftware_gegenspieler:latest" image in your local registry, which you will need here.

2. Then, execute here:

```
docker compose -f docker/docker-compose.yml up
```

The required key material for SSL-secured connection between client and server is also included here.

3. Connect to the client container and you can simulate parts of manufacturing there.

=== Building debian packages

The productionserver gets packaged and installed as debian package. The packaging happens in the pipeline. We have three stages:

* All commits on the dev branch cause a (manual) snapshot build. The resulting debian artifact can be uploaded to the dev component via manual pipeline job. No manual changes to the changelog and no tags are necessary.
* Also, all commits on the pre-release branch cause manual snapshot builds, which can be uploaded to the qa component. Again, no manual changes to the changelog or tags are necessary.
* PROD Releases work like this:
** You run the following command directly on main:
  ```
  gbp dch -a -R --ignore-branch --spawn-editor=always -D unstable
  ```
  This will open up a text editor where you can fill in the correct version. The distribution should be unstable, as this is completely irrelevant.
** You commit the change on main and push it
** You run the manual pipeline jobs to build and upload the debian package.
** After each release, it is important to merge back main onto dev!!

=== Sending requests to productionserver via postman

The included docker-compose setup forwards the server to localhost:1443, therefore you can also send requests via postman. You just have to configure the required key material (just use the included files again...): -> Settings -> Certificates

=== test build
```
sudo python -m build
```
python-wheel (package) is stored under `dist/` 

install wheel with:

```
(sudo) pip install dist/productionserver-0.4.1-py3-none-any.whl
```
and start server with
```
(sudo) productionserver
```
The productionserver is starting default from a interface called `eth0` (-> LAN-1 on Leaflet). 
If you want to start from another interface, you can specify it as a argument.
The following cmd shows how to start from `localhost`: 
```
(sudo) productionserver localhost
```

=== TODO uninstall python wheel

```
pip uninstall productionserver
```
is not working (tries to delete a lot of python packages)


Manually delete package:
```
rm -rd /usr/local/lib/python3.7/dist-packages/productionserver*
```




=== Class diagramm
Each hardware-interface has its own test. E.g. there is one instance for the 
ethernet-interface, which will be used sequentially for all three eth-interfaces.

The testcases are inherited in the class allTests and are registered as JSON-RPC-methods.
Each testcase is separated in a abstracted test_-file and a hal_-file.

[umlet, "{imagedir}/classdiagramm_testsoftware", png]
....
include::{umletdir}/classdiagramm_testsoftware.uxf[]
....

=== Sequence chart for one test case
Each Interface is tested after the same concept.

[umlet, "{imagedir}/sequence_test", png]
....
include::{umletdir}/sequence_test.uxf[]
....
The answer of getResult[interface] can also contain a error message, which is currenty only implemented in test_wMBus.py.

=== State Machine teststate
Each test will have a state machine with the current teststate, according to the following chart:

[umlet, "{imagedir}/statemachine_testsoftware", png]
....
include::{umletdir}/statemachine_testsoftware.uxf[]
....




== DEBUG 
=== GPIOs
Set default position of Relays

```
gpioset conegx 0=0 1=0 2=0 3=0
```
Set all Relays
```
gpioset conegx 0=1 1=1 2=1 3=1
```
Read switchINs
```
gpioget conegx 12 13 14 15
```
=== Ethernet
```
ping -c 1 -q -s 64 -W 1 -I eth0 www.google.com
```
=== Bluetooth
set up device
```
systemctl start bluetooth
btattach -B /dev/ttymxc1 -S 115200 -N -P h4 &
```
check if bt is set up
```
hcitool dev
```


alternative create service `attach-bluetooth-device`
```
nano /lib/systemd/system/attach-bluetooth-device.service
```
and insert
```
[Unit]
Description=Sets up bluetooth device, after bluetooth.service is acitve.
After=bluetooth.service

[Service]
ExecStartPre=/bin/sleep 1s
ExecStart=/usr/bin/btattach -B /dev/ttymxc1 -S 115200 -N -P h4

[Install]
WantedBy=multi-user.target
```
and afterwards
```
systemctl daemon-reload
systemctl enable attach-bluetooth-device
systemctl enable bluetooth
```


== Dauertest
=== Service for Dauertest

change /lib/systemd/system/production-test.service

```
[Unit]
Description=1U0022 Production Test Server..
After=multi-user.target

[Service]
Type=oneshot
WorkingDirectory=/usr/bin/productiontest
ExecStart=/usr/bin/python3 JSON_RPC_Server_SSL.py

RemainAfterExit=yes

[Install]
WantedBy=multi-user.target
```

```
systemctl daemon-reload
systemctl start production-test
```

If necessary, update testSW in /usr/bin/productiontest/
```
rm -rd /usr/bin/productiontest/*
git clone git@gitlab.consolinno-it.de:leafletfirmware/cls-firmware/leaflet-production-test.git .
```


== Known Issues
* for productionserver > v0.5 -> long-term test fails after ~5 loops (probaly an issue with gpiod v1.5.4)
```
10.15.2.169 - - [11/Mar/2024 10:14:31] "POST / HTTP/1.1" 200 -
Gpio read Error (switchIN3):  [Errno 24] Too many open files: '/sys/bus/gpio/devices/gpiochip5/dev'
10.15.2.169 - - [11/Mar/2024 10:14:31] "POST / HTTP/1.1" 200 -
Gpio read Error (switchIN4):  [Errno 24] Too many open files: '/dev'
10.15.2.169 - - [11/Mar/2024 10:14:32] "POST / HTTP/1.1" 200 -
Gpio init Error (relay) : [Errno 24] Too many open files: '/dev'
Relay init error __init__() should return None, not 'int'
10.15.2.169 - - [11/Mar/2024 10:14:32] "POST / HTTP/1.1" 200 -
Gpio init Error (relay) : [Errno 24] Too many open files: '/dev'
Relay init error __init__() should return None, not 'int'

```
