Documentation
¶
Index ¶
Constants ¶
const (
DefaultRemote = "192.168.91.1:443"
)
Variables ¶
var ( // QueryStatus is a general query of the Powerwall leader. // It returns total kW/kWh etc for the entire system, status and so on. QueryStatus = Query{ Query: " query DeviceControllerQuery {\n control {\n systemStatus {\n nominalFullPackEnergyWh\n nominalEnergyRemainingWh\n }\n islanding {\n customerIslandMode\n contactorClosed\n microGridOK\n gridOK\n }\n meterAggregates {\n location\n realPowerW\n }\n alerts {\n active\n },\n siteShutdown {\n isShutDown\n reasons\n }\n batteryBlocks {\n din\n disableReasons\n }\n pvInverters {\n din\n disableReasons\n }\n }\n system {\n time\n sitemanagerStatus {\n isRunning\n }\n updateUrgencyCheck {\n urgency\n version {\n version\n gitHash\n }\n timestamp\n }\n }\n neurio {\n isDetectingWiredMeters\n readings {\n serial\n dataRead {\n voltageV\n realPowerW\n reactivePowerVAR\n currentA\n }\n timestamp\n }\n pairings {\n serial\n shortId\n status\n errors\n macAddress\n isWired\n modbusPort\n modbusId\n lastUpdateTimestamp\n }\n }\n pw3Can {\n firmwareUpdate {\n isUpdating\n progress {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n }\n }\n esCan {\n bus {\n PVAC {\n packagePartNumber\n packageSerialNumber\n subPackagePartNumber\n subPackageSerialNumber\n PVAC_Status {\n isMIA\n PVAC_Pout\n PVAC_State\n PVAC_Vout\n PVAC_Fout\n }\n PVAC_InfoMsg {\n PVAC_appGitHash\n }\n PVAC_Logging {\n isMIA\n PVAC_PVCurrent_A\n PVAC_PVCurrent_B\n PVAC_PVCurrent_C\n PVAC_PVCurrent_D\n PVAC_PVMeasuredVoltage_A\n PVAC_PVMeasuredVoltage_B\n PVAC_PVMeasuredVoltage_C\n PVAC_PVMeasuredVoltage_D\n PVAC_VL1Ground\n PVAC_VL2Ground\n }\n alerts {\n isComplete\n isMIA\n active\n }\n }\n PINV {\n PINV_Status {\n isMIA\n PINV_Fout\n PINV_Pout\n PINV_Vout\n PINV_State\n PINV_GridState\n }\n PINV_AcMeasurements {\n isMIA\n PINV_VSplit1\n PINV_VSplit2\n }\n PINV_PowerCapability {\n isComplete\n isMIA\n PINV_Pnom\n }\n alerts {\n isComplete\n isMIA\n active\n }\n }\n PVS {\n PVS_Status {\n isMIA\n PVS_State\n PVS_vLL\n PVS_StringA_Connected\n PVS_StringB_Connected\n PVS_StringC_Connected\n PVS_StringD_Connected\n PVS_SelfTestState\n }\n alerts {\n isComplete\n isMIA\n active\n }\n }\n THC {\n packagePartNumber\n packageSerialNumber\n THC_InfoMsg {\n isComplete\n isMIA\n THC_appGitHash\n }\n THC_Logging {\n THC_LOG_PW_2_0_EnableLineState\n }\n }\n POD {\n POD_EnergyStatus {\n isMIA\n POD_nom_energy_remaining\n POD_nom_full_pack_energy\n }\n POD_InfoMsg {\n POD_appGitHash\n }\n }\n MSA {\n packagePartNumber\n packageSerialNumber\n MSA_InfoMsg {\n isMIA\n MSA_appGitHash\n MSA_assemblyId\n }\n METER_Z_AcMeasurements {\n isMIA\n lastRxTime\n METER_Z_CTA_InstRealPower\n METER_Z_CTA_InstReactivePower\n METER_Z_CTA_I\n METER_Z_VL1G\n METER_Z_CTB_InstRealPower\n METER_Z_CTB_InstReactivePower\n METER_Z_CTB_I\n METER_Z_VL2G\n }\n MSA_Status {\n lastRxTime\n }\n }\n SYNC {\n packagePartNumber\n packageSerialNumber\n SYNC_InfoMsg {\n isMIA\n SYNC_appGitHash\n }\n METER_X_AcMeasurements {\n isMIA\n isComplete\n lastRxTime\n METER_X_CTA_InstRealPower\n METER_X_CTA_InstReactivePower\n METER_X_CTA_I\n METER_X_VL1N\n METER_X_CTB_InstRealPower\n METER_X_CTB_InstReactivePower\n METER_X_CTB_I\n METER_X_VL2N\n METER_X_CTC_InstRealPower\n METER_X_CTC_InstReactivePower\n METER_X_CTC_I\n METER_X_VL3N\n }\n METER_Y_AcMeasurements {\n isMIA\n isComplete\n lastRxTime\n METER_Y_CTA_InstRealPower\n METER_Y_CTA_InstReactivePower\n METER_Y_CTA_I\n METER_Y_VL1N\n METER_Y_CTB_InstRealPower\n METER_Y_CTB_InstReactivePower\n METER_Y_CTB_I\n METER_Y_VL2N\n METER_Y_CTC_InstRealPower\n METER_Y_CTC_InstReactivePower\n METER_Y_CTC_I\n METER_Y_VL3N\n }\n SYNC_Status {\n lastRxTime\n }\n }\n ISLANDER {\n ISLAND_GridConnection {\n ISLAND_GridConnected\n isComplete\n }\n ISLAND_AcMeasurements {\n ISLAND_VL1N_Main\n ISLAND_FreqL1_Main\n ISLAND_VL2N_Main\n ISLAND_FreqL2_Main\n ISLAND_VL3N_Main\n ISLAND_FreqL3_Main\n ISLAND_VL1N_Load\n ISLAND_FreqL1_Load\n ISLAND_VL2N_Load\n ISLAND_FreqL2_Load\n ISLAND_VL3N_Load\n ISLAND_FreqL3_Load\n ISLAND_GridState\n lastRxTime\n isComplete\n isMIA\n }\n }\n }\n enumeration {\n inProgress\n numACPW\n numPVI\n }\n firmwareUpdate {\n isUpdating\n powerwalls {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n msa {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n sync {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n pvInverters {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n }\n phaseDetection {\n inProgress\n lastUpdateTimestamp\n powerwalls {\n din\n progress\n phase\n }\n }\n inverterSelfTests {\n isRunning\n isCanceled\n pinvSelfTestsResults {\n din\n overall {\n status\n test\n summary\n setMagnitude\n setTime\n tripMagnitude\n tripTime\n accuracyMagnitude\n accuracyTime\n currentMagnitude\n timestamp\n lastError\n }\n testResults {\n status\n test\n summary\n setMagnitude\n setTime\n tripMagnitude\n tripTime\n accuracyMagnitude\n accuracyTime\n currentMagnitude\n timestamp\n lastError\n }\n }\n }\n }\n}\n", Signature: []byte("0\201\206\002A\024\261\227\245\177\255\265\272\321r\032\250\275j\305\030\2300\266\022B\242\264pO\262\024vd\267\316\032\f\376\322V\001\f\177*\366\345\333g_/`\v\026\225_qc\023$\323\216y\276~\335A1\022x\002Ap\a_\264\037]\304>\362\356\005\245V\301\177*\b\307\016\246]\037\202\242\353I~\332\317\021\336\006\033q\317\311\264\315\374\036\365s\272\225\215#o!\315z\353\345z\226\365\341\f\265\256r\373\313/\027\037"), } // QueryComponents can be targeted at an individual DIN in a multidevice system. // It yields information about individual Powerwall devices. QueryComponents = Query{ Query: " query ComponentsQuery (\n $pchComponentsFilter: ComponentFilter,\n $pchSignalNames: [String!],\n $pwsComponentsFilter: ComponentFilter,\n $pwsSignalNames: [String!],\n $bmsComponentsFilter: ComponentFilter,\n $bmsSignalNames: [String!],\n $hvpComponentsFilter: ComponentFilter,\n $hvpSignalNames: [String!],\n $baggrComponentsFilter: ComponentFilter,\n $baggrSignalNames: [String!],\n ) {\n # TODO STST-57686: Introduce GraphQL fragments to shorten\n pw3Can {\n firmwareUpdate {\n isUpdating\n progress {\n updating\n numSteps\n currentStep\n currentStepProgress\n progress\n }\n }\n }\n components {\n pws: components(filter: $pwsComponentsFilter) {\n signals(names: $pwsSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n pch: components(filter: $pchComponentsFilter) {\n signals(names: $pchSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n bms: components(filter: $bmsComponentsFilter) {\n signals(names: $bmsSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n hvp: components(filter: $hvpComponentsFilter) {\n partNumber\n serialNumber\n signals(names: $hvpSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n baggr: components(filter: $baggrComponentsFilter) {\n signals(names: $baggrSignalNames) {\n name\n value\n textValue\n boolValue\n timestamp\n }\n activeAlerts {\n name\n }\n }\n }\n}\n", Signature: []byte("0\201\210\002B\000\270q\354>\243m\325p\371S\253\231\346~:\032\216~\242\263\207\017L\273O\203u\241\270\333w\233\354\276\246h\262\243\255\261\007\202D\277\353x\023O\022\303\216\264\010-'i6\360>B\237\236\304\244m\002B\001\023Pk\033)\277\236\342R\264\247g\260u\036\023\3662\354\242\353\035\221\234\027\245\321J\342\345\037q\262O\3446-\353\315m1\237zai0\341\207C4\307\300Z\177@h\335\327\0239\252f\n\206W"), Vars: []byte("{\"pwsComponentsFilter\":{\"types\":[\"PW3SAF\"]},\"pwsSignalNames\":[\"PWS_SelfTest\",\"PWS_PeImpTestState\",\"PWS_PvIsoTestState\",\"PWS_RelaySelfTest_State\",\"PWS_MciTestState\",\"PWS_appGitHash\",\"PWS_ProdSwitch_State\"],\"pchComponentsFilter\":{\"types\":[\"PCH\"]},\"pchSignalNames\":[\"PCH_State\",\"PCH_PvState_A\",\"PCH_PvState_B\",\"PCH_PvState_C\",\"PCH_PvState_D\",\"PCH_PvState_E\",\"PCH_PvState_F\",\"PCH_AcFrequency\",\"PCH_AcVoltageAB\",\"PCH_AcVoltageAN\",\"PCH_AcVoltageBN\",\"PCH_packagePartNumber_1_7\",\"PCH_packagePartNumber_8_14\",\"PCH_packagePartNumber_15_20\",\"PCH_packageSerialNumber_1_7\",\"PCH_packageSerialNumber_8_14\",\"PCH_PvVoltageA\",\"PCH_PvVoltageB\",\"PCH_PvVoltageC\",\"PCH_PvVoltageD\",\"PCH_PvVoltageE\",\"PCH_PvVoltageF\",\"PCH_PvCurrentA\",\"PCH_PvCurrentB\",\"PCH_PvCurrentC\",\"PCH_PvCurrentD\",\"PCH_PvCurrentE\",\"PCH_PvCurrentF\",\"PCH_BatteryPower\",\"PCH_AcRealPowerAB\",\"PCH_SlowPvPowerSum\",\"PCH_AcMode\",\"PCH_AcFrequency\",\"PCH_DcdcState_A\",\"PCH_DcdcState_B\",\"PCH_appGitHash\"],\"bmsComponentsFilter\":{\"types\":[\"PW3BMS\"]},\"bmsSignalNames\":[\"BMS_nominalEnergyRemaining\",\"BMS_nominalFullPackEnergy\",\"BMS_appGitHash\"],\"hvpComponentsFilter\":{\"types\":[\"PW3HVP\"]},\"hvpSignalNames\":[\"HVP_State\",\"HVP_appGitHash\"],\"baggrComponentsFilter\":{\"types\":[\"BAGGR\"]},\"baggrSignalNames\":[\"BAGGR_State\",\"BAGGR_OperationRequest\",\"BAGGR_NumBatteriesConnected\",\"BAGGR_NumBatteriesPresent\",\"BAGGR_NumBatteriesExpected\",\"BAGGR_LOG_BattConnectionStatus0\",\"BAGGR_LOG_BattConnectionStatus1\",\"BAGGR_LOG_BattConnectionStatus2\",\"BAGGR_LOG_BattConnectionStatus3\"]}"), } // QueryDeviceController is like QueryStatus, but contains even more fields. QueryDeviceController = Query{ Query: "query DeviceControllerQuery($msaComp:ComponentFilter$msaSignals:[String!]){control{systemStatus{nominalFullPackEnergyWh nominalEnergyRemainingWh}islanding{customerIslandMode contactorClosed microGridOK gridOK disableReasons}meterAggregates{location realPowerW}alerts{active}siteShutdown{isShutDown reasons}batteryBlocks{din disableReasons}pvInverters{din disableReasons}}system{time supportMode{remoteService{isEnabled expiryTime sessionId}}sitemanagerStatus{isRunning}updateUrgencyCheck{urgency version{version gitHash}timestamp}}neurio{isDetectingWiredMeters readings{firmwareVersion serial dataRead{voltageV realPowerW reactivePowerVAR currentA}timestamp}pairings{serial shortId status errors macAddress hostname isWired modbusPort modbusId lastUpdateTimestamp}}teslaRemoteMeter{meters{din reading{timestamp firmwareVersion ctReadings{voltageV realPowerW reactivePowerVAR energyExportedWs energyImportedWs currentA}}firmwareUpdate{updating numSteps currentStep currentStepProgress progress}}detectedWired{din serialPort}}pw3Can{firmwareUpdate{isUpdating progress{updating numSteps currentStep currentStepProgress progress}}enumeration{inProgress}}esCan{bus{PVAC{packagePartNumber packageSerialNumber subPackagePartNumber subPackageSerialNumber PVAC_Status{isMIA PVAC_Pout PVAC_State PVAC_Vout PVAC_Fout}PVAC_InfoMsg{PVAC_appGitHash}PVAC_Logging{isMIA PVAC_PVCurrent_A PVAC_PVCurrent_B PVAC_PVCurrent_C PVAC_PVCurrent_D PVAC_PVMeasuredVoltage_A PVAC_PVMeasuredVoltage_B PVAC_PVMeasuredVoltage_C PVAC_PVMeasuredVoltage_D PVAC_VL1Ground PVAC_VL2Ground}alerts{isComplete isMIA active}}PINV{PINV_Status{isMIA PINV_Fout PINV_Pout PINV_Vout PINV_State PINV_GridState}PINV_AcMeasurements{isMIA PINV_VSplit1 PINV_VSplit2}PINV_PowerCapability{isComplete isMIA PINV_Pnom}alerts{isComplete isMIA active}}PVS{PVS_Status{isMIA PVS_State PVS_vLL PVS_StringA_Connected PVS_StringB_Connected PVS_StringC_Connected PVS_StringD_Connected PVS_SelfTestState}PVS_Logging{PVS_numStringsLockoutBits PVS_sbsComplete}alerts{isComplete isMIA active}}THC{packagePartNumber packageSerialNumber THC_InfoMsg{isComplete isMIA THC_appGitHash}THC_Logging{THC_LOG_PW_2_0_EnableLineState}}POD{POD_EnergyStatus{isMIA POD_nom_energy_remaining POD_nom_full_pack_energy}POD_InfoMsg{POD_appGitHash}}SYNC{packagePartNumber packageSerialNumber SYNC_InfoMsg{isMIA SYNC_appGitHash SYNC_assemblyId}METER_X_AcMeasurements{isMIA isComplete METER_X_CTA_InstRealPower METER_X_CTA_InstReactivePower METER_X_CTA_I METER_X_VL1N METER_X_CTB_InstRealPower METER_X_CTB_InstReactivePower METER_X_CTB_I METER_X_VL2N METER_X_CTC_InstRealPower METER_X_CTC_InstReactivePower METER_X_CTC_I METER_X_VL3N}METER_Y_AcMeasurements{isMIA isComplete METER_Y_CTA_InstRealPower METER_Y_CTA_InstReactivePower METER_Y_CTA_I METER_Y_VL1N METER_Y_CTB_InstRealPower METER_Y_CTB_InstReactivePower METER_Y_CTB_I METER_Y_VL2N METER_Y_CTC_InstRealPower METER_Y_CTC_InstReactivePower METER_Y_CTC_I METER_Y_VL3N}}ISLANDER{ISLAND_GridConnection{ISLAND_GridConnected isComplete}ISLAND_AcMeasurements{ISLAND_VL1N_Main ISLAND_FreqL1_Main ISLAND_VL2N_Main ISLAND_FreqL2_Main ISLAND_VL3N_Main ISLAND_FreqL3_Main ISLAND_VL1N_Load ISLAND_FreqL1_Load ISLAND_VL2N_Load ISLAND_FreqL2_Load ISLAND_VL3N_Load ISLAND_FreqL3_Load ISLAND_GridState isComplete isMIA}}}enumeration{inProgress numACPW numPVI}firmwareUpdate{isUpdating powerwalls{updating numSteps currentStep currentStepProgress progress}msa{updating numSteps currentStep currentStepProgress progress}msa1{updating numSteps currentStep currentStepProgress progress}sync{updating numSteps currentStep currentStepProgress progress}pvInverters{updating numSteps currentStep currentStepProgress progress}}phaseDetection{inProgress lastUpdateTimestamp powerwalls{din progress phase}}inverterSelfTests{isRunning isCanceled pinvSelfTestsResults{din overall{status test summary setMagnitude setTime tripMagnitude tripTime accuracyMagnitude accuracyTime currentMagnitude timestamp lastError}testResults{status test summary setMagnitude setTime tripMagnitude tripTime accuracyMagnitude accuracyTime currentMagnitude timestamp lastError}}}}components{msa:components(filter:$msaComp){partNumber serialNumber signals(names:$msaSignals){name value textValue boolValue timestamp}activeAlerts{name}}}ieee20305{longFormDeviceID polledResources{url name pollRateSeconds lastPolledTimestamp}controls{defaultControl{mRID setGradW opModEnergize opModMaxLimW opModImpLimW opModExpLimW opModGenLimW opModLoadLimW}activeControls{opModEnergize opModMaxLimW opModImpLimW opModExpLimW opModGenLimW opModLoadLimW}}registration{dateTimeRegistered pin}}}", Signature: []byte("0\x81\x87\x02B\x01A\x95\x12\xe3B\xd1\xca\x1a\xd3\x00\xf6}\x0bE@/\x9a\x9f\xc0\r\x06%\xac,\x0ej!)\nd\xef\xe67\x8b\xafb\xd7\xf8&\x0b.\xc1\xac\xd9!\x1f\xd6\x83\xffkIm\xf3\\J\xd8\xeeiTY\xde\x7f\xc5xR\x02A\x1dC\x03H\xfb8\"\xb0\xe4\xd6\x18\xde\x11\xc45\xb2\xa9VB\xa6J\x8f\x08\x9d\xba\x86\xf1 W\xcdJ\x8c\x02*\x05\x12\xcb{<\x9b\xc8g\xc9\x9d9\x8bR\xb3\x89\xb8\xf1\xf1\x0f\x0e\x16E\xed\xd7\xbf\xd5&)\x92.\x12"), Vars: []byte("{\"msaComp\":{\"types\" :[\"PVS\",\"PVAC\", \"TESYNC\", \"TEPINV\", \"TETHC\", \"STSTSM\", \"TEMSA\", \"TEPINV\" ]},\n\t\"msaSignals\":[\n\t\"MSA_pcbaId\",\n\t\"MSA_usageId\",\n\t\"MSA_appGitHash\",\n\t\"PVAC_Fan_Speed_Actual_RPM\",\n\t\"PVAC_Fan_Speed_Target_RPM\",\n\t\"MSA_HeatingRateOccurred\",\n\t\"THC_AmbientTemp\",\n\t\"METER_Z_CTA_InstRealPower\",\n\t\"METER_Z_CTA_InstReactivePower\",\n\t\"METER_Z_CTA_I\",\n\t\"METER_Z_VL1G\",\n\t\"METER_Z_CTB_InstRealPower\",\n\t\"METER_Z_CTB_InstReactivePower\",\n\t\"METER_Z_CTB_I\",\n\t\"METER_Z_VL2G\"]}"), } )
these are the three queries from pypowerwall (from some kind of extraction from firmware) they have a signature that's from a private key Tesla has; you can't make new queries it's unclear whether the interpolated variables are part of the sig
Functions ¶
func FormatPowerTable ¶
Types ¶
type Query ¶
type Query struct {
Query string // string graphQL query
Signature []byte // tesla-private-key sig: https://github.com/jasonacox/Powerwall-Dashboard/discussions/392#discussioncomment-12023958
Vars json.RawMessage // interpolated into $-variables in Query (likely map[string]any)
}
Query is a known query that a Powerwall can execute. It's unlikely you can make new instances of this; the signature has to be generated with Tesla's private key.
type SimpleDeviceMPPTStatus ¶
func (SimpleDeviceMPPTStatus) FormatPower ¶
func (s SimpleDeviceMPPTStatus) FormatPower() (out string)
type SimpleDeviceStatus ¶
type SimpleDeviceStatus struct {
BatteryEnergy int `json:"battery"`
BatteryFullEnergy int `json:"batteryFull"`
PowerBattery float64 `json:"powerBattery"`
PowerSolar float64 `json:"powerSolar"`
Freq float64 `json:"freq"`
Voltage float64 `json:"voltage"`
MPPT []SimpleDeviceMPPTStatus `json:"mppt"`
}
func GetSimpleDeviceStatus ¶
func GetSimpleDeviceStatus(ctx context.Context, td *TEDApi, din string) (status *SimpleDeviceStatus, err error)
GetSimpleDeviceStatus reads a SimpleDeviceStatus struct from an individual device. For a PW3, this contains its charge etc plus the status of its MPPTs. You must pass individual DINs (get from SimpleStatus).
type SimplePhase ¶
type SimpleStatus ¶
type SimpleStatus struct {
Leader string `json:"dinLeader"`
Shutdown bool `json:"shutdown"`
Island bool `json:"island"`
BatteryEnergy int `json:"battery"`
BatteryFullEnergy int `json:"batteryFull"`
PowerBattery float64 `json:"powerBattery"`
PowerSite float64 `json:"powerSite"`
PowerLoad float64 `json:"powerLoad"`
PowerSolar float64 `json:"powerSolar"`
PowerSolarRGM float64 `json:"powerSolarRGM"`
PowerGenerator float64 `json:"powerGenerator"`
PowerConductor float64 `json:"powerConductor"`
BatteryBlocks []string `json:"batteryBlocks"`
Phase [3]SimplePhase `json:"phase"`
}
func GetSimpleStatus ¶
func GetSimpleStatus(ctx context.Context, td *TEDApi) (status *SimpleStatus, err error)
GetSimpleStatus reads a SimpleStatus struct from your Powerwall system. This contains aggregate information from the leader.
type TEDApi ¶
type TEDApi struct {
DIN string // DIN of target, will be transparently fetched if not provided
Secret string // must be provided, typically printed under your Powerwall's casing
Remote string // default "192.168.91.1:443" if unspecified
// contains filtered or unexported fields
}
TEDApi specifies how to connect to a Powerwall.
func (*TEDApi) Config ¶
Config reads a config file from the device as raw bytes. Known files include "config.json".
func (*TEDApi) Query ¶
Query performs a query on the device. Returns a json.RawMessage you can decode or use somehow.
func (*TEDApi) QueryDevice ¶
func (td *TEDApi) QueryDevice(ctx context.Context, q Query, customDin string) (out json.RawMessage, err error)
Query performs a query on the leader, but potentially targeted at another device (e.g., follower). Returns a json.RawMessage you can decode or use somehow.