2024-08-03 -

This commit is contained in:
Adolfo Delorenzo 2024-08-03 18:58:02 -06:00
parent 8f315b06f7
commit 1c9cd6a447
2 changed files with 253 additions and 3 deletions

253
modbus_gps002.py Normal file
View File

@ -0,0 +1,253 @@
#!/usr/bin/env python3
# -*- coding:utf-8 -*-
import RPi.GPIO as GPIO
import paho.mqtt.client as mqtt
import os
import minimalmodbus
import time
import serial
from datetime import datetime
from influxdb_client import InfluxDBClient, Point
from influxdb_client.client.write_api import SYNCHRONOUS
import logging
import subprocess
# Set up logging
logging.basicConfig(level=logging.DEBUG, format='%(asctime)s - %(levelname)s - %(message)s')
# GPIO configuration
GPIO.setmode(GPIO.BCM)
GPIO.setwarnings(False)
GPIO.cleanup()
# MQTT Broker settings
mqttBroker = "65.108.199.212"
myhost = os.uname()[1]
mqtt_client = mqtt.Client(myhost)
mqtt_client.connect(mqttBroker, 1883)
# Modbus configuration
modbus_device = '/dev/modbus'
mb_address = 1
sensy_boi = minimalmodbus.Instrument(modbus_device, mb_address)
sensy_boi.serial.baudrate = 9600
sensy_boi.serial.bytesize = 8
sensy_boi.serial.parity = minimalmodbus.serial.PARITY_NONE
sensy_boi.serial.stopbits = 1
sensy_boi.serial.timeout = 0.5
sensy_boi.mode = minimalmodbus.MODE_RTU
sensy_boi.clear_buffers_before_each_transaction = True
sensy_boi.close_port_after_each_call = True
# GPS configuration
gps_device = '/dev/ttyUSB3'
# InfluxDB settings
INFLUXDB_URL = "http://100.64.024:6"
INFLUXDB_TOKEN = "IPtqPXbaXuuMHvx_tOt1cmIZfLHucd-9DcepXTVpQc-fNKBhp6pkhyTsq_XnoGXdxwILy5AFFgZ_QUZCE5Jhg=="
INFLUXDB_ORG = "juandiego"
INFLUXDB_BUCKET = "gpsdata"
# Initialize InfluxDB client
influx_client = InfluxDBClient(url=INFLUXDB_URL, token=INFLUXDB_TOKEN, org=INFLUXDB_ORG)
write_api = influx_client.write_api(write_options=SYNCHRONOUS)
# GPIO pin configuration
PIN_17 = 17
LuzPuerta = 18
GPIO_25 = 25
GPIO.setup(PIN_17, GPIO.IN)
GPIO.setup(LuzPuerta, GPIO.OUT)
GPIO.setup(GPIO_25, GPIO.OUT)
# Pending data list
pending_data = []
def control_gpio():
status_17 = GPIO.input(PIN_17)
if status_17 == GPIO.LOW:
GPIO.output(LuzPuerta, GPIO.HIGH) # Red light on
else:
GPIO.output(LuzPuerta, GPIO.LOW)
return status_17
def initialize_gps(gps_ser):
"""
Initializes the GPS device by sending necessary commands and checking the response.
"""
try:
# Send configuration commands to the GPS
commands = [
b'AT+CGNSPWR=1\r', # Power on the GPS
b'AT+CGNSSEQ="RMC"\r', # Configure the data sequence
b'AT+CGNSTST=1\r' # Start data transmission
]
for cmd in commands:
gps_ser.write(cmd)
time.sleep(2) # Increased delay
response = gps_ser.read(100)
logging.info(f"GPS command {cmd} response: {response}")
if b'ERROR' in response:
logging.error(f"GPS initialization error for command {cmd}")
return False
logging.info("GPS initialized successfully")
return True
except Exception as e:
logging.error(f"Error initializing GPS: {e}")
return False
def read_gps_data(gps_ser):
"""
Reads GPS data and returns it as a string.
"""
try:
gps_ser.write(b'AT+CGNSINF\r')
time.sleep(1)
response = gps_ser.read(200)
if b'+CGNSINF:' in response:
# Extract the GPS data from the response
gps_data = response.split(b'+CGNSINF: ')[1].strip()
logging.info(f"GPS data read: {gps_data}")
return gps_data.decode('ascii')
else:
logging.warning(f"Unexpected GPS response: {response}")
return None
except Exception as e:
logging.error(f"Error reading GPS data: {e}")
return None
def publish_to_mqtt(topic, payload):
"""
Publica un mensaje en el broker MQTT.
"""
try:
mqtt_client.publish(topic, payload)
logging.info(f"Published to MQTT topic {topic}: {payload}")
except Exception as e:
logging.error(f"Error publishing to MQTT: {e}")
def write_to_influxdb(data):
"""
Escribe los datos en InfluxDB.
"""
try:
point = Point("gps_data").tag("host", myhost).field("data", data)
write_api.write(bucket=INFLUXDB_BUCKET, org=INFLUXDB_ORG, record=point)
logging.info(f"Data written to InfluxDB: {data}")
except Exception as e:
logging.error(f"Error writing to InfluxDB: {e}")
def get_gps_position(gps_ser):
"""
Obtiene la posición GPS.
"""
gps_data = read_gps_data(gps_ser)
if gps_data:
# Process GPS data here if needed
publish_to_mqtt(f"iiot/{myhost}/gps", gps_data)
write_to_influxdb(gps_data)
return True
return False
def reset_usb_ports():
"""
Resetea los puertos USB.
"""
try:
subprocess.run(["usbreset", "/dev/bus/usb/001/001"], check=True)
logging.info("USB ports reset successfully")
except Exception as e:
logging.error(f"Error resetting USB ports: {e}")
def reinitialize_devices():
"""
Re-inicializa los dispositivos.
"""
try:
global sensy_boi, gps_ser
sensy_boi = minimalmodbus.Instrument(modbus_device, mb_address)
gps_ser = serial.Serial(gps_device, baudrate=9600, timeout=1)
if initialize_gps(gps_ser):
logging.info("Devices reinitialized successfully")
else:
logging.error("Failed to reinitialize GPS")
except Exception as e:
logging.error(f"Error reinitializing devices: {e}")
def main():
try:
# Initialize GPS
gps_ser = serial.Serial(gps_device, baudrate=9600, timeout=1)
if not initialize_gps(gps_ser):
logging.error("Failed to initialize GPS. Continuing without GPS functionality.")
reset_counter = 0
while True:
try:
# Control GPIO
status_17 = control_gpio()
# Read Modbus data
try:
temp = sensy_boi.read_register(0, 1) # Example register for temperature
hum = sensy_boi.read_register(1, 1) # Example register for humidity
# Try to publish current data
publish_to_mqtt(f"iiot/{myhost}/temperature", temp)
publish_to_mqtt(f"iiot/{myhost}/humidity", hum)
publish_to_mqtt(f"iiot/{myhost}/door/pin17", str(status_17))
# Try to publish pending data
for item in pending_data:
publish_to_mqtt(f"iiot/{myhost}/temperature", item["temperature"])
publish_to_mqtt(f"iiot/{myhost}/humidity", item["humidity"])
publish_to_mqtt(f"iiot/{myhost}/door/pin17", item["door_status"])
pending_data.clear() # Clear the list if all data was published
except Exception as e:
logging.error(f"Error publishing data to MQTT: {str(e)}")
pending_data.append({
"temperature": temp,
"humidity": hum,
"door_status": str(status_17)
}) # Save data in memory
# Print processed data
logging.info("-------------------------------------")
logging.info(f"Temperature = {temp:.1f}°C")
logging.info(f"Relative humidity = {hum:.1f}%")
logging.info(f"Door status (PIN 17) = {status_17}")
logging.info("-------------------------------------")
except Exception as e:
logging.error(f"Error reading Modbus data: {str(e)}")
# Get GPS position
if not get_gps_position(gps_ser):
logging.warning("Failed to get GPS position")
reset_counter += 1
if reset_counter >= 60: # Reset every 30 minutes (60 * 30 seconds)
reset_usb_ports()
reinitialize_devices()
reset_counter = 0
time.sleep(30)
except KeyboardInterrupt:
logging.info("Program interrupted by user")
except Exception as e:
logging.error(f"Unexpected error: {str(e)}")
finally:
GPIO.cleanup()
gps_ser.close()
influx_client.close()
if __name__ == "__main__":
main()

View File

@ -27,9 +27,6 @@ mqtt_client = mqtt.Client(myhost)
mqtt_client.connect(mqttBroker, 1883)
# Modbus configuration
#preferred_device = '/dev/ttyUSB0'
#fallback_device = '/dev/ttyUSB5'
#device_path = preferred_device if os.path.exists(preferred_device) else fallback_device
modbus_device = '/dev/modbus'
mb_address = 1