diff --git a/chademo.go b/chademo.go index dd94fed..c1b730d 100644 --- a/chademo.go +++ b/chademo.go @@ -5,9 +5,11 @@ import ( ) const ( - CAN_ID_100 = 256 - CAN_ID_101 = 257 - CAN_ID_102 = 258 + CAN_ID_100 = 0x100 + CAN_ID_101 = 0x101 + CAN_ID_102 = 0x102 + CAN_ID_108 = 0x108 + CAN_ID_109 = 0x109 DISABLED VehicleChargingEnabled = iota ENABLED @@ -23,6 +25,15 @@ const ( NO_REQUEST StopRequest = iota STOP_REQUEST + + VEHICLE_WELDING_DETECTION_SUPPORTED SuppVehicleWeldingDetection = iota + VEHICLE_WELDING_DETECTION_NOT_SUPPORTED + + STANDBY StationState = iota + CHARGING + + CONNECTOR_LOCKED ConnectorLock = iota + CONNECTOR_UNLOCKED ) type VehicleChargingEnabled uint8 @@ -35,6 +46,12 @@ type ContactorVehicleStatus uint8 type StopRequest uint8 +type SuppVehicleWeldingDetection uint8 + +type StationState uint8 + +type ConnectorLock uint8 + type ChademoEvent interface { // GetValue Return processed/calculated value and timestamp string GetValue() (interface{}, *string) @@ -62,8 +79,8 @@ type MaxChargingTimeM frame // EstChargingTimeM Estimated remaining time before the end of charging calculated by EV type EstChargingTimeM frame -// ControlProtocolNumber Software version of control protocol to which EV corresponds -type ControlProtocolNumber frame +// EVControlProtocolNumber Software version of control protocol to which EV corresponds +type EVControlProtocolNumber frame // TargetBatteryVoltage Target battery voltage ed charging voltage at the vehicle inlet terminals type TargetBatteryVoltage frame @@ -104,6 +121,53 @@ type HighBattTemperature frame // BattVoltageDeviationErr Status flag indicating whether or not the vehicle battery voltage deviates from the output voltage measured by the station type BattVoltageDeviationErr frame +// EVSE entity from here + +// EVcontWeldingDetectSupport Identifier indicating whether or not the station deals with EV contactor welding detection +type EVcontWeldingDetectSupport frame + +// AvailableOutputVoltage Maximum output voltage value at the vehicle connector terminals +type AvailableOutputVoltage frame + +// AvailableOutputCurrent Maximum output current value of the station +type AvailableOutputCurrent frame + +// ThresholdVoltage Threshold voltage to stop the charging process in order to protect vehicle battery +type ThresholdVoltage frame + +// EVSEControlProtocolNumber Software version number of control protocol or charging sequences that the station deals with +type EVSEControlProtocolNumber frame + +// OutputVoltage Supply voltage value of the output circuit in the station +type OutputVoltage frame + +// OutputCurrent Supply current value of the output circuit in the station +type OutputCurrent frame + +// RemainingChargingTimeS Remaining time before the end of charging (counted by 10 s) +type RemainingChargingTimeS frame + +// RemainingChargingTimeM Remaining time before the end of charging (counted by min) +type RemainingChargingTimeM frame + +// StationStatus Status flag indicating the energy transfer from the station +type StationStatus frame + +// StationMalfunction Status flag indicating whether or not there is a malfunction caused by the station +type StationMalfunction frame + +// VehicleConnectorLock Status flag indicating Vehicle connector lock the electromagnetic lock status of vehicle connector +type VehicleConnectorLock frame + +// BatteryIncompatibility Status flag indicating the compatibility of vehicle battery with the output voltage of station +type BatteryIncompatibility frame + +// ChargingSystemMalfunction Status flag indicating whether or not there is a problem with EV, such as improper connection +type ChargingSystemMalfunction frame + +// ChargerStopControl Status flag indicating whether or not the station proceeds with shutdown process +type ChargerStopControl frame + func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent { events := make(chan ChademoEvent) @@ -121,7 +185,7 @@ func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent { events <- &MaxChargingTimeM{frame} events <- &EstChargingTimeM{frame} case CAN_ID_102: - events <- &ControlProtocolNumber{frame} + events <- &EVControlProtocolNumber{frame} events <- &TargetBatteryVoltage{frame} events <- &ChargingCurrentReq{frame} events <- &ChargingRate{frame} @@ -135,6 +199,20 @@ func FromCanFrames(frames <-chan *CanFrame) <-chan ChademoEvent { events <- &BattCurrentDeviationErr{frame} events <- &HighBattTemperature{frame} events <- &BattVoltageDeviationErr{frame} + case CAN_ID_108: + events <- &EVcontWeldingDetectSupport{frame} + events <- &AvailableOutputVoltage{frame} + events <- &AvailableOutputCurrent{frame} + events <- &ThresholdVoltage{frame} + case CAN_ID_109: + events <- &EVSEControlProtocolNumber{frame} + events <- &OutputVoltage{frame} + events <- &OutputCurrent{frame} + events <- &RemainingChargingTimeS{frame} + events <- &RemainingChargingTimeM{frame} + events <- &StationStatus{frame} + events <- &StationMalfunction{frame} + events <- &VehicleConnectorLock{frame} } } }() @@ -198,6 +276,27 @@ func bytesToUint16(bytes []uint8) uint16 { return result } +func evWeldingDetectionSupport(bytes *[]uint8) SuppVehicleWeldingDetection { + if (*bytes)[0] == 0 { + return VEHICLE_WELDING_DETECTION_NOT_SUPPORTED + } + return VEHICLE_WELDING_DETECTION_SUPPORTED +} + +func getStationState(bytes *[]uint8) StationState { + if isBitSet((*bytes)[5], 0) { + return CHARGING + } + return STANDBY +} + +func getConnectorLock(bytes *[]byte) ConnectorLock { + if isBitSet((*bytes)[5], 2) { + return CONNECTOR_LOCKED + } + return CONNECTOR_UNLOCKED +} + func (m MaximumBatteryVoltage) GetValue() (interface{}, *string) { return bytesToUint16(m.payload[4:6]), &m.date } @@ -222,7 +321,7 @@ func (e EstChargingTimeM) GetValue() (interface{}, *string) { return e.payload[3], &e.date } -func (c ControlProtocolNumber) GetValue() (interface{}, *string) { +func (c EVControlProtocolNumber) GetValue() (interface{}, *string) { return c.payload[0], &c.date } @@ -278,6 +377,54 @@ func (b BattVoltageDeviationErr) GetValue() (interface{}, *string) { return getFault(&b.payload, 4, 4), &b.date } +func (e EVcontWeldingDetectSupport) GetValue() (interface{}, *string) { + return evWeldingDetectionSupport(&e.payload), &e.date +} + +func (a AvailableOutputVoltage) GetValue() (interface{}, *string) { + return bytesToUint16(a.payload[1:3]), &a.date +} + +func (a AvailableOutputCurrent) GetValue() (interface{}, *string) { + return a.payload[3], &a.date +} + +func (t ThresholdVoltage) GetValue() (interface{}, *string) { + return bytesToUint16(t.payload[4:6]), &t.date +} + +func (e EVSEControlProtocolNumber) GetValue() (interface{}, *string) { + return e.payload[0], &e.date +} + +func (o OutputVoltage) GetValue() (interface{}, *string) { + return bytesToUint16(o.payload[1:3]), &o.date +} + +func (o OutputCurrent) GetValue() (interface{}, *string) { + return o.payload[3], &o.date +} + +func (r RemainingChargingTimeS) GetValue() (interface{}, *string) { + return r.payload[6] * 10, &r.date +} + +func (r RemainingChargingTimeM) GetValue() (interface{}, *string) { + return r.payload[7], &r.date +} + +func (s StationStatus) GetValue() (interface{}, *string) { + return getStationState(&s.payload), &s.date +} + +func (s StationMalfunction) GetValue() (interface{}, *string) { + return getFault(&s.payload, 5, 1), &s.date +} + +func (v VehicleConnectorLock) GetValue() (interface{}, *string) { + return getConnectorLock(&v.payload), &v.date +} + func (v VehicleChargingEnabled) String() string { switch v { case DISABLED: @@ -332,3 +479,36 @@ func (s StopRequest) String() string { panic("StopRequest not implemented") } } + +func (s SuppVehicleWeldingDetection) String() string { + switch s { + case VEHICLE_WELDING_DETECTION_NOT_SUPPORTED: + return "not supported" + case VEHICLE_WELDING_DETECTION_SUPPORTED: + return "supported" + default: + panic("SuppVehicleWeldingDetection not implemented") + } +} + +func (s StationState) String() string { + switch s { + case CHARGING: + return "charging" + case STANDBY: + return "standby" + default: + panic("StationState not implemented") + } +} + +func (c ConnectorLock) String() string { + switch c { + case CONNECTOR_LOCKED: + return "locked" + case CONNECTOR_UNLOCKED: + return "unlocked" + default: + panic("ConnectorLock not implemented") + } +}