Monday, March 25, 2024

2024-03-23 - File Server Samba (SMB) Login Script

 I was talking to my instructor, Doug,  about how I want to give access to my file server to various computers around my apartment so roommates can watch things downstairs, my mom can use it at her apartment, and so on. But people often accidentally delete things. I know I do this on occasion. I find every once in a while that files are missing and so either I deleted them or there is something happening in file transfers that I cannot nail down. So I would like a way to write protect and or remove write privileges except for when I decide and I can just make sure that nothing happens that I am not intending. 

    Doug talked about different user accounts, one for my mom and one for me so when we built my file server, I created two accounts, one for me with write privileges and one for her without. And if she wants a change, I can just do it for her since she doesn't know how to do it anyway. She can use the files but copy and paste are sorcery as far as she is concerned. Since I care about what happens to the contents I go through the trouble to put on there, I am fine with just being the one that takes care of all that myself. 

    I talked to Doug about other solutions too but Linux is different from how Windows works, and I don't even remember what those conversations were about except that I was surprised that Linux didn't do this or that thing that I am so used to doing on Windows, or at least knew Windows could do. No need to defend Linux, I am sure Linux has features that Windows does not, I am just totally unaware of what they are. 

    I suppose this is a good time to also mention that unlike Windows, Linux has no Recycle Bin. If you delete a file, there is only one protection to stop this action if you catch yourself in time. There is just a dialogue box asking if you are sure you want to delete the file. In Windows this used to be a thing but since Windows 10 I think, it has been optional and I always turn it off with the peace of mind that it is simply moved to the Recycle Bin and if I realize my mistake later, I can recover it. 

    But Linux has no such protection. There is just that dialogue box. I don't remember this conversation with Doug all that well either when he revealed this shocking news to me, but I asked him why every time I delete a file from Windows, even though I have that "Are you sure" dialogue box disabled, I need to sift through files and delete them quickly because I am sifting through thousands of files manually, so the dialogue box really slows me down and plus I am thinking like, what is going on, this option is turned off on my desktop? 

    Doug informed me that because of the way I was deleting the files, this was actually Linux doing this, and I don't remember what way that was, but this was the protection from Linux. And I was like yeah, but why aren't the files then also moving to my Recycle Bin? And he was like, because this is Linux. 

    And I was like, yeah, I know the file server is running Linux, thanks Doug, now back to why the pictures aren't moving to the Recycle Bin. 

    And he starts to subtly smile at this point every time while sort of jokingly being condescending while explaining again, that because this is Linux, there is no Recycle Bin. 

    Huh? This makes no sense! 

    He says sure it does, you're doing this through a method where Linux's safeguards take effect, and these files are located on Linux, so when you delete something, there will be just that dialogue box and once deleted, they will not be moved to the Recycle Bin. 

    Wait, what? Why not?

    Because this is Linux, and Linux does not have a Recycle Bin?

    What manner of barbarism is this? Linux has no Recycle Bin? Well, what happens if you accidentally delete a file?

    That is why there is the dialogue box. 

    That's it?! That is all the protection you get? You mean I was deleting files because I had a trigger finger and that is why when I went to my Windows Recycle bin, there was nothing there? 

    Yes. 

    Long face, jaw on the floor. Dude, seriously... ... ...

    Okay so I will just continue with the lesson for the Fundamentals students. He starts to turn and does something like explaining how the print command puts the code you just created onto the screen in a shell like this is some incredible magic trick. 

    Wait Doug...

    He ignored me. My mind was blown. To be honest, this conversation didn't actually completely go down this way, it was the beginning of class and people were still arriving. But this is the sort of thing that happens with some regularity. I let the newer students think I am stupid and then somehow they get this idea I actually know a lot. C'mon guys, I just unearthed a major discovery that apparently most of the planet already knows...Linux has no Recycle Bin!

    I am sure I inserted some sort of comment in there somewhere in my conversation with Doug saying, and this is the OS that you insisted we should use for my file server?!

    Yes, Windows Server would have costed a thousand dollars and Linux was free. 

    Yeah, anyway, so that conversation was like six months ago or something like that. But about a month ago, I told him yeah okay, lets create more users. I want a read only user so I can put that on the computer downstairs in my living room where my roommates can do whatever they want except delete files. Hey, wait, is there a way to limit what files they have access to? 

    This was another conversation that we had which ended in my being stunned because there's no way to just have one iteration of files in a place where access is limited. Either I need to just have those files by themselves separated from the others for just that user I guess, or something like that, or I need to have two iterations of the same files, which I don't really want to do. I wonder if I can do file shortcuts? Oh wait, no I think that is also something Doug might have said we cannot do. Because if I could create another directory so to speak, just another file tree right next to the file tree with the actual file and then made shortcuts of all those things in the second tree, then I could partition off those for that user and have read only access and all that crap, and also, not have to have multiple iterations or files in different places. 

    I have to ask Doug. He will probably tell me to just do research. Well, he might just answer in the interest of time. 

    Okay, so a month ago we had the idea that we could create multiple users that access all the same files but one would be read only and one would be normal access. And I told him, the only thing I don't like about this is that it would be tedious to log into one to use it, log out and then in again to another to change something, even one small thing, log out again, log back into the other just to use the file without the risk of accidentally deleting it and so on. You could see how this might get tedious at the speed of light. 

    Doug was like, well, there is a way to make that process simpler, it just involves a solution that you might not like, but knowing you, you may be fine with it. We could create a script that logs out of one and into the other, and another script that logs out of that one again and into the first one again. So one to go from 1 to 2, and then one to go from 2 back to 1. That way I get write protections but it's not tedious to the nth degree. The catch is that you have to insert the passwords into the scripts so that it works if you don't want to have to retype the password every few seconds. Done, lets do it Doug! I just have to make sure that no one ever finds these files. That's all! 

    We went through a few iterations of trying to get these scripts to work. We got them to a strange point where they seemed to work if we copied the scripts into the CLI directly, but if we ran the same exact commands as a script, they absolutely would not work. 

    We inserted a delay command for a few seconds in the beginning of the script because Doug thought that perhaps it needed time to log out of the server and wasn't getting enough of a buffer between that and logging into it with another user. 

    Then we tried pausing at the end of the script, and then also adding the exit command. Neither of us remembers why we tried these things. I personally recall that we tried like twenty different things, working on this after class had ended for like a half hour to forty five minuets because Doug just needed to know why this wasn't working and finally ran out of time to solve it. 

    We pasted it in several times and we can't remember what was going on here because it only worked when we pasted it in. It worked that way for both scripts but if you ran the scripts, neither of them worked. 

    Now a few weeks later, I had a scenario at home where I actually needed to use the scripts to log in and out of SAMBA and since pasting the scripts into the Shell worked fine but not running the script, I tried pasting. But now, pasting didn't work either. What is going on. I brought it back in to Doug to see if we could resolve the new added problem. This strikes me as strange because all of the sudden, the actual problem stopping the scripts from working revealed itself but not the reason pasting the script into the Shell was working before and not now. 

    So I grabbed Doug at the end of class to see if he could resolve this issue because I couldn't figure it out. I am not proficient at writing scripts in the first place, let alone writing any code. So this was completely beyond me why this wasn't working. And I was explaining to Doug that pasting was working before when we were trying to troubleshoot the two script files and then that stopped too when I got home so I opened both scripts to edit them in notepad and opened a Shell, whichever one I am not sure, CMD Admin, PowerShell (PS), no idea what I had opened each of these different times, but according to Doug this doesn't matter because "net use" is a CMD command, and will run in PS but because it is a CMD command and not a PS command, it's sort of like PS will use CMD to run the command. So it follows the CMD rules so-to-speak. 

    We pasted the two scripts into the Shell and all of the sudden, Doug realized something he didn't realize last time. The emoji that Jack in class told me like six or so months ago to include in the file path for my server, the skull and crossbones emoji, which was added initially as a joke, I was trying to be cool and said yeah sure lets keep it. And it has caused problems ever since because anytime I need to type it in I have to go online and fine the emoji and depending on what OS you're on, emojis display different, so my iPhone would display the same one a slightly different way that confused me and caused me to think it was the wrong emoji for a while six months ago when connecting my phone to the server, and then now, with the log-in and log-out scripts, turns out CMD does not recognize emoji characters because it runs using Ascii, while PowerShell runs on Unicode. 

    Just for a refresher or whatever, Ascii is an older standard and only has like 128 characters or something. But Unicode is newer, and there are many types too, and it has new characters added to it all the time. It has hundreds of thousands. 

    In talking about this, Zack and Doug started debating how many characters there were. I swear we're not geeks!

    The finalized versions of the two scripts are as follows, for the script to delete the READONLY log-in and log into the regular user with all privileges:


"net use /delete S:

net use S: "\\192.168.XXX.XXX\KeepOut" /USER:biff (password here)"


Then the script for logging out of the regular user with privileges and back into the READONLY user:


"@echo off

net use /delete S:

net use S: \\192.168.XXX.XXX\KeepOut /USER:readonly (password here)

exit"


    We had forgotten to delete the exit command at the end of the second script before I wrote this blog. Both scripts now run great! 

This has been Truncat3d 00000000111100010100110______________end of line

Friday, March 22, 2024

2024-03-22 - GPD Pocket 3 laptop touchpad typing issues

    I have had the GPD Pocket 3 laptop for a year. It's been a great laptop. Can fit in my pocket literally, but would cause my sweat pants to fall right down. There is one problem with it that I have been struggling with for this whole past year and finally, while in a phase where I am typing quite a bit lately, it has started to drive me nuts. Apparently this problem plagues all Pocket 3 users, I looked it up. 

    If you observe, the touchpad is above the keyboard and to the right. This seems like a great placement for such a small laptop designed to be able to be used with two hands, and it does work quite well that way. But if you type with it, you will quickly discover that every few minutes while typing, the cursor gets clicked somewhere else on your document and without you're noticing until it's too late, you have been typing everything in the wrong place and it's frustrating to find where you were, where it's typing now, and how far back to cut the text to reapply it where it was meant to be typed. And it always chops off a few of the first characters of text when this happens too, so you have to make sure to retype that word that you were typing when it happened. To me, this happens every five minutes. 



    It's always funny when you take on an assignment to get better at something like troubleshooting, to then need your instructors help because you're stumped, just to have him say, well...troubleshoot it! 

    I have searched this problem a number of times. I I didn't find the answer any of those times because the option they refer to isn't on my Windows 11 Home edition laptop. This option that is referred to by countless people online is firstly, to just press the function key with the button meant to turn the touchpad off, which the Pocket 3 doesn't have. And then they refer you to an option in Settings > Devices > Touchpad > and look for an option that says "Turn off touchpad when USB mouse is plugged in". Well, it ain't there! I have checked. About twenty times. I keep thinking I must have navigated to the wrong place or something, but there is no selection on my laptop for the touchpad. And the devices menu in Win11 isn't Devices anymore, it's Bluetooth and Devices. So this caused me to do a lot of extra searching just in case every time I looked. 

    Then I finally found an option online to disable the touchpad in Device management and a couple other places too, where access to managing devices is available. But I didn't see anything for a touchpad in Device Management. I looked at the drivers for a while and checked a video online of how someone else did it, and I finally thought okay, it has to be this HID-Compliant Mouse option under the mouse tree within Device Manager. 

    I thought, well, if I screw something up, I can always use my USB mouse to try and restore it, and the screen is a touch screen too, so I think I will be okay if I test this. So I right clicked and selected disable device. It disabled. The touchpad was no more. I was satisfied that the main problem is resolved but I would far prefer to keep it enabled and only disable it if I have a mouse plugged in. There will be times when I don't have a mouse. 

    I looked and looked and looked some more. I found instructions that troubleshooted the problem, said firstly to check to make sure the OS is updated, there may be something that would be fixed by an update. I didn't actually think this would solve it. 

    I am not exactly a huge advocate of updating fixing everything. People just always turn to that so you have to update to the latest thing regardless of what you want just so that can be eliminated even though I have seldom actually found that to be the solution. In fact, I don't think that has ever been the solution in y case. Yes yes yes, you need to do it for X, Y and Z reasons. Okay I covered myself, now you know the reasons why you should update whenever there's an update available. 

    seems the only reason everyone insists that you update is because it's the next thing on the list. And people are sooooo sure that will fix it. Just happened with Wells Fargo last week, had a problem with the app and they insisted updating my phone OS would solve it. I told them it would take a few days to make sure everything is backed up to my satisfaction, so the call ended and the next day the problem just went away. I never updated the OS. Seems to me each next update uses more battery life. I don't often find the updates are anything to write home about anyway. 

    Write home about...unless I'm in a serious relationship with the OS on my phone, I probably shouldn't be writing home about it at all. No wonder why people think I'm weird, they think I'm...yeah anyway. 

    I turned to Doug after looking through this for a while and he took one look at the menu with Bluetooth and Devices, then through the devices in the list and there was a section for the touch screen and a section for the mouse, and another for the keyboard but not one for the touchpad.  He immediately suspected no drivers were installed. We went to Device Manager and he was like yeah, HID-Compliant Mouse, it's not a mouse, it thinks it's a mouse. He then went looking for drivers and asked if I had installed any drivers from GPD. No. It never occurred to e to do such a thing. I've never bought a new laptop before, or a desktop built by a company. Every computer I have used was either twenty years old or I built it myself. Never went to Dell to install drivers for example. I sort of just thought that stuff just comes pre-installed on the device, you know, like bloatware. 

    Reminds me of the scene in Odd Couple, the 1968 movie, where people are coming for dinner and the meatloaf came out early so Oscar asks Felix if he can keep it warm by pouring gravy on it and Felix is like "Gravy? What gravy?" 
   "Don't you have any gravy?"
    "Where the hell am I gonna get gravy at eight o'clock?"
    "I dunno, I though it comes when you cook the meat."
    "Comes when you cook the meat. You don't know what you're talking about, Oscar. You just don't know, because you have to MAKE gravy, it doesn't just come when you cook the meat!" 

    Great movie. Anyway, we found a site for GPD Pocket 3 firmware and it led to a Google Drive with a bunch of zipped files, and Doug was like, man these guys are a small company. I think he asked if I trusted this and I was like, wait, is there any reason I shouldn't? 

    We downloaded them and I was able to unzip one of them and the other just kept erroring out. That was tge one for the touchpad, which was the one we really wanted. So, I am happy to say that this is now unresolved. Good luck everybody!

This has been Truncat3d 00000000111100010100110______________end of line

Tuesday, March 5, 2024

2023-11-02 - File Server / Pi Hole / Pi VPN All-In-One

  •  Showed my mom who I intend to share file server with this really cool thing that's replacing all of our free, low memory, only-3-device-per-account Dropbox accounts. I parked in her apartment's parking lot because her computer set up is messed up. I used my iPhone as a wireless hotspot, loaded up my laptop, turned on my VPN, accessed my file server, showed her her user folder and then showed her mine, I started playing a video off of it to show her how cool this was that I did not have this on my laptop but was grabbing it from home and playing it here in her parking lot. But it buffered. 
  • decided I wanted to start thinking about how to improve the bandwidth of my network set up through my VPN, which currently uses a Pi Zero Wireless without an ethernet adapter to get the most out of it. I have a USB 2.0 to ethernet adapter for my Pi Zero, but its not going to give me that much bandwidth over USB 2.0. I've never seen speeds above about 30 Mbps and Doug said basically half that for both the up and down speeds together at the same time and its roughly the 13 Mbps down that I was already getting. 
  • I thought about buying a Pi4 for an upgrade. Was going to install it on my old laptop which would surely be able to handle the load and although its an old ten plus year old laptop, it has 1Gbps ethernet. But I didn't want to lose my windows install because every once in a while it is useful to have a separate device other than my desktop or laptop. I thought about doing a VirtualBox with Linux installed with Pi Hole running on that and Doug recommended against it. Better to have it running directly on the metal than a number of layers away from it. And I think he might have said something on another topic about my server, and I had already found that basic Linux can run Pi Hole, it doesn't have to be Raspbian. It just has to be most versions of Linux. And then my eyes widened. Can my server do the pi hole and pi VPN? He said yes. So here we are. File server part two except its not file server its really just all in one now. 
  • I fugure I've done this already so this shouldn't be very hard. Turns out because Doug has been having me focus more on what the commands I type in Linux mean, rather than just looking them up because I have particular ideas about how I want my set up to work, so I should know what commands to use. So now that I am putting a more granular focus on each thing im doing, its like I have done this already but if you were working with me tonight on project day in class, you would probably ask, have you done this before? I would say yes and you would be like, then why don't you know what to do here, and there, and in this thing over here? And I would say, well because last time I just ran through it. I can do it but it would be like installing windows on a new machine and not changing your wallpaper, or setting times for virus protection to scan that bothers you the least like at night or something, and not setting power settings like when to sleep, hibernate, turen the screen off, so on, not setting screen savers, not installing the particular picture viewing, video or audio file playing or internet browsing applications you would prefer to install. So the route im taking this time guarantees i know how to get the particulars that I want without help this time. 
  • I actually started the process without talking to my instructor at all. I started with updating linux, then upgrading linux. Then I installed curl, which I do not remember doing last time at all. I would have eventually learned that most likely. I installed curl, then I used the pi hole curl command again, and I only stopped and restarted like eight times because I wanted to record every screen that asked me a question so I could know every detail this time. 
  • Then a classmate named Ronald was looking at class project tickets and saw mine that I had juts posted and was thinking about doing it. But then I told him hey yeah thats mine. So he joined me and I explained everything. He eventually had to go back to doing his own thing. 
  • When at the end of asking a bunch of questions, it gave me that password that you need to log into the Pi Hole web interface, which you must record if you want to access it at all and maintain it or anything, I recorded it and then Doug was like, oh yeah hey, lets change that password now. So we typed "Pi Hole -a -p". he recommended I just use the same password for the web server Pi Hole interface as last time so I just grabbed the same password for less confusion since after all, there is a lot of encryption before this password already, and I'm literally just replacing my Pi zero with this new configuration. 
  • I entered my servers IP address into my web browser and it gave me a placeholder page for my query.
  • Doug got passed this instantly however, by adding "/admin/" to the end of it. and we got the Pi Hole web interface page. 
  • i logged into the new Pi Hole web interface and added the blocklist project stuff to it, i changed the DNS server address in my router to my servers IP address. then i installed PiVPN.
  • I had lots of questions for Doug in this process because this part was sort of expedited for me last time. Just say yes and click default a lot, doug said. 
  • PiVPN is isntalled. All my devices are now using my Pi Hole as the DNS server. But I am not using the VPN I installed yet. 
  • I need to go pivpn -a to add devices and I need to reconfigure my router, not my roommates router, to point the port forward towards my server instead of my raspberry pi Zero. 
  • then I need to configure the two different kinds of vpn tunnels for different purposes (half tunnel and full tunnel)
  • So I've been needing to ask Doug about this for a while and even on multiple blod posts and finally we got to it now. So, here's the deal. When you use WireGuard, you can set what the sllowed IP addresses are. What this means is if you have it set to default which is just a bunch of 0's and colins and a couoke of slashes and another 0, this is CIDR notation, which is shorthand for sayong all IP addresses are allowed, because /0 means none of the bits in the IP address are locked down. If you have all allowed IP addresses like in the case of entering a /0, this means that everything, every single query from the device will be put through the VPN tunnel, which means you have a full tunnel. All of the data will go out from my devices to the internet through the VPN, to my server that's hosting the VPN, and say it's a google query, then it will then travel out of my server and network back to the internet ot do the actual query, the results will then be sent to my server, and then those results will be sent back through the VPN from my server to my devices that performed the query in the first place. So if you have a half tunnel, you will then specify the private network that your VPN server is on, so the whole range for that subnet that your server is on, and then the whole subnet range that the VPN will be using to route traffic over the virtual network it is creating for your remote devices. The VPN acts like another router in your network that then has all the remote devices connected to it. 


This has been Truncat3d 00000000111100010100110______________end of line

2024-03-05 - Raspberry Pi Weather Display Project

 I decided I wanted an always-on display in my room that tells me the weather so I can just glance at it and know to grab my coat or if it's okay to let my cat out or when I should let her out. I talked to my instructor, Doug, about this and he told me that he wanted me to create a proposal / plan, which I will go over with him before I start the project. This has various benefits, including avoiding scope creep, which is a major problem when doing projects. 

 To explain scope creep, basically you get an idea for a project you want to do, and say you're doing this just for yourself, it's not official and all that so you just plunge forward and try to figure out how to do this. And you might have to go for a while before you figure out how you're going to do it, you might initially guess that it won't cost more than X amount, and you're fine with that, but as you do the project, or try to, you get caught up in other things, maybe you don't feel like tackling a certain problem just then, you put it off, all sorts of things happen. And then you finally start getting the parts and / or tools you need for the project, it turns out it costs more than you initially thought. And it's taking longer than you thought it would. And then before you finish, you suddenly decide that you want this or that feature added and you think well, it's only going to add another few weeks to the plan, just for it to take another month or so. And then before you know it, you have scope creep. 

Scope creep is a thing that companies want to eliminate, cost overruns, time overruns, all sort of things. And so they have the project manager or whoever create a proposal. This states what the project is, what it's benefits are, how long it is estimated to take, how much will it cost, and this plan or proposal has to be followed carefully because if there are any changes like you get halfway through it and realize, well, we need this feature, the higher-ups can then decide by looking over the revised plan, if they want to go through with it. The initial plan or proposal also lets them decide if they want to even bother with this project in the first place. Do we want to spend X amount of dollars, have our guys spend X amount of time doing this instead of other things that are needed, do we really need or want this benefit? 

So I am creating a proposal...or plan. Even Doug forgot what it's called, lol. I'm sitting here thinking he does these all the time because he works like three other IT jobs while teaching at MTEC. But I forgot what he called this and I barged in on the middle of his lesson to a few newer Fundamentals students so I could ask what he called it and he sat there for like thirty seconds tripping over what I was asking him. He mumbled and fumbled for a bit and said like five different words that didn't sound right, then he said plan, and then proposal and said, "Proposal, I like that one, let's go with that one!" 

THE BASIC IDEA 

-To have a device with a small always-on screen so I can have the weather displayed at all times so I can know if it is raining / snowing, is it too cold to go without a coat or to let my cat outside. I want this and have a desire for it other than just learning. I want to either get a raspberry Pi 4 because there's cool open frame Pi tower case I want for it to put this on. Alternatively it might be able to fit snugly on my Ubuntu File Server and I can somehow attach a display to it that's just for displaying weather data. 

I want to learn with this, however, it needs to be simple enough to complete within a reasonable period of time, no month after month unable to progress situations. 

WANTS / NEEDS

-It needs to be reasonably low power, this includes the screen but I am not currently decided on the size of screen, whether it has color or not, or graphics or anything like that. 

-The cost needs to be front loaded and back-end free. 

-Having a small device on my computer cabinet the size of a Pi that plugs in via ethernet is fine. 

-I don't mind having options, graphics, I don't mind if the device is fancy.

-I want to use this to know if I need my coat or if its snowing or raining or if its too cold for my cat.

-I do want the screen to display temperature constantly and basic weather like "windy" in one word, or "snow" or "rain". It can be more than one word but the point is that it doesn't have to be super detailed but detail is fine is possible and easy to read / implement.

DO NOT WANT:

-No continually paying for services monthly to keep it working, any resources it uses that are provided by other services need to be free of cost. Including the API's I will use. 

-I don't want this to take multiple months to accomplish or require long recesses. 

-I want to learn in the process but I don't want to have to learn all of how to program in Python in order to do this. I want to learn but within reason. 

-Do not want to set up a weathervane on my roof or sensors outside my window if I can more simply just get what I want from the internet for free.

-I don't want to have to press a bunch of buttons or turn things on or off to get the information i want, I want to be able to glance at this screen while getting ready as I run out the door--just so I know if I need my coat every morning. 

-

THE GOAL

-Looks like a screen with a little device attached to the back that runs the project. Ideally there'd be a case for the Pi and the screen, and I can just plug this in to ethernet and power, or plug in a USB wifi dongle and power. 

THE PLAN

    I Looked up projects on GitHub where others had done the same thing and basically did all the work for me. This is important because I want to learn but not actually reinvent the wheel. The confidence in my ability to do stuff like this without someone standing over me making sure it went well while getting something cool I want to make my life easier is what's desired here. 


    2024-03

    Okay, I don't know if that actually resolves the issue with the...plan? Proposal? Whatever. If my instructor is going to give me this assignment it should probably not be beyond him what exactly it's called or how to do it. I really did assume that because he works multiple IT jobs that surely, he knows all about this and has done it countless times. Nope! I strangely have this idea that he is more proactive than his typical co-worker that doesn't challenge themselves much and now I am learning that this just isn't a thing where he has worked. And he'll read this, laugh, and then turn to me and say "Okay, blaw blaw blaw excuse excuse excuse" and then I will pretend to rewrite this section. 

    It's fine, he can only get me kicked out of the program, no big deal!

    So, I looked through GitHub weather station projects others had done and pasted. This one guy posted something that looked really cool and I started to drool, and then realized I was scope creeping already and I haven't even finished writing the proposal yet by this point. But I reigned it back and thought, no I don't need that, then found this other guy that seemed to pretty much do exactly what I wanted already. And it was better because the screen was an E-ink display. So when I turn the lights off, this thing won't be lighting my room. All of my other strip lights and stuff will take care of that. Basically, the lights are always on in my room, just to varying degrees of dimming. Darkness? Where we're going, we don't need darkness! 

    Okay, so I was going through this guys parts list and found the E-ink display he was going to use and I thought it was really cool, it was even like seven and a half inches. I was like, perfect, not too small! And then I went on Amazon to see if I could find it and it turned out that Amazon doesn't carry it. This thing is made internationally, I would have to buy it from Europe and convert to Pounds and all that. Nope, I am sure Amazon has something more local that will work fine. I found something that was almost the same and used an SPI connector, looks like what a Pi would use, usually to connect cameras. Doug and I both looked at it and I was willing to take the chance and buy it to see if it worked. He said yeah, that's the only way to know. I got it in the mail today. 

    I was also thinking a few weeks ago, I should get a Pi, and I had a Pi Zero 2W, which is what my initial Pi Hole installation was on and it worked great except for bandwidth when I got my file server going. After this, I saw no reason to keep it so when new Fundamentals students came in like three months ago or whatever, they were all like, you know how to build a Pi Hole? Wo! ...What is a Pi Hole anyway? So we decided for project day one Thursday, and since I was SCRUM Master that month, which meant I had to hold their hands and make sure they did projects and stayed busy, I guess I will reluctantly stop what I'm doing and help them and make a Pi Hole. But Chey felt he could afford to buy his own Pi and Jayden had no money. Chey wasn't sure if he would have a Pi by the next Thursday when we were slated to do this, so I asked them if either of them wanted my Zero 2W and Chey said he could get his own and Jayden was like, yeah okay, I'll take it. So I brought in all the stuff I had for it and gave it to him. 

    Fast forward a few months, he never finished the project because he never did the port passthrough on his router until the last time I saw him a few weeks ago, when he withdrew himself from the program because he was having a tough time outside of class. And only a month ago did I discover that I would have liked to have simply been able to use my Pi Zero for this project. I just started paying for a trainer, which is expensive, and that took up most of my play money so if there was some way to not have to pay the $22 to purchase, pay tax and ship the device over a few weeks, and then another $10 for the same case I bought the first time, and any other parts I would want to buy besides the screen, I was sort of not looking forward to this. My other purchasing needs have increased since I lost so much of my purchasing power. 

    But then the security guard, the one all the girls are all up in his business the whole time he's clocked in, seriously I don't think he's a hot looking dude, what do these girls see in him? Anyway, hey Owen, just forget the last sentence exists, you are surely a stud...apparently. Well, you get more action than I do anyway. Helps if you talk to 'em occasionally. 

    Yeah so anyway, he came in a few weeks ago with a couple of tackleboxes with all these little boxes full of electronics, Pi's, bread boards, wires, chips, sensors, little tiny screens for things like Pi's. And everything had a little box that it fit neatly into that was repurposed for that thing. He said he had a few Pi Zeros and I suddenly went wide eyed. Oh? Yeah, I have a Zero 2W and a Zero 1, not a W, meaning there's no WiFi. He said he didn't want the second one so if I bought it from him, he'd give me a real good price. We looked up the price and I think they were selling somewhere in the teens, so he was like well, six dollars? I was like, yes please! Hey Doug this can do my weather project right? Yeah. So now I have the Pi and the screen. Just need to figure out the case for the screen and the Pi too if I can help it. I keep thinking about this one project I saw online once where someone cut out an Altoids container and attached a Zero to the inside. And I keep thinking, I wonder if there are any tins like that but that can hold a Pi and a seven and a half inch screen. 

    So update, I bought a paper white screen for one such project I had found online with instructions that does exactly what I want. I also bought a case that came with all sorts of adapters, a power switch, HDMI to mini or micro HDMI, and a USB micro to full size adapter. These became indispensable in order for me to get any work done on my project today, now April 18th. 

    I got stumped because yesterday I was looking at the instructions and thinking fondly of starting the project and the first thing he said was to do SUDO RASPI-CONFIG". But he seemed to skip like twenty steps, he said absolutely nothing about installing an OS. So wait, what OS do I install. I looked and looked and couldn't find anything. I came up with a potential solution to just go ahead and install Raspbian which is now called Raspberry Pi OS or something like that because this project is after all, on a Raspberry Pi device. I think it's a fair assumption. But if I went through all the trouble to get this going just to find out I have to start all over and flash it with another OS like Ubuntu or something, I would be really frustrated. 

    Doug wasn't in yesterday so I couldn't ask him what the deal was. I came in today and told him my idea but he was too busy to comment while working with another student and I suddenly had an idea. I could good what OS that SUDO RASPI-CONFIG command works with and it is probably only going to be Raspbian. It says RASPI in the command. I googled it, I was right. 

    Moving on, I grabbed a USB card reader and a new micro SD card, loaded up Pi Imager and entered the hostname, username, I made them the same just to eliminate any confusion, password, an SSD, I discovered around this point that I have made a grave error in judgement when buying the parts. I can't do anything till I buy a micro USB hub with an ethernet port on it. I gave the one I bought for my other Pi Zero 2W to another student so he could make a Pi Hole because I was so sure I wouldn't do anything with the Pi. I had upgraded to a full blown desktop with way more power that I could install numerous things on. What could I possibly need the 2W for? Well...huh! And I gave him all the stuff that went with the Pi, including the micro USB hub with ethernet. 

    So now since I don't have one, I need one and don't have it. And I looked at my balance and discovered I had to be careful, it was not within my budget to then buy it right now. I thought, well, I can install the OS, there are adapters so I can connect a screen and a keyboard since those are the only available ports, the non-power USB and the HDMI port on the Zero 1 I am now using. 

    Doug provided me with a WiFi dongle and so I grabbed that micro USB to full size USB adapter from the pi case kit I just bought, and used that adapter so I would have WiFi. I had entered the network SSID and password, its a hidden network so I selected the hidden SSID option. And then Doug told me five minutes later that by the way, that WiFi dongle is 2.4 GHz only, so I can't connect it to the network I was going to connect it to because that wireless access point doesn't transmit over 2.4, only 5.0, so I needed to switch the imager settings being flashed to include this other WiFi SSID and password that connect to the same router but do use 2.4 GHz. So I reimaged it to include the other WiFi network instead. 

    I imaged it, I connected it, I was expecting to SSH in, so I had selected for SSH to be enabled, I plugged it in and inserted the card and powered it on. The green light flashed a few times and then stayed on. I went into the router settings in class and checked the WiFi connections for the router that the alternative WiFi network we were using only had about four devices connected to it. One was an IP camera, another was named something definitely not my Pi, and then there were two question marked network names. And in the DHCP listing of all network devices, there were four devices with question marks. I tried SSH-ing into all four of them with my hostname I had given it in the imager and two of them were refused, and one of them didn't respond to requests twice. 

    The keyboard lights were not coming on during this process, so I was wondering about that too. 

    Doug found a USB hub I could plug into the micro USB to type A adapter plugged into the pi, so now we had WiFi, keyboard, and power and screen, I used the HDMI micro to full size adapter and plugged a screen in. It went into a boot loop. Doug was concerned that we were taxing the pi for too much power when using my 1 amp 5 volt power brick for old iPhones. He switched it out for a 2.5 amp brick. That didn't change anything. He also unplugged all USB devices and it still boot looped. I had inadvertently installed the maximized, or full sized version of Raspbian, with the desktop environment that was a couple gigabytes. I reimaged for the lite or minimized version with just the command line interface. That didn't work. Still boot looped. Doug tried various solutions, plugging and unplugging various things to see what it was, and then in case there was something wrong with how I was imaging the card, he tried imaging it on his computer, and finally after twenty minutes he said that he wasn't going to jump right to hardware failure, although, it isn't looking good. It is probably hardware failure. So I would have to buy another Pi and this time, a Zero 2W, and a dongle with extra USB ports and an ethernet port as well, like last time. I don't know what else this could be though, if not hardware failure. He then grabbed the card so he could try a different kind of image. 

    I asked Doug what all the reasons were that a Pi would boot loop and the only thing he said was "power issues". 

    Okay, it finally booted successfully. 

    The mini HDMI to HDMI adapter was interfering with the ability to detect the monitor, so it turned off HDMI output as soon as the computer booted fully.  To fix this, we had to edit the config.txt file that could be found in the root of the boot partition (I did this using File explorer and browsing into the SD card after imaging it).  I added (or uncommented) the following line: "hdmi_force_hotpulg=1"

That forces the pi to output HDMI even if it doesn't detect a monitor.  That fixed it!

    We also determined that the USB hub was drawing too much power from the pi, and also the keyboard lights did start working. 


    Okay, now Monday, we started by soldering the pin holes on the Zero 1 to pins provided by the nifty ten dollar case I bought from amazon that has a micro USB to USB A adapter, a mini HDMI to full size HDMI adapter, and I think it also has a pi on/off switch for the power cord. 

    I had never soldered before so this was a learning experience. Apparently the solder already has flux inside it which cleans the oxidation off the solder. I had been watching Louis Rossman YouTube videos for years where he would just talk about stuff while he would solder a bunch of stuff with a Mac laptop motherboard and use tons of flux. So I was aware of some of this stuff. I just learn better when I do it myself. 

    Doug did about half of the pins for me to show me and to help get me through so the soldering was finished before the end of the class. And then he watched me do a few and left me to finish the rest of them and then came and checked them when I was done. I think there is something like forty pins, he did half, and he only fixed two of the ones I did when I was done. He and I both were surprised to see how quickly I got through it. He was expecting this to take all class. 

    He showed me how you hold the side of the iron to a pin and heat it up and then after a little bit, you sneak the solder in and touch the pin--not the iron with the solder. You want the solder to melt when it touches the pin and then sink into the pin hole on the Pi and cover all the copper all the way around the pin. The metal just sort of clings to the point its supposed to be and then sinks into place. If you did it right, then it sort of cleans itself up in a way, there won't be a mess. I started having problems where I would bring the solder in a few seconds after touching the iron to the pin and then the solder, all of the roll of the solder would then be soldered to the pin. I couldn't figure out what I was doing wrong but Doug explained that that happens when you don't wait for it to heat up more before touching the solder to the pin. 

    The soldering was done and I did my part of it in about fifteen or twenty minutes. 

    I went about connecting the case to the Zero 1 and then connected the Pi to my new micro USB hub with extra USB A ports and an ethernet port. I was so sure that with a Zero, you could either plug the hub I bought, which does do passthrough power, to either the power only micro USB and use the hub to power the Zero 1, or I could connect it to the data port and get the benefits of the extra USB ports and now the ethernet port as well. Doug said that he had both data and power over the same USB on his Zero at home. He had me google if the data and power needed to be activated both at the same time or something and the first thing that came up said that the right port is power only and has no data pins, but the left micro USB port has both power and data pins. So Doug plugged in my hub while plugged into power to the data and power plug, and it worked. 

    I later concluded that I might have been having problems with my Pi Zero 2W before I gave it to Jayden because I was also using one of those Pi on/off switch adapters for the power cord so you don't have to keep plugging and unplugging the Pi to reboot it or just leave it turned off, and so I might have had it plugged into the data/power port with that power switch adapter plugged in, and so I would only get power on one or data on the other, which I would only plug in the data stuff anyway if I wasn't using it as a power switch so I would remove the power switch adapter whenever transferring the hub to the data port. So this explains why it only did data on the data/power port on my Zero 2W, and only did power on the power port. 

    We ran a SUDO APT UPDATE and then a SUDO APT UPGRADE, Doug stopped me before I pressed Y and enter to confirm the upgrades, he asked me what his rule is, "I don't know!" He said, "If it's a capitol Y and a lowercase n, that means you can simply press enter and it will automatically assume you meant the capitalized letter, which is Y. 

PS C:\Users\Christian> ssh user@192.168.1.188

The authenticity of host '192.168.1.188 (192.168.1.188)' can't be established.

ED25519 key fingerprint is SHA256:pyKs4OG3q3jT4nXvzBesQdBDy2BFrjmEI/VfXBeUC8U.

This key is not known by any other names

Are you sure you want to continue connecting (yes/no/[fingerprint])? yes

Warning: Permanently added '192.168.1.188' (ED25519) to the list of known hosts.

user@192.168.1.188's password:

Linux weatherstation 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l


The programs included with the Debian GNU/Linux system are free software;

the exact distribution terms for each program are described in the

individual files in /usr/share/doc/*/copyright.


Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

Last login: Mon Mar 11 19:17:40 2024

user@weatherstation:~ $ sudo apt update

Get:1 http://archive.raspberrypi.org/debian bullseye InRelease [23.6 kB]

Get:2 http://raspbian.raspberrypi.org/raspbian bullseye InRelease [15.0 kB]

Get:3 http://archive.raspberrypi.org/debian bullseye/main armhf Packages [313 kB]

Get:4 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf Packages [13.2 MB]

Fetched 13.6 MB in 38s (355 kB/s)

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

13 packages can be upgraded. Run 'apt list --upgradable' to see them.

user@weatherstation:~ $ sudo apt upgrade

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

Calculating upgrade... Done

The following packages will be upgraded:

  bsdextrautils bsdutils eject fdisk libblkid1 libfdisk1 libmount1 libsmartcols1 libuuid1 libwbclient0 mount rfkill

  util-linux

13 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

Need to get 2,978 kB of archives.

After this operation, 0 B of additional disk space will be used.

Do you want to continue? [Y/n]

Get:1 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf bsdutils armhf 1:2.36.1-8+deb11u2 [139 kB]

Get:2 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libblkid1 armhf 2.36.1-8+deb11u2 [181 kB]

Get:3 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libuuid1 armhf 2.36.1-8+deb11u2 [82.7 kB]

Get:4 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libfdisk1 armhf 2.36.1-8+deb11u2 [226 kB]

Get:5 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libmount1 armhf 2.36.1-8+deb11u2 [193 kB]

Get:6 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libsmartcols1 armhf 2.36.1-8+deb11u2 [144 kB]

Get:7 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf fdisk armhf 2.36.1-8+deb11u2 [178 kB]

Get:8 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf util-linux armhf 2.36.1-8+deb11u2 [1,038 kB]

Get:9 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf mount armhf 2.36.1-8+deb11u2 [177 kB]

Get:10 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf bsdextrautils armhf 2.36.1-8+deb11u2 [138 kB]

Get:11 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf libwbclient0 armhf 2:4.13.13+dfsg-1~deb11u6 [296 kB]

Get:12 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf eject armhf 2.36.1-8+deb11u2 [98.9 kB]

Get:13 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf rfkill armhf 2.36.1-8+deb11u2 [86.6 kB]

Fetched 2,978 kB in 16s (186 kB/s)

Reading changelogs... Done

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../bsdutils_1%3a2.36.1-8+deb11u2_armhf.deb ...

Unpacking bsdutils (1:2.36.1-8+deb11u2) over (1:2.36.1-8+deb11u1) ...

Setting up bsdutils (1:2.36.1-8+deb11u2) ...

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../libblkid1_2.36.1-8+deb11u2_armhf.deb ...

Unpacking libblkid1:armhf (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Setting up libblkid1:armhf (2.36.1-8+deb11u2) ...

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../libuuid1_2.36.1-8+deb11u2_armhf.deb ...

Unpacking libuuid1:armhf (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Setting up libuuid1:armhf (2.36.1-8+deb11u2) ...

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../libfdisk1_2.36.1-8+deb11u2_armhf.deb ...

Unpacking libfdisk1:armhf (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Preparing to unpack .../libmount1_2.36.1-8+deb11u2_armhf.deb ...

Unpacking libmount1:armhf (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Setting up libmount1:armhf (2.36.1-8+deb11u2) ...

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../libsmartcols1_2.36.1-8+deb11u2_armhf.deb ...

Unpacking libsmartcols1:armhf (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Setting up libsmartcols1:armhf (2.36.1-8+deb11u2) ...

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../fdisk_2.36.1-8+deb11u2_armhf.deb ...

Unpacking fdisk (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Preparing to unpack .../util-linux_2.36.1-8+deb11u2_armhf.deb ...

Unpacking util-linux (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Setting up util-linux (2.36.1-8+deb11u2) ...

fstrim.service is a disabled or a static unit not running, not starting it.

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../mount_2.36.1-8+deb11u2_armhf.deb ...

Unpacking mount (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Preparing to unpack .../bsdextrautils_2.36.1-8+deb11u2_armhf.deb ...

Unpacking bsdextrautils (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Preparing to unpack .../libwbclient0_2%3a4.13.13+dfsg-1~deb11u6_armhf.deb ...

Unpacking libwbclient0:armhf (2:4.13.13+dfsg-1~deb11u6) over (2:4.13.13+dfsg-1~deb11u5) ...

Preparing to unpack .../eject_2.36.1-8+deb11u2_armhf.deb ...

Unpacking eject (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Preparing to unpack .../rfkill_2.36.1-8+deb11u2_armhf.deb ...

Unpacking rfkill (2.36.1-8+deb11u2) over (2.36.1-8+deb11u1) ...

Setting up bsdextrautils (2.36.1-8+deb11u2) ...

Setting up libwbclient0:armhf (2:4.13.13+dfsg-1~deb11u6) ...

Setting up eject (2.36.1-8+deb11u2) ...

Setting up rfkill (2.36.1-8+deb11u2) ...

Setting up libfdisk1:armhf (2.36.1-8+deb11u2) ...

Setting up mount (2.36.1-8+deb11u2) ...

Setting up fdisk (2.36.1-8+deb11u2) ...

Processing triggers for libc-bin (2.31-13+rpt2+rpi1+deb11u8) ...

Processing triggers for man-db (2.9.4-2) ...

Processing triggers for mailcap (3.69) ...


    Here we were about to pack up for the night when I asked Doug if we could change the username. So he did so real quick. We can't see what he did in the nano text editor though.

user@weatherstation:~ $ sudo nano /etc/hostname

user@weatherstation:~ $ sudo nano /etc/hostname

user@weatherstation:~ $ sudo nano /etc/hosts

user@weatherstation:~ $

    We entered one file and changed the hostname he gave it when we were troubleshooting a problem that caused us to keep re-imagine the disk, and changed it to "rpiweather". He said however that it would be best if we didn't change any passwords or usernames until we were done with the project. 


Tuesday 2024-04-23

I was just thinking of doing something like a disaster movie, DAY 2 after all the cities were destroyed by the aliens and survivors are fleeing aimlessly...I wanted to see if my micro USB Pi on/off switch adapter carried a data signal and plugged it in between the Pi and the hub, connected ethernet to the hub and tried to SSH into it, and nothing happened. It got power! But then I did IPCONFIG to see what my default gateway was so I could search that in my browser and check the device list on the router web interface and see if my Pi was listed after we removed the on/off switch adapter and plugged it back in, and checked wired connections and found rpiweather listed there. I checked it's current IP address since its on DHCP,  and then I SSH-ed into it. 

PS C:\Users\Christian> ssh user@192.168.1.188

ssh: connect to host 192.168.1.188 port 22: Connection timed out

PS C:\Users\Christian> ipconfig

...

   Default Gateway . . . . . . . . . :

...

   Default Gateway . . . . . . . . . : 192.168.1.1

PS C:\Users\Christian> ssh user@192.168.1.188

user@192.168.1.188's password:

Linux rpiweather 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l

...

user@rpiweather:~ $ sudo apt update

Get:1 http://raspbian.raspberrypi.org/raspbian bullseye InRelease [15.0 kB]

Get:2 http://archive.raspberrypi.org/debian bullseye InRelease [23.6 kB]

Get:3 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf Packages [13.2 MB]

Get:4 http://archive.raspberrypi.org/debian bullseye/main armhf Packages [313 kB]

Fetched 13.6 MB in 37s (363 kB/s)

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

All packages are up to date.

user@rpiweather:~ $ sudo apt upgrade

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

Calculating upgrade... Done

0 upgraded, 0 newly installed, 0 to remove and 0 not upgraded.

    Doug said I needed to set up the hat so I could use it before I could expect anything to come out of the display. So I looked for anything that would show me how to get the Waveshare e-ink 7.5 inch screen hat set up. I came across a website for Waveshare "https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_Manual#Working_With_Raspberry_Pi", and the guy on GitHub said first to go SUDO RASPI-CONFIG. But Doug was of the mind that we don't know if those instructions only work for the alternative Inky wHAT display he was using. So on the above listed website I found the instructions for setting this up for the Waveshare screen I bought that matches the Inky wHAT screen the GitHub guy used. 

user@rpiweather:~ $ sudo raspi-config

    And so far, in the instructions that come after connecting the hardware, the first thing said to do is also to go SUDO RASPI-CONFIG. These instructions however, say to go to 5 INTERFACING OPTIONS > P4 SPI, however, I stupidly just went to option 5 to discover that on my Pi Zero,  Interface Options is actually option 3. And then go P4 SPI, and select enable SPI Interface. 




Back in the INTERFACE menu, I also had to enable I2C. 


Enable I2C!


Go SUDO REBOOT!

user@rpiweather:~ $ sudo reboot

user@rpiweather:~ $ Connection to 192.168.1.188 closed by remote host.

Connection to 192.168.1.188 closed. 

I rebooted and SSH-ed back in. Then I updated again just in case before installing Git, which I will explain in a bit. 

user@rpiweather:~ $ sudo apt update

Hit:1 http://raspbian.raspberrypi.org/raspbian bullseye InRelease

Hit:2 http://archive.raspberrypi.org/debian bullseye InRelease

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

All packages are up to date.

user@rpiweather:~ $ sudo apt install git

Reading package lists... Done

Building dependency tree... Done

Reading state information... Done

The following additional packages will be installed:

  git-man liberror-perl

Suggested packages:

  git-daemon-run | git-daemon-sysvinit git-doc git-el git-email git-gui gitk gitweb git-cvs git-mediawiki git-svn

The following NEW packages will be installed:

  git git-man liberror-perl

0 upgraded, 3 newly installed, 0 to remove and 0 not upgraded.

Need to get 6,564 kB of archives.

After this operation, 33.1 MB of additional disk space will be used.

Do you want to continue? [Y/n]

Get:1 http://mirrors.syringanetworks.net/raspbian/raspbian bullseye/main armhf liberror-perl all 0.17029-1 [31.0 kB]

Get:2 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf git-man all 1:2.30.2-1+deb11u2 [1,828 kB]

Get:3 http://raspbian.raspberrypi.org/raspbian bullseye/main armhf git armhf 1:2.30.2-1+deb11u2 [4,704 kB]

Fetched 6,564 kB in 11s (600 kB/s)

Selecting previously unselected package liberror-perl.

(Reading database ... 43926 files and directories currently installed.)

Preparing to unpack .../liberror-perl_0.17029-1_all.deb ...

Unpacking liberror-perl (0.17029-1) ...

Selecting previously unselected package git-man.

Preparing to unpack .../git-man_1%3a2.30.2-1+deb11u2_all.deb ...

Unpacking git-man (1:2.30.2-1+deb11u2) ...

Selecting previously unselected package git.

Preparing to unpack .../git_1%3a2.30.2-1+deb11u2_armhf.deb ...

Unpacking git (1:2.30.2-1+deb11u2) ...

Setting up liberror-perl (0.17029-1) ...

Setting up git-man (1:2.30.2-1+deb11u2) ...

Setting up git (1:2.30.2-1+deb11u2) ...

Processing triggers for man-db (2.9.4-2) ...

So, Git is sort of like APT for installing packages, it will go retrieve repository libraries from GitHub so your device can use them. 

Now the two sets of instructions I am following, the one from GitHub because the guy built the weather display I want to do, and the other because this guy used an Inky screen, and I am using Waveshare, I am then also following Waveshares instructions. I asked Doug from here what he thought I should do because he said that the guy on GitHub's instructions might work with my Waveshare just fine. But I would have to go into the code and do some programming to get his code to work with my screen. Or I could follow the Waveshare instructions. The fear I have is that if I do the latter, there will be too much of a deviation from the instructios on GitHub because it's his project I am doing. Doug suggested that we to the GitHub instructions for now and see how they work, and if they don't we can then just switch back to following the Waveshare instructions. 

    Even if this makes it harder, Doug usually has a good reason for it because I will learn something or learn how to do more without his help. Or I will just get exposed to more things. Plus, we just don't know what will happen. It may be that the GitHub instructions are sufficient. 

user@rpiweather:~ $ curl https://get.pimoroni.com/inky | bash

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100 34932  100 34932    0     0   5920      0  0:00:05  0:00:05 --:--:--  8069


This script will install everything needed to use

Inky pHAT & wHAT


Always be careful when running scripts and commands copied

from the internet. Ensure they are from a trusted source.


This script should -- only be run on a Raspberry Pi with RPi OS --

other systems and SBCs are not supported and may explode!


If you want to see what this script does before running it,

you should run: 'curl https://get.pimoroni.com/inky'



Note: Inky pHAT & wHAT requires SPI communication

Note: Inky pHAT & wHAT requires I2C communication


Do you wish to continue? [y/N] y

    

Checking hardware requirements...


Checking for packages required for GPIO control...

raspi-gpio is already installed

....................................RPi.GPIO installed and up-to-date


SPI already enabled


Checking packages required by SPI interface...

spidev installed and up-to-date


I2C already enabled


Checking packages required by I2C interface...

Python 2 smbus installed and up-to-date

Python 3 smbus installed and up-to-date


Inky pHAT & wHAT comes with examples and documentation that you may wish to install.

Performing a full install will ensure those resources are installed,

along with all required dependencies. It may however take a while!


Do you wish to perform a full install? [y/N]


Checking for dependencies...

python3-numpy is already installed

python3-pil is already installed

python3-lxml is required

Installing python3-lxml...

python3-smbus is already installed


Installing Inky pHAT & wHAT library for Python 3...


Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting inky

  Downloading https://www.piwheels.org/simple/inky/inky-1.5.0-py3-none-any.whl (32 kB)

Requirement already satisfied: spidev in /usr/lib/python3/dist-packages (from inky) (3.5)

Requirement already satisfied: numpy in /usr/lib/python3/dist-packages (from inky) (1.19.5)

Collecting smbus2

  Downloading https://www.piwheels.org/simple/smbus2/smbus2-0.4.3-py2.py3-none-any.whl (11 kB)

Installing collected packages: smbus2, inky

Successfully installed inky-1.5.0 smbus2-0.4.3


Checking for additional software...

python3-geocoder is required

Installing python3-geocoder...

E: Unable to locate package python3-geocoder

Apt failed to install python3-geocoder!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting geocoder

  Downloading https://www.piwheels.org/simple/geocoder/geocoder-1.38.1-py2.py3-none-any.whl (98 kB)

     |████████████████████████████████| 98 kB 223 kB/s

WARNING: Retrying (Retry(total=4, connect=None, read=None, redirect=None, status=None)) after connection broken by 'ProtocolError('Connection aborted.', RemoteDisconnected('Remote end closed connection without response'))': /simple/click/

Collecting click

  Downloading https://www.piwheels.org/simple/click/click-8.1.7-py3-none-any.whl (97 kB)

     |████████████████████████████████| 97 kB 272 kB/s

Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from geocoder) (2.25.1)

Collecting future

  Downloading https://www.piwheels.org/simple/future/future-1.0.0-py3-none-any.whl (491 kB)

     |████████████████████████████████| 491 kB 255 kB/s

Collecting ratelim

  Downloading https://www.piwheels.org/simple/ratelim/ratelim-0.1.6-py2.py3-none-any.whl (4.0 kB)

Requirement already satisfied: six in /usr/lib/python3/dist-packages (from geocoder) (1.16.0)

Collecting decorator

  Downloading https://www.piwheels.org/simple/decorator/decorator-5.1.1-py3-none-any.whl (10 kB)

Installing collected packages: decorator, ratelim, future, click, geocoder

Successfully installed click-8.1.7 decorator-5.1.1 future-1.0.0 geocoder-1.38.1 ratelim-0.1.6

python3-beautifulsoup4 is required

Installing python3-beautifulsoup4...

E: Unable to locate package python3-beautifulsoup4

Apt failed to install python3-beautifulsoup4!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: beautifulsoup4 in /usr/lib/python3/dist-packages (4.9.3)

Requirement already satisfied: soupsieve>1.2 in /usr/lib/python3/dist-packages (from beautifulsoup4) (2.2.1)

python3-qrcode is required

Installing python3-qrcode...

python3-icalendar is required

Installing python3-icalendar...

python3-fonts is required

Installing python3-fonts...

E: Unable to locate package python3-fonts

Apt failed to install python3-fonts!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting fonts

  Downloading https://www.piwheels.org/simple/fonts/fonts-0.0.3-py3-none-any.whl (4.2 kB)

Installing collected packages: fonts

Successfully installed fonts-0.0.3

python3-font_hanken_grotesk is required

Installing python3-font_hanken_grotesk...

E: Unable to locate package python3-font_hanken_grotesk

Apt failed to install python3-font_hanken_grotesk!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting font_hanken_grotesk

  Downloading https://www.piwheels.org/simple/font-hanken-grotesk/font_hanken_grotesk-0.0.2-py3-none-any.whl (391 kB)

     |████████████████████████████████| 391 kB 251 kB/s

Installing collected packages: font-hanken-grotesk

Successfully installed font-hanken-grotesk-0.0.2

python3-font_intuitive is required

Installing python3-font_intuitive...

E: Unable to locate package python3-font_intuitive

Apt failed to install python3-font_intuitive!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting font_intuitive

  Downloading https://www.piwheels.org/simple/font-intuitive/font_intuitive-0.0.4-py3-none-any.whl (36 kB)

Installing collected packages: font-intuitive

Successfully installed font-intuitive-0.0.4

python3-font_fredoka_one is required

Installing python3-font_fredoka_one...

E: Unable to locate package python3-font_fredoka_one

Apt failed to install python3-font_fredoka_one!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting font_fredoka_one

  Downloading https://www.piwheels.org/simple/font-fredoka-one/font_fredoka_one-0.0.4-py3-none-any.whl (27 kB)

Installing collected packages: font-fredoka-one

Successfully installed font-fredoka-one-0.0.4

python3-font_source_serif_pro is required

Installing python3-font_source_serif_pro...

E: Unable to locate package python3-font_source_serif_pro

Apt failed to install python3-font_source_serif_pro!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting font_source_serif_pro

  Downloading https://www.piwheels.org/simple/font-source-serif-pro/font_source_serif_pro-0.0.1-py3-none-any.whl (1.8 MB)

     |████████████████████████████████| 1.8 MB 1.9 MB/s

Installing collected packages: font-source-serif-pro

Successfully installed font-source-serif-pro-0.0.1

python3-font_source_sans_pro is required

Installing python3-font_source_sans_pro...

E: Unable to locate package python3-font_source_sans_pro

Apt failed to install python3-font_source_sans_pro!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting font_source_sans_pro

  Downloading https://www.piwheels.org/simple/font-source-sans-pro/font_source_sans_pro-0.0.1-py3-none-any.whl (2.2 MB)

     |████████████████████████████████| 2.2 MB 1.8 MB/s

Installing collected packages: font-source-sans-pro

Successfully installed font-source-sans-pro-0.0.1

python3-wikiquotes is required

Installing python3-wikiquotes...

E: Unable to locate package python3-wikiquotes

Apt failed to install python3-wikiquotes!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Collecting wikiquotes

  Downloading https://www.piwheels.org/simple/wikiquotes/wikiquotes-1.4-py3-none-any.whl (20 kB)

Collecting slacker

  Downloading https://www.piwheels.org/simple/slacker/slacker-0.14.0-py3-none-any.whl (9.4 kB)

Collecting bs4

  Downloading https://www.piwheels.org/simple/bs4/bs4-0.0.2-py2.py3-none-any.whl (1.2 kB)

Requirement already satisfied: lxml in /usr/lib/python3/dist-packages (from wikiquotes) (4.6.3)

Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from wikiquotes) (2.25.1)

Collecting unidecode

  Downloading https://www.piwheels.org/simple/unidecode/Unidecode-1.3.8-py3-none-any.whl (235 kB)

     |████████████████████████████████| 235 kB 259 kB/s

Requirement already satisfied: beautifulsoup4 in /usr/lib/python3/dist-packages (from bs4->wikiquotes) (4.9.3)

Requirement already satisfied: soupsieve>1.2 in /usr/lib/python3/dist-packages (from beautifulsoup4->bs4->wikiquotes) (2.2.1)

Installing collected packages: unidecode, slacker, bs4, wikiquotes

Successfully installed bs4-0.0.2 slacker-0.14.0 unidecode-1.3.8 wikiquotes-1.4


Downloading examples and documentation...

Resources for your Inky pHAT & wHAT were copied to

/home/user/Pimoroni/inky


Finalising Install...


Some packages could not be installed, review the output for details!


user@rpiweather:~ $ client_loop: send disconnect: Connection reset


The next instructions on GitHub are to install pyOWM. pyOWM is a python library that utilizes the OpenWeatherMaps APIs. 


    So, while it was installing curl https://get.pimoroni.com/inky | bash, it was unable to install several packages and then disconnected from SSH at the end. I missed this because I moved right on to installing the weather API next and none of the commands such as pip or sudo or anything was recognized. I then saw that the user went from being "user@rpiweather:~ $" at the beginning of every command to "PS  C:\Users\(my name)>"

    Discovered that it's that time of night where the wifi gives out. I told Doug that the Pi was on a wired connection since this is a wifi issue, so the installation probably wasn't interrupted, but the printing on the screen is interrupted and what happened after that is gone/. He suggested I redo the curl https://get.pimoroni.com/inky | bash command again. Oof, that was taking some time. Dangit! Class is almost over. I was hoping to get a little further than this. 

Fortunately it skipped a few things that were already done. 

user@rpiweather:~ $ curl https://get.pimoroni.com/inky | bash

  % Total    % Received % Xferd  Average Speed   Time    Time     Time  Current

                                 Dload  Upload   Total   Spent    Left  Speed

100 34932  100 34932    0     0   3510      0  0:00:09  0:00:09 --:--:--  7871


This script will install everything needed to use

Inky pHAT & wHAT


Always be careful when running scripts and commands copied

from the internet. Ensure they are from a trusted source.


This script should -- only be run on a Raspberry Pi with RPi OS --

other systems and SBCs are not supported and may explode!


If you want to see what this script does before running it,

you should run: 'curl https://get.pimoroni.com/inky'


Note: Inky pHAT & wHAT requires SPI communication

Note: Inky pHAT & wHAT requires I2C communication


Do you wish to continue? [y/N] y


Checking environment...

Updating apt indexes...

.....................


Checking hardware requirements...


Checking for packages required for GPIO control...

raspi-gpio is already installed

RPi.GPIO installed and up-to-date


SPI already enabled


Checking packages required by SPI interface...

spidev installed and up-to-date


I2C already enabled


Checking packages required by I2C interface...

Python 2 smbus installed and up-to-date

Python 3 smbus installed and up-to-date


Inky pHAT & wHAT comes with examples and documentation that you may wish to install.

Performing a full install will ensure those resources are installed,

along with all required dependencies. It may however take a while!


Do you wish to perform a full install? [y/N] Y


Checking for dependencies...

python3-numpy is already installed

python3-pil is already installed

python3-lxml is already installed

python3-smbus is already installed


Installing Inky pHAT & wHAT library for Python 3...


Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: inky in /usr/local/lib/python3.9/dist-packages (1.5.0)

Collecting inky

  Using cached https://www.piwheels.org/simple/inky/inky-1.5.0-py3-none-any.whl (32 kB)

  Downloading https://www.piwheels.org/simple/inky/inky-1.4.0-py3-none-any.whl (28 kB)

Requirement already satisfied: spidev in /usr/lib/python3/dist-packages (from inky) (3.5)

Requirement already satisfied: smbus2 in /usr/local/lib/python3.9/dist-packages (from inky) (0.4.3)

Requirement already satisfied: numpy in /usr/lib/python3/dist-packages (from inky) (1.19.5)


Checking for additional software...

python3-geocoder is required

Installing python3-geocoder...

E: Unable to locate package python3-geocoder

Apt failed to install python3-geocoder!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: geocoder in /usr/local/lib/python3.9/dist-packages (1.38.1)

Requirement already satisfied: six in /usr/lib/python3/dist-packages (from geocoder) (1.16.0)

Requirement already satisfied: future in /usr/local/lib/python3.9/dist-packages (from geocoder) (1.0.0)

Requirement already satisfied: click in /usr/local/lib/python3.9/dist-packages (from geocoder) (8.1.7)

Requirement already satisfied: ratelim in /usr/local/lib/python3.9/dist-packages (from geocoder) (0.1.6)

Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from geocoder) (2.25.1)

Requirement already satisfied: decorator in /usr/local/lib/python3.9/dist-packages (from ratelim->geocoder) (5.1.1)

python3-beautifulsoup4 is required

Installing python3-beautifulsoup4...

E: Unable to locate package python3-beautifulsoup4

Apt failed to install python3-beautifulsoup4!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: beautifulsoup4 in /usr/lib/python3/dist-packages (4.9.3)

Requirement already satisfied: soupsieve>1.2 in /usr/lib/python3/dist-packages (from beautifulsoup4) (2.2.1)

python3-qrcode is already installed

python3-icalendar is already installed

python3-fonts is required

Installing python3-fonts...

E: Unable to locate package python3-fonts

Apt failed to install python3-fonts!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: fonts in /usr/local/lib/python3.9/dist-packages (0.0.3)

python3-font_hanken_grotesk is required

Installing python3-font_hanken_grotesk...

E: Unable to locate package python3-font_hanken_grotesk

Apt failed to install python3-font_hanken_grotesk!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: font_hanken_grotesk in /usr/local/lib/python3.9/dist-packages (0.0.2)

python3-font_intuitive is required

Installing python3-font_intuitive...

E: Unable to locate package python3-font_intuitive

Apt failed to install python3-font_intuitive!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: font_intuitive in /usr/local/lib/python3.9/dist-packages (0.0.4)

python3-font_fredoka_one is required

Installing python3-font_fredoka_one...

E: Unable to locate package python3-font_fredoka_one

Apt failed to install python3-font_fredoka_one!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: font_fredoka_one in /usr/local/lib/python3.9/dist-packages (0.0.4)

python3-font_source_serif_pro is required

Installing python3-font_source_serif_pro...

E: Unable to locate package python3-font_source_serif_pro

Apt failed to install python3-font_source_serif_pro!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: font_source_serif_pro in /usr/local/lib/python3.9/dist-packages (0.0.1)

python3-wikiquotes is required

Installing python3-wikiquotes...

E: Unable to locate package python3-wikiquotes

Apt failed to install python3-wikiquotes!

Falling back on pypi...

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple

Requirement already satisfied: wikiquotes in /usr/local/lib/python3.9/dist-packages (1.4)

Requirement already satisfied: bs4 in /usr/local/lib/python3.9/dist-packages (from wikiquotes) (0.0.2)

Requirement already satisfied: unidecode in /usr/local/lib/python3.9/dist-packages (from wikiquotes) (1.3.8)

Requirement already satisfied: requests in /usr/lib/python3/dist-packages (from wikiquotes) (2.25.1)

Requirement already satisfied: slacker in /usr/local/lib/python3.9/dist-packages (from wikiquotes) (0.14.0)

Requirement already satisfied: lxml in /usr/lib/python3/dist-packages (from wikiquotes) (4.6.3)

Requirement already satisfied: beautifulsoup4 in /usr/lib/python3/dist-packages (from bs4->wikiquotes) (4.9.3)

Requirement already satisfied: soupsieve>1.2 in /usr/lib/python3/dist-packages (from beautifulsoup4->bs4->wikiquotes) (2.2.1)


Downloading examples and documentation...

The examples directory already exists on your system!

We've backed them up as examples-backup, just in case you've changed anything!


Resources for your Inky pHAT & wHAT were copied to

/home/user/Pimoroni/inky


Finalising Install...


Some packages could not be installed, review the output for details!

user@rpiweather:~ $ pip install pyowm

Looking in indexes: https://pypi.org/simple, https://www.piwheels.org/simple


Collecting pyowm

  Downloading pyowm-3.3.0-py3-none-any.whl (4.5 MB)

     |████████████████████████████████| 4.5 MB 10 kB/s

Collecting geojson<3,>=2.3.0

  Downloading https://www.piwheels.org/simple/geojson/geojson-2.5.0-py2.py3-none-any.whl (14 kB)

Requirement already satisfied: requests<3,>=2.20.0 in /usr/lib/python3/dist-packages (from pyowm) (2.25.1)

Collecting PySocks<2,>=1.7.1

  Downloading https://www.piwheels.org/simple/pysocks/PySocks-1.7.1-py3-none-any.whl (16 kB)

Installing collected packages: PySocks, geojson, pyowm

Successfully installed PySocks-1.7.1 geojson-2.5.0 pyowm-3.3.0

user@rpiweather:~ $

user@rpiweather:~ $ git clone https://github.com/Hothomir/weather-report.git

Cloning into 'weather-report'...

remote: Enumerating objects: 377, done.

remote: Counting objects: 100% (34/34), done.

remote: Compressing objects: 100% (14/14), done.

remote: Total 377 (delta 30), reused 20 (delta 20), pack-reused 343

Receiving objects: 100% (377/377), 228.46 KiB | 745.00 KiB/s, done.

Resolving deltas: 100% (160/160), done.

user@rpiweather:~ $ cd weather-report/

user@rpiweather:~/weather-report $ nano configfile.ini

We were looking at the details of installing andadjusting the weather API for my Pi, and Doug wanted to see how we would make these adjustments so he nono'd into it.

user@rpiweather:~/weather-report $ exit

Thats it for the day!


Thursday 2024-04-25

    Today went a lot slower than I thought. I always intend to come in and get right started with a project but I am SCRUM Master in class right now and for some reason it always takes an hour to get that over with, talking with everyone in the group about where they are in their studies, and then getting everyone to agree on a research assignment for the weekend. I feel like people should just say a quick little thing without droning on endlessly, my classmates disagree. The SCRUM meetings are actually intended to keep people productive, not give them a reason to not be productive by talking about what they're doing endlessly and having full fledged conversations about it and joking and stuff. 

    So then I suggested a research assignment of making a batch script, Chey said he doesn't want to do that, it sounds pointless and unpleasant and I tried to convince him that its not the case by showing him scripts I use regularly to manage various things on my file server and this is when I discovered because I am doing a cleaning check at my apartment right now, something must have gotten jostled and so now I have no internet access, so I disabled my VPN and re-enabled it because sometimes that's the problem, it just needs the connection refreshed again, and that didn't fix it and then I realized when I was jostling my router because I was trying to clean up a problem on my desk with speakers for my sound system which was right next to the router, this must have unplugged the router. So no VPN or server today, and if it is activated, then I have no internet access. 

    Then Doug started talking to me about why I might be having problems using my VPN for the livingroom laptop that we use to play movies downstairs from my file server and he thought it had to be a problem with the VPN and it's a long story why but basically my roommate has his router and I have my router and I did a port forward on both of them for my server, and because I gave the downstairs laptop access to my VPN while being plugged into my roommates router, that means everything goes outside of my network and then back and then to my router and then to my server which could be slowing files down. Doug made a suggestion that could speed this up after I told him the laptop won't play files of certain sizes and up and 4k files and he was so sure it was because of the VN exiting my roommates routers network and then back in and then to mine and then my server and back and all that. But I told him I transferred the file to the laptop and played it and it still didn't work and then he was satisfied it wasn't my VPN. 

    So after all this talk and then Doug finally convincing Chey that actually eh should do a research assignment on what batch scripts are and how they work, then we could do that this next week, where he could actually create one that he would use, since this is actually a really good thing to learn. So I am an affective SRUM Master if you think I am a good leader, but only because of my ideas because I don't exactly inspire followers to go along with my ideas. Ha ha!

    So I SSH-ed into my Pi for the weather project again:

user@rpiweather:~ $ git clone https://github.com/Hothomir/weather-report.git

fatal: destination path 'weather-report' already exists and is not an empty directory.

user@rpiweather:~ $ ls

Pimoroni  weather-report

user@rpiweather:~ $ cd weather-report

user@rpiweather:~/weather-report $ ls

cond_icons.py  configfile.ini  impression-main.py  LICENSE  main.py  __pycache__  README.md  resources


    Now that we edited the configfile.ini with nano to use the key that we were given from an API we created an account for, and added my location data into the configfile.ini file. 

user@rpiweather:~/weather-report $ python main.py

Traceback (most recent call last):

  File "/home/user/weather-report/main.py", line 14, in <module>

    import cond_icons

  File "/home/user/weather-report/cond_icons.py", line 14, in <module>

    OWMAPI = configObj["OWM_API"]

  File "/usr/lib/python3.9/configparser.py", line 960, in __getitem__

    raise KeyError(key)

KeyError: 'OWM_API'

    When I created an account with https://openweathermap.org/api, there was a page that had a key that was already created for me, but it had no label. We copied that into the script and now it's throwing errors for the API. So we tried creating another key, and labelling it this time as 'WatherDisplay'. We copied the key and used nano to edit the configfile.ini file. And then I tried running the program again. 

 raise KeyError(key)

KeyError: 'OWM_API'

    We googled the error but that didn't produce anything useful except that the python script couldn't find the config file. So we looked based on that error, the stack tracer, the chain of messages from that error, we looked at the line of code that was giving the error and that's when we saw the file path was wrong. Doug was looking at  File "/home/user/weather-report/cond_icons.py", line 14, in <module> and checked file path, which said "/home/pi/weather-report/configfile.ini" and Doug asked me if that file path looked right. I told him I only knew the weather-report/configfile.ini part of the file path because I had to cd into it. That's when he realized that the GitHub project we were going off of had all the code reflecting an older version of Raspbian OS where the user was always Pi. Our username is user. So we had to change the file path in every part in his code that used the wrong file path. 

user@rpiweather:~/weather-report $ grep -RH "/home/pi" .


This command allowed us to look at every problem. Initially we just searched Pi instead of the file path and this brought up numerous things that said 'pip' and 'api' and many other things including just what we were looking for, this was a long list of things that looked like they needed to be corrected but we were able to lose a lot of this confusion by redoing the grep command to reflect the file path instead. 

    Since we were running out of time and Doug is seasoned at this, he went ahead and did all the nano edits himself, there were five or so and he was able to do it one minute. Class is now over. 


    Doug wanted me to see results with this so we kept working for a little while. Course this goes into the brief period of time each day when he gets to see his wife. So he only does this once in a while. 

    Doug did more of those grep commands, kind of an intuition thing because he has messed with a lot of code, and then he figured that the URI (URL for API's), URI's are different from URL's but this is an explanation for another time. And the URI has changed from what is in his code. The Open Weather Map website uses a different URI than they used to. 



    We started floating the idea that I may need to find another project on GitHub that is even more current because all sorts of things are wrong with this guys code, every time we fixed a bunch of errors, we would use the grep command and find a whole bunch more errors. 

    Doug had an idea that since this is such a problem, getting the API to work, we need to just make a call and see if this API even works at all. So we need to manually do it, not through the Pi Zero but through my computer to see if it returns results from an API call. He had the idea that we could install Postman, a GUI program that will run API calls. And then we will go from there, but that's for next week, provided I actually pass my A+ core 2 certification exam. I failed it a few weeks ago and will get kicked from the program if I fail it tomorrow and again after that two weeks from now. So tomorrows test results determine what I am focusing all my energy n for the next two weeks. 


Monday 2024-04-29

    I SSH-ed into my Pi again and I installed Postman on my Windows laptop, the free non-account version so we could make an API phone call to test the API code in this GitHub project and see if the whole thing needs to be trashed and we need to find another one that does the same thing or if this is at all salvageable or whatever. We keep getting keys from openweathermap.org. 

    Doug instantly got annoyed with my Windows PowerShell and installed the official PowerShell Terminal that runs even better. He got annoyed that we couldn't scroll in Nano on my Pi Zero. Then he discovered that it will wasn't scrolling and figured that it must have been an option he enabled. 

    We used Postman to see if the openweathermaps.org API was the problem. To make a n API call in Postman, we pasted "https://api.openweathermap.org/data/2.5/weather?lat={lat}&lon={lon}&appid={API key}" in there and ran it. It worked fine, it gave us weather data through Postman that we could see and so the problem isn't with the openweathermaps.org API. 

    But the API was failing, that's how we found out that the current API was working, but there was a problem with the One Call API. One Call is something that the website made up that gives you all the weather details while making a single API call instead of having to make multiple API calls for each detail. The One Call API was failing for two reasons, one we didn't subscribe to it because we didn't purchase the subscription. Two, they are deprecating the 2.5 One Call API for a new version called 3.0 which is not supported by the Python script that was written by the guy on GitHub that created the package we were using. His package used 2.5, and this can't be easily remedied because 2.5 One Call is written countless times throughout the code, and to fix that and all the other problems similar to this, would basically require rewriting the whole package and constantly error checking endlessly until it worked, which would be a nightmare and not worth doing. Almost sounds like writing a new one from scratch would be easier and I don't even know how.  

    That's when we decided that we will have to abandon the script and write our own or find another one. So then that's when we chanted gears today to just trying to get the E-ink display to function. So we pulled up one of the other Waveshare tabs I had open on my laptop for the past few months now so then we installed their instructions to install some of their packages and download their demo script and we plugged the screen in after shutting it down. First Doug installed all the code for the C language and realized what he did and then went back to delete all the things he installed so we could start over because we discovered instructions with Python which would have been much easier. 

    C would be better but you would have to compile it, Python is the fad language right now so there will be a lot more resources online for it, in a nutshell. Doug actually prefers C for things like this because the code is lighter weight, but for me, he said I would have a lot more resources to hold my hand with Python. 

https://www.waveshare.com/wiki/7.5inch_e-Paper_HAT_Manual#Working_With_Raspberry_Pi    

Python

  • Install the function library:
sudo apt-get update
sudo apt-get install python3-pip
sudo apt-get install python3-pil
sudo apt-get install python3-numpy
sudo pip3 install RPi.GPIO
sudo pip3 install spidev
  • Install function library (python2):
sudo apt-get update
sudo apt-get install python-pip
sudo apt-get install python-pil
sudo apt-get install python-numpy
sudo pip install RPi.GPIO
sudo pip install spidev
  • Install gpiozero library (it is installed in the system by default, if not, you can install it by following the commands below):
sudo apt-get update
# python3
sudo apt install python3-gpiozero
# python2
sudo apt install python-gpiozero
  • Download the demo via GitHub (You can skip this step if you have downloaded it.)
git clone https://github.com/waveshare/e-Paper.git
cd e-Paper/RaspberryPi_JetsonNano/
  • Download the demo (You can skip this step if you have downloaded it.)
wget https://files.waveshare.com/upload/7/71/E-Paper_code.zip
unzip E-Paper_code.zip -d e-Paper
cd e-Paper/RaspberryPi_JetsonNano/
  • Run the demo:
# Make sure it's in e-Paper/RaspberryPi_JetsonNano/
cd python/examples/
python3 epd_7in5_V2_test.py

    

The screen worked!!!!!!!!!

    Then we spent a couple minutes looking at the demo code for the E-ink display to see how it works and we found online that the display wears out real quick if it isn't put to sleep with the display left on it within a certain amount of time, I think ti said like within 180 seconds or something, it said you need to refresh it within at least 180 seconds. And then it recommended that you do a full refresh once a day which is easily done in code. So all we needed to do was figure out how to put it in low power mode sleep after something was written to the screen. 

    We looked at the code in the demo to try to figure it out and to test it, and we changed it to not clear the screen before putting it to sleep, using the sleep command which I will enter later_____________and Doug put hashtags for comments in code throughout all code that showed all sorts of other things on the screen and then commented out the two commands that clear the display, and then I was worried about it getting that message stuck on the screen because he shut down the Pi with stuff on the screen, I didn't know any better. So Doug booted it again and went back into Nano to remove the comment hashtag character from the two screen clearing commands and ran it, the screen cleared, no problem. 


    when ssh into pi, do ls and then cd into weather-display then ls then cd into the main.py file to change all the variables of placement fint size etcetera


Thursday

    CLI PS C:\Users\Christian> scp -r user@192.168.1.188:~/weather-report/resources/icons .\Desktop\weatherdisplay

    to update display go     sudo python3 main.py

    to update the background image with the lines go     scp -r .\Desktop\weatherdisplay\* user@192.168.1.188:~/weather-report/resources/.

MAKE SURE IT IS A 1 BIT IMAGE, THERE CANNOT BE ANY GRAY WHATSOEVER OR THE SIPLAY WITH MALFUNCTION, EVERYTHING ABSOLUTELY MUST BE EITHER BLACK OR WHTIE!!!!!!!!!!!

user@192.168.1.188's password:

moon.png                                                                              100% 1762   344.5KB/s   00:00

few_clouds_moon.png                                                                   100% 1442   350.5KB/s   00:00

light_rain.png                                                                        100% 1400   302.6KB/s   00:00

fog.png                                                                               100% 1167   284.9KB/s   00:00

clouds.png                                                                            100% 1442   466.7KB/s   00:00

snow.png                                                                              100% 1459   405.8KB/s   00:00

thunderstorm.png                                                                      100% 1529   426.0KB/s   00:00

location.png                                                                          100%  630   204.5KB/s   00:00

sun.png                                                                               100% 1643   534.1KB/s   00:00

rain.png                                                                              100% 1390   386.0KB/s   00:00

thunder.png                                                                           100% 1515   493.3KB/s   00:00

few_clouds_sun.png                                                                    100% 1603   518.7KB/s   00:00

PS C:\Users\Christian> scp -r user@192.168.1.188:~/weather-report/resources/background .\Desktop\weatherdisplay

user@192.168.1.188's password:

test.png                                                                              100%  612   149.8KB/s   00:00

weather-report-bg.png                                                                 100%  721   155.4KB/s   00:00

PS C:\Users\Christian> ssh user@192.168.1.188

user@192.168.1.188's password:

Linux rpiweather 6.1.21+ #1642 Mon Apr  3 17:19:14 BST 2023 armv6l


The programs included with the Debian GNU/Linux system are free software;

the exact distribution terms for each program are described in the

individual files in /usr/share/doc/*/copyright.


Debian GNU/Linux comes with ABSOLUTELY NO WARRANTY, to the extent

permitted by applicable law.

Last login: Thu May  2 18:50:15 2024 from 192.168.1.118

user@rpiweather:~ $ ls

Pimoroni  weather-report

user@rpiweather:~ $ cd weather-report/

user@rpiweather:~/weather-report $ ls

cond_icons.py  configfile.ini  main.py  __pycache__  README.md  resources

user@rpiweather:~/weather-report $ nano main.py

user@rpiweather:~/weather-report $ nano configfile.ini

user@rpiweather:~/weather-report $ nano main.py

user@rpiweather:~/weather-report $ nano main.py

user@rpiweather:~/weather-report $ ls

cond_icons.py  configfile.ini  main.py  __pycache__  README.md  resources

user@rpiweather:~/weather-report $ nano main.py

user@rpiweather:~/weather-report $ cp main.py backupmain.py

user@rpiweather:~/weather-report $ nano main.py

user@rpiweather:~/weather-report $ cat main.py


# WEATHER DISPLAY - Bartosz Jaskulski

#

# Modified by Doug Webb


import os, sys

from datetime import datetime, timedelta

import cond_icons


import configparser


# config.ini file

configObj = configparser.ConfigParser()

configObj.read("/home/user/weather-report/configfile.ini")

OWMAPI = configObj["OWM_API"]

UserLoc = configObj["Location"]


api = OWMAPI["api"]


lat =float(UserLoc["latitude"])

lon = float(UserLoc["longitude"])

city = str(UserLoc["city"])

country = str(UserLoc["country"])


# Waveshare Libraries

from waveshare_epd import epd7in5_V2

from PIL import Image, ImageFont, ImageDraw

epd = epd7in5_V2.EPD()


# pyOWM Libraries

from pyowm.owm import OWM

from pyowm.utils import config

from pyowm.utils import timestamps


CURR_DIR = os.path.dirname(os.path.realpath(__file__)) + "/"

RESOURCES = CURR_DIR + "resources/"


# Fonts

PIXEL_FONT = RESOURCES + "fonts/Pixel12x10.ttf"

Terminal_FONT = RESOURCES + "fonts/terminal-grotesque.ttf"

Mister_Pixel_FONT = RESOURCES + "fonts/Mister_Pixel_Regular.otf"

B_FONT = RESOURCES + "fonts/04B_03.ttf"

VG5000_FONT = RESOURCES + "fonts/VG5000-Regular.otf"

FT88Reg_FONT = RESOURCES + "fonts/FT88-Regular.otf"

Matrix_FONT = RESOURCES + "fonts/MATRIX.ttf"


TimeDate = datetime.now()

OneDaysTime = (datetime.now()+timedelta(days=1)).strftime("%A")

TwoDaysTime = (datetime.now()+timedelta(days=2)).strftime("%A")

ThreeDaysTime = (datetime.now()+timedelta(days=3)).strftime("%A")

FourDaysTime = (datetime.now()+timedelta(days=4)).strftime("%A")


degreeSign = u"\N{DEGREE SIGN}"


# OpenWeatherMap Integration

owm = OWM(api)

mgr = owm.weather_manager()

weather = mgr.weather_at_place(city+","+country).weather

forecast = mgr.forecast_at_place(city+","+country, '3h')


getTemp = weather.temperature("fahrenheit") # Enables temp in fahrenheit

curTemp = int(getTemp["temp"]) # Get current temp


# Current "feels like" temperature

feelsLike = int(getTemp["feels_like"])

currentFeelsLike = "Feels: "+str(feelsLike)+degreeSign


# Current max and min temps

maxTemp = int(getTemp["temp_max"])

minTemp = int(getTemp["temp_min"])


# Current wind speeds

getWind = weather.wind(unit="miles_hour")

curWind = int(getWind["speed"])


img = Image.open("/home/user/weather-report/resources/background/weather-report-bg.png")

draw = ImageDraw.Draw(img)


font_tiny = ImageFont.truetype(Matrix_FONT, 24)

font_small = ImageFont.truetype(Matrix_FONT, 24)

font_medium = ImageFont.truetype(Matrix_FONT, 55)

font_medium2 = ImageFont.truetype(Matrix_FONT, 36)

font_big = ImageFont.truetype(Matrix_FONT, 140)

font2 = ImageFont.truetype(Matrix_FONT, 20)


currentTemp = str(curTemp)+degreeSign


currentMaxTemp = "Max: "+str(maxTemp)+degreeSign # Current temp max

currentMinTemp = "Min: "+str(minTemp)+degreeSign # Current temp min


tomorrow = timestamps.tomorrow()

twodays = tomorrow + timedelta(days=1)

threedays = tomorrow + timedelta(days=2)

fourdays = tomorrow + timedelta(days=3)


OneDayTemp = str(int(forecast.get_weather_at(tomorrow).temperature("fahrenheit").get("temp", 0))) # Get temp in 1 day

OneDayCond = str(forecast.get_weather_at(tomorrow).status)

TwoDayTemp = str(int(forecast.get_weather_at(twodays).temperature("fahrenheit").get("temp", 0))) # Get temp in 2 days

TwoDayCond = str(forecast.get_weather_at(twodays).status)

ThreeDayTemp = str(int(forecast.get_weather_at(threedays).temperature("fahrenheit").get("temp", 0))) # Get temp in 3 days

ThreeDayCond = str(forecast.get_weather_at(threedays).status)

FourDayTemp = str(int(forecast.get_weather_at(fourdays).temperature("fahrenheit").get("temp", 0))) # Get temp in 4 days

FourDayCond = str(forecast.get_weather_at(fourdays).status)


currentCond = str(weather.status)

currentDetailCond = str(weather.detailed_status).title()


currentHumidity = "Hum:"+str(weather.humidity)+"%"

currentWind = "Wind:"+str(curWind)+" MPH"

currentLoc = ": " + city


# Math for proper text placement

projectName = "DOUG'S WEATHER REPORT"

w_name, h_name = font2.getsize(projectName)

x_name = 400 - (w_name/2)


w_OneDayTemp, h_OneDayTemp = font_medium.getsize(OneDayTemp)

x_OneDayTemp = (100) - (w_OneDayTemp/2)

w_OneDaysTime, h_OneDaysTime = font_tiny.getsize(OneDaysTime)

x_OneDaysTime = 100 - (w_OneDaysTime/2)

w_OneDayCond, h_OneDayCond = font_tiny.getsize(OneDayCond)

x_OneDayCond = 100 - (w_OneDayCond/2)


w_TwoDayTemp, h_TwoDayTemp = font_medium.getsize(TwoDayTemp)

x_TwoDayTemp = (300) - (w_TwoDayTemp/2)

w_TwoDaysTime, h_TwoDaysTime = font_tiny.getsize(TwoDaysTime)

x_TwoDaysTime = 300 - (w_TwoDaysTime/2)

w_TwoDayCond, h_TwoDayCond = font_tiny.getsize(TwoDayCond)

x_TwoDayCond = 300 - (w_TwoDayCond/2)


w_ThreeDayTemp, h_ThreeDayTemp = font_medium.getsize(ThreeDayTemp)

x_ThreeDayTemp = (500) - (w_ThreeDayTemp/2)

w_ThreeDaysTime, h_ThreeDaysTime = font_tiny.getsize(ThreeDaysTime)

x_ThreeDaysTime = 500 - (w_ThreeDaysTime/2)

w_ThreeDayCond, h_ThreeDayCond = font_tiny.getsize(ThreeDayCond)

x_ThreeDayCond = 500 - (w_ThreeDayCond/2)


w_FourDayTemp, h_FourDayTemp = font_medium.getsize(FourDayTemp)

x_FourDayTemp = (700) - (w_FourDayTemp/2)

w_FourDaysTime, h_FourDaysTime = font_tiny.getsize(FourDaysTime)

x_FourDaysTime = 700 - (w_FourDaysTime/2)

w_FourDayCond, h_FourDayCond = font_tiny.getsize(FourDayCond)

x_FourDayCond = 700 - (w_FourDayCond/2)



# Draw data and text onto display

# To place text, use draw.text((x,y),text,font = font)


draw.text((5, 4),TimeDate.strftime("%m-%d-%Y"), font = font2, fill = 255)       # Date

draw.text((235, 210),TimeDate.strftime("%I:%M %p"), font = font_big)                    # Time

draw.text((x_name, 4),projectName, font = font2, fill = 255)                    # Project name


draw.text((315, 40), currentTemp, font = font_big)                              # Current temp

draw.text((510, 60), "o", font = font_medium2)                              # Degree symbol

draw.text((584, 75), currentMaxTemp, font = font_small)                         # Current max temp

draw.text((584, 105), currentMinTemp, font = font_small)                        # Current min temp

draw.text((584, 39), currentFeelsLike, font = font_small)


draw.text((x_OneDayTemp, 395), OneDayTemp+degreeSign, font =  font_medium)      # Temp in 1 day

draw.text((x_TwoDayTemp, 395),TwoDayTemp+degreeSign, font = font_medium)        # Temp in 2 days

draw.text((x_ThreeDayTemp, 395), ThreeDayTemp+degreeSign, font = font_medium)   # Temp in 3 days

draw.text((x_FourDayTemp, 395), FourDayTemp+degreeSign, font = font_medium)     # Temp in 4 days


draw.text((x_OneDayCond, 455), OneDayCond, font = font_tiny)                    # Condition in 1 day

draw.text((x_TwoDayCond, 455), TwoDayCond, font = font_tiny)                    # Condition in 2 days

draw.text((x_ThreeDayCond, 455), ThreeDayCond, font = font_tiny)                # Condition in 3 days

draw.text((x_FourDayCond, 455), FourDayCond, font = font_tiny)                  # Condition in 4 days


draw.text((x_OneDaysTime, 380), OneDaysTime, font = font_tiny)                  # DOtW in 1 day

draw.text((x_TwoDaysTime, 380), TwoDaysTime, font = font_tiny)                  # DOtW in 2 days

draw.text((x_ThreeDaysTime, 380), ThreeDaysTime, font = font_tiny)              # DOtW in 3 days

draw.text((x_FourDaysTime, 380), FourDaysTime, font = font_tiny)                # DOtW in 4 days


draw.text((584, 150), currentHumidity, font = font_small)                       # Current humidity in percentage

draw.text((584, 200), currentWind, font = font_small)                           # Current wind speed in MPH


draw.text((10, 40), currentDetailCond, font = font_medium2)                     # Current weather conditions, detailed


black = Image.open("/home/user/weather-report/resources/icons/black.png")

img.paste(black, (10, 80))

#img.paste(cond_icons.CurrCondIcon(), (30, 75))                                  # Current Weather Icon


# Write image to the screen

epd.init() # Turn screen on

epd.display(epd.getbuffer(img)) # Send image to screen

epd.sleep() # Turn screen off

user@rpiweather:~/weather-report $


    Monday 2024-05-06

     Last Friday Doug had some extra time while he was network administering at BYU, and decided to find a way to get my Pi Zero to process an image into black and white, since the display only does straight black  and white, it would have to use a process called dithering to disperse black and white dots in such a fashion that a grayscale image could be created to create the whites, the blacks, and different amounts of white or black dots mixed together to make all the in-between tones of gray. This is Dithering. He created a script that once an image is uploaded through the SCP command on my Pi while SSH-ed into my Pi from the computer that has the file. You would type for example "scp "C:\Users\Christian\Dropbox\...\...\...IMG_3626-3.JPG" user@192.168.1.188:~/.", and then it asks for the password you use to SSH into the device. 

    The result was stuff like this:


   

    In class today we got a kick out of running Doug's script on a few pictures and displaying them on my paperwhite e-ink display for the weather display. Everyone wanted to come look at it, Doug was pleased with his work, he went around explaining to everyone what he did. And he is doing another thing too, since we are placing everything on the screen and moving them around for the weather display before finalizing this part of the project, instead of taking the time to have the code process in Python and print everything to the e-ink display, which can take about thirty seconds every time you make a change and want to see the results, Doug has decided to have the computer SSH-ing into the Pi do the processing and then create a black and white image of what it would look like on the e-ink display, which would be much faster. He is clearly trying to speed this project up so we can get me passed with CompTIA Network +. 

    I got to work on fine tuning the thumbnail images that will show what the sky is doing like partly cloudy or raining or snowing or sunshine. They are all pixelated from the GitHub project we've been working from. 

    Doug is also working on a script that hopefully will only refresh the clock every minute rather than the whole display, kind of like a Kindle only refreshes part of the page if there's only a small change, rather than refreshing the screen, inverting it and refreshing it again. Although, while this will look nicer, his concern is that the minute to minute refresh just for the clock would wear the screen way down real quick. However, this would also still wear out the part of the screen that displays the clock just as much as the whole screen would be worn out now the way it currently works with an entire screen refresh. 

Wednesday 2024-05-06

Doug came up with a way to set it up so if I ever wanted to display something different on the display than the weather, it can show a dithered image with the clock over it and we got the clock placed. He was trying to install an update to Python3 to do this however it lagged out and we sat there after class was over for like forty five minutes and he cancelled it and rewrote the script to this:

import sys
from PIL import Image, ImageFont, ImageDraw
from waveshare_epd import epd7in5_V2
from datetime import datetime, timedelta

# Open the given image
try:
        img = Image.open(sys.argv[1])
except:
        print("An error occured opening the image. Make sure the file is given as a parameter.")
        exit()

# Crop and resize the image to fit on the e-ink display
width, height = img.size
ratio = width / height
if ratio < 5/3:
        removal = (height - 3 * width / 5) / 2
        img = img.crop((0,removal,width,height - removal))
else:
        removal = (width - 5 * height / 3) / 2
        img = img.crop((removal,0,width - removal,height))
img = img.resize((800,480))

# Convert image to B+W only
img = img.convert('1')
# img.save('bwwibg.png')

The reason for this update to Python3 would have been so that he could write an algorithm that would count how many white pixels were in the black and white dithered image so it would change the color of the time being displayed either white or black so the time is easier to see. We did already sort of fix this problem however because he put a white border around the time when it is black or a black one when it is white. We had it set to black at first because we thought it was cool. with the Matrix movie cover font I found a .ttf file for, and uploaded this font file to the Pi and in a certain folder so that it could be used with this project. 
    And it looks like this:


We did do something Thursday but I don't remember what it was other than that it was basically a continuation of Wednesdays work. Well, I did change the font from Matrix to Linkin Parks Hybrid Theories album cover font that I think Mike Shinoda came up with when he did the album cover. Doug predicted that this font would be a totally different size, so all of my perfect placements of the time and weather and everything and the sizes that I wanted would then be a waste of time. He was right. 


Monday 2024-05-13

We added a bunch of pictures of mine that I like and Doug solved the problem why the algorithm wasn't properly counting all the white pixels and then displaying the time in the best tone, wither white or black depending on the overall tone of the picture. 

    He taught me the SCP command in Linux. I created a folder named pictures on my desktop and then I SSH-ed into the device and typed "scp -r .\Desktop\pictures\ user@192.168.1.188:~/." Scp means secure copy, - lowercase r means recursive so you not only copy the folder but its contents as well. You type a space and then a period which means to do the thing right here but is optional in some cases, but it confirms absolutely that this is where you want it, but after you type the -r and a space, the period tells the system to do the thing here, if you look at the directory the command is being typed in or the working directory, the period tells it to start there and then we can finish typing the file path from the working directory rather than retyping the whole file path. Then type a backslash then the source. This is where we finish typing the address which doesn't have to be entered completely from scratch. Doug calls this a local address when you can just continue from where the working directory is and finish typing the file path. So Desktop\pictures\, every time I typed another folder location to the file path we would press tab to make sure it was entered correctly. And then since pictures is the folder we want to copy, I typed a space and then the user@the ip address that we want to copy the pictures to. At the end of the ip address, I typed a colin, tilde (~) which represents home, and another period to specify that this is where I want it moved. "Right here!" is basically what it's saying., 


Monday 2024-05-20

Last Thursday, I don't recall getting much work done, Doug was working on an algorithm for the alternate time display he's been doing as a challenge to himself, which will choose what place to put the time over one of my images I've uploaded to the Pi according to what part of the image has the most whites or most blacks. I didn't like that very much because I predicted that the algorithm might decide that the darkest or lightest part of the image to put the time in happens to be the focal point of the image, say like the lightest or darkest part of the image happens to be al of your families faces in a family photo. However I decided that the focal point of the typical image would have more tonal differences, more nuance, and so will likely need to be well lit but with good definition in the details. So it would not be the darkest or lightest part of the image by definition.  

    But there's one problem, I will always want the weather even though I really like the time display with my images dithered on this display, so I thought, wait, what if we combined the two things? I asked Doug what the possibilities of putting my photography behind the weather so basically combining his project he is adding onto my project and we spent much of the class discussing how hard that would be and how he got the time text to show up in front of my photography in a way that's easy to read. 

    Basically, he made four layers of text and told the Pi in Python code to put all four of those layers in roughly the same spot but in a plus shape, so there are four layers positioned the exact same pixels away from each other for every character, an 8 written to the screen if it is black on a brighter image, will have white outline around it, and he creates this outline by putting an 8 below the black 8, but it's white and a few pixels up, and then there's another a few pixels to the left, and another to the right and another to a few pixels down. This could also be done in an x fashion and create the same result. 

    But that means all code has to be replicated four more times under the main layer, all with slightly different pixel coordinates. With the amount of layers I have for my weather display, he did some quick math and said that currently it is x amount of lines and this would cause for it to now have to be another 120 lines of code or something like that. 

    And I started thinking of alternatives, he said he isn't going to do it because that would take so much time and goes into personal passion territory so I would have to do it myself and I contemplated doing it myself and then he sited that what we are doing isn't even my project anymore, and this is the definition of scope creep. When I told him this is just an idea I was curious about, we're not implementing it and I haven't even decided if I would, he said that this is the problem, I don't have a working, self updating display yet. Everything still needs to be arranged on the display. I haven't hardly touched it most of this week, and so we need to finish that because we even think about doing other things. 

    However, Friday I committed myself to actually working on getting the one thing I wanted to do finished so it's out of the way. All I wanted to do going forward since I mostly like all the placements and the display basically has everything I want aside from new ideas like my photography in the background. All I really need to do now is tidy up some font problems. I have changed the font for the display from the Matrix movie cover font I was using to this Linkin Park album cover font from Hybrid Theories that I really liked, which I think Mike Shinoda sprayed somewhere and they put on the inside of the album cover I think, so their band name has this weird but cool font I like so I found it online and kept it for years now incase I ever had the opportunity to use it. And I decided I wanted to use it now but this font unfortunately has no numbers. And I decided to stick with the numbers from the Matrix movie cover, which means everything now has to be divided up between the two fonts, which means there is a lot of text that just says things like that it feels like 55 degrees and I need to figure out how to put the "feels like" in Linkin Park font, and the actual temperature text in Matrix font. 

    Friday I started looking at how to do this since I was kind of understanding the Python code well enough to make changes myself without Doug standing over me constantly, but not any change. And then I couldn't figure out how to do this. I tried to figure out where the actual text was written in the code to be printed to the screen, but I couldn't. I made some effort to try and figure out how to solve this problem going forward so I can figure these things out for myself without Doug holding my hand through everything. And this is especially time critical because technically I am supposes to be done with school in a month even though I easily have about three more months of classwork ahead of me and no time to do it except for when I'm in class, which is my project time where I can get Doug's help. 

    Doug had the idea of me doing an hour and a half at the beginning of class for classwork and then the last hour and a half for projects since he agreed I learn a great deal from these projects and the ultimate goal was for me to come here to brush up and also to do projects, and not so much to get certified even though there are lots of benefits to these certifications from CompTIA. So I have been doing that even though it isn't helping me to keep up in class. 

    So I talked to Doug about how I was going through the problem of trying to figure out how to separate the code for the letters and the numbers so I can use two different fonts  for each and I spent some time going through trying to figure out how to do this just for one little thing on the display, which would open the door to being able to do it for the rest of the display. I told Doug if I could go through with him on how I was trying to solve the problem right up to the point where I got stuck, maybe he would be able to point out what I do wrong when I am about to get stuck and then we can work on this right before I leave this class and hopefully i will finally consider myself competent...haha. 

    So he did. We have font objects, and then we had strong which are just text like the string HELLO or APPLE or whatever and the object font, which gives me a font type and size. And I mentioned how a problem I was having when testing is I will ask him questions about a test question I got, and I can't figure out but then he will just point out the thing I seemed to ignore, which I already understood but somehow missed, and I will say something like "Hey Doug, ...[test question about TELNET which is port 23] ..., I don't understand what it means when it gives me 4 IP addresses that start with 10 and they are...the first one has five octets, that can't be right, no IPv4 address has five octets!" He's like, "What is the last octet?" "It's a 56 for all but the last one...which is twenty thr...three. Huhhhhh! I missed that the dot between the last two octets wasn't a dot, it was a colin, this is an address with a port number for a certain protocol other than the default protocol. Got it, thanks Doug!" I miss it every single time!

    So I was hoping Doug could do one of those and then my 'figure it out yourself' problem will be solved. So I started explaining where I was about to get stuck when he interrupted and said that I already texted him about this back on Friday when I was doing this and he already knows where I got stuck. Oh? And he explained, I want you to go to the top of the document and start telling me what each line does. SO I was like, actually, I think I can do that with some ease. 

    "img = Image.open("background/weather-report-bg.png")"

    This line refers to the image that stands as the background, and it equates "img" with this document. It opens it and puts everything on top of it since code later dictates that it's in the back of everything, the backdrop everything is set against. 

    "draw = ImageDraw.Draw(img)"

    This tells it to draw the image.

    We went through several lines and it started to become clear that I wasn't paying attention to everything even though I understood a lot of it. He suggested that just like when I take tests, if I really work to make sure I understand each individual part of the question before moving on the understand each of the next parts and the multiple choice answers, then I should do much better on my tests. He suggested I do the same thing here. So now it is becoming apparent that what I struggle with is seeing everything that is right in front of me and giving it due attention. 

    I think what is going on here is I have a thing called Low Latency Inhibition, so I notice a lot of details about things that others ignore, and so I have to basically reinterpret everything on its own merits rather than just automatically seeing that every doorknob is just a doorknob, I have to wrap my head around it first and then eventually realize what it is. This is happening because most peoples Visual Cortex will take in all the stimuli the eyes pick up and process it and it has to throw a great deal of information away by determining what's important, and it's not doing this for me. An example of what this looks like is if you're being chased by a bear, you're not giving the slightest bit of thought to the pretty flowers on the side of the path you're running on. All of your focus is on the path and staying away from the bear and not getting eaten alive. So all those details like that piece of trash someone didn't throw away and that sign that says "Beware of Bears" all get thrown away by the Visual Cortex so you can narrow your focus according to the situation. Mine doesn't do that as much as others does. So I see a lot more things and pay attention to details that don't always matter which causes me to draw conclusions that are often useless. This is frustrating. However it does have a major benefit, which I only seldom get to enjoy. This is the same condition that Sherlock Holmes has. But his is dialed to eleven. 

    "...they go up to eleven, does that mean it's louder? Is it any louder?"

    "Well, it's one louder [than 10] isn't it?! It's not ten. You see, most blokes are gonna be play'n at ten, ...you're on ten on your guitar, where can you go from there? Where?"

    "I don't know."

    "Nowhere! Exactly. What we do is if we need that extra push over the cliff, you know what we do?"

    "Put it up to eleven."

    "Eleven, exactly! One louder!"

    "Why don't you just make ten louder and make ten be the top number and make that a little louder? 

    "...[pointing] these go to eleven!" 


Sherlock Holmes can look at something one time and derive all these details from it, and come to all sorts of conclusions. The difference is he does this very fast, with multiple details, uses them to come to a number of conclusions...and he is uh ... right about his conclusions a lot of the time. 

    So yeah, now that I drew the link between myself and the nonexistent genius of Sherlock Holmes, I will end there for tonight. 


    Monday 2024-06-03 

    I got a little carried away with working on the project and not writing about it. But the big problem here is that my instructor did most of the programming that actually got all the parts to work. But he wasn't going to manually adjust the placements, sizes and fonts and pictures of everything on the display for me especially since I have such particular tastes. And little did I know, this project was going to really introduce me to coding. And I suppose it couldn't have been a better language that Python because Python is so ubiquitous right now. 

    At first, the display was going to have just a white image behind the text with a few lines and a black header line to put white text on to say the name of the project and give the time in tiny text and so on. And eventually came a point where I got tired of adjusting the lines in paint.net (my photoshop is on the fritz), which separate the current feels like temperature from the minimum temp, max temp, humidity and wind speed. I got rid of the black lines because I felt that they were unnecessary. 

    I know I already talked about this, but at this same time Doug was working on an alternate program to put on my Pi to work with my e-ink display, so if for whatever reason I got tired of displaying the weather, which I don't think I will because I am a weather enthusiast and always want to know conditions before I go outside so I don't need to come back upstairs to grab my coat or something, Doug created a program that just displays the time against an image. Then he got fancy and created an algorithm that will look at the image and if it's a darker image, it will switch the time text from white to black or visa versa. Then he created another algorithm that will place the time text in any one of the four corners depending on where there's the most contrast to put the text against, so if there's more black pixels then it'll display white text for example. He got all this working and I started to actually really kind of want to buy another Pi and another screen so I could have this as a dedicated clock in another spot in my room. I wondered why Doug was doing this even though I was definitely all about the weather display and apparently he just wanted to challenge himself. 

    We also determined that there were still cases where the time text was hard to see so he found a way to put outlines around all the numbers. This turns out to be interesting and I ended up utilizing it in a big way. He was against adding it himself to my weather display to make it look cooler because he said how many lines of code I have right now and that he would be multiplying that by 120 or some huge number and he was absolutely not going to do that. I asked, well, you're not going to discourage me from doing it are you? He said no. And then explained how to do it. So I did it. 

    I started getting to work about a week and a half or two weeks ago on arranging the text on the weather display in the code. In some ways the code wasn't the prettiest because Doug wasn't all about making things easy to interpret but he then added comments at the end of many lines and labeled them, so I kept up the tradition when I made changes and even redid some of his and sorted parts of the code out for my liking since I have a hard time seeing things that are right in front of me. I kept making changes and not being able to find things so I started to organize things to my liking. I think I will go ahead and paste the code as it is right now or maybe the final version at the end. 

    I changed the current temperature and the time so they were the most prominent on the screen. And then added some of my favorite fonts to the code. I have things like a certain Linkin Park font I used for most alphabetical text on the screen and then all the numbers used Matrix movie cover font. 

    Doug put an outline of layers in python code to make the time stand out better no matter what image was displayed behind the clock and that made me want to do it too. So he showed me how to do it since this would add so many lines of code for every single line printed to the page that he was not about to touch that himself, he said we can't do that because he won't do it and I asked him how hard it would be for me to do it and it turned out it was quite simple and I was perfectly willing to take the time to do this for myself. 

    Then we were talking last Thursday about how I haven't been doing the research assignments and I said well I suppose I'd be willing to put a few minutes into writing a research assignment paper on how to do the layers in python code for the text on my weather display and Doug said ok, in fact, I want you to write it like it's an entry in a knowledge base, which is a good skill to have. SO he pulled up an example of a knowledge base which he writes all the time for his other job at BYU, which people can then reference if they need to replicate what he did and he isn't there or he can't do it or whatever. 

    So, here's what I wrote:

    Layering Text in Python Code with draw.text

Assuming you already know how to do some coding in Python3, this guide will demonstrate how to layer your text in order to create a cool effect or to outline text so that it's easier to see for example, if it is drawn in front of a dynamic image, which makes seeing lettering more difficult to see. 

Lets say you have a string of text such as the time being displayed in a screen:


"draw.text((293, 198),TimeDate.strftime("%I:%M"), font = font_big)"



        In this image, the time has the affect applied to the time. 

In this particular case, the text automatically displays as black, using a Matrix movie cover font. However, if for example you wanted the text to diaplay as white with a black outline, you can add "fill = 'white'" isolated by commas from the rest of the code and you can add this  after "TimeDate.strftime("%I:%M"),", or you can add this to the end after the font is specified, preceeded with a comma. 


"draw.text((305, 204),TimeDate.strftime("%I:%M"), fill = 'white', font = font_big)"


However as you want the text to be white in this case with a black outline or shadows for the text, you would write all the lines of code in a layer fashion for all of the outline text or shadow text to lie underneath the main text, and the last line will the text with the "fill = 'white'" command. The code for text with 5 layers of shadows looks like this:


"draw.text((293, 198),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((299, 210),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((309, 198),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((307, 208),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((294, 208),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((305, 204),TimeDate.strftime("%I:%M"), fill = 'white', font = font_big)"


It is important to understand the placement of the layers. They're drawn in a pixel coordinate fashion. You'll notice that after "draw.text" is two parentheses, one to open the location and definituion of the code that is to be inserted so the system knows what to do with it, and then a second opening parentheses to specify just the coordinants. If you look at the coordinate numbers for each layer or line, you'll see each of the pixel coordinates is slightly off from the others. This was to create a certain aesthetic for the text in question and to make sure that certain parts of the text had an outline so it'd be distinguishable from the background picture. 


It is also useful to understand that if you which to fully encapsulate the text in shdaow or underlying outline text, then you need to draw either all four shdaows around the edges of the main text, one above, one below, one to the left and one to the right. Or you can draw in an X fashion rather than a cross fashion. If for whatever reason this doesn't fully encapsulte the text as you will see the font used in this example is more complex and has more sides and edges and markings throughout the text than your average text does, so in this case you can add more layers following this same pattern. 


Review the included imagef file with this document to see the example. 


For easy copying, use the following example: 


draw.text((293, 198),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((299, 210),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((309, 198),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((307, 208),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((294, 208),TimeDate.strftime("%I:%M"), font = font_big)

draw.text((305, 204),TimeDate.strftime("%I:%M"), fill = 'white', font = font_big)

Keep in mind you will have to have variables defining the font type, and size, and where the .ttf (truetypefont) files are located written before these text layers. 


        Monday 2024-06-16 

    Doug liked that so much he wanted me to do it again and this time to explain how to use a mask with Python. So here we go again. I don't know if this is a thing that people already did or if somehow Doug just figured out a way to do this. But if you use3 Photoshop and do masking, then you are familiar with this concept. However, we didn't use Photoshop for this. I was going to but then it stopped working on my laptop and I didn't have the time to troubleshoot so he suggested I juts install Paint.net and that would allow me to do a great deal of the things Photoshop allows and would fulfill all of our needs. I was surprised, it even had layers and filters. 

    This was actually a long journey with complexity and luck. It all started with Doug working on the clock project he just decided to do off the back of my weather display and putting an image in the background. In the process of this Doug got concerned that we should figure out how to save refresh cycles on my e-ink display because the number of refreshes an e-ink display does is what really wears them down. They don't refresh hardly ever unless you're turning the page and stuff like that. So Kindles are really popular and last a while for most people. When we first set the screen up with the Pi-hat from Waveshare for this 7 inch screen, it seemed to refresh like four times or something like that every time you wanted to change the display. That took time and was kind of obnoxious to watch. He figured out how to get it to only refresh twice. Now, there was something about how it had to refresh at least twice because what happens to release any stuck particles in the display, it inverts the image that you are refreshing to and displays it and so that's one refresh and then another to reverse the inversion. It also just happens that if you look at the back of the display between refreshes, you can see that the inverse of whatever is on the front of the screen is visible on the back of it. The particles literally switch places. 

    However, he kept tinkering because there were all these options that he was trying to figure out how they worked while I was doing other parts of the weather display project, and he kept trying to figure out how to do a partial refresh on the screen instead of a full screen refresh because he thought that would save refresh cycles and I wouldn't have to replace the screen as often. I told him however, that it doesn't matter to me as much. He kept thinking that we need to save refreshes which I liked the idea of, but not by sacrificing things like the clock only updating once every five minutes or something like that. And I also told him if he couldn't figure out the partial refresh thing, it's not the end of the world because ultimately, this isn't very useful or appealing anymore if the one part of the screen that updates all the time is worn out and the rest works just fine. He's like yeah but you wouldn't have to replace the screen as often. I said, I would rather replace the whole screen than worry about moving the time around to different parts of the screen just to get around certain parts being worn out more than others. I want everything on the screen to display properly. This isn't some dystopian movie where they're using old technology or mixed parts to jimmy rig something together to make it work. I would be willing to replace the screen at that point. 

    He kept working on it and finally cracked the but one day and was really proud of himself. But there was a new problem. You see, he got the screen to do a partial refresh just for the time and nothing else, but this had consequences. This means that the original display since the last full refresh will still be there, it's just covered by a new partial refresh of the image. So every time the clock goes up one minute, lets say it's 10:30, there will be a new image placed over the zero of the minutes in order to display a 1. And then another placed over that one minute later to display a 2. And on and on this goes until ever so often, I have it set to do a full refresh or something. But he was having trouble getting it to display this properly. It sounded to me at the time that he was saying I would have to sacrifice either the partial refresh or the clock itself in his clock display and my weather display as well, or there'd have to be some very unclean, choppy cut and paste like job--but no worry, at least I'd get the partial refresh, the time updating minutely, and everything else would be displayed as desired, there would just be some cosmetic issues. 

    And then a while later like a week or something like that, he cracked that nut too. And now it refreshes every minute without any cosmetic issues whatsoever, just the minute changes, and apparently, there are hidden layers of previous times going way back to the most recent full refresh. So that was cool that he figured that out. And he was so pleased that this was going to work properly and now I would have this and this and that, and I then said, yeah, but how am I ever going to write about this in the blog? You did it, I didn't have the luxury of watching you do it with constant explanations, and you're not going to explain it to me because that would be too complicated and take forever. And honestly, there are a lot of details he wouldn't remember anyway. Considering my writing style where elaborate on every microscopic detail to the enth-degree in-perpetuity and often never actually make my point. 

    So I guess that's where these Knowledge Bases come in. We're killing multiple birds with one stone. I haven't been doing my research assignments or my assignments once a week to improve my employment situation other than to work on this project, and I haven't added to my blog in a while because of all the stuff that I would have to explain that I cannot explain, and plus just how incredibly busy I am every single day from sunrise to sunset and far beyond with work and dieting and working out and church stuff and school and assignments and projects and errands, and then really annoyingly, friends! Tss.  I mean seriously, who has time for friends! What a waste of my time. Like they just want to sit and do stuff that isn't important. Lol. 

    So Doug is having me do Knowledge Bases for each aspect of this project in order to get all of those birds killed. 

    Alright, so that thing where the time keeps updating over itself in partial refreshes, that is essentially the mask. It is just like a mask in Photoshop or something. So when I decided I wanted to add Matric movie Digital Rain code to the display, just to deal with the empty spaces between all the data being shown, I know, yes there is already a background image, but it just seemed strange to me to have information jam packed all over the display but not be able to organize everything in such a way that there is no wasted space to my satisfaction and display this background image. SO I decided to just have stuff displaying on the screen that is totally static--it never changes. The background image occasionally changes, the weather updates ever so often, the time changes every minute, but this one thing doesn't change. Doug thought the display was already way too busy for this. But I was determined to find a way to make it work. I started by trying to figure out how to display text all across the screen. 

    So we used wrap-around text in the Python code to do this, with a "/n" about every 57 characters to define a new line without actually writing the code on a separate line like code is not meant to do. However long the line needs to be is how long it is in programming, but if you need to insert new lines like it's a document, then this can be a problem for programming so the /n function comes in handy. I forget the terminology that programming uses for this. And so depending on the size of all the characters in the line, to cover the screen with these Matrix Digital Rain characters, it could be more than 587 characters for the screen I am using. 

    I didn't realize Digital Rain, this whole time, was Japanese written language, I've watched the movies a million times and had no clue. I even had the screensaver on my PC at home for ten years. And apparently, it's called Kanji. I assume the reason they use Kanji for digital rain is because anime is huge in Japan and the Matrix movies were chalk full of things the Wachowski's liked such as kung fu and stuff like that. This is just a guess. 

    It actually got pretty trying to keep writing random characters 57 or so characters long with a break for a new paragraph using /n and keep getting the wrong lengths because I didn't want the code to be any longer than it had to be to fill the screen, and with the font size I was using it needed a lot of lines. Doug suggested to speed the process up I could just copy a few lines and I told him I would notice. I would know I did it and not stop looking for it until I found the lack of randomness. So then I had the idea to do what he said, but to reuse random lines for the last half of the screen. 

    Also, it covered the whole screen and made the information displaying for weather and time too hard to see. And then it also rendered the background image pointless. So I experimented with only outlining the screen with Kanji, and that took a lot of extra effort, I didn't want to have this huge and endless line of code with all these broken up spaces in them and asked Doug if there's a way to just tell the program that I want it to insert twenty spaces here and forty five there and it can just simulate that without me having to have forty five spaces in the code. He said not to his knowledge, I would have to figure that out myself. But then he asked why I didn't just create a mask. 

    What!? 

    Yeah, do a mask. You remember this! We had to mess around last week with the weather icon images for like cloudy skies showing two clouds next to the temperature and weather condition. Or dropping dots for rain and so on. I wanted the icons to be transparent, so I could just have the outline of the cloud but see the background image behind the icon where the empty cloud space is. So we experimented with that and found that .png is one of few image formats that allow this. .ico is another. That is the format that windows icons actually use. And both of these formats have a unique feature. Say for example you want to have an icon blend seamlessly into the wallpaper of your desktop. Well, I've never seen a Jpeg pull that off without the frame of the image squaring off whatever the image is. So how do icons do this? It's a transparency feature that as far as I am aware, only .png and .ico allows. You have to use a .png to create an image like tis, and then you can use an image conversion website online to convert the .png into a .ico so you can then switch your icons on your computer to that .ico image. 

    So to my surprise, I already knew this, and learned how to do it one day ten years ago out of boredom and a  reluctancy to look for jobs--probably the thing I hate doing most out of everything else. I think I would rather chew broken glass than look for a job! I would rather work a bad job than to look for a good one; and I have! 

    Anyway, so for the weather icons, and this just kept getting more complicated because of my layering with all the text, I wanted a similar effect with the icons as well. I had the idea to do layers with the cons after we figured out how to make them transparent but Doug was juts like, look, lets just figure out how to make them transparent first and then in Paint.net, you can just create the effect there with layers and then flatten the icons and then place one image for each icon in the program. Okay fine. I created the icons as I wished in paint.net, I saved them as .png's, I turned to Doug and said okay so how did you do that mask thing you were talking about? He wanted to see so I showed him them but I told him there's a problem. You can't just delete the background from the image and save it as a .png for some reason and have that void space. I have done it before but I don't know why it's not working now, and I am not as familiar with Paint.net as I am with Photoshop. So we did it again, deleted the backgrounds from the icons, and this time I didn't save them and close them to my chagrin, and we had to save them as 1 bit so that there would only be black and white pixels because if there is even one shade of gray in the entire image, the display gets all discombobulated and won't work. We went through this a while back. We even had trouble getting an all white image to display when Doug had the idea to simply add one black pixel to the upper left corner that was small enough not to be noticeable and for whatever reason, this allowed the image to work. So now, apparently 32 bit was crucial to make .png display transparency. But the images had to be 1 bit for the display to use them. What gives! We tried saving them as automatic bit rate, saving in the proper folder and updating the image and it still didn't work, and on a hunch, Doug tried saving the images at first as 1 bit with dithering which is crucial for this display, and closing them and then re-opening them and re-deleting the background of the icons again, and then resaving them as 32 bit so we could take advantage of transparency. It worked. 


Well, it sort of worked, anyway. The icon displayed properly, just not anything else but the background image. Btw, I took that picture of the Shelby Cobra 427 at Park City like fifteen years ago, and you have no idea how much I wish I had asked the dude to remove his papers for the car from the windshield before I took the pictures of his car. I dealt with that for years and finally got around to photoshopping them out manually and having to create I think it was the passenger side hop bars from scratch to get rid of the eye sore that was those papers. What a pain!

    We did get the icon problem sorted out but I don't remember at this point how we did it. 

    So this is the very last bit of code in the program:

        icon = Image.open("resources/icons/clouds.png")     # icon weather condition image
        img.paste(icon, (3, 75),icon) # the second icon is a mask!

        #icon_border = Image.open("resources/icons/border.png")     # icon border (temporary)
        #img.paste(icon_border, (3, 75),icon_border)

        # Write image to the screen
        img.save("screen.png")

    So icon = image.open is telling the system that anytime you write icon as a command, it'll open the image for the icon to the corresponding weather condition. And in parentheses is the file path to grab the icons from. The icon border is just a thing I created to outline the entire space the icon may take up without having to keep displaying this huge black square in the middle of my display. I wanted to see behind the black box after weeks of programming with a black box there. But we couldn't use the icons themselves because the cloudy icon may not take up the same aera of the available space for the icons that for instance, the sun icon might take. All the icons are shaped differently and take up various amounts of the frame that is invisible to the viewer if the black box wasn't standing in for it. I got tired of it so I created a black outline for the frame so if I needed to move anything, it wouldn't accidentally infringe with the icon images and I would only discover this like a month from now or something. When I was done with it, I commented it out with a hashmark or pound sign so the program would ignore it as programming notes not to be read by the program itself. 

    And then the next line said to paste the icon and what its pixel coordinates on the screen would be. After the pixel coordinates, you'll notice that icon is written a second time. This is important! 

    So if you'll notice, the line goes like this "img.paste(icon, (3, 75),icon)", so it pastes the image, says its an icon so the program knows where to get it and what it is, the pixel coordinates, and then it says icon again. Why? Well, this is the mask making its first appearance to my program. 

    What happens here is python can't do fancy transparency stuff lie .png can. It has a .png that says to do it, but in order for it to display, the program is still automatically going to fill all the space behind the icon with something. You can't put an image there without there being nothing behind it. So my background images would be obscured by this inconvenient image backing that the program automatically puts in there. But there is a workaround. A mask! 

    What the mask does is when you display it again, it tells the program that whatever space is taken up by that second image, just remove the image from that spot. So you have the image, and then you pate another one over the parts you want to get rid of, and that second iteration becomes a mask which tells the program to erase any pixels in the first iteration that are then taken up by the mask on the display. 

    So when the wraparound text from the Kanji became an issue, Doug had me create a mask. I went into Paint.net and took one of my display examples, cleared it with all white with the paint bucket and used a brush and the eraser tool to blotch in spaces where I didn't wa t the Kanji to obscure the background image and weather and time information. I wanted to have a dirty look, like the Kanji was there but it was broken up, it didn't come through clearly or whatever, but you could still see that the Kanji was supposed to be there. Doug realized that this was do-able because we were using dithering. We were going to have to dither the image for one reason or another, so instead of dithering for no reason, we were able to use it to create the effect I wanted with opacity changes to the Kanji text. 


    I had to be careful where to put Kanji and where to remove it with the mask because if it was prominently displayed where weather info might be displayed even if it isn't displayed in this image at this time, I don't want it to not be visible enough to read easily later. So there are noticeable gaps where you would think Kanji would be displayed. I have since also refined the mask so it looks a little less roughly created, like under the 0 for the time. 

    In case its not obvious, I also created layers for the Kanji text so it'd be noticeable regardless of the overall color of the background image. So whether it's white or grayish or black, you can still see the Kanji. 

        Thursday 2024-07-11

    Fun update, not much work has been done on the Weather Display for several weeks because tests had to be taken and Doug was out several times last week so my troubleshooting didn't go very far. And I recently pulled the screen out to start working on the project again having started a few weeks ago on making the frame that the screen, Pi and hub were going to go in to be hanged on my wall, but Jack knows Blender and offered to make the frame in 3D but doesn't come to class much, and then came in a few times this week to get his attendance back up and helped again with Blender and I quickly reached the point where I had to figure out the light source that will light up my display so I can see it at night but not so bright that it lights up the room and preferably only lights up the display itself. Doug and I were thinking of buying an LED RGB light strip that's three feet long and cut it to seven inches, since the lights are really close together and this strip can be cut between every single light. And then we were discussing where the light would go and had a few ideas I liked but Doug then added that we could put the light strip behind the display since it is transparent. I didn't like this idea but was looking at it and decided to put a flashlight behind it and look at it to see how I felt about it because it would be the best option if it actually worked. And there was a sticker on the back so I tried to pry off the sticker, and then went to grab a disposable wipe at Doug's desk which I thought would be more abrasive without falling apart like a paper towel. And I grabbed the wipe and dropped the screen and it hit the carpet and cracked in two places in the middle of the screen because it is really thin. I tested it and it is definitely a lot cause. I have to buy another one. So it's coming tomorrow and I can't do much with it till then. 


    Wednesday 2024-07-17

    So Doug and I went to work on the weather display again. Everything that needed to be done with the display was basically done, now we just needed to write scripts that would run the python program Doug and I had created several months ago. Doug likes to write separate scripts that run other scripts. He told me since I am still really new at writing scripts, I aught to have ChatGPT do write this separate script, and I could go into detail about what I need from the script. I didn't have a lot of faith in this. I have tried doing this in the past and not had good results on numerous occasions. So I was very skeptical. I was willing to do it but I wasn't jumping right on it because I didn't think it'd work this time either. I thought it would come close but that it would be messy and not actually provide the desired result. Well, I finally did it today. 

    I told ChatGPT "I need to write an activation script in python3 that will activate a number of other scripts or programs in python, which will start by running a file called "checkWeather.py" in the folder "weather-report" every 30 minutes and then every minute, running a file called "updateTime.py" in the same folder. And I want it to skip running "updateTime.py anytime it runs "checkWeather.py". Also, the "updateTime.py" script needs to run when the time changes, so the display this runs, doesn't show time changes like 30 seconds after the time has changed. The "updateTime.py" script takes 3 seconds to run. And the "checkWeather.py" script takes 15 seconds to run. So the "checkWeather.py" script needs to run at any time when first activated by the activation script, but then it needs to run at the 30 minute mark of every hour and also again at the beginning of every new hour. And it needs to be run 14 seconds before the new hour and 14 seconds before the 30 minute mark. The "updateTime.py" script can be run 2 seconds before the new minute every minute."

    I wanted it to run the time update a full second late after the new minute because I didn't want to risk that it starts updating and always updates like four or five seconds after the new minute but I also really didn't want it to update the time from like 5:34PM to 5:34PM because it was still 5:34 when it was set to update the time to the current minute. So I wanted it to finish updating one second late during the new minute each time so that it would officially be 5:35 when the update finalizes and it would show the latest minute instead of the last one every time it updated. I don't know if I am overthinking this but I didn't want to risk that once the time information is fetched and it updates the screen, that it updates it with a time that is now passed. I would rather have it be a second or two off at the new minute than a whole minute off every single time. 

    It worked rather well. ChatGPT gave me:

"

import sched

import time

import subprocess

from datetime import datetime


scheduler = sched.scheduler(time.time, time.sleep)


def run_check_weather():

    subprocess.run(["python3", "weather-report/checkWeather.py"])


def run_update_time():

    subprocess.run(["python3", "weather-report/updateTime.py"])


def schedule_tasks():

    now = datetime.now()

    current_minute = now.minute

    current_second = now.second

    next_minute = (current_minute + 1) % 60

    next_hour = (now.hour + 1) % 24


    # Schedule checkWeather.py at the 30 minute mark and at the top of the hour

    if now.minute == 30:

        # Calculate the seconds until the next run

        seconds_until_next_check = 14 - current_second

    else:

        seconds_until_next_check = 60 * (30 - current_minute) + 14 - current_second


    scheduler.enter(seconds_until_next_check, 1, run_check_weather)

    scheduler.enter(seconds_until_next_check + 1800, 1, run_check_weather)  # 30 mins later


    # Schedule updateTime.py every minute except when checkWeather.py is scheduled

    for i in range(60):

        if i != 0 and i % 30 != 0:

            seconds_until_update = 60 * i - 2 - current_second

            scheduler.enter(seconds_until_update, 1, run_update_time)


    # Schedule next round of tasks

    scheduler.enter(3600 - current_minute * 60 - current_second, 1, schedule_tasks)


def main():

    schedule_tasks()

    scheduler.run()


if __name__ == "__main__":

    main()

"

    I was shocked! Doug did look at it and he said that for what I asked it to do, there was a lot of extra code in there that was unnecessary, for instance at the end, it defines main as schedule tasks and then if the name is main then run main when according to Doug, this was completely unnecessary and it also went through a whole thing of creating this elaborate schedule thing which could be majorly simplified and work the same. But he said it should run fine. 

    We loaded it up, it didn't run, but then we discovered that because I told ChatGPT that the files I want to run were inside this one folder, it wrote the code so that it would always specify that folder in the file path, when the whole time, the script ChatGPT just wrote for me would be in that same folder. I had ChatGPT write it as a relative path rather than a full file path. So when this code ran, it didn't run because the Pi went looking for these two time and weather programs in a folder that didn't exist. The script should have been written so that it was either assumed that the two programs were in the same folder as the script activating them, or a full file path should have been given in the script for both programs so that the Pi would ultimately always start from the home directory and look for the programs in the folder they are located in regardless of what directory or folder tat was being worked from at that time. 

    Doug quickly changed both of the file paths to the full file path in the activation script. Problem solved. We were both delighted when we were able to watch it update the time every minute only one second late as I requested, and then updated the weather and time and the background image every half hour. 

    After this, I said it would be nice if I had a button I could press which would tell the Pi to switch from my weather display to Doug's background image and time program which is really cool, has some awesome features which use algorithm's to decide where to put the time based on the contrast of the image in any one of the four corners, so that the time gets placed in the least busiest part of the image and displays as white if its a dark area of the picture or back if it's a bright area of the picture. It's really clean and cool looking and crisp a lot of the time. I don't want to never use it so I asked Doug about using a button and he ultimately said that it could be done but it would require rewriting a lot of what we have already done. A far easier way would be to write yet another over-over-arching script that runs on startup so every time you cut power to the Pi, it automatically runs one of these two scripts and depending on which one ran the last time the Pi was booted, it will instead run the other program. So all I would need to do is unplug it and re-plug it in and around a minute later, the e-ink display would be updated with the other program.

    I thought that would be cool but ultimately wanted the button but he sort of shattered by hopes and dreams by talking about re-programing the whole thing just to include a button. Alternatively I could always buy another Pi and screen and Pi hat and have one program on one Pi and the other program on the second Pi. But I'll have to think about that and certainly wouldn't do it right now. 

    So right before class was over, Doug started working furiously to see if he could get Python to run on startup and did figure out how do to so. But when we programmed it to work and tested it before class was officially over, it didn't work. He said, well that's it for today, we'll try again tomorrow. 


     Tuesday 2024-07-23   

    I got set up and thought we were working on getting these programs to run on startup. So I plugged it in and we were talking about the whole CrowdStrike debacle at BYU that he had to work on and he was out of town when it happened so when he got back, these past few days have been rough. And I just happened to look over at my screen and instead of the picture of the Saleen S7 car and 8:59PM displayed on the screen, instead there was a Shelby Mustang GT500 and the time was 6:30PM. 

    Huh?

    Hey Doug, it's working, it ran the over-arching script on startup!

    So now we just need to write another over-over-arching script that will switch between the two programs depending on which one ran on the last boot. 

    To ChatGPT again. I am actually a bit confused about this one because the way I see it, if it is running on startup, this means that the over-over-arching script needs to know what OS is running on it so it can somehow tell it in whatever it is doing to wait, load this please. But it seems like Doug says that's not the case and I don't understand why. 

    We had to put this on h9old however because at one of the thirty minute marks when the check-weather program I have been working on for a month or two several months ago updates every half hour, we just noticed that it is updating the time thirty seconds late. So Doug and I nano-ed the activation script ChatGPT wrote last Wednesday and we combed over the scheduling code per my specifications and found something interesting. In the code which says when to run checkWeather.py every thirty minutes, and updateTime.py every minute, if you compare what the code says for updateTime.py and what it says for checkWeather.py, it says:

"

# Schedule checkWeather.py at the 30 minute mark and at the top of the hour

    if now.minute == 30:

        # Calculate the seconds until the next run

        seconds_until_next_check = 14 - current_second

    else:

        seconds_until_next_check = 60 * (30 - current_minute) + 14 - current_second


    scheduler.enter(seconds_until_next_check, 1, run_check_weather)

    scheduler.enter(seconds_until_next_check + 1800, 1, run_check_weather)  # 30 mins later


    # Schedule updateTime.py every minute except when checkWeather.py is scheduled

    for i in range(60):

        if i != 0 and i % 30 != 0:

            seconds_until_update = 60 * i - 2 - current_second

            scheduler.enter(seconds_until_update, 1, run_update_time)

"

    So if you look closely, you can see that updateTime.py which runs properly says:

"seconds_until_update = 60 * i - 2 - current_second"

    And then checkWeather.py by comparrison says:

"seconds_until_next_check = 60 * (30 - current_minute) + 14 - current_second"

    Why did ChatGPT tell it to run at the time plus 14 seconds rather than minus 14? So after studying it for a while we changed it to:

        "seconds_until_next_check = 60 - 13 - current_second

    else:

        seconds_until_next_check = 60 * (30 - current_minute) - 13 - current_second"

    Both of the red highlighted minus's were plus's and so we changed those. But this wasn't the only change we had to make. We had to nano into checkWeather.py and look for where the program updates the time for every 30 minute and 1 hour mark:

"TimeDate = datetime.now()"

    We changed it to: 

"TimeDate = datetime.now()+timedelta(seconds=20)"

    In python, timedelta is a part of the datetime module and helps calculate the difference between two events. In this case, we want the time to start updating to the next minute 20 seconds before the time changes because despite my attempts in ChatGPT to have it finish updating a second late into the new minute, it was still displaying the previous minute when the activation script ran checkWeather.py.  

    We put 20 seconds because we wanted it to be greater than the 14 second delay otherwise it might still give us the wrong minute because we tested it after we made the first change in the activation script and what happened was on the new hour mark, it updated the time to the same time five seconds before to the time changed at the new hour, leaving the time outdated, so it didn't update the time right at the 1 hour mark, and then for some reason Doug and I didn't understand, the updateTime.py script then updated the time properly fifteen seconds after the new hour started even though I had specified to ChatGPT to not have it run when checkWeather.py runs. Well, okay, that just answered our question...tss. Because checkWeather.py did not run at the new hour mark because it did it fifteen seconds earlier, the Pi was like, oh, I am supposed to then run updateTime.py. We don't know why it was fifteen seconds late, but the discrepancy with it changing the time at the wrong time was with checkWeather.py and not updateTime.py.  imagine that it waited for checkWeather.py to finish r something and then waited a few seconds since updateTime.py also takes some time. Maybe it wasn't fifteen seconds late, maybe it was five or ten. I don't know for sure. because we weren't timing it when this happened. 

    A couple of funny jokes while we were doing all this, my classmate and friend Jack passed CompTIA Network+ last night so he is sort of done with the program except that there are some details that have to be sorted. And he got one of the highest scores, Doug was trying to remember the highest score any student had gotten on the certification exam and said yeah, 795, (passing is 720 and most people don't get anywhere near that and this was Jack's first try and most people have to take it multiple times and may don't even pass it then. I took it once. Then Doug started going over how everyone in the class was passing this, this and that and that thing over there too, he named like ten students that took various certification exams and how they passed, and then he said we have had a good run lately. And he was like, "When...who failed last?..." And he looked across the classroom at me and said "Christian!" Everyone started laughing. 

    "Hey wait!"

    "He then added, "Well, Christian failed it on purpose so he could buy more time because he wants to keep hounding me for help with projects so that doesn't really count." Tss


    Thursday 2024-07-25

    I again went to ChatGPT to write what Doug has lovingly named for me the "overOverOverOverarchingScript.py", which is the over, overarching script that will run either runThisToRunEverything.py  or runThisToRunEverything2.py, and the former is the script I wrote last week which will run my weather display and the latter is the script that will run Doug's clock program. And whichever was running on the last boot, overOverOverOverarchingScript.py will run the other instead so that every time it boots, it will automatically switch to and activate the other program and the scripts that keep running it every minute. 

    I went to ChatGPT and wrote "I need a script in python3 on a raspberry pi os called "overOverOverOverarchingScript.py" located the home folder and it's going to activate one file in a folder at home/user/weather-report/. and it's called runThisToRunEverything.py and also another file in folder path home/user/image-display-tools/. and the file is called runThisToRunEverything2.py. And the purpose of the overOverOverOverarchingScript.py which I need written now is that when the Pi boots, it checks which program was running on the last boot, either runThisToRunEverything.py or runThisToRunEverything2.py. And depending on which one was running on last boot, overOverOverOverarchingScript.py will activate the other one instead. So every time the pi boots, it will run the opposite script from the last boot and rebooting will automatically activate the other script."

    ChatGPT gave me an output of:

"

import os

import subprocess


# Paths to the scripts

script1 = "/home/user/weather-report/runThisToRunEverything.py"

script2 = "/home/user/image-display-tools/runThisToRunEverything2.py"


# Path to the state file

state_file = "/home/user/last_script.txt"


def read_last_script():

    if os.path.exists(state_file):

        with open(state_file, 'r') as file:

            return file.read().strip()

    return None


def write_last_script(script):

    with open(state_file, 'w') as file:

        file.write(script)


def run_script(script):

    subprocess.run(["python3", script])


def main():

    last_script = read_last_script()

    

    if last_script == script1:

        next_script = script2

    else:

        next_script = script1

    

    run_script(next_script)

    write_last_script(next_script)


if __name__ == "__main__":

    main()

"

    It also wanted me to create the state file called "last_script":

echo "/home/user/weather-report/runThisToRunEverything.py" > /home/user/last_script.txt

You just paste this line into the cli and run it and it creates the file for you. Then we went to "/etc/systemd/system/weather_report.service" and we edited the file to point to the one we wanted it to read, which in this case is called overOverOverOverarchingScript.py. It was like a text document with the name of the file, then the description, and then one with command to execute when the service is started which is where we put the overarching script. 

    Then we ran "sudo systemctl daemon-reload" which basically applies changes to services. And then we did "car last_script.txt" which said "/home/user/weather-report/runThisToRunEverything.py", basically telling us that weather-report ran last. 

    We rebooted to see if it worked and it didn't. So now we have to wait till Monday to figure out why. 


    Monday - 2024-08-19

    Apparently it works fine until it doesn't and then the problem seems to disappear on its own. 









This has been Truncat3d 00000000111100010100110______________end of line

2025-07-10 - BYU Wi‑Fi captive portal troubleshooting

  BYU Wi‑Fi Captive Portal Troubleshooting What happened I had used BYU Wi‑Fi just fine before, but at some point, the captive portal star...