spali / go-rscp Goto Github PK
View Code? Open in Web Editor NEWGo library to communicate with a E3DC system implementing the RSCP (Remote Storage Control Protocol)
Home Page: https://github.com/spali/go-rscp
License: MIT License
Go library to communicate with a E3DC system implementing the RSCP (Remote Storage Control Protocol)
Home Page: https://github.com/spali/go-rscp
License: MIT License
Wrong User/Password is reported with:
error: authentication failed: AUTH_LEVEL_NO_AUT
But wrong key just breaks the communication with EOF error.
During authentication this will be me most assumable use-case.
So we should print a hint to the console (warning level) for this case.
see #5
evcc requires to inject a custom logger library and be idependent of other libraries that may use logrus. (evcc-io/evcc#13403 (comment))
it looks like under some conditions (till now not reproduced) time values with go representation time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC)
get's returned.
regarding time
package documentation, this results in Year -1
which is invalid for json decoding that has a year range from 0-9999.
json decoding for time.Time
requires a min of:
time.Date(1, 0, 0, 0, 0, 0, 0, time.UTC) // json marshal result: `"0000-11-30T00:00:00Z"`.
rscp responses can contain:
time.Time: time.Time: time.Date(0, 0, 0, 0, 0, 0, 0, time.UTC) // not valid in json !
experienced once by my self and reported once here:
#16 (comment)
Current guess is after a firmware update or maybe reboot of E3DC that the EMS_MANUAL_CHARGE_LASTSTART
returns a negative year.
So for json marshaling, we need to fix this responses to at least year = 1.
We assume the json output is mostly used in third-party directly, we "fix" the time to.
time.Unix(0, 0).UTC() // json: "1970-01-01T00:00:00Z"
This should be better supported in third party than smaller dates and are commonly also seen as "zero" time.
DataType check has to be removed due server responses with mixed data types for the same Tag.
See example below.
Maybe we need to remove this also in the check for Message validation when we find a case.
["EMS_REQ_GET_SYS_SPECS"]
[
{
"Tag": "EMS_GET_SYS_SPECS",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 15
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "hybridModeSupported"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 1
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 14
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "installedBatteryCapacity"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 25782
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 13
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxAcPower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 10
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxBatChargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 11
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxBatDischargPower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 0
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxChargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 1
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxDischargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 8
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxFbcChargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 9
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxFbcDischargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Int32",
"Value": 12
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxPvPower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Error",
"Value": "ERR_NOT_AVAILABLE"
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 4
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxStartChargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 6
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "maxStartDischargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4500
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 5
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "minStartChargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 0
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 7
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "minStartDischargePower"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 0
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 2
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "recommendedMinChargeLimit"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 4300
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 3
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "recommendedMinDischargeLimit"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 2200
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 16
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "startChargeDefault"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 65
}
]
},
{
"Tag": "EMS_SYS_SPEC",
"DataType": "Container",
"Value": [
{
"Tag": "EMS_SYS_SPEC_INDEX",
"DataType": "Uint32",
"Value": 17
},
{
"Tag": "EMS_SYS_SPEC_NAME",
"DataType": "CString",
"Value": "startDischargeDefault"
},
{
"Tag": "EMS_SYS_SPEC_VALUE_INT",
"DataType": "Int32",
"Value": 65
}
]
}
]
}
]
Erstmal Danke für die super Lösung. Ist echt praktisch.
Ich habe leider bei manchen Tags Probleme mit der Abfrage und erkenne nicht direkt, was ich falsch mache:
e3dc.json:
[
"INFO_REQ_TIME",
"EMS_REQ_BAT_SOC",
"EMS_REQ_POWER_ADD",
"EMS_REQ_POWER_BAT",
"EMS_REQ_POWER_HOME",
"EMS_REQ_POWER_GRID",
"EMS_REQ_SELF_CONSUMPTION",
"EMS_REQ_AUTARKY",
"EMS_REQ_GET_POWER_SETTINGS",
"EMS_REQ_GET_MANUAL_CHARGE",
"EMS_REQ_EMERGENCY_POWER_STATUS",
"EP_REQ_IS_GRID_CONNECTED",
"EP_REQ_IS_POSSIBLE",
"EP_REQ_IS_READY_FOR_SWITCH",
"EP_REQ_IS_INVALID_STATE",
"WB_REQ_ENERGY_ALL",
"EMS_REQ_STATUS",
"BAT_REQ_INFO"
]
Ergebnis (Auszug):
result:
EMS_POWER_BAT: -1266
EMS_POWER_HOME: 1167
EMS_AUTARKY: 99.83789
...
BAT_INFO: ERR_FORMAT
INFO_TIME: '2022-01-31T22:33:58.000416Z'
EP_IS_READY_FOR_SWITCH: true
EP_IS_GRID_CONNECTED: true
EP_IS_INVALID_STATE: false
EP_IS_POSSIBLE: true
WB_ENERGY_ALL: ERR_FORMAT
Warum bekommen BAT_INFO
und WB_ENERGY_ALL
als Ergebnis ERR_FORMAT
?
Wie kann ich das "debuggen"?
Danke für einen Hinweis.
Hello,
I'm new in go, so I struggle a bit with the installation.
I get the issue...
root/go/src/github.com/spali/go-rscp/rscp/constants.go:50:39: syntax error: unexpected b0001000000000000, expecting semicolon or newline or )
Can you give me please advice...
Thanks in advance.
Hi,
really excited about your work!
I'm having issues running your example though.
I installed go 1.21 on linux and trying to execute
go run ./e3dc.go
but keep getting
./e3dc.go:15:16: undefined: conf
./e3dc.go:16:23: undefined: conf
./e3dc.go:17:16: undefined: conf
./e3dc.go:18:16: undefined: conf
./e3dc.go:19:16: undefined: conf
./e3dc.go:31:15: undefined: unmarshalJSONRequests
./e3dc.go:31:44: undefined: conf
./e3dc.go:34:5: undefined: conf
./e3dc.go:46:9: undefined: conf
./e3dc.go:52:29: undefined: NewJSONSimpleMessages
./e3dc.go:52:29: too many errors
I did put a .config
file in the local directory. But also it seems that those JSON methods are not being recognised. Could you please provide a few more details on how to execute the example exactly.
Many thanks!
Guten Abend Spali,
gibt es einen Tag zum aktiven Netzladen den ich triggern kann ?
In der S10 Gui kann man einmal am Tag eine manuelle Netzladung von bis zu 3 kWh starten.
Das würde ich gerne automatisch mit ioBroker initiieren.
Vorhandener NodeRed Flow:
Die preisgünstigen Stunden von Awattar.de ermittelt der ioBroker und setzt SG Ready Eingang 1 (heizen) = EIN (1) und bei teuren Stunden SG Ready Eingang 2 (vermeiden)= EIN (1).
Gruß Michael
Reading unknown tag and marshal to json error:
TRAC[0000] read plain []byte{0xe3, 0xdc, 0x0, 0x11, 0x20, 0x17, 0x20, 0x66, 0x0, 0x0, 0x0, 0x0, 0xa8, 0x74, 0x58, 0x17, 0x8, 0x0, 0x7d, 0x2, 0x80, 0x1, 0x3, 0x1, 0x0, 0x0, 0x75, 0xfc, 0xe5, 0x38}
TRAC[0000] read [{ Tag(25166461) UChar8 0 }]
error: json: error calling MarshalJSON for type main.JSONMessage: invalid character '2' looking for beginning of object key string
see #25
Hi Spali,
I just updated the Home Assistant version and now it does no longer work:
"
sensor:
platform: command_line
command: "/config/packages/e3dc/e3dc.sh"
name: e3dc
command_timeout: 1
scan_interval: 1
json_attributes:
platform: template
sensors:
e3dc_grid_power:
friendly_name: E3DC Netz
device_class: power
value_template: "{{ state_attr('sensor.e3dc', 'result')['EMS_POWER_GRID'] }}"
unit_of_measurement: W
"
Home Assistant Log:
"
...
ValueError: Sensor sensor.e3dc_grid_power has device class 'power', state class 'None' unit 'W' and suggested precision 'None' thus indicating it has a numeric value; however, it has the non-numeric value: '' (<class 'str'>)
"
Do you have any suggestions?
Thank you,
Marco
Hey!
I desperately need a way to cancel the charging of the wallbox. So I need to send a single parameter to the e3dc via rscp. I go the parameter "ABORT_CHARGING_TYP2" and I need a way to send that to it.
Your application seems like the way to go, but what am I supposed to do with it? No Makefile, no INSTALL...
The referenced "e3dc" binary does not exist. So there is a missing part from "cloning git" to "configuring"
Some help please :)
I´m interested to set the emergency limits (e.g. max. unloading down to 2kWh) in my S10X.
Couldn´t get it done so far.
In this and other forums I found hints in relation to this subject, maybe helpful?
None of them work for me in that way:
./e3dc '[["TAG_EMS_ISE_EMERGENCY_POWER_SIZE"]]'
--> error: TAG_EMS_ISE_EP_SIZE does not belong to Tag values
Also found a list of tags from the E3DC website which might be related to emergency power
As I´m quite new in using this cool tool, maybe somehow has an advice?
Hi Spali,
ist es auch möglich mit deiner go-rscp API über das Webportal von e3dc die Daten abzufragen ? Ich habe eine weitere e3dc Anlage mit meinem Webportal verknüpft und möchte von dieser ebenfalls Daten abfragen.
LG Maik
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.