1 Commits

Author SHA1 Message Date
biqu a8bfba6a77 Sheller MQTT app configuration 2024-09-24 16:30:31 -04:00
+110 -89
View File
@@ -1,101 +1,122 @@
import paho.mqtt.client as mqtt import paho.mqtt.client as mqtt
import re import serial
from dynio import *
import time import time
# State variable to check if HOME is received before POS
home_received = False
home = 0
dxl_io = []
motor = None
# Functions to run when the corresponding command is received class ShellerRPMDisplay:
def home(): mqtt_host = "172.22.112.94"
global motor, home
motor.write_control_table('Torque_Limit', 200)
motor.set_velocity_mode()
print('velocity mode set')
motor.torque_enable()
print('torque enabled')
motor.set_velocity(300)
print('velocity set')
time.sleep(1)
while motor.read_control_table('Present_Speed') > 0:
pass
motor.torque_disable()
home = motor.get_position()
motor.write_control_table('Multi_Turn_Offset', -1 * home)
motor.set_extended_position_mode()
motor.torque_enable()
def set_pos(num): COM_PORTS = [ "/dev/ttyACM0", "/dev/ttyUSB0" ]
global motor buffer = ""
motor.set_position(num) def init(self):
time.sleep(0.2) self.drum = 0
while motor.read_control_table('Present_Speed') > 0: self.paddle = 0
pass try:
self.serials = [
serial.Serial(
self.COM_PORTS[1],
9600,
timeout=1,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
),
serial.Serial(
self.COM_PORTS[0],
9600,
timeout=1,
stopbits=serial.STOPBITS_ONE,
bytesize=serial.EIGHTBITS
)
]
self.mqtt_inform()
for s in self.serials:
s.write(bytearray("@D1\r\n", encoding='ascii'))
return True
except Exception as e:
print(e)
time.sleep(1)
if hasattr(self, "serials"):
del self.serials
return False
def disable_torque(): def start(self):
global motor, home_received self.isrunning = True
motor.torque_disable() self.mqtt_inform()
home_received = False
def stop(self):
self.isrunning = False
if hasattr(self, "serials"):
try:
for serial in self.serials:
serial.close()
except:
pass
del self.serials
# The callback for when the client receives a CONNACK response from the server. def main(self):
def on_connect(client, userdata, flags, rc): while self.isrunning:
print(f"Connected with result code {str(rc)}") if not hasattr(self, "serials"):
self.init()
try:
for i, serial in enumerate(self.serials):
if serial.in_waiting > 0:
self.buffer += serial.read(serial.in_waiting).decode(
"utf-8"
)
print(self.buffer)
self.process_text(self.buffer[: self.buffer.index("\r")], i)
self.buffer = ""
except Exception as e:
print(e)
time.sleep(1)
# Subscribing in on_connect() means that if we lose the connection and def mqtt_inform(self):
# reconnect then subscriptions will be renewed. # Publish MQTT messages for Moisture Percentage
client.subscribe("/meyer/#") self.client = mqtt.Client()
self.client.connect(self.mqtt_host, 1883)
self.client.publish(
"homeassistant/sensor/sheller-paddle-rpm/config",
'{\
"name": "Paddle RPM", \
"state_topic": "homeassistant/sensor/sheller/state", \
"unit_of_measurement": "RPM", \
"value_template": "{{ value_json.paddle }}", \
"unique_id": "sheller-paddle-rpm", \
"device":{ \
"identifiers": ["shelling-machine"], \
"name": "Shelling Machine", \
"manufacturer": "ME&E" \
} \
}', retain=True
)
self.client.publish(
"homeassistant/sensor/sheller-drum-rpm/config",
'{\
"name": "Drum RPM", \
"state_topic": "homeassistant/sensor/sheller/state", \
"unit_of_measurement": "RPM", \
"value_template": "{{ value_json.drum }}", \
"unique_id": "sheller-drum-rpm", \
"device":{ \
"identifiers": ["shelling-machine"] \
} \
}', retain=True
)
# Connect to Dynamixels def process_text(self, text, index):
global dxl_io, motor print(text)
dxl_io = dxl.DynamixelIO('/dev/ttyACM0') if index == 0:
motor = dxl_io.new_mx106(1,1) self.paddle = text
motor.get_position() elif index == 1:
motor.write_control_table('Torque_Limit', 200) self.drum = text
self.client.publish(
"homeassistant/sensor/sheller/state",
'{"paddle": "%s", "drum": "%s"}'
% (self.paddle, self.drum), retain=True
)
# The callback for when a PUBLISH message is received from the server. if __name__ == "__main__":
def on_message(client, userdata, msg): obj = ShellerRPMDisplay()
global home_received, motor obj.start()
obj.main()
message = msg.payload.decode()
if msg.topic != "/meyer/":
return
if message == "HOME":
home()
home_received = True
time.sleep(0.5)
set_pos(int(-250*53.248))
client.publish("/meyer/pos", -250.0)
elif message == "DISABLE":
disable_torque()
elif re.match(r"^POS -?\d+$", message): # This matches POS followed by a number
pos_num = int(message.split()[1]) # Extract the number from the message
pos_num *= 5.3248
if pos_num < -25000 or pos_num > 0: # Check if the number is out of range
client.publish("/meyer/error", "Error: Number out of range")
elif not home_received: # Check if HOME was received before POS
client.publish("/meyer/error", "Error: HOME command has to be run before POS")
else:
set_pos(int(pos_num))
client.publish("/meyer/pos", round(pos_num / 53.248,1))
else:
client.publish("/meyer/error", "Error: Unknown command")
client = mqtt.Client()
client.on_connect = on_connect
client.on_message = on_message
# Connect to the broker
client.connect("192.168.1.1", 1883, 60)
# Blocking call that processes network traffic, dispatches callbacks and
# handles reconnecting.
client.loop_forever()