Welcome to my NJU Charging - Gulou or NJU Charging - Xianlin
The origin of all this came from a certain evening in September when I couldn't find a charging pile...
In fact, there was already a NJU Charging webpage before that: https://charge.zhuxh.net/

However, personally I felt it was still lacking. You could only see at a glance where there were vacancies, but because charging piles were too scarce, when you wanted to charge, it was likely all red, or the only green ones were far away.
So I decided to write my own, which could display estimated remaining time, making it convenient for me to wait in advance , to outcompete you all
Backend Data Scraping
Web scraping is quite easy for me, after all I've written several scraping-related projects. Reqable start!
Getting Charging Station IDs
First, filter out the charging stations belonging to NJU Xianlin from a bunch of requests in the Shankai Laidian app, get the station_id of the charging stations. This step is purely manual copying, the specific IDs are as follows:
Getting Outlet IDs for Each Charging Station
The previous step only had 33 charging stations, manual copying was acceptable, but if I had to manually copy 302 outlet IDs, please spare me.
Written on June 16, 2025: Why do many of the newly added charging piles have only two outlets per station, causing me to manually copy station_id for a long time today. Currently, Xianlin campus has a total of 112 charging stations and 724 outlets.
From f'https://wemp.issks.com/charge/v1/outlet/station/outlets/{station_id}' you can get the information of each charging station, which includes the outlet IDs.
Finally, Let's Get the Status of Each Outlet
In the previous step we can get the outletNo of each charging outlet under each charging station (e.g., School of Astronomy). In this step, we can get the specific status of each outlet from f'https://wemp.issks.com/charge/v1/charging/outlet/{outletNo}' based on outletNo!
Example response:
Actually, a lot of the information inside is unnecessary. I just need to extract the outlet name, estimated remaining time, used time, status code (idle, fault, per-minute billing mode, fixed amount mode), and whether there is error information. At the same time, calculate an estimated available time for the frontend to display directly (after all, my frontend skills are too weak). The code is as follows:
Fortunately, this step of getting status does not require a token, and the outlets under each station are completely fixed. Afterwards, updating data just requires repeating this step based on the existing outletNo.
Data Post-processing
When I deploy it myself, I use multithreading (302 data entries are basically done in about 2 seconds, and in practice it doesn't trigger risk control) to run, and update the data on the backend machine every minute.
To make it easier for the frontend to call, I also sort the data by remaining time on the backend, and change the grouping of charging stations from originally by xx machine to by xx building:
First Version Frontend
After all, I'm a frontend idiot, my first version frontend was generated using Python. >︿<
I'm posting it here for everyone to laugh at.
And the interface was quite crude, but at least I used GPT to generate a piece of JS code for filtering stations.

Second Version Frontend
The so-called second version was just writing a few lines of CSS to try to salvage the interface.

Third Version Frontend
I started tinkering with my new personal homepage. Since Mix Space supports writing Markdown with JavaScript, I put /charge.html under my personal homepage, and also improved the original filtering function. When filtering, it changes the URL parameters, so after refreshing, it can remember the last station the user filtered and display it directly.

Fourth Version Frontend
Since the first version used a table display, as can be seen from the above images, the experience on the more common use case—mobile phones—was truly indescribable. So I made up my mind to spend half a day refactoring the UI, and added a statistics table at the beginning, making it more convenient to plan charging destinations.

Basically all the frontend and backend code is in the GitHub repository below. You are welcome to use it but please comply with the MIT license and retain my copyright information when using it.
Subsequent Minor Updates
- 2024-12-01: Added Gulou campus.
- 2025-01-07: Today I suddenly discovered that charging must be recharged and then billed by the minute, damn it. Updated to sort by used time in reverse order. According to the instructions provided by Shankai Charging, this time is a maximum of 480 minutes, at least it can serve as a reference to roughly know which charging pile is about to finish.
- 2025-02-22: In the per-minute billing mode, users can now choose the prepaid amount themselves, so the estimated available time can be estimated based on this. However, considering that some people directly choose a higher amount to fully charge, and the precision of the values returned by the API leads to low calculation accuracy, it is for reference only. The per-kWh billing mode could theoretically also be estimated, but considering that the API cannot directly read the power, it is not implemented for now.
- 2025-06-16: Added multiple charging piles in Gulou and Xianlin. (Outlet count changes: Gulou 148->308, Xianlin 302->724)
- 2025-06-22: It seems the system's maximum charging time is set to 480 minutes, so based on this, the estimation of remaining time has been modified.
- 2025-09-09: Removed the historical charging record feature.
- 2025-10-11: Updated charging piles.