Class: Ocpp::Rails::ChargingSession

Inherits:
ApplicationRecord show all
Defined in:
app/models/ocpp/rails/charging_session.rb

Constant Summary collapse

MAX_TRANSACTION_ID =

OCPP 1.6 transactionId is a signed 32-bit integer

(2**31) - 1

Class Method Summary collapse

Instance Method Summary collapse

Class Method Details

.generate_wire_transaction_idObject



58
59
60
61
62
63
# File 'app/models/ocpp/rails/charging_session.rb', line 58

def self.generate_wire_transaction_id
  loop do
    candidate = SecureRandom.random_number(MAX_TRANSACTION_ID) + 1
    break candidate unless exists?(transaction_id: candidate)
  end
end

Instance Method Details

#active?Boolean

Returns:

  • (Boolean)


17
18
19
# File 'app/models/ocpp/rails/charging_session.rb', line 17

def active?
  stopped_at.nil?
end

#calculate_durationObject



41
42
43
44
# File 'app/models/ocpp/rails/charging_session.rb', line 41

def calculate_duration
  return 0 unless started_at
  ((stopped_at || Time.current) - started_at).to_i
end

#calculate_energy_consumed(stop_value = nil) ⇒ Object

Returns nil (never a negative number) when the stop value is below meterStart, e.g. after a register rollover or meter swap.



48
49
50
51
52
53
# File 'app/models/ocpp/rails/charging_session.rb', line 48

def calculate_energy_consumed(stop_value = nil)
  return 0 unless start_meter_value
  stop_val = stop_value || stop_meter_value || start_meter_value
  return nil if stop_val < start_meter_value
  stop_val - start_meter_value
end

#stop!(reason: "Local", meter_value: nil) ⇒ Object



21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
# File 'app/models/ocpp/rails/charging_session.rb', line 21

def stop!(reason: "Local", meter_value: nil)
  energy = calculate_energy_consumed(meter_value)
   =  || {}

  if energy.nil?
    ::Rails.logger.warn("[OCPP] Session #{transaction_id}: stop meter value below meterStart (rollover or meter swap?); flagging instead of recording negative energy")
     = .merge("energy_anomaly" => "stop_below_start")
  end

  update(
    stopped_at: Time.current,
    stop_meter_value: meter_value,
    stop_reason: reason,
    duration_seconds: calculate_duration,
    energy_consumed: energy,
    status: "Completed",
    metadata: 
  )
end