Skip to content
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

Release 2.1.0 #20

Merged
merged 9 commits into from
Jan 22, 2024
2 changes: 2 additions & 0 deletions .gitignore
Original file line number Diff line number Diff line change
Expand Up @@ -35,3 +35,5 @@ build/

### VS Code ###
.vscode/

/api/src/test/kotlin/de/jnkconsulting/e3dc/easyrscp/api/generators/*
2 changes: 2 additions & 0 deletions README.md
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,8 @@

easy-rscp is an INOFFICIAL library written in Kotlin (fully Java compatible) for accessing E3DC home power plants.

If you are looking for a TypeScript or JavaScript library, take a look at [easy-rscp-js](https://github.com/jnk-cons/easy-rscp-js).

E3DC is a brand of HagerEnergy Gmbh ([website](https://www.e3dc.com/)). I have nothing to do with the company, except that I own a home power plant from E3DC and wanted to include it in my SmartHome. This "desire" gave birth to easy-rscp.

## Getting started
Expand Down
2 changes: 1 addition & 1 deletion api/pom.xml
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,7 @@
<parent>
<groupId>de.jnk-consulting.e3dc.easyrscp</groupId>
<artifactId>jnk-easy-rscp</artifactId>
<version>2.0.0</version>
<version>2.1.0</version>
</parent>

<artifactId>jnk-easy-rscp-api</artifactId>
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -51,21 +51,21 @@ val FIXED_VALUES = FixedValues(
* Map containing all known tags. The key is the respective hex code as string in lowercase with leading prefix 0x
*/
val tagsByHexString = mutableMapOf<String, Tag>()
.apply { putAll(BatTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(DBTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(DCDCTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(EMSTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(EPTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(FMSTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(HATag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(InfoTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(PMTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(PVITag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(RSCPTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(SRVTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(SYSTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(UMTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(WBTag.values().associateBy { it.hex.lowercase() }) }
.apply { putAll(BatTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(DBTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(DCDCTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(EMSTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(EPTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(FMSTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(HATag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(InfoTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(PMTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(PVITag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(RSCPTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(SRVTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(SYSTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(UMTag.entries.associateBy { it.hex.lowercase() }) }
.apply { putAll(WBTag.entries.associateBy { it.hex.lowercase() }) }
.toMap()

/**
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,8 @@ import java.time.format.DateTimeFormatter
* @param value The actual value
*
* @since 2.0
* @since 2.1 new function:
* - [valueAsErrorCode]
*/
data class Data(
val tag: ByteArray,
Expand Down Expand Up @@ -272,15 +274,25 @@ data class Data(
value

/**
* Liest den Int wert des Datenblocks und wandelt ihn in einen [ResultCode]
* Reads the Int value of the data block and converts it into a [ResultCode].
*
* @return [ResultCode] Wert
* @return [ResultCode] value
*
* @since 2.0
*/
fun valueAsResultCode() =
if (typeObject() == DataType.ERROR) ResultCode.UNKNOWN else ResultCode.byRscpCode(valueAsInt()?:ResultCode.UNKNOWN.rscpCode)

/**
* Reads the Int value of the data block and converts it into a [ErrorCode].
*
* @return [ErrorCode] Value
*
* @since 2.1
*/
fun valueAsErrorCode() =
if (typeObject() == DataType.ERROR) ResultCode.UNKNOWN else ErrorCode.byRscpCode(valueAsInt() ?: ErrorCode.UNKNOWN.rscpCode.toInt())

/**
* Checks if the response type is of type error.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ enum class DataType(val code: Byte) {
* @since 2.0
*/
fun byCode(code: Byte) =
DataType.values()
entries
.find { it.code == code }
?: UNKNOWN

Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,49 @@
package de.jnkconsulting.e3dc.easyrscp.api.frame

/**
* Possible error codes that can be in data blocks of type [DataType.ERROR]
*
* @param rscpCode Code in the data block that identifies the error type
*
* @since 2.1
*/
enum class ErrorCode(val rscpCode: Byte) {
/**
* Empty data block. Usually used for request frames; code = 0x00
*/
NOT_HANDLED(rscpCode = 0x00.toByte()),
/**
* Boolean typ. 1 for true, 0 for false; code = 0x01
*/
ACCESS_DENIED(rscpCode = 0x01.toByte()),

/**
* Contains a 1byte number; code = 0x02
*/
FORMAT(rscpCode = 0x02.toByte()),
/**
* Contains a 1byte number (unsigned); code = 0x03
*/
AGAIN(rscpCode = 0x03.toByte()),

UNKNOWN(rscpCode = 0xFF.toByte());


companion object {

/**
* Returns the [ErrorCode] object for the given code.
*
* If the code is not known, [UNKNOWN] is supplied.
*
* @return [ErrorCode] object to the given code
*
* @since 2.1
*/
fun byRscpCode(code: Int) =
entries
.find { it.rscpCode.toInt() == code }
?: UNKNOWN

}
}
Original file line number Diff line number Diff line change
Expand Up @@ -17,11 +17,14 @@ import java.time.Instant
* Data, the RSCP data itself.
*
* @param timestamp Creation time of the frame
* @param controlBytes Control functions. Currently the protocol version as well as a control bit whether checksum are used or not. See [FIXED_VALUES].
* @param controlBytes Control functions. Currently, the protocol version as well as a control bit whether checksum are used or not. See [FIXED_VALUES].
* @param data The data itself. See [Data]
* @param parser The parser to use for parsing container data
*
* @since 2.0
* @since 2.1 new functions:
* - [isDataBlockInError]
* - [errorCodeByTag]
*/
data class Frame(
val timestamp: Instant,
Expand Down Expand Up @@ -280,6 +283,36 @@ data class Frame(
find(tag, data, *containerPath)
?.valueAsResultCode() ?: ResultCode.UNKNOWN

/**
* Checks whether the data block in the frame is of data type [DataType.ERROR].
*
* @param tag The [Tag] to search for
* @param containerPath Optional path through datablocks of type [DataType.CONTAINER].
*
* @return true if the data block is of type [DataType.ERROR], otherwise false
*
* @since 2.1
*/
fun isDataBlockInError(tag: Tag, vararg containerPath: Tag) =
find(tag, data, *containerPath)
?.isErrorResponse() ?: false

/**
* Searches for a data block of type [tag] and returns the value as [ErrorCode].
*
* If the block is not found [ErrorCode.UNKNOWN] is returned.
*
* @param tag The [Tag] to search for
* @param containerPath Optional path through datablocks of type [DataType.CONTAINER].
*
* @return Value of the data block as [ErrorCode] or [ErrorCode.UNKNOWN] if the data block does not exist.
*
* @since 2.1
*/
fun errorCodeByTag(tag: Tag, vararg containerPath: Tag) =
find(tag, data, *containerPath)
?.valueAsErrorCode() ?: ErrorCode.UNKNOWN

/**
* Query whether the frame calculates the checksum or not.
*
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -91,7 +91,7 @@ enum class Namespace(val code: Byte) {

companion object {
fun byCode(code: Byte) =
values()
entries
.find { it.code == code }
?: UNKNOWN

Expand Down
Loading