Compare commits
1 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| a8bfba6a77 |
+110
-89
@@ -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()
|
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user