EMS4J is an open-source EMS management system built on a Spring Boot multi-module architecture. It supports prepaid operations, energy-consumption analytics, IoT device access, remote device control, account management, and financial accounting. The system supports multiple billing models such as pay-as-you-go, consolidated billing, and monthly plans, and fits typical scenarios such as campus dormitories and industrial parks. It is also an open-source project for learning complex business modeling and Spring Boot multi-module architecture design.
- Multi-protocol device access
- Billing models (pay-as-you-go / consolidated billing / monthly subscription)
- Metering and billing (peak/off-peak/valley / tiered rates)
- Account management (opening / closing / recharge)
- Daily report snapshots and electric bill reports (daily meter/account snapshots, list and detail queries)
- Remote control (switch on/off, multi-rate configuration)
- Financial accounting (bills, transactions, reconciliation)
- Dormitory EMS management systems
- Industrial park EMS management systems
- Prepaid energy management systems
- EMS systems with IoT-based remote meter control
- Java projects that need a reference for multi-module architecture and complex business modeling
Frontend app: http://119.45.165.253:30080
Demo credentials:
- Username:
admin - Password:
Abc123!@#
cp deploy/env.example .env
docker compose -f deploy/compose/docker-compose.full.yml up -d --buildDefault access URLs:
- Frontend app:
http://127.0.0.1:4173 - Backend API docs:
http://127.0.0.1:8080/doc.html
Notes:
docker-compose.full.ymlstarts frontend, backend, iot, iot-simulator, MySQL, Redis, and RabbitMQ together- The first startup may take longer because images need to be built and dependencies initialized
- If you prefer running frontend and backend separately, see the
Development & Deploymentsection below
| Component | Version | Required |
|---|---|---|
| JDK | 17+ | Yes |
| Maven | 3.8+ | Yes |
| MySQL | 8.0+ | Yes |
| Redis | 6.0+ | Yes |
| RabbitMQ | 4.1+ | No |
| Node.js | 18.18+ | Required for frontend development/build |
| pnpm | 10.32+ | Required for frontend development/build |
Clone the repository first:
git clone <repository-url>
cd ems4jBackend middleware dependencies can be started with Docker Compose:
cp deploy/env.example .env
docker compose -f deploy/compose/docker-compose.infra.yml up -dThen start backend and frontend separately:
# backend
mvn clean package -DskipTests
java -jar ems-bootstrap/target/ems-*.jar --spring.profiles.active=dev
# frontend
cd frontend-web
pnpm install
pnpm devcp deploy/env.example .env
# full container mode uses: ems-bootstrap/src/main/resources/application-docker.yml
docker compose -f deploy/compose/docker-compose.full.yml up -d --buildNotes:
deploy/compose/docker-compose.infra.yml: MySQL / Redis / RabbitMQ onlydeploy/compose/docker-compose.full.yml: backend / frontend / iot / iot-simulator / middleware- RabbitMQ image already includes the
x-delayed-messageplugin iotuses thedocker,nettyprofile by default and listens on8880and19500iot-simulatoruses thedockerprofile by default and connects toiot:19500iot-simulatorpersists runtime state to/app/.data/iot-simulator-state.json- If replay start and end times are not configured explicitly,
iot-simulatorreplays data from the first day of the current month up to one second before now. If the state file already exists, replay resumes from the saved cursor instead of restarting from month start every time
The project already includes Helm charts for a single-node K3s setup. This is the recommended path when deploying backend / frontend / iot / iot-simulator / mysql / redis / rabbitmq together on Kubernetes.
Entry document:
The current Helm layout includes:
ems-infra: MySQL, Redis, RabbitMQems-app: Backend, Frontend, IOT, IOT Simulator
Recommended prerequisites:
- Harbor or another reachable image registry
- A K3s cluster with namespaces
ems-infraandems-app - The image pull secret
harbor-pull-secretin both namespaces
The Helm guide already includes:
- Image build and push commands
- Installation commands for
ems-infraandems-app - Post-deployment verification commands
- Log inspection steps for
iotandiot-simulator
# import database
mysql -u <user> -p <db> < deploy/mysql/init/001-ems.sql
mysql -u <user> -p <db> < deploy/mysql/init/002-menu.sql
mysql -u <user> -p <db> < deploy/mysql/init/003-example.sql
mysql -u <user> -p <db> < deploy/mysql/init/101-iot.sql
# install RabbitMQ x-delayed-message plugin
# @see https://github.com/rabbitmq/rabbitmq-delayed-message-exchangeEdit ems-bootstrap/src/main/resources/application-dev.yml:
- Database connection (
spring.datasource) - Redis connection (
spring.data.redis) - RabbitMQ connection (
spring.rabbitmq, optional)
Frontend proxy target defaults to http://127.0.0.1:8080 and can be overridden:
cd frontend-web
VITE_PROXY_TARGET=http://127.0.0.1:18080 pnpm devBuild and run:
mvn clean package -DskipTests
java -jar ems-bootstrap/target/ems-*.jar --spring.profiles.active=dev# Full build (skip tests)
mvn clean install -DskipTests
# Run tests
mvn test
# Module build/test (example)
mvn -pl ems-business/ems-business-device -am test
# Frontend
cd frontend-web
pnpm typecheck
pnpm test:unit
pnpm test:unit:coverage
pnpm test:e2e| Category | Technology |
|---|---|
| Language/Framework | Java 17 / Spring Boot 3.5 |
| Persistence | MyBatis-Plus / MySQL 8.0 |
| Cache | Redis / Redisson |
| Message Queue | RabbitMQ (optional) |
| IoT Access | Netty |
| Auth | Sa-Token + JWT |
| API Doc | Knife4j / SpringDoc OpenAPI |
Notes:
- ems-web can depend on both ems-business and ems-foundation (user/org/space/system, etc.).
- ems-web should depend on service/dto only; avoid direct repository/entity/mapper access.
- ems-foundation should not depend on ems-business/ems-web to keep base domains reusable.
Notes:
- ems-mq-api provides message contracts and base messaging services (infrastructure layer).
- ems-mq-rabbitmq is the business messaging app layer, hosting message listeners and orchestration.
- Frontend details are maintained in
frontend-web/README.md.
| Vendor | Type |
|---|---|
| Acrel (安科瑞) | Meter / Gateway |
| Sfere (斯菲尔) | Meter |
| Yige (仪歌) | Meter |
| Yke (燕赵) | Meter |
There are two integration approaches:
- Direct device access (in-house platform)
- Implement protocol access, parsing, command translation, and event publishing in
ems-iot. - References:
- Third-party IoT platforms
- Implement platform adapters under
ems-foundation/integrationand coordinate withems-iotand business modules. - Reference:
For detailed platform integration solutions, see:
| Document | Description |
|---|---|
| Development Practices Guide | Code style, naming conventions and development practices |
| Business Module Documentation | Business modules documentation (device, account, billing, order, lease, plan) |
| Foundation Module Documentation | Foundation modules documentation (user, organization, space, system, integration) |
| IoT Module Documentation | IoT module documentation for device access and protocol integration |
| Test Guidelines | Unit and integration test standards and best practices |
| Page | Screenshot |
|---|---|
| Account Detail | ![]() |
| Account Settlement | ![]() |
| Order List | ![]() |
| Order Creation | ![]() |
| Page | Screenshot |
|---|---|
| Meter Detail | ![]() |
| Power Consumption Trend | ![]() |
| Electric Bill Report | ![]() |
| Price Plan Detail | ![]() |
| Warning Plan Detail | ![]() |
This project grew out of an ongoing effort to reorganize and refactor a real-world complex business system.
In a prepaid energy domain, devices, accounts, billing, orders, permissions, and remote control are tightly coupled. As the business evolves, unclear module boundaries quickly make the code harder to maintain and harder to extend.
EMS4J is not only about making the features work. It is about making those relationships explicit: what belongs to device, what belongs to billing, what should be split out of account, and what logic should remain in upper-layer orchestration.
That is why this repository is both a runnable prepaid energy system and a practical reference for complex domain modeling, module-boundary governance, and engineering maintainability.
If this project gives you useful ideas, consider giving it a ⭐️.
This project is licensed under the MIT License. See LICENSE.
-
Add me on WeChat and note
ems4j:
-
Zhihu Column: 能源管理系统实践










