Skip to content

Commit

Permalink
Merge pull request #57 from leonunix/master
Browse files Browse the repository at this point in the history
add storage battery support.
  • Loading branch information
scottyphillips authored Jan 2, 2023
2 parents 636e25d + 7c1858a commit ca2494d
Show file tree
Hide file tree
Showing 5 changed files with 210 additions and 21 deletions.
1 change: 1 addition & 0 deletions CHANGES.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,3 +37,4 @@ v2.3.9, 06 Aug 2022 -- Added LowVoltageSmartElectricEnergyMeter, Create a anothe
V2.3.10, 26 Aug 2022 -- Revert use of send-only socket
-- Bug fix for acceptability judgment when sending a request
-- Adjusting the LowVoltageSmartElectricEnergyMeter
V2.3.11, 1 Dec 2022 -- Add storage battery support
176 changes: 167 additions & 9 deletions pychonet/StorageBattery.py
Original file line number Diff line number Diff line change
@@ -1,7 +1,164 @@
from pychonet.EchonetInstance import EchonetInstance
from pychonet.lib.epc_functions import (
_int,
_signed_int,
_hh_mm,
_to_string,
_yyyy_mm_dd,
)


def _permission_setting(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x41: "permitted",
0x42: "Prohibited",
}
return values.get(op_mode, "Invalid setting")


def _027DC1(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x00: "other",
0x01: "maximum",
0x02: "surplus",
0x03: "designatedPower",
0x04: "designatedCurrent",
}
return values.get(op_mode, "Invalid setting")


def _027DC2(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x00: "other",
0x01: "maximum",
0x02: "loadFollowing",
0x03: "designatedPower",
0x04: "designatedCurrent",
}
return values.get(op_mode, "Invalid setting")


def _max_min_int(edt):
max = str(int.from_bytes(edt[0:4], "big"))
min = str(int.from_bytes(edt[4:8], "big"))
return max + "/" + min


def _max_min_short_int(edt):
max = str(int.from_bytes(edt[0:2], "big"))
min = str(int.from_bytes(edt[2:4], "big"))
return max + "/" + min


def _027DCF(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x41: "rapidCharging",
0x42: "charging",
0x43: "discharging",
0x44: "standby",
0x45: "test",
0x46: "auto",
0x48: "restart",
0x49: "capacityRecalculation",
0x40: "Other",
}
return values.get(op_mode, "Invalid setting")


def _027DDB(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x00: "reversePowerFlowAcceptable",
0x01: "independent",
0x02: "reversePowerFlowNotAcceptable",
}
return values.get(op_mode, "Invalid setting")


def _027DE6(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x00: "unknown",
0x01: "lead",
0x02: "ni_mh",
0x03: "ni_cd",
0x04: "Lithium",
0x05: "zinc",
0x06: "alkaline",
}
return values.get(op_mode, "Invalid setting")


class StorageBattery(EchonetInstance):
EPC_FUNCTIONS = {
0x83: _to_string, #Identification number
0x97: _hh_mm, # Current time setting
0x98: _yyyy_mm_dd, # Current date setting
0xA0: _int, #AC effective capacity (charging)
0xA1: _int, #AC effective capacity (discharging)
0xA2: _int, #AC chargeable capacity
0xA3: _int, #AC dischargeable capacity
0xA4: _int, #AC chargeable electric energy
0xA5: _int, #AC dischargeable electric energy
0xA6: _int, #AC charge upper limit setting
0xA7: _int, #AC discharge lower limit setting
0xA8: _int, #AC measured cumulative charging electric energy
0xA9: _int, #AC measured cumulative discharging electric energy"
0xAA: _int, #AC charge amount setting value
0xAB: _int, #AC discharge amount setting value
0xC1: _027DC1, #Charging method
0xC2: _027DC2, #Discharging method
0xC7: _int, #AC rated electric energy
0xC8: _max_min_int, #Minimum/maximum charging electric power
0xC9: _max_min_int, #Minimum/maximum discharging electric power
0xCA: _max_min_short_int, #Minimum/maximum charging currentt
0xCB: _max_min_short_int, #Minimum/maximum discharging current
0xCC: _permission_setting, #Re-interconnection permission setting
0xCD: _permission_setting, #"Operation permission setting
0xCE: _permission_setting, #"Independent operation permission setting
0xCF: _027DCF, #Working operation status
0xD0: _int, #Rated electric energy
0xD1: _int, #Rated capacity
0xD2: _int, #Rated voltage
0xD3:
_signed_int, #Measured instantaneous charging/discharging electric energy
0xD4:
_signed_int, #Measured instantaneous charging/discharging current
0xD5:
_signed_int, #Measured instantaneous charging/discharging voltage
0xD6: _int, #Measured cumulative discharging electric energy
# set only 0xD7: "Measured cumulative discharging electric energy” reset setting",
0xD8: _int, #Measured cumulative charging electric energy
# set only 0xD9: "Measured cumulative charging electric energy” reset setting",
0xDA: _027DCF, #Operation mode setting
0xDB: _027DDB, #System-interconnected type
0xDC: _max_min_int, #Minimum/maxim um charging power (Independent)
0xDD: _max_min_int, #Minimum/maxim um discharging power (Independent)
0xDE:
_max_min_short_int, #Minimum/maxim um charging current (Independent)
0xDF:
_max_min_short_int, #Minimum/maxim um discharging current (Independent)
0xE0: _signed_int, #Charging/discharging amount setting 1
0xE1: _signed_int, #Charging/discharging amount setting 2
0xE2: _int, #Remaining stored electricity 1
0xE3: _int, #Remaining stored electricity 2
0xE4: _int, #Remaining stored electricity 3
0xE5: _int, #Battery state of health
0xE6: _027DE6, #Battery type
0xE7: _int, #Charging amount setting 1
0xE8: _int, #Discharging amount setting 1
0xE9: _int, #Charging amount setting 2
0xEA: _int, #Discharging amount setting 2
0xEB: _int, #Charging electric energy setting
0xEC: _int, #Discharging electric energy setting
0xED: _int, #Charging current setting
0xEE: _int, #Discharging current setting
0xEF: _int, #Rated voltage (Independent)
}

WORKING_OPERATION_STATES = {
0x40: "Other",
Expand All @@ -15,15 +172,16 @@ class StorageBattery(EchonetInstance):
0x49: "Effective capacity recalculation processing",
}

def _permission_setting(edt):
op_mode = int.from_bytes(edt, "big")
values = {
0x41: "permitted",
0x42: "Prohibited",
}
return values.get(op_mode, "Invalid setting")

def __init__(self, host, api_connector=None, instance=0x1):
self._eojgc = 0x02
self._eojcc = 0x7D
EchonetInstance.__init__(
self, host, self._eojgc, self._eojcc, instance, api_connector
)

def getRemainingStoredElectricity3(self):
return self.getMessage(0xE4)

def getWorkingOperationStatus(self):
return self.getMessage(0xCF)
EchonetInstance.__init__(self, host, self._eojgc, self._eojcc,
instance, api_connector)
31 changes: 26 additions & 5 deletions pychonet/lib/epc.py
Original file line number Diff line number Diff line change
Expand Up @@ -754,10 +754,31 @@
},
0x7D: { # Storage battery class
0x80: "Operation status",
0xC8: "Minimum/maxim um charging electric energy",
0xC9: "Minimum/maxim um discharging electric energy",
0xCA: "Minimum/maxim um charging current",
0xCB: "Minimum/maxim um discharging current",
0x83: "Identification number",
0x97: "Current time setting",
0x98: "Current date setting",
0xA0: "AC effective capacity (charging)",
0xA1: "AC effective capacity (discharging)",
0xA2: "AC chargeable capacity",
0xA3: "AC dischargeable capacity",
0xA4: "AC chargeable electric energy",
0xA5: "AC dischargeable electric energy",
0xA6: "AC charge upper limit setting",
0xA7: "AC discharge lower limit setting",
0xA8: "AC measured cumulative charging electric energy",
0xA9: "AC measured cumulative discharging electric energy",
0xAA: "AC charge amount setting value",
0xAB: "AC discharge amount setting value",
0xC1: "Charging method",
0xC2: "Discharging metho",
0xC7: "AC rated electric energy",
0xC8: "Minimum/maximum charging electric power",
0xC9: "Minimum/maximum discharging electric power",
0xCA: "Minimum/maximum charging currentt",
0xCB: "Minimum/maximum discharging current",
0xCC: "Re-interconnection permission setting",
0xCD: "Operation permission setting",
0xCE: "Independent operation permission setting",
0xCF: "Working operation status",
0xD0: "Rated electric energy",
0xD1: "Rated capacity",
Expand All @@ -770,7 +791,7 @@
0xD8: "Measured cumulative charging electric energy",
0xD9: "“Measured cumulative charging electric energy” reset setting",
0xDA: "Operation mode setting",
0xDB: "System-interconne cted type",
0xDB: "System-interconnected type",
0xDC: "Minimum/maxim um charging power (Independent)",
0xDD: "Minimum/maxim um discharging power (Independent)",
0xDE: "Minimum/maxim um charging current (Independent)",
Expand Down
21 changes: 15 additions & 6 deletions pychonet/lib/epc_functions.py
Original file line number Diff line number Diff line change
Expand Up @@ -17,9 +17,18 @@ def _hh_mm(edt): # basic time unit
mm = str(int.from_bytes(edt[1:2], "big")).zfill(2)
return f"{hh}:{mm}"


def _yyyy_mm_dd(edt): # basic year unit
yyyy = str(int.from_bytes(edt[0:4], "big")).zfill(4)
mm = str(int.from_bytes(edt[4:6], "big")).zfill(2)
dd = str(int.from_bytes(edt[6:8], "big")).zfill(2)
return f"{yyyy}:{mm}:{dd}"


def _to_string(edt):
return edt.decode('utf-8')


# Check status of Echonnet Instance
# ----------------- EPC SUPER FUNCTIONS -----------------------------
def _0080(edt):
Expand All @@ -44,14 +53,14 @@ def _009X(edt):
return payload


def _0083(edt, host = None): # UID
def _0083(edt, host=None): # UID
if edt is not None:
if len(edt) > 1:
ops_value = edt[1:].hex()
else:
if host is not None:
digits = host.split(".")
ops_value = digits[2].zfill(3) + digits[3].zfill(3)
ops_value = digits[2].zfill(3) + digits[3].zfill(3)
else:
ops_value = None
return ops_value
Expand Down Expand Up @@ -93,12 +102,10 @@ def _009A(edt): # cumulative runtime
0x9F: _009X,
}


# ------- EPC FUNCTIONS -------------------------------------------------
# TODO - Move these to their classes
# -----------------------------------------------------------------------


# --- Low voltage smart meter class


Expand All @@ -125,8 +132,10 @@ def _0288E7(edt):


def _0288E8(edt):
r_phase = float(int.from_bytes(edt[0:2], "big", signed=True)) / 10 # R Phase
t_phase = float(int.from_bytes(edt[2:4], "big", signed=True)) / 10 # T Phase
r_phase = float(int.from_bytes(edt[0:2], "big",
signed=True)) / 10 # R Phase
t_phase = float(int.from_bytes(edt[2:4], "big",
signed=True)) / 10 # T Phase
return {"r_phase_amps": r_phase, "t_phase_amps": t_phase}


Expand Down
2 changes: 1 addition & 1 deletion pychonet/version.py
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
__version_info__ = (2, 3, 10)
__version_info__ = (2, 3, 11)
__version__ = '.'.join(map(str, __version_info__))

0 comments on commit ca2494d

Please sign in to comment.