ocpp-rails 0.2.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- checksums.yaml +7 -0
- data/MIT-LICENSE +20 -0
- data/README.md +461 -0
- data/Rakefile +8 -0
- data/app/assets/stylesheets/ocpp/rails/application.css +15 -0
- data/app/channels/ocpp/rails/charge_point_channel.rb +94 -0
- data/app/controllers/ocpp/rails/application_controller.rb +7 -0
- data/app/helpers/ocpp/rails/application_helper.rb +6 -0
- data/app/jobs/ocpp/rails/application_job.rb +6 -0
- data/app/jobs/ocpp/rails/async_hook_job.rb +25 -0
- data/app/jobs/ocpp/rails/authorization_async_hook_job.rb +25 -0
- data/app/jobs/ocpp/rails/change_availability_job.rb +42 -0
- data/app/jobs/ocpp/rails/change_configuration_job.rb +41 -0
- data/app/jobs/ocpp/rails/cleanup_authorizations_job.rb +28 -0
- data/app/jobs/ocpp/rails/cleanup_state_changes_job.rb +28 -0
- data/app/jobs/ocpp/rails/clear_cache_job.rb +37 -0
- data/app/jobs/ocpp/rails/get_configuration_job.rb +38 -0
- data/app/jobs/ocpp/rails/remote_start_transaction_job.rb +39 -0
- data/app/jobs/ocpp/rails/remote_stop_transaction_job.rb +38 -0
- data/app/jobs/ocpp/rails/reset_job.rb +39 -0
- data/app/jobs/ocpp/rails/unlock_connector_job.rb +38 -0
- data/app/mailers/ocpp/rails/application_mailer.rb +8 -0
- data/app/models/ocpp/rails/application_record.rb +7 -0
- data/app/models/ocpp/rails/authorization.rb +26 -0
- data/app/models/ocpp/rails/charge_point.rb +69 -0
- data/app/models/ocpp/rails/charging_session.rb +72 -0
- data/app/models/ocpp/rails/message.rb +17 -0
- data/app/models/ocpp/rails/meter_value.rb +24 -0
- data/app/models/ocpp/rails/state_change.rb +26 -0
- data/app/services/ocpp/rails/actions/authorize_handler.rb +47 -0
- data/app/services/ocpp/rails/actions/boot_notification_handler.rb +62 -0
- data/app/services/ocpp/rails/actions/heartbeat_handler.rb +25 -0
- data/app/services/ocpp/rails/actions/meter_values_handler.rb +97 -0
- data/app/services/ocpp/rails/actions/start_transaction_handler.rb +126 -0
- data/app/services/ocpp/rails/actions/status_notification_handler.rb +99 -0
- data/app/services/ocpp/rails/actions/stop_transaction_handler.rb +121 -0
- data/app/services/ocpp/rails/authorization_hook_manager.rb +102 -0
- data/app/services/ocpp/rails/message_handler.rb +153 -0
- data/app/services/ocpp/rails/meter_anomaly_detector.rb +50 -0
- data/app/services/ocpp/rails/protocol.rb +65 -0
- data/app/services/ocpp/rails/rate_limiter.rb +53 -0
- data/app/services/ocpp/rails/state_change_hook_manager.rb +26 -0
- data/app/services/ocpp/rails/station_authenticator.rb +46 -0
- data/app/services/ocpp/rails/timestamp_parser.rb +25 -0
- data/config/routes.rb +5 -0
- data/db/migrate/20251008162902_create_ocpp_models.rb +77 -0
- data/db/migrate/20251015190754_make_charging_session_id_nullable_in_meter_values.rb +5 -0
- data/db/migrate/20251016000000_create_ocpp_state_changes.rb +17 -0
- data/db/migrate/20251017000000_create_ocpp_authorizations.rb +15 -0
- data/db/migrate/20260707000000_add_timestamp_provenance_to_ocpp_meter_values.rb +6 -0
- data/db/migrate/20260707000001_convert_ocpp_transaction_id_to_integer.rb +19 -0
- data/db/migrate/20260707000002_add_active_session_guard_to_ocpp_charging_sessions.rb +11 -0
- data/db/migrate/20260707000003_add_anomaly_flags_to_ocpp_meter_values.rb +6 -0
- data/db/migrate/20260707000004_add_auth_password_digest_to_ocpp_charge_points.rb +5 -0
- data/lib/generators/ocpp/rails/install_generator.rb +42 -0
- data/lib/generators/ocpp/rails/templates/README +45 -0
- data/lib/generators/ocpp/rails/templates/create_ocpp_charge_points.rb +21 -0
- data/lib/generators/ocpp/rails/templates/create_ocpp_charging_sessions.rb +22 -0
- data/lib/generators/ocpp/rails/templates/create_ocpp_messages.rb +18 -0
- data/lib/generators/ocpp/rails/templates/create_ocpp_meter_values.rb +21 -0
- data/lib/generators/ocpp/rails/templates/ocpp_rails.rb +13 -0
- data/lib/ocpp/rails/engine.rb +19 -0
- data/lib/ocpp/rails/version.rb +5 -0
- data/lib/ocpp/rails.rb +82 -0
- data/lib/tasks/ocpp/authorizations.rake +18 -0
- data/lib/tasks/ocpp/rails_tasks.rake +4 -0
- data/lib/tasks/ocpp/state_changes.rake +18 -0
- metadata +196 -0
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
===============================================================================
|
|
2
|
+
|
|
3
|
+
Ocpp::Rails has been installed!
|
|
4
|
+
|
|
5
|
+
Next steps:
|
|
6
|
+
|
|
7
|
+
1. Run the migrations:
|
|
8
|
+
|
|
9
|
+
rails db:migrate
|
|
10
|
+
|
|
11
|
+
2. The engine is mounted at /ocpp
|
|
12
|
+
|
|
13
|
+
OCPP Rails is a backend-only engine (no bundled UI). Mounting it exposes the
|
|
14
|
+
OCPP WebSocket endpoint; you build your own dashboard on top of the models.
|
|
15
|
+
|
|
16
|
+
3. Point your charge points at the OCPP WebSocket endpoint:
|
|
17
|
+
|
|
18
|
+
ws://localhost:3000/ocpp/cable
|
|
19
|
+
|
|
20
|
+
Each station subscribes to Ocpp::Rails::ChargePointChannel, passing its
|
|
21
|
+
charge_point_id. By default stations authenticate with HTTP Basic Auth on the
|
|
22
|
+
WebSocket upgrade (OCPP-J Security Profile 1), so provision a per-station
|
|
23
|
+
credential first:
|
|
24
|
+
|
|
25
|
+
charge_point.update!(auth_password: SecureRandom.base58(32))
|
|
26
|
+
|
|
27
|
+
4. Configure OCPP settings in config/initializers/ocpp_rails.rb
|
|
28
|
+
|
|
29
|
+
5. ActionCable transport:
|
|
30
|
+
|
|
31
|
+
No setup is required for development or test — the engine defaults to the
|
|
32
|
+
async adapter (SQLite-friendly, no Redis). For a multi-server production
|
|
33
|
+
deployment, configure a shared adapter in config/cable.yml, e.g.:
|
|
34
|
+
|
|
35
|
+
production:
|
|
36
|
+
adapter: redis
|
|
37
|
+
url: redis://localhost:6379/1
|
|
38
|
+
|
|
39
|
+
6. Start your Rails server with:
|
|
40
|
+
|
|
41
|
+
rails server
|
|
42
|
+
|
|
43
|
+
For more information, visit: https://github.com/trahfo/ocpp-rails
|
|
44
|
+
|
|
45
|
+
===============================================================================
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class CreateOcppChargePoints < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
2
|
+
def change
|
|
3
|
+
create_table :ocpp_charge_points do |t|
|
|
4
|
+
t.string :identifier, null: false, index: { unique: true }
|
|
5
|
+
t.string :vendor
|
|
6
|
+
t.string :model
|
|
7
|
+
t.string :serial_number
|
|
8
|
+
t.string :firmware_version
|
|
9
|
+
t.string :iccid
|
|
10
|
+
t.string :imsi
|
|
11
|
+
t.string :meter_type
|
|
12
|
+
t.string :meter_serial_number
|
|
13
|
+
t.string :ocpp_protocol, default: "1.6"
|
|
14
|
+
t.string :status, default: "Available"
|
|
15
|
+
t.datetime :last_heartbeat_at
|
|
16
|
+
t.boolean :connected, default: false
|
|
17
|
+
t.jsonb :metadata, default: {}
|
|
18
|
+
t.timestamps
|
|
19
|
+
end
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,22 @@
|
|
|
1
|
+
class CreateOcppChargingSessions < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
2
|
+
def change
|
|
3
|
+
create_table :ocpp_charging_sessions do |t|
|
|
4
|
+
t.references :charge_point, null: false, foreign_key: { to_table: :ocpp_charge_points }
|
|
5
|
+
t.integer :connector_id, null: false
|
|
6
|
+
t.string :transaction_id, index: { unique: true }
|
|
7
|
+
t.string :id_tag
|
|
8
|
+
t.string :status, default: "Preparing"
|
|
9
|
+
t.datetime :started_at
|
|
10
|
+
t.datetime :stopped_at
|
|
11
|
+
t.decimal :start_meter_value, precision: 10, scale: 2
|
|
12
|
+
t.decimal :stop_meter_value, precision: 10, scale: 2
|
|
13
|
+
t.decimal :energy_consumed, precision: 10, scale: 2
|
|
14
|
+
t.integer :duration_seconds
|
|
15
|
+
t.string :stop_reason
|
|
16
|
+
t.jsonb :metadata, default: {}
|
|
17
|
+
t.timestamps
|
|
18
|
+
end
|
|
19
|
+
|
|
20
|
+
add_index :ocpp_charging_sessions, [:charge_point_id, :connector_id]
|
|
21
|
+
end
|
|
22
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
class CreateOcppMessages < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
2
|
+
def change
|
|
3
|
+
create_table :ocpp_messages do |t|
|
|
4
|
+
t.references :charge_point, null: false, foreign_key: { to_table: :ocpp_charge_points }
|
|
5
|
+
t.string :message_id, null: false
|
|
6
|
+
t.string :direction, null: false # inbound, outbound
|
|
7
|
+
t.string :action
|
|
8
|
+
t.string :message_type # CALL, CALLRESULT, CALLERROR
|
|
9
|
+
t.jsonb :payload, default: {}
|
|
10
|
+
t.string :status # pending, sent, received, error
|
|
11
|
+
t.text :error_message
|
|
12
|
+
t.timestamps
|
|
13
|
+
end
|
|
14
|
+
|
|
15
|
+
add_index :ocpp_messages, :message_id
|
|
16
|
+
add_index :ocpp_messages, [:charge_point_id, :created_at]
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
class CreateOcppMeterValues < ActiveRecord::Migration[<%= ActiveRecord::Migration.current_version %>]
|
|
2
|
+
def change
|
|
3
|
+
create_table :ocpp_meter_values do |t|
|
|
4
|
+
t.references :charging_session, null: false, foreign_key: { to_table: :ocpp_charging_sessions }
|
|
5
|
+
t.references :charge_point, null: false, foreign_key: { to_table: :ocpp_charge_points }
|
|
6
|
+
t.integer :connector_id
|
|
7
|
+
t.string :measurand
|
|
8
|
+
t.string :phase
|
|
9
|
+
t.string :unit
|
|
10
|
+
t.string :context
|
|
11
|
+
t.string :format
|
|
12
|
+
t.string :location
|
|
13
|
+
t.decimal :value, precision: 15, scale: 4
|
|
14
|
+
t.datetime :timestamp
|
|
15
|
+
t.timestamps
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
add_index :ocpp_meter_values, :measurand
|
|
19
|
+
add_index :ocpp_meter_values, :timestamp
|
|
20
|
+
end
|
|
21
|
+
end
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
Ocpp::Rails.setup do |config|
|
|
2
|
+
# Default OCPP version to use
|
|
3
|
+
config.ocpp_version = "1.6"
|
|
4
|
+
|
|
5
|
+
# Supported OCPP versions (only 1.6 is implemented)
|
|
6
|
+
config.supported_versions = [ "1.6" ]
|
|
7
|
+
|
|
8
|
+
# Heartbeat interval in seconds
|
|
9
|
+
config.heartbeat_interval = 300
|
|
10
|
+
|
|
11
|
+
# Connection timeout in seconds
|
|
12
|
+
config.connection_timeout = 30
|
|
13
|
+
end
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
module Ocpp
|
|
2
|
+
module Rails
|
|
3
|
+
class Engine < ::Rails::Engine
|
|
4
|
+
isolate_namespace Ocpp::Rails
|
|
5
|
+
|
|
6
|
+
config.generators.api_only = true
|
|
7
|
+
|
|
8
|
+
# Configure ActionCable to use the async adapter (works with SQLite)
|
|
9
|
+
# This is suitable for development, testing, and single-server deployments
|
|
10
|
+
# For production with multiple servers, use Redis or PostgreSQL adapter.
|
|
11
|
+
# An existing config/cable.yml always takes precedence.
|
|
12
|
+
initializer "ocpp_rails.action_cable", before: "actioncable.set_configs" do |app|
|
|
13
|
+
if (::Rails.env.development? || ::Rails.env.test?) && !app.root.join("config/cable.yml").exist?
|
|
14
|
+
app.config.action_cable.cable ||= { "adapter" => "async" }
|
|
15
|
+
end
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
19
|
+
end
|
data/lib/ocpp/rails.rb
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
require "ocpp/rails/version"
|
|
2
|
+
require "ocpp/rails/engine"
|
|
3
|
+
|
|
4
|
+
module Ocpp
|
|
5
|
+
module Rails
|
|
6
|
+
class << self
|
|
7
|
+
attr_accessor :configuration
|
|
8
|
+
end
|
|
9
|
+
|
|
10
|
+
def self.configuration
|
|
11
|
+
@configuration ||= Configuration.new
|
|
12
|
+
end
|
|
13
|
+
|
|
14
|
+
def self.setup
|
|
15
|
+
yield(configuration)
|
|
16
|
+
end
|
|
17
|
+
|
|
18
|
+
def self.supported_versions
|
|
19
|
+
configuration.supported_versions
|
|
20
|
+
end
|
|
21
|
+
|
|
22
|
+
def self.message_rate_limiter
|
|
23
|
+
@message_rate_limiter ||= RateLimiter.new { configuration.max_messages_per_minute }
|
|
24
|
+
end
|
|
25
|
+
|
|
26
|
+
def self.connection_rate_limiter
|
|
27
|
+
@connection_rate_limiter ||= RateLimiter.new { configuration.max_connection_attempts_per_minute }
|
|
28
|
+
end
|
|
29
|
+
|
|
30
|
+
def self.reset_rate_limiters!
|
|
31
|
+
@message_rate_limiter&.reset!
|
|
32
|
+
@connection_rate_limiter&.reset!
|
|
33
|
+
end
|
|
34
|
+
|
|
35
|
+
class Configuration
|
|
36
|
+
attr_accessor :ocpp_version, :supported_versions, :heartbeat_interval, :connection_timeout,
|
|
37
|
+
:state_change_hooks, :state_change_retention_days, :state_change_cleanup_enabled,
|
|
38
|
+
:authorization_hooks, :authorization_retention_days, :authorization_cleanup_enabled,
|
|
39
|
+
:implausible_energy_jump_wh, :authentication_mode,
|
|
40
|
+
:max_messages_per_minute, :max_connection_attempts_per_minute
|
|
41
|
+
|
|
42
|
+
def initialize
|
|
43
|
+
@ocpp_version = "1.6"
|
|
44
|
+
# Only 1.6 is implemented; expand when 2.x support lands.
|
|
45
|
+
@supported_versions = [ "1.6" ]
|
|
46
|
+
@heartbeat_interval = 300
|
|
47
|
+
@connection_timeout = 30
|
|
48
|
+
@state_change_hooks = []
|
|
49
|
+
@authorization_hooks = []
|
|
50
|
+
@state_change_retention_days = 30
|
|
51
|
+
@state_change_cleanup_enabled = true
|
|
52
|
+
@authorization_retention_days = 30
|
|
53
|
+
@authorization_cleanup_enabled = true
|
|
54
|
+
# Max plausible energy register increase between samples, in Wh;
|
|
55
|
+
# readings jumping further are flagged. nil disables the check.
|
|
56
|
+
@implausible_energy_jump_wh = 1_000_000
|
|
57
|
+
# :basic (OCPP-J Security Profile 1, HTTP Basic Auth) or :none.
|
|
58
|
+
# :none accepts any client that knows a station identifier - only
|
|
59
|
+
# for closed networks or during migration.
|
|
60
|
+
@authentication_mode = :basic
|
|
61
|
+
# Per-station ingress limits (fixed 60s windows, per process);
|
|
62
|
+
# nil disables the respective check.
|
|
63
|
+
@max_messages_per_minute = 300
|
|
64
|
+
@max_connection_attempts_per_minute = 12
|
|
65
|
+
end
|
|
66
|
+
|
|
67
|
+
def register_state_change_hook(hook)
|
|
68
|
+
unless hook.respond_to?(:call)
|
|
69
|
+
raise ArgumentError, "Hook must respond to :call method"
|
|
70
|
+
end
|
|
71
|
+
@state_change_hooks << hook
|
|
72
|
+
end
|
|
73
|
+
|
|
74
|
+
def register_authorization_hook(hook)
|
|
75
|
+
unless hook.respond_to?(:call)
|
|
76
|
+
raise ArgumentError, "Hook must respond to :call method"
|
|
77
|
+
end
|
|
78
|
+
@authorization_hooks << hook
|
|
79
|
+
end
|
|
80
|
+
end
|
|
81
|
+
end
|
|
82
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
namespace :ocpp do
|
|
2
|
+
namespace :authorizations do
|
|
3
|
+
desc "Clean up old OCPP authorization records"
|
|
4
|
+
task cleanup: :environment do
|
|
5
|
+
retention_days = ENV["RETENTION_DAYS"]&.to_i || Ocpp::Rails.configuration.authorization_retention_days
|
|
6
|
+
deleted_count = Ocpp::Rails::Authorization.older_than(retention_days).delete_all
|
|
7
|
+
|
|
8
|
+
puts "Deleted #{deleted_count} Authorization records older than #{retention_days} days"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
desc "Start the automatic cleanup job (runs daily)"
|
|
12
|
+
task start_cleanup_job: :environment do
|
|
13
|
+
Ocpp::Rails::CleanupAuthorizationsJob.perform_later
|
|
14
|
+
|
|
15
|
+
puts "Automatic cleanup job started. It will run daily if cleanup is enabled."
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
namespace :ocpp do
|
|
2
|
+
namespace :state_changes do
|
|
3
|
+
desc "Clean up old OCPP state change records"
|
|
4
|
+
task cleanup: :environment do
|
|
5
|
+
retention_days = ENV["RETENTION_DAYS"]&.to_i || Ocpp::Rails.configuration.state_change_retention_days
|
|
6
|
+
deleted_count = Ocpp::Rails::StateChange.older_than(retention_days).delete_all
|
|
7
|
+
|
|
8
|
+
puts "Deleted #{deleted_count} StateChange records older than #{retention_days} days"
|
|
9
|
+
end
|
|
10
|
+
|
|
11
|
+
desc "Start the automatic cleanup job (runs daily)"
|
|
12
|
+
task start_cleanup_job: :environment do
|
|
13
|
+
Ocpp::Rails::CleanupStateChangesJob.perform_later
|
|
14
|
+
|
|
15
|
+
puts "Automatic cleanup job started. It will run daily if cleanup is enabled."
|
|
16
|
+
end
|
|
17
|
+
end
|
|
18
|
+
end
|
metadata
ADDED
|
@@ -0,0 +1,196 @@
|
|
|
1
|
+
--- !ruby/object:Gem::Specification
|
|
2
|
+
name: ocpp-rails
|
|
3
|
+
version: !ruby/object:Gem::Version
|
|
4
|
+
version: 0.2.4
|
|
5
|
+
platform: ruby
|
|
6
|
+
authors:
|
|
7
|
+
- Jakob Sommerhuber
|
|
8
|
+
bindir: bin
|
|
9
|
+
cert_chain: []
|
|
10
|
+
date: 1980-01-02 00:00:00.000000000 Z
|
|
11
|
+
dependencies:
|
|
12
|
+
- !ruby/object:Gem::Dependency
|
|
13
|
+
name: rails
|
|
14
|
+
requirement: !ruby/object:Gem::Requirement
|
|
15
|
+
requirements:
|
|
16
|
+
- - ">="
|
|
17
|
+
- !ruby/object:Gem::Version
|
|
18
|
+
version: 8.0.0
|
|
19
|
+
type: :runtime
|
|
20
|
+
prerelease: false
|
|
21
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
22
|
+
requirements:
|
|
23
|
+
- - ">="
|
|
24
|
+
- !ruby/object:Gem::Version
|
|
25
|
+
version: 8.0.0
|
|
26
|
+
- !ruby/object:Gem::Dependency
|
|
27
|
+
name: websocket-driver
|
|
28
|
+
requirement: !ruby/object:Gem::Requirement
|
|
29
|
+
requirements:
|
|
30
|
+
- - "~>"
|
|
31
|
+
- !ruby/object:Gem::Version
|
|
32
|
+
version: '0.7'
|
|
33
|
+
type: :runtime
|
|
34
|
+
prerelease: false
|
|
35
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
36
|
+
requirements:
|
|
37
|
+
- - "~>"
|
|
38
|
+
- !ruby/object:Gem::Version
|
|
39
|
+
version: '0.7'
|
|
40
|
+
- !ruby/object:Gem::Dependency
|
|
41
|
+
name: rspec-rails
|
|
42
|
+
requirement: !ruby/object:Gem::Requirement
|
|
43
|
+
requirements:
|
|
44
|
+
- - "~>"
|
|
45
|
+
- !ruby/object:Gem::Version
|
|
46
|
+
version: '6.0'
|
|
47
|
+
type: :development
|
|
48
|
+
prerelease: false
|
|
49
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
50
|
+
requirements:
|
|
51
|
+
- - "~>"
|
|
52
|
+
- !ruby/object:Gem::Version
|
|
53
|
+
version: '6.0'
|
|
54
|
+
- !ruby/object:Gem::Dependency
|
|
55
|
+
name: factory_bot_rails
|
|
56
|
+
requirement: !ruby/object:Gem::Requirement
|
|
57
|
+
requirements:
|
|
58
|
+
- - "~>"
|
|
59
|
+
- !ruby/object:Gem::Version
|
|
60
|
+
version: '6.0'
|
|
61
|
+
type: :development
|
|
62
|
+
prerelease: false
|
|
63
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
64
|
+
requirements:
|
|
65
|
+
- - "~>"
|
|
66
|
+
- !ruby/object:Gem::Version
|
|
67
|
+
version: '6.0'
|
|
68
|
+
- !ruby/object:Gem::Dependency
|
|
69
|
+
name: faker
|
|
70
|
+
requirement: !ruby/object:Gem::Requirement
|
|
71
|
+
requirements:
|
|
72
|
+
- - "~>"
|
|
73
|
+
- !ruby/object:Gem::Version
|
|
74
|
+
version: '3.0'
|
|
75
|
+
type: :development
|
|
76
|
+
prerelease: false
|
|
77
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
78
|
+
requirements:
|
|
79
|
+
- - "~>"
|
|
80
|
+
- !ruby/object:Gem::Version
|
|
81
|
+
version: '3.0'
|
|
82
|
+
- !ruby/object:Gem::Dependency
|
|
83
|
+
name: webmock
|
|
84
|
+
requirement: !ruby/object:Gem::Requirement
|
|
85
|
+
requirements:
|
|
86
|
+
- - "~>"
|
|
87
|
+
- !ruby/object:Gem::Version
|
|
88
|
+
version: '3.0'
|
|
89
|
+
type: :development
|
|
90
|
+
prerelease: false
|
|
91
|
+
version_requirements: !ruby/object:Gem::Requirement
|
|
92
|
+
requirements:
|
|
93
|
+
- - "~>"
|
|
94
|
+
- !ruby/object:Gem::Version
|
|
95
|
+
version: '3.0'
|
|
96
|
+
description: Use this engine to communicate to your EV Charging stations
|
|
97
|
+
email:
|
|
98
|
+
- jakob@sommerhuber.name
|
|
99
|
+
executables: []
|
|
100
|
+
extensions: []
|
|
101
|
+
extra_rdoc_files: []
|
|
102
|
+
files:
|
|
103
|
+
- MIT-LICENSE
|
|
104
|
+
- README.md
|
|
105
|
+
- Rakefile
|
|
106
|
+
- app/assets/stylesheets/ocpp/rails/application.css
|
|
107
|
+
- app/channels/ocpp/rails/charge_point_channel.rb
|
|
108
|
+
- app/controllers/ocpp/rails/application_controller.rb
|
|
109
|
+
- app/helpers/ocpp/rails/application_helper.rb
|
|
110
|
+
- app/jobs/ocpp/rails/application_job.rb
|
|
111
|
+
- app/jobs/ocpp/rails/async_hook_job.rb
|
|
112
|
+
- app/jobs/ocpp/rails/authorization_async_hook_job.rb
|
|
113
|
+
- app/jobs/ocpp/rails/change_availability_job.rb
|
|
114
|
+
- app/jobs/ocpp/rails/change_configuration_job.rb
|
|
115
|
+
- app/jobs/ocpp/rails/cleanup_authorizations_job.rb
|
|
116
|
+
- app/jobs/ocpp/rails/cleanup_state_changes_job.rb
|
|
117
|
+
- app/jobs/ocpp/rails/clear_cache_job.rb
|
|
118
|
+
- app/jobs/ocpp/rails/get_configuration_job.rb
|
|
119
|
+
- app/jobs/ocpp/rails/remote_start_transaction_job.rb
|
|
120
|
+
- app/jobs/ocpp/rails/remote_stop_transaction_job.rb
|
|
121
|
+
- app/jobs/ocpp/rails/reset_job.rb
|
|
122
|
+
- app/jobs/ocpp/rails/unlock_connector_job.rb
|
|
123
|
+
- app/mailers/ocpp/rails/application_mailer.rb
|
|
124
|
+
- app/models/ocpp/rails/application_record.rb
|
|
125
|
+
- app/models/ocpp/rails/authorization.rb
|
|
126
|
+
- app/models/ocpp/rails/charge_point.rb
|
|
127
|
+
- app/models/ocpp/rails/charging_session.rb
|
|
128
|
+
- app/models/ocpp/rails/message.rb
|
|
129
|
+
- app/models/ocpp/rails/meter_value.rb
|
|
130
|
+
- app/models/ocpp/rails/state_change.rb
|
|
131
|
+
- app/services/ocpp/rails/actions/authorize_handler.rb
|
|
132
|
+
- app/services/ocpp/rails/actions/boot_notification_handler.rb
|
|
133
|
+
- app/services/ocpp/rails/actions/heartbeat_handler.rb
|
|
134
|
+
- app/services/ocpp/rails/actions/meter_values_handler.rb
|
|
135
|
+
- app/services/ocpp/rails/actions/start_transaction_handler.rb
|
|
136
|
+
- app/services/ocpp/rails/actions/status_notification_handler.rb
|
|
137
|
+
- app/services/ocpp/rails/actions/stop_transaction_handler.rb
|
|
138
|
+
- app/services/ocpp/rails/authorization_hook_manager.rb
|
|
139
|
+
- app/services/ocpp/rails/message_handler.rb
|
|
140
|
+
- app/services/ocpp/rails/meter_anomaly_detector.rb
|
|
141
|
+
- app/services/ocpp/rails/protocol.rb
|
|
142
|
+
- app/services/ocpp/rails/rate_limiter.rb
|
|
143
|
+
- app/services/ocpp/rails/state_change_hook_manager.rb
|
|
144
|
+
- app/services/ocpp/rails/station_authenticator.rb
|
|
145
|
+
- app/services/ocpp/rails/timestamp_parser.rb
|
|
146
|
+
- config/routes.rb
|
|
147
|
+
- db/migrate/20251008162902_create_ocpp_models.rb
|
|
148
|
+
- db/migrate/20251015190754_make_charging_session_id_nullable_in_meter_values.rb
|
|
149
|
+
- db/migrate/20251016000000_create_ocpp_state_changes.rb
|
|
150
|
+
- db/migrate/20251017000000_create_ocpp_authorizations.rb
|
|
151
|
+
- db/migrate/20260707000000_add_timestamp_provenance_to_ocpp_meter_values.rb
|
|
152
|
+
- db/migrate/20260707000001_convert_ocpp_transaction_id_to_integer.rb
|
|
153
|
+
- db/migrate/20260707000002_add_active_session_guard_to_ocpp_charging_sessions.rb
|
|
154
|
+
- db/migrate/20260707000003_add_anomaly_flags_to_ocpp_meter_values.rb
|
|
155
|
+
- db/migrate/20260707000004_add_auth_password_digest_to_ocpp_charge_points.rb
|
|
156
|
+
- lib/generators/ocpp/rails/install_generator.rb
|
|
157
|
+
- lib/generators/ocpp/rails/templates/README
|
|
158
|
+
- lib/generators/ocpp/rails/templates/create_ocpp_charge_points.rb
|
|
159
|
+
- lib/generators/ocpp/rails/templates/create_ocpp_charging_sessions.rb
|
|
160
|
+
- lib/generators/ocpp/rails/templates/create_ocpp_messages.rb
|
|
161
|
+
- lib/generators/ocpp/rails/templates/create_ocpp_meter_values.rb
|
|
162
|
+
- lib/generators/ocpp/rails/templates/ocpp_rails.rb
|
|
163
|
+
- lib/ocpp/rails.rb
|
|
164
|
+
- lib/ocpp/rails/engine.rb
|
|
165
|
+
- lib/ocpp/rails/version.rb
|
|
166
|
+
- lib/tasks/ocpp/authorizations.rake
|
|
167
|
+
- lib/tasks/ocpp/rails_tasks.rake
|
|
168
|
+
- lib/tasks/ocpp/state_changes.rake
|
|
169
|
+
homepage: https://github.com/trahfo/ocpp-rails
|
|
170
|
+
licenses:
|
|
171
|
+
- MIT
|
|
172
|
+
metadata:
|
|
173
|
+
homepage_uri: https://github.com/trahfo/ocpp-rails
|
|
174
|
+
source_code_uri: https://github.com/trahfo/ocpp-rails/tree/main
|
|
175
|
+
changelog_uri: https://github.com/trahfo/ocpp-rails/blob/main/CHANGELOG.md
|
|
176
|
+
bug_tracker_uri: https://github.com/trahfo/ocpp-rails/issues
|
|
177
|
+
documentation_uri: https://github.com/trahfo/ocpp-rails/blob/main/README.md
|
|
178
|
+
rubygems_mfa_required: 'true'
|
|
179
|
+
rdoc_options: []
|
|
180
|
+
require_paths:
|
|
181
|
+
- lib
|
|
182
|
+
required_ruby_version: !ruby/object:Gem::Requirement
|
|
183
|
+
requirements:
|
|
184
|
+
- - ">="
|
|
185
|
+
- !ruby/object:Gem::Version
|
|
186
|
+
version: '4.0'
|
|
187
|
+
required_rubygems_version: !ruby/object:Gem::Requirement
|
|
188
|
+
requirements:
|
|
189
|
+
- - ">="
|
|
190
|
+
- !ruby/object:Gem::Version
|
|
191
|
+
version: '0'
|
|
192
|
+
requirements: []
|
|
193
|
+
rubygems_version: 4.0.10
|
|
194
|
+
specification_version: 4
|
|
195
|
+
summary: Rails engine that provides OCPP 1.6 communication for EV charging stations
|
|
196
|
+
test_files: []
|