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.
211 lines
6.4 KiB
211 lines
6.4 KiB
package main
|
|
|
|
import (
|
|
"fmt"
|
|
)
|
|
|
|
const (
|
|
CAN_ID_100 = 100
|
|
CAN_ID_101 = 101
|
|
CAN_ID_102 = 102
|
|
|
|
DISABLED VehicleCharging = iota
|
|
ENABLED
|
|
|
|
PARKING ShiftLever = iota
|
|
OTHER
|
|
|
|
NORMAL SystemFault = iota
|
|
FAULT
|
|
|
|
CONTACTOR_CLOSED VehicleStatus = iota
|
|
CONTACTOR_OPEN
|
|
|
|
NO_REQUEST StopRequest = iota
|
|
STOP_REQUEST
|
|
)
|
|
|
|
type VehicleCharging uint8
|
|
|
|
type ShiftLever uint8
|
|
|
|
type SystemFault uint8
|
|
|
|
type VehicleStatus uint8
|
|
|
|
type StopRequest uint8
|
|
|
|
type ChademoEvent interface {
|
|
GetValue() interface{}
|
|
}
|
|
|
|
type MaximumBatteryVoltage interface {
|
|
// GetMaxBattVoltage Maximum battery voltage
|
|
GetMaxBattVoltage() uint16
|
|
}
|
|
|
|
type ConstChargingRateInd interface {
|
|
// GetChargingRate Constant of charging rate indication
|
|
GetChargingRate() uint8
|
|
}
|
|
|
|
type frame100 struct {
|
|
maxBattVoltage uint16 // The maximum voltage value at the vehicle inlet terminals, at which the station stops charging to protect the vehicle battery
|
|
chargingRateInd uint8 // Fixed value for charging rate indication, which is the maximum charging rate (100 %) of vehicle battery
|
|
date string
|
|
}
|
|
|
|
type frame101 struct {
|
|
batteryCapacity float32 // Rated capacity of battery
|
|
maxChargingTimeS uint16 // Maximum charging time permitted by EV, set by 10 s
|
|
maxChargingTimeM uint8 // Maximum charging time permitted by EV, set by minute
|
|
estChargingTimeM uint8 // Estimated remaining time before the end of charging calculated by EV
|
|
date string
|
|
}
|
|
|
|
type frame102 struct {
|
|
controlProtocolNumber uint8 // Software version of control protocol to which EV corresponds
|
|
targetBatteryVoltage uint16 // Target battery voltage ed charging voltage at the vehicle inlet terminals
|
|
chargingCurrentReq uint8 // Current value requested by EV during charging
|
|
chargingRate uint8 // Charging rate of vehicle battery
|
|
vehicleCharging VehicleCharging // Status flag indicating charge permission status of EV
|
|
shiftLever ShiftLever // Status flag indicating the shift lever position
|
|
chargingSystemFault SystemFault // Status flag indicating Charging system fault a malfunction caused by EV or the station, and detected by EV
|
|
vehicleStatus VehicleStatus // Status flag indicating the EV contactor status
|
|
normalStopReq StopRequest // Status flag indicating the request of EV to stop charging control
|
|
battOvervoltage SystemFault // Status flag indicating whether or not the vehicle battery voltage exceeds the maximum limit specified by EV
|
|
battUndervoltage SystemFault // Status flag indicating whether or not the vehicle battery voltage is less than the lower limit specified by EV
|
|
battCurrentDeviationErr SystemFault // Status flag indicating whether or not the output current deviates from EV requested current
|
|
highBattTemperature SystemFault // Status flag indicating whether or not the temperature of vehicle battery exceeds the maximum limit
|
|
battVoltageDeviationErr SystemFault // Status flag indicating whether or not the vehicle battery voltage deviates from the output voltage measured by the station
|
|
date string
|
|
}
|
|
|
|
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:
|
|
event := &frame100{
|
|
maxBattVoltage: bytesToUint16(frame.payload[4:6]),
|
|
chargingRateInd: frame.payload[6],
|
|
date: frame.date,
|
|
}
|
|
events <- event
|
|
case CAN_ID_101:
|
|
event := &frame101{
|
|
batteryCapacity: 0.1 * float32(bytesToUint16(frame.payload[5:7])),
|
|
maxChargingTimeS: 10 * uint16(frame.payload[1]),
|
|
maxChargingTimeM: frame.payload[2],
|
|
estChargingTimeM: frame.payload[3],
|
|
date: frame.date,
|
|
}
|
|
fmt.Println(event)
|
|
//events <- event
|
|
case CAN_ID_102:
|
|
event := &frame102{
|
|
controlProtocolNumber: frame.payload[0],
|
|
targetBatteryVoltage: bytesToUint16(frame.payload[1:3]),
|
|
chargingCurrentReq: frame.payload[3],
|
|
chargingRate: frame.payload[6],
|
|
vehicleCharging: getVehicleCharging(&frame.payload),
|
|
shiftLever: getVehicleShiftLever(&frame.payload),
|
|
chargingSystemFault: getFault(&frame.payload, 5, 2),
|
|
vehicleStatus: getVehicleStatus(&frame.payload),
|
|
normalStopReq: getNormalStopReq(&frame.payload),
|
|
battOvervoltage: getFault(&frame.payload, 4, 0),
|
|
battUndervoltage: getFault(&frame.payload, 4, 1),
|
|
battCurrentDeviationErr: getFault(&frame.payload, 4, 2),
|
|
highBattTemperature: getFault(&frame.payload, 4, 3),
|
|
battVoltageDeviationErr: getFault(&frame.payload, 4, 4),
|
|
}
|
|
fmt.Println(event)
|
|
//events <- event
|
|
}
|
|
}
|
|
}()
|
|
|
|
return events
|
|
}
|
|
|
|
func getVehicleShiftLever(bytes *[]byte) ShiftLever {
|
|
if isBitSet((*bytes)[5], 1) {
|
|
return OTHER
|
|
}
|
|
return PARKING
|
|
}
|
|
|
|
func getVehicleStatus(bytes *[]byte) VehicleStatus {
|
|
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) VehicleCharging {
|
|
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 (f frame100) GetMaxBattVoltage() uint16 {
|
|
return f.maxBattVoltage
|
|
}
|
|
|
|
func (f frame100) GetChargingRate() uint8 {
|
|
return f.chargingRateInd
|
|
}
|
|
|
|
func (f frame100) GetValue() interface{} {
|
|
return fmt.Sprintf("%v | MaxBattVoltage = %vV, ChargingRate = %v%%", f.date, f.maxBattVoltage, f.chargingRateInd)
|
|
}
|
|
|
|
func (f frame101) GetValue() interface{} {
|
|
return fmt.Sprintf("%v | batteryCapacity = %vkWh, maxChargingTime = %vsec, maxChargingTime = %vmin, estChargingTime = %vmin",
|
|
f.date, f.batteryCapacity, f.maxChargingTimeS, f.maxChargingTimeM, f.estChargingTimeM)
|
|
}
|
|
|
|
func (f frame102) GetValue() interface{} {
|
|
//TODO implement me
|
|
return ""
|
|
}
|
|
|