beep-projects / SystaPi

Adding WiFi and a REST API to Paradigma SystaComfort units
GNU General Public License v3.0
16 stars 3 forks source link
home-automation raspberry-pi systacomfort
SystaPi

GitHub license JUnit shellcheck Pylint GitHub issues GitHub forks GitHub stars GitHub repo size
Scc Count Badge Scc Count Badge Scc Count Badge Scc Count Badge Scc Count Badge Visitors

SystaPi and SystaREST

SystaPi adds a REST API to Paradigma SystaComfort units. The goal of this project is to make the Paradigma system compatible with every home automation system that supports REST APIs. The project contains an installation script to setup a Raspberry Pi as SystaPi for running the SystaREST server. Up to now only reading of values is supported by SystaREST, see the documentation for details of the supported fields Javadoc: SystaStatus.

SystaPi Dashboard rawData_react_html
Note: The communication protocol is not publicly available! Everything here is based on reverse engineering and will only work for systems that are used by contributors. Please contribute information from your system!

To support you in reverse engineering, the server has a rudimentary logging functionality integrated. dashboard gives you an overview of the known values received in the last 24h and has buttons to start/stop the logging and to download all log files as zip, for easy logfile handling.
You can also use monitorrawdata to monitor the data sent by SystaPi and contribute new fields that you can identify with your system (see also monitorrawdata). These pages are created using React, so you also can use them as starting point for creating your own dashboard.

If you want to report new fields, simply open a new issue or discussion.

This project is inspired by this post on the VDR portal Heizungssteuerung: Daten auslesen and I also used some information from the SystaComfortPrometheusExporter.

Build with a Raspberry Pi Zero WH and ENC28J60 Ethernet HAT, the SystaPi fits easily into the housing of the Paradigma SystaComfort.
SystaPi SystaComfort_and_Pi_open SystaComfort_and_Pi_closed

Content

Directory Structure of this Project

SystaPi
├── docs                 # JavaDoc for the SystaRESTServer, best accessed via https://beep-projects.github.io/SystaPi/
├── helpers              # collection of resources that are helpful for reverse engineering the SystaComfort protocol
│                        # or setting up systapi
├── install_systapi.sh   # Script for automatically downloading, flashing and configuring 
│                        # a Micro SD card for running the SystaREST server
├── LICENSE              # License for using and editing this software
├── README.md            # This file
├── resources            # folder for images or other files linked with README.md
├── SystaPi_files        # files required for configuring a Raspberry Pi OS image to run the SystaRESTAPI server
│   ├── cmdline.txt      # file to be placed under /boot/cmdline.txt on the pi. Triggers the execution of firstrun.sh
│   │                    # on first boot (actually the second one, after resizing the image)
│   ├── firstrun.sh      # script for configuring WiFi, keyboard and timezone. You have to configure a few things in here!
│   ├── secondrun.sh     # called after a reboot. Should have network running. Does a full-upgrade of the system, 
│   │                    # installs required packages (dnsmasq, OpenJDK) and the SystaRESTAPI.service
│   └── thirdrun.sh      # called after a reboot. Cleans up after the installation and reboots into the final system
└── SystaRESTServer      # Java based server for providing a REST API for a Paradigma SystaComfort unit
    ├── bin              # precompiled .class files for running the SystaRESTAPI server
    ├── build.sh         # build file for compiling SystaRESTServer
    ├── build_test.sh    # build file for building the JUnit test run at each commit
    ├── lib              # .jar files required for running the server
    └── src              # src files of the server, for everyone who wants to improve this

Parts List

This is what I am using for this project, but any Raspberry Pi with at least one Ethernet interface and a second WiFi or Ethernet interface should do the job. The required size of the Micro SD card depends on the amount of data you want to log. Logging data of one day requires ~100 MB.

Of course you also need a Paradigma SystaComfort or Paradigmy SystaComfort II. The following are the paradigma software versions that I succesfully used with SystaPi (#1, #2) or that where reported to work (#3)

#1 #2 #3
SystaComfort V1.14 8.08.14 V1.26 10.02.20 V1.12 20.05.14
System V2.09.2 V2.16.1 V2.09.1
Basis V0.23 V0.34 V0.23

Installation

For easy installation I have created some scripts that configure the Raspberry Pi OS automatically on a Micro SD card. These scripts are not actively maintained, so they might stop working at some time. If auto configuration fails, step through the files firstrun.sh and secondrun.sh and run the commands manually on your systapi. Your are also welcome to fix the scripts and create a pull request to this repository.

Once the Micro SD card is prepared as described in the next sections, the scripts should do the following on first boot ups of the Raspberry Pi:

SystaComfort

You have to make sure that your Paradigma SystaComfort unit is sending unencrypted data to paradigma.remoteportal.de. If you are one of the unlucky ones, that got a SystaComfort installed with encryption enabled, or the remote portal being disable, you have to get hold of the SystaService software. You can ask Paradigma for that, or your system installer. See also the instructions for setting up the SystaComfortPrometheusExporter english/german

Linux

For Linux I provide a script that downloads Raspberry Pi OS and flashes it onto a Micro SD card. The script was mainly written out of curiosity to see how that could work. So it has no added sanity checks and you should use it with care. Check each step, when asked to confirm. If unsure, follow the manual installation guide.

  1. Run the following commands in a shell for downloading and unzipping the project files

    wget https://github.com/beep-projects/SystaPi/releases/download/2.2/SystaPi-2.2.zip
    unzip SystaPi-2.2.zip
  2. Open SystaPi-2.2/SystaPi_files/firstrun.sh with a text editor and configure everything in the marked section to your liking. Most probably you want to generate your WPA_PASSPHRASE via wpa_passphrase MY_WIFI passphrase , or use the WPA PSK (Raw Key) Generator, and add the credentials to the file. If you use the network 192.168.1.x for your local network, you should change the IP_PREFIX to another IP range, to avoid network collisions

    #-------------------------------------------------------------------------------
    #----------------------- START OF CONFIGURATION --------------------------------
    #-------------------------------------------------------------------------------
    
    # which hostname do you want to give your raspberry pi?
    HOSTNAME=systapi
    #username: beep, password: projects
    #you can change the password if you want and generate a new password with
    #Linux: mkpasswd --method=SHA-256
    #Windows: you can use an online generator like https://www.dcode.fr/crypt-hasing-function
    USER=beep
    # shellcheck disable=SC2016
    PASSWD='$5$oLShbrSnGq$nrbeFyt99o2jOsBe1XRNqev5sWccQw8Uvyt8jK9mFR9' #keep single quote to avoid expansion of $
    # configure the wifi connection
    # the example WPA_PASSPHRASE is generated via
    #     wpa_passphrase MY_WIFI passphrase
    # but you also can enter your passphrase as plain text, if you accept the potential insecurity of that approach
    SSID=MY_WIFI
    WPA_PASSPHRASE=3755b1112a687d1d37973547f94d218e6673f99f73346967a6a11f4ce386e41e
    # define the network to use for communication between systapi and Systa Comfort
    # change if you use the same network range on your wifi network
    IP_PREFIX="192.168.1"
    # configure your timezone and key board settings
    TIMEZONE="Europe/Berlin"
    COUNTRY="DE"
    XKBMODEL="pc105"
    XKBLAYOUT=$COUNTRY
    XKBVARIANT=""
    XKBOPTIONS=""
    # if you want to use an ENC28J60 Ethernet HAT, enable it here
    ENABLE_ENC28J60=true
    
    #-------------------------------------------------------------------------------
    #------------------------ END OF CONFIGURATION ---------------------------------
    #-------------------------------------------------------------------------------
  3. Insert the Micro SD card that you want to get prepared as SystaPi into your computing device

  4. Continue in the shell

    cd SystaPi-2.2
    ./install_systapi.sh
  5. Eject the Micro SD card and insert it into your Raspberry Pi

  6. Connect the Raspberry Pi with an Ethernet cable to your Paradigma SystaComfort

  7. Power up the Raspberry Pi

  8. Wait a while (~20 minutes, depending on the number of system updates available) and then try to load the WADL of the server: http://systapi:1337/application.wadl?detail=true For troubleshooting, you can check the progress by checking the logs. After 5 minutes the resize of the partitions and firstrun.sh should be finished, so that you can ssh into the systapi and watch the installation process. Default user is beep with password projects.

    ssh -x beep@systapi.local
    tail -f /boot/secondrun.log

Windows / manual installation

  1. Install Raspberry Pi OS following this guide. Raspberry Pi OS Lite is sufficient.

  2. Download SystaPi

  3. Extract the downloaded zip file

  4. Change into the SystaPi_files subfolder of the extracted archive

  5. Open firstrun.sh with a text editor and configure everything in the marked section to your liking. Most probably you want to use something like WPA PSK (Raw Key) Generator and add the generated credentials to the file. If you use the network 192.168.1.x for your local network, you should change the IP_PREFIX to another IP range, to avoid network collisions

    #-------------------------------------------------------------------------------
    #----------------------- START OF CONFIGURATION --------------------------------
    #-------------------------------------------------------------------------------
    
    # which hostname do you want to give your raspberry pi?
    HOSTNAME=systapi
    #username: beep, password: projects
    #you can change the password if you want and generate a new password with
    #Linux: mkpasswd --method=SHA-256
    #Windows: you can use an online generator like https://www.dcode.fr/crypt-hasing-function
    USER=beep
    # shellcheck disable=SC2016
    PASSWD='$5$oLShbrSnGq$nrbeFyt99o2jOsBe1XRNqev5sWccQw8Uvyt8jK9mFR9' #keep single quote to avoid expansion of $
    # configure the wifi connection
    # the example WPA_PASSPHRASE is generated via
    #     wpa_passphrase MY_WIFI passphrase
    # but you also can enter your passphrase as plain text, if you accept the potential insecurity of that approach
    SSID=MY_WIFI
    WPA_PASSPHRASE=3755b1112a687d1d37973547f94d218e6673f99f73346967a6a11f4ce386e41e
    # define the network to use for communication between systapi and Systa Comfort
    # change if you use the same network range on your wifi network
    IP_PREFIX="192.168.1"
    # configure your timezone and key board settings
    TIMEZONE="Europe/Berlin"
    COUNTRY="DE"
    XKBMODEL="pc105"
    XKBLAYOUT=$COUNTRY
    XKBVARIANT=""
    XKBOPTIONS=""
    # if you want to use an ENC28J60 Ethernet HAT, enable it here
    ENABLE_ENC28J60=true
    
    #-------------------------------------------------------------------------------
    #------------------------ END OF CONFIGURATION ---------------------------------
    #-------------------------------------------------------------------------------
  6. Make sure that the boot-partition of the Micro SD card is accessible via file explorer

  7. Open cmdline.txt from the Micro SD card and copy the root=PARTUUID=-Number over into the cmdline.txt in the SystaPi_files subfolder. If you do not do this step, your pi will not boot!

  8. Copy all files from the SystaPi_files subfolder to boot-partition of the Micro SD card

  9. Copy the SystaRESTServer folder and all of its content to the boot-partition.

  10. Eject the Micro SD card and insert it into your Raspberry Pi

  11. Connect the Raspberry Pi with an Ethernet cable to your Paradigma SystaComfort

  12. Power up the Raspberry Pi

  13. Wait a while (~20 minutes, depending on the number of system updates available) and then try to load the WADL of the server: http://systapi:1337/application.wadl?detail=true For troubleshooting, you can check the progress by checking the logs. After 5 minutes the resize of the partitions and firstrun.sh should be finished, so that you can ssh into the systapi and whatch the installation process.. Default user is beep with password projects.

    ssh -x beep@systapi.local
    tail -f /boot/secondrun.log

Troubleshooting the installation

  1. The autoconfig of the Raspberry Pi OS worked fine when I did the commit for it. But if development of Raspberry Pi OS goes on, the scripts might break. If you connect the Raspberry Pi to a screen via HDMI, you will see if something gets wrong.
  2. If the pi does not boot, check if you did step 7 in case of a manual installation.
  3. If you do not know where the install script died on the Raspberry Pi, have a look into the /boot folder via ls /boot/*.log. Each script creates a log file, so check firstrun.log, secondrun.log and thirdrun.log, to see where the script failed.
  4. SystaRESTServer is installed as a service on the raspberry pi. systemctl status SystaRESTServer.service will show you if the service is running or died for some reason

The SystaREST API

Per default, the SystaREST server is listening on port 1337, you can change this by editing /home/pi/SystaRESTServer/bin/SystaREST.properties. The hostname of the Raspberry Pi is set to systapi. The path and method names on the REST server are implemented case insensitive. The root path is: systarest, or SystaREST, or any variation you like. So you should be able to access the server via http://systapi:1337/SystaREST/. This base URL will be used for the following examples and should work for most network configurations. If not, you have to replace systapi with the URL assigned by your router. The server provides a WADL of the provided API at: http://systapi:1337/application.wadl?detail=true If a command is called which should retrieve data from the SystaREST, but the communication is not running, start is automatically called, but the reply will be empty until the first data packet is received from the Paradigma SystaComfort. Data packets are sent every minute.

findsystacomfort

GET /SystaREST/findsystacomfort http://systapi:1337/SystaREST/findsystacomfort
Searches the available interfaces for any attached SystaComfort unit.

curl "http://systapi:1337/SystaREST/findsystacomfort"
{
    "SystaWebIP":"192.168.11.1",
    "SystaWebPort":22460,
    "DeviceTouchBcastIP":"192.168.11.255",
    "DeviceTouchBcastPort":8001,
    "deviceTouchInfoString":"SC2 1 192.168.11.23 255.255.255.0 192.168.11.1 SystaComfort-II\u00000 0809720001 0 V0.34 V1.00 2CBE9700BEE9",
    "unitIP":"192.168.11.23",
    "unitName":"SystaComfort-II",
    "unitId":"0809720001",
    "unitApp":8,
    "unitPlatform":9,
    "unitVersion":"1.14.1",
    "unitMajor":114,
    "unitMinor":1,
    "unitBaseVersion":"V0.34",
    "unitMac":"2CBE9700BEE9",
    "STouchAppSupported":false,
    "DeviceTouchPort":-1,
    "DeviceTouchPassword":"null"
}

start

POST /SystaREST/start
start communication with the connected Paradigma SystaComfort

curl -X POST http://systapi:1337/SystaREST/start

stop

POST /SystaREST/stop
stop communication with the connected Paradigma SystaComfort

curl -X POST http://systapi:1337/SystaREST/stop

servicestatus

GET /SystaREST/servicestatus
http://systapi:1337/SystaREST/servicestatus
Returns the status of the SystaREST server

curl "http://systapi:1337/SystaREST/servicestatus"
{
    "connected":true,
    "running":true,
    "lastDataReceivedAt":"Wed-30.06.21-00:00:19",
    "packetsReceived":234,
    "paradigmaListenerIP":"192.168.1.1",
    "paradigmaListenerPort":22460,
    "paradigmaIP":"192.168.1.23",
    "paradigmaPort":8002,
    "loggingData":false,
    "logFileSize":60,
    "logFilePrefix":"SystaREST",
    "logFileDelimiter":";",
    "logFileRootPath":"/home/pi/SystaRESTServer/bin/",
    "logFilesWritten":0,
    "logBufferedEntries":60
}

rawdata

GET /SystaREST/rawdata http://systapi:1337/SystaREST/rawdata
Returns the raw data received from the Paradigma Systa Comfort with added timestamp information.

curl "http://systapi:1337/SystaREST/rawdata"
{
    "timestamp":1623836832,
    "timestampString":"Wed-16.06.21-09:47:12",
    "rawData":[
        250,
        273,
        277,
        736,
        650,
        565,
        -300,
        -300,
        -300,
        0,
        0,
        0,
        332,
        ... (250 entries) ...
    ]
}

dashboard

GET /SystaREST/dashboard http://systapi:1337/SystaREST/dashboard

Returns a React-based HTML dashboard that displays the received data for the last 24h. On the bottom right of the dashboard, you can start the logging of data (log/stop), delete the log files on the SystaPi (del) and download all saved logs as zip file (zip). Call this function from your browser, to see something like:

systapidashboard

monitorrawdata

GET /SystaREST/monitorrawdata http://systapi:1337/SystaREST/monitorrawdata

Optional parameters:

Returns a React-based HTML page for monitoring of the raw data received from the Paradigma Systa Comfort. The content of the page should automatically refresh, but be aware that the SystaComfort sends its data only every minute, so parameter changes on the unit will be displayed with some lag. Call this function from your browser, to see something like:

http://systapi:1337/SystaREST/monitorrawdata http://systapi:1337/SystaREST/monitorrawdata?theme=systaweb
rawData_react_html rawData_react_html

waterheater

GET /SystaREST/waterheater
http://systapi:1337/SystaREST/waterheater
Returns the information for a Home Assistant Water Heater

curl "http://systapi:1337/SystaREST/waterheater"
{
    "min_temp":40.0,
    "max_temp":65.0,
    "current_temperature":71.0,
    "target_temperature":0.0,
    "target_temperature_high":85.0,
    "target_temperature_low":0.0,
    "temperature_unit":"TEMP_CELSIUS",
    "current_operation":"locked",
    "operation_list":[
        "off",
        "normal",
        "comfort",
        "locked"
    ],
    "supported_features":[
    ],
    "is_away_mode_on":false,
    "timestamp":1623675405,
    "timestampString":"Mon-14.06.21-12:56:45"
}

status

GET /SystaREST/status
http://systapi:1337/SystaREST/status
Returns all known fields from the received data.

curl "http://systapi:1337/SystaREST/status"
{
    "outsideTemp":7.9,
    "operationMode":0,
    "operationModeName":"Auto Prog. 1",
    "circuit1FlowTemp":42.9,
    "circuit1ReturnTemp":29.8,
    "circuit1FlowTempSet":44.2,
    "circuit1LeadTime":0,
    "hotWaterTemp":59.3,
    "hotWaterTempSet":50.0,
    "hotWaterTempNormal":50.0,
    "hotWaterTempComfort":60.0,
    "hotWaterTempMax":85.0,
    "hotWaterOperationMode":1,
    "hotWaterOperationModeName":"normal",
    "hotWaterHysteresis":5.0,
    "bufferTempTop":54.6,
    "bufferTempBottom":34.0,
    "bufferTempSet":44.2,
    "logBoilerFlowTemp":21.3,
    "logBoilerReturnTemp":17.9,
    "logBoilerBufferTempTop":-30.2,
    "logBoilerBufferTempMin":30.0,
    "logBoilerTempMin":65.0,
    "logBoilerSpreadingMin":100.0,
    "logBoilerPumpSpeedMin":60,
    "logBoilerPumpSpeedActual":0,
    "logBoilerSettings":19,
    "boilerOperationMode":0,
    "boilerOperationModeName":"off",
    "boilerFlowTemp":37.6,
    "boilerReturnTemp":37.6,
    "boilerTempSet":0.0,
    "boilerSuperelevation":0,
    "boilerHysteresis":5.0,
    "boilerOperationTime":5,
    "boilerShutdownTemp":40.0,
    "boilerPumpSpeedMin":25,
    "circulationTemp":-30.0,
    "circulationPumpIsOn":false,
    "circulationPumpOverrun":3,
    "circulationLockoutTimePushButton":15,
    "circulationHysteresis":5.0,
    "circuit2FlowTemp":-30.0,
    "circuit2ReturnTemp":-30.0,
    "circuit2FlowTempSet":44.2,
    "roomTempActual1":0.0,
    "roomTempSet1":20.0,
    "roomTempActual2":0.0,
    "roomTempSet2":0.0,
    "roomTempSetNormal":20.0,
    "roomTempSetComfort":22.0,
    "roomTempSetLowering":15.0,
    "roomImpact":0.0,
    "roomTempCorrection":0.0,
    "collectorTempActual":0.0,
    "swimmingpoolFlowTemp":0.0,
    "swimmingpoolFlowTeamp":0.0,
    "swimmingpoolReturnTemp":0.0,
    "heatingOperationMode":1,
    "heatingOperationModeName":"normal",
    "heatingCurveBasePoint":35.0,
    "heatingCurveGradient":1.3,
    "heatingLimitTemp":20.0,
    "heatingLimitTeampLowering":10.0,
    "heatingPumpSpeedActual":100,
    "heatingPumpOverrun":10,
    "heatingPumpIsOn":true,
    "heatingCircuitSpreading":20.0,
    "heatingPumpSpeedMin":100,
    "controlledBy":0,
    "controlMethodName":"external temp",
    "maxFlowTemp":70.0,
    "antiFreezeOutsideTemp":2.0,
    "heatUpTime":120,
    "mixerRuntime":2,
    "mixer1IsOnWarm":false,
    "mixer1IsOnCool":false,
    "mixer1State":0,
    "mixer1StateName":"off",
    "underfloorHeatingBasePoint":35.0,
    "underfloorHeatingGradient":1.3,
    "bufferTempMax":95.0,
    "bufferTempMin":0.0,
    "adjustRoomTempBy":0.0,
    "solarPowerActual":0.0,
    "solarGainDay":0.0,
    "solarGainTotal":0.0,
    "relay":2049,
    "chargePumpIsOn":false,
    "boilerIsOn":false,
    "burnerIsOn":false,
    "systemNumberOfStarts":26,
    "burnerNumberOfStarts":394,
    "boilerOperationTimeHours":234,
    "boilerOperationTimeMinutes":58,
    "unknowRelayState1IsOn":false,
    "unknowRelayState2IsOn":true,
    "unknowRelayState5IsOn":true,
    "error":65535,
    "operationModeX":0,
    "heatingOperationModeX":1,
    "timestamp":1640345997,
    "timestampString":"Fri-24.12.21-11:39:57"
}

enablelogging

PUT /SystaREST/enablelogging
enables the logging of each received data element to a delimited log file. To reduce the number of file writes, this function stores entriesPerFile data segments in memory and then writes them into a single file. If logging is not enabled, SystaREST still stores the last entriesPerFile data segments in memory and saves them to the disc as soon as logging gets enabled. This feature shall help to implement triggers for value changes of interest, by also saving data that has been received before the interesting event happened.

Optional parameters:

curl -X PUT "http://systapi:1337/SystaREST/enablelogging?filePrefix=SystaREST&logEntryDelimiter=;&entriesPerFile=1337"

disablelogging

PUT /SystaREST/disablelogging
stop the logging of received data packets. This writes all currently stored data segments to a file and stops the writing to disc.

curl -X PUT http://systapi:1337/SystaREST/disblelogging

Known Issues

There are some ENC28J60 modules sold with wrong jumper settings. Make sure you set the jumpers as in the picture on the left (vertically connecting the PINs).

correct wrong
correct jumper settings wrong jumper settings

Links