Skip to content

Commit

Permalink
Merge pull request #34 from fondberg/signalr
Browse files Browse the repository at this point in the history
Signalr streaming data support
  • Loading branch information
olalid authored Dec 27, 2020
2 parents 2b8a219 + f837fcd commit 92d2d9f
Show file tree
Hide file tree
Showing 8 changed files with 515 additions and 12 deletions.
1 change: 1 addition & 0 deletions pyeasee/__init__.py
Original file line number Diff line number Diff line change
Expand Up @@ -5,3 +5,4 @@
from .charger import * # noqa:
from .site import * # noqa:
from .utils import * # noqa:
from .const import * # noqa:
76 changes: 68 additions & 8 deletions pyeasee/__main__.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,16 +2,34 @@
import json
import logging
import argparse
import threading
import sys
from typing import List
from .utils import lookup_charger_stream_id, lookup_equalizer_stream_id

from . import Easee, Charger, Site, Circuit, Equalizer
from . import Easee, Charger, Site, Circuit, Equalizer, DatatypesStreamData


CACHED_TOKEN = "easee-token.json"

_LOGGER = logging.getLogger(__file__)


def add_input(queue):
queue.put_nowait(sys.stdin.read(1))


async def print_signalr(id, data_type, data_id, value):

type_str = DatatypesStreamData(data_type).name
if id[0] == "Q":
data_str = lookup_equalizer_stream_id(data_id)
else:
data_str = lookup_charger_stream_id(data_id)

print(f"SR: {id} data type {data_type} {type_str} data id {data_id} {data_str} value {value}")


def parse_arguments():
parser = argparse.ArgumentParser(description="Read data from your Easee EV installation")
parser.add_argument("-u", "--username", help="Username", required=True)
Expand All @@ -21,7 +39,10 @@ def parse_arguments():
parser.add_argument("-ci", "--circuits", help="Get circuits information", action="store_true")
parser.add_argument("-e", "--equalizers", help="Get equalizers information", action="store_true")
parser.add_argument(
"-a", "--all", help="Get all sites, circuits, equalizers and chargers information", action="store_true",
"-a",
"--all",
help="Get all sites, circuits, equalizers and chargers information",
action="store_true",
)
parser.add_argument(
"-sum",
Expand All @@ -30,6 +51,7 @@ def parse_arguments():
action="store_true",
)
parser.add_argument("-l", "--loop", help="Loop charger data every 5 seconds", action="store_true")
parser.add_argument("-r", "--signalr", help="Listen to signalr stream", action="store_true")
parser.add_argument("--countries", help="Get active countries information", action="store_true")
parser.add_argument(
"-d",
Expand All @@ -41,11 +63,17 @@ def parse_arguments():
default=logging.WARNING,
)
parser.add_argument(
"-v", "--verbose", help="Be verbose", action="store_const", dest="loglevel", const=logging.INFO,
"-v",
"--verbose",
help="Be verbose",
action="store_const",
dest="loglevel",
const=logging.INFO,
)
args = parser.parse_args()
logging.basicConfig(
format="%(asctime)-15s %(name)-5s %(levelname)-8s %(message)s", level=args.loglevel,
format="%(asctime)-15s %(name)-5s %(levelname)-8s %(message)s",
level=args.loglevel,
)
return args

Expand Down Expand Up @@ -176,7 +204,32 @@ async def main():
print(e)
await easee.close()

await easee.close()
if args.signalr:
chargers: List[Charger] = await easee.get_chargers()
equalizers = []
sites: List[Site] = await easee.get_sites()
for site in sites:
equalizers_site = site.get_equalizers()
for equalizer in equalizers_site:
equalizers.append(equalizer)
for charger in chargers:
await easee.sr_subscribe(charger, print_signalr)
for equalizer in equalizers:
await easee.sr_subscribe(equalizer, print_signalr)

queue = asyncio.Queue(1)
input_thread = threading.Thread(target=add_input, args=(queue,))
input_thread.daemon = True
input_thread.start()

while True:
await asyncio.sleep(1)

if queue.empty() is False:
# print "\ninput:", input_queue.get()
break

await easee.close()


async def chargers_info(chargers: List[Charger]):
Expand Down Expand Up @@ -220,7 +273,12 @@ async def equalizers_info(equalizers: List[Equalizer]):
eq["state"] = state
data.append(eq)

print(json.dumps(data, indent=2,))
print(
json.dumps(
data,
indent=2,
)
)


async def charger_loop(charger: Charger, header=False):
Expand Down Expand Up @@ -256,10 +314,12 @@ async def charger_loop(charger: Charger, header=False):
print(str_fixed_length(f"{round(state.__getitem__('inCurrentT5'),1)}A", 10), end=" ")
print(str_fixed_length(f"{round(state.__getitem__('voltage'),1)}V", 10), end=" ")
print(
str_fixed_length(f"{round(state.__getitem__('sessionEnergy'),2)}kWh", 10), end=" ",
str_fixed_length(f"{round(state.__getitem__('sessionEnergy'),2)}kWh", 10),
end=" ",
)
print(
str_fixed_length(f"{round(state.__getitem__('energyPerHour'),2)}kWh/h", 10), end=" ",
str_fixed_length(f"{round(state.__getitem__('energyPerHour'),2)}kWh/h", 10),
end=" ",
)
print(str_fixed_length(f"{str(state.__getitem__('reasonForNoCurrent'))}", 25), end=" ")
print(" ")
Expand Down
242 changes: 242 additions & 0 deletions pyeasee/const.py
Original file line number Diff line number Diff line change
@@ -0,0 +1,242 @@
# Data IDs for Charger from signalr stream

from enum import Enum


class ChargerStreamData(Enum):
SelfTestResult = 1
SelfTestDetails = 2
WifiEvent = 10
ChargerOfflineReason = 11
EaseeLinkCommandResponse = 13
EaseeLinkDataReceived = 14
config_localPreAuthorizeEnabled = 15
config_localAuthorizeOfflineEnabled = 16
config_allowOfflineTxForUnknownId = 17
ErraticEVMaxToggles = 18
BackplateType = 19
SiteStructure = 20
config_detectedPowerGridType = 21
config_circuitMaxCurrentP1 = 22
config_circuitMaxCurrentP2 = 23
config_circuitMaxCurrentP3 = 24
Location = 25
SiteIDString = 26
SiteIDNumeric = 27
state_lockCablePermanently = 30
config_isEnabled = 31
CircuitSequenceNumber = 33
SinglePhaseNumber = 34
config_enable3PhasesDEPRECATED = 35
config_wiFiSSID = 36
config_enableIdleCurrent = 37
config_phaseMode = 38
ForcedThreePhaseOnITWithGndFault = 39
config_ledStripBrightness = 40
config_localAuthorizationRequired = 41
config_authorizationRequired = 42
config_remoteStartRequired = 43
config_smartButtonEnabled = 44
config_offlineChargingMode = 45
state_ledMode = 46
config_maxChargerCurrent = 47
state_dynamicChargerCurrent = 48
config_maxCurrentOfflineFallbackP1 = 50
config_maxCurrentOfflineFallbackP2 = 51
config_maxCurrentOfflineFallbackP3 = 52
schedule_chargingSchedule = 62
config_pairedEqualizer = 65
state_wiFiAPEnabled = 68
PairedUserIDToken = 69
state_circuitTotalAllocatedPhaseConductorCurrentL1 = 70
state_circuitTotalAllocatedPhaseConductorCurrentL2 = 71
state_circuitTotalAllocatedPhaseConductorCurrentL3 = 72
state_circuitTotalPhaseConductorCurrentL1 = 73
state_circuitTotalPhaseConductorCurrentL2 = 74
state_circuitTotalPhaseConductorCurrentL3 = 75
NumberOfCarsConnected = 76
NumberOfCarsCharging = 77
NumberOfCarsInQueue = 78
NumberOfCarsFullyCharged = 79
state_chargerFirmware = 80
ICCID = 81
ModemFwId = 82
OTAErrorCode = 83
MobileNetworkOperator = 84
RebootReason = 89
PowerPCBVersion = 90
ComPCBVersion = 91
state_reasonForNoCurrent = 96
LoadBalancingNumberOfConnectedChargers = 97
UDPNumOfConnectedNodes = 98
LocalConnection = 99
PilotMode = 100
CarConnectedDEPRECATED = 101
state_smartCharging = 102
state_cableLocked = 103
state_cableRating = 104
PilotHigh = 105
PilotLow = 106
BackPlateID = 107
UserIDTokenReversed = 108
state_chargerOpMode = 109
state_outputPhase = 110
state_dynamicCircuitCurrentP1 = 111
state_dynamicCircuitCurrentP2 = 112
state_dynamicCircuitCurrentP3 = 113
state_outputCurrent = 114
DeratedCurrent = 115
DeratingActive = 116
DebugString = 117
ErrorString = 118
ErrorCode = 119
state_totalPower = 120
state_sessionEnergy = 121
state_energyPerHour = 122
LegacyEvStatus = 123
state_lifetimeEnergy = 124
LifetimeRelaySwitches = 125
LifetimeHours = 126
DynamicCurrentOfflineFallbackDEPRICATED = 127
UserIDToken = 128
ChargingSession = 129
state_cellRSSI = 130
CellRAT = 131
state_wiFiRSSI = 132
CellAddress = 133
WiFiAddress = 134
WiFiType = 135
state_localRSSI = 136
MasterBackPlateID = 137
LocalTxPower = 138
LocalState = 139
state_foundWiFi = 140
state_chargerRAT = 141
CellularInterfaceErrorCount = 142
CellularInterfaceResetCount = 143
WifiInterfaceErrorCount = 144
WifiInterfaceResetCount = 145
config_localNodeType = 146
config_localRadioChannel = 147
config_localShortAddress = 148
config_localParentAddrOrNumOfNodes = 149
state_tempMax = 150
TempAmbientPowerBoard = 151
TempInputT2 = 152
TempInputT3 = 153
TempInputT4 = 154
TempInputT5 = 155
TempOutputN = 160
TempOutputL1 = 161
TempOutputL2 = 162
TempOutputL3 = 163
TempAmbient = 170
LightAmbient = 171
IntRelHumidity = 172
BackPlateLocked = 173
CurrentMotor = 174
BackPlateHallSensor = 175
state_inCurrentT2 = 182
state_inCurrentT3 = 183
state_inCurrentT4 = 184
state_inCurrentT5 = 185
state_inVoltageT1T2 = 190
state_inVoltageT1T3 = 191
state_inVoltageT1T4 = 192
state_inVoltageT1T5 = 193
state_inVoltageT2T3 = 194
state_inVoltageT2T4 = 195
state_inVoltageT2T5 = 196
state_inVoltageT3T4 = 197
state_inVoltageT3T5 = 198
state_inVoltageT4T5 = 199
OutVoltPin12 = 202
OutVoltPin13 = 203
OutVoltPin14 = 204
OutVoltPin15 = 205
VoltLevel33 = 210
VoltLevel5 = 211
VoltLevel12 = 212
LTERSRP = 220
LTESINR = 221
LTERSRQ = 222
EqAvailableCurrentP1 = 230
EqAvailableCurrentP2 = 231
EqAvailableCurrentP3 = 232
ListenToControlPulse = 56
ControlPulseRTT = 57


# Data IDs for Equalizer from signalr stream
class EqualizerStreamData(Enum):
selfTestResult = 1
selfTestDetails = 2
easeeLinkCommandResponse = 13
easeeLinkDataReceived = 14
siteIDNumeric = 19
config_siteStructure = 20
state_softwareRelease = 21
config_meterType = 25
config_meterID = 26
oBISListIdentifier = 27
config_gridType = 29
config_numPhases = 30
state_currentL1 = 31
state_currentL2 = 32
state_currentL3 = 33
state_voltageNL1 = 34
state_voltageNL2 = 35
state_voltageNL3 = 36
state_voltageL1L2 = 37
state_voltageL1L3 = 38
state_voltageL2L3 = 39
state_activePowerImport = 40
state_activePowerExport = 41
state_reactivePowerImport = 42
state_reactivePowerExport = 43
state_maxPowerImport = 44
state_cumulativeActivePowerImport = 45
state_cumulativeActivePowerExport = 46
state_cumulativeReactivePowerImport = 47
state_cumulativeReactivePowerExport = 48
state_clockAndDateMeter = 49
state_rcpi = 50
config_ssid = 51
config_masterBackPlateID = 55
equalizerID = 56
exceptionData = 60
bootReason = 61
highCurrentTransitions = 64
vCap = 65
vBusMin = 66
vbusMax = 67
internalTemperature = 68
hanSnapshot = 69
state_localRSSI = 70
localTxPower = 71
localRadioChannel = 72
localShortAddress = 73
localNodeType = 74
localParentAddress = 75
circuitPhaseMapping = 80
phaseMappingReport = 81
modbusConfiguration = 85
loadbalanceThrottle = 86
availableCurrentL1 = 87
availableCurrentL2 = 88
availableCurrentL3 = 89
hanChecksumErrors = 90
APMacAddress = 91
wifiReconnects = 92
ledMode = 100


# Data IDs for Equalizer from signalr stream
class DatatypesStreamData(Enum):
Binary = 1
Boolean = 2
Double = 3
Integer = 4
Position = 5
String = 6
Statistics = 7
Loading

0 comments on commit 92d2d9f

Please sign in to comment.