-
-
Notifications
You must be signed in to change notification settings - Fork 3.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
[kostal-inverter] Cannot connect to PLENTICORE PLUS 10.0 #7492
Comments
I could actually connect to my kostal inverter using this python code: Now, I'm comparing the two codes and figuring out what's the issue with the Java implementation. |
I made the authentication code work with following code. It does not seem too different from the original code. so I'm wondering whether this code is already shipped with the latest docker image. package authtest;
import com.google.gson.*;
import org.eclipse.jdt.annotation.Nullable;
import org.eclipse.jetty.client.HttpClient;
import org.eclipse.jetty.client.api.ContentResponse;
import org.eclipse.jetty.client.api.Request;
import org.eclipse.jetty.client.util.StringContentProvider;
import org.eclipse.jetty.http.HttpHeader;
import org.eclipse.jetty.http.HttpMethod;
import org.eclipse.jetty.http.HttpVersion;
import javax.crypto.*;
import javax.crypto.spec.GCMParameterSpec;
import javax.crypto.spec.PBEKeySpec;
import javax.crypto.spec.SecretKeySpec;
import java.io.UnsupportedEncodingException;
import java.security.*;
import java.security.spec.InvalidKeySpecException;
import java.util.Base64;
import java.util.Random;
import java.util.concurrent.ExecutionException;
import java.util.concurrent.TimeUnit;
import java.util.concurrent.TimeoutException;
public class OriginalAuthTest {
public static void main(String[] args) {
OriginalAuthTest test = new OriginalAuthTest();
final String host = "192.168.178.149";
final String userPassword = "xxxxxxxx";
test.initHttpClient();
test.authenticate(host, userPassword);
test.closeHttpClient();
}
private HttpClient httpClient;
public void initHttpClient() {
httpClient = new HttpClient();
httpClient.setFollowRedirects(false);
try {
httpClient.start();
} catch (Exception e) {
e.printStackTrace();
}
}
public void closeHttpClient() {
try {
httpClient.stop();
} catch (Exception e) {
e.printStackTrace();
}
}
// ===================================================================================================
/*
* operations used for authentication
*/
private static final String AUTH_START = "/auth/start";
private static final String AUTH_FINISH = "/auth/finish";
private static final String AUTH_CREATE_SESSION = "/auth/create_session";
/*
* operations used for gathering process data from the device
*/
private static final String PROCESSDATA = "/processdata";
/**
* This function is used to authenticate against the SCB.
* SCB uses PBKDF2 and AES256 GCM mode with a slightly modified authentication message.
* The authentication will fail on JRE < 8u162. since the security policy is set to "limited" by default (see readme
* for fix)
*/
public void authenticate(String host, String userPassword) {
// Create random numbers
String clientNonce = createClientNonce();
// Perform first step of authentication
JsonObject authMeJsonObject = new JsonObject();
authMeJsonObject.addProperty("username", USER_TYPE);
authMeJsonObject.addProperty("nonce", clientNonce);
ContentResponse authStartResponseContentResponse;
try {
authStartResponseContentResponse = executeHttpPost(httpClient, host, AUTH_START, authMeJsonObject);
// 200 is the desired status code
int statusCode = authStartResponseContentResponse.getStatus();
if (statusCode == 400) {
// Invalid user (which is hard coded and therefore can not be wrong until the api is changed by the
// manufacturer
return;
}
if (statusCode == 403) {
// User is logged
// This can happen, if the user had to many bad attempts of entering the password in the web
// front end
return;
}
if (statusCode == 503) {
// internal communication error
// This can happen if the device is not ready yet for communication
return;
}
} catch (InterruptedException | TimeoutException | ExecutionException e) {
return;
}
JsonObject authMeResponseJsonObject = getJsonObjectFromResponse(authStartResponseContentResponse);
// Extract information from the response
String salt = authMeResponseJsonObject.get("salt").getAsString();
String serverNonce = authMeResponseJsonObject.get("nonce").getAsString();
int rounds = authMeResponseJsonObject.get("rounds").getAsInt();
String transactionId = authMeResponseJsonObject.get("transactionId").getAsString();
// Do the cryptography stuff (magic happens here)
byte[] saltedPasswort;
byte[] clientKey;
byte[] serverKey;
byte[] storedKey;
byte[] clientSignature;
byte[] serverSignature;
String authMessage;
try {
saltedPasswort = getPBKDF2Hash(userPassword, Base64.getDecoder().decode(salt), rounds);
clientKey = getHMACSha256(saltedPasswort, "Client Key");
serverKey = getHMACSha256(saltedPasswort, "Server Key");
storedKey = getSha256Hash(clientKey);
authMessage = String.format("n=%s,r=%s,r=%s,s=%s,i=%d,c=biws,r=%s", USER_TYPE, clientNonce, serverNonce,
salt, rounds, serverNonce);
clientSignature = getHMACSha256(storedKey, authMessage);
serverSignature = getHMACSha256(serverKey, authMessage);
} catch (NoSuchAlgorithmException | InvalidKeySpecException | InvalidKeyException | IllegalStateException e2) {
return;
}
String clientProof = createClientProof(clientSignature, clientKey);
// Perform step 2 of the authentication
JsonObject authFinishJsonObject = new JsonObject();
authFinishJsonObject.addProperty("transactionId", transactionId);
authFinishJsonObject.addProperty("proof", clientProof);
ContentResponse authFinishResponseContentResponse;
JsonObject authFinishResponseJsonObject;
try {
authFinishResponseContentResponse = executeHttpPost(httpClient, host, AUTH_FINISH, authFinishJsonObject);
authFinishResponseJsonObject = getJsonObjectFromResponse(authFinishResponseContentResponse);
// 200 is the desired status code
if (authFinishResponseContentResponse.getStatus() == 400) {
// Authentication failed
return;
}
} catch (InterruptedException | TimeoutException | ExecutionException e3) {
return;
}
// Extract information from the response
byte[] signature = Base64.getDecoder().decode(authFinishResponseJsonObject.get("signature").getAsString());
String token = authFinishResponseJsonObject.get("token").getAsString();
// Validate provided signature against calculated signature
if (!java.util.Arrays.equals(serverSignature, signature)) {
return;
}
// Calculate protocol key
SecretKeySpec signingKey = new SecretKeySpec(storedKey, HMAC_SHA256_ALGORITHM);
Mac mac;
byte[] protocolKeyHMAC;
try {
mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
mac.init(signingKey);
mac.update("Session Key".getBytes());
mac.update(authMessage.getBytes());
mac.update(clientKey);
protocolKeyHMAC = mac.doFinal();
} catch (NoSuchAlgorithmException | InvalidKeyException e1) {
// Since the necessary libraries are provided, this should not happen
return;
}
byte[] data;
byte[] iv;
// AES GCM stuff
iv = new byte[16];
new SecureRandom().nextBytes(iv);
SecretKeySpec skeySpec = new SecretKeySpec(protocolKeyHMAC, "AES");
GCMParameterSpec param = new GCMParameterSpec(protocolKeyHMAC.length * 8 - AES_GCM_TAG_LENGTH, iv);
Cipher cipher;
try {
cipher = Cipher.getInstance("AES_256/GCM/NOPADDING");
cipher.init(Cipher.ENCRYPT_MODE, skeySpec, param);
} catch (NoSuchAlgorithmException | NoSuchPaddingException | InvalidKeyException | InvalidAlgorithmParameterException e1) {
// The java installation does not support AES encryption in GCM mode
return;
}
try {
data = cipher.doFinal(token.getBytes("UTF-8"));
} catch (IllegalBlockSizeException | BadPaddingException | UnsupportedEncodingException e1) {
// No JSON answer received
return;
}
byte[] ciphertext = new byte[data.length - AES_GCM_TAG_LENGTH / 8];
byte[] gcmTag = new byte[AES_GCM_TAG_LENGTH / 8];
System.arraycopy(data, 0, ciphertext, 0, data.length - AES_GCM_TAG_LENGTH / 8);
System.arraycopy(data, data.length - AES_GCM_TAG_LENGTH / 8, gcmTag, 0, AES_GCM_TAG_LENGTH / 8);
JsonObject createSessionJsonObject = new JsonObject();
createSessionJsonObject.addProperty("transactionId", transactionId);
createSessionJsonObject.addProperty("iv", Base64.getEncoder().encodeToString(iv));
createSessionJsonObject.addProperty("tag", Base64.getEncoder().encodeToString(gcmTag));
createSessionJsonObject.addProperty("payload", Base64.getEncoder().encodeToString(ciphertext));
// finally create the session for further communication
ContentResponse createSessionResponseContentResponse;
JsonObject createSessionResponseJsonObject;
try {
createSessionResponseContentResponse = executeHttpPost(httpClient, host, AUTH_CREATE_SESSION, createSessionJsonObject);
createSessionResponseJsonObject = getJsonObjectFromResponse(createSessionResponseContentResponse);
} catch (InterruptedException | TimeoutException | ExecutionException e) {
return;
}
// 200 is the desired status code
if (createSessionResponseContentResponse.getStatus() == 400) {
return;
}
String sessionId = createSessionResponseJsonObject.get("sessionId").getAsString();
System.out.println("sessionId: " + sessionId);
}
// ===================================================================================================
// List of all constants used for the authentication
static final String USER_TYPE = "user";
static final String HMAC_SHA256_ALGORITHM = "HMACSHA256";
static final String SHA_256_HASH = "SHA-256";
static final int AES_GCM_TAG_LENGTH = 128; // bit count
// ===================================================================================================
/**
* This method generates the HMACSha256 encrypted value of the given value
*
* @param password Password used for encryption
* @param valueToEncrypt value to encrypt
* @return encrypted value
* @throws InvalidKeyException thrown if the key generated from the password is invalid
* @throws NoSuchAlgorithmException thrown if HMAC SHA 256 is not supported
*/
static byte[] getHMACSha256(byte[] password, String valueToEncrypt)
throws InvalidKeyException, NoSuchAlgorithmException {
SecretKeySpec signingKey = new SecretKeySpec(password, HMAC_SHA256_ALGORITHM);
Mac mac = Mac.getInstance(HMAC_SHA256_ALGORITHM);
mac.init(signingKey);
mac.update(valueToEncrypt.getBytes());
return mac.doFinal();
}
/**
* This methods generates the client proof.
* It is calculated as XOR between the {@link clientSignature} and the {@link serverSignature}
*
* @param clientSignature client signature
* @param serverSignature server signature
* @return client proof
*/
static String createClientProof(byte[] clientSignature, byte[] serverSignature) {
byte[] result = new byte[clientSignature.length];
for (int i = 0; i < clientSignature.length; i++) {
result[i] = (byte) (0xff & (clientSignature[i] ^ serverSignature[i]));
}
return Base64.getEncoder().encodeToString(result);
}
/**
* Create the PBKDF2 hash
*
* @param password password
* @param salt salt
* @param rounds rounds
* @return hash
* @throws NoSuchAlgorithmException if PBKDF2WithHmacSHA256 is not supported
* @throws InvalidKeySpecException if the key specification is not supported
*/
static byte[] getPBKDF2Hash(String password, byte[] salt, int rounds)
throws NoSuchAlgorithmException, InvalidKeySpecException {
PBEKeySpec spec = new PBEKeySpec(password.toCharArray(), salt, rounds, 256);
SecretKeyFactory skf = SecretKeyFactory.getInstance("PBKDF2WithHmacSHA256");
return skf.generateSecret(spec).getEncoded();
}
/**
* Create the SHA256 hash value for the given byte array
*
* @param valueToHash byte array to get the hash value for
* @return the hash value
* @throws NoSuchAlgorithmException if SHA256 is not supported
*/
static byte[] getSha256Hash(byte[] valueToHash) throws NoSuchAlgorithmException {
return MessageDigest.getInstance(SHA_256_HASH).digest(valueToHash);
}
/**
* Create the nonce (numbers used once) for the client for communication
*
* @return nonce
*/
static String createClientNonce() {
Random generator = new Random();
// Randomize the random generator
byte[] randomizeArray = new byte[1024];
generator.nextBytes(randomizeArray);
// 3 words of 4 bytes are required for the handshake
byte[] nonceArray = new byte[12];
generator.nextBytes(nonceArray);
// return the base64 encoded value of the random words
return Base64.getMimeEncoder().encodeToString(nonceArray);
}
// ===================================================================================================
// base URL of the web api
private static final String WEB_API = "/api/v1";
// GSON handler
private static final Gson GSON = new GsonBuilder().setDateFormat("yyyy-MM-dd'T'HH:mm:ss.SSS'Z'")
.setFieldNamingPolicy(FieldNamingPolicy.LOWER_CASE_WITH_UNDERSCORES).create();
/**
* Helper function to execute a HTTP post request
*
* @param httpClient httpClient to use for communication
* @param url IP or hostname or the device
* @param resource web API resource to post to
* @param parameters the JSON content to post
* @return the HTTP response for the created post request
* @throws ExecutionException Error during the execution of the http request
* @throws TimeoutException Connection timed out
* @throws InterruptedException Connection interrupted
*/
static ContentResponse executeHttpPost(HttpClient httpClient, String url, String resource, JsonObject parameters)
throws InterruptedException, TimeoutException, ExecutionException {
return executeHttpPost(httpClient, url, resource, parameters, null);
}
/**
* Helper function to execute a HTTP post request
*
* @param httpClient httpClient to use for communication
* @param url IP or hostname or the device
* @param resource web API resource to post to
* @param sessionId optional session ID
* @param parameters the JSON content to post
* @return the HTTP response for the created post request
* @throws ExecutionException Error during the execution of the http request
* @throws TimeoutException Connection timed out
* @throws InterruptedException Connection interrupted
*/
static ContentResponse executeHttpPost(HttpClient httpClient, String url, String resource, JsonElement parameters, @Nullable String sessionId)
throws InterruptedException, TimeoutException, ExecutionException {
Request response = httpClient.newRequest(String.format("%s/%s%s", url, WEB_API, resource), 80).scheme("http")
.agent("Jetty HTTP client").version(HttpVersion.HTTP_1_1).method(HttpMethod.POST)
.header(HttpHeader.ACCEPT, "application/json").header(HttpHeader.CONTENT_TYPE, "application/json")
.timeout(5, TimeUnit.SECONDS);
response.content(new StringContentProvider(parameters.toString()));
if (sessionId != null) {
response.header(HttpHeader.AUTHORIZATION, String.format("Session %s", sessionId));
}
return response.send();
}
/**
* Helper function to execute a HTTP get request
*
* @param httpClient httpClient to use for communication
* @param url IP or hostname or the device
* @param resource web API resource to get
* @return the HTTP response for the created get request
* @throws ExecutionException Error during the execution of the http request
* @throws TimeoutException Connection timed out
* @throws InterruptedException Connection interrupted
*/
static ContentResponse executeHttpGet(HttpClient httpClient, String url, String resource)
throws InterruptedException, TimeoutException, ExecutionException {
return executeHttpGet(httpClient, url, resource, null);
}
/**
* Helper function to execute a HTTP get request
*
* @param httpClient httpClient to use for communication
* @param url IP or hostname or the device
* @param resource web API resource to get
* @param sessionId optional session ID
* @return the HTTP response for the created get request
* @throws ExecutionException Error during the execution of the http request
* @throws TimeoutException Connection timed out
* @throws InterruptedException Connection interrupted
* @throws Exception thrown if there are communication problems
*/
static ContentResponse executeHttpGet(HttpClient httpClient, String url, String resource, @Nullable String sessionId)
throws InterruptedException, TimeoutException, ExecutionException {
Request response = httpClient.newRequest(String.format("%s/%s%s", url, WEB_API, resource), 80).scheme("http")
.agent("Jetty HTTP client").version(HttpVersion.HTTP_1_1).method(HttpMethod.GET)
.header(HttpHeader.ACCEPT, "application/json").header(HttpHeader.CONTENT_TYPE, "application/json")
.timeout(5, TimeUnit.SECONDS);
if (sessionId != null) {
response.header(HttpHeader.AUTHORIZATION, String.format("Session %s", sessionId));
}
return response.send();
}
/**
* Helper to extract the JsonArray from a HTTP response.
* Use only, if you expect a JsonArray and no other types (e.g. JSON array)!
*
* @param reponse the HTTP response
* @return the JSON object
*/
static JsonArray getJsonArrayFromResponse(ContentResponse reponse) {
return GSON.fromJson(reponse.getContentAsString(), JsonArray.class);
}
/**
* Helper to extract the JSON object from a HTTP response.
* Use only, if you expect a JSON object and no other types (e.g. JSON array)!
*
* @param reponse the HTTP response
* @return the JSON object
*/
static JsonObject getJsonObjectFromResponse(ContentResponse reponse) {
return GSON.fromJson(reponse.getContentAsString(), JsonObject.class);
}
} My packages I used as pom.xml <?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0"
xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 http://maven.apache.org/xsd/maven-4.0.0.xsd">
<modelVersion>4.0.0</modelVersion>
<groupId>kostalinverter</groupId>
<artifactId>kostalinverter-authtest</artifactId>
<version>1.0-SNAPSHOT</version>
<dependencies>
<dependency>
<groupId>org.eclipse.jetty</groupId>
<artifactId>jetty-client</artifactId>
<version>9.4.28.v20200408</version>
</dependency>
<dependency>
<groupId>org.eclipse.jdt</groupId>
<artifactId>org.eclipse.jdt.annotation</artifactId>
<version>2.2.400</version>
</dependency>
<dependency>
<groupId>com.google.code.gson</groupId>
<artifactId>gson</artifactId>
<version>2.8.6</version>
</dependency>
<dependency>
<groupId>com.google.code.findbugs</groupId>
<artifactId>jsr305</artifactId>
<version>2.0.1</version>
</dependency>
</dependencies>
<build>
<plugins>
<plugin>
<groupId>org.apache.maven.plugins</groupId>
<artifactId>maven-compiler-plugin</artifactId>
<configuration>
<source>8</source>
<target>8</target>
</configuration>
</plugin>
</plugins>
</build>
</project> I'm using Java version 1.8.0_172. Maybe the Java version makes the code fail. |
Hi, BR Stefan |
Hi Stefan, unfortunately I could only make my code snippet work (see post). So, at least we've got a fallback for the authentication in Java that works fine. The next step would be making a nightly build and testing it as is. And if the issue still remains I would go further into debugging the code. Do you know how to make a nightly build? I couldn't figure it out yet. Best wishes |
Hi Marco, I´m sorry but I don´t know how to do nightly builds. I recognized that some steps of the authentication seem to work as a wrong password is detected immediately. BR Stefan |
Hi Stefan, you can be prompted the java version by executing following command: java -version But I actually don't think that the Java version is the matter. It's more about the openHAB release 2.5.4. How are you running openHAB? Do you use a docker setup or a plain installation? In case of a docker setup you need to attach to the interactive docker console, first. This can be achieved by following command: docker exec -it <container-name> bash Best wishes |
In the meantime I was able to download the addon-repo and successfully build the current source code (binary=jar-file). I could also manage to apply the jar-file to my local openHAB instance (this is possible by simply putting the jar-file into the addons folder of your openHAB installation and restart openHAB for loading it). And what can I say ... unfortunately the error showed up again, so now we can at least be sure that the current source code is broken and needs to be fixed. In my next step, I'm going to debug into the addon-code (see openHAB documentation: https://www.openhab.org/docs/developer/ide/intellij.html). Maybe I can find out the issue that way. |
I added some lines to log some useful debugging information. The failure acutually occurs at step 3 /auth/create_session of the authentication process (as suggested in my initial post). It fails at lines 432/433 of ThirdGenerationHandler.java with "java.security.InvalidKeyException: Illegal key size" exception. signature: /oWmrNWKJ7h6xf8KM1kX0fTCz8GCbtPkJGKkO94qbIw= Does anyone know why there is an illegal key size? And why does the same code actually work fine with other java versions (e.g. java 8 update 172)? |
Hi, Before that I tried the same with a 2.4 installation, where the thing-configuration in paper UI looks a little bit different (+ username). So far unfortunately no other news from me ;) |
Hi Stefan, there is a known issue with Java versions lower than 1.8_u162 because Java developers changed their encryption policy in terms of key strength, so your openHAB instance will probably run into an invalid key length exception. Unfortunately the fix for this issue is done by manually changing a configuration file in your Java runtime. And by doing so, you would change the security policy for your whole openHAB instance (or even your entire raspi) which may obviously by critical to other applications. What makes me curious is that I'm also encountering issues in that regard, even though the Java version inside my docker container is 1.8_u232 (openHAB image 2.5.4) which should be absolutely fine as versions above 1.8_u162 have the stronger crypto policy setting automatically activated. I found out that it is possible to manipulate the crypto policy programmatically. But then you need to execute this line at application startup before the crypto tools are used for the first time. Security.setProperty("crypto.policy", "unlimited"); In my opinion there should be a programatic solution which does not affect other parts of openHAB. I only see two alternatives to solving this issue:
|
Hi Marco, I am writing because of your invitation in the according thread in the OpenHab community :-) First of all i want to thank you very much for your effort in this topic! Unfortunately i can not support you very much, my coding skills are very limited... I have checked my Java version, I am running 1.8.0_152 too. What do we have to do for solving this issue according your first alternative? BR |
Hi Bertl, not everyone is using the same Java version, e.g. I'm using the official docker image of openHAB (2.5.4) which is running Java version 1.8_u232 inside the container. Simply said, the issue is that the authentication fails due to the change of encryption strength made by the Java devs. And it's not really binding-related because the source code is fine. The execution environment (Java runtime) is the problem as it provides security settings that make the authentication fail. So, it's more of a configuration / hosting issue. Obviously you could try to install a Java version > 1.8_u161 which activates the stronger encryption by default that is required for your kostal inverter. Or alternatively you could keep your Java version and only make changes to the security settings file. But this may lead to further issues with other Java applications that are running onto the same machine. So, it really depends on your particular setup and if you are willing to take the risk of other applications to fail due to those changes. I hope this post sums the problem a bit up and shows quick fixes. Best wishes |
Hello everyone, I just managed to fix the kostal-inverter binding's authentication issue. You just need to change the $JAVA_HOME/jre/lib/security/java.security file. There is a line crypto.policy=limited which needs to be changed to crypto.policy=unlimited. (you need to scroll quite a bit down to find it) After restarting the service, the authentication worked fine. But as I pointed out before there may be collateral damage doing so as other Java applications may require the limited setting ... I'm just wondering why the official openHAB docker image has this setting set to limited even though all java 8 versions greater than 161 have the unlimited setting by default. This means they changed it back to limited on purpose. I don't know whether there is another component of openHAB that requires the value to be set to limited. Maybe I should ask the docker image team why. Anyways ... thank you for your participation in this issue. Best wishes |
I just did a little research on the 2.5.4 openHAB docker image that may help enabling the unlimited security setting. The entrypoint.sh file (see https://github.com/openhab/openhab-docker/blob/master/2.5.4/debian/entrypoint.sh) checks for an environment variable CRYPTO_POLICY. If this variable is set to 'unlimited' then the Java security policy is enabled automatically. version: '2.2'
services:
openhab:
image: "openhab/openhab:2.5.4"
restart: always
network_mode: host
volumes:
- "/etc/localtime:/etc/localtime:ro"
- "/etc/timezone:/etc/timezone:ro"
- "./openhab_addons:/openhab/addons"
- "./openhab_conf:/openhab/conf"
- "./openhab_userdata:/openhab/userdata"
environment:
OPENHAB_HTTP_PORT: "8080"
OPENHAB_HTTPS_PORT: "8443"
EXTRA_JAVA_OPTS: "-Duser.timezone=Europe/Berlin"
CRYPTO_POLICY: "unlimited" |
Just read the README page of the official docker image. They actually don't enable the unlimited security settings due to legal law issues as stronger encryption might not be used in some countries. Are you f*ckin kiddin me??? This cost me 2 weeks of my life. https://github.com/openhab/openhab-docker#java-cryptographic-strength-policy |
Hi Bonifatius, at first thank you very much for diggin so deep into this topic! I tried to follow your instructions and found the line, Currently I´m checking if any of my other services are impacted... Thank you very much for your effort and help!!! BR Stefan |
You're welcome, Stefan. I've proposed a merge request to the kostal inverter documentation, so people see at first glance that they need to turn on strong crypto settings to connect to their kostal inverter. |
Hi Marco, I have also tried your suggested changes and now the binding is working! Up to now i could not find out any problems with other services… Thank you very much for taking care about this problem! I hope your proposal will be realized soon, for people with poor coding knowledge it`s nearly impossible to solve this problem… BR |
Hi Bertl, my changes to the official addon documentation are already merged into the source code of the next major version 2.5.5 (see #7581). Though it was quite hard to propose those changes only affecting 4 lines of the README.md file. Oh well ... The activation of the strong cryptography should not harm your system at all. It just prevents an exception to be thrown when you try to use strong cryptography without the licence permission bound to your country, so e.g. terrorists might not use strong encrypted ciphers. So it does not change the behavior of weak encryption. Thank you very much for your participation. You brought me to the right suggestions. Best wishes |
This issue has been mentioned on openHAB Community. There might be relevant details there: https://community.openhab.org/t/kostal-inverter-plenticore-plus-10-fw-01-42-no-connection/97322/43 |
Hello everyone,
I've got an openHAB instance running as a docker container and want to connect to my Kostal inverter (model: PLENTICORE PLUS 10.0). The connection to other "things" in the LAN works, so I assume that it's not a network issue, but rather an authentication error. And I'm also sure that the password is correct as I can log into the scb website as well.
Have you already tested this code explicitly for my device? I've tried to debug into your code, but the last authentication step /auth/create_session always seems to fail. I'm getting 400 BadRequest. The previous steps /auth/start and /auth/finish seem to work fine.
Thanks for you help in advance!
Best wishes
Marco
Expected Behavior
openHAB should be able to establish connections to Kostal PLENTICORE PLUS 10.0 devices using the kostal-inverter binding
Current Behavior
As you can see from the event log, I've been installing a thing using the kostal-inverter binding. The thing first goes into INITIALIZING state, then into UNKNOWN state and after creating several links it finally goes into OFFLINE (COMMUNICATION_ERROR) state. The message also tells that there is an authentication error which support my former suggestions when debugging the code. Althouh I had to restart the container because it showed me 503 No connection error.
Possible Solution
Steps to Reproduce (for Bugs)
Context
I just want to retrieve sensor data from my Kostal inverter and combine it with weather data to send notifications when to e.g. switch on the wasching machine etc. to increase my self-sufficiency (and hopefully save money). This is just a freetime project, so nothing critical.
Your Environment
The text was updated successfully, but these errors were encountered: