Pytes E-Box Component

Ahoy :wink:

i’m looking for some guys that can help me test my Component for Pytes Battery (E-Box)

The PytesEbox component allows you to pull data from Pytes Batteries into ESPHome.

It uses UART for communication.

Hardware Setup

You can connect to Pytes E-Box using the port labeled Console

Any connections via CAN or RS485 (e.g. to an inverter) are untouched and remain functional.

The console port offers a RS232 interface using a RJ45 connector.

The voltage levels are not TTL-compatible. A RS232 transceive r must be placed between the Batteries and the ESPHome device. MAX3232 -based transceivers have been tested and work well.

If you have multiple batteries you need to connect to the master battery’s console port.

rj45_pinout

ESP Pin Transceiver RJ45 Pin Function
GPIO 6 RX 3 TX
GND GND 4 Ground
GPIO 5 TX 6 RX
3v3 VCC NC Power

Commands:

Command Info Note
pwr Power data show - pwr [index]
pwr N Power data show - pwr [index]
bat N Battery data show - bat [pwr][index]
soh N State of health - soh [addr] Not ready yet, my FW has no soh :frowning:

Tested devcies:

Manufacturer Devcie
Pytes E-BOX-48100R-C
Pytes E-BOX-48100V-D (V5)
Pytes E-BOX-48100R-B (pending)

Tested EPS:

Manufacturer Devcie
Waveshare S3-Zero
- WROOM32 D1 mini
1 Like

Reserved for future post.

Hello. I am trying to install this on Pytes V5 battery but I can’t compile it. where do I put the “components” folder? “homeassistant/esphome/components/pytes_e_box” doesn’t work.

Hello, and sorry for the late replay :frowning:

you need to use the github implementation, like this:

external_components:
  - source: github://oxynatOr/esphome-pytes_e_box@frim_curr_date-sensor_fix
    components: [ pytes_e_box ]
    refresh: 5s

thanks for giving it a try :heart:

It works on Pytes V5. I only have 1 battery so I cannot test multiple battery. I checked: Battery current, SOC, Temperature, Voltage, Cell Voltage/Current/Base/temperature State, Events, Barcode, State, etc. It doesn’t show the cells voltages. It only show Normal State. Can you modify the code?

uh that looks nice !

i will check what i can do at the weekend.

are you familiar with : how to connect to console and send commands:
like
pwr
pwr 1
bat 1
soh 1

maybe the output of V5 is bit different, so i could implement this as well

This is the Putty output:






1 Like

thanks a lot!!!

okay the firmware/output is the same, even the SoH-Status is missing ^^

i will give it a shoot tomorrow (Saturday).

just one more question, what “IoT” device u are using?
i did with an ESP-32-S3-Mini/Zero, and had no luck with an C3-SuperMini.

Cya-

sensor:
  - platform: pytes_e_box
    pytes_e_box_id: ${pytes_e_box_id}
    battery: ${battery_num}
    cells: 
      - cell: 0
        voltage:
          name: "${cell_prefix} ${battery_num}.0 Voltage"
        temperature:
          name: "${cell_prefix} ${battery_num}.0 Temperature"
        coulomb:
          name: "${cell_prefix} ${battery_num}.0 Coulomb"
        current:
          name: "${cell_prefix} ${battery_num}.0 Current"

image

can you re-check the config file pls.

/e: here is an example of mine:

It works now. I see the cell voltage.


The “IoT” devices I used are Esp32 Wroom and Esp32 D1 mini( GPIO16-RX, GPIO17-TX

Thank you for the code!

cool!!

if you see any strange values or bug, or new thing, let me know!

Hi, I would like to test this.
I have 4x E-Box 48100R (B Version) and a lot of NodeMCU with ESP32 or ESP8266. Will order a MAX323 now.

I already had some experience with ESPHome and build a Modbus Adapter for my wallbox.

But I think my knowledge in not enough to understand, how to install/implement the software part.
Can you write a little tutorial?

Thanks
Eugen

Ahoy!

sure, can you tell me where the issue start, and what part need to be explained?

i would start with the ESP32, get it displayed in ESPHome and HA.

when this is working, you can link to the component.

external_components:
  - source: github://oxynatOr/esphome-pytes_e_box@frim_curr_date-sensor_fix
    components: [ pytes_e_box ]
    refresh: 5s

with the MAX in place, you can add this:

uart:
  tx_pin: GPIO5
  rx_pin: GPIO6
  baud_rate: 115200
  rx_buffer_size: 1024
  id: uart01   

pytes_e_box:
  - id: pvbatt
    uart_id: uart01
    update_interval: 30s
    batteries: 4
    poll_timeout: 4s 
    command_idle_time: 150ms

and see what will happen.

but pls. tell me where u get stuck, and i will explain it to you.

btw, thanks for helping me!

Hi an update:

  1. I managed to get this great piece of work deployed in my Home Assistant and Pytes Battery setup.

  2. The board I used is a generic WROOM-32D ESP32 dev board from Aliexpress. It has 30 pins only, therefore I used GPIO5 and GPIO4, instead of GPIO6. I hope that makes sense.

  3. I used a MAX3232 RS232 to TTL Serial Port Leavel Converter to convert the signal.
    https://www.aliexpress.com/item/1005006546673328.html

  4. I have two Pytes V5 batteries, installed in an external Nema 3 outdoor box

After some trial and error, below is the wiring diagram that I have put together.

The main issue I faced was the wifi signal range. The wifi signal is weak since my batteries are installed in an external area. The wifi strength of the ESP32 board which I have got is also very poor. I will order a new board with a design in which the wifi antenna is detached from the PCB. Let’s hope that can improve.

The ESPHome code is as below:

esphome:
  name: esphome-web-xxxx
  friendly_name: Pytes_eBox
  min_version: 2024.11.0
  name_add_mac_suffix: false

esp32:
  board: esp32dev
  framework:
    type: esp-idf

# Enable logging
logger:

# Enable Home Assistant API
api:

# Allow Over-The-Air updates
ota:
- platform: esphome

wifi:
  ssid: xxxxx
  password: xxxxx

external_components:
  - source: github://oxynatOr/esphome-pytes_e_box@frim_curr_date-sensor_fix
    components: [ pytes_e_box ]
    refresh: 5s


uart:
  tx_pin: GPIO5
  rx_pin: GPIO4
  baud_rate: 115200
  rx_buffer_size: 1024
  id: uart01  

pytes_e_box:
  - id: pvbatt
    uart_id: uart01
    update_interval: 30s
    batteries: 2
    poll_timeout: 4s 
    command_idle_time: 150ms

sensor:
  - platform: pytes_e_box
    pytes_e_box_id: pvbatt
    battery: 1
    voltage:
      name: "Battery 1 Voltage"
    current:
      name: "Battery 1 Current"
    coulomb:
      name: "Battery 1 State of Charge"
    temperature:
      name: "Battery 1 Temperature"
  - platform: pytes_e_box
    pytes_e_box_id: pvbatt
    battery: 2
    voltage:
      name: "Battery 2 Voltage"
    current:
      name: "Battery 2 Current"
    coulomb:
      name: "Battery 2 State of Charge"
    temperature:
      name: "Battery 2 Temperature"
1 Like

Hello, guys. Do you toch dip switch on a buttery? What settings do you have? Does it binary adress set?

Sorry, I understand my fault)

I’m used to the fact that rs-485 it is modbus or something like that. But here it is uart over rs-232.

An update, my ESP32 board Wifi works okay if I use a 5V power supply via the Vin pin, rather than using the USB-C socket as power source.

I was told that is due to poor Chinese board design and manufacturing that, when the board is fed from a 5V USB-C power source, the same 5V power is used to feed the CH340C chip, and the chip output 5V signal to the ESP32. Since ESP32 is supposed to work with 3.3V signal only, this causes significant interference in the circuit and distorts the Wifi performance.

1 Like

Hi,
I got it running and displaying data in ha but I’m not sure if this is a bug or if I’m doing something wrong.

[15:00:06][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:06][I][pytes_e_box:079]: Retry command from queue: bat 3 from index: 6 (2)
[15:00:06][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:06][I][pytes_e_box:079]: Retry command from queue: bat 3 from index: 6 (3)
[15:00:06][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:06][I][pytes_e_box:079]: Retry command from queue: bat 3 from index: 6 (4)
[15:00:07][W][component:237]: Component pytes_e_box took a long time for an operation (102 ms).
[15:00:07][W][component:238]: Components should block for at most 30 ms.
[15:00:07][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:07][I][pytes_e_box:079]: Retry command from queue: bat 3 from index: 6 (5)
[15:00:07][W][component:237]: Component pytes_e_box took a long time for an operation (143 ms).
[15:00:07][W][component:238]: Components should block for at most 30 ms.
[15:00:07][D][pytes_e_box:258]: parsed command -> Battery Data Index [Battery: 3]
[15:00:07][I][pytes_e_box:145]: PytesEBox command queue done.
[15:00:27][D][pytes_e_box:101]: Sending command from queue: pwr from index: 0
[15:00:27][W][component:237]: Component pytes_e_box took a long time for an operation (206 ms).
[15:00:27][W][component:238]: Components should block for at most 30 ms.
[15:00:27][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 0]
[15:00:27][I][pytes_e_box:079]: Retry command from queue: pwr from index: 0 (0)
[15:00:28][W][component:237]: Component pytes_e_box took a long time for an operation (102 ms).
[15:00:28][W][component:238]: Components should block for at most 30 ms.
[15:00:28][W][component:237]: Component pytes_e_box took a long time for an operation (77 ms).
[15:00:28][W][component:238]: Components should block for at most 30 ms.
[15:00:28][D][pytes_e_box:258]: parsed command -> Power Data [Battery: 0]
[15:00:28][D][sensor:093]: 'Battery 1 Voltage': Sending state 53.70700 V with 3 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 1 Current': Sending state 714.00000 mA with 3 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 1 Temperature': Sending state 26.00000 °C with 1 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 1 State of Charge': Sending state 75.00000 % with 0 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 2 Voltage': Sending state 53.69500 V with 3 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 2 Current': Sending state -374.00000 mA with 3 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 2 Temperature': Sending state 27.00000 °C with 1 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 2 State of Charge': Sending state 75.00000 % with 0 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 3 Voltage': Sending state 53.69200 V with 3 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 3 Current': Sending state -2582.00000 mA with 3 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 3 Temperature': Sending state 26.00000 °C with 1 decimals of accuracy
[15:00:28][D][sensor:093]: 'Battery 3 State of Charge': Sending state 64.00000 % with 0 decimals of accuracy
[15:00:28][E][pytes_e_box:338]: invalid line: found only 1, should be 23 items. in line 8
: 8     -      -      -    ??      -      -      -      ??????  -    ?j?   -        -        -                    -        -        -                    -                 
[15:00:28][E][pytes_e_box:338]: invalid line: found only 1, should be 23 items. in line 10
: 10    - ?jjjjjj????  -        -        -        -        -                    -        -  ?j?             ??j?  ?
[15:00:28][D][pytes_e_box:101]: Sending command from queue: pwr 1 from index: 1
[15:00:28][W][component:237]: Component pytes_e_box took a long time for an operation (109 ms).
[15:00:28][W][component:238]: Components should block for at most 30 ms.
[15:00:28][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 1]
[15:00:28][I][pytes_e_box:079]: Retry command from queue: pwr 1 from index: 1 (0)
[15:00:28][W][component:237]: Component pytes_e_box took a long time for an operation (90 ms).
[15:00:29][W][component:238]: Components should block for at most 30 ms.
[15:00:29][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 1]
[15:00:29][I][pytes_e_box:079]: Retry command from queue: pwr 1 from index: 1 (1)
[15:00:29][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 1]
[15:00:29][I][pytes_e_box:079]: Retry command from queue: pwr 1 from index: 1 (2)
[15:00:29][W][component:237]: Component pytes_e_box took a long time for an operation (160 ms).
[15:00:29][W][component:238]: Components should block for at most 30 ms.
[15:00:29][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 1]
[15:00:29][I][pytes_e_box:079]: Retry command from queue: pwr 1 from index: 1 (3)
[15:00:32][E][pytes_e_box:129]: timeout command from queue: pwr 1 with 4 retries
[15:00:32][D][pytes_e_box:101]: Sending command from queue: bat 1 from index: 2
[15:00:32][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 1]
[15:00:32][I][pytes_e_box:079]: Retry command from queue: bat 1 from index: 2 (0)
[15:00:33][W][component:237]: Component pytes_e_box took a long time for an operation (108 ms).
[15:00:33][W][component:238]: Components should block for at most 30 ms.
[15:00:33][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 1]
[15:00:33][I][pytes_e_box:079]: Retry command from queue: bat 1 from index: 2 (1)
[15:00:33][W][component:237]: Component pytes_e_box took a long time for an operation (72 ms).
[15:00:33][W][component:238]: Components should block for at most 30 ms.
[15:00:33][D][pytes_e_box:258]: parsed command -> Battery Data Index [Battery: 1]
[15:00:33][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 9
: 9        3352     25000    Dischg       Normal       Normal       Norma???*?????j
[15:00:33][E][pytes_e_box:308]: invalid line: found only 1, should be 9 items. in line 10
: 10       ?&?????"?????      Normal       Normal       Normal        76%      76077 m
[15:00:33][D][pytes_e_box:101]: Sending command from queue: pwr 2 from index: 3
[15:00:33][W][component:237]: Component pytes_e_box took a long time for an operation (94 ms).
[15:00:33][W][component:238]: Components should block for at most 30 ms.
[15:00:33][D][pytes_e_box:258]: parsed command -> Power Data Index [Battery: 2]
[15:00:34][D][pytes_e_box:101]: Sending command from queue: bat 2 from index: 4
[15:00:34][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 2]
[15:00:34][I][pytes_e_box:079]: Retry command from queue: bat 2 from index: 4 (0)
[15:00:34][W][component:237]: Component pytes_e_box took a long time for an operation (86 ms).
[15:00:34][W][component:238]: Components should block for at most 30 ms.
[15:00:34][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 2]
[15:00:34][I][pytes_e_box:079]: Retry command from queue: bat 2 from index: 4 (1)
[15:00:34][W][component:237]: Component pytes_e_box took a long time for an operation (138 ms).
[15:00:34][W][component:238]: Components should block for at most 30 ms.
[15:00:34][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 2]
[15:00:34][I][pytes_e_box:079]: Retry command from queue: bat 2 from index: 4 (2)
[15:00:35][W][component:237]: Component pytes_e_box took a long time for an operation (122 ms).
[15:00:35][W][component:238]: Components should block for at most 30 ms.
[15:00:35][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 2]
[15:00:35][I][pytes_e_box:079]: Retry command from queue: bat 2 from index: 4 (3)
[15:00:38][E][pytes_e_box:129]: timeout command from queue: bat 2 with 4 retries
[15:00:38][D][pytes_e_box:101]: Sending command from queue: pwr 3 from index: 5
[15:00:38][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:38][I][pytes_e_box:079]: Retry command from queue: pwr 3 from index: 5 (0)
[15:00:38][W][component:237]: Component pytes_e_box took a long time for an operation (92 ms).
[15:00:38][W][component:238]: Components should block for at most 30 ms.
[15:00:38][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:38][I][pytes_e_box:079]: Retry command from queue: pwr 3 from index: 5 (1)
[15:00:38][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:38][I][pytes_e_box:079]: Retry command from queue: pwr 3 from index: 5 (2)
[15:00:38][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:38][I][pytes_e_box:079]: Retry command from queue: pwr 3 from index: 5 (3)
[15:00:39][W][component:237]: Component pytes_e_box took a long time for an operation (178 ms).
[15:00:39][W][component:238]: Components should block for at most 30 ms.
[15:00:39][D][pytes_e_box:258]: parsed command -> Not in List [Battery: 3]
[15:00:39][I][pytes_e_box:079]: Retry command from queue: pwr 3 from index: 5 (4)
[15:00:39][W][component:237]: Component pytes_e_box took a long time for an operation (104 ms).
[15:00:39][W][component:238]: Components should block for at most 30 ms.
[15:00:39][D][pytes_e_box:258]: parsed command -> Power Data Index [Battery: 3]
[15:00:40][D][pytes_e_box:101]: Sending command from queue: bat 3 from index: 6
[15:00:40][W][component:237]: Component pytes_e_box took a long time for an operation (51 ms).
[15:00:40][W][component:238]: Components should block for at most 30 ms.
[15:00:40][D][pytes_e_box:258]: parsed command -> Battery Data Index [Battery: 3]
[15:00:40][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 1
: 1        3358     26000    Dischg       Normal       Normal       Normal ???*??¢?j
[15:00:40][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 3
: 3        3355     26000?"?????      Normal       Normal       Normal        66%      66847 m
[15:00:40][E][pytes_e_box:308]: invalid line: found only 2, should be 9 items. in line 4
: 4        3349  ????00?"?????      Normal       Normal       Normal  ???*?????j
[15:00:40][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 6
: 6        3350     26000    Dischg       Normal   ?r?????      Normal        65%      65990 m
[15:00:40][E][pytes_e_box:308]: invalid line: found only 1, should be 9 items. in line 8
: 8  ??????????"?????      Normal       Normal       Normal        64%      64121 m
[15:00:40][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 9
: 9        3357     26000    ?Z?,?      Normal       Normal    ?9?????    ???*?????j
[15:00:40][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 11
: 11       3356     25000    Dischg       Normal       Normal       No?[X??*?????j
[15:00:40][E][pytes_e_box:308]: invalid line: found only 7, should be 9 items. in line 14
: 14       3349     25000    Dischg     ?r?????      Normal       Normal        65%      65321 m
[15:00:40][E][pytes_e_box:308]: invalid line: found only 2, should be 9 items. in line 15
: 15       33MM?????"?????      Normal       Normal       Normal        66%     ???Sj
[15:00:40][I][pytes_e_box:145]: PytesEBox command queue done.
[15:00:41][I][safe_mode:041]: Boot seems successful; resetting boot loop counter

Config yaml

external_components:
  - source: github://oxynatOr/esphome-pytes_e_box@frim_curr_date-sensor_fix
    components: [ pytes_e_box ]
    refresh: 5s

uart:
  tx_pin: GPIO12
  rx_pin: GPIO14
  baud_rate: 115200
  rx_buffer_size: 1024
  id: uart01   

pytes_e_box:
  - id: pvbatt
    uart_id: uart01
    update_interval: 30s
    batteries: 3
    poll_timeout: 4s 
    command_idle_time: 150ms

sensor:
  - platform: pytes_e_box
    pytes_e_box_id: pvbatt
    battery: 1
    voltage:
      name: "Battery 1 Voltage"
    current:
      name: "Battery 1 Current"
    coulomb:
      name: "Battery 1 State of Charge"
    temperature:
      name: "Battery 1 Temperature"
  - platform: pytes_e_box
    pytes_e_box_id: pvbatt
    battery: 2
    voltage:
      name: "Battery 2 Voltage"
    current:
      name: "Battery 2 Current"
    coulomb:
      name: "Battery 2 State of Charge"
    temperature:
      name: "Battery 2 Temperature"
  - platform: pytes_e_box
    pytes_e_box_id: pvbatt
    battery: 3
    voltage:
      name: "Battery 3 Voltage"
    current:
      name: "Battery 3 Current"
    coulomb:
      name: "Battery 3 State of Charge"
    temperature:
      name: "Battery 3 Temperature"

Device is a Wemos D1 Mini (ESP8266) with MAX3232
3x Pytes E-Box-48100R

the same issue you have with fpr example Waveshare ESPs. You will power the Chip.

Vin is always good, because you can fire it with 5v. (ESP is 3v3)

this looks pretty odd :frowning: it’s the raw output.
maybe the Firmware of the Pytes, or the ESP… i use an ESP32. You have an ESP32 around for testing?