{"id":140,"date":"2021-02-27T14:34:00","date_gmt":"2021-02-27T14:34:00","guid":{"rendered":""},"modified":"2023-12-18T12:12:47","modified_gmt":"2023-12-18T12:12:47","slug":"much-improved-pi-assistant-message-reader","status":"publish","type":"post","link":"https:\/\/doctor-dark.co.uk\/blog\/much-improved-pi-assistant-message-reader\/","title":{"rendered":"Much improved Pi Assistant message reader."},"content":{"rendered":"<div style=\"text-align: justify;\"><span style=\"font-family: verdana; font-size: medium;\">The most important improvement is that this program now works&#8230; \ud83d\ude0e&nbsp;<\/span><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-family: verdana; font-size: medium;\"><br \/><\/span><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-size: medium;\"><span style=\"font-family: verdana;\">I just leave it running on the Pi Assistant, along with the Google provided&nbsp;<\/span><b style=\"font-family: verdana;\">assistant_library_with_button_demo.py<\/b><span style=\"font-family: verdana;\"> program that I like to use, when I want to ask the Google Assistant something&#8230;<\/span><\/span><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-family: verdana; font-size: medium;\"><br \/><\/span><\/div>\n<div style=\"text-align: left;\">\n<div><span style=\"font-family: arial; font-size: x-small;\">#!\/usr\/bin\/python3<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">#<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\"># Program to run on PiAssistant, to watch for newly arrived text files in<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\"># \/home\/pi\/Messages that it should speak, and delete them once it has.<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">import os<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">import paramiko<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">import time<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">path = &#8220;\/home\/pi\/Messages\/&#8221;<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">while True:<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; with os.scandir(path) as entries:<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; for entry in entries:<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f = open(entry, &#8220;r&#8221;)<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content = f.read()<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; f.close()<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; command = &#8220;python ~\/AIY-projects-python\/src\/aiy\/voice\/tts.py &#8220;&#8221; + <\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; content + &#8220;&#8221; &#8211;lang en-GB &#8211;volume 10 &#8211;pitch 60 &#8211;speed 90&#8243;<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.system(command)<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; os.remove(path+entry.name)&nbsp; &nbsp; &nbsp;&nbsp;<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; # Now wait for tts.py to finish<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; command = &#8220;ps -ef | grep -v grep | grep &#8220;voice.tts&#8221; | wc -l&#8221;<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; while True:<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; ssh_stdin, ssh_stdout, ssh_stderr = ssh.exec_command(command)<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; answer = str(ssh_stdout.read())<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if answer[2] == &#8220;0&#8221;:<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; break&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; time.sleep(0.5)<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: x-small;\">&nbsp; &nbsp; time.sleep(0.5)<\/span><\/div>\n<div><span style=\"font-family: arial; font-size: medium;\"><br \/><\/span><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-size: medium;\"><span style=\"font-family: arial;\">And here is a program to run on a cluster of Raspberry Pi computers, as <b>say_who.py<\/b>, which will each send a message to the Pi Assistant, from each core of the processor. The assistant will read them out, separately. It does seem still to lose some messages, and if I work out why, I will let you know!&nbsp;<\/span><span style=\"font-family: arial;\">I have been searching for simple example programs for Raspberry Pi clusters on the internet for ages, and have not found very many. Here&#8217;s my little gift&#8230;<\/span><\/span><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-family: arial;\"><br \/><\/span><\/div>\n<div><span style=\"font-family: arial;\"><\/p>\n<div style=\"font-size: small;\">#!\/usr\/bin\/python3<\/div>\n<div style=\"font-size: small;\">from mpi4py import MPI<\/div>\n<div style=\"font-size: small;\">import os<\/div>\n<div style=\"font-size: small;\">import time<\/div>\n<div style=\"font-size: small;\">import subprocess as sp<\/div>\n<div style=\"font-size: small;\"><\/div>\n<div style=\"font-size: small;\"># Attach to the cluster and find out who I am and what my rank is<\/div>\n<div style=\"font-size: small;\">comm = MPI.COMM_WORLD<\/div>\n<div style=\"font-size: small;\">my_rank = comm.Get_rank()<\/div>\n<div style=\"font-size: small;\">cluster_size = comm.Get_size()<\/div>\n<div style=\"font-size: small;\">my_host = os.popen(&#8216;cat \/etc\/hostname&#8217;).read().strip()<\/div>\n<div style=\"font-size: small;\">&nbsp; &nbsp;&nbsp;<\/div>\n<div style=\"font-size: small;\"># Make something for the assistant to say<\/div>\n<div style=\"font-size: small;\">speech = &#8220;Host is&nbsp; {} &#8220;.format(my_host)<\/div>\n<div style=\"font-size: small;\">speech = speech + &#8220;Rank {} &#8220;.format(my_rank)<\/div>\n<div style=\"font-size: small;\"><\/div>\n<div style=\"font-size: small;\"># Make a unique filename and path<\/div>\n<div style=\"font-size: small;\">message = &#8220;\/home\/pi\/&#8221; + my_host + str(my_rank)<\/div>\n<div style=\"font-size: small;\">&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; + time.strftime(&#8220;%H%M%S&#8221;) + &#8220;.txt&#8221;<\/div>\n<div style=\"font-size: small;\"># Put the speech in the file<\/div>\n<div style=\"font-size: small;\">fp = open(message,&#8221;x&#8221;)<\/div>\n<div style=\"font-size: small;\">fp.write(speech)<\/div>\n<div style=\"font-size: small;\">fp.close()<\/div>\n<div style=\"font-size: small;\"><\/div>\n<div style=\"font-size: small;\"># Put a copy of the file on PiAssistant<\/div>\n<div style=\"font-size: small;\">cmd = &#8220;scp &#8221; + message + &#8221; pi@PiAssistant:\/home\/pi\/Messages\/&#8221;<\/div>\n<div style=\"font-size: small;\">sp.call(cmd,shell=True)<\/div>\n<div style=\"font-size: small;\">os.remove(message)<\/div>\n<div style=\"font-size: small;\"><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-size: medium;\">You would load that program on each of the Pi machines in your cluster, and then set it running using the command<\/span><\/div>\n<div style=\"text-align: justify;\"><span style=\"font-size: medium;\"><br \/><\/span><\/div>\n<div><span style=\"font-size: medium;\"><b>mpiexec -n 16 -hostfile myhostfile python3 say_who.py<\/b><\/span><\/div>\n<div><span style=\"font-size: medium;\"><b><br \/><\/b><\/span><\/div>\n<div>\n<div><span style=\"font-size: medium;\">I&#8217;m assuming you have four Pi 3 machines in the cluster, hence the <b>-n 16<\/b> parameter.&nbsp;<\/span><\/div>\n<div><span style=\"font-size: medium;\"><br \/><\/span><\/div>\n<\/div>\n<div><span style=\"font-size: medium;\">#RaspberryPi #Cluster #Python <\/span><\/div>\n<p><\/span><\/div>\n<\/div>\n","protected":false},"excerpt":{"rendered":"<p>The most important improvement is that this program now works&#8230; \ud83d\ude0e&nbsp; I just leave it running on the Pi Assistant, along with the Google provided&nbsp;assistant_library_with_button_demo.py program that I like to use, when I want to ask the Google Assistant something&#8230; #!\/usr\/bin\/python3 # # Program to run on PiAssistant, to watch for newly arrived text files &hellip; <a href=\"https:\/\/doctor-dark.co.uk\/blog\/much-improved-pi-assistant-message-reader\/\" class=\"more-link\">Continue reading<span class=\"screen-reader-text\"> &#8220;Much improved Pi Assistant message reader.&#8221;<\/span><\/a><\/p>\n","protected":false},"author":1,"featured_media":0,"comment_status":"closed","ping_status":"closed","sticky":false,"template":"","format":"standard","meta":{"footnotes":""},"categories":[7],"tags":[],"class_list":["post-140","post","type-post","status-publish","format-standard","hentry","category-raspberry-pi"],"jetpack_featured_media_url":"","_links":{"self":[{"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/posts\/140","targetHints":{"allow":["GET"]}}],"collection":[{"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/posts"}],"about":[{"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/types\/post"}],"author":[{"embeddable":true,"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/users\/1"}],"replies":[{"embeddable":true,"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/comments?post=140"}],"version-history":[{"count":1,"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/posts\/140\/revisions"}],"predecessor-version":[{"id":349,"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/posts\/140\/revisions\/349"}],"wp:attachment":[{"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/media?parent=140"}],"wp:term":[{"taxonomy":"category","embeddable":true,"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/categories?post=140"},{"taxonomy":"post_tag","embeddable":true,"href":"https:\/\/doctor-dark.co.uk\/blog\/wp-json\/wp\/v2\/tags?post=140"}],"curies":[{"name":"wp","href":"https:\/\/api.w.org\/{rel}","templated":true}]}}