You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
407 lines
12 KiB
407 lines
12 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
type ChademoEvent interface {
|
|
// GetValue Return processed/calculated value and timestamp string
|
|
GetValue() (interface{}, *string)
|
|
}
|
|
|
|
type frame struct {
|
|
*CanFrame
|
|
}
|
|
|
|
// MaximumBatteryVoltage The maximum voltage value at the vehicle inlet terminals, at which the station stops charging to protect the vehicle battery
|
|
type MaximumBatteryVoltage frame
|
|
|
|
// ConstChargingRateInd Fixed value for charging rate indication, which is the maximum charging rate (100 %) of vehicle battery
|
|
type ConstChargingRateInd frame
|
|
|
|
// BatteryCapacity Rated capacity of battery
|
|
type BatteryCapacity frame
|
|
|
|
// MaxChargingTimeS Maximum charging time permitted by EV, set by 10 s
|
|
type MaxChargingTimeS frame
|
|
|
|
// MaxChargingTimeM Maximum charging time permitted by EV, set by minute
|
|
type MaxChargingTimeM frame
|
|
|
|
// EstChargingTimeM Estimated remaining time before the end of charging calculated by EV
|
|
type EstChargingTimeM 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
|
|
|
|
// ChargingCurrentReq Current value requested by EV during charging
|
|
type ChargingCurrentReq frame
|
|
|
|
// ChargingRate Charging rate of vehicle battery
|
|
type ChargingRate frame
|
|
|
|
// VehicleCharging Status flag indicating charge permission status of EV
|
|
type VehicleCharging frame
|
|
|
|
// ShiftLever Status flag indicating the shift lever position
|
|
type ShiftLever frame
|
|
|
|
// ChargingSystemFault Status flag indicating Charging system fault a malfunction caused by EV or the station, and detected by EV
|
|
type ChargingSystemFault frame
|
|
|
|
// VehicleStatus Status flag indicating the EV contactor status
|
|
type VehicleStatus frame
|
|
|
|
// NormalStopReq Status flag indicating the request of EV to stop charging control
|
|
type NormalStopReq frame
|
|
|
|
// BattOvervoltage Status flag indicating whether or not the vehicle battery voltage exceeds the maximum limit specified by EV
|
|
type BattOvervoltage frame
|
|
|
|
// BattUndervoltage Status flag indicating whether or not the vehicle battery voltage is less than the lower limit specified by EV
|
|
type BattUndervoltage frame
|
|
|
|
// BattCurrentDeviationErr Status flag indicating whether or not the output current deviates from EV requested current
|
|
type BattCurrentDeviationErr frame
|
|
|
|
// HighBattTemperature Status flag indicating whether or not the temperature of vehicle battery exceeds the maximum limit
|
|
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)
|
|
|
|
go func() {
|
|
defer close(events)
|
|
|
|
for frame := range frames {
|
|
switch frame.canid {
|
|
case CAN_ID_100:
|
|
events <- &MaximumBatteryVoltage{frame}
|
|
events <- &ConstChargingRateInd{frame}
|
|
case CAN_ID_101:
|
|
events <- &BatteryCapacity{frame}
|
|
events <- &MaxChargingTimeS{frame}
|
|
events <- &MaxChargingTimeM{frame}
|
|
events <- &EstChargingTimeM{frame}
|
|
case CAN_ID_102:
|
|
events <- &EVControlProtocolNumber{frame}
|
|
events <- &TargetBatteryVoltage{frame}
|
|
events <- &ChargingCurrentReq{frame}
|
|
events <- &ChargingRate{frame}
|
|
events <- &VehicleCharging{frame}
|
|
events <- &ShiftLever{frame}
|
|
events <- &ChargingSystemFault{frame}
|
|
events <- &VehicleStatus{frame}
|
|
events <- &NormalStopReq{frame}
|
|
events <- &BattOvervoltage{frame}
|
|
events <- &BattUndervoltage{frame}
|
|
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}
|
|
events <- &BatteryIncompatibility{frame}
|
|
events <- &ChargingSystemMalfunction{frame}
|
|
events <- &ChargerStopControl{frame}
|
|
}
|
|
}
|
|
}()
|
|
|
|
return events
|
|
}
|
|
|
|
func getVehicleShiftLever(bytes *[]byte) ShiftLeverPosition {
|
|
if isBitSet((*bytes)[5], 1) {
|
|
return OTHER
|
|
}
|
|
return PARKING
|
|
}
|
|
|
|
func getVehicleStatus(bytes *[]byte) ContactorVehicleStatus {
|
|
if isBitSet((*bytes)[5], 3) {
|
|
return CONTACTOR_OPEN
|
|
}
|
|
return CONTACTOR_CLOSED
|
|
}
|
|
|
|
func getNormalStopReq(bytes *[]byte) StopRequest {
|
|
if isBitSet((*bytes)[5], 4) {
|
|
return STOP_REQUEST
|
|
}
|
|
return NO_REQUEST
|
|
}
|
|
|
|
func getFault(bytes *[]byte, octet byte, bit byte) SystemFault {
|
|
if isBitSet((*bytes)[octet], bit) {
|
|
return FAULT
|
|
}
|
|
return NORMAL
|
|
}
|
|
|
|
func getVehicleCharging(bytes *[]uint8) VehicleChargingEnabled {
|
|
if isBitSet((*bytes)[5], 0) {
|
|
return ENABLED
|
|
}
|
|
return DISABLED
|
|
}
|
|
|
|
func isBitSet(buf uint8, num uint8) bool {
|
|
mask := uint8(1) << num
|
|
val := buf & mask
|
|
if val == mask {
|
|
return true
|
|
}
|
|
return false
|
|
}
|
|
|
|
func bytesToUint16(bytes []uint8) uint16 {
|
|
if len(bytes) != 2 {
|
|
fmt.Println("Wrong array size in bytesToUint16()")
|
|
return 0
|
|
}
|
|
|
|
var result uint16
|
|
result = uint16(bytes[1]) << 8
|
|
result = result | uint16(bytes[0])
|
|
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 getBatteryCompatibility(bytes *[]uint8) BatteryCompatible {
|
|
if isBitSet((*bytes)[5], 3) {
|
|
return BATTERY_INCOMPATIBLE
|
|
}
|
|
return BATTERY_COMPATIBLE
|
|
}
|
|
|
|
func getChargerStopControl(bytes *[]uint8) StopControl {
|
|
if isBitSet((*bytes)[5], 5) {
|
|
return SHUTDOWN_STOP
|
|
}
|
|
return OPERATING
|
|
}
|
|
|
|
func (m MaximumBatteryVoltage) GetValue() (interface{}, *string) {
|
|
return bytesToUint16(m.payload[4:6]), &m.date
|
|
}
|
|
|
|
func (c ConstChargingRateInd) GetValue() (interface{}, *string) {
|
|
return c.payload[6], &c.date
|
|
}
|
|
|
|
func (b BatteryCapacity) GetValue() (interface{}, *string) {
|
|
return 0.1 * float32(bytesToUint16(b.payload[5:7])), &b.date
|
|
}
|
|
|
|
func (m MaxChargingTimeS) GetValue() (interface{}, *string) {
|
|
return 10 * uint16(m.payload[1]), &m.date
|
|
}
|
|
|
|
func (m MaxChargingTimeM) GetValue() (interface{}, *string) {
|
|
return m.payload[2], &m.date
|
|
}
|
|
|
|
func (e EstChargingTimeM) GetValue() (interface{}, *string) {
|
|
return e.payload[3], &e.date
|
|
}
|
|
|
|
func (c EVControlProtocolNumber) GetValue() (interface{}, *string) {
|
|
return c.payload[0], &c.date
|
|
}
|
|
|
|
func (t TargetBatteryVoltage) GetValue() (interface{}, *string) {
|
|
return bytesToUint16(t.payload[1:3]), &t.date
|
|
}
|
|
|
|
func (c ChargingCurrentReq) GetValue() (interface{}, *string) {
|
|
return c.payload[3], &c.date
|
|
}
|
|
|
|
func (c ChargingRate) GetValue() (interface{}, *string) {
|
|
return c.payload[6], &c.date
|
|
}
|
|
|
|
func (s ShiftLever) GetValue() (interface{}, *string) {
|
|
return getVehicleShiftLever(&s.payload), &s.date
|
|
}
|
|
|
|
func (v VehicleCharging) GetValue() (interface{}, *string) {
|
|
return getVehicleCharging(&v.payload), &v.date
|
|
}
|
|
|
|
func (c ChargingSystemFault) GetValue() (interface{}, *string) {
|
|
return getFault(&c.payload, 5, 2), &c.date
|
|
}
|
|
|
|
func (v VehicleStatus) GetValue() (interface{}, *string) {
|
|
return getVehicleStatus(&v.payload), &v.date
|
|
}
|
|
|
|
func (n NormalStopReq) GetValue() (interface{}, *string) {
|
|
return getNormalStopReq(&n.payload), &n.date
|
|
}
|
|
|
|
func (b BattOvervoltage) GetValue() (interface{}, *string) {
|
|
return getFault(&b.payload, 4, 0), &b.date
|
|
}
|
|
|
|
func (b BattUndervoltage) GetValue() (interface{}, *string) {
|
|
return getFault(&b.payload, 4, 1), &b.date
|
|
}
|
|
|
|
func (b BattCurrentDeviationErr) GetValue() (interface{}, *string) {
|
|
return getFault(&b.payload, 4, 2), &b.date
|
|
}
|
|
|
|
func (h HighBattTemperature) GetValue() (interface{}, *string) {
|
|
return getFault(&h.payload, 4, 3), &h.date
|
|
}
|
|
|
|
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 (b BatteryIncompatibility) GetValue() (interface{}, *string) {
|
|
return getBatteryCompatibility(&b.payload), &b.date
|
|
}
|
|
|
|
func (c ChargingSystemMalfunction) GetValue() (interface{}, *string) {
|
|
return getFault(&c.payload, 5, 4), &c.date
|
|
}
|
|
|
|
func (c ChargerStopControl) GetValue() (interface{}, *string) {
|
|
return getChargerStopControl(&c.payload), &c.date
|
|
}
|
|
|