Skip to content

Latest commit

 

History

History
370 lines (288 loc) · 15.4 KB

File metadata and controls

370 lines (288 loc) · 15.4 KB

EMS4J

Java Spring Boot License

中文文档

EMS4J is a Spring Boot multi-module energy management system that supports both prepaid operations and energy-consumption analytics. It provides remote device control and multiple billing modes (pay-as-you-go, consolidated, monthly), supports both WeChat Pay and offline payments, and includes peak/off-peak metering, tiered pricing, account management, and financial accounting. It is compatible with multi-protocol device access, and can be adapted to typical scenarios such as campus dormitory prepaid systems and industrial park prepaid systems. The codebase is cleanly structured for easy extension. It is also an open-source project for learning complex business modeling and Spring Boot multi-module architecture design. If this project helps you, please consider giving it a ⭐️.

Features

  • 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)
  • Remote control (switch on/off, multi-rate configuration)
  • Financial accounting (bills, transactions, reconciliation)

Quick Experience

cp deploy/env.example .env
docker compose -f deploy/compose/docker-compose.full.yml up -d --build

Default access URLs:

  • Frontend app: http://127.0.0.1:4173
  • Backend API docs: http://127.0.0.1:8080/doc.html

Default credentials:

  • Username: admin
  • Password: Abc123!@#

Notes:

  • docker-compose.full.yml starts the frontend, backend, 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 & Deployment section below

Highlights and Design Focus

  • A complete prepaid business loop
    Covers account opening, recharge, charging, warnings, account settlement, order payment, and remote control beyond a simple CRUD admin system.

  • Clear multi-module layering
    Built with a Spring Boot multi-module structure where domains such as device / account / billing / order / lease / plan / aggregation stay explicit and readable.

  • Useful for studying complex business modeling
    Includes pay-as-you-go, consolidated, and monthly billing models, plus the collaboration between accounts, meters, orders, and accounting flows.

  • Includes the IoT access path, not just the business backend
    The standalone ems-iot module covers multi-protocol access, packet parsing, command dispatch, and event publishing.

  • Solid async and idempotency practices
    Covers MQ-based processing, transactional messaging, duplicate report handling, and unique-index-backed protection.

  • Runnable locally, not just a conceptual repository
    Includes frontend and backend projects, Docker-based dependencies, SQL bootstrap scripts, and runtime documentation.

Key Screens

Core Business Loop

Page Screenshot
Account Detail Account Detail
Account Settlement Account Settlement
Order List Order List
Order Creation Order Creation

Device and Billing Capabilities

Page Screenshot
Meter Detail Meter Detail
Price Plan Detail Price Plan Detail
Warning Plan Detail Warning Plan Detail

Prepaid Mode Description

The system supports three billing types: pay-as-you-go, consolidated, and monthly. In pay-as-you-go and consolidated modes, balance is deducted based on actual usage. In pay-as-you-go mode, each water/electric meter is settled independently. In consolidated mode, the balance is recharged on one water/electric meter and other meters use that balance. Monthly is settled at a fixed amount per cycle.

The typical flow is recharge after account opening, usage generates charges and continuously updates the balance, and when the balance is insufficient or reaches the warning threshold it can trigger notifications and remote disconnect. Full account closure will be settled and a settlement order will be generated, resulting in refunds or additional payment.

Requirements

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

Development & Deployment

Clone the repository first:

git clone <repository-url>
cd ems4j

Option A: Docker local development mode

Backend middleware dependencies can be started with Docker Compose:

cp deploy/env.example .env
docker compose -f deploy/compose/docker-compose.infra.yml up -d

Then start backend and frontend separately:

# backend
mvn clean package -DskipTests
java -jar ems-bootstrap/target/ems-0.2.0.jar --spring.profiles.active=dev

# frontend
cd frontend-web
pnpm install
pnpm dev

Default access URLs:

  • Backend API docs: http://127.0.0.1:8080/doc.html
  • Frontend app: http://127.0.0.1:4173

Option B: Full Docker startup

cp 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 --build

Notes:

  • deploy/compose/docker-compose.infra.yml: MySQL / Redis / RabbitMQ only
  • deploy/compose/docker-compose.full.yml: backend / frontend / middleware
  • RabbitMQ image already includes the x-delayed-message plugin

Option C: Manual environment setup

# import database
mysql -u <user> -p <db> < sql/ems.sql

# install RabbitMQ x-delayed-message plugin
# @see https://github.com/rabbitmq/rabbitmq-delayed-message-exchange

Edit 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 dev

Build and run:

mvn clean package -DskipTests
java -jar ems-bootstrap/target/ems-0.2.0.jar --spring.profiles.active=dev

Build & Test

# 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

Tech Stack

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

Module Layered Architecture

+-------------------------------+          +-------------------------------+
|        ems-bootstrap          |          |           ems-iot             |
|       (Web Service Entry)     |          |      (IoT Service Standalone) |
+-------------------------------+          +-------------------------------+
               |                                          |
   +-----------+-----------+-----------+                  |
   |           |           |           |                  |
+--v-----+ +---v----+ +----v-------+   |                  |
| ems-web| | ems-mq | |ems-schedule|   |                  |
|(HTTP   | | (Msg)  | |  (Schedule)|   |                  |
| API)   | |        | |            |   |                  |
+--+-----+ +---+----+ +-----+------+   |                  |
   |           |            |          |                  |
   +-----------+------------+----------+------------------+
               |
+------------------------------------------------------------------+
|                        ems-business                               |
|    +------------+  +------------+  +------------+  +------------+ |
|    |   device   |  |  account   |  |  billing   |  |    order   | |
|    | (Device Mgmt)| | (Account   |  | (Balance & |  | (Trade &   | |
|    |            |  |  Mgmt)     |  |  Consume)  |  |  Payment)  | |
|    +------------+  +------------+  +------------+  +------------+ |
|    |    lease   |  |    plan    |  | aggregation|                 |
|    | (Owner &   |  | (Pricing   |  | (Cross-    |                 |
|    |  Space)    |  |  Plan)     |  | domain)    |                 |
|    +------------+  +------------+  +------------+                 |
+------------------------------------------------------------------+
               |
   +-----------+-----------+
   |                       |
+--v-------------------+  +v-----------------------+
|    ems-foundation    |  |    ems-components      |
| +------+ +---------+ |  | +----------+ +------+  |
| | user | |integrat.| |  | |datasource| | lock |  |
| +------+ +---------+ |  | +----------+ +------+  |
| +------+ +---------+ |  | +---------+ +-------+  |
| | space| | system  | |  | | context | | redis |  |
| +------+ +---------+ |  | +---------+ +-------+  |
| +------+ +---------+ |  +------------------------+
| | org  | | notifi. | |
| +------+ +---------+ |
+----------------------+
               |
       +-------v-------+
       |  ems-common   |
       | (Common Utils)|
       +---------------+

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.

Data Flow

+----------+    Command Send    +----------+    Protocol Conv   +----------+
|  ems-web |----------------->|  ems-iot |----------------->|   Device   |
+----------+                  +----------+                  +----------+
     ^                              |                              |
     |                              | Data Report                  |
     |                              v                              |
     |                       +----------+                         |
     +-----------------------| Business |<------------------------+
        API Result           | Layer    |
                           +----------+
                                 |
                                 v
                           +----------+
                           |   MySQL  |
                           +----------+

Module Details

Module Responsibility
ems-bootstrap Application entry (Spring Boot)
ems-web HTTP API layer
ems-business-device Meter, gateway, device management
ems-business-account Account opening, closing, balance and recharge
ems-business-billing Balance, meter consumption, correction, billing flows
ems-business-order Order creation, payment callback, order query and completion
ems-business-lease Owner-space lease relation, lease query and unlease validation
ems-business-plan Pricing plans, rates, time-of-use periods
ems-business-aggregation Cross-domain read aggregation and application orchestration
ems-foundation-user Authentication, permissions, roles
ems-foundation-organization Multi-tenant, org structure
ems-foundation-space Space/area management
ems-foundation-system System configuration
ems-foundation-integration Third-party platform integration
ems-components-* Common components (datasource/lock/context)
ems-mq-* Messaging infrastructure API (ems-mq-api) and business messaging app layer (ems-mq-rabbitmq)
ems-iot Netty device access, protocol parsing
ems-schedule Scheduled jobs
frontend-web Vue 3 + TypeScript admin frontend with Vitest unit tests and Playwright smoke tests
deploy TRY IT Docker Compose files, Dockerfiles, init SQL and environment examples for local infrastructure and full deployment orchestration

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.

Supported Devices

Vendor Type
Acrel (安科瑞) Meter / Gateway
Sfere (斯菲尔) Meter
Yige (仪歌) Meter
Yke (燕赵) Meter

IoT Integration

There are two integration approaches:

  1. Direct device access (in-house platform)
  1. Third-party IoT platforms
  • Implement platform adapters under ems-foundation/integration and coordinate with ems-iot and business modules.
  • Reference:

For detailed platform integration solutions, see:

Documentation

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

Motivation

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.

License

This project is licensed under the MIT License. See LICENSE.

Contact

  • Add me on WeChat and note ems4j:

    WeChat QR Code