Farmer on-going protests
Before I start with the education system in India which I have talked about many times in the past, first let me share couple of pieces about the farmer movement which is still at Sanghu Delhi border.
<Manjeet Kaur,62 at farmer protest with her friends.
The above picture became somewhat viral as it showed Manjeet Kaur, who drove down from Patiala, Punjab to Sanghu border along with her friends to take part in the on-going protests. The picture not only shares how the women are part and parcel of this protest but also they are independently taking part in the protest.
The other were two articles I read today, first was an article in tribune which questions that if the policy worked, why it didn t work in the state of Bihar. The other by a young law student who had to go from Chandigarh to Delhi with family for some work and her experience with the ongoing protest. In fact, an interesting observation was made by the CJI in the many suits against farmer protests in the SC. This makes for much more interesting read when you see an RTI query filed by Saket Gokhale to NHAI , a Central Govt. agency which is supposed to be independent and asks if they had filed an FIR and asked compensation from Haryana State and Haryana State Police which had dug up National Highway 44 and if any permission was asked for the same from NHAI. And NHAI unable to take any action for the same. If this isn t shameful, I dunno what is
Saket Gokhale s RTI query on digging up NH44
NHAI response to Saket Gokhale s query.
Sadly, the way the response has been worded makes it impossible for NHAI to discharge its own responsibilities and this becomes a precedent for other states now that know that NHAI is vulnerable. A pretty sad turn on events.
Indian Education can t go online
There was a recent article on scroll which shared how Indian education can t go online as only a few have computers with decent netlink speeds as well as other factors which are needed for online education. But there are also many things that the article doesn t take into account which actually make the task more difficult and raise the boundary more.
Now in most schools and colleges, the number of students to teacher ratio could be anywhere between 70-150 or even more. In the last few years, a lot of schools have been closed down by various Governments, including and not limited to the ruling Govt. They have in fact intensified closures of public schools wherever their Govt. has been in power. Closing to 5000+ schools in one state in a year is a dramatic shift and such has been happening time and again. In fact, the rising costs of Indian education has made many to leave Indian shores and do studies abroad. And once they do their masters or whatever, the chances of them coming back to India become more and more remote. In India the costs have been becoming so bad that NBFC s have started products targeting the same. How NBFC and Banks have (both public and private) have fared with respect to Indian consumers needs its own blog post but one word to describe it is bad . But as shared above, needs its own blog post.
Coming to the Indian context though, what has not been captured in that article is that the responsibility of making new content also raises huge barriers for teachers. My own experience in teacher s trainings for ICT usage has shown that most teachers do not know and use internet effectively both to sustain their own curiosity as well as their students. Part of which is whether you are private employee or a public school teacher, the teacher is not paid enough. I have had multiple conversations with friends over the years who are teachers who shared that they get 50% salary in-hand while they sign for 100%. This is more in the case or private schools though. In Govt. schools, the teachers apart from their regular administrative duties apart from teaching duties are also unpaid labor for Govt. policy. Take the recent covid crisis, it was the teachers who for months together went from door-to-door asking if they had a covid patient. This was all over India. Even for voter registration, census, polio and various other immunization efforts, the teachers are roped in. So apart from that, they somehow have to figure out how to make ends meet and also boost student morale. Hence the attention is only limited to the first couple of benches rather than the whole as a 45-minute to an hr. session is just not enough to go through a class of 70-150 school students giving individual attention. And this is when for most teachers, teaching is a means to an end and not the end itself.
I am going to take one example of science and sort of break-it-down in multiple steps and how I would have approached that topic for say the 5th-6th standard students in say a public school in Pune and especially if Covid would not have been an issue so you have face-to-face meetup.
There was recent news about a mysterious radio signal which came from one of our closest galactic neighbors Proxima Centauri. Now let s say there was a class I was teaching/sharing which I had shared before and there already is trust formed.
So before coming to the news, I would tell the students about frequency and more generally the notation of why we like to measure things and how we measure things. There is so much beautiful history which could be acted and enacted which can show and remains in mind why measurement is needed. Once that is understood, discussed and an underpinning is established, we could move to human perception or the lack of it. We know that humans have lots of limits in almost everything, whether it is talking, touching, hearing, all of our five senses are pretty limited with what we know of spectrum available in the immediate family kingdom as well as in the Universe. I would start with how far can a person throw his voice and be heard without using any other means. There does come a point where they need to use anything from a megaphone to a loudspeaker and what it actually does.
The other thing I would then talk is about the radio and ask the students to find more about the internals of a radio. If possible to bring an old radio to school where it could be disassembled. After they are familiar with some names of the electronic components and what they do, take them to the electronics market where they try to source all the things needed to make a radio and whatever they encounter. This would allow the students to try and do bargain shopping as well as learn from where to source things. Some might even get a copy or two of electronic projects where the shop themselves sell blueprints to hobbyists so that they can tinker.
If there is a place in the school where soldering can be done, then all can try and sooner or later we come to know if something works or not. There is also possibility of talking about noise cancellation and then the topic of ITU can also be bought up and how they do frequency allocation. Last but not the least then the topic can be approached about an alien civilization and an unknown radio signal and what it means and what it can mean.
Now if just one topic can give such a wide range of things to do and develop an understanding about not the subject itself but surrounding subjects as well I see no reason why teachers can t do this except they are handcuffed to lot of policy as well as real-life constraints.
For e.g. I remember in my school days, we used to go out once or twice a year and that used to be either a school picnic or something similar. The only other I know is going to Mumbai for Nehru planetarium and Nehru science Centre. Unfortunately, I didn t go at that time because the school was taking students via air and the tickets were super costly at the time and that too for a 10 minute journey between the two cities. Those were different days, today you can t have a direct flight between the two cities as it doesn t make an economic sense. It makes more sense to go to Mumbai via train or bus as you will reach Mumbai in about couple of hrs. Of course, Pune does have its own planetarium at New English school and there are a few amateur astronomy clubs in Pune but nothing on the scale that what Mumbai has, but then this is getting off-topic.
Now, again in an online world could this be done? Not without both the teacher and the student both spending lot of resources online and even then will be a lower understanding as both the hands-on experience as well as interacting with other students and learning from other students (aping) would be hugely limited. Even the social skills that students develop in a school setting will be rusted. My own social skills probably have weakened and rusted as I have very limited interaction with people over the past few months due to Covid fears and would be at least for the next few years till a large enough population is not vaccinated.
phosh is graphical shell for mobile, touch based devices like
smart phones. It's the default graphical shell on Purism's
Librem 5 (and that's where
it came to life) but projects like postmarketOS,
Mobian and
Debian have picked it up
putting it into use on other devices as well and contributing patches.
This post is meant as a short overview how things are tied together so
further posts can provide more details.
A PHone SHell
As mobile shell phosh provides the interface components commonly
found on mobile devices to
launch applications
switch between running applications and close them
lock and unlock the screen
display status information (e.g. network connectivity, battery level)
provide quick access to things like torch or Bluetooth
show notifications
It uses
GObject object system and
GTK to build up the user
interface components. Mobile specific patterns are brought in via
libhandy.
Since phosh is meant to blend into GNOME as seamlessly as possible it
uses the common interfaces present there via
D-Bus like
org.gnome.Screensaver or org.gnome.keyring.SystemPrompter and
retrieves user configuration like keybindings via
GSettings from preexisting
schema.
The components of a running graphical session roughly look like this:
The blue boxes are the very same found on GNOME desktop sessions
while the white ones are currently only found on
phones.
feedbackd is explained
quickly: It's used for providing haptic or visual user feedback and
makes your phone rumble and blink when applications (or the shell)
want to notify the user about certain events like incoming phone calls
or new messages. What about phoc and squeekboard?
phoc and squeekboard
Although some stacks combine the graphical shell with the display server
(the component responsible for drawing applications and handling user
input) this isn't the case for phosh. phosh relies on a
Wayland
compositor to be present for that. Keeping shell and compositor apart
has some advantages like being able to restart the shell without
affecting other applications but also adds the need for some
additional communication between compositor and shell. This additional
communication is implemented via Wayland protocols. The Wayland
compositor used with phosh is called
phoc for PHone
Compositor.
One of these additional protocols is wlr-layer-shell.
It allows the shell to reserve space on the screen that is not used
by other applications and allows it to draw things like the top and
bottom bar or lock screen. Other protocols used by phosh (and hence implemented by phoc) are
wlr-output-management
to get information on and control properties of monitors or
wlr-foreign-toplevel-management
to get information about other windows on the display. The later
is used to allow to switch between running applications.
However these (and other) Wayland protocols are not implemented in
phoc from scratch. phoc leverages the
wlroots library for that. The library
also handles many other compositor parts like interacting with the
video and input hardware.
The details on how phoc actually puts things up on the screen deserves
a separate post. For the moment it's sufficient to note that phosh
requires a Wayland compositor like phoc.
We've not talked about entering text without a physical keyboard yet -
phosh itself does not handle that either.
squeekboard is the on
screen keyboard for text (and emoji) input. It again uses Wayland
protocols to talk to the Wayland compositor and it's (like phosh) a
component that wants exclusive access to some areas of the screen
(where the keyboard is drawn) and hence leverages the layer-shell
protocol. Very roughly speaking it turns touch input in that area into
text and sends that back to the compositor that then passes it back to
the application that currently gets the text input. squeekboard's main
author dcz has some more details
here.
The session
So how does the graphical session in the picture above come into existence?
As this is meant to be close to a regular GNOME session it's done via
gnome-session that is
invoked somewhat like:
phoc -E 'gnome-session --session=phosh'
So the compositor phoc is started up, launches gnome-session which
then looks at phosh.session for the session's components. These are
phosh, squeekboard and gnome-settings-daemon.
These then either connect to already running services via D-Bus
(e.g. NetworkManager, ModemManager, ...) or spawn them via D-Bus
activation when required (e.g. feedbackd).
Calling conventions
So when talking about phosh it's good to keep several things apart:
phosh - the graphical shell
phoc - the compositor
squeekboard - the on screen keyboard
phosh.session: The session that ties these and GNOME together
On top of that people sometimes refer to 'Phosh' as the software
collection consisting of the above plus more components from GNOME
(Settings, Contacs, Clocks, Weather, Evince, ...) and components that
currently aren't part of GNOME but adapt to small screen sizes, use
the same technologies and are needed to make a phone fun to use
e.g. Geary for email, Calls for making phone calls and Chats for SMS
handling.
Since just overloading the term Phosh is confusing GNOME/Phosh
Mobile Environment or Phosh Mobile Environment have been used
to describe the above collection of software and I've contacted GNOME on how to name
this properly, to not infringe on the GNOME trademark but also give proper credit
and hopefully being able to move things upstream that can live upstream.
That's it for a start. phosh's development documentation can be
browsed here but is
also available in the source code.
Besides the projects mentioned above credits go to
Purism for allowing me and others to work on the
above and other parts related to moving Free Software on mobile Linux
forward.
In case you're wondering why I would pick up a self-help book with such an
uninspiring title, it's because this book was originally published in
Canada with the title Relax, Damnit! Why Caulfield's US publishers
would have changed that title is beyond me. Canada clearly got the better
end of this deal. (I'm hoping it's not because they thought "damn" would
scare someone off, but it probably is.)
The topic of this book is a scientific take on all the little decisions
that you may worry about throughout the day: whether to eat breakfast, how
much water to drink, whether public toilet seats are risky, whether to
weigh yourself, how important flossing is, and much more. Caulfield is a
law professor at the University of Alberta specializing in health law and
scientific ethics, but the hat he's wearing when writing this book is that
of professional skeptic. I found out about this book through
Dr. Jen Gunter, a connection that you
won't find surprising when I mention that one of Caulfield's earlier books
is titled Is Gwyneth Paltrow Wrong About Everything?. (Spoiler:
yes.)
Caulfield chose to organize this collection of random essays around the
timeline of a single day, starting with waking up (how long should you
sleep?) and morning routines (what do scientific studies say about
brushing your teeth?), going through a work day (there's a chapter on
multitasking and why you really shouldn't do it), and concluding with
dinner (no, you can't taste the difference between most wines even if you
think you can), evening routines, and sleep. This worked for me. It's
still a bit arbitrary, but it's hard to organize random bits of
skepticism, and this layout let Caulfield make a point about how
frequently most people check their phones. (Stop doomscrolling. It makes
you feel bad. Yes, I'm talking to myself.)
I've now read several books, and considerably more essays, on scientific
skepticism of this type. They're all a bit the same, and unless you enjoy
this general genre of writing, there aren't many compelling reasons to
read this specific entry. (Ben Goldacre's Bad Science is still my favorite.) I think the only tidbit that
I found surprising and hadn't heard elsewhere is that the science on
flossing is meh at best. The rest is the standard mix of mainstream
scientific advice (don't drink raw milk, you're not going to catch
something from a public toilet seat, multivitamins just give you expensive
urine), advice that's scientifically correct but that I'm still not going
to follow (there's no scientific reason to wash your hair daily but I
still prefer how it feels), and advice to not worry about things with no
evidence on either side (it doesn't matter whether you eat breakfast, ten
thousand steps is a marketing gimmick, drink water when you're thirsty and
don't worry about how much). Caulfield does have a particularly good
debunking of the myth that angry ranting helps you calm down and feel
better (it does the exact opposite), but if you're reasonably well-read on
scientific trivia, nothing here will be that novel.
If you don't follow scientific trivia and want a good collection of
debunking essays, this book is fine. I certainly won't discourage you
from reading it. Caulfield is engaging and succinct, and there's a
balanced mix of odd trivia, debunking of pseudoscience, and good public
health advice, all comfortably in line with what I've read elsewhere.
That said, I found it striking to read this book shortly after
Can't Even. I was hoping that Caulfield
would tackle the larger problem of anxiety and overload that is in part
created by the proliferation of arbitrary standards and rules to which we
hold ourselves. He does tackle some related topics, such as our bizarre
belief in the US (and apparently Canada) that it is unsafe to let children
walk to school without adult supervision, but Caulfield's solutions are
nearly all individual. He wants to inform the reader, he wants to show
you how to analyze scientific research and notice when news articles are
scaring you unnecessarily, and he wants you to become more immune to
fear-mongering.
Petersen's salient point in Can't Even is that many of us are
burned out already and this is even more work. In order to avoid being
gratuitously frightened and deceived by con artists and sensational news
stories, we have to run a mental checklist of evidence evaluation and go
do independent research. Sure, this works, makes you better at risk
analysis, and may thus make you feel calmer, but this takes a lot of time
and energy. Wasn't a point of having the news media that other people
would do some of that work for you? Once again, everything that's wrong
with the world becomes another chore or energy expenditure that we all
have to independently make.
I know, it's asking too much of a harmless book on the scientific evidence
behind daily life decisions to make a political point about individual
versus collective effort. But it's hard to shake the feeling that asking
individuals to try harder to ignore intentionally deceptive and
well-funded propaganda campaigns doesn't scale. Not everyone enjoys
skepticism as a hobby, and there's only so much individual energy to go
around.
Relax, Damnit! is good advice as far as it goes. But I'm more in
the mood for the books that look at who is making us so anxious in the
first place and how we can (collectively) get them to stop. I don't know
what that looks like (there are obvious free speech concerns), but we need
reliable sources of information that don't make us anxious.
Rating: 6 out of 10
This is the second book of the Malloreon, which in turn is a sequel
trilogy to The Belgariad. You could start
here, since Eddings does a good job at summarizing previous volumes, but
I'm not sure why you'd want to.
This is the sort of book that gives epic fantasy series a bad name. After
a lot of action in Guardians of the West, our
band of heroes has been mostly assembled. They set out after the villain
through the novel strategy of exploring the parts of the world map we have
not yet seen. By the end of 400 pages of traveling they... are on the
trail of the villain while exploring parts of the world map we have not
yet seen.
What I'm saying is that you'd better be really enjoying Silk's nose
twitching and Belgarath being grumpy at Polgara, because that's about all
you get. The protagonists collect a few important plot coupons and set up
some emotional conflicts whose resolutions are already telegraphed, and
that's about it.
After wasting a bunch of time getting to and wandering around Nyissa, all
of which felt pointless except for one moment of Errand doing something
nifty (often the best parts of this series), the band of heroes ventures
into enemy territory as foreshadowed by the title. The structure of
Eddings's series is basically
Suikoden (collect all the
protagonists), so as one might expect the point of this excursion is to
pick up another protagonist. In the process, we get to see a bit more of
the Murgos than we have before.
I've commented before that Eddings takes racial essentialism to such an
absurd degree that these books start feeling like animal fairy tales,
which is why I'm willing to tolerate all of the stereotyping. It's
Planet of
Hats except with fantasy countries. That tolerance is stretched rather
thin when it comes to the bad guys, since the congruence with real-life
racism and dehumanization of enemies is a bit too strong. Eddings dodges
this mostly by not putting many of the bad guys in the page, but in
King of the Murgos he has a golden opportunity to undercut his
racial structure and surprise the reader. What if one of the Murgos is a
protagonist and is vital to the series plot?
I won't spoil what Eddings actually does, but if you imagine the stupidest
and most obvious way to avoid having to acknowledge his fantasy races are
not uniform, you probably just guessed the big reveal in this book. It's
sadly not surprising, since Eddings is all in on his racial construction
of this fantasy world, but it's still disgusting.
The main reason why I decided to re-read this series, which is notorious
for being a re-run of the Belgariad, is because I think what Eddings does
here with prophecy, the voice in Garion's head, and the meddling of the
seers is hilarious. The plot is openly on rails to the point that the
characters actively grumble about it. I find that oddly entertaining, a
bit like watching a Twitch streamer play an RPG. In this installment,
Errand does something random in the middle of a Murgo temple, Garion gets
a level-up chime, the prophecy gets very smug about how well things are
going, and no one knows why. It's an absolute delight, and I don't know
of any other series that isn't pure parody that would be willing to use
that as a plot element.
Sadly, King of the Murgos has only one or two enjoyable moments
like that, a whole lot of frankly boring map exploration, some truly
egregious racist claptrap, and no plot development worth speaking of. I
probably should have skipped this one when re-reading this series.
Followed by Demon Lord of Karanda.
Rating: 4 out of 10
Following up to yesterday s article about how NNCP rehabilitates asynchronous communication with modern encryption and onion routing, here is the first of my posts showing how to put it into action.
Email is a natural fit for async; in fact, much of early email was carried by UUCP. It is useful for an airgapped machine to be able to send back messages; errors from cron, results of handling incoming data, disk space alerts, etc. (Of course, this would apply to a non-airgapped machine also).
The NNCP documentation already describes how to do this for Postfix. Here I will show how to do it for Exim.
A quick detour to UUCP land
When you encounter a system such as email that has instructions for doing something via UUCP, that should be an alert to you that here is some very relevant information for doing this same thing via NNCP. The syntax is different, but broadly, here s a table of similar NNCP commands:
Purpose
UUCP
NNCP
Connect to remote system
uucico -s, uupoll
nncp-call, nncp-caller
Receive connection (pipe, daemon, etc)
uucico (-l or similar)
nncp-daemon
Request remote execution, stdin piped in
uux
nncp-exec
Copy file to remote machine
uucp
nncp-file
Copy file from remote machine
uucp
nncp-freq
Process received requests
uuxqt
nncp-toss
Move outbound requests to dir (for USB stick, airgap, etc)
N/A
nncp-xfer
Create streaming package of outbound requests
N/A
nncp-bundle
If you used UUCP back in the day, you surely remember bang paths. I will not be using those here. NNCP handles routing itself, rather than making the MTA be aware of the network topology, so this simplifies things considerably.
Sending from Exim to a smarthost
One common use for async email is from a satellite system: one that doesn t receive mail, or have local mailboxes, but just needs to get email out to the Internet. This is a common situation even for conventionally-connected systems; in Exim speak, this is a satellite system that routes mail via a smarthost. That is, every outbound message goes to a specific target, which then is responsible for eventual delivery (over the Internet, LAN, whatever).
This is fairly simple in Exim.
We actually have two choices for how to do this: bsmtp or rmail mode. bsmtp (batch SMTP) is the more modern way, and is essentially a derivative of SMTP that explicitly can be queued asynchronously. Basically it s a set of SMTP commands that can be saved in a file. The alternative is rmail (which is just an alias for sendmail these days), where the data is piped to rmail/sendmail with the recipients given on the command line. Both can work with Exim and NNCP, but because we re doing shiny new things, we ll use bsmtp.
These instructions are loosely based on the Using outgoing BSMTP with Exim HOWTO. Some of these may assume Debianness in the configuration, but should be easily enough extrapolated to other configs as well.
First, configure Exim to use satellite mode with minimal DNS lookups (assuming that you may not have working DNS anyhow).
Then, in the Exim primary router section for smarthost (router/200_exim4-config_primary in Debian split configurations), just change transport = remote_smtp_smarthost to transport = nncp.
Now, define the NNCP transport. If you are on Debian, you might name this transports/40_exim4-config_local_nncp:
This is pretty straightforward. We pipe to nncp-exec, run it as the nncp user. nncp-exec sends it to a target node and runs whatever that node has called rsmtp (the command to receive bsmtp data). When the target node processes the request, it will run the configured command and pipe the data in to it.
More complicated: Routing to various NNCP nodes
Perhaps you would like to be able to send mail directly to various NNCP nodes. There are a lot of ways to do that.
Fundamentally, you will need a setup similar to the UUCP example in Exim s manualroute manual, which lets you define how to reach various hosts via UUCP/NNCP. Perhaps you have a star topology (every NNCP node exchanges email with a central hub). In the NNCP world, you have two choices of how you do this. You could, at the Exim level, make the central hub the smarthost for all the side nodes, and let it redistribute mail. That would work, but requires decrypting messages at the hub to let Exim process. The other alternative is to configure NNCP to just send to the destinations via the central hub; that takes advantage of onion routing and doesn t require any Exim processing at the central hub at all.
Receiving mail from NNCP
On the receiving side, first you need to configure NNCP to authorize the execution of a mail program. In the section of your receiving host where you set the permissions for the client, include something like this:
exec:
rsmtp: ["/usr/sbin/sendmail", "-bS"]
The -bS option is what tells Exim to receive BSMTP on stdin.
Now, you need to tell Exim that nncp is a trusted user (able to set From headers arbitrarily). Assuming you are running NNCP as the nncp user, then add MAIN_TRUSTED_USERS = nncp to a file such as /etc/exim4/conf.d/main/01_exim4-config_local-nncp. That s it!
Some hosts, of course, both send and receive mail via NNCP and will need configurations for both.
Over the course of the last year and a half, I ve been doing some self-directed
learning on how radios work. I ve gone from a very basic understanding of
wireless communications (there s usually some sort of antenna, I guess?) all
the way through the process of learning about and implementing a set of
libraries to modulate and demodulate data using my now formidable stash of SDRs.
I ve been implementing all of the RF processing code from first principals and
purely based on other primitives I ve written myself to prove to myself that I
understand each concept before moving on.
I figured that there was a fun capstone to be done here - the blind reverse
engineering and implementation of the protocol my cheep Amazon power switch
uses to turn on and off my Christmas Tree. All the work described in this post
was done over the course of a few hours thanks to help during the demodulation
from Tom Bereknyei and
hlieberman.
Going in blind
When I first got my switch, I checked it for any FCC markings in order to look
up the FCC filings to determine the operational frequency of the device, and
maybe some other information such as declared modulation or maybe even part
numbers and/or diagrams. However, beyond a few regulatory stickers, there were
no FCC ids or other distinguishing IDs on the device. Worse yet, it appeared to
be a whitelabeled version of another product, so searching Google for the
product name was very unhelpful.
Since operation of this device is unlicensed, I figured I d start looking in
the ISM band. The most common band used that I ve seen is the band starting
at 433.05MHz up to 434.79MHz. I fired up my trusty waterfall tuned to a
center frequency of 433.92MHz (since it s right in the middle of the band, and
it let me see far enough up and down the band to spot the remote) and pressed
a few buttons. Imagine my surprise when I realize the operational frequency of
this device is 433.920MHz, exactly dead center. Weird, but lucky!
After taking a capture, I started to look at understanding what the modulation
type of the signal was, and how I may go about demodulating it.
Using inspectrum, I was able to clearly
see the signal in the capture, and it immediately stuck out to my eye to be
encoded using OOK / ASK.
Next, I started to measure the smallest pulse, and see if I could infer the
symbols per second, and try to decode it by hand. These types of signals are
generally pretty easy to decode by eye.
This wound up giving me symbol rate of 2.2 Ksym/s, which is a lot faster than I
expected. While I was working by hand, Tom
demodulated a few messages in Python, and noticed that if you grouped the bits
into groups of 4, you either had a 1000 or a 1110 which caused me to
realize this was encoded using something I saw documented elsewhere, where the
0 is a short pulse, and a 1 is a long pulse, not unlike morse code, but
where each symbol takes up a fixed length of time (monospace morse code?).
Working on that assumption, I changed my inspectrum symbol width, and
demodulated a few more by hand. This wound up demodulating nicely (and the
preamble / clock sync could be represented as repeating 0s, which is handy!)
and gave us a symbol rate of 612(ish) symbols per second a lot closer to
what I was expecting.
If we take the code for on in the inspectrum capture above and demodulate
it by hand, we get 0000000000110101100100010 (treat a short pulse as a 0, and
a long pulse as a 1). If you re interested in following along at home, click on
the inspectrum image, and write down the bits you see, and compare it to what
I have!
Right, so it looks like from what we can tell so far that the packet looks
something like this:
preamble / sync
stuff
Next, I took a capture of all the button presses and demodulated them by hand,
and put them into a table to try and understand the format of the messages:
Button
Demod'd Bits
On
0000000000110101100100010
Off
00000000001101011001010000
Dim Up
0000000000110101100110100
Dim Down
0000000000110101100100100
Timer 1h
0000000000110101100110010
Timer 2h
0000000000110101100100110
Timer 4h
0000000000110101100100000
Dim 100%
0000000000110101000101010
Dim 75%
00000000001101010001001100
Dim 50%
00000000001101010001001000
Dim 25%
0000000000110101000100000
Great! So, this is enough to attempt to control the tree with, I think so I
wrote a simple modulator. My approach was to use the fact that I can break down
a single symbol into 4 sub-symbol components which is to say, go back to
representing a 1 as 1110, and a 0 as 1000. This let me allocate IQ
space for the symbol, break the bit into 4 symbols, and if that symbol is 1,
write out values from a carrier wave (cos in the real values, and sin in
the imaginary values) to the buffer. Now that I can go from bits to IQ data,
I can transmit that IQ data using my PlutoSDR or HackRF and try and control my
tree. I gave it a try, and the tree blinked off!
Success!
But wait that s not enough for me I know I can t just demodulate bits and
try and replay the bits forever there s stuff like addresses and keys and
stuff, and I want to get a second one of these working. Let s take a look at
the bits to see if we spot anything fun & interesting.
At first glance, a few things jumped out at me as being weird? First is
that the preamble is 10 bits long (fine, let s move along - maybe it
just needs 8 in a row and there s two to ensure clocks sync?). Next is that
the messages are not all the same length. I double (and triple!) checked
the messages, and it s true, the messages are not all the same length. Adding
an extra bit at the end didn t break anything, but I wonder if that s just due
to the implementation rather than the protocol.
But, good news, it looks like we have a stable prefix to the messages from the
remote must be my device s address! The stable 6 bits that jump out right
away are 110101. Something seems weird, though, 6 bits is a bit awkward, even
for a bit limited embedded device. Why 6? But hey, wait, we had 10 bits in the
preamble, what if we have an 8 bit address meaning my device is 00110101,
and the preamble is 8 0 symbols! Those are numbers that someone working on
an 8 bit aligned platform would pick! To test this, I added a 0 to the
preamble to see if the message starts at the first 1, or if it requires all
the bits to be fully decoded, and lo and behold, the tree did not turn on or
off. This would seem to me to confirm that the 0s are part of the address,
and I can assume we have two 8 bit aligned bytes in the prefix of the message.
preamble / sync
address
stuff
Now, when we go through the 9-10 bits of stuff , we see all sorts of weird
bits floating all over the place. The first 4 bits look like it s either
1001 or 0001, but other than that, there s a lot of chaos. This is where
things get really squishy. I needed more information to try and figure this out,
but no matter how many times I sent a command it was always the same bits (so,
no counters), and things feel very opaque still.
The only way I was going to make any progress is to get another switch and see
how the messages from the remote change. Off to Amazon I went, and ordered
another switch from the same page, and eagerly waited its arrival.
Switch #2
The second switch showed up, and I hurriedly unboxed the kit, put batteries
into the remote, and fired up my SDR to take a capture. After I captured the
first button ( Off ), my heart sunk as I saw my lights connected to
Switch #1 flicker off. Apparently the new switch and the old switch have the
same exact address. To be sure, I demodulated the messages as before, and
came out with the exact same bit pattern. This is a setback and letdown I
was hoping to independently control my switches, but it also means I got no
additional information about the address or button format.
The upside to all of this, though, is that because the switches are controlled
by either remote, I only needed one remote, so why not pull it apart and see if
I can figure out what components it s using to transmit, and find any
datasheets I can. The PCB was super simple, and I wound up finding a WL116SC
IC on the PCB.
After some googling, I found a single lone
datasheet,
entirely in Chinese. Thankfully, Google Translate seems to have worked well
enough on technical words, and I was able to put together at least a little bit
of understanding based on the documentation that was made available. I took a
few screenshots below - I put the google translated text above the hanzi. From
that sheet, we can see we got the basics of the 1 and 0 symbol encoding
right (I was halfway expecting the bits to be flipped), and a huge find by way
of a description of the bits in the message!
It s a bummer that we missed the clock sync / preamble pulse before the data
message, but that s OK somehow. It also turns out that 8 or 10 bit series of of
0"s wasn t clock sync at all - it was part of the address! Since it also turns
out that all devices made by this manufacturer have the hardcoded address of
[]byte 0x00, 0x35 , that means that the vast majority of bits sent are always
going to be the same for any button press on any remote made by this vendor.
Seems like a waste of bits to me, but hey, what do I know.
Additionally, this also tells us the trailing zeros are not part of the data
encoding scheme, which is progress!
address
keycode
Now, working on the assumptions validated by the datasheet, here s the updated
list of scancodes we ve found:
Button
Scancode Bits
Integer
On
10010001
145 / 0x91
Off
10010100
148 / 0x94
Dim Up
10011010
154 / 0x9A
Dim Down
10010010
146 / 0x92
Timer 1h
10011001
154 / 0x99
Timer 2h
10010011
147 / 0x93
Timer 4h
10010000
144 / 0x90
Dim 100%
00010101
21 / 0x15
Dim 75%
00010011
19 / 0x13
Dim 50%
00010010
18 / 0x12
Dim 25%
00010000
16 / 0x10
Interestingly, I think the Dim keys may have a confirmation that we have
a good demod the codes on the bottom are missing the most significant
bit, and when I look back at the scancode table in the datasheet, they make an
interesting pattern the bottom two rows, right and left side values match
up! If you take a look, Dim 100% is S1 , Dim 75% is S19 , Dim 50% is S8 ,
and Dim 25% is S20 . Cool!
Since none of the other codes line up, I am willing to bet the most significant
bit is a Combo indicator, and not part of the button (leaving 7 bits for the
keycode).
And even more interestingly, one of our scancodes ( Off , which is 0x94) shows up just
below this table, in the examples.
Over all, I think this tells us we have the right bits to look at for
determining the scan code! Great news there!
Back to the modulation!
So, armed with this knowledge, I was able to refactor my code to match the
timings and understanding outlined by the datasheet and ensure things still work.
The switch itself has a high degree of tolerance, so being wildly off frequency
or a wildly wrong symbol rate may actually still work. It s hard to know if
this is more or less correct, but matching documentation seems like a more stable
foundation if nothing else.
This code has been really reliable, and tends to work just as well as the
remote from what I ve been able to determine. I ve been using incredibly low
power to avoid any interference, and it s been very robust - a testament to the
engineering that went into the outlet hardware, even though it cost less than
of a lot of other switches! I have a lot of respect for the folks who built
this device - it s incredibly simple, reliable and my guess is this thing will
keep working even in some fairly harsh RF environments.
The only downside is the fact the manufacturer used the same address for all
their devices, rather than programming a unique address for each outlet and
remote when the underlying WL116SC chip supports it. I m sure this was done to
avoid complexity in assembly (e.g. pairing the remote and outlet, and having to
keep those two items together during assembly), but it s still a bummer. I took
apart the switch to see if I could dump an EEPROM and change the address in
ROM, but the entire thing was potted in waterproof epoxy, which is a very nice
feature if this was ever used outdoors. Not good news for tinkering, though!
Unsolved Mysteries
At this point, even though I understand the protocol enough to control the
device, it still feels like I hit a dead end in my understanding. I m not able
to figure out how exactly the scancodes are implemented, and break them down
into more specific parts. They are stable and based on the physical wiring of
the remote, so I think I m going to leave it a magic number. I have what I was
looking for, and these magic constants appear to be the right one to use, even
if I did understand how to create the codes itself.
This does leave us with a few bits we never resolved, which I ll memorialize
below just to be sure I don t forget about them.
Question #1: According to the datasheet there should be a preamble. Why do
I not see one leading the first message?
My hunch is that the trailing 0 at the end of the payload is actually just
the preamble for the next message (always rendering the first message
invalid?). This would let us claim there s an engineering reason why we are
ignoring the weird bit, and also explain away something from the documentation.
It s just weird that it wouldn t be present on the first message.
This theory is mostly confirmed by measuring the timing and comparing it to the
datasheet, but it s not exactly in line with the datasheet timings either
(specifically, it s off by 200 s, which is kinda a lot for a system using 400 s
timings). I think I could go either way on the last 0 being the preamble for
the next message. It could be that the first message is technically invalid, or
it could also be that this was not implemented or actively disabled by the
vendor for this specific application / device. It s really hard to know
without getting the source code for the WL116SC chip in this specific remote
or the source in the outlet itself.
Question #2: Why are some keycodes 8 bits and others 9 bits?
I still have no idea why there sometimes 8 bits (for instance, On ) and
other times there are 9 bits (for instance, Off ) in the 8 bit keycode
field.
I spent some time playing with the trailing zeros, when I try and send an
Off with the most significant 8 bits (without the least significant / last
9th bit, which is a 0 ), it does not turn the tree off. If I send an On with
9 bits (an additional 0 after the least significant bit), it does work,
but both On and Off work when I send 10, 11 or 12 bits padded with trailing
zeros. I suspect my outlet will ignore data after the switch is done reading
bits regardless of trailing zeros. The docs tell me there should only be 8 bits,
but it won t work unless I send 9 bits for some commands. There s something
fishy going on here, and the datasheet isn t exactly right either way.
Question #3: How in the heck do those scancodes work?
This one drove me nuts. I ve spent countless hours on trying to figure this
out, including emailing the company that makes the WL116SC (they re really
nice!), and even though they were super kind and generous with documentation
and example source, I m still having a hard time lining up their documentation
and examples with what I see from my remote. I think the manufacturer of my
remote and switch has modified the protocol enough to where there s actually
something different going on here. Bummer.
I wound up in my place of last resort asking friends over Signal to try and
see if they could find a pattern, as well as making
multiple pleas to the twittersphere, to no avail (but thank you to
Ben Hilburn,
devnulling,
Andreas Bombe and Larme
for your repiles, help and advice!)
I still don t understand how they assemble the scan code for instance,
if you merely add, you won t know if a key press of 0x05 is 0x03 + 0x02
or if it s 0x01 + 0x04. On the other hand, treating it as two 4-bit
integers won t work for 0x10 to 0x15 (since they need 5 bits to
represent). It s also likely the most significant bit is a combo indicator,
which only leaves 7 bits for the actual keypress data. Stuffing 10 bits of data
into 7 bits is likely resulting in some really intricate bit work.
On a last ditch whim, I tried to XOR the math into working, but some initial
brute forcing to make the math work given the provided examples did not result
in anything. It could be a bitpacked field that I don t understand, but I don t
think I can make progress on that without inside knowledge and much more work.
Here s the table containing the numbers I was working off of:
Keys
Key Codes
Scancode
S3 + S9
0x01 + 0x03
0x96
S6 + S12
0x07 + 0x09
0x94
S22 + S10
0x0D + 0x0F
0x3F
If anyone has thoughts on how these codes work, I d love to hear about it! Send
me an email or a tweet or something - I m a bit stumped.
There s some trick here that is being used to encode the combo key in a way
that is decodeable. If it s actually not decodeable (which is a real
possibility!), this may act as a unique button combo hash which allows the
receiver to not actually determine which keys are pressed, but have a unique
button that gets sent when a combo is used. I m not sure I know enough to
have a theory as to which it may be.
After a particularly unlucky year for her family, Maria Konnikova was
reading about the balance between luck and control in life and discovered,
to her surprise, that John von Neumann, one of the foundational thinkers
of computer science, was fascinated by poker. He found most card games
boring because they relied on luck. Poker, however, he thought was the
perfect balance between luck and skill: enough skill to make its effect
undeniable, but enough luck that one could not control the game fully
regardless of skill.
Konnikova decided on a research project: spend one year learning No Limit
Texas Hold'em from one of the best poker players in the world, with a goal
of competing in the World Series of Poker. She had studied the
description-experience gap during her doctoral research in psychology
and wanted to see if the experience of randomness in poker would teach her
something the description of the randomness of life could not. Before
starting this project, she didn't know the basic rules and had never
watched a game. Erik
Seidel agreed to mentor her, and The Biggest Bluff is her account
of that experience.
This book is simultaneously frustrating and fascinating in ways that I
don't think can be untangled without making it a far different book.
Fitting, I suppose, for a book about how our brains entangle luck and
skill.
First, if you're looking for a book about poker play, this is not one.
Konnikova rarely talks about specific hands or tournaments in more detail
than her overall trajectory. That was a disappointment. In the few
places she does describe some of her betting decisions, analysis of the
other players, and tournament strategy, her accounts are engrossing and
suspenseful. I would have happily read a book chronicling her poker
tournaments and the decisions she made, but this is not that book.
What The Biggest Bluff is instead is a psychological and
philosophical examination of the process of learning poker. Konnikova
uses her experiences as launching points into philosophical digressions.
Even the lessons that have limited surface utility outside of poker, such
as learning to suppress body language to avoid giving away information,
turn into digressions about interpersonal dynamics and personality types.
There are interesting tidbits here, but I've read a lot of popular
psychology and was more interested in the poker. My frequent reading
experience was impatiently waiting for Konnikova to finish lecturing and
get back to her narrative.
What Konnikova does do though, at a level that I haven't seen before
before in a book of this type, is be brutally honest about her mistakes
and her learning process. And I do mean brutally: The book opens with her
throwing up in a casino bathroom. (This is not a fun book to read if you
don't like reading about stress reactions and medical problems. There
aren't many of them, but they're... memorable.) Konnikova knows and can
explain the psychological state she's trying to reach, but still finds it
hard to do in the moment. Correctly reacting to probabilities, cutting
losses, and neither being too over-confident or too scared is very hard.
Most books of this type elide over the repeated failures in a sort of
training montage, which makes the process look easier than it feels.
Konnikova tries to realistically show the setbacks and failures, and I
think succeeds.
That relentless introspection and critical honesty is the best part of
this book, but I think it's also behind the stream of consciousness
digressions about psychology and philosophy. It's a true portrayal of how
Konnikova makes sense of the world. A more polished and streamlined book
about the poker would have been more dramatically engrossing, but it might
have lost the deep examination of how she combines poker with her
knowledge of psychology to change her thinking.
The one place where I think that self-reflection may fall a bit short,
which I want to mention because I thought it was a missed opportunity, is
around knowledge of hand probabilities. Konnikova makes a point, early in
the book, of not approaching poker through the memorization and
mathematics route and instead trying to find a play style that focuses on
analyzing the other players and controlling her own emotions. This is a
good hook, but by the end of the book it's not entirely true.
The point that I think she was trying to make is that her edge against
other poker players at her same level comes more from psychology than from
calculation of precise odds in rare situations. This is true. But by the
time she reaches high levels of play, she is using statistical simulators,
practice tools, and intensive study just like any professional poker
player. There is a minimum level of pure knowledge and memorization
required that cannot be avoided. It's clear from the few things she says
about this that those tools became more interesting to her as she became
better at poker, and I wish she would have dug more into why and how that
happened. How much of her newfound ability to make decisions and stick to
a plan comes from emotional changes, and how much from that background
store of confident knowledge? Or maybe those are different ways of
looking at the same change?
I did appreciate Konnikova's explicit acknowledgment at the end of the
book that poker did not, in the end, provide some deep insight into the
balance of luck and skill in real life. Learning poker instead gave
Konnikova more personal ability to make a plan for the things that she can
control and let go of the things she can't. I'm glad that worked for her,
but since reading this book I have noticed former poker players who think
life is more knowable than it is.
Poker combines random chance with psychological play against other people,
but it does so in a way and to an extent that is quantifiable. You can
make the correct play and still lose a hand, but you can also know when
this has happened. When you're used to analyzing the world through that
frame and real life fails to provide that certainty, it's tempting to
impose it anyway and insist your simplified models are more accurate
because they're more comprehensible. But poker is a game, not a model;
being more predictable and more constrained than real life is part of what
makes it fun. The skill that Konnikova learned from it has a potential
downside that she doesn't talk about.
I'm not sure how to sum up this book. Konnikova's internal analysis and
honesty is truly admirable and illuminating, but it left me wanting to
read a different book that was more focused on poker narration. I know
there are lots of those books out there, but I doubt they would be written
with Konnikova's self-awareness and lack of ego. However, they would
probably also lack the moments that made me cringe or that were deeply
uncomfortable to read.
My feelings are mixed. But if you want popular psychology wrapped around
a deeply honest account of the process of learning poker, I suspect this
book is one of a kind.
Rating: 7 out of 10
Have you ever been traveling, shot a ton of photos and videos, but were annoyed to find it was saturating the terrible wifi you had access to? Maybe you d wish the upload to pause until you get somewhere else, but then pausing syncing on your Nextcloud/Syncthing/Dropbox would also pause other syncing you didn t want to pause. Or you have trouble backing up your laptop when not at home, in a way that won t accidentaly eat up your cell phone data.
There are ways to help with this: asynchronous transfer.
Here s a lot of background. If you want to see how encrypted, onion-routed UUCP looks, skip ahead to the NNCP section!
There is an old saying: When all you have is a hammer, every problem looks like a nail. We have this wonderful tool called ssh available, and it is pervasive and well-understood, so we tend to use it. But we ve missed out on some benefits of asynchronous processing that we actually used to have more frequently.
Of course, we are all used to some asynchronous services in our lives. Email is a popular example: most mail clients work offline and will transmit stored messages when the mail server becomes reachable. Mail servers themselves work that way, too. Many instant messaging platforms do as well.
Even some backup systems do. Bacula/Bareos, for instance, spools all backup data to disk on the system connected to the tape drive, and from there to the tape itself. They do this for several reasons, but primarily the fact that if tape drives are not fed with data at their design speed, it can cause physical damage to the tape or even the drive. It causes the drive to have to pause, and seek backwards to reposition for the next write. This creates excessive travel of the tape over the write heads, causing a condition known as tape shine where the tape is damaged prematurely.
Here are some problems people often run into when sending data across a network (or the Internet) synchronously:
One side of the communication is much faster than the other
Internet issues interrupting communications mid-stream
Slow Internet causing processes to take much longer than planned, resulting in unexpected results or locking issues
Physical damage due to performance issues
Of course, there are plenty of situations where synchronous communication is a must. For instance:
When the status of the transaction at the remote end must be known immediately
When there is insufficient space to spool a job s data
I suspect that the reason we don t do more asynchronous processing these days, despite it being strong in the Unix heritage, is the lack of modern tools to do it. Let s explore some more.
Some of my use cases
I run ZFS on all my systems that support it: file server, laptops, workstations, etc. It is only natural to use ZFS send/receive to do backups, and I do. However, when I am traveling, my laptop never gets backed up, because the backups are pulled from the backup system. Sure, there are ways around that; a VPN, for instance. But then we have the situation where sometimes I do not want to send the backup even if I have a working Internet connection: perhaps I m tethered to a mobile connection and it would be expensive to do so, or I m on hotel Wifi that is flaky and slow and I don t want to give up any of its meager bandwidth.
I have another backup-related problem. I have a remote server, which until recently was using extremely slow disks. If I made significant changes, the backup would take the better part of a day. That s annoying when I try to back up hourly. So of course I had to implement locking, but then that means none of my other machines would back up that day either.
Once I needed to transmit about 2TB of data. My home Internet connection was terribly slow, and I calculated it would take multiple months to do this. So I took to manually copying parts of the data to my laptop, and whenever I d find an airport or coffee shop with faster Internet than at home, I d send off those bits from it. But it took a ton of work.
The bespoke asynchronous problem
And that ton of work is perhaps why we aren t doing more of this. There s been no great standard solution, so it s all roll your own when you need to. So we just use ssh, because it s easier and usually good enough . But as I wrote in my recent article on airgapped backups, there are reasons to go async.
Solutions
Wouldn t it be great to be able to queue up data for a machine, and let it get there in whatever way it can? Maybe a fast Internet connection is found, or via Tor, or via copying to a USB stick, or via radio broadcast? It would make many of these scenarios a lot easier. And there are ways for this now, with modern security!
We have some tools on Linux for this: git-annex for storage and migration, syrep for synchronization, and NNCP for file transfer and remote execution (could be combined with some of these other tools). Let s dive in to NNCP.
NNCP
If you already know UUCP, think of NNCP as UUCP brought into the modern era, with modern security and tools.
Basically, NNCP permits you to send files to a remote system, request files from a remote system, and pipe data to an NNCP command that requests execution remotely. So you could, say, pipe a zfs send to NNCP which sends it to the remote and pipes it to zfs receive when it gets there.
NNCP has a delay-tolerant, resumable protocol that can run over just about any reliable connection: TCP, serial, Tor, radios of various kinds, you name it. But that s not all; it also can dump its queue onto something like a USB stick for transport, or even make a tar-style stream that could be munged however you like. If you want to get fancy, you can assign priorities to data packets, so that, for instance, outbound email will always get sent before that 1TB file you ve got to send also. You can also configure it so that certain carriers handle certain priorities of data; your cell phone would only handle the most urgent, but a USB stick would take anything.
NNCP is source-routed; you can tell it that the way that Bob reaches Alice is via Carl, then Betty. Bob can generate a message that will be sent along that route, fully encrypted and authenticated at each step of the way; Carl can t see the content of the message or even anything about it other than its next hop.
How this helps
Let s revisit some of my scnearios with NNCP.
For the laptop being backed up, while traveling it can queue up its backups, or photos, or videos, or whatever. They could be triggered by a command when on a good connection, or automatically. The data could be copied to USB and given to a friend to transmit; perfectly safe due to encryption. Or it could all wait until arriving at home, safely out of your other syncing directories. The NNCP documentation has an example of this.
For the server being backed up slowly, that s easily solved; the slow backup would simply be queued up, and transmitted and processed when it s ready. This wouldn t interrupt other backups.
How about the 2TB transmission problem? That s also made a lot easier. A command could be run to fill up a USB stick with parts of the queue, then that USB stick plugged in and transmitted whenever at a fast location. Repeat as needed while the slow system continues its upload of the remaining bits.
NNCP has a lot of interesting use cases documented as well.
If you are already familiar with how public keys work in SSH, then NNCP should be immediately familiar as well. It is a similar concept (though arguably somewhat easier to set up).
I am working on setting up a NNCP network, and will have more posts on how to do so once I ve got it going. In the meantime, the documentation for the project is also pretty good.
Jenkins in the Ops space is in general already painful. Lately the deprecation of the
multiple-scms plugin caused
some headache, becaue we relied heavily on it to generate pipelines in a
Seedjob based on structure inside
secondary repositories. We kind of started from scratch now and ship parameterized
pipelines defined in Jenkinsfiles in those secondary repositories. Basically that
is the way it should be, you store the pipeline definition along with code you'd
like to execute. In our case that is mostly terraform and ansible.
Problem
Directory structure is roughly "stage" -> "project" -> "service".
We'd like to have one job pipeline per project, which dynamically
reads all service folder names and offers those as available
parameters. A service folder is the smallest entity we manage with
terraform in a separate state file.
Now Jenkins pipelines are by intention limited, but you can add some
groovy at will if you whitelist the usage in Jenkins. You have to
click through some security though to make it work.
Jenkinsfile
This is basically a commented version of the Jenkinsfile we copy
now around as a template, to be manually adjusted per project.
// Syntax: https://jenkins.io/doc/book/pipeline/syntax/
// project name as we use it in the folder structure and job name
def TfProject = "myproject-I-dev"
// directory relative to the repo checkout inside the jenkins workspace
def jobDirectory = "terraform/dev/$ TfProject "
// informational string to describe the stage or project
def stageEnvDescription = "DEV"
/* Attention please if you rebuild the Jenkins instance consider the following:
- You've to run this job at least *thrice*. It first has to checkout the
repository, then you've to add permisions for the groovy part, and on
the third run you can gather the list of available terraform folder.
- As a safeguard the first first folder name is always the invalid string
"choose-one". That prevents accidential execution of a random project.
- If you add new terraform folder you've to run the "choose-one" dummy rollout so
the dynamic parameters pick up the new folder. */
/* Here we hardcode the path to the correct job workspace on the jenkins host, and
discover the service folder list. We have to filter it slightly to avoid temporary folders created by Jenkins (like @tmp folders). */
List tffolder = new File("/var/lib/jenkins/jobs/terraform $ TfProject /workspace/$ jobDirectory ").listFiles().findAll it.isDirectory() && it.name ==~ /(?i)[a-z0-9_-]+/ .sort()
/* ensure the "choose-one" dummy entry is always the first in the list, otherwise
initial executions might execute something. By default the first parameter is
used if none is selected */
tffolder.add(0,"choose-one")
pipeline
agent any
/* Show a choice parameter with the service directory list we stored
above in the variable tffolder */
parameters
choice(name: "TFFOLDER", choices: tffolder)
// Configure logrotation and coloring.
options
buildDiscarder(logRotator(daysToKeepStr: "30", numToKeepStr: "100"))
ansiColor("xterm")
// Set some variables for terraform to pick up the right service account.
environment
GOOGLE_CLOUD_KEYFILE_JSON = '/var/lib/jenkins/cicd.json'
GOOGLE_APPLICATION_CREDENTIALS = '/var/lib/jenkins/cicd.json'
stages
stage('TF Plan')
/* Make sure on every stage that we only execute if the
choice parameter is not the dummy one. Ensures we
can run the pipeline smoothly for re-reading the
service directories. */
when expression params.TFFOLDER != "choose-one"
steps
/* Initialize terraform and generate a plan in the selected
service folder. */
dir("$ params.TFFOLDER ")
sh 'terraform init -no-color -upgrade=true'
sh 'terraform plan -no-color -out myplan'
// Read in the repo name we act on for informational output.
script
remoteRepo = sh(returnStdout: true, script: 'git remote get-url origin').trim()
echo "INFO: job *$ JOB_NAME * in *$ params.TFFOLDER * on branch *$ GIT_BRANCH * of repo *$ remoteRepo *"
stage('TF Apply')
/* Run terraform apply only after manual acknowledgement, we have to
make sure that the when condition is actually evaluated before
the input. Default is input before when. */
when
beforeInput true
expression params.TFFOLDER != "choose-one"
input
message "Cowboy would you really like to run **$ JOB_NAME ** in **$ params.TFFOLDER **"
ok "Apply $ JOB_NAME to $ stageEnvDescription "
steps
dir("$ params.TFFOLDER ")
sh 'terraform apply -no-color -input=false myplan'
post
failure
// You can also alert to noisy chat platforms on failures if you like.
echo "job failed"
job-dsl side of the story
Having all those when conditions in the pipeline stages above allows us to
create a dependency between successful Seedjob executions and just let that trigger
the execution of the pipeline jobs. This is important because the Seedjob
execution itself will reset all pipeline jobs, so your dynamic parameters are gone.
By making sure we can re-execute the job, and doing that automatically, we still
have up to date parameterized pipelines, whenever the Seedjob ran successfully.
The job-dsl script looks like this:
Disadvantages
There are still a bunch of disadvantages you've to consider
Jenkins Rebuilds are Painful
In general we rebuild our Jenkins instances quite frequently. With the
approach outlined here in place, you've to allow the groovy script execution
after the first Seedjob execution, and then go through at least another
round of run the job, allow permissions, run the job, until it's finally
all up and running.
Copy around Jenkinsfile
Whenever you create a new project you've to copy around Jenkinsfiles for each
and every stage and modify the variables at the top accordingly.
Keep the Seedjob definitions and Jenkinsfile in Sync
You not only have to copy the Jenkinsfile around, but you also have to
keep the variables and names in sync with what you define for the Seedjob.
Sadly the pipeline env-vars are not available outside of the pipeline when
we execute the groovy parts.
Kudos
This setup was crafted with a lot of help by
Michael and
Eric.
Nick Pettigrew was an anti-social behavior officer for council housing for
over a decade. This book is a diary of one year in the life of that job.
According to the author, the dates, names, and some of the identifying
details have been changed but not exaggerated. While it's hard to verify
that, and I'm sure a few of the stories have been tweaked to make better
narratives, it has a messiness and chaos of half-resolved drama mixed with
mundane office tedium that makes it ring true.
The subject matter requires some explanation for US readers.
Council housing is the UK's version of what the US would call public
housing or "the projects," although it's a far larger percentage of the
housing stock in the UK than it is in the US. These are buildings built
by the government and run by local governments or non-profits to provide
housing to working class and poor people at reduced cost compared to the
private market. As in the US, new council housing construction has
dropped off dramatically; as in the US, a bunch of it has been privatized,
although in the UK the Right to Buy law at least sells the housing to the
people living in it, as opposed to slumlords.
The 1998 UK Crime and Disorder Act collects under anti-social behavior a
bunch of low-grade irritations that in the US would fall under public
nuisance laws, noise ordinances, and other vague misdemeanors like
"creating a public disturbance": essentially, all the irritating and
obnoxious things that people subject their neighbors to, but which fall
short of obvious criminal behavior like theft or assault. As Pettigrew
puts it:
"I just don't want to hear the word 'cunt' shouted repeatedly at 3am
every night any more. I don't think that's unreasonable."
That law required the organizations managing council estates to have a
procedure to deal with anti-social behavior, and thus the job of an
anti-social behavior officer was created.
In the US, these sorts of problems are dealt with by the local police,
which is a little like trying to get rid of a raccoon by running it over
with a balky, thirty-year-old car. The best outcome is that the raccoon
gets freaked out by your efforts to get the car to start and leaves. The
worst outcome is that you accidentally run over your neighbor's kid while
aiming for the raccoon. Either way, neither you nor the car nor your
neighbors are going to be happy about the process.
An anti-social behavior officer is someone with some authority to do
things like install cameras, tell people who don't live somewhere that
they need to stop coming there, and start eviction proceedings, but who
doesn't carry guns, can't arrest people, and enforces those rules when
necessary via court proceedings or calling the police. In other words,
it's one of the types of alternative responders whose job is to solve
problems rather than stop crimes that we've been talking about in the
United States. And although Pettigrew is quite grumpy and cynical about
his job (for very understandable reasons explained in this book), my
takeaway from another country with even worse problems is that the system
sort of works. It's underfunded and poorly managed and nebulous and
sometimes very sad, but it also achieves some of what it sets out to do,
and you can see the outlines of a better system beneath it.
My favorite thing about this book is that it forces the reader to grapple
with the actual job in all its messiness, rather than our ideals of what
we want the job to be. For example, if you're going to hire a bunch of
people to do this job, you need some way to figure out whether they're any
good at it, but it's not obvious how to measure success.
One infuriating KPI we're measured on is the final question a resident
is asked once their case is closed: "Are you happy with the outcome of
your case?" Because unless you evict the problem neighbor within a
fortnight, erect a security wall around the complainant's house
manned by armed guards, and bake them a cake, the answer will almost
certainly be no.
Pettigrew has a background in comedy so he's sarcastically funny rather
than strident or didactic, which for me was just the tone I needed to
enjoy reading this enough to think deeply about it.
The thing that most surprised me, even though it probably shouldn't, was
just how many of the problems Pettigrew had to deal with stemmed from
drugs. My guess is that a good 75% of the issues he described were a
direct result of someone dealing drugs, growing drugs, stealing things to
buy drugs, throwing parties with druggie friends, doing bizarre and
dangerous things because they were on drugs, not taking care of their
property because they were too busy doing drugs, or letting their property
be taken over by other people doing or selling drugs. It's just
never-ending. The case load is clearly made worse by chronic
understaffing and underfunding, and spending more money on giving people
more assistance is part of any reasonable solution, but so is reducing the
demand. If the pattern of complaints in the US is at all similar (and I
bet it is), it's no wonder that the police perceive drugs as central to
their job.
Pettigrew talks about this at some length in the epilogue, and I think one
of his conclusions is worth quoting here:
Years of interacting with class A drug users has shown me that they
really don't want to be out hustling to make enough money for their
next score of diluted heroin. They want to sit at home, take drugs
and when those drugs wear off, take some more. You may view this as a
wasted life, and you may well be right, but here's the thing: they are
going to do this anyway, whether we decide to criminalize them or not.
If, after a lengthy period of honest, mature drug education across the
country via schools, further education, government advertising and so
on, class A drugs were made legally available on prescription to
adults via pharmacies, the vast majority of users would pick up their
prescriptions, go home, take their drugs and leave everyone else
alone. They couldn't be arsed to break into your car if they didn't
have to.
The decriminalization argument is a lot larger than the space of this book
review, so I won't get into it further, except to say that if you think
that conclusion sounds unreasonable or dangerous or destructive to
society, consider reading this book. One of the things that becomes
obvious from Pettigrew's diary of incidents is that most people just want
to feel safe, and a truly stunning amount of crime and anti-social
behavior that makes them feel not safe is a direct or indirect result of
people trying to get drugs or to get money to get drugs.
The other pattern that's obvious from this book (and obvious from most
writing by anyone involved in the justice system) is that the system
doesn't really work.
The best way to describe going to court is that it's like paying a
visit to a run-down hospital where nobody gets better.
Some of that is because it's not set up to solve problems, and a lot of
that is because solving problems is a lot more expensive than we want to
admit and we don't want to pony up the resources.
I'm probably making this book sound hopelessly depressing, but it's not.
It's angry and cynical, but it's also very funny (particularly if you like
sarcasm), extremely quotable, insightful, and deeply empathetic. There
are people trying their best to help other people despite a system that
doesn't reward them for doing so, and surprisingly often they manage to do
so. The path to helping more people isn't even that difficult to find.
The epilogue of this book is full of solid and straightforward ideas that
don't require some novel insight into humanity, just a bunch of hard work.
And, while reading about the work of helping people and being exasperated
by people, you'll also get to laugh at the bits of office nonsense that
are universal.
The old form for monthly one-to-ones used to have two questions
"What did you do over the last month?" and "What do you plan to do in
the next month?" and my line manager at the time seemed unimpressed
when I answered "my job" to both.
I loved this book. It was one of my favorite random finds of the year,
and, at least judging from how difficult it is to find in Amazon search
results, it's not gotten enough attention in the United States. Highly
recommended.
Rating: 9 out of 10
TL;DR: CPS-conversion and defunctionalization can help you to come up with a constant-stack algorithm.
Update: Turns out I inadvertedly plagiarized the talk The Best Refactoring You ve Never Heard Of by James Koppel. Please consider this a form of sincere flattery.
The starting point
Today, I ll take you on a another little walk through the land of program transformations. Let s begin with a simple binary tree, with value of unknown type in the leaves, as well as the canonical map function:
dataT a =L a B (T a) (T a)
map1 :: (a -> b) ->T a ->T b
map1 f (L x) =L (f x)
map1 f (B t1 t2) =B (map1 f t1) (map1 f t2)
As you can see, this map function is using the program stack as it traverses the tree. Our goal is now to come up with a map function that does not use the stack!
Why? Good question! In Haskell, there wouldn t be a strong need for this, as the Haskell stack is allocated on the heap, just like your normal data, so there is plenty of stack space. But in other languages or environments, the stack space may have a hard limit, and it may be advised to not use unbounded stack space.
That aside, it s a fun exercise, and that s sufficient reason for me.
(In the following, I assume that tail-calls, i.e. those where a function end with another function call, but without modifying its result, do not actually use stack space. Once all recursive function calls are tail calls, the code is equivalent to an imperative loop, as we will see.)
Think?
We could now just stare at the problem (rather the code), and try to come up with a solution directly. We d probably think ok, as I go through the tree, I have to remember all the nodes above me so I need a list of those nodes and for each of these nodes, I also need to remember whether I am currently processing the left child, and yet have to look at the right one, or whether I am done with the left child so what do I have to remember about the current node ?
ah, my brain spins already. Maybe eventually I figure it out, but why think when we can derive the solution? So let s start with above map1, and rewrite it, in several, mechanical, steps into a stack-less, tail-recursive solution.
Go!
Before we set out, let me rewrite the map function using a local go helper, as follows:
map2 :: forall a b. (a -> b) ->T a ->T b
map2 f t = go t
where go ::T a ->T b
go (L x) =L (f x)
go (B t1 t2) =B (go t1) (go t2)
This transformation (effectively the static argument transformation ) has the nice advantage that we do not have to pass f around all the time, and that when we copy the function, I only have to change the top-level name, but not the names of the inner functions.
Also, I find it more aesthetically pleasing.
CPS
A blunt, effective tool to turn code that is not yet using tail-calls into code that only uses tail-calls is use continuation-passing style. If we have a function of type -> t, we turn it into a function of type -> (t -> r) -> r, where r is the type of the result we want at the very end. This means the function now receives an extra argument, often named k for continuation, and instead of returning some x, the function calls k x.
We can apply this to our go function. Here, both t and r happen to be T b; the type of finished trees:
map3 :: forall a b. (a -> b) -> T a -> T b
map3 f t = go t (\r -> r)
where
go :: T a -> (T b -> T b) -> T b
go (L x) k = k (L (f x))
go (B t1 t2) k = go t1 (\r1 -> go t2 (\r2 -> k (B r1 r2)))
Note that when initially call go, we pass the identity function (\r -> r) as the initial continuation.
Alas, suddenly all function calls are in tail position, and this codes does not use stack space! Technically, we are done, although it is not quite satisfying; all these lambdas floating around obscure the meaning of the code, are maybe a bit slow to execute, and also, we didn t really learn much yet. This is certainly not the code we would have writing after thinking hard .
Defunctionalization
So let s continue rewriting the code to something prettier, simpler. Something that does not use lambdas like this.
Again, there is a mechanical technique that can help it. It likely won't make the code prettier, but it will get rid of the lambdas, so let s do that an clean up later.
The technique is called defunctionalization (because it replaces functional values by plain data values), and can be seen as a form of refinement.
Note that we pass around vales of type (T b -> T b), but we certainly don t mean the full type (T b -> T b). Instead, only very specific values of that type occur in our program, So let us replace (T b -> T b) with a data type that contains representatives of just the values we actually use.
We find at all values of type (T b -> T b). These are:
(\r -> r)
(\r1 -> go t2 (\r2 -> k (B r1 r2)))
(\r2 -> k (B r1 r2))
We create a datatype with one constructor for each of these:
dataK=IK1K2
(This is not complete yet.)
We introduce an interpretation function that turns a K back into a (T b -> T b):
eval ::K-> (T b ->T b)
eval = (*TBD*)
In the function go, instead of taking a parameter of type (T b -> T b), we take a K. And when we actually use the continuation, we have to turn the K back to the function using eval:
go ::T a ->K a b ->T b
go (L x) k = eval k (L (f x))
go (B t1 t2) k = go t1 K1
We also do this to the code fragments identified in the first step; these become:
(\r -> r)
(\r1 -> go t2 K2)
(\r2 -> eval k (B r1 r2))
Now we complete the eval function: For each constructor, we simply map it to the corresponding lambda from step 1:
eval ::K-> (T b ->T b)
eval I= (\r -> r)
eval K1= (\r1 -> go t2 K2)
eval K2= (\r2 -> eval k (B r1 r2))
This doesn t quite work yet: We have variables on the right hand side that are not bound (t2, r1, k). So let s add them to the constructors K1 and K2 as needed. This also changes the type K itself; it now needs to take type parameters.
This leads us to the following code:
dataK a b
=IK1 (T a) (K a b)
K2 (T b) (K a b)
map4 :: forall a b. (a -> b) ->T a ->T b
map4 f t = go t Iwhere go ::T a ->K a b ->T b
go (L x) k = eval k (L (f x))
go (B t1 t2) k = go t1 (K1 t2 k)
eval ::K a b -> (T b ->T b)
eval I= (\r -> r)
eval (K1 t2 k) = (\r1 -> go t2 (K2 r1 k))
eval (K2 r1 k) = (\r2 -> eval k (B r1 r2))
Not really cleaner or prettier, but everything is still tail-recursive, and we are now working with plain data.
We like lists
To clean it up a little bit, we can notice that the K data type really is just a list of values, where the values are either T a or T b. We do not need a custom data type for this! Instead of our K, we can just use the following, built from standard data types:
type K' a b = [Either (T a) (T b)]
Now I replace I with [], K1 t2 k with Left t2 : k and K2 r1 k with Right r1 : k. I also, very suggestively, rename go to down and eval to up:
map5 :: forall a b. (a -> b) ->T a ->T b
map5 f t = down t []
where down ::T a ->K' a b ->T b
down (L x) k = up k (L (f x))
down (B t1 t2) k = down t1 (Left t2 : k)
up ::K' a b ->T b ->T b
up [] r = r
up (Left t2 : k) r1 = down t2 (Right r1 : k)
up (Right r1 : k) r2 = up k (B r1 r2)
At this point, the code suddenly makes more sense again. In fact, I can try to verbalize it:
As we traverse the tree, we have to remember for all parent nodes, whether there is still something Left to do when we come back to it (so we remember a T a), or if we are done with that (so we have a T b). This is the list K' a b.
We begin to go down the left of the tree (noting that the right siblings are still left to do), until we hit a leaf. We transform the leaf, and then go up.
If we go up and hit the root, we are done. Else, if we go up and there is something Left to do, we remember the subtree that we just processed (as that is already in the Right form), and go down the other subtree. But if we go up and there is nothing Left to do, we put the two subtrees together and continue going up.
Quite neat!
The imperative loop
At this point we could stop: the code is pretty, makes sense, and has the properties we want. But let s turn the dial a bit further and try to make it an imperative loop.
We know that if we have a single tail-recursive function, then that s equivalent to a loop, with the function s parameter turning into mutable variables. But we have two functions!
It turns out that if you have two functions a -> r and b -> r that have the same return type (which they necessarily have here, since we CPS-converted them further up), then those two functions are equivalent to a single function taking a or b , i.e. Either a b -> r. This really nothing else than the high-school level algebra rule of rarb = ra + b.
So (after reordering the arguments of down to put T b first) we can rewrite the code as
map6 :: forall a b. (a -> b) ->T a ->T b
map6 f t = go (Left t) []
where go ::Either (T a) (T b) ->K' a b ->T b
go (Left (L x)) k = go (Right (L (f x))) k
go (Left (B t1 t2)) k = go (Left t1) (Left t2 : k)
go (Right r) [] = r
go (Right r1) (Left t2 : k) = go (Left t2) (Right r1 : k)
go (Right r2) (Right r1 : k) = go (Right (B r1 r2)) k
Do you see the loop yet? If not, maybe it helps to compare it with the following equivalent imperative looking pseudo-code:
mapLoop :: forall a b. (a -> b) -> T a -> T b
mapLoop f t
var node = Left t;
var parents = [];
while (true)
switch (node)
Left (L x) -> node := Right (L (f x))
Left (B t1 t2) -> node := Left t1; parents.push(Left t2)
Right r1 ->
if (parents.len() == 0)
return r1;
else
switch (parents.pop())
Left t2 -> node := Left t2; parents.push(Right r1);
Right r2 -> node := Right (B r1 r2)
Conclusion
I find it enlightening to see how apparently very different approaches to a problem (recursive, lazy functions and imperative loops) are connected by a series of rather mechanical transformations. When refactoring code, it is helpful to see if one can conceptualize the refactoring as one of those mechanical steps (refinement, type equivalences, defunctionalization, cps conversion etc.)
If you liked this post, you might enjoy my talk The many faces of isOrderedTree, which I have presented at MuniHac 2019 and Haskell Love 2020.
Hail is a gunrunner, an outlaw and criminal, someone who knows how to
survive violence and navigate by personal loyalty. That world knows her
as Cressen Stone. What her colleagues don't know is that she's also an
Imperial Princess. Hailimi Mercedes Jaya Bristol left that world twenty
years earlier in secret pursuit of her father's killer and had no
intention of returning. But her sisters are dead, her mother's health is
failing, and two Imperial Trackers have been sent to bring her back to her
rightful position as heir.
I'm going to warn up-front that the first half of this novel was rough to
the point of being unreadable. Wagers tries much too hard to establish
Hail as a reluctant heroine torn between her dislike of royal protocols
and her grief and anger at the death of her sisters. The result is
excessively melodramatic and, to be frank, badly written. There are a lot
of passages like this:
His words slammed into me, burning like the ten thousand volts of a
Solarian Conglomerate police Taser.
(no, there's no significance to the Solarian Conglomerate here), or, just
three paragraphs later:
The air rushed out of my lungs. Added grief for a niece I'd never
known. One more log on the pyre set to burn my freedom to ashes. The
hope I'd had of getting out of this mess was lost in that instant, and
I couldn't do anything but stare at Emmory in abject shock.
Given how much air rushes out of Hail's lungs and how often she's struck
down with guilt or grief, it's hard to believe she doesn't have brain
damage.
Worse, Hail spends a great deal of the first third of the book whining,
which given that the book is written in first person gets old very
quickly. Every emotion is overwritten and overstressed as Hail rails
against obvious narrative inescapability. It's blatantly telegraphed from
the first few pages that Hail is going to drop into the imperial palace
like a profane invasion force and shake everything up, but the reader has
to endure far too long of Hail being dramatically self-pitying about the
plot. I almost gave up on this book in irritation (and probably should
have).
And then it sort of grew on me, because the other thing Wagers is doing
(also not subtly) is a story trope for which I have a particular
weakness: The fish out of water who nonetheless turns out to be the person
everyone needs because she's systematically and deliberately kind and
thoughtful while not taking any shit. Hail left Pashati young and
inexperienced, with a strained relationship with her mother and a habit of
letting her temper interfere with her ability to negotiate palace
politics. She still has the temper, but age, experience, and confidence
mean that she's decisive and confident in a way she never was before. The
second half of this book is about Hail building her power base and winning
loyalty by being loyal and decent. It's still not great writing, but
there's something there I enjoyed reading.
Wagers's setting is intriguing, although it makes me a bit nervous. The
Indranan Empire was settled by colonists of primarily Indian background.
The court trappings, mythology, and gods referenced in Behind the
Throne are Hindu-derived, and I suspect (although didn't confirm) that
the funeral arrangements are as well. Formal wear (and casual wear) for
women is a sari. There's a direct reference to the goddess Lakshimi (not
Lakshmi, which Wikipedia seems to indicate is the correct spelling,
although transliteration is always an adventure).
I was happy to see this, since there are more than enough SF novels out
there that seem to assume only western countries go into space. But I'm
never sure whether the author did enough research or has enough personal
knowledge to pull off the references correctly, and I personally wouldn't
know the difference.
The Indranan Empire is also matriarchal, and here Wagers goes for an
inversion of sexism that puts men in roughly the position women were in
the 1970s. They can, in theory, do most jobs, but there are many things
they're expected not to do, there are some explicit gender lines in power
structures, and the role of men in society is a point of political
conflict. It's skillfully injected as social background, with a
believable pattern of societal prejudice that doesn't necessarily apply to
specific men in specific situations. I liked that Wagers did this without
giving the Empire itself any feminine-coded characteristics. All admirals
are women because the characters believe women are obviously better
military leaders, not because of some claptrap about nurturing or caring
or some other female-coded reason from our society.
That said, this gender role inversion didn't feel that significant to the
story. The obvious "sexism is bad, see what it would be like if men were
subject to it" message ran parallel to the main plot and never felt that
insightful to me. I'm therefore not sure it was successful or worth the
injection of sexism into the reading experience, although it certainly is
different from the normal fare of space empires.
I can't recommend Behind the Throne because a lot of it just isn't
very good. But I still kind of want to because I sincerely enjoyed the
last third of the book, despite some lingering melodrama. Watching Hail
succeed by being a decent, trustworthy, loyal, and intelligent person is
satisfying, once she finally stops whining. The destination is probably
not worth the journey, but now that I've finished the first book, I'm
tempted to grab the second.
Followed by After the Crown.
Rating: 6 out of 10
The people who are pro-Government and in this case pro-Corporate do not have any success stories that they can share. Hence, most of the time the arguments are that the other are bad. For e.g. quite a few people argue that we don t need farmers, we can just order from restaurant. They have completely disassociated the idea that even then you need farmers as unless the farmers put the seed in, till the soil and wait for the rains or have irrigation you won t get ripe vegetables which then has to be taken out, and somehow sold to the wholesaler from where it comes to the restaurant and then to your plate. Sadly, even the farm-to-fork infographics are so depressingly sad, you want to look away. If you see the infographic you see it is just not non-veg but also vegetarian food grains which go under lot of questionable practices. Even, with such scenarios that is done by corporations our people want to go ahead. I will share stories from other countries which tell how they are doing more.
The Soldier-Farmer
Another sad part of these protests have been soldiers who have been returning their medals. The ones who oppose have the gall to say they should return the cash rewards they got. So just like farmers, seems soldiers also do not need money to survive. They are supposed to live only on air and water. This is after the present Govt. has reduced their pensions after retirement and that too without any discussion
GOI pensions to ex-servicemen
Now I nor anybody else would have minded if these conditions were shared going forward rather than doing it retrospectively. People who usually go to the army are not in it for money but for the adventure and glory they bring. But they do also have a family and have a family responsibility. In most other countries, the soldier and his families are well-looked after. If you know that even after you die, the Government would look after your family, you will do your best. Unfortunately, many veterans in India themselves are asked to help by many war widows as the widows don t get family pensions. The proposal naturally has left many miffed. In fact many of the veterans who used to advise people to join the armed forces now advise young people to pursue civilian life and careers. This is when Indian Army has been ironically having shortage of officers from well over a decade and stresses felt by Army personnel also known for a long time.
Even under this nationalistic Government, if it cannot take care of its soldiers, then forget about others.
India Defence Spending vis-a-vis other countries.
Now it is nobody s argument that India needs to improve its tooth-to-tail ratio but this is the wrong way to go about it. I would probably talk about that some other time as that totally needs its whole place.
Even OROP, which was the mandate of this Government hasn t had been done in full as there are quite a few cases in the Supreme Court. Almost all the cases have been heard and only decisions have to be given which the SC for whatever reason doesn t want to give. They just keep changing the date of the hearing. Nowadays, in many suits/cases, the SC asks for fresh hearings even though all the old records are there. This is a newish phenomena which is being observed in SC. Why is it being done? Your guess is as good as mine. One thing for sure has changed, the SC which used to be citizen-focussed or enabler of human rights and used to be held as a beacon for judicial activism has changed but these are other topics which need their own space.
Update 16/12/2020 The SC recommends setting up a committee to discuss farmer issues. And this is nothing new. This is called death by committee. When there is already so much literature on the subject, including the works done by Swaminathan Commission. There has been 6 reports which do look at farmer issues in a holistic manner. This is the Supreme Court giving an escape route to GOI. They also have abstained from having a whole session citing Covid. This is when the ruling Govt. is putting a massive 1000 crore on a new building on which the SC has put on hold. And even then the GOI went ahead and did a Bhoomi-Pujan (traditional ceremony when making a new construction from scratch.)
Naturally due to the double whammy of both the pension reforms and now the laws to make corporate farming more aggressive has left a deep impact on the soldier-farmer that the state does not think or feel for him.
Even the United States farm-aid eloquently describes how corporate farming has made independent farmers suffer. You read that, and it seems it is as the state of our farmers here in India. Even their average land-holding has dropped a bit. I have shared about the state of farmers in India, in twoblog posts previously. And it is not just farm owners who have had it bad, even farm workers in U.S. The issue may look to be about the pandemic but goes far deeper.
The Israeli Model
The Israelis have always used collective farming and do have a large share in farming there. The old model called Kibbutz is what made Israelis self-sufficient in food and water and actually are world-leaders where they export their services to other nations on the same thing.
France
Just like many other countries, France also seems to have favored farmer co-operatives. Almost 75% of all farmers are in co-operatives.
Italy
The country world-famous for its wines and cheese are made by its co-operatives. In fact co-ops are the buzzword it seems in Italy, more so in Northern Italy.
Asian economies
Even Asian economies, especially East Asian economies by and large have been turning to co-operatives.
Brazil
Now Brazil is almost 40% more than India. In fact, in most of the indices, Brazil beats India handsomely. So one would be forgiven to think that Brazil must have corporate farming. But nothing could be further from the truth. The only downer is that they have high crime in some areas. Otherwise, they are in many ways better than India. In fact, I was surprised a few years ago to learn about Mercsour. I would have to admit though I learned much about Brazil when Debian was holding a debconf about a year back. Otherwise, I had known about the country for number of years but apart from its carnival and samba, hadn t known much about it. I did come to know that most of Latin America also loves spices as much as Indians do. They show that love by using hot sauces. I do one day wanna try one of their sauces to see what makes it tick. I do know they like to barbecuevegetables as much as barbecuing non-veg food. This is going a bit OT but then that s the foodie in me Conclusion
I could have shared more countries which have chosen the co-operative way rather than corporate farming and that is simply because they know what is best for their people and what is best even politically. The new farm laws are neither grounded in farmer s welfare nor anything else. The Govt. has been trying to undermine the farmers for years together. In fact, Madhya Pradesh has openly said that they will not allow farmers from other states to sell in their state. Although, even before these laws there was nothing to restrict the farmer from selling his produce anywhere in the country. Angering the farmers is not good politics as was found sometime back but guessing some lessons need to be re-learned.
One comment though, on social media I have seen many people especially youngsters having no real understanding of what inflation is all about. For e.g. if you ask them how come we are having a sort of record inflation in a technical recession (there has been a contraction, actually) and you see them putting themselves into bigger and bigger ditches. This does explain in part why the BJP wins in elections. If you do more rhetoric, which BJP is good as, rather than educating people than you are bound to win. You don t need plans, you don t need a vision, just rhetoric will do. What more evidence is needed when the economy is and was in a worse shape even before the pandemic and BJP won. I would probably write about that as that again needs lot of background and understanding as well as related terms.
Like many other people, I first became aware of Anne Helen Petersen's
journalism when her Buzzfeed article
"How Millennials Became the Burnout Generation" went viral. Can't
Even is the much-awaited (at least by me) book-length expansion of that
thesis: The United States is, as a society, burning out, and that burnout
is falling on millennials the hardest. We're not recognizing the symptoms
because we think burnout looks like something dramatic and flashy. But
for most people burnout looks less like a nervous breakdown and more like
constant background anxiety and lack of energy.
Laura, who lives in Chicago and works as a special ed teacher, never
wants to see her friends, or date, or cook she's so tired, she just
wants to melt into the couch. "But then I can't focus on what I'm
watching, and end up unfocused again, and not completely relaxing,"
she explained. "Here I am telling you I don't even relax right! I
feel bad about feeling bad! But by the time I have leisure time, I
just want to be alone!"
Petersen explores this idea across childhood, education, work, family, and
parenting, but the core of her thesis is the precise opposite of the
pervasive myth that millennials are entitled and lazy (a persistent
generational critique that Petersen points out was also leveled at their
Baby Boomer parents in the 1960s and 1970s). Millennials aren't slackers;
they're workaholics from childhood, for whom everything has become a
hustle and a second (or third or fourth) job. The struggle with
"adulting" is a symptom of the burnout on the other side of exhaustion,
the mental failures that happen when you've forced yourself to keep going
on empty so many times that it's left lingering damage.
Petersen is a synthesizing writer who draws together the threads of other
books rather than going deep on a novel concept, so if you've been reading
about work, psychology, stress, and productivity, many of the ideas here
will be familiar. But she's been reading the same authors that I've been
reading (Tressie McMillan Cottom,
Emily Guendelsberger, Brigid Schulte, and even Cal Newport), and
this was the book that helped me pull those analyses together into a
coherent picture.
That picture starts with the shift of risk in the 1970s and 1980s from
previously stable corporations with long-lasting jobs and retirement
pensions onto individual employees. The corresponding rise in precarity
and therefore fear led to a concerted effort to re-establish a feeling of
control. Baby Boomers doubled down on personal responsibility and
personal capability, replacing unstructured childhood for their kids with
planned activities and academic achievement. That generation, in turn,
internalized the need for constant improvement, constant grading, and
constant achievement, accepting an implied bargain that if they worked
very hard, got good grades, got into good schools, and got a good degree,
it would pay off in a good life and financial security.
They were betrayed. The payoff never happened; many millennials graduated
into the Great Recession and the worst economy since World War II. In
response, millennials doubled down on the only path to success they were
taught. They took on more debt, got more education, moved back in with
their parents to cut expenses, and tried even harder.
Even after watching our parents get shut out, fall from, or simply
struggle anxiously to maintain the American Dream, we didn't reject
it. We tried to work harder, and better, more efficiently, with more
credentials, to achieve it.
Once one has this framework in mind, it's startling how pervasive the
"just try harder" message is and how deeply we've internalized it. It is
at the center of the time management literature: Getting Things Done focuses almost entirely on individual
efficiency. Later time management work has become more aware of the
importance of pruning the to-do list and doing fewer things, but addresses
that through techniques for individual prioritization.
Cal Newport is more aware than most that
constant busyness and multitasking interacts poorly with the human brain,
and has taken a few tentative steps towards treating the problem as
systemic rather than individual, but his focus is still primarily on
individual choices. Even when tackling a problem that is clearly
societal, such as the monetization of fear and outrage on social media,
the solutions are all individual: recognize that those platforms are bad
for you, make an individual determination that your attention is being
exploited, and quit social media through your personal force of will.
And this isn't just productivity systems. Most of public discussion of
environmentalism in the United States is about personal energy
consumption, your individual carbon footprint, household recycling, and
whether you personally should eat meat. Discussions of monopoly and
monopsony become debates over whether you personally should buy from
Amazon. Concerns about personal privacy turn into advocacy for using an
ad blocker or shaming people for using Google products. Articles about
the growth of right-wing extremism become exhortations to take
responsibility for the right-wing extremist in your life and argue them
out of their beliefs over the dinner table. Every major systemic issue
facing society becomes yet another personal obligation, another place we
are failing as individuals, something else that requires trying harder,
learning more, caring more, doing more.
This advice is well-meaning (mostly; sometimes it is an intentional and
cynical diversion), and can even be effective with specific problems. But
it's also a trap. If you're feeling miserable, you just haven't found the
right combination of time-block scheduling, kanban, and bullet journaling
yet. If you're upset at corporate greed and the destruction of the
environment, the change starts with you and your household. The solution
is in your personal hands; you just have try a little harder, work a
little harder, make better decisions, and spend money more ethically
(generally by buying more expensive products). And therefore, when we're
already burned out, every topic becomes another failure, increasing our
already excessive guilt and anxiety.
Believing that we're in control, even when we're not, does have
psychological value. That's part of what makes it such a beguiling trap.
While drafting this review, I listened to Ezra Klein's interview with
Robert Sapolsky on poverty and stress, and one of the points he made is
that, when mildly or moderately bad things happen, believing you have
control is empowering. It lets you recast the setback as a larger
disaster that you were able to prevent and avoid a sense of futility. But
when something major goes wrong, believing you have control is actively
harmful to your mental health. The tragedy is now also a personal
failure, leading to guilt and internal recrimination on top of the effects
of the tragedy itself. This is why often the most comforting thing we can
say to someone else after a personal disaster is "there's nothing you
could have done."
Believing we can improve our lives if we just try a little harder does
work, until it doesn't. And because it does work for smaller things, it's
hard to abandon; in the short term, believing we're at the mercy of forces
outside our control feels even worse. So we double down on
self-improvement, giving ourselves even more things to attempt to do and
thus burning out even more.
Petersen is having none of this, and her anger is both satisfying and
clarifying.
In writing that article, and this book, I haven't cured anyone's
burnout, including my own. But one thing did become incredibly clear.
This isn't a personal problem. It's a societal one and it will not
be cured by productivity apps, or a bullet journal, or face mask skin
treatments, or overnight fucking oats. We gravitate toward those
personal cures because they seem tenable, and promise that our lives
can be recentered, and regrounded, with just a bit more discipline, a
new app, a better email organization strategy, or a new approach to
meal planning. But these are all merely Band-Aids on an open wound.
They might temporarily stop the bleeding, but when they fall off, and
we fail at our new-found discipline, we just feel worse.
Structurally, Can't Even is half summaries of other books and
essays put into this overall structure and half short profiles and quotes
from millennials that illustrate her point. This is Petersen's typical
journalistic style if you're familiar with her other work. It gains a lot
from the voices of individuals, but it can also feel like argument from
anecdote. If there's a epistemic flaw in this book, it's that Petersen
defends her arguments more with examples than with scientific study. I've
read enough of the other books she cites, many of which do go into the
underlying studies and statistics, to know that her argument is
well-grounded, but I think Can't Even works better as a roadmap and
synthesis than as a primary source of convincing data.
The other flaw that I'll mention is that although Petersen tries very hard
to incorporate poorer and non-white millennials, I don't think the effort
was successful, and I'm not sure it was possible within the structure
of this book. She frequently makes a statement that's accurate and
insightful for millennials from white, middle-class families, acknowledges
that it doesn't entirely apply to, for example, racial minorities, and
then moves on without truly reconciling those two perspectives. I think
this is a deep structural problem: One's experience of American life
is very different depending on race and class, and the phenomenon that
Petersen is speaking to is to an extent specific to those social classes
who had a more comfortable and relaxing life and are losing it.
One way to see the story of the modern economy is that white people are
becoming as precarious as everyone else already was, and are reacting by
making the lives of non-white people yet more miserable. Petersen is
accurately pointing to significant changes in relationships with
employers, productivity, family, and the ideology of individualism, but
experiencing that as a change is more applicable to white people than
non-white people. That means there are, in a way, two books here: one
about the slow collapse of the white middle class into constant burnout,
and a different book about the much longer-standing burnout of being
non-white in the United States and our systemic failure to address the
causes of it. Petersen tries to gesture at the second book, but she's not
the person to write it and those two books cannot comfortably live between
the same covers. The gestures therefore feel awkward and forced, and
while the discomfort itself serves some purpose, it lacks the insight that
Petersen brings to the rest of the book.
Those critiques aside, I found Can't Even immensely clarifying.
It's the first book that explained to me in a way I understood what's so
demoralizing and harmful about Instagram and its allure of cosplaying as a
successful person. It helped me understand how productivity and
individual political choices fit into a system that emphasizes individual
action as an excuse to not address collective problems. And it also gave
me a strange form of hope, because if something can't go on forever, it
will, at some point, stop.
Millennials have been denigrated and mischaracterized, blamed for
struggling in situations that set us up to fail. But if we have the
endurance and aptitude and wherewithal to work ourselves this deeply
into the ground, we also have the strength to fight. We have little
savings and less stability. Our anger is barely contained. We're a
pile of ashes smoldering, a bad memory of our best selves.
Underestimate us at your peril: We have so little left to lose.
Nothing will change without individual people making different decisions
and taking different actions than they are today. But we have gone much
too far down the path of individual, atomized actions that may produce
feelings of personal virtue but that are a path to ineffectiveness and
burnout when faced with systemic problems. We need to make different
choices, yes, but choices towards solidarity and movement politics rather
than personal optimization.
There is a backlash coming. If we let it ground itself in personal
grievance, it could turn ugly and take a racist and nationalist direction.
But that's not, by in large, what millennials have done, and that makes me
optimistic. If we embrace the energy of that backlash and help shape it
to be more inclusive, just, and fair, we can rediscover the effectiveness
of collective solutions for collective problems.
Rating: 8 out of 10
VDPAU is the Video Decode and Presentation API for Unix [1]. I noticed an error with mplayer Failed to open VDPAU backend libvdpau_i965.so: cannot open shared object file: No such file or directory , Googling that turned up Debian Bug #869815 [2] which suggested installing the packages vdpau-va-driver and libvdpau-va-gl1 and setting the environment variable VDPAU_DRIVER=va_gl to enable VPDAU.
The command vdpauinfo from the vdpauinfo shows the VPDAU capabilities, which showed that VPDAU was working with va_gl.
When mplayer was getting the error about a missing i915 driver it took 35.822s of user time and 1.929s of system time to play Self Control by Laura Branigan [3] (a good music video to watch several times while testing IMHO) on my Thinkpad Carbon X1 Gen1 with Intel video and a i7-3667U CPU. When I set VDPAU_DRIVER=va_gl mplayer took 50.875s of user time and 4.207s of system time but didn t have the error.
It s possible that other applications on my Thinkpad might benefit from VPDAU with the va_gl driver, but it seems unlikely that any will benefit to such a degree that it makes up for mplayer taking more time. It s also possible that the Self Control video I tested with was a worst case scenario, but even so taking almost 50% more CPU time made it unlikely that other videos would get a benefit.
For this sort of video (640 480 resolution) it s not a problem, 38 seconds of CPU time to play a 5 minute video isn t a real problem (although it would be nice to use less battery). For a 1600*900 resolution video (the resolution of the laptop screen) it took 131 seconds of user time to play a 433 second video. That s still not going to be a problem when playing on mains power but will suck a bit when on battery. Most Thinkpads have Intel video and some have NVidia as well (which has issues from having 2 video cards and from having poor Linux driver support). So it seems that the only option for battery efficient video playing on the go right now is to use a tablet.
On the upside, screen resolution is not increasing at a comparable rate to Moore s law so eventually CPUs will get powerful enough to do all this without using much electricity.
Like each month, here comes a report about the work of paid contributors to Debian LTS.
Individual reports
In November, 239.25 work hours have been dispatched among 13 paid contributors. Their reports are available:
Evolution of the situation
In November we held the last
LTS team meeting for 2020 on IRC, with the next one coming up at the end of January.
We announced a new formalized initiative for
Funding Debian projects with money from Freexian s LTS service.
Finally, we would like to remark once again that we are constantly looking
for new contributors. Please contact Holger
if you are interested!
We re also glad to welcome two new sponsors, Moxa, a device manufacturer, and a French research lab (Institut des Sciences Cognitives Marc Jeannerod).
The security tracker currently lists 37 packages with a known CVE and the dla-needed.txt file has 40 packages needing an update.
Thanks to our sponsors
Sponsors that joined recently are in bold.
Today, the Debian website displays a new homepage.
Since the most recent web team sprint
in March 2019, we have been working on renewing the structure, content, layout
and scripts that build the site.
There has been work mainly in two areas: removing or updating obsolete content,
and creating a new homepage which is more attractive to newcomers,
and which also highlights the social aspect of the Debian project
in addition to the operating system we develop.
Although this took longer than we would have liked,
and we don't consider this new homepage final,
we think it's a good first step towards a much better web site.
The web team will continue to work on restructuring the Debian website.
We would like to appeal to the community for help, and are also considering
external assistance, since we're a small group, whose members are also involved
in other Debian teams. Some of the next steps we expect to walk are
improve the CSS, icons, and layout in general, and review of the content,
to have a better structure.
If you would like to help, contact us. You can reply to the version of this
article (with some more details)
published in our public mailing list
or chat with us in the #debian-www IRC channel (at irc.debian.org).
I have a secret: risotto doesn't have to involve standing over a pot,
stirring for 30 minutes. There is a better way.
I've made risotto using the "stir 5ever" method and frankly this one is half
the work and just as good. I took inspiration from Kenji
Lopez-Alt, who describes how you can make risotto with only a few
minutes of stirring at the end! Yes, this is a secret too good to keep to
myself.
The linked recipe is too rich for a weeknight dinner, at least for my tastes,
so I've included my typical modifications below, which omits the heavy cream. I
usually make mushroom risotto, because all the ingredients are long-lived
pantry ingredients, which means I can make this on a whim without having to
grocery shop!
Mushroom risotto
Serves 3 as a main course. Active time: 25m. Total time: 45m.
Ingredients:
1oz (28g) dried mushrooms, such as porcini (or morels!)
3 cups chicken or vegetable stock
1 cups short-grained rice (I use arborio)
cup white wine
2 tbsp olive oil
2 tbsp unsalted butter
4 cloves garlic, minced
1 small onion, small diced
3oz (85g) grated Parmesan cheese
herbs for garnish (optional)
Recipe:
Leave mushrooms to rehydrate in 1 cup of hot water for at least 10 minutes.
Set a wide saucepan (about 3.5qts) or skillet on medium heat.
Mix stock and wine for a total of 4 cups. You can used homemade stock (the
best), boxed, or reconstitute from bouillon (my usual). If you use bouillon,
I find you get the best flavour if you use a mix, so I tend to use half
"no-chicken" and half "organic chicken" of the Better than Bouillon brand.
Let this cool if you used boiling water; you don't want it to be too hot.
Mix the rice and stock in a large bowl, agitating it to release the starch.
Reserve stock and set the rice in a strainer to drain.
Small dice an onion. Add olive oil and butter to the pan, and then add
the onion. Cook the onion until it's translucent, but don't brown it.
Increase the heat to high and add the rice to the pan to toast until it
becomes a little bit brown, stirring occasionally, about 3-4 minutes. Set a
timer so it doesn't burn
Meanwhile, drain the mushrooms, making sure you reserve the broth. Chop
mushrooms and mince the garlic. Once the rice is toasted, add mushrooms and
garlic and stir.
Stir the reserved stock. Add all of the mushroom liquid and all but 1 cup of
the starchy stock to the pan. Bring to a boil.
Once it has reached a boil, cover, reduce to the lowest heat, and allow the
rice to simmer undisturbed for 10 minutes. In the meantime, you can grate
the cheese.
After 10 minutes, stir the rice once, shake the pan to ensure it is level,
and return to the heat for 10 more minutes. Sit back, relax, and bask in the
very little stirring you are doing.
At this point, the rice should be nearly cooked. Give it a stir, and add
the remaining cup of broth. Stir until fully incorporated, turn the heat up
to high, and cook until the risotto reaches your preferred consistency. I
like mine rather thick.
Once the rice is fully cooked, turn off the heat and stir in the grated
cheese a bit at a time, reserving some for garnish. Taste, and season with
salt and pepper.
Garnish with the grated cheese, and perhaps some herbs. Serve and enjoy!
Variations
No mushrooms: Okay, okay, you hate mushrooms! Sorry! You can leave them
out. Don't bother with the mushrooms, and add broth to make up for the lost
liquid.
Mushroom lover: Alternatively, if you love mushrooms and you have fresh
ones available, use &frac13 to a pound (150-225g) chopped fresh
mushrooms instead of dried. Add them at the same time you add the onions to
ensure all the liquid cooks off.
Milanese, with stuff: One of my favourite variations on this dish is a
version with shrimp, asparagus, and saffron. Leave the mushrooms out, increase
the wine to or even 1 cup (seafood likes a little extra acidity),
ensure you have a total of 5 cups of broth, and add a few strands of saffron.
Chop asparagus and shrimp, season with salt and pepper, saut them with some
butter or olive oil in a separate pan so they don't overcook, and fold them in
at the very end, after you've added the cheese.
I MUST SUFFER: This was too easy? Want to stir more??? Fine, have it your
$*!#ing way.
I'm sure you can be creative and come up with something on your own...
This time of year, a lot of people are thinking of buying gadgets and phones as gifts. But there are a lot of tech companies that have unethical practices, from terrible working conditions in their factories to spying on their users. Here are some buying guides to help you find gadgets that are fun and not creepy.
The Free Software Foundation s Ethical Tech Giving Guide is a fantastic resource from what s probably the pickiest organization out there when it comes to tech. Not only do they highlight good devices, they also explain why and why you should, for instance, avoid the iPhone (their history of silencing political activists and spying on users).
The FSF also has a Guide to DRM-Free Living talks about books, video, audio, and software that respects your freedom by letting you make your own backups, move it to other devices, and continue to use your purchases even if you have no Internet or the company you bought them from goes bankrupt. This is a fantastic and HUGE resource; there are hundreds of organizations out there that provide content in a way that respects your rights and many of them do it for free, legally, as well.
PrivacyTools has a fantastic series of guides on everything from email providers to operating systems, as well as links to a number of other guides.
The DeGoogle wiki on Reddit (as well as the sidebar) has a lot of fantastic alternatives to things like Chromebooks, Chrome, Gmail, etc.
Related resources
Here are some resources for education (what the issues are) and information about what companies and products to avoid.
In addition to the FSF s other fantastic resources above, they also have a list of proprietary malware. It lists things, practices, and companies to avoid, and talks about the reasons why. Their addictions page is particularly good and relevant to my recent post on the problems of the attention economy.
The Surveillance Self-Defense site from the Electronic Frontier Foundation is a fantastic introduction into how corporate surveillance works and how to defend against it.
Use with a grain of salt:
Mozilla, the people behind Firefox, have a site called Privacy Not Included that rates products by how creepy they are. They focus more narrowly on privacy than the more expansive set of freedoms the FSF considers (privacy is one of a number of things the FSF looks at), and in some cases I would say Mozilla is too generous (eg, with the Amazon Kindle, a number of their data points are just incorrect.)
Despite having worked on a numberofARMplatforms I ve never actually had an ARM based development box at home. I have a Raspberry Pi B Classic (the original 256MB rev 0002 variant) a coworker gave me some years ago, but it s not what you d choose for a build machine and generally gets used as a self contained TFTP/console server for hooking up to devices under test. Mostly I ve been able to do kernel development with the cross compilers already built as part of Debian, and either use pre-built images or Debian directly when I need userland pieces. At a previous job I had a Marvell MACCHIATObin available to me, which works out as a nice platform - quad core A72 @ 2GHz with 16GB RAM, proper SATA and a PCIe slot. However they re still a bit pricey for a casual home machine. I really like the look of the HoneyComb LX2 - 16 A72 cores, up to 64GB RAM - but it s even more expensive.
So when I saw the existence of the 8GB Raspberry Pi 4 I was interested. Firstly, the Pi 4 is a proper 64 bit device (my existing Pi B is ARMv6 which means it needs to run Raspbian instead of native Debian armhf), capable of running an upstream kernel and unmodified Debian userspace. Secondly the Pi 4 has a USB 3 controller sitting on a PCIe bus rather than just the limited SoC USB 2 controller. It s not SATA, but it s still a fairly decent method of attaching some storage that s faster/more reliable than an SD card. Finally 8GB RAM is starting to get to a decent amount - for a headless build box 4GB is probably generally enough, but I wanted some headroom.
The Pi comes as a bare board, so I needed a case. Ideally I wanted something self contained that could take the Pi, provide a USB/SATA adaptor and take the drive too. I came across the pre-order for the DeskPi Pro, decided it was the sort of thing I was after, and ordered one towards the end of September. It finally arrived at the start of December, at which point I got round to ordering a Pi 4 from CPC.
Total cost ~ 120 for the case + Pi.
The Bad
First, let s get the bad parts out of the way.
I managed to break a USB port on the Desk Pi. It has a pair of forward facing ports, I plugged my wireless keyboard dongle into it and when trying to remove it the solid spacer bit in the socket broke off. I ve never had this happen to me before and I ve been using USB devices for 20 years, so I m putting the blame on a shoddy socket.
The first drive I tried was an old Crucial M500 mSATA device. I have an adaptor that makes it look like a normal 2.5 drive so I used that. Unfortunately it resulted in a boot loop; the Pi would boot its initial firmware, try to talk to the drive and then reboot before even loading Linux. The DeskPi Pro comes with an m2 adaptor and I had a spare m2 drive, so I tried that and it all worked fine. This might just be power issues, but it was an unfortunate experience especially after the USB port had broken off.
(Given I ended up using an M.2 drive another case option would have been the Argon ONE M.2, which is a bit more compact.)
The Annoying
The case is a little snug; I was worried I was going to damage things as I slid it in. Additionally the construction process is a little involved. There s a good set of instructions, but there are a lot of pieces and screws involved. This includes a couple of FFC cables to join things up. I think this is because they ve attempted to make a compact case rather than allowing a little extra room, and it does have the advantage that once assembled it feels robust without anything loose in it.
I hate the need for an external USB3 dongle to bridge from the Pi to the USB/SATA adaptor. All the cases I ve seen with an internal drive bay have to do this, because the USB3 isn t brought out internally by the Pi, but it just looks ugly to me. It s hidden at the back, but meh.
Fan control is via a USB/serial device, which is fine, but it attaches to the USB C power port which defaults to being a USB peripheral. Raspbian based kernels support device tree overlays which allows easy reconfiguration to host mode, but for a Debian based system I ended up rolling my own dtb file. I changed
#include "bcm283x-rpi-usb-peripheral.dtsi"
to
#include "bcm283x-rpi-usb-host.dtsi"
in arch/arm/boot/dts/bcm2711-rpi-4-b.dts and then I did:
and the resulting bcm2711-rpi-4-b.dtb file replaced the one in /boot/firmware. This isn t a necessary step if you don t want to use the cooling fan in the case, or the front USB ports, and it s not really anyone s fault, but it was an annoying extra step to have to figure out.
The DeskPi came with a microSD card that was supposed to have RaspiOS already on it. It didn t, it was blank. In my case that was fine, because I wanted to use Debian, but it was a minor niggle.
The Good
I used Gunnar s pre-built Pi Debian image and it Just Worked; I dd d it to the microSD as instructed and the Pi 4 came up with working wifi, video and USB enabling me to get it configured for my network. I did an apt upgrade and got updated to the Buster 10.7 release, as well as the latest 5.9 backport kernel, and everything came back without effort after a reboot. It s lovely to be able to run Debian on this device without having to futz around with self-compiled kernels.
The DeskPi makes a lot of effort to route things externally. The SD slot is brought out to the front, making it easy to fiddle with the card contents without having to open the case to replace it. All the important ports are brought out to the back either through orientation of the Pi, or extenders in the case. That means the built in Pi USB ports, the HDMI sockets (conveniently converted to full size internally), an audio jack and a USB-C power port. The aforementioned USB3 dongle for the bridge to the drive is the only external thing that s annoying.
Thermally things seem good too. I haven t done a full torture test yet, but with the fan off the system is sitting at about 40 C while fairly idle. Some loops in bash that push load up to above 2 get the temperature up to 46 C or so, and turning the fan on brings it down to 40 C again. It s audible, but quieter than my laptop and not annoying.
I liked the way the case came with everything I needed other than the Pi 4 and a suitable disk drive. There was an included PSU (a proper USB-C PD device, UK plug), the heatsink/fan is there, the USB/SATA converter is there and even an SD card is provided (though that s just because I had a pre-order).
Speaking of the SD, I only needed it for initial setup. Recent Pi 4 bootloaders are capable of booting directly from USB mass storage devices. So I upgraded using the RPi EEPROM Recovery image (which just needs extracted to the SD FAT partition, no need for anything complicated - boot with it and the screen goes all green and you know it s ok), then created a FAT partition at the start of the drive for the kernel / bootloader config and a regular EXT4 partition for root. Copies everything over, updated paths, took out the SD and it all just works happily.
Summary
My main complaint is the broken USB port, which feels like the result of a cheap connector. For a front facing port expected to see more use than the rear ports I think there s a reasonable expectation of robustness. However I m an early adopter and maybe future runs will be better.
Other than that I m pretty happy. The case is exactly the sort of thing I wanted; I was looking for something that would turn the Pi into a box that can sit on my desk on the network and that I don t have to worry about knocking wires out of or lots of cables hooking bits up. Everything being included made it very convenient to get up and running. I still haven t poked the Pi that hard, but first impressions are looking good for it being a trouble free ARM64 dev box in the corner, until I can justify a HoneyComb.