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.
Files changed (68) hide show
  1. checksums.yaml +7 -0
  2. data/MIT-LICENSE +20 -0
  3. data/README.md +461 -0
  4. data/Rakefile +8 -0
  5. data/app/assets/stylesheets/ocpp/rails/application.css +15 -0
  6. data/app/channels/ocpp/rails/charge_point_channel.rb +94 -0
  7. data/app/controllers/ocpp/rails/application_controller.rb +7 -0
  8. data/app/helpers/ocpp/rails/application_helper.rb +6 -0
  9. data/app/jobs/ocpp/rails/application_job.rb +6 -0
  10. data/app/jobs/ocpp/rails/async_hook_job.rb +25 -0
  11. data/app/jobs/ocpp/rails/authorization_async_hook_job.rb +25 -0
  12. data/app/jobs/ocpp/rails/change_availability_job.rb +42 -0
  13. data/app/jobs/ocpp/rails/change_configuration_job.rb +41 -0
  14. data/app/jobs/ocpp/rails/cleanup_authorizations_job.rb +28 -0
  15. data/app/jobs/ocpp/rails/cleanup_state_changes_job.rb +28 -0
  16. data/app/jobs/ocpp/rails/clear_cache_job.rb +37 -0
  17. data/app/jobs/ocpp/rails/get_configuration_job.rb +38 -0
  18. data/app/jobs/ocpp/rails/remote_start_transaction_job.rb +39 -0
  19. data/app/jobs/ocpp/rails/remote_stop_transaction_job.rb +38 -0
  20. data/app/jobs/ocpp/rails/reset_job.rb +39 -0
  21. data/app/jobs/ocpp/rails/unlock_connector_job.rb +38 -0
  22. data/app/mailers/ocpp/rails/application_mailer.rb +8 -0
  23. data/app/models/ocpp/rails/application_record.rb +7 -0
  24. data/app/models/ocpp/rails/authorization.rb +26 -0
  25. data/app/models/ocpp/rails/charge_point.rb +69 -0
  26. data/app/models/ocpp/rails/charging_session.rb +72 -0
  27. data/app/models/ocpp/rails/message.rb +17 -0
  28. data/app/models/ocpp/rails/meter_value.rb +24 -0
  29. data/app/models/ocpp/rails/state_change.rb +26 -0
  30. data/app/services/ocpp/rails/actions/authorize_handler.rb +47 -0
  31. data/app/services/ocpp/rails/actions/boot_notification_handler.rb +62 -0
  32. data/app/services/ocpp/rails/actions/heartbeat_handler.rb +25 -0
  33. data/app/services/ocpp/rails/actions/meter_values_handler.rb +97 -0
  34. data/app/services/ocpp/rails/actions/start_transaction_handler.rb +126 -0
  35. data/app/services/ocpp/rails/actions/status_notification_handler.rb +99 -0
  36. data/app/services/ocpp/rails/actions/stop_transaction_handler.rb +121 -0
  37. data/app/services/ocpp/rails/authorization_hook_manager.rb +102 -0
  38. data/app/services/ocpp/rails/message_handler.rb +153 -0
  39. data/app/services/ocpp/rails/meter_anomaly_detector.rb +50 -0
  40. data/app/services/ocpp/rails/protocol.rb +65 -0
  41. data/app/services/ocpp/rails/rate_limiter.rb +53 -0
  42. data/app/services/ocpp/rails/state_change_hook_manager.rb +26 -0
  43. data/app/services/ocpp/rails/station_authenticator.rb +46 -0
  44. data/app/services/ocpp/rails/timestamp_parser.rb +25 -0
  45. data/config/routes.rb +5 -0
  46. data/db/migrate/20251008162902_create_ocpp_models.rb +77 -0
  47. data/db/migrate/20251015190754_make_charging_session_id_nullable_in_meter_values.rb +5 -0
  48. data/db/migrate/20251016000000_create_ocpp_state_changes.rb +17 -0
  49. data/db/migrate/20251017000000_create_ocpp_authorizations.rb +15 -0
  50. data/db/migrate/20260707000000_add_timestamp_provenance_to_ocpp_meter_values.rb +6 -0
  51. data/db/migrate/20260707000001_convert_ocpp_transaction_id_to_integer.rb +19 -0
  52. data/db/migrate/20260707000002_add_active_session_guard_to_ocpp_charging_sessions.rb +11 -0
  53. data/db/migrate/20260707000003_add_anomaly_flags_to_ocpp_meter_values.rb +6 -0
  54. data/db/migrate/20260707000004_add_auth_password_digest_to_ocpp_charge_points.rb +5 -0
  55. data/lib/generators/ocpp/rails/install_generator.rb +42 -0
  56. data/lib/generators/ocpp/rails/templates/README +45 -0
  57. data/lib/generators/ocpp/rails/templates/create_ocpp_charge_points.rb +21 -0
  58. data/lib/generators/ocpp/rails/templates/create_ocpp_charging_sessions.rb +22 -0
  59. data/lib/generators/ocpp/rails/templates/create_ocpp_messages.rb +18 -0
  60. data/lib/generators/ocpp/rails/templates/create_ocpp_meter_values.rb +21 -0
  61. data/lib/generators/ocpp/rails/templates/ocpp_rails.rb +13 -0
  62. data/lib/ocpp/rails/engine.rb +19 -0
  63. data/lib/ocpp/rails/version.rb +5 -0
  64. data/lib/ocpp/rails.rb +82 -0
  65. data/lib/tasks/ocpp/authorizations.rake +18 -0
  66. data/lib/tasks/ocpp/rails_tasks.rake +4 -0
  67. data/lib/tasks/ocpp/state_changes.rake +18 -0
  68. 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
@@ -0,0 +1,5 @@
1
+ module Ocpp
2
+ module Rails
3
+ VERSION = "0.2.4"
4
+ end
5
+ 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,4 @@
1
+ # desc "Explaining what the task does"
2
+ # task :ocpp_rails do
3
+ # # Task goes here
4
+ # 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: []