Ruby implementation of the S2 standard (EN 50491-12-2) for smart grid energy flexibility.
S2 is the European standard for communication between Customer Energy Managers (CEM) and Resource Managers (RM). It enables demand-response and flexible power control for devices like EV chargers, heat pumps, and home batteries. Essential for balancing the grid as we electrify our homes and integrate more renewable energy.
This library implements the S2 protocol for the Resource Manager role, allowing devices to communicate their energy flexibility to energy management systems.
- WebSocket-based communication with automatic reconnection
- Full message validation using JSON schemas from the S2 specification
- Support for Fill Rate Based Control (FRBC) - ideal for battery and EV charging
- Extensible message handler pattern for custom business logic
- Built on async Ruby for efficient concurrent connections
This library implements S2 version 0.0.2-beta.
Add to your Gemfile:
gem "s2-ruby"Or install directly:
gem install s2-rubyrequire "s2"
# Configure logging (optional)
S2.logger = Logger.new($stdout)
# Set supported protocol versions (optional, defaults to ["0.0.2-beta"])
S2.supported_protocol_versions = ["0.0.2-beta"]class MyMessageHandler < S2::MessageHandler
on S2::Messages::HandshakeResponse do |message|
# Handle handshake response
end
on S2::Messages::SelectControlType do |message|
# Handle control type selection
end
end
S2.message_handler_class = MyMessageHandlerAsync do |task|
connection = S2::Connection.new(
resource_id: "my-resource-id",
task: task,
ws_url: "wss://example.com/s2"
)
connection.connect
end# Parse incoming message
message = S2::MessageFactory.create_message(json_string)
# Create outgoing message
handshake = S2::Messages::Handshake.new(
message_id: SecureRandom.uuid,
message_type: S2::Messages::HandshakeMessageType::Handshake,
role: S2::Messages::EnergyManagementRole::Rm,
supported_protocol_versions: ["0.0.2-beta"]
)
json = handshake.to_json- Handshake / HandshakeResponse
- ResourceManagerDetails
- SelectControlType
- PowerForecast / PowerMeasurement
- ReceptionStatus
- InstructionStatusUpdate
- RevokeObject
- SessionRequest
- FRBC (Fill Rate Based Control) messages:
- SystemDescription, StorageStatus, ActuatorStatus
- Instruction, UsageForecast, FillLevelTargetProfile
- LeakageBehaviour, TimerStatus
┌─────────────────────┐ WebSocket ┌─────────────────┐
│ Your Application │◄─────────────────────►│ CEM Server │
│ (Resource Manager) │ │ │
└──────────┬──────────┘ └─────────────────┘
│
▼
┌─────────────────────┐
│ S2::Connection │ ← Manages WebSocket lifecycle
│ S2::Session │ ← Handles protocol state
│ S2::MessageHandler │ ← Your custom logic
└─────────────────────┘
bundle install
bundle exec rspec
bundle exec rubocopBug reports and pull requests are welcome on GitHub at https://github.com/stekker/s2-ruby.
Stekker is a smart charging service provider offering AI-powered, grid-aware EV charging solutions. We help partners optimize charging schedules based on solar energy, grid capacity, and dynamic energy prices, enabling growth within grid limits. This library is part of our commitment to open standards like S2, OCPP, and OpenADR.
This gem is available as open source under the Apache License 2.0.