10 interesting stories served every morning and every evening.

Kill the Cookie Banner!

killthecookiebanner.eu

Stop the track­ing cir­cus.

Tired of mis­lead­ing cookie ban­ners? The EU Commission has fi­nally pro­posed a so­lu­tion: set your pri­vacy pref­er­ences in the browser once, and never see an­other ban­ner. Unfortunately, the track­ing in­dus­try is push­ing back — and so far, they’ve been suc­cess­ful. We need YOUR help to #KillTheCookieBanner!

Cookie ban­ners are made to trick you into waiv­ing your rights

You may think that EU pri­vacy law re­quires cookie ban­ners. But the law is clear: on­line track­ing is pro­hib­ited by de­fault.

Therefore, the track­ing in­dus­try needs you to waive your rights. That’s why they in­vented cookie ban­ners, which of­ten are de­lib­er­ately mis­lead­ing as well as an­noy­ing.

This re­sults in up to 90% of peo­ple say­ing YES — even though only around 3% ac­tu­ally want to be tracked on­line. This sys­tem is bro­ken by de­sign.

The so­lu­tion: au­to­mat­i­cally com­mu­ni­cate your pri­vacy pref­er­ence

In Autumn 2025, as part of a big­ger le­gal re­form*, the EU Commission fi­nally pro­posed a so­lu­tion to the cookie ban­ner prob­lem: au­to­mated sig­nals that would com­mu­ni­cate your pri­vacy pref­er­ences be­tween your de­vice and web­sites or apps. You could then choose whether you want to ac­cept, refuse, or limit track­ing.

This idea is nei­ther new nor com­plex. Your browser al­ready au­to­mat­i­cally sig­nals other pref­er­ences to web­sites, for ex­am­ple your pre­ferred lan­guage. In some US states, such sig­nals for pri­vacy pref­er­ences are al­ready legally sup­ported.

The track­ing lobby fights to keep the cookie ban­ner

This would be a sim­ple so­lu­tion. But the track­ing in­dus­try seems afraid that if you can ex­press your pref­er­ences ef­fi­ciently, it could re­sult in lower con­sent rates for track­ing.

Following lob­by­ing ef­forts spear­headed by Google and the track­ing in­dus­try, sev­eral Member States are now block­ing the EU Commission’s pro­posal to get rid of the cookie ban­ner.

But not only that: in­dus­try groups are also lob­by­ing the European Parliament to re­ject the pro­posal.

We need YOUR help!

That’s where you come in: the fight to kill the cookie ban­ner is far from over. The Member States and the European Parliament have not yet de­cided on their po­si­tion on the is­sue yet.

You can take ac­tion by con­tact­ing your rep­re­sen­ta­tive in the European Parliament or in your Member State and ex­press your frus­tra­tion.

*This pro­posal for pri­vacy sig­nals is part of an EU law re­form called the Digital Omnibus. Most other parts of this re­form are prob­lem­atic and would weaken peo­ple’s rights. We want to make clear that we do not sup­port these other as­pects of the pro­posed re­form.

*This pro­posal for pri­vacy sig­nals is part of an EU law re­form called the Digital Omnibus. Most other parts of this re­form are prob­lem­atic and would weaken peo­ple’s rights. We want to make clear that we do not sup­port these other as­pects of the pro­posed re­form.

A shell colon does nothing. Use it anyway.

refp.se

I’ve writ­ten more shell scripts than I can count, but I still stum­ble upon tricks that hon­estly blow my mind far too of­ten than I care to ad­mit. Latest thing that blew my head clean off? The shell colon.

#shell

#posix

#unix

In a land far-far away..

… there was once a far too cold cup of cof­fee next to a freshly brewed far-too-hot one. Four dif­fer­ent ter­mi­nals where three could have been closed an hour ago, and a shell script which I re­ally (really) did not want to write.

Who would have thought a sin­gle colon would be the one to save the day night?

Note: Want your mind blown straight away? See more colons in the lime­light.

Note: Want your mind blown straight away? See more colons in the lime­light.

Checking for re­quired ar­gu­ments

This is a fa­mil­iar dance, it’s pretty much mus­cle mem­ory by this point. You have a script, it takes a few ar­gu­ments, and some of them are manda­tory; al­right, an if-state­ment like so many times be­fore:

if [ -z $1” ]; then echo missing ar­gu­ment, abort­ing.” 1>&2 exit 1 fi

echo Hello $1!”

Though.. what if I told you the above four lines could be re­placed by just… one?

: ${1:?missing ar­gu­ment, abort­ing.}” echo Hello $1!”

$ bash ex­am­ple.sh ex­am­ple.sh: line 1: 1: miss­ing ar­gu­ment, abort­ing.

$ bash ex­am­ple.sh refp Hello refp!

And look what hap­pens if we re­fer to a vari­able with a proper name — it’s the same be­hav­ior as pre­vi­ously but eas­ier to spot; the di­ag­nos­tic in­cludes the name of our vari­able!

: ${GREET_NAME:?missing ar­gu­ment, abort­ing.}” echo Hello $GREET_NAME!”

$ bash greet.sh greet.sh: line 1: GREET_NAME: miss­ing ar­gu­ment, abort­ing.

Parameter ex­pan­sion and the story of :?

There are two things go­ing on in the pre­vi­ous snip­pet, and you are cor­rect in iden­ti­fy­ing that one part is us­ing pa­ra­me­ter ex­pan­sion:

The syn­tax ${name:?diagnostic} checks whether $name is un­set or empty — if it is, the di­ag­nos­tic is printed to stderr and the shell ex­its with a non-zero sta­tus, oth­er­wise;

The syn­tax ${name:?diagnostic} checks whether $name is un­set or empty — if it is, the di­ag­nos­tic is printed to stderr and the shell ex­its with a non-zero sta­tus, oth­er­wise;

if the vari­able is set, it is equiv­a­lent to $name.

if the vari­able is set, it is equiv­a­lent to $name.

That.. other colon

So that’s one colon, but what about that other one, the one who sits alone at the be­gin­ning of the line?

: is the null-com­mand — a builtin that does noth­ing but eval­u­ate its ar­gu­ments and dis­card the re­sult.

: is the null-com­mand — a builtin that does noth­ing but eval­u­ate its ar­gu­ments and dis­card the re­sult.

: is old — it goes all the way back to the 1971 Thompson shell where it dou­bled as a la­bel and Unix’s very first com­ment marker.

: is old — it goes all the way back to the 1971 Thompson shell where it dou­bled as a la­bel and Unix’s very first com­ment marker.

: two eyes star­ing at you in the dark, with love.

: two eyes star­ing at you in the dark, with love.

More colons in the lime­light

Perhaps we have al­ready es­tab­lished that there is more to : than meets the eye, but to prove the real magic of the null-com­mand — here are a few us­ages that blew my mind.

: ${DATA_DIR:=/var/data}” # set de­faults, : swal­lows the re­sult : ${RETRIES:=3}” # in­stead of run­ning it as a com­mand

: > er­ror.log # trun­cate er­ror.log : > er­ror.log > ac­cess.log # trun­cate both er­ror.log and ac­cess.log

( : < dataset.json ) && echo YES # is dataset.json read­able? ( : >> re­sult.json ) && echo YES # is re­sult.json writable?

trap : INT # trap re­quires a com­mand sleep 60 # sleep is in­ter­rupt­ible

set -u # er­ror on un­set vari­ables : $DEPLOY_ENV” $HOST # check DEPLOY_ENV and HOST

if some-com­mand; then : # com­mand re­quired else echo command failed” fi

Con-colon-sion

So, if you are like me and pre­fer less typ­ing (gotta go fast) — the null-com­mand and pa­ra­me­ter ex­pan­sion are a pair worth study­ing be­fore your cof­fee goes cold.

And also.. is­n’t this — magic?

set  : : : : : : : : : : : : : : : : : : : : :

while : colons are more than ${1:?magic}”; do echo $*” && shift done

Note: The above ex­am­ple is safe to run lo­cally, try it!

Note: The above ex­am­ple is safe to run lo­cally, try it!

Frequently Asked Questions

After read­ing a few com­ments on­line, it seems I skipped over some things worth ex­plain­ing. I will keep this sec­tion up­dated as ques­tions come up.

Why do I need the null-com­mand? Doesn’t the ex­pan­sion hap­pen with­out the colon? The pa­ra­me­ter ex­pan­sion will hap­pen re­gard­less, but with­out a null-com­mand or sim­i­lar us­age the shell will treat the re­sult­ing string as a com­mand to run. % ${HELLO:=123} zsh: com­mand not found: 123

If we pre­fix our pa­ra­me­ter-ex­pan­sion with the null-com­mand, the re­sult is dis­carded, but the ex­pres­sion is still eval­u­ated (setting HELLO to 123). % : ${HELLO:=123} % echo $HELLO 123

Why do I need the null-com­mand? Doesn’t the ex­pan­sion hap­pen with­out the colon?

The pa­ra­me­ter ex­pan­sion will hap­pen re­gard­less, but with­out a null-com­mand or sim­i­lar us­age the shell will treat the re­sult­ing string as a com­mand to run.

% ${HELLO:=123} zsh: com­mand not found: 123

If we pre­fix our pa­ra­me­ter-ex­pan­sion with the null-com­mand, the re­sult is dis­carded, but the ex­pres­sion is still eval­u­ated (setting HELLO to 123).

% : ${HELLO:=123} % echo $HELLO 123

Why use the null-com­mand when I could do VAR=${VAR:-default-value}? This at its core boils down to per­sonal pref­er­ence, but us­ing our beloved colon we can shrink the num­ber of po­ten­tial ty­pos to one (rather than two): : ${DATA_DIR:=/var/data}” # <- DATA_DIR men­tioned once (1) DATA_DIR=“${DATA_DRI:-/var/data}” # <- oops (2)

Why use the null-com­mand when I could do VAR=${VAR:-default-value}?

This at its core boils down to per­sonal pref­er­ence, but us­ing our beloved colon we can shrink the num­ber of po­ten­tial ty­pos to one (rather than two):

: ${DATA_DIR:=/var/data}” # <- DATA_DIR men­tioned once (1) DATA_DIR=“${DATA_DRI:-/var/data}” # <- oops (2)

Why would I do any of these when it hurts read­abil­ity? There are a few com­mon mis­con­cep­tions about the — very con­trived — ex­am­ples pre­sented in this ar­ti­cle, ques­tions re­gard­ing their use­ful­ness, or if one should ever-ever use these things at all. Let’s take the be­low as an ex­am­ple. if some-com­mand; then : # com­mand re­quired else echo command failed” fi

Of course you can use if ! some-com­mand and get rid of the branch­ing, but that is­n’t the point of the snip­pet — the point is to show that the null-com­mand can be used in places where a com­mand is re­quired, but noth­ing is de­sired. It was never meant to be read as oh, if I have an if-state­ment I should use null-com­mand”, it is in­tended to be read as oh, if I am in a con­text which re­quires a com­mand, I can use the null-com­mand to no-op it”.

Clever real-world us­age of : in the wild User if­philipe posted what fol­lows as a com­ment on news.ycombi­na­tor.com, which is the di­rect equiv­a­lent of need­ing a com­mand which does ab­solutely noth­ing.

I use the colon as EDITOR with Git when I want to do an in­ter­ac­tive re­base com­bined with auto squash with­out hav­ing to edit the todo list. I have an alias[1] for that which I call a quick in­ter­ac­tive re­base: riq = -c se­quence.ed­i­tor=: re­base –interactive

Could this ar­ti­cle have used the above rather than the so much de­bated if-state­ment? If I was clever enough to come up with it — yes.. but would it be as com­pre­hen­si­ble in terms of un­der­stand­ing what : re­ally is? I strongly sus­pect not.

Why would I do any of these when it hurts read­abil­ity?

There are a few com­mon mis­con­cep­tions about the — very con­trived — ex­am­ples pre­sented in this ar­ti­cle, ques­tions re­gard­ing their use­ful­ness, or if one should ever-ever use these things at all.

Let’s take the be­low as an ex­am­ple.

if some-com­mand; then : # com­mand re­quired else echo command failed” fi

Of course you can use if ! some-com­mand and get rid of the branch­ing, but that is­n’t the point of the snip­pet — the point is to show that the null-com­mand can be used in places where a com­mand is re­quired, but noth­ing is de­sired.

It was never meant to be read as oh, if I have an if-state­ment I should use null-com­mand”, it is in­tended to be read as oh, if I am in a con­text which re­quires a com­mand, I can use the null-com­mand to no-op it”.

Clever real-world us­age of : in the wild

User if­philipe posted what fol­lows as a com­ment on news.ycombi­na­tor.com, which is the di­rect equiv­a­lent of need­ing a com­mand which does ab­solutely noth­ing.

I use the colon as EDITOR with Git when I want to do an in­ter­ac­tive re­base com­bined with auto squash with­out hav­ing to edit the todo list. I have an alias[1] for that which I call a quick in­ter­ac­tive re­base: riq = -c se­quence.ed­i­tor=: re­base –interactive

I use the colon as EDITOR with Git when I want to do an in­ter­ac­tive re­base com­bined with auto squash with­out hav­ing to edit the todo list. I have an alias[1] for that which I call a quick in­ter­ac­tive re­base:

riq = -c se­quence.ed­i­tor=: re­base –interactive

Could this ar­ti­cle have used the above rather than the so much de­bated if-state­ment? If I was clever enough to come up with it — yes.. but would it be as com­pre­hen­si­ble in terms of un­der­stand­ing what : re­ally is? I strongly sus­pect not.

GrapheneOS protections against data extraction from locked devices

discuss.grapheneos.org

GrapheneOS Discussion Forum

htmx 4: the game

swag.htmx.org

$35.91

CAD

HTMX 4.0, the first JavaScript li­brary to re­lease ex­clu­sively on the Game Boy® plat­form!

Experience the power of HTMX, now on your fa­vorite portable hand­held.

Four lev­els of pickle-col­lect­ing ex­cite­ment.  Squish client-side JS down to size, avoid slop and, if you have the skills, de­feat Warren to un­lock the htmx 4.0 source code!

Be the hero that the web needs!

Quality is guar­an­teed. If there is a print er­ror or vis­i­ble qual­ity is­sue, we’ll re­place or re­fund it.

Because the prod­ucts are made to or­der, we do not ac­cept gen­eral re­turns or siz­ing-re­lated re­turns.

Ruff v0.16.0

astral.sh

Ruff v0.16.0 is avail­able now! Install it from PyPI, or with your pack­age man­ager of choice:

uv tool in­stall ruff@lat­est

As a re­minder: Ruff is an ex­tremely fast Python lin­ter and for­mat­ter, writ­ten in Rust. Ruff can be used to re­place Black, Flake8 (plus dozens of plu­g­ins), isort, py­doc­style, pyup­grade, and more, all while ex­e­cut­ing tens or hun­dreds of times faster than any in­di­vid­ual tool.

Migrating to v0.16 #

Ruff v0.16 has a small num­ber of break­ing changes, al­low­ing most users to up­date with­out sig­nif­i­cant changes to code or con­fig­u­ra­tion. The main ex­cep­tion is de­scribed be­low.

Better de­fault rule set #

Ruff now en­ables 413 rules by de­fault, up from 59 in pre­vi­ous ver­sions.

Since Ruff’s de­fault rule set was last mod­i­fied in v0.1.0, the num­ber of rules in Ruff has grown from 708 to 968. Many of these rules catch se­vere is­sues, in­clud­ing syn­tax er­rors and im­me­di­ate run­time er­rors but were not pre­vi­ously en­abled by de­fault. With the new rule set, Ruff will bring these is­sues and many oth­ers to your at­ten­tion with­out any Ruff con­fig­u­ra­tion. Even if you’re al­ready us­ing se­lect or ex­tend-se­lect, we hope that this will draw your at­ten­tion to help­ful rules that you pre­vi­ously had­n’t dis­cov­ered.

The full list­ing of en­abled rules is too long to in­clude here, but you can find it on our new Default Rules page in the doc­u­men­ta­tion. A few of the high­lights in­clude rules from the pop­u­lar flake8-bug­bear (B) and pyup­grade (UP) lin­ters, as well as rules from our own RUF cat­e­gory.

If you want to re­vert to the old de­fault set, you can eas­ily se­lect the old rules with this con­fig­u­ra­tion:

[lint] se­lect = [“E4, E7″, E9, F”]

We view this work as closely tied to our long­stand­ing goal of rule re­cat­e­go­riza­tion, so look for­ward to up­com­ing de­vel­op­ments in this area.

New fea­tures in v0.16 #

Ruff v0.16 also in­cludes sev­eral newly sta­bi­lized fea­tures that are high­lighted be­low.

Markdown code block for­mat­ting #

Ruff can now for­mat Python code blocks em­bed­ded in Markdown files.

In these files, Ruff v0.16 will for­mat fenced code blocks with a python, py, python3, py3, pyi, or py­con info string. pyi blocks are for­mat­ted like stub files, py­con blocks as REPL ses­sions, and the oth­ers use nor­mal Python file for­mat­ting. For ex­am­ple:

# README

Here’s an ex­am­ple:

```py im­port ruff

ruf­f_bi­nary = ( ruff.find­_ruf­f_bin() ) ```

will be re­for­mat­ted when run­ning ruff for­mat:

This can also be used to for­mat Quarto note­books be­cause Ruff still rec­og­nizes the lan­guage when sur­rounded by curly braces (e.g. ```{python}). Note that you may need to con­fig­ure your ex­ten­sion map­ping if your Quarto files use the .qmd ex­ten­sion.

If you need to sup­press for­mat­ting, you have sev­eral op­tions. If you want the sup­pres­sion com­ments to ap­pear in the code block, you can use nor­mal fmt: off and fmt: on com­ments within the code block it­self, or you can use sim­i­lar HTML com­ments to dis­able for­mat­ting for a whole re­gion of the doc­u­ment:

# README

<!– fmt: off –>

```py x = this will be sup­pressed” ```

<!– fmt: on –>

To sup­press Markdown for­mat­ting en­tirely, you can use the nor­mal ex­tend-ex­clude set­ting to ex­clude all Markdown files with a glob like *.md.

See the full doc­u­men­ta­tion for more de­tails.

ruff: ig­nore com­ments of­fer new sup­pres­sion fea­tures #

Ruff now has its own sup­pres­sion com­ment for­mat that can be used on its own line.

In v0.15, the Ruff lin­ter gained a range sup­pres­sion mech­a­nism through paired ruff: dis­able and ruff: en­able com­ments, much like the fmt: off and fmt: on pair de­scribed above:

# ruff: dis­able[N803] def foo( lega­c­yArg1, lega­c­yArg2, lega­c­yArg3, lega­c­yArg4, ): … # ruff: en­able[N803]

Ruff v0.16 builds on this to add two ad­di­tional ruff sup­pres­sion com­ments. ruff: ig­nore can be used to sup­press a di­ag­nos­tic on the same line, like noqa, or on the fol­low­ing log­i­cal line:

im­port math # ruff: ig­nore[F401]

# ruff: ig­nore[N803] def foo( lega­c­yArg1, lega­c­yArg2, lega­c­yArg3, lega­c­yArg4, ): …

In this case, the log­i­cal line spans the whole func­tion header (from def to the colon), so the ruff: ig­nore sup­presses all of the same N803 di­ag­nos­tics as the dis­able/​en­able pair above.

ruff: file-ig­nore com­ments can be used to sup­press di­ag­nos­tics for the en­tire file, just like ruff: noqa com­ments:

# ruff: file-ig­nore[F401] Allow un­used im­ports in this file

im­port foo im­port bar im­port baz

As this ex­am­ple also shows, each of these com­ment kinds can have an as­so­ci­ated reason” ex­plain­ing why they were added, in this case Allow un­used im­ports in this file.

ruff: ig­nore com­ments can be added au­to­mat­i­cally with the new –add-ignore CLI flag, and in pre­view, all of these ruff sup­pres­sion com­ments sup­port rule names in­stead of codes:

❯ echo import math’ > try.py ❯ uvx ruff@lat­est check –preview –add-ignore try.py Added 1 ig­nore com­ment. ❯ cat try.py im­port math # ruff: ig­nore[un­used-im­port]

You can find the full spec­i­fi­ca­tion for all of these com­ments in the doc­u­men­ta­tion.

Fixes are now shown in check and for­mat –check out­put #

Ruff now shows the diff for lin­ter and for­mat­ter fixes when ren­der­ing di­ag­nos­tics.

Both the check and for­mat sub­com­mands have long sup­ported the –diff flag for show­ing the changes in­tro­duced by ap­ply­ing fixes with check –fix or for­mat, but this was sep­a­rate from the nor­mal out­put and sup­pressed the ac­com­pa­ny­ing ex­plana­tory di­ag­nos­tics. In v0.16, avail­able fixes are now shown as part of the de­fault full out­put for­mat, ren­dered be­low the help sub­di­ag­nos­tic:

The same is true for for­mat –check. Given the fol­low­ing in­put:

# ex­am­ple.py

if True: pass elif False: pass

The for­mat­ter pro­duces:

for­mat –check also now sup­ports the full se­lec­tion of out­put for­mats sup­ported by the lin­ter. You can use this to ob­tain ma­chine-read­able JSON out­put or pro­duce the for­mats ex­pected by GitHub and GitLab to ren­der an­no­ta­tions in CI, as just a cou­ple of ex­am­ples. See the CLI help or doc­u­men­ta­tion for the full list of sup­ported for­mats.

One fi­nal note on out­put for­mats is that there is a small break­ing change to the JSON out­put in v0.16. The file­name, lo­ca­tion, end_lo­ca­tion, fix.ed­its[].lo­ca­tion, and fix.ed­its[].end_lo­ca­tion fields may now be null rather than de­fault­ing to the empty string and row 1, col­umn 1, re­spec­tively. This should af­fect very few of Ruff’s ex­ist­ing di­ag­nos­tics but bet­ter re­flects the in­ter­nal di­ag­nos­tic rep­re­sen­ta­tion and may be­come more com­mon in fu­ture rules.

Rule sta­bi­liza­tions #

The fol­low­ing rules have been sta­bi­lized and are no longer in pre­view:

air­flow3-in­com­pat­i­ble-func­tion-sig­na­ture (AIR303)

miss­ing-copy­right-no­tice (CPY001)

un­nec­es­sary-from-float (FURB164)

sorted-min-max (FURB192)

im­plicit-string-con­cate­na­tion-in-col­lec­tion-lit­eral (ISC004)

log-ex­cep­tion-out­side-ex­cept-han­dler (LOG004)

in­valid-bool-re­turn-type (PLE0304)

too-many-po­si­tional-ar­gu­ments (PLR0917)

stop-it­er­a­tion-re­turn (PLR1708)

none-not-at-end-of-union (RUF036)

ac­cess-an­no­ta­tions-from-class-dict (RUF063)

du­pli­cate-en­try-in-dun­der-all (RUF068)

Other be­hav­ior sta­bi­liza­tions #

This re­lease also sta­bi­lizes some ad­di­tional be­hav­ior, pre­vi­ously only avail­able in pre­view mode:

blind-ex­cept (BLE001) is now sup­pressed when the ex­cep­tion is logged via log­ging meth­ods other than crit­i­cal, er­ror and ex­cep­tion.

fu­ture-re­quired-type-an­no­ta­tion (FA102) now checks for ad­di­tional PEP 585-compatible APIs, such as those from col­lec­tions.abc.

f-string-in-get-text-func-call (INT001), for­mat-in-get-text-func-call (INT002), and printf-in-get-text-func-call (INT003) now check for ad­di­tional com­mon ways of us­ing the get­text mod­ule, such as as­sign­ing it to builtins._.

sus­pi­cious-url-open-us­age (S310) now re­solves lo­cal string lit­eral bind­ings to avoid more false pos­i­tives.

snmp-in­se­cure-ver­sion (S508) and snmp-weak-cryp­tog­ra­phy (S509) now sup­port the rec­om­mended API from newer ver­sions of PySNMP.

typ­ing-text-str-alias (UP019) now rec­og­nizes typ­ing_ex­ten­sions.Text in ad­di­tion to typ­ing.Text.

Thank you! #

Thank you to every­one who pro­vided feed­back re­gard­ing the changes in­cluded in Ruff’s pre­view mode and to our con­trib­u­tors. It’s an honor build­ing Ruff with you!

View the full changelog on GitHub.

Read more about Astral — the com­pany be­hind Ruff.

Thanks to Zanie Blue, David Peter, Micha Reiser, and Alex Waygood who con­tributed to this blog post.

wsj.com

www.wsj.com

Please en­able JS and dis­able any ad blocker

You can now park by robot at London Gatwick Airport

aerospaceglobalnews.com

London Gatwick has be­come the first UK air­port to in­tro­duce ro­botic park­ing, al­low­ing pas­sen­gers to leave their car in a pri­vate drop-off cabin. Autonomous ro­bots park it in a se­cure stor­age area and car own­ers don’t need to hand over their keys.

The new ser­vice, launched in part­ner­ship with Stanley Robotics, is now avail­able to book ahead of its first cus­tomer jour­neys in August. Eliminating the has­sle of search­ing for a park­ing space, the tech­nol­ogy gets pas­sen­gers from their car to the ter­mi­nal more quickly while mak­ing more ef­fi­cient use of air­port park­ing ca­pac­ity.

How Gatwick’s ro­botic park­ing works

Instead of dri­ving around a car park look­ing for an avail­able space, pas­sen­gers sim­ply drive into a pri­vate en­closed cabin near the South Terminal and scan their book­ing.

After park­ing the ve­hi­cle in­side the cabin, they leave the car and keep their keys. A Stanley Robotics au­tonomous park­ing ro­bot then slides un­der­neath the ve­hi­cle, lifts it by its tyres and trans­ports it to a se­cure stor­age area.

Passengers pro­vide their re­turn flight de­tails dur­ing the book­ing process, al­low­ing the sys­tem to mon­i­tor their ar­rival and have the ve­hi­cle wait­ing in a col­lec­tion cabin when they re­turn.

The fa­cil­ity is within walk­ing dis­tance of the South Terminal, al­though a free shut­tle bus is also avail­able.

No need to hand over your keys

Unlike tra­di­tional valet park­ing, pas­sen­gers re­tain pos­ses­sion of their keys through­out their trip.

According to London Gatwick, this of­fers ad­di­tional peace of mind while the au­to­mated sys­tem han­dles park­ing and re­trieval.

If pas­sen­gers ac­ci­den­tally leave an es­sen­tial item in the ve­hi­cle af­ter drop-off, on-site staff will be avail­able to re­trieve emer­gency items.

Helping air­ports use park­ing space more ef­fi­ciently

Robotic park­ing sys­tems are de­signed to im­prove the cus­tomer ex­pe­ri­ence while also max­imis­ing the num­ber of ve­hi­cles that can be stored within a given foot­print.

Because no one needs to ac­cess the ve­hi­cles once parked, cars can be po­si­tioned much closer to­gether than in a con­ven­tional car park. This helps air­ports in­crease park­ing ca­pac­ity with­out build­ing ad­di­tional park­ing in­fra­struc­ture.

Stanley Robotics has de­ployed sim­i­lar sys­tems in­ter­na­tion­ally. The Gatwick in­stal­la­tion is its first de­ploy­ment at a UK air­port.

Supporting Gatwick’s fu­ture growth

Oli Bedford, Head of Airport Access, Marketing and Commercial Products at London Gatwick, de­scribed the ser­vice as a real game-changer.”

It’s quick, easy and com­pletely has­sle-free — and you even get to keep your keys, giv­ing ex­tra peace of mind while you’re en­joy­ing your hol­i­day,” Bedford said.

Stanley Robotics CEO Clément Boussard said the tech­nol­ogy would help ad­dress fu­ture park­ing de­mand as the air­port con­tin­ues to grow.

We are thrilled to part­ner with London Gatwick, a global leader in avi­a­tion, to de­ploy our so­lu­tion and ad­dress their crit­i­cal park­ing ca­pac­ity chal­lenges as they pre­pare for sig­nif­i­cant growth,” Boussard said. This pro­ject marks a ma­jor mile­stone for Stanley Robotics in the UK, and we are proud to bring our in­no­v­a­tive tech­nol­ogy to one of the world’s most for­ward-think­ing air­ports.”

Gatwick ro­botic park­ing ve­hi­cle re­quire­ments

The ro­botic park­ing ser­vice at Gatwick is avail­able for most stan­dard pas­sen­ger cars, sub­ject to the fol­low­ing lim­its:

Maximum weight: 2.6 tonnes

Maximum height: 2.3 me­tres

Maximum wheel­base: 3.3 me­tres

Maximum wheel di­am­e­ter: 21 inches

The ser­vice must be booked in ad­vance. Same-day drive-up park­ing is not avail­able.

An ESP32 based plane radar

blog.ktz.me

This pro­ject made for a per­fect lazy Saturday un­wind, af­ter a busy week giv­ing a talk at Devrelcon in NYC. Makerworld had this thing as one of their fea­tured mod­els about a week or two ago, and the parts came in while I was away.

GitHub repos­i­tory ESP32-Plane-Radar Open-source ESP32 firmware for a 1.28″ round dis­play that shows live ADS-B air­craft around your lo­ca­tion as a sonar-style plane radar. by iron­icbad­ger · C++ · MIT

Plane radar is a neat lit­tle pro­ject that turns an ESP32-C3 and a 1.28-inch round dis­play into a live air­craft radar. It pulls nearby ADS-B traf­fic, plots each air­craft by dis­tance and bear­ing, and shows the de­tails di­rectly on the screen.

It was an easy build, al­though it did re­quire a lit­tle sol­der­ing. I al­ways en­joy do­ing that as it re­minds me of my days build­ing rac­ing drones. Thin, sil­i­cone based wires made quick work of the ca­bling. And af­ter about 15 min­utes, we were ready to go.

It is in­sanely easy to flash firmwares to a fresh es­p32 these days us­ing the browser-based ESPHome web flash­ing tool. Under 30s and you’re done.

A quick note about the 3d model

The orig­i­nal model was fea­tured on Makerworld, be­cause it looks great. Reality though was, in prac­tice, it’s not ac­tu­ally that great.

MakerWorld

5.4Klikes 3.3Kdownloads 15.1Ksaves 2.4Kmakes

Original 3D model ESP32 Plane Radar Live ADS-B on a Round Display by matixovi · Published May 31, 2026

Unfortunately the tol­er­ances are just too tight to be us­able with the batch of boards I got. So I’m likely go­ing to model my own re­place­ment at some point, but for now I ended up print­ing this model in­stead.

MakerWorld

154likes 195downloads 471saves 103makes

Original 3D model ESP32-S3 1.28″ Waveshare Plane Radar

by ThePrintableWatch · Published Jun 10, 2026

Customising the firmware

I’ve spent to­day im­prov­ing my fork of ESP32 Plane Radar pro­ject, with the help of pure vibes.

The biggest im­prove­ment is proper flight con­text. Where the data is avail­able, air­craft now show their ori­gin and des­ti­na­tion in­stead of just their tail num­ber, with the call­sign used as a fall­back. Aircraft types are also more de­scrip­tive, some­thing like B737 – 800 rather than sim­ply B737. I added lo­cal weather, tem­per­a­ture, hu­mid­ity, time and date as well.

The web in­ter­face can now mod­ify co­or­di­nates af­ter ini­tial setup. Display op­tions can now be changed with­out re­set­ting the Wi-Fi con­fig­u­ra­tion, and there are con­trols for units, run­ways, weather, tem­per­a­ture for­mat and 12/24-hour time. Text is 10% larger by de­fault, with a per­sis­tent 80 – 130% slider for ad­just­ing it.

Finally, the firmware now sup­ports au­then­ti­cated OTA up­dates, so fu­ture builds can be in­stalled through the browser in­stead of con­nect­ing the board over USB.

This is a bit like how ESPHome ap­plies firmware up­dates. Compile the bi­nary on your lo­cal lap­top and then up­load it to the ESP32 wire­lessly.

Next up might be port­ing it to a larger dis­play, and de­sign­ing a more for­giv­ing 3D printed en­clo­sure for it.

JetZero

www.jetzero.aero

Made up of lead­ers from aero­space, tech­nol­ogy, and mo­bil­ity from around the world. Half of the team is lo­cated at our Long Beach CA cam­pus, with other team­mates work­ing re­motely near our sup­pli­ers, fu­ture cus­tomers, and part­ners.

Ministry of National Defence

english.mapn.ro

No. 149 26.07.2026

Drone Shot Down by a Romanian Air Force F-16 Fighting Falcon Aircraft

On Sunday, July 26th, at 10:13, a Romanian Air Force F-16 air­craft shot down a drone that had en­tered the na­tional air­space with­out au­tho­riza­tion.

More

No. 148 25.07.2026

Second Drone Shot Down by a Romanian Air Force F-16 Fighting Falcon Aircraft

On Saturday, July 25th, at 08:22, the radar sur­veil­lance sys­tems of the Romanian Ministry of National Defence de­tected an­other unau­tho­rized pen­e­tra­tion of the na­tional air­space by a drone op­er­at­ing in the vicin­ity of the Ukrainian bor­der.

More

No. 147 24.07.2026

Drone Neutralized by Romanian Air Force Pilot in National Airspace

An F-16 fighter air­craft of the Romanian Air Force, as­signed to the 86th Air Base, Fetești, while con­duct­ing an air polic­ing mis­sion to mon­i­tor and track an un­manned aer­ial ve­hi­cle (UAV) that had vi­o­lated na­tional air­space, en­gaged the tar­get with an air-to-air mis­sile on Friday, July 24th and neu­tral­ized it over an un­pop­u­lated area in the vicin­ity of Padina, Buzău County.

More

To add this web app to your iOS home screen tap the share button and select "Add to the Home Screen".

10HN is also available as an iOS App

If you visit 10HN only rarely, check out the the best articles from the past week.

Visit pancik.com for more.