This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
projects:farmrobot:batteriemanagement [2021/03/21 18:23] jonas [Monitoring BMS] |
projects:farmrobot:batteriemanagement [2021/03/21 19:02] (current) jonas [Modbus Python and Watson-IoT MQTT publish on Raspberry Pi 4B] |
||
---|---|---|---|
Line 103: | Line 103: | ||
- | ===== Modbus Python and WatsonIoT | + | ===== Modbus Python and Watson-IoT |
- | Using FTDI USB adapter which can be interfaced on / | + | Using FTDI USB adapter which can be interfaced on / |
+ | Adding the current user to the " | ||
sudo adduser pi dialout | sudo adduser pi dialout | ||
- | | + | |
+ | Installing prerequisites: | ||
sudo apt install python3 | sudo apt install python3 | ||
wget https:// | wget https:// | ||
sudo python3 get-pip.py | sudo python3 get-pip.py | ||
- | sudo pip install pymodbus | + | sudo pip install pymodbus\\ |
- | \\ | + | |
+ | ModbusSerialClient is the Modbus client that is used to interface the registers on the BMS: | ||
from pymodbus.client.sync import ModbusSerialClient | from pymodbus.client.sync import ModbusSerialClient | ||
- | Using IBM Watson IoT platform | + | === IBM Watson IoT platform |
Creating a new device and gathering credentials: | Creating a new device and gathering credentials: | ||
Line 129: | Line 131: | ||
pip install wiotp-sdk | pip install wiotp-sdk | ||
- | Modbus communication implementation based on: https:// | + | Modbus communication implementation based on: https:// |
+ | === Code: === | ||
<file py pc_bms_modbus_mqtt.py> | <file py pc_bms_modbus_mqtt.py> | ||
import numpy as np | import numpy as np | ||
import wiotp.sdk.device | import wiotp.sdk.device | ||
+ | from time import sleep | ||
+ | from datetime import datetime | ||
import pymodbus.client.sync | import pymodbus.client.sync | ||
- | # Modbus client | ||
dev_port = '/ | dev_port = '/ | ||
- | modbus_client = pymodbus.client.sync.ModbusSerialClient(method=' | + | modbus_client = pymodbus.client.sync.ModbusSerialClient(method=' |
- | modbus_client.connect() | + | bytesize=8, stopbits=1, timeout=2, |
+ | my_config = wiotp.sdk.device.parseConfigFile(" | ||
+ | mqtt_client = wiotp.sdk.device.DeviceClient(config=my_config, | ||
- | myConfig = wiotp.sdk.device.parseConfigFile("device.yaml") | + | |
- | mqtt_client = wiotp.sdk.device.DeviceClient(config=myConfig, | + | def connect_modbus(): |
- | mqtt_client.connect() | + | if not modbus_client.is_socket_open(): |
+ | modbus_client.connect() | ||
+ | print("connect_modbus: | ||
+ | |||
+ | |||
+ | def connect_mqtt(): | ||
+ | mqtt_client.connect() | ||
+ | print(" | ||
Line 151: | Line 164: | ||
def read_registers(address, | def read_registers(address, | ||
- | | + | |
+ | result = modbus_client.read_holding_registers(address, | ||
+ | if not result.isError(): | ||
+ | register = result.registers | ||
+ | return register | ||
- | modbus_client.read_holding_registers(0, 1, unit=0xAA) | + | def ask_registers(): |
+ | read_registers(0, | ||
+ | lifetime_counter = (convert(read_registers(32, | ||
+ | time_left = (convert(read_registers(34, | ||
+ | pack_voltage = convert(read_registers(36, | ||
+ | pack_current = convert(read_registers(38, | ||
+ | min_cell = (read_registers(40, | ||
+ | max_cell = (read_registers(41, 1)[0])/ | ||
+ | cell_diff = (read_registers(104, 1)[0])/ | ||
+ | soc = (convert(read_registers(46, | ||
+ | bms_temperature = (read_registers(48, | ||
+ | bms_online = hex(read_registers(50, | ||
+ | max_discharge_current = (read_registers(102, | ||
+ | max_charge_current = (read_registers(103, | ||
+ | charge_count = read_registers(111, | ||
- | lifetime_counter | + | f_data = { |
- | time_left | + | ' |
- | pack_voltage | + | ' |
- | pack_current | + | ' |
- | min_cell | + | ' |
- | max_cell | + | ' |
- | cell_diff | + | ' |
- | soc = convert(read_registers(46, 2), np.uint32) | + | ' |
- | bms_temperature | + | ' |
- | bms_online | + | ' |
- | max_discharge_current | + | ' |
- | max_charge_current | + | ' |
- | charge_count | + | ' |
+ | ' | ||
+ | } | ||
+ | print(f_data) | ||
+ | print(" | ||
+ | return f_data | ||
- | myData = { | + | |
- | ' | + | def publish(p_data): |
- | | + | |
- | ' | + | |
- | ' | + | |
- | ' | + | def output_time(): |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | |
- | | + | while True: |
- | | + | |
- | mqtt_client.publishEvent(eventId=" | + | |
- | mqtt_client.disconnect() | + | |
+ | | ||
+ | | ||
+ | sleep(10) | ||
</ | </ | ||
+ | {{: | ||
+ | |||
+ | ==== Receiving MQTT messages on Watson IoT platform ==== | ||
+ | Received messages:\\ | ||
+ | {{: | ||
+ | |||
+ | Raw status data available: | ||
+ | {{: | ||
+ | |||
+ | ===== Web Interface to view and graph the data ===== | ||
+ | An easy way to set up a web interface is to host a node-red instance on a server, for example on a stationary Raspberry Pi 4, which can be accesses via network or can be made accessible with port forwarding from the internet.\\ | ||
+ | |||
+ | Setting up a Raspberry Pi 4B with docker and docker run portainer. | ||
+ | Create a new Node-Red Stack with a compose file, which creates a node-red web instance on the device on port 1880. | ||
+ | The ip adress is needed which can be requested with: | ||
+ | ifconfig | ||
+ | |||
+ | <file yaml compose.yaml> | ||
+ | version: " | ||
+ | |||
+ | services: | ||
+ | node-red: | ||
+ | image: nodered/ | ||
+ | environment: | ||
+ | - TZ=Europe/ | ||
+ | ports: | ||
+ | - " | ||
+ | networks: | ||
+ | - node-red-net | ||
+ | volumes: | ||
+ | - ~/ | ||
+ | |||
+ | networks: | ||
+ | node-red-net: | ||
+ | </ | ||
+ | |||
+ | The node-red webapp can then be accessed via [[http:// | ||
+ | The Node-RED Dashboard module is needed to display the data with node-red\\ | ||
+ | To install, click the Menu Button and choose " | ||
+ | Then click on install and install in the pop-up window. Then return to the main view.\\ | ||
+ | {{: | ||
+ | |||
+ | |||
===== Micropython implementation on espressiv ESP32 DevKitc v4 ===== | ===== Micropython implementation on espressiv ESP32 DevKitc v4 ===== | ||
Required software: Linux OS and python3 (sudo apt-get install python3) | Required software: Linux OS and python3 (sudo apt-get install python3) |