Add counter, MQTT

This commit is contained in:
Cole Deck 2024-07-30 12:54:13 -05:00
parent 621a530530
commit b677556ece
6 changed files with 101 additions and 5 deletions

View File

@ -5,6 +5,10 @@ core:
server: Hyper-Vd
loopspeed: 60 # fps
mqtt:
enabled: True
server: 172.31.108.4
arm:
ip: 192.168.1.145
tool:

@ -1 +1 @@
Subproject commit 4b5cb19bd87a8aa1f3b43962e54c0336247cb291
Subproject commit 08eebd400b752488527f917e1b05a11931b1fbba

View File

@ -471,7 +471,7 @@ class LEDSystem():
if not self.showtoggle:
self.changecount = self.fadeorder(self.rings[ring][2],self.rings[ring][2]+24, self.changecount, 0,100,0)
else:
self.changecount = self.fadeorder(self.rings[ring][2],self.rings[ring][2]+24, self.changecount, 0,50,100)
self.changecount = self.fadeorder(self.rings[ring][2],self.rings[ring][2]+24, self.changecount, 100,20,100)
else:
self.changecount = self.animation_time / 2 # 100hz
self.showtoggle = not self.showtoggle

1
pick_count.pkl Normal file
View File

@ -0,0 +1 @@
<EFBFBD>K7.

View File

@ -22,6 +22,7 @@ ghostscript
pyzbar
segno
pyModbusTCP
paho-mqtt
# Development
matplotlib

96
run.py
View File

@ -30,6 +30,8 @@ from search import JukeboxSearch
from pyModbusTCP.client import ModbusClient
from uptime import uptime
import fileserver
import paho.mqtt.client as mqtt
import pickle
# set to false to run without real hardware for development
real = False
@ -74,6 +76,13 @@ arm_position_process = None
start_animation = False
failcount = 0
timecount = 0
secondsclock = 0
unacked_publish = set()
mqttc = mqtt.Client(mqtt.CallbackAPIVersion.VERSION2)
counter_file = 'pick_count.pkl'
mqttc.user_data_set(unacked_publish)
def arm_start_callback(res):
fprint("Arm action complete.")
@ -121,6 +130,28 @@ def send_data(type, call, data, client_id="*"):
out["data"] = data
to_server_queue.put((client_id, json.dumps(out)))
def initialize_counter():
global counter
try:
with open(counter_file, 'rb') as file:
counter = pickle.load(file)
if not isinstance(counter, int):
raise ValueError("Counter is not an integer")
except (FileNotFoundError, ValueError, pickle.PickleError):
counter = 101
save_counter()
# Save the counter to the file
def save_counter():
with open(counter_file, 'wb') as file:
pickle.dump(counter, file)
# Increment the counter
def increment_counter():
global counter
counter += 1
save_counter()
def check_server():
#print("HI")
global cable_list
@ -455,11 +486,36 @@ def setup_server(pool, manager):
fprint("Starting websocket server...", sendqueue=to_server_queue)
websocket_process = server.start_websocket_server(to_server_queue, from_server_queue)
fprint("Starting image file server...", sendqueue=to_server_queue)
fprint("Starting file server...", sendqueue=to_server_queue)
image_server_process = Process(target=fileserver.run_server, args=(config["cables"]["port"], config["cables"]["directory"]))
image_server_process.start()
if config["mqtt"]["enabled"]:
global mqttc
global unacked_publish
mqttc.on_publish = on_publish
mqttc.user_data_set(unacked_publish)
mqttc.connect(config["mqtt"]["server"])
mqttc.loop_start()
initialize_counter()
return True
def mqtt_send(msg, name):
global config
if config["mqtt"]["enabled"]:
global mqttc
global unacked_publish
msg_info = mqttc.publish("jukebox/" + name, msg, qos=1)
unacked_publish.add(msg_info.mid)
while len(unacked_publish):
sleep(0.01)
# Due to race-condition described above, the following way to wait for all publish is safer
msg_info.wait_for_publish()
def handle_error(error):
print(error, flush=True)
@ -518,6 +574,24 @@ def get_open_spot(sensordata):
return False
def on_publish(client, userdata, mid, reason_code, properties):
# reason_code and properties will only be present in MQTTv5. It's always unset in MQTTv3
try:
userdata.remove(mid)
except KeyError:
print("on_publish() is called with a mid not present in unacked_publish")
print("This is due to an unavoidable race-condition:")
print("* publish() return the mid of the message sent.")
print("* mid from publish() is added to unacked_publish by the main thread")
print("* on_publish() is called by the loop_start thread")
print("While unlikely (because on_publish() will be called after a network round-trip),")
print(" this is a race-condition that COULD happen")
print("")
print("The best solution to avoid race-condition is using the msg_info from publish()")
print("We could also try using a list of acknowledged mid rather than removing from pending list,")
print("but remember that mid could be re-used !")
def mainloop_server(pool, manager):
# NON-blocking loop
global real
@ -548,10 +622,12 @@ def mainloop_server(pool, manager):
global start_animation
global failcount
global timecount
global secondsclock
if mode != oldmode:
print(" ***** Running mode:", mode, "***** ")
oldmode = mode
mqtt_send(mode, "mode")
if mode == "Startup": # very first loop
pass
@ -561,8 +637,10 @@ def mainloop_server(pool, manager):
# check for messages
check_server()
# do every loop!
checkpoint = None
val = None
if not arm_updates.empty():
val = arm_updates.get()
@ -610,6 +688,16 @@ def mainloop_server(pool, manager):
else:
pass
# every 1 second
if secondsclock >= config["core"]["loopspeed"]:
secondsclock = 1
else:
secondsclock += 1
# if start_animation is False and ring_animation is not None and ledsys.mode != "Idle" and real:
# ledsys.mainloop(None, ring_animation, arm_position=arm_position)
@ -801,7 +889,9 @@ def mainloop_server(pool, manager):
killme.set(1)
else:
fprint("Movement requested. Keep clear of the machine!")
mqtt_send("start", "cycle_start")
increment_counter()
mqtt_send(counter, "pick_count_total")
if get_cable > -1:
global sensors
if action == "pickup":
@ -838,7 +928,7 @@ def mainloop_server(pool, manager):
# complete
if arm_ready == True:
mode = "Idle"
mqtt_send("start", "cycle_end")
else:
# getting cable and bringing to tray
# led animation