Page Not Found
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
diff --git a/404.html b/404.html index f7b0056f..3cd1f8ef 100644 --- a/404.html +++ b/404.html @@ -16,8 +16,8 @@ - - + +
We could not find what you were looking for.
Please contact the owner of the site that linked you to the original URL and let them know their link is broken.
nmcli
",id:"connecting-to-a-wifi-network-using-nmcli",level:3},{value:"Connecting to multiple networks simultaneously",id:"connecting-to-multiple-networks-simultaneously",level:3},{value:"Starting the Pioreactor local access point using nmcli
",id:"starting-the-pioreactor-local-access-point-using-nmcli",level:3},{value:"Changing leader_address
and MQTT broker
in your config.ini",id:"changing-leader_address-and-mqtt-broker-in-your-configini",level:4},{value:"Changing web UI port from 80
to something else",id:"changing-web-ui-port-from-80-to-something-else",level:3},{value:"Connecting to eduroam",id:"connecting-to-eduroam",level:2},{value:"Common questions",id:"common-questions",level:2},{value:"My Pioreactor activities start very slowly from the UI",id:"my-pioreactor-activities-start-very-slowly-from-the-ui",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,t.a)(),...e.components};return(0,o.jsxs)(o.Fragment,{children:[(0,o.jsx)(n.admonition,{type:"info",children:(0,o.jsxs)(n.p,{children:["Previously, Raspberry Pis used a file called ",(0,o.jsx)(n.code,{children:"wpa_supplicant.conf"})," to handle wifi network connections. ",(0,o.jsx)(n.strong,{children:"This is not longer the case"}),". Modern Raspberry Pi software, including the Pioreactor, doesn't use ",(0,o.jsx)(n.code,{children:"wpa_supplicant.conf"})," at all. Instead, the tool ",(0,o.jsx)(n.code,{children:"nmcli"})," replaces it. Don't follow tutorials that use ",(0,o.jsx)(n.code,{children:"wpa_supplicant.conf"}),"."]})}),"\n",(0,o.jsx)(n.h2,{id:"general-networking-tools",children:"General networking tools"}),"\n",(0,o.jsxs)(n.p,{children:['The main "entry point" for networking on the Pioreactor (and Raspberry Pi\'s in general) is the tool ',(0,o.jsx)(n.code,{children:"nmcli"}),". This controls discovering networks, connecting to them, and editing connections. For example, running ",(0,o.jsx)(n.code,{children:"nmcli con"})," will diplay a list of possible networking connections, and connected ones in green."]}),"\n",(0,o.jsxs)(n.h3,{id:"connecting-to-a-wifi-network-using-nmcli",children:["Connecting to a wifi network using ",(0,o.jsx)(n.code,{children:"nmcli"})]}),"\n",(0,o.jsx)(n.p,{children:"You can first discover all the visible networks with:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo nmcli d wifi list\n"})}),"\n",(0,o.jsx)(n.p,{children:"If you see your network on the list, then run:"}),"\n",(0,o.jsx)(n.pre,{children:(0,o.jsx)(n.code,{children:"sudo nmcli device wifi connect nmcli
",id:"connecting-to-a-wifi-network-using-nmcli",level:3},{value:"Connecting to multiple networks simultaneously",id:"connecting-to-multiple-networks-simultaneously",level:3},{value:"Starting the Pioreactor local access point using nmcli
",id:"starting-the-pioreactor-local-access-point-using-nmcli",level:3},{value:"Changing leader_address
and MQTT broker
in your config.ini",id:"changing-leader_address-and-mqtt-broker-in-your-configini",level:4},{value:"Changing web UI port from 80
to something else",id:"changing-web-ui-port-from-80-to-something-else",level:3},{value:"Connecting to eduroam",id:"connecting-to-eduroam",level:2},{value:"Common questions",id:"common-questions",level:2},{value:"My Pioreactor activities start very slowly from the UI",id:"my-pioreactor-activities-start-very-slowly-from-the-ui",level:3}];function d(e){const n={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",...(0,t.a)(),...e.components};return(0,i.jsxs)(i.Fragment,{children:[(0,i.jsx)(n.admonition,{type:"info",children:(0,i.jsxs)(n.p,{children:["Previously, Raspberry Pis used a file called ",(0,i.jsx)(n.code,{children:"wpa_supplicant.conf"})," to handle wifi network connections. ",(0,i.jsx)(n.strong,{children:"This is not longer the case"}),". Modern Raspberry Pi software, including the Pioreactor, doesn't use ",(0,i.jsx)(n.code,{children:"wpa_supplicant.conf"})," at all. Instead, the tool ",(0,i.jsx)(n.code,{children:"nmcli"})," replaces it. Don't follow tutorials that use ",(0,i.jsx)(n.code,{children:"wpa_supplicant.conf"}),"."]})}),"\n",(0,i.jsx)(n.h2,{id:"general-networking-tools",children:"General networking tools"}),"\n",(0,i.jsxs)(n.p,{children:['The main "entry point" for networking on the Pioreactor (and Raspberry Pi\'s in general) is the tool ',(0,i.jsx)(n.code,{children:"nmcli"}),". This controls discovering networks, connecting to them, and editing connections. For example, running ",(0,i.jsx)(n.code,{children:"nmcli con"})," will diplay a list of possible networking connections, and connected ones in green."]}),"\n",(0,i.jsxs)(n.h3,{id:"connecting-to-a-wifi-network-using-nmcli",children:["Connecting to a wifi network using ",(0,i.jsx)(n.code,{children:"nmcli"})]}),"\n",(0,i.jsx)(n.p,{children:"You can first discover all the visible networks with:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"sudo nmcli d wifi list\n"})}),"\n",(0,i.jsx)(n.p,{children:"If you see your network on the list, then run:"}),"\n",(0,i.jsx)(n.pre,{children:(0,i.jsx)(n.code,{children:"sudo nmcli device wifi connect pioreactor
network in the list of available wifi networks?",id:"do-you-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",level:4},{value:"Alternatively, do you not see the pioreactor
network in the list of available wifi networks?",id:"alternatively-do-you-not-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",level:4},{value:"I'm on the network, but can't load the Pioreactor UI at http://pioreactor.local
",id:"im-on-the-network-but-cant-load-the-pioreactor-ui-at-httppioreactorlocal",level:3},{value:"I can't connect a worker to my local access point",id:"i-cant-connect-a-worker-to-my-local-access-point",level:3},{value:"I'm pretty sure I'm at the limit of ~4-8 clients on my access point - what can I do?",id:"im-pretty-sure-im-at-the-limit-of-4-8-clients-on-my-access-point---what-can-i-do",level:3}];function h(e){const a={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",strong:"strong",ul:"ul",...(0,c.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(a.p,{children:"For some use cases, you may want to create a local WiFi network just for your Pioreactors (this is called a local access point, or a hotspot). Why might you want to do this?"}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"If you want to get started right away, without dealing with exiting WiFi networks."}),"\n",(0,n.jsx)(a.li,{children:"If your usual WiFi network is restrictive (ex: doesn't allow Raspberry Pis, or requires IT support to host them)."}),"\n",(0,n.jsx)(a.li,{children:"If you want to take the Pioreactor, or cluster of Pioreactors, out into the field where there is no network."}),"\n"]}),"\n",(0,n.jsx)(a.p,{children:"The Pioreactor comes with the ability to create its own local access point, which other Pioreactors can connect to. See image below:"}),"\n",(0,n.jsx)(a.p,{children:(0,n.jsx)(a.img,{alt:"Using the Pioreactor to create a local access point",src:o(13726).Z+"",width:"1191",height:"387"})}),"\n",(0,n.jsx)(a.admonition,{type:"info",children:(0,n.jsx)(a.p,{children:"The built-in local access point is meant for small clusters of Pioreactors, and it's range and stability is limited. If you want a proper local access point, we suggest purchasing an inexpensive wifi router and using that (the router does not need to be connected to the internet - it will still create a wifi network you can connect Pioreactors to regardless)."})}),"\n",(0,n.jsx)(a.h2,{id:"starting-a-local-access-point",children:"Starting a local access point"}),"\n",(0,n.jsx)(a.p,{children:"The Pioreactor has the necessary software and hardware to create the local access point. To start the access point:"}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsxs)(a.li,{children:["If starting with a new Pioreactor, during software set up:","\n",(0,n.jsxs)(a.ol,{children:["\n",(0,n.jsxs)(a.li,{children:['Leave the "Configure wireless LAN" unchecked. Continue with the instructions at ',(0,n.jsx)(a.a,{href:"/user-guide/software-set-up#setting-up-your-raspberry-pi",children:"Setting up your Raspberry Pi"}),"."]}),"\n",(0,n.jsxs)(a.li,{children:["After the SD card has been written to, remove the SD card from your computer, and immediately insert it back in. A ",(0,n.jsx)(a.code,{children:"boot"})," (or ",(0,n.jsx)(a.code,{children:"bootfs"}),") device should be present now that is your SD card. If asked to reformat the SD card, select NO."]}),"\n",(0,n.jsxs)(a.li,{children:["\n",(0,n.jsx)(i,{}),"\n"]}),"\n",(0,n.jsxs)(a.li,{children:["Drag/move the downloaded ",(0,n.jsx)(a.code,{children:"local_access_point"})," file to the SD card directory."]}),"\n",(0,n.jsxs)(a.li,{children:["Eject the SD card safely, and continue with instructions at ",(0,n.jsx)(a.a,{href:"/user-guide/software-set-up#setting-up-your-raspberry-pi",children:"Setting up your Raspberry Pi"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(a.li,{children:["If starting from an existing Pioreactor:","\n",(0,n.jsxs)(a.ol,{children:["\n",(0,n.jsx)(a.li,{children:"with the power off remove the SD card from the Pioreactor and insert it into a computer."}),"\n",(0,n.jsxs)(a.li,{children:["\n",(0,n.jsx)(i,{}),"\n"]}),"\n",(0,n.jsxs)(a.li,{children:["Drag/move the downloaded ",(0,n.jsx)(a.code,{children:"local_access_point"})," file to your SD card (called ",(0,n.jsx)(a.code,{children:"boot"})," or ",(0,n.jsx)(a.code,{children:"bootfs"}),")."]}),"\n",(0,n.jsx)(a.li,{children:"Eject the SD card safely, and put back into the Pioreactor."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(a.h2,{id:"access-the-local-access-point",children:"Access the local access point"}),"\n",(0,n.jsxs)(a.p,{children:["After plugging in the Pioreactor, the local access point will start and you should see a new network called ",(0,n.jsx)(a.code,{children:"pioreactor"}),", with password ",(0,n.jsx)(a.code,{children:"raspberry"}),". You should be able to connect to this new access point with any computer, phone, tablet, etc."]}),"\n",(0,n.jsx)("img",{src:"/img/user-guide/pioreactor_ap.png",width:"325"}),"\n",(0,n.jsxs)(a.p,{children:["Once connected, the usual urls should work: ",(0,n.jsx)(a.a,{href:"http://pioreactor.local",children:"http://pioreactor.local"})," will bring up the Pioreactor interface (having trouble? Not working? Try our troubleshooting steps below."]}),"\n",(0,n.jsx)(a.admonition,{type:"info",children:(0,n.jsxs)(a.p,{children:["Without access to the internet, the Pioreactor will have the wrong internal time. You can change this ",(0,n.jsx)(a.a,{href:"/user-guide/common-questions#how-do-i-change-the-date-or-time-on-the-pioreactor",children:"using this method"})]})}),"\n",(0,n.jsx)(a.h3,{id:"connecting-more-pioreactors-to-your-local-access-point",children:"Connecting more Pioreactors to your local access point"}),"\n",(0,n.jsx)(a.admonition,{type:"info",children:(0,n.jsxs)(a.p,{children:["Raspberry Pi 3B and Raspberry Pi Zero W have trouble connecting to these local access points. Follow instructions ",(0,n.jsx)(a.a,{href:"https://github.com/Pioreactor/pioreactor/blob/992d986881f3a3504a08b781a494b1a6e3b5a0e3/CHANGELOG.md?plain=1#L110C11-L121",children:"here"}),"."]})}),"\n",(0,n.jsxs)(a.p,{children:["Other Pioreactors will need to be reconfigured to connect to this new access point. During set up in the Raspberry Pi Imager, using the ssid / wifi credentials: ",(0,n.jsx)(a.code,{children:"pioreactor"})," and password ",(0,n.jsx)(a.code,{children:"raspberry"})," in the wireless LAN section. ",(0,n.jsxs)(a.strong,{children:["Don't add the ",(0,n.jsx)(a.code,{children:"local_access_point"})," file to these other Pioreactors - you only need to do that once"]}),"."]}),"\n",(0,n.jsxs)(a.p,{children:["The maximum number of machines (Pioreactors and computers) that can be connected to a local access point on a Pioreactor is ~4-8. There is a possibility to add more, see ",(0,n.jsx)(a.a,{href:"https://github.com/Pioreactor/pioreactor/issues/442",children:"issue here"}),"."]}),"\n",(0,n.jsx)(a.p,{children:"This network may not be connected to the internet, so you won't be able to upgrade any software on the Pioreactors. See section below on how to add internet."}),"\n",(0,n.jsx)(a.h2,{id:"adding-internet-access-to-your-local-access-point",children:"Adding internet access to your local access point"}),"\n",(0,n.jsx)(a.p,{children:"If you are hosting the local access point on a Raspberry Pi that has an ethernet port (B models), you can plug this into a router that has access to the internet to provide internet to your entire cluster."}),"\n",(0,n.jsx)(a.p,{children:(0,n.jsx)(a.img,{alt:"Using the Pioreactor to create a local access point, and the is connected to a router",src:o(8026).Z+"",width:"578",height:"387"})}),"\n",(0,n.jsx)(a.h2,{id:"turning-off-a-local-access-point",children:"Turning off a local access point"}),"\n",(0,n.jsxs)(a.p,{children:["After SSH-ing into your Pioreactor, simply delete the ",(0,n.jsx)(a.code,{children:"local_access_point"})," file in the ",(0,n.jsx)(a.code,{children:"/boot/firmware/"})," directory, and reboot."]}),"\n",(0,n.jsx)(a.h2,{id:"changing-ssid-name-or-password-for-your-local-access-point",children:"Changing SSID name or password for your local access point"}),"\n",(0,n.jsxs)(a.p,{children:["In the ",(0,n.jsx)(a.code,{children:"config.ini"}),", the SSID and password are editable under the section ",(0,n.jsx)(a.code,{children:"local_access_point"}),". This requires a power-cycle to take effect."]}),"\n",(0,n.jsx)(a.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,n.jsx)(a.h3,{id:"my-computer-cant-connect-to-the-local-access-point",children:"My computer can't connect to the local-access-point"}),"\n",(0,n.jsxs)(a.h4,{id:"do-you-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",children:["Do you see the ",(0,n.jsx)(a.code,{children:"pioreactor"})," network in the list of available wifi networks?"]}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:'If presented, use the option "Use security key to connect" (this is an alias for the password).'}),"\n",(0,n.jsx)(a.li,{children:"Try power-cycling your Pioreactor"}),"\n",(0,n.jsxs)(a.li,{children:["The maximum number of machines (Pioreactors and computers) that can be connected to a local access point on a Pioreactor is ~4-8. There is a possibility to add more, see ",(0,n.jsx)(a.a,{href:"https://github.com/Pioreactor/pioreactor/issues/442",children:"issue here"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(a.h4,{id:"alternatively-do-you-not-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",children:["Alternatively, do you ",(0,n.jsx)(a.em,{children:"not"})," see the ",(0,n.jsx)(a.code,{children:"pioreactor"})," network in the list of available wifi networks?"]}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"Try power-cycling the Raspberry Pi"}),"\n",(0,n.jsxs)(a.li,{children:["If you unplug the Pioreactor, and place the SD card back into your computer, do you see the ",(0,n.jsx)(a.code,{children:"local_access_point"})," file? If not, try adding the file again, inserting the SD card in the Pioreactor, and restarting the Pioreactor."]}),"\n"]}),"\n",(0,n.jsxs)(a.h3,{id:"im-on-the-network-but-cant-load-the-pioreactor-ui-at-httppioreactorlocal",children:["I'm on the network, but can't load the Pioreactor UI at ",(0,n.jsx)(a.code,{children:"http://pioreactor.local"})]}),"\n",(0,n.jsxs)(a.p,{children:["Try ",(0,n.jsx)(a.code,{children:"http://pioreactor
network in the list of available wifi networks?",id:"do-you-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",level:4},{value:"Alternatively, do you not see the pioreactor
network in the list of available wifi networks?",id:"alternatively-do-you-not-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",level:4},{value:"I'm on the network, but can't load the Pioreactor UI at http://pioreactor.local
",id:"im-on-the-network-but-cant-load-the-pioreactor-ui-at-httppioreactorlocal",level:3},{value:"I can't connect a worker to my local access point",id:"i-cant-connect-a-worker-to-my-local-access-point",level:3},{value:"I'm pretty sure I'm at the limit of ~4-8 clients on my access point - what can I do?",id:"im-pretty-sure-im-at-the-limit-of-4-8-clients-on-my-access-point---what-can-i-do",level:3}];function h(e){const a={a:"a",admonition:"admonition",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,c.a)(),...e.components};return(0,n.jsxs)(n.Fragment,{children:[(0,n.jsx)(a.p,{children:"For some use cases, you may want to create a local WiFi network just for your Pioreactors (this is called a local access point, or a hotspot). Why might you want to do this?"}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"If you want to get started right away, without dealing with exiting WiFi networks."}),"\n",(0,n.jsx)(a.li,{children:"If your usual WiFi network is restrictive (ex: doesn't allow Raspberry Pis, or requires IT support to host them)."}),"\n",(0,n.jsx)(a.li,{children:"If you want to take the Pioreactor, or cluster of Pioreactors, out into the field where there is no network."}),"\n"]}),"\n",(0,n.jsx)(a.p,{children:"The Pioreactor comes with the ability to create its own local access point, which other Pioreactors can connect to. See image below:"}),"\n",(0,n.jsx)(a.p,{children:(0,n.jsx)(a.img,{alt:"Using the Pioreactor to create a local access point",src:o(13726).Z+"",width:"1191",height:"387"})}),"\n",(0,n.jsx)(a.admonition,{type:"info",children:(0,n.jsx)(a.p,{children:"The built-in local access point is meant for small clusters of Pioreactors, and it's range and stability is limited. If you want a proper local access point, we suggest purchasing an inexpensive wifi router and using that (the router does not need to be connected to the internet - it will still create a wifi network you can connect Pioreactors to regardless)."})}),"\n",(0,n.jsx)(a.h2,{id:"starting-a-local-access-point",children:"Starting a local access point"}),"\n",(0,n.jsx)(a.p,{children:"The Pioreactor has the necessary software and hardware to create the local access point. To start the access point:"}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsxs)(a.li,{children:["If starting with a new Pioreactor, during software set up:","\n",(0,n.jsxs)(a.ol,{children:["\n",(0,n.jsxs)(a.li,{children:['Leave the "Configure wireless LAN" unchecked. Continue with the instructions at ',(0,n.jsx)(a.a,{href:"/user-guide/software-set-up#setting-up-your-raspberry-pi",children:"Setting up your Raspberry Pi"}),"."]}),"\n",(0,n.jsxs)(a.li,{children:["After the SD card has been written to, remove the SD card from your computer, and immediately insert it back in. A ",(0,n.jsx)(a.code,{children:"boot"})," (or ",(0,n.jsx)(a.code,{children:"bootfs"}),") device should be present now that is your SD card. If asked to reformat the SD card, select NO."]}),"\n",(0,n.jsxs)(a.li,{children:["\n",(0,n.jsx)(i,{}),"\n"]}),"\n",(0,n.jsxs)(a.li,{children:["Drag/move the downloaded ",(0,n.jsx)(a.code,{children:"local_access_point"})," file to the SD card directory."]}),"\n",(0,n.jsxs)(a.li,{children:["Eject the SD card safely, and continue with instructions at ",(0,n.jsx)(a.a,{href:"/user-guide/software-set-up#setting-up-your-raspberry-pi",children:"Setting up your Raspberry Pi"}),"."]}),"\n"]}),"\n"]}),"\n",(0,n.jsxs)(a.li,{children:["If starting from an existing Pioreactor:","\n",(0,n.jsxs)(a.ol,{children:["\n",(0,n.jsx)(a.li,{children:"with the power off remove the SD card from the Pioreactor and insert it into a computer."}),"\n",(0,n.jsxs)(a.li,{children:["\n",(0,n.jsx)(i,{}),"\n"]}),"\n",(0,n.jsxs)(a.li,{children:["Drag/move the downloaded ",(0,n.jsx)(a.code,{children:"local_access_point"})," file to your SD card (called ",(0,n.jsx)(a.code,{children:"boot"})," or ",(0,n.jsx)(a.code,{children:"bootfs"}),")."]}),"\n",(0,n.jsx)(a.li,{children:"Eject the SD card safely, and put back into the Pioreactor."}),"\n"]}),"\n"]}),"\n"]}),"\n",(0,n.jsx)(a.h2,{id:"access-the-local-access-point",children:"Access the local access point"}),"\n",(0,n.jsxs)(a.p,{children:["After plugging in the Pioreactor, the local access point will start and you should see a new network called ",(0,n.jsx)(a.code,{children:"pioreactor"}),", with password ",(0,n.jsx)(a.code,{children:"raspberry"}),". You should be able to connect to this new access point with any computer, phone, tablet, etc."]}),"\n",(0,n.jsx)("img",{src:"/img/user-guide/pioreactor_ap.png",width:"325"}),"\n",(0,n.jsxs)(a.p,{children:["Once connected, the usual urls should work: ",(0,n.jsx)(a.a,{href:"http://pioreactor.local",children:"http://pioreactor.local"})," will bring up the Pioreactor interface (having trouble? Not working? Try our troubleshooting steps below."]}),"\n",(0,n.jsx)(a.admonition,{type:"info",children:(0,n.jsxs)(a.p,{children:["Without access to the internet, the Pioreactor will have the wrong internal time. You can change this ",(0,n.jsx)(a.a,{href:"/user-guide/common-questions#how-do-i-change-the-date-or-time-on-the-pioreactor",children:"using this method"})]})}),"\n",(0,n.jsx)(a.h3,{id:"connecting-more-pioreactors-to-your-local-access-point",children:"Connecting more Pioreactors to your local access point"}),"\n",(0,n.jsx)(a.admonition,{type:"info",children:(0,n.jsxs)(a.p,{children:["Raspberry Pi 3B and Raspberry Pi Zero W have trouble connecting to these local access points. Follow instructions ",(0,n.jsx)(a.a,{href:"https://github.com/Pioreactor/pioreactor/blob/992d986881f3a3504a08b781a494b1a6e3b5a0e3/CHANGELOG.md?plain=1#L110C11-L121",children:"here"}),"."]})}),"\n",(0,n.jsxs)(a.p,{children:["Other Pioreactors will need to be reconfigured to connect to this new access point. During set up in the Raspberry Pi Imager, using the ssid / wifi credentials: ",(0,n.jsx)(a.code,{children:"pioreactor"})," and password ",(0,n.jsx)(a.code,{children:"raspberry"})," in the wireless LAN section. ",(0,n.jsxs)(a.strong,{children:["Don't add the ",(0,n.jsx)(a.code,{children:"local_access_point"})," file to these other Pioreactors - you only need to do that once"]}),"."]}),"\n",(0,n.jsxs)(a.p,{children:["The maximum number of machines (Pioreactors and computers) that can be connected to a local access point on a Pioreactor is ~4-8. There is a possibility to add more, see ",(0,n.jsx)(a.a,{href:"https://github.com/Pioreactor/pioreactor/issues/442",children:"issue here"}),"."]}),"\n",(0,n.jsx)(a.p,{children:"This network may not be connected to the internet, so you won't be able to upgrade any software on the Pioreactors. See section below on how to add internet."}),"\n",(0,n.jsx)(a.h2,{id:"adding-internet-access-to-your-local-access-point",children:"Adding internet access to your local access point"}),"\n",(0,n.jsx)(a.p,{children:"If you are hosting the local access point on a Raspberry Pi that has an ethernet port (B models), you can plug this into a router that has access to the internet to provide internet to your entire cluster."}),"\n",(0,n.jsx)(a.p,{children:(0,n.jsx)(a.img,{alt:"Using the Pioreactor to create a local access point, and the is connected to a router",src:o(8026).Z+"",width:"578",height:"387"})}),"\n",(0,n.jsx)(a.h2,{id:"turning-off-a-local-access-point",children:"Turning off a local access point"}),"\n",(0,n.jsxs)(a.p,{children:["After SSH-ing into your Pioreactor, simply delete the ",(0,n.jsx)(a.code,{children:"local_access_point"})," file in the ",(0,n.jsx)(a.code,{children:"/boot/firmware/"})," directory, and reboot."]}),"\n",(0,n.jsx)(a.h2,{id:"changing-ssid-name-or-password-for-your-local-access-point",children:"Changing SSID name or password for your local access point"}),"\n",(0,n.jsxs)(a.p,{children:["In the ",(0,n.jsx)(a.code,{children:"config.ini"}),", the SSID and password are editable under the section ",(0,n.jsx)(a.code,{children:"local_access_point"}),". This requires a power-cycle to take effect."]}),"\n",(0,n.jsx)(a.h2,{id:"troubleshooting",children:"Troubleshooting"}),"\n",(0,n.jsx)(a.h3,{id:"my-computer-cant-connect-to-the-local-access-point",children:"My computer can't connect to the local-access-point"}),"\n",(0,n.jsxs)(a.h4,{id:"do-you-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",children:["Do you see the ",(0,n.jsx)(a.code,{children:"pioreactor"})," network in the list of available wifi networks?"]}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:'If presented, use the option "Use security key to connect" (this is an alias for the password).'}),"\n",(0,n.jsx)(a.li,{children:"Try power-cycling your Pioreactor"}),"\n",(0,n.jsxs)(a.li,{children:["The maximum number of machines (Pioreactors and computers) that can be connected to a local access point on a Pioreactor is ~4-8. There is a possibility to add more, see ",(0,n.jsx)(a.a,{href:"https://github.com/Pioreactor/pioreactor/issues/442",children:"issue here"}),"."]}),"\n"]}),"\n",(0,n.jsxs)(a.h4,{id:"alternatively-do-you-not-see-the-pioreactor-network-in-the-list-of-available-wifi-networks",children:["Alternatively, do you ",(0,n.jsx)(a.em,{children:"not"})," see the ",(0,n.jsx)(a.code,{children:"pioreactor"})," network in the list of available wifi networks?"]}),"\n",(0,n.jsxs)(a.ul,{children:["\n",(0,n.jsx)(a.li,{children:"Try power-cycling the Raspberry Pi"}),"\n",(0,n.jsxs)(a.li,{children:["If you unplug the Pioreactor, and place the SD card back into your computer, do you see the ",(0,n.jsx)(a.code,{children:"local_access_point"})," file? If not, try adding the file again, inserting the SD card in the Pioreactor, and restarting the Pioreactor."]}),"\n"]}),"\n",(0,n.jsxs)(a.h3,{id:"im-on-the-network-but-cant-load-the-pioreactor-ui-at-httppioreactorlocal",children:["I'm on the network, but can't load the Pioreactor UI at ",(0,n.jsx)(a.code,{children:"http://pioreactor.local"})]}),"\n",(0,n.jsxs)(a.p,{children:["Try ",(0,n.jsx)(a.code,{children:"http://http://pioreactor.local
point to?",id:"if-i-have-multiple-pioreactor-leaders-on-my-network-what-leader-does-httppioreactorlocal-point-to",level:3}];function c(e){const t={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.Z,{toc:d}),"\n",(0,r.jsx)(t.h2,{id:"pioreactor-operation",children:"Pioreactor operation"}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-restart-my-pioreactor-is-pulling-the-power-plug-out-safe",children:"How can I restart my Pioreactor? Is pulling the power plug out safe?"}),"\n",(0,r.jsx)(t.p,{children:"We suggest using the UI to reboot a Pioreactor:"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Rebooting your pi",src:i(15713).Z+"",width:"3010",height:"1440"})}),"\n",(0,r.jsx)(t.p,{children:"Pulling the plug is usually fine, but try to avoid doing it as it does risk data corruption."}),"\n",(0,r.jsx)(t.h3,{id:"can-i-still-use-the-pioreactor-software-without-the-hardware",children:"Can I still use the Pioreactor software without the hardware?"}),"\n",(0,r.jsxs)(t.p,{children:['Yes - the Pioreactor UI and software will still work. We provide a "leader-only" image that is designed to only host a cluster, and not be an active worker. The leader-only image, ',(0,r.jsx)(t.code,{children:"pioreactor_leader.zip "}),", are available ",(0,r.jsx)(t.a,{href:"https://github.com/Pioreactor/CustoPiZer/releases",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-onboard-blue-led-keep-flashing",children:"Why does the onboard blue LED keep flashing?"}),"\n",(0,r.jsxs)(t.p,{children:["There may be a problem. You can diagnose the problem by ",(0,r.jsx)(t.a,{href:"/user-guide/error-codes",children:"counting the number of flashes observed"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"what-does-the-onboard-button-do",children:"What does the onboard button do?"}),"\n",(0,r.jsx)(t.p,{children:'The button on the Pioreactor HAT sends a signal to the web UI to display a "hello" message. This is useful to know which Pioreactor in a cluster you are interacting with.'}),"\n",(0,r.jsxs)(t.p,{children:["The button can be ",(0,r.jsx)(t.a,{href:"/developer-guide/hat-button",children:"reprogrammed"}),", too."]}),"\n",(0,r.jsx)(t.h3,{id:"how-do-i-change-the-date-or-time-on-the-pioreactor",children:"How do I change the date or time on the Pioreactor?"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"/user-guide/accessing-raspberry-pi",children:"SSH"})," into your Pioreactor, and run:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:'sudo date --set "2023-11-02 09:46:50"\n\n'})}),"\n",(0,r.jsx)(t.h2,{id:"optical-density-and-leds",children:"Optical density and LEDs"}),"\n",(0,r.jsx)(t.h3,{id:"how-does-optical-density-work-on-the-pioreactor",children:"How does optical density work on the Pioreactor?"}),"\n",(0,r.jsxs)(t.p,{children:["The Pioreactor uses turbidity to measure optical density (other systems, like spectrophotometers, use attenuation). Specifically, the Pioreactor uses ",(0,r.jsx)(t.em,{children:"scattering"})," of light. The system will shine infrared light into the culture, and measure the amount of light that is scattered off cells. The scattering has a good linear range (see below for more), and higher saturation point than attenuation for cultures of 20ml volume. If you have an instrument that measures OD600 or some other measurement of optical density, and you wish to calibrate to that, the Pioreactor has a routine to perform a calibration and record in the instruments units. See ",(0,r.jsx)(t.a,{href:"/user-guide/calibrate-od600",children:"docs here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"what-are-the-units-of-pioreactors-optical-density",children:"What are the units of Pioreactor's optical density"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.em,{children:"uncalibrated"})," optical densities reported the UI and recorded in the database are have an arbitrary unit, and are per Pioreactor (so they can't be compared to each other). However, the ",(0,r.jsx)(t.em,{children:"normalized optical density"}),", generated after starting the activity ",(0,r.jsx)(t.strong,{children:"Growth rate"})," in the UI, is comparable, which is why we suggest using it for inferences (especially if you haven't calibrated to some OD600 machine). Read more about our ",(0,r.jsx)(t.a,{href:"https://docs.pioreactor.com/user-guide/od-normal-growth-rate",children:"optical density measurements here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-change-the-frequency-rate-of-optical-density-measurements",children:"How can I change the frequency (rate) of optical density measurements?"}),"\n",(0,r.jsxs)(t.p,{children:["In the configuration, you can edit the parameter ",(0,r.jsx)(t.code,{children:"samples_per_second"}),' to adjust the how often the Pioreactor takes an optical density snapshot. Note that this parameter is the inverse of "duration between readings". For example, if you wish to record a measurement every 60 seconds, then ',(0,r.jsx)(t.code,{children:"samples_per_second=0.01666667"})," (which is 1/60)."]}),"\n",(0,r.jsxs)(t.admonition,{type:"tip",children:[(0,r.jsxs)(t.p,{children:["If you put a large gap between readings, like 1 reading / 60 seconds, then we also suggest turning off the ",(0,r.jsx)(t.em,{children:"downsampling"})," on the UI's charts (it's on by default to avoid plotting thousands of points). To do this, ",(0,r.jsx)(t.a,{href:"/user-guide/accessing-raspberry-pi",children:"SSH"})," into your leader, and we'll edit the following files:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"nano /var/www/pioreactorui/contrib/charts/05_od.yaml\n"})}),(0,r.jsxs)(t.p,{children:["And change the field ",(0,r.jsx)(t.code,{children:"down_sample"})," from ",(0,r.jsx)(t.code,{children:"true"})," to ",(0,r.jsx)(t.code,{children:"false"}),". Do the same for the following files:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"nano /var/www/pioreactorui/contrib/charts/01_implied_growth_rate.yaml\n"})}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"nano /var/www/pioreactorui/contrib/charts/04_normalized_od.yaml\n"})})]}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-intensity-for-led-a-turn-on--off-during-an-experiment",children:"Why does the intensity for LED A turn on & off during an experiment?"}),"\n",(0,r.jsx)(t.p,{children:"You may have noticed that the LED labelled A turns on & off every 5 seconds or so. This is (normally) the channel for the infrared (IR) LED, which is used in the optical density measurements. We only take reading every 5 seconds (the default), we don't need the IR LED on all the time. The Pioreactor will only turn on LED when needed. This preserves the strength of the LED over longer periods of time. For more advanced use cases, it also allows other optical measurements to take place without the IR LED interfering with them."}),"\n",(0,r.jsx)(t.h3,{id:"why-does-my-optical-density-flatten-or-even-decrease-what-is-a-saturation-point",children:"Why does my optical density flatten, or even decrease? What is a saturation point?"}),"\n",(0,r.jsxs)(t.p,{children:["For some experiments, especially when using a scatter angle of 135\xb0, you may notice that the optical density starts to flatten, and even decrease, ",(0,r.jsx)(t.em,{children:"when you know the culture should still be growing"}),". This is not a property of the culture, but occurs because the culture is getting too dense, and light is now being interrupted before it reaches the photodiodes. Prior to this point, called the saturation point, the relationship between culture density and optical density is nearly linear. But after this point, there is a flattening, even negative, relationship between culture density and optical density. For all analysis, we recommend only studying when the culture is in the linear regime. You can mitigate the problem by choosing a smaller scatter angle (like 90\xb0 or 45\xb0), diluting the culture using an automation like the turbidostat, or using a lower concentration of nutrient(s) in the media. Read more about Pioreactor's optical system ",(0,r.jsx)(t.a,{href:"https://pioreactor.com/blogs/pioreactor/estimating-growth-rates-with-kalman-filters",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"what-does-the-effect-of-the-scatter-angle-have-on-optical-density",children:"What does the effect of the scatter angle have on optical density?"}),"\n",(0,r.jsxs)(t.p,{children:["The scatter angle is the angle between the IR LED and a photodiode. This angle can be 45\xb0, 90\xb0, or 135\xb0 (although 180\xb0 is possible, we don't consider it here). What is there to consider when choosing an angle. In general, the trend is shorter angles => less sensitive at low densities, but higher saturation point. By default, we suggest 45\xb0 as a good trade off between sensitivity and saturation. You can mix angles, and the Pioreactor's internal algorithm will still combine them into a single growth rate. Read more about Pioreactor's optical system ",(0,r.jsx)(t.a,{href:"https://pioreactor.com/blogs/pioreactor/estimating-growth-rates-with-kalman-filters",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-my-own-5mm-leds-and-photodiodes-for-optical-density",children:"Can I use my own 5mm LEDs and photodiodes for optical density?"}),"\n",(0,r.jsx)(t.p,{children:"Of course! The only two requirements are that the spectrum of the LED overlaps with the spectrum of the photodiode, and that the LED light won't be absorbed by media/culture, nor damage the media/culture. Thus, the often-used 600nm light source works in the Pioreactor. None of our internal algorithms or analytics are dependent on the wavelength of light chosen."}),"\n",(0,r.jsx)(t.p,{children:"When you are using additional LEDs outside of the optical density LED & photodiode pair, you may worry that your additional LEDs will interfere with the optical density measurement. This won't happen, as we turn off all non-optical density LEDs before taking an optical density measurement."}),"\n",(0,r.jsx)(t.h3,{id:"is-optical-density-the-same-as-turbidity",children:"Is optical density the same as turbidity?"}),"\n",(0,r.jsx)(t.p,{children:"Turbidity is a measure of optical density, like how decibels are a measurement of sound intensity. Similarly, absorbance is a measure of optical density."}),"\n",(0,r.jsx)(t.h2,{id:"heating-and-temperature-control",children:"Heating and Temperature control"}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-pioreactor-only-provide-a-temperature-reading-every-few-minutes",children:"Why does the Pioreactor only provide a temperature reading every few minutes?"}),"\n",(0,r.jsxs)(t.p,{children:["We made a design choice early on to make preparation as error-free as possible. This involved thinking about sensors being ",(0,r.jsx)(t.em,{children:"in situ"})," (in place), versus the sensors being on the outside of the vial. The temperature sensor in the Pioreactor is outside the vial, which means less chance of contamination, but there's a tradeoff (as you could guess): we have to rely on an estimation algorithm that requires a gew minutes to gather data on. We think this is a fair trade-off, as high frequency temperature readings are not that important in an experiment that lasts 12 hours or more."]}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-pioreactors-heating-keep-shutting-off",children:"Why does the Pioreactor's heating keep shutting off?"}),"\n",(0,r.jsx)(t.p,{children:"If you find that the Pioreactor's heating is shutting off, typically with an accompanying error and flashing blue light, then likely the temperature is becoming too high for safe handling. We restrict the onboard PCB's temperature to be no higher than 63\u2103. Temperature's higher than this can deform the plastic, and possibly cause burns. If the Pioreactor detects a temperature near or above this value, the software will shut off the heating, and possible the entire Raspberry Pi in extreme cases."}),"\n",(0,r.jsxs)(t.p,{children:["To avoid this occurring, we suggest not setting the target temperature too high - not more than 20\u2103 above ambient temperature. Also, reducing the ",(0,r.jsx)(t.code,{children:"Kd"})," parameter in ",(0,r.jsx)(t.code,{children:"[temperature_automation.stable]"})," section in the config.ini would help."]}),"\n",(0,r.jsx)(t.h3,{id:"how-does-heating-work-on-the-pioreactor",children:"How does heating work on the Pioreactor?"}),"\n",(0,r.jsx)(t.p,{children:"The Pioreactor has an onboard PCB, called the heating PCB, that sits below the glass vial. On the PCB are resistors that convert current from PWM outputs into heat. By varying the duty cycle of the PWM, we vary the amount of energy converted to heat."}),"\n",(0,r.jsx)(t.h2,{id:"mixing-and-stirring-in-the-pioreactor",children:"Mixing and stirring in the Pioreactor"}),"\n",(0,r.jsx)(t.h3,{id:"how-is-mixing--stirring-performed-in-the-pioreactor",children:"How is mixing / stirring performed in the Pioreactor?"}),"\n",(0,r.jsx)(t.p,{children:"Stirring is performed with a micro stir bar inside the vial, controlled by a pair of magnets spinning below the vial. The rotation speed, RPM, of the stir bar can be controlled using the Pioreactor software. This stirring is also how aeration is done."}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-my-own-stir-bar",children:"Can I use my own stir bar?"}),"\n",(0,r.jsx)(t.p,{children:"Of course! The maximum length of a stir bar is 20mm. Keep the height low as to not interfere with the optics. (The provided stir bar is 3mm high). Try using other stir bar shapes / designs!"}),"\n",(0,r.jsx)(t.h3,{id:"the-magnets-rubs-against-the-plastic-screws-above-them-causing-the-stirring-performance-to-be-degraded--stop-how-do-i-fix-this",children:"The magnets rubs against the plastic screws above them, causing the stirring performance to be degraded / stop. How do I fix this?"}),"\n",(0,r.jsx)(t.p,{children:"Dis-attach the top faceplate. Under the faceplate, slightly unscrew each of the four metal screws. This will add more space between the magnets and the plastic screws."}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-increase-the-strength-of-the-magnetic-force-applied-to-the-stirbar",children:"How can I increase the strength of the magnetic force applied to the stirbar?"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"For Pioreactor 20ml v1.0"}),": Try to reduce the distance between the stirring magnets and the stir bar by carefully raising the stirring fan a small amount. Going even further, you can remove the 4mm screws in the bottom of the vial holder (but find another way to secure the PCB), thereby be able to bring the magnets even closer."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-improve-mixing-and-aeration",children:"How can I improve mixing and aeration?"}),"\n",(0,r.jsx)(t.p,{children:"If the standard mixing and aeration with the stir bar is not enough for your application, you can do a few things, (in increasing order of complication, not necessarily effectiveness):"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"If the tubes in the cap are submerged during operation, this is reduce the transfer of air. Pull them up from the top of the cap to keep them out of the liquid. Even more effective: shorten them with scissors."}),"\n",(0,r.jsx)(t.li,{children:"Increase the RPM of the stirring. This will increase the surface area exposed to the air. Be warned though: too high of an RPM will cause either a large enough vortex to interfere with the optical systems, or will causing the stir bar to fall out of sync."}),"\n",(0,r.jsxs)(t.li,{children:["Add a ",(0,r.jsx)(t.a,{href:"https://www.printables.com/model/575292-baffle-for-pioreactor-vial-cap-a/files",children:"baffle"})," to the vial cap. A simple cylinder that rests into the liquid causes disturbance in the rotating liquid that both mixing and aeration are significantly improved. A tube can be removed from the cap, and a autoclavable rod can be inserted such that it enters the media, but won't interfere with the optics."]}),"\n",(0,r.jsx)(t.li,{children:"Adding external aeration to your Pioreactor. In the simplest case, using an air pump."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-plot-the-rpm-in-a-chart-in-the-ui",children:"Can I plot the RPM in a chart in the UI?"}),"\n",(0,r.jsxs)(t.p,{children:["Yes, follow the instructions ",(0,r.jsx)(t.a,{href:"https://forum.pioreactor.com/t/creating-stirring-rpm-and-pwm-duty-cycle-charts-on-the-ui/339",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"raspberry-pi-hardware",children:"Raspberry Pi Hardware"}),"\n",(0,r.jsx)(t.h3,{id:"what-raspberry-pi-hardware-can-i-use-i-see-raspberry-pi-1-2-3-4-5-a-b--zero---its-confusing",children:"What Raspberry Pi hardware can I use? I see Raspberry Pi 1, 2, 3, 4, 5, A, B, +, Zero - it's confusing!"}),"\n",(0,r.jsx)(t.p,{children:"We've designed the hardware and software to be compatible with most Raspberry Pis that have an onboard Wifi and a 40 pin header. That includes (at the time of writing):"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 3 Model B & B+"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 3 Model A+"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 4 Model B \xb2 \xb3"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 5 \xb2 \xb3"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi Zero 2 (with headers)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Although you can use any above, ",(0,r.jsx)(t.strong,{children:"we like the Raspberry Pi 3 B+, Raspberry Pi 4 B 2GB and Raspberry Pi Zero 2"}),". All have the necessary CPU power and memory for the Pioreactor workload, and are generally easy to source. However, they don't a ethernet connector built-in. So talk to your team about if you need to use ethernet or wifi. If you need ethernet, we like the model RPi 3 B+ or 4 B, or purchase some microUSB-to-ethernet dongles for the RPi Zero 2."]}),"\n",(0,r.jsx)(t.p,{children:"\xb2 You don't need a lot of RAM for the Pioreactor, so we recommend getting the lower RAM RPi if offered a choice. 2GB or less is fine. Also, if you are going to buy a Raspberry Pi 4, you should consider just upgrading for the Raspberry Pi 5 2GB (it's only a few dollars more, and much more performant)."}),"\n",(0,r.jsx)(t.p,{children:"\xb3 These have a USB-C power connector, whereas the other Pis have a microUSB power connector."}),"\n",(0,r.jsx)(t.h3,{id:"what-microsd-cards-do-you-recommend",children:"What microSD cards do you recommend?"}),"\n",(0,r.jsx)(t.p,{children:"At least 16GB. We like 16GB or 32GB SanDisk Edge or Samsung microSD cards for their longevity, but any good quality, class 10 SD card will do."}),"\n",(0,r.jsx)(t.h3,{id:"what-power-supply-unit-psu-do-i-need",children:"What power supply unit (PSU) do I need?"}),"\n",(0,r.jsxs)(t.p,{children:["If you look at the power rating, it should be about 5 V and at least 2.25 A, or above 12 W. We really like the ",(0,r.jsx)(t.a,{href:"https://www.raspberrypi.com/products/#power-supplies-and-cables",children:"official Raspberry Pi PSUs"}),", available at most places you can purchase Raspberry Pis."]}),"\n",(0,r.jsxs)(t.p,{children:["If you need to power multiple Pioreactors, you might consider a single PSU with USB ports ",(0,r.jsx)(t.a,{href:"/user-guide/powering-cluster",children:"detailed here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"do-i-need-any-cooling-for-the-raspberry-pi",children:"Do I need any cooling for the Raspberry Pi?"}),"\n",(0,r.jsx)(t.p,{children:"Nope, you shouldn't. However, extra heat sinks are never a bad idea!"}),"\n",(0,r.jsx)(t.h3,{id:"could-a-raspberry-pi-compatible-board-work-like-rock-pi-4",children:"Could a Raspberry Pi-compatible board work, like Rock Pi 4?"}),"\n",(0,r.jsx)(t.p,{children:"Maybe? We haven't tested them, but so long as i) the GPIO pins are identical, and ii) Raspberry Pi OS can be installed, it should work."}),"\n",(0,r.jsx)(t.h3,{id:"what-is-the-usernamepassword-for-the-raspberry-pi",children:"What is the username/password for the Raspberry Pi?"}),"\n",(0,r.jsxs)(t.p,{children:["When setting up your Raspberry Pi with the Pioreactor software, you would have chosen a password. Try the recommended username: ",(0,r.jsx)(t.code,{children:"pioreactor"}),", and password: ",(0,r.jsx)(t.code,{children:"raspberry"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-the-desktop-interface-with-a-display-with-the-pioreactor",children:"Can I use the desktop interface (with a display) with the Pioreactor?"}),"\n",(0,r.jsx)(t.p,{children:'Not currently. Our software is based of the "headless" operating-system, which doesn\'t have display output.'}),"\n",(0,r.jsx)(t.h2,{id:"dosing",children:"Dosing"}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-media-card-in-the-ui-not-update-when-i-run-a-dosing-command",children:"Why does the Media card in the UI not update when I run a dosing command?"}),"\n",(0,r.jsxs)(t.p,{children:["The Media card will ",(0,r.jsx)(t.em,{children:"only"})," update when an ",(0,r.jsx)(t.a,{href:"/user-guide/dosing-automations",children:"Dosing Automation"})," is active (even the ",(0,r.jsx)(t.code,{children:"Silent"})," automation). Why is it done this way? Often, you don't want volumes to be recorded there: during cleaning, during testing, etc. Often you only want volumes associated with the experiment to be there."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:['All dosing events ares recorded to the database however, and with a record of when the event occurred, and source of action. This data is available in the "Export data" web page, under ',(0,r.jsx)(t.code,{children:"Dosing event log"}),"."]})}),"\n",(0,r.jsx)(t.h2,{id:"data-storage-access-and-recovery",children:"Data storage, access and recovery"}),"\n",(0,r.jsxs)(t.blockquote,{children:["\n",(0,r.jsx)(t.p,{children:"\ud83d\udca1 For any important project, we suggest manually exporting or backing up critical data multiple different places. This doesn't just apply to using the Pioreactor, but is good advice in general."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"where-are-logs-stored",children:"Where are logs stored?"}),"\n",(0,r.jsxs)(t.p,{children:["For the logs that you see in the Log Table in the ",(0,r.jsx)(t.em,{children:"Experiment Overview"})," page, these can be download on the ",(0,r.jsx)(t.em,{children:"Download experiment data"})," page in the Pioreactor web interface. Other logs are also available, including dosing event and algorithm change-logs."]}),"\n",(0,r.jsxs)(t.p,{children:["More granular logs per Pioreactor are available in ",(0,r.jsx)(t.code,{children:"/var/log/pioreactor.log"})," on the Raspberry Pis."]}),"\n",(0,r.jsx)(t.h3,{id:"how-do-i-access-raw-experiment-data",children:"How do I access raw experiment data?"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.em,{children:"Export data"})," page in the Pioreactor UI provides CSV exports of common datasets from a pre-selected experiment."]}),"\n",(0,r.jsxs)(t.li,{children:["All data eventually lands in a SQLite3 database on the leader Pioreactor, by default located in ",(0,r.jsx)(t.code,{children:"/home/pioreactor/.pioreactor/storage/pioreactor.sqlite"}),". This can be download using a tool like ",(0,r.jsx)(t.code,{children:"scp"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["To access the SQLite3 database from the command line, try ",(0,r.jsx)(t.code,{children:"pio db"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"my-microsd-card-is-corrupted---what-can-i-do",children:"My microSD card is corrupted - what can I do?"}),"\n",(0,r.jsx)(t.p,{children:"Unfortunately, the microSD card becoming corrupted or damaged is an infrequent but possible risk with using Raspberry Pis."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["If the microSD card was inside a non-leader Pioreactor, it's best to try to reformat the microSD card and start fresh (i.e. ",(0,r.jsx)(t.a,{href:"/user-guide/software-set-up#adding-workers-to-your-cluster",children:"reinstall the Pioreactor software and reintroduce it to the cluster"}),"). This is usually okay as no critical data is stored locally in workers, only log files and hardware calibrations will be lost."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["If the microSD was inside the leader Raspberry Pi, this is a bigger problem. Likely any running experiment will have to be restarted. Fortunately, if you have more than one Pioreactor in your cluster, then the leader's SQLite database has been periodically backing itself up to other Pioreactors in the cluster every few days. Using the command line, check other Pioreactors' ",(0,r.jsx)(t.code,{children:"/home/pioreactor/.pioreactor/storage"})," directory for the ",(0,r.jsx)(t.em,{children:"latest"})," backup named ",(0,r.jsx)(t.code,{children:"pioreactor.sqlite.backup"})," (should be from within the past few days hours). You can use this database to restart a new leader."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"networking",children:"Networking"}),"\n",(0,r.jsx)(t.h3,{id:"how-do-i-changeedit-the-network-the-pioreactor-on",children:"How do I change/edit the network the Pioreactor on?"}),"\n",(0,r.jsxs)(t.p,{children:["See documentation on networking ",(0,r.jsx)(t.a,{href:"/user-guide/networking#general-networking-tools",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-ethernet-cable-connections-instead-of-wifi-connections",children:"Can I use Ethernet cable connections instead of Wifi connections?"}),"\n",(0,r.jsxs)(t.p,{children:["Yes, so long as the Raspberry Pi's are connected to the same network and discoverable, this should work. Even mixing Ethernet and Wifi is fine. You can read more about networking Pioreactors ",(0,r.jsx)(t.a,{href:"/user-guide/networking",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-determine-the-pioreactors-ip-address-or-the-mac-address",children:"How can I determine the Pioreactor's IP address? Or the MAC address?"}),"\n",(0,r.jsx)(t.p,{children:"Depending on your access to the Pioreactor, there are a few ways:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"In the UI's Inventory page."}),"\n",(0,r.jsxs)(t.li,{children:["If you can't access the Pioreactor's UI or SSH in: the software will write the IP address to the ",(0,r.jsx)(t.code,{children:"/boot"})," directory on the SD card. After the Pioreactor's blue LED has blinked, you can unplug the Pioreactor, remove the SD card, and place the SD card in another computer. Navigate to the card, and in the directory you should see a file called ",(0,r.jsx)(t.code,{children:"ip"}),". Open this file, and the IP address should be there. Place the SD card back into the Pioreactor and plug it back in."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"im-using-a-local-access-point-but-id-like-to-install-plugins-update-software-etc",children:"I'm using a local access point, but I'd like to install plugins, update software, etc."}),"\n",(0,r.jsx)(t.h4,{id:"to-install-a-plugin",children:"To install a plugin"}),"\n",(0,r.jsxs)(t.p,{children:["On a computer that is connected to the internet, download the ",(0,r.jsx)(t.code,{children:".whl"})," file from the plugins webpage on PyPI. Then, connect that computer to your Pioreactor's local access point's network. To each Pioreactor you wish to install the plugin on, transfer the ",(0,r.jsx)(t.code,{children:".whl"})," file to the Pioreactor (using SFTP or FTP). Then, run ",(0,r.jsx)(t.code,{children:"pio plugins install http://pioreactor.local
point to?",id:"if-i-have-multiple-pioreactor-leaders-on-my-network-what-leader-does-httppioreactorlocal-point-to",level:3}];function c(e){const t={a:"a",admonition:"admonition",blockquote:"blockquote",code:"code",em:"em",h2:"h2",h3:"h3",h4:"h4",img:"img",li:"li",ol:"ol",p:"p",pre:"pre",strong:"strong",ul:"ul",...(0,o.a)(),...e.components};return(0,r.jsxs)(r.Fragment,{children:[(0,r.jsx)(n.Z,{toc:d}),"\n",(0,r.jsx)(t.h2,{id:"pioreactor-operation",children:"Pioreactor operation"}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-restart-my-pioreactor-is-pulling-the-power-plug-out-safe",children:"How can I restart my Pioreactor? Is pulling the power plug out safe?"}),"\n",(0,r.jsx)(t.p,{children:"We suggest using the UI to reboot a Pioreactor:"}),"\n",(0,r.jsx)(t.p,{children:(0,r.jsx)(t.img,{alt:"Rebooting your pi",src:i(15713).Z+"",width:"3010",height:"1440"})}),"\n",(0,r.jsx)(t.p,{children:"Pulling the plug is usually fine, but try to avoid doing it as it does risk data corruption."}),"\n",(0,r.jsx)(t.h3,{id:"can-i-still-use-the-pioreactor-software-without-the-hardware",children:"Can I still use the Pioreactor software without the hardware?"}),"\n",(0,r.jsxs)(t.p,{children:['Yes - the Pioreactor UI and software will still work. We provide a "leader-only" image that is designed to only host a cluster, and not be an active worker. The leader-only image, ',(0,r.jsx)(t.code,{children:"pioreactor_leader.zip "}),", are available ",(0,r.jsx)(t.a,{href:"https://github.com/Pioreactor/CustoPiZer/releases",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-onboard-blue-led-keep-flashing",children:"Why does the onboard blue LED keep flashing?"}),"\n",(0,r.jsxs)(t.p,{children:["There may be a problem. You can diagnose the problem by ",(0,r.jsx)(t.a,{href:"/user-guide/error-codes",children:"counting the number of flashes observed"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"what-does-the-onboard-button-do",children:"What does the onboard button do?"}),"\n",(0,r.jsx)(t.p,{children:'The button on the Pioreactor HAT sends a signal to the web UI to display a "hello" message. This is useful to know which Pioreactor in a cluster you are interacting with.'}),"\n",(0,r.jsxs)(t.p,{children:["The button can be ",(0,r.jsx)(t.a,{href:"/developer-guide/hat-button",children:"reprogrammed"}),", too."]}),"\n",(0,r.jsx)(t.h3,{id:"how-do-i-change-the-date-or-time-on-the-pioreactor",children:"How do I change the date or time on the Pioreactor?"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.a,{href:"/user-guide/accessing-raspberry-pi",children:"SSH"})," into your Pioreactor, and run:"]}),"\n",(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:'sudo date --set "2023-11-02 09:46:50"\n\n'})}),"\n",(0,r.jsx)(t.h2,{id:"optical-density-and-leds",children:"Optical density and LEDs"}),"\n",(0,r.jsx)(t.h3,{id:"how-does-optical-density-work-on-the-pioreactor",children:"How does optical density work on the Pioreactor?"}),"\n",(0,r.jsxs)(t.p,{children:["The Pioreactor uses turbidity to measure optical density (other systems, like spectrophotometers, use attenuation). Specifically, the Pioreactor uses ",(0,r.jsx)(t.em,{children:"scattering"})," of light. The system will shine infrared light into the culture, and measure the amount of light that is scattered off cells. The scattering has a good linear range (see below for more), and higher saturation point than attenuation for cultures of 20ml volume. If you have an instrument that measures OD600 or some other measurement of optical density, and you wish to calibrate to that, the Pioreactor has a routine to perform a calibration and record in the instruments units. See ",(0,r.jsx)(t.a,{href:"/user-guide/calibrate-od600",children:"docs here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"what-are-the-units-of-pioreactors-optical-density",children:"What are the units of Pioreactor's optical density"}),"\n",(0,r.jsxs)(t.p,{children:["The ",(0,r.jsx)(t.em,{children:"uncalibrated"})," optical densities reported the UI and recorded in the database are have an arbitrary unit, and are per Pioreactor (so they can't be compared to each other). However, the ",(0,r.jsx)(t.em,{children:"normalized optical density"}),", generated after starting the activity ",(0,r.jsx)(t.strong,{children:"Growth rate"})," in the UI, is comparable, which is why we suggest using it for inferences (especially if you haven't calibrated to some OD600 machine). Read more about our ",(0,r.jsx)(t.a,{href:"https://docs.pioreactor.com/user-guide/od-normal-growth-rate",children:"optical density measurements here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-change-the-frequency-rate-of-optical-density-measurements",children:"How can I change the frequency (rate) of optical density measurements?"}),"\n",(0,r.jsxs)(t.p,{children:["In the configuration, you can edit the parameter ",(0,r.jsx)(t.code,{children:"samples_per_second"}),' to adjust the how often the Pioreactor takes an optical density snapshot. Note that this parameter is the inverse of "duration between readings". For example, if you wish to record a measurement every 60 seconds, then ',(0,r.jsx)(t.code,{children:"samples_per_second=0.01666667"})," (which is 1/60)."]}),"\n",(0,r.jsxs)(t.admonition,{type:"tip",children:[(0,r.jsxs)(t.p,{children:["If you put a large gap between readings, like 1 reading / 60 seconds, then we also suggest turning off the ",(0,r.jsx)(t.em,{children:"downsampling"})," on the UI's charts (it's on by default to avoid plotting thousands of points). To do this, ",(0,r.jsx)(t.a,{href:"/user-guide/accessing-raspberry-pi",children:"SSH"})," into your leader, and we'll edit the following files:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"nano /var/www/pioreactorui/contrib/charts/05_od.yaml\n"})}),(0,r.jsxs)(t.p,{children:["And change the field ",(0,r.jsx)(t.code,{children:"down_sample"})," from ",(0,r.jsx)(t.code,{children:"true"})," to ",(0,r.jsx)(t.code,{children:"false"}),". Do the same for the following files:"]}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"nano /var/www/pioreactorui/contrib/charts/01_implied_growth_rate.yaml\n"})}),(0,r.jsx)(t.pre,{children:(0,r.jsx)(t.code,{children:"nano /var/www/pioreactorui/contrib/charts/04_normalized_od.yaml\n"})})]}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-intensity-for-led-a-turn-on--off-during-an-experiment",children:"Why does the intensity for LED A turn on & off during an experiment?"}),"\n",(0,r.jsx)(t.p,{children:"You may have noticed that the LED labelled A turns on & off every 5 seconds or so. This is (normally) the channel for the infrared (IR) LED, which is used in the optical density measurements. We only take reading every 5 seconds (the default), we don't need the IR LED on all the time. The Pioreactor will only turn on LED when needed. This preserves the strength of the LED over longer periods of time. For more advanced use cases, it also allows other optical measurements to take place without the IR LED interfering with them."}),"\n",(0,r.jsx)(t.h3,{id:"why-does-my-optical-density-flatten-or-even-decrease-what-is-a-saturation-point",children:"Why does my optical density flatten, or even decrease? What is a saturation point?"}),"\n",(0,r.jsxs)(t.p,{children:["For some experiments, especially when using a scatter angle of 135\xb0, you may notice that the optical density starts to flatten, and even decrease, ",(0,r.jsx)(t.em,{children:"when you know the culture should still be growing"}),". This is not a property of the culture, but occurs because the culture is getting too dense, and light is now being interrupted before it reaches the photodiodes. Prior to this point, called the saturation point, the relationship between culture density and optical density is nearly linear. But after this point, there is a flattening, even negative, relationship between culture density and optical density. For all analysis, we recommend only studying when the culture is in the linear regime. You can mitigate the problem by choosing a smaller scatter angle (like 90\xb0 or 45\xb0), diluting the culture using an automation like the turbidostat, or using a lower concentration of nutrient(s) in the media. Read more about Pioreactor's optical system ",(0,r.jsx)(t.a,{href:"https://pioreactor.com/blogs/pioreactor/estimating-growth-rates-with-kalman-filters",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"what-does-the-effect-of-the-scatter-angle-have-on-optical-density",children:"What does the effect of the scatter angle have on optical density?"}),"\n",(0,r.jsxs)(t.p,{children:["The scatter angle is the angle between the IR LED and a photodiode. This angle can be 45\xb0, 90\xb0, or 135\xb0 (although 180\xb0 is possible, we don't consider it here). What is there to consider when choosing an angle. In general, the trend is shorter angles => less sensitive at low densities, but higher saturation point. By default, we suggest 45\xb0 as a good trade off between sensitivity and saturation. You can mix angles, and the Pioreactor's internal algorithm will still combine them into a single growth rate. Read more about Pioreactor's optical system ",(0,r.jsx)(t.a,{href:"https://pioreactor.com/blogs/pioreactor/estimating-growth-rates-with-kalman-filters",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-my-own-5mm-leds-and-photodiodes-for-optical-density",children:"Can I use my own 5mm LEDs and photodiodes for optical density?"}),"\n",(0,r.jsx)(t.p,{children:"Of course! The only two requirements are that the spectrum of the LED overlaps with the spectrum of the photodiode, and that the LED light won't be absorbed by media/culture, nor damage the media/culture. Thus, the often-used 600nm light source works in the Pioreactor. None of our internal algorithms or analytics are dependent on the wavelength of light chosen."}),"\n",(0,r.jsx)(t.p,{children:"When you are using additional LEDs outside of the optical density LED & photodiode pair, you may worry that your additional LEDs will interfere with the optical density measurement. This won't happen, as we turn off all non-optical density LEDs before taking an optical density measurement."}),"\n",(0,r.jsx)(t.h3,{id:"is-optical-density-the-same-as-turbidity",children:"Is optical density the same as turbidity?"}),"\n",(0,r.jsx)(t.p,{children:"Turbidity is a measure of optical density, like how decibels are a measurement of sound intensity. Similarly, absorbance is a measure of optical density."}),"\n",(0,r.jsx)(t.h2,{id:"heating-and-temperature-control",children:"Heating and Temperature control"}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-pioreactor-only-provide-a-temperature-reading-every-few-minutes",children:"Why does the Pioreactor only provide a temperature reading every few minutes?"}),"\n",(0,r.jsxs)(t.p,{children:["We made a design choice early on to make preparation as error-free as possible. This involved thinking about sensors being ",(0,r.jsx)(t.em,{children:"in situ"})," (in place), versus the sensors being on the outside of the vial. The temperature sensor in the Pioreactor is outside the vial, which means less chance of contamination, but there's a tradeoff (as you could guess): we have to rely on an estimation algorithm that requires a gew minutes to gather data on. We think this is a fair trade-off, as high frequency temperature readings are not that important in an experiment that lasts 12 hours or more."]}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-pioreactors-heating-keep-shutting-off",children:"Why does the Pioreactor's heating keep shutting off?"}),"\n",(0,r.jsx)(t.p,{children:"If you find that the Pioreactor's heating is shutting off, typically with an accompanying error and flashing blue light, then likely the temperature is becoming too high for safe handling. We restrict the onboard PCB's temperature to be no higher than 63\u2103. Temperature's higher than this can deform the plastic, and possibly cause burns. If the Pioreactor detects a temperature near or above this value, the software will shut off the heating, and possible the entire Raspberry Pi in extreme cases."}),"\n",(0,r.jsxs)(t.p,{children:["To avoid this occurring, we suggest not setting the target temperature too high - not more than 20\u2103 above ambient temperature. Also, reducing the ",(0,r.jsx)(t.code,{children:"Kd"})," parameter in ",(0,r.jsx)(t.code,{children:"[temperature_automation.stable]"})," section in the config.ini would help."]}),"\n",(0,r.jsx)(t.h3,{id:"how-does-heating-work-on-the-pioreactor",children:"How does heating work on the Pioreactor?"}),"\n",(0,r.jsx)(t.p,{children:"The Pioreactor has an onboard PCB, called the heating PCB, that sits below the glass vial. On the PCB are resistors that convert current from PWM outputs into heat. By varying the duty cycle of the PWM, we vary the amount of energy converted to heat."}),"\n",(0,r.jsx)(t.h2,{id:"mixing-and-stirring-in-the-pioreactor",children:"Mixing and stirring in the Pioreactor"}),"\n",(0,r.jsx)(t.h3,{id:"how-is-mixing--stirring-performed-in-the-pioreactor",children:"How is mixing / stirring performed in the Pioreactor?"}),"\n",(0,r.jsx)(t.p,{children:"Stirring is performed with a micro stir bar inside the vial, controlled by a pair of magnets spinning below the vial. The rotation speed, RPM, of the stir bar can be controlled using the Pioreactor software. This stirring is also how aeration is done."}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-my-own-stir-bar",children:"Can I use my own stir bar?"}),"\n",(0,r.jsx)(t.p,{children:"Of course! The maximum length of a stir bar is 20mm. Keep the height low as to not interfere with the optics. (The provided stir bar is 3mm high). Try using other stir bar shapes / designs!"}),"\n",(0,r.jsx)(t.h3,{id:"the-magnets-rubs-against-the-plastic-screws-above-them-causing-the-stirring-performance-to-be-degraded--stop-how-do-i-fix-this",children:"The magnets rubs against the plastic screws above them, causing the stirring performance to be degraded / stop. How do I fix this?"}),"\n",(0,r.jsx)(t.p,{children:"Dis-attach the top faceplate. Under the faceplate, slightly unscrew each of the four metal screws. This will add more space between the magnets and the plastic screws."}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-increase-the-strength-of-the-magnetic-force-applied-to-the-stirbar",children:"How can I increase the strength of the magnetic force applied to the stirbar?"}),"\n",(0,r.jsxs)(t.p,{children:[(0,r.jsx)(t.strong,{children:"For Pioreactor 20ml v1.0"}),": Try to reduce the distance between the stirring magnets and the stir bar by carefully raising the stirring fan a small amount. Going even further, you can remove the 4mm screws in the bottom of the vial holder (but find another way to secure the PCB), thereby be able to bring the magnets even closer."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-improve-mixing-and-aeration",children:"How can I improve mixing and aeration?"}),"\n",(0,r.jsx)(t.p,{children:"If the standard mixing and aeration with the stir bar is not enough for your application, you can do a few things, (in increasing order of complication, not necessarily effectiveness):"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"If the tubes in the cap are submerged during operation, this is reduce the transfer of air. Pull them up from the top of the cap to keep them out of the liquid. Even more effective: shorten them with scissors."}),"\n",(0,r.jsx)(t.li,{children:"Increase the RPM of the stirring. This will increase the surface area exposed to the air. Be warned though: too high of an RPM will cause either a large enough vortex to interfere with the optical systems, or will causing the stir bar to fall out of sync."}),"\n",(0,r.jsxs)(t.li,{children:["Add a ",(0,r.jsx)(t.a,{href:"https://www.printables.com/model/575292-baffle-for-pioreactor-vial-cap-a/files",children:"baffle"})," to the vial cap. A simple cylinder that rests into the liquid causes disturbance in the rotating liquid that both mixing and aeration are significantly improved. A tube can be removed from the cap, and a autoclavable rod can be inserted such that it enters the media, but won't interfere with the optics."]}),"\n",(0,r.jsx)(t.li,{children:"Adding external aeration to your Pioreactor. In the simplest case, using an air pump."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-plot-the-rpm-in-a-chart-in-the-ui",children:"Can I plot the RPM in a chart in the UI?"}),"\n",(0,r.jsxs)(t.p,{children:["Yes, follow the instructions ",(0,r.jsx)(t.a,{href:"https://forum.pioreactor.com/t/creating-stirring-rpm-and-pwm-duty-cycle-charts-on-the-ui/339",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h2,{id:"raspberry-pi-hardware",children:"Raspberry Pi Hardware"}),"\n",(0,r.jsx)(t.h3,{id:"what-raspberry-pi-hardware-can-i-use-i-see-raspberry-pi-1-2-3-4-5-a-b--zero---its-confusing",children:"What Raspberry Pi hardware can I use? I see Raspberry Pi 1, 2, 3, 4, 5, A, B, +, Zero - it's confusing!"}),"\n",(0,r.jsx)(t.p,{children:"We've designed the hardware and software to be compatible with most Raspberry Pis that have an onboard Wifi and a 40 pin header. That includes (at the time of writing):"}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 3 Model B & B+"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 3 Model A+"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 4 Model B \xb2 \xb3"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi 5 \xb2 \xb3"}),"\n",(0,r.jsx)(t.li,{children:"Raspberry Pi Zero 2 (with headers)"}),"\n"]}),"\n",(0,r.jsxs)(t.p,{children:["Although you can use any above, ",(0,r.jsx)(t.strong,{children:"we like the Raspberry Pi 3 B+, Raspberry Pi 4 B 2GB and Raspberry Pi Zero 2"}),". All have the necessary CPU power and memory for the Pioreactor workload, and are generally easy to source. However, they don't a ethernet connector built-in. So talk to your team about if you need to use ethernet or wifi. If you need ethernet, we like the model RPi 3 B+ or 4 B, or purchase some microUSB-to-ethernet dongles for the RPi Zero 2."]}),"\n",(0,r.jsx)(t.p,{children:"\xb2 You don't need a lot of RAM for the Pioreactor, so we recommend getting the lower RAM RPi if offered a choice. 2GB or less is fine. Also, if you are going to buy a Raspberry Pi 4, you should consider just upgrading for the Raspberry Pi 5 2GB (it's only a few dollars more, and much more performant)."}),"\n",(0,r.jsx)(t.p,{children:"\xb3 These have a USB-C power connector, whereas the other Pis have a microUSB power connector."}),"\n",(0,r.jsx)(t.h3,{id:"what-microsd-cards-do-you-recommend",children:"What microSD cards do you recommend?"}),"\n",(0,r.jsxs)(t.p,{children:["The Raspberry Pi has an ",(0,r.jsx)(t.em,{children:"official Raspberry Pi microSD card"})," that we recommend for its high quality. You can likely purchase it at the same place you purchase PSUs and Pis. The 32 GB, blank, version is fine."]}),"\n",(0,r.jsx)(t.p,{children:"In general: at least 16GB. We like 16GB or 32GB SanDisk Edge or Samsung microSD cards for their longevity, but any good quality, class 10 microSD card will do."}),"\n",(0,r.jsx)(t.h3,{id:"what-power-supply-unit-psu-do-i-need",children:"What power supply unit (PSU) do I need?"}),"\n",(0,r.jsxs)(t.p,{children:["If you look at the power rating, it should be about 5 V and at least 2.25 A, or above 12 W. We really like the ",(0,r.jsx)(t.a,{href:"https://www.raspberrypi.com/products/#power-supplies-and-cables",children:"official Raspberry Pi PSUs"}),", available at most places you can purchase Raspberry Pis."]}),"\n",(0,r.jsxs)(t.p,{children:["If you need to power multiple Pioreactors, you might consider a single PSU with USB ports ",(0,r.jsx)(t.a,{href:"/user-guide/powering-cluster",children:"detailed here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"do-i-need-any-cooling-for-the-raspberry-pi",children:"Do I need any cooling for the Raspberry Pi?"}),"\n",(0,r.jsx)(t.p,{children:"Nope, you shouldn't. However, extra heat sinks are never a bad idea!"}),"\n",(0,r.jsx)(t.h3,{id:"could-a-raspberry-pi-compatible-board-work-like-rock-pi-4",children:"Could a Raspberry Pi-compatible board work, like Rock Pi 4?"}),"\n",(0,r.jsx)(t.p,{children:"Maybe? We haven't tested them, but so long as i) the GPIO pins are identical, and ii) Raspberry Pi OS can be installed, it should work."}),"\n",(0,r.jsx)(t.h3,{id:"what-is-the-usernamepassword-for-the-raspberry-pi",children:"What is the username/password for the Raspberry Pi?"}),"\n",(0,r.jsxs)(t.p,{children:["When setting up your Raspberry Pi with the Pioreactor software, you would have chosen a password. Try the recommended username: ",(0,r.jsx)(t.code,{children:"pioreactor"}),", and password: ",(0,r.jsx)(t.code,{children:"raspberry"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-the-desktop-interface-with-a-display-with-the-pioreactor",children:"Can I use the desktop interface (with a display) with the Pioreactor?"}),"\n",(0,r.jsx)(t.p,{children:'Not currently. Our software is based of the "headless" operating-system, which doesn\'t have display output.'}),"\n",(0,r.jsx)(t.h2,{id:"dosing",children:"Dosing"}),"\n",(0,r.jsx)(t.h3,{id:"why-does-the-media-card-in-the-ui-not-update-when-i-run-a-dosing-command",children:"Why does the Media card in the UI not update when I run a dosing command?"}),"\n",(0,r.jsxs)(t.p,{children:["The Media card will ",(0,r.jsx)(t.em,{children:"only"})," update when an ",(0,r.jsx)(t.a,{href:"/user-guide/dosing-automations",children:"Dosing Automation"})," is active (even the ",(0,r.jsx)(t.code,{children:"Silent"})," automation). Why is it done this way? Often, you don't want volumes to be recorded there: during cleaning, during testing, etc. Often you only want volumes associated with the experiment to be there."]}),"\n",(0,r.jsx)(t.admonition,{type:"note",children:(0,r.jsxs)(t.p,{children:['All dosing events ares recorded to the database however, and with a record of when the event occurred, and source of action. This data is available in the "Export data" web page, under ',(0,r.jsx)(t.code,{children:"Dosing event log"}),"."]})}),"\n",(0,r.jsx)(t.h2,{id:"data-storage-access-and-recovery",children:"Data storage, access and recovery"}),"\n",(0,r.jsxs)(t.blockquote,{children:["\n",(0,r.jsx)(t.p,{children:"\ud83d\udca1 For any important project, we suggest manually exporting or backing up critical data multiple different places. This doesn't just apply to using the Pioreactor, but is good advice in general."}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"where-are-logs-stored",children:"Where are logs stored?"}),"\n",(0,r.jsxs)(t.p,{children:["For the logs that you see in the Log Table in the ",(0,r.jsx)(t.em,{children:"Experiment Overview"})," page, these can be download on the ",(0,r.jsx)(t.em,{children:"Download experiment data"})," page in the Pioreactor web interface. Other logs are also available, including dosing event and algorithm change-logs."]}),"\n",(0,r.jsxs)(t.p,{children:["More granular logs per Pioreactor are available in ",(0,r.jsx)(t.code,{children:"/var/log/pioreactor.log"})," on the Raspberry Pis."]}),"\n",(0,r.jsx)(t.h3,{id:"how-do-i-access-raw-experiment-data",children:"How do I access raw experiment data?"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsxs)(t.li,{children:["The ",(0,r.jsx)(t.em,{children:"Export data"})," page in the Pioreactor UI provides CSV exports of common datasets from a pre-selected experiment."]}),"\n",(0,r.jsxs)(t.li,{children:["All data eventually lands in a SQLite3 database on the leader Pioreactor, by default located in ",(0,r.jsx)(t.code,{children:"/home/pioreactor/.pioreactor/storage/pioreactor.sqlite"}),". This can be download using a tool like ",(0,r.jsx)(t.code,{children:"scp"}),"."]}),"\n",(0,r.jsxs)(t.li,{children:["To access the SQLite3 database from the command line, try ",(0,r.jsx)(t.code,{children:"pio db"}),"."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"my-microsd-card-is-corrupted---what-can-i-do",children:"My microSD card is corrupted - what can I do?"}),"\n",(0,r.jsx)(t.p,{children:"Unfortunately, the microSD card becoming corrupted or damaged is an infrequent but possible risk with using Raspberry Pis."}),"\n",(0,r.jsxs)(t.ul,{children:["\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["If the microSD card was inside a non-leader Pioreactor, it's best to try to reformat the microSD card and start fresh (i.e. ",(0,r.jsx)(t.a,{href:"/user-guide/software-set-up#adding-workers-to-your-cluster",children:"reinstall the Pioreactor software and reintroduce it to the cluster"}),"). This is usually okay as no critical data is stored locally in workers, only log files and hardware calibrations will be lost."]}),"\n"]}),"\n",(0,r.jsxs)(t.li,{children:["\n",(0,r.jsxs)(t.p,{children:["If the microSD was inside the leader Raspberry Pi, this is a bigger problem. Likely any running experiment will have to be restarted. Fortunately, if you have more than one Pioreactor in your cluster, then the leader's SQLite database has been periodically backing itself up to other Pioreactors in the cluster every few days. Using the command line, check other Pioreactors' ",(0,r.jsx)(t.code,{children:"/home/pioreactor/.pioreactor/storage"})," directory for the ",(0,r.jsx)(t.em,{children:"latest"})," backup named ",(0,r.jsx)(t.code,{children:"pioreactor.sqlite.backup"})," (should be from within the past few days hours). You can use this database to restart a new leader."]}),"\n"]}),"\n"]}),"\n",(0,r.jsx)(t.h2,{id:"networking",children:"Networking"}),"\n",(0,r.jsx)(t.h3,{id:"how-do-i-changeedit-the-network-the-pioreactor-on",children:"How do I change/edit the network the Pioreactor on?"}),"\n",(0,r.jsxs)(t.p,{children:["See documentation on networking ",(0,r.jsx)(t.a,{href:"/user-guide/networking#general-networking-tools",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"can-i-use-ethernet-cable-connections-instead-of-wifi-connections",children:"Can I use Ethernet cable connections instead of Wifi connections?"}),"\n",(0,r.jsxs)(t.p,{children:["Yes, so long as the Raspberry Pi's are connected to the same network and discoverable, this should work. Even mixing Ethernet and Wifi is fine. You can read more about networking Pioreactors ",(0,r.jsx)(t.a,{href:"/user-guide/networking",children:"here"}),"."]}),"\n",(0,r.jsx)(t.h3,{id:"how-can-i-determine-the-pioreactors-ip-address-or-the-mac-address",children:"How can I determine the Pioreactor's IP address? Or the MAC address?"}),"\n",(0,r.jsx)(t.p,{children:"Depending on your access to the Pioreactor, there are a few ways:"}),"\n",(0,r.jsxs)(t.ol,{children:["\n",(0,r.jsx)(t.li,{children:"In the UI's Inventory page."}),"\n",(0,r.jsxs)(t.li,{children:["If you can't access the Pioreactor's UI or SSH in: the software will write the IP address to the ",(0,r.jsx)(t.code,{children:"/boot"})," directory on the SD card. After the Pioreactor's blue LED has blinked, you can unplug the Pioreactor, remove the SD card, and place the SD card in another computer. Navigate to the card, and in the directory you should see a file called ",(0,r.jsx)(t.code,{children:"ip"}),". Open this file, and the IP address should be there. Place the SD card back into the Pioreactor and plug it back in."]}),"\n"]}),"\n",(0,r.jsx)(t.h3,{id:"im-using-a-local-access-point-but-id-like-to-install-plugins-update-software-etc",children:"I'm using a local access point, but I'd like to install plugins, update software, etc."}),"\n",(0,r.jsx)(t.h4,{id:"to-install-a-plugin",children:"To install a plugin"}),"\n",(0,r.jsxs)(t.p,{children:["On a computer that is connected to the internet, download the ",(0,r.jsx)(t.code,{children:".whl"})," file from the plugins webpage on PyPI. Then, connect that computer to your Pioreactor's local access point's network. To each Pioreactor you wish to install the plugin on, transfer the ",(0,r.jsx)(t.code,{children:".whl"})," file to the Pioreactor (using SFTP or FTP). Then, run ",(0,r.jsx)(t.code,{children:"pio plugins install Your Docusaurus site did not load properly.
\nA very common reason is a wrong site baseUrl configuration.
\nCurrent configured baseUrl = ${e} ${"/"===e?" (default value)":""}
\nWe suggest trying baseUrl =
\n.comment
can become .namespace--comment
) or replace them with your defined ones (like .editor__comment
). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll
and highlightAllUnder
methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(29901),a=n(39642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(16500).resolve(t)],delete Prism.languages[e],n(16500)(t),o.add(e)}))}i.silent=!1,e.exports=i},96854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;ld.reach&&(d.reach=O);var I=k.prev;if(R&&(I=l(t,I,R),S+=R.length),u(t,I,C),k=l(t,I,new a(p,h?r.tokenize(A,h):A,v,A)),N&&l(t,k,N),C>1){var D={cause:p+","+m,reach:O};i(e,t,n,k.prev,S,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a {const o=t.toLowerCase(),i=((e,t)=>{const[n,r]=(0,c.useState)(G(t,e)),a=(0,c.useRef)(),o=(0,c.useRef)();return(0,c.useEffect)((()=>{t===a.current&&e===o.current||(a.current=t,o.current=e,r(G(t,e)))}),[e,t]),n})(o,r),s=(e=>(0,c.useCallback)((t=>{var n=t,{className:r,style:a,line:o}=n,i=E(n,["className","style","line"]);const s=_(S({},i),{className:(0,d.Z)("token-line",r)});return"object"==typeof e&&"plain"in e&&(s.style=e.plain),"object"==typeof a&&(s.style=S(S({},s.style||{}),a)),s}),[e]))(i),l=(e=>{const t=(0,c.useCallback)((({types:t,empty:n})=>{if(null!=e)return 1===t.length&&"plain"===t[0]?null!=n?{display:"inline-block"}:void 0:1===t.length&&null!=n?e[t[0]]:Object.assign(null!=n?{display:"inline-block"}:{},...t.map((t=>e[t])))}),[e]);return(0,c.useCallback)((e=>{var n=e,{token:r,className:a,style:o}=n,i=E(n,["token","className","style"]);const s=_(S({},i),{className:(0,d.Z)("token",...r.types,a),children:r.content,style:t(r)});return null!=o&&(s.style=S(S({},s.style||{}),o)),s}),[t])})(i),u=(({prism:e,code:t,grammar:n,language:r})=>{const a=(0,c.useRef)(e);return(0,c.useMemo)((()=>{if(null==n)return X([t]);const e={code:t,grammar:n,language:r,tokens:[]};return a.current.hooks.run("before-tokenize",e),e.tokens=a.current.tokenize(t,n),a.current.hooks.run("after-tokenize",e),X(e.tokens)}),[t,n,r])})({prism:a,language:o,code:n,grammar:a.languages[o]});return e({tokens:u,className:`prism-code language-${o}`,style:null!=i?i.root:{},getLineProps:s,getTokenProps:l})},ee=e=>(0,c.createElement)(J,_(S({},e),{prism:e.prism||T,theme:e.theme||U,code:e.code,language:e.language}))},788:(e,t,n)=>{"use strict";function r(e){var t,n,a="";if("string"==typeof e||"number"==typeof e)a+=e;else if("object"==typeof e)if(Array.isArray(e))for(t=0;t Your Docusaurus site did not load properly. A very common reason is a wrong site baseUrl configuration. Current configured baseUrl = ${e} ${"/"===e?" (default value)":""} We suggest trying baseUrl = d.reach&&(d.reach=O);var I=k.prev;if(R&&(I=l(t,I,R),S+=R.length),u(t,I,C),k=l(t,I,new a(p,h?r.tokenize(A,h):A,v,A)),N&&l(t,k,N),C>1){var D={cause:p+","+m,reach:O};i(e,t,n,k.prev,S,D),d&&D.reach>d.reach&&(d.reach=D.reach)}}}}}}function s(){var e={value:null,prev:null,next:null},t={value:null,prev:e,next:null};e.next=t,this.head=e,this.tail=t,this.length=0}function l(e,t,n){var r=t.next,a={value:n,prev:t,next:r};return t.next=a,r.prev=a,e.length++,a}function u(e,t,n){for(var r=t.next,a=0;a/g,(function(){return n})).replace(/*\/?)?>/.source),e.languages.jsx.tag.inside.tag.pattern=/^<\/?[^\s>\/]*/,e.languages.jsx.tag.inside["attr-value"].pattern=/=(?!\{)(?:"(?:\\[\s\S]|[^\\"])*"|'(?:\\[\s\S]|[^\\'])*'|[^\s'">]+)/,e.languages.jsx.tag.inside.tag.inside["class-name"]=/^[A-Z]\w*(?:\.[A-Z]\w*)*$/,e.languages.jsx.tag.inside.comment=t.comment,e.languages.insertBefore("inside","attr-name",{spread:{pattern:o(/.comment
can become .namespace--comment
) or replace them with your defined ones (like .editor__comment
). You can even add new classes.",owner:"dvkndn",noCSS:!0},"file-highlight":{title:"File Highlight",description:"Fetch external files and highlight them with Prism. Used on the Prism website itself.",noCSS:!0},"show-language":{title:"Show Language",description:"Display the highlighted language in code blocks (inline code does not show the label).",owner:"nauzilus",noCSS:!0,require:"toolbar"},"jsonp-highlight":{title:"JSONP Highlight",description:"Fetch content with JSONP and highlight some interesting content (e.g. GitHub/Gists or Bitbucket API).",noCSS:!0,owner:"nauzilus"},"highlight-keywords":{title:"Highlight Keywords",description:"Adds special CSS classes for each keyword for fine-grained highlighting.",owner:"vkbansal",noCSS:!0},"remove-initial-line-feed":{title:"Remove initial line feed",description:"Removes the initial line feed in code blocks.",owner:"Golmote",noCSS:!0},"inline-color":{title:"Inline color",description:"Adds a small inline preview for colors in style sheets.",require:"css-extras",owner:"RunDevelopment"},previewers:{title:"Previewers",description:"Previewers for angles, colors, gradients, easing and time.",require:"css-extras",owner:"Golmote"},autoloader:{title:"Autoloader",description:"Automatically loads the needed languages to highlight the code blocks.",owner:"Golmote",noCSS:!0},"keep-markup":{title:"Keep Markup",description:"Prevents custom markup from being dropped out during highlighting.",owner:"Golmote",optional:"normalize-whitespace",noCSS:!0},"command-line":{title:"Command Line",description:"Display a command line with a prompt and, optionally, the output/response from the commands.",owner:"chriswells0"},"unescaped-markup":{title:"Unescaped Markup",description:"Write markup without having to escape anything."},"normalize-whitespace":{title:"Normalize Whitespace",description:"Supports multiple operations to normalize whitespace in code blocks.",owner:"zeitgeist87",optional:"unescaped-markup",noCSS:!0},"data-uri-highlight":{title:"Data-URI Highlight",description:"Highlights data-URI contents.",owner:"Golmote",noCSS:!0},toolbar:{title:"Toolbar",description:"Attach a toolbar for plugins to easily register buttons on the top of a code block.",owner:"mAAdhaTTah"},"copy-to-clipboard":{title:"Copy to Clipboard Button",description:"Add a button that copies the code block to the clipboard when clicked.",owner:"mAAdhaTTah",require:"toolbar",noCSS:!0},"download-button":{title:"Download Button",description:"A button in the toolbar of a code block adding a convenient way to download a code file.",owner:"Golmote",require:"toolbar",noCSS:!0},"match-braces":{title:"Match braces",description:"Highlights matching braces.",owner:"RunDevelopment"},"diff-highlight":{title:"Diff Highlight",description:"Highlights the code inside diff blocks.",owner:"RunDevelopment",require:"diff"},"filter-highlight-all":{title:"Filter highlightAll",description:"Filters the elements the highlightAll
and highlightAllUnder
methods actually highlight.",owner:"RunDevelopment",noCSS:!0},treeview:{title:"Treeview",description:"A language with special styles to highlight file system tree structures.",owner:"Golmote"}}})},2885:(e,t,n)=>{const r=n(29901),a=n(39642),o=new Set;function i(e){void 0===e?e=Object.keys(r.languages).filter((e=>"meta"!=e)):Array.isArray(e)||(e=[e]);const t=[...o,...Object.keys(Prism.languages)];a(r,e,t).load((e=>{if(!(e in r.languages))return void(i.silent||console.warn("Language does not exist: "+e));const t="./prism-"+e;delete n.c[n(16500).resolve(t)],delete Prism.languages[e],n(16500)(t),o.add(e)}))}i.silent=!1,e.exports=i},96854:()=>{!function(e){function t(e,t){return"___"+e.toUpperCase()+t+"___"}Object.defineProperties(e.languages["markup-templating"]={},{buildPlaceholders:{value:function(n,r,a,o){if(n.language===r){var i=n.tokenStack=[];n.code=n.code.replace(a,(function(e){if("function"==typeof o&&!o(e))return e;for(var a,s=i.length;-1!==n.code.indexOf(a=t(r,s));)++s;return i[s]=e,a})),n.grammar=e.languages.markup}}},tokenizePlaceholders:{value:function(n,r){if(n.language===r&&n.tokenStack){n.grammar=e.languages[r];var a=0,o=Object.keys(n.tokenStack);!function i(s){for(var l=0;l