Odd permissions issue on new Inky Impressions 7.3"

I created an issue on the github page about this issue, but I’ll repost it here, in case this gets more visibility:

I have two Impressions now, a 5.7" I’ve had for a while and a new 7.3" I’m setting up now. I’ve run into a weird issue that appears to be permissions-based, but somehow at the level of the screen itself. Both of my setups are running on Pi Zero Ws with Raspbian 11, and all of the latest packages installed.

On my 5.7", when running ‘identify.py’ I get:

$ ./identify.py 
Found: 7-Colour (UC8159)
Display: 600x447
Color: None
PCB Variant: 1.2
Display Variant: 14
Time: b'2022-09-29 10:58:30.9'

And on my 7.3" I get:

$ ./identify.py 
Found: None
Display: 800x480
Color: None
PCB Variant: 1.0
Display Variant: 20
Time: b'2023-08-21 08:48:46.6'

Except, if I run it as root, I get:

$ sudo ./identify.py
Found: 7-Colour 800x480 (AC073TC1A)
Display: 800x480
Color: None
PCB Variant: 1.0
Display Variant: 20
Time: b'2023-08-21 08:48:46.6'

Similarly, none of the other examples will run unless I run them as root:

$ ./name-badge.py --name Test
Inky pHAT/wHAT: Hello... my name is:

Use Inky pHAT/wHAT as a personalised name badge!


Detected None
Failed to detect an Inky board. Trying --type/--colour arguments instead...

usage: name-badge.py [-h] [--simulate] --type {what,phat,phatssd1608,impressions,7colour,whatssd1683} [--colour {red,black,yellow}]
name-badge.py: error: the following arguments are required: --type/-t

And specifying the type as shown does not resolve the issue.:

$ ./name-badge.py --type 7colour --name Test
Inky pHAT/wHAT: Hello... my name is:

Use Inky pHAT/wHAT as a personalised name badge!


Detected None
Failed to detect an Inky board. Trying --type/--colour arguments instead...

/home/sal/.local/lib/python3.9/site-packages/inky/inky_uc8159.py:302: UserWarning: Busy Wait: Held high. Waiting for 32.00s
  warnings.warn("Busy Wait: Held high. Waiting for {:0.2f}s".format(timeout))
/home/sal/.local/lib/python3.9/site-packages/inky/inky_uc8159.py:302: UserWarning: Busy Wait: Held high. Waiting for 0.20s
  warnings.warn("Busy Wait: Held high. Waiting for {:0.2f}s".format(timeout))

To eliminate variables, I tried to swap the sdcards from the two installs, to see if it was the setup itself, but the 5.7" install had the same issue running with the 7.3" screen, and the 7 install had no issues working with the 5 screen.
I then swapped the entire Pi Zero from the known working setup onto the new screen and it still had the same issue.

Seeing as the only variable is the screen itself, I’m thinking that there’s something different there, either hardware or firmware-wise. I also have the busy/wait issue #1876581066 and don’t have that on the other Impressions, so perhaps it’s related.

The 7color/image.py script does work fine when running as root, which is what I’m using the screen for, so I’m not dead in the water, but I figured A: If someone else has this issue, they can refer to this, and B: Help fix the issue.

If I’m following your ‘swap’ tests correctly, (the “issue” card has the same trouble with both screens?), that would indeed tend to indicate a setup issue.

I’m wondering if you have a old local (user-level) package that you pick up when running as your regular user, while running as root via sudo you pick up a globally installed (slightly more up to date?) package?

No, sorry, I guess I didn’t make it clear enough. It’s other way around.

Regardless of which setup I use, the issue follows the screen.
5Zero/5setup/5screen works fine
5Zero/7setup/5screen works fine
5Zero/5setup/7screen has this issue.
5zero/7setup/7screen has this issue
7Zero/7Setup/7screen has this issue.
7zero/5setup/7screen has this issue.
7zero/7setup/5screen works fine.
7zero/5setup/5screen works fine.

My guess is there’s either a firmware or hardware issue with the screen. I’m hoping it’s firmware and I can just update something and it’ll work fine.

Ahh, ok I’m with you now (I think!)

I don’t see how it can be screen-related, because the screen won’t have any idea what permissions you have reading the EEPROM - and it clearly is reading the EEPROM and getting stuff like the display variant, but not decoding it right.

Still feels like a library version thing; what version do you have installed in /home/sal/.local/lib/python3.9/site-packages/inky/ (should be set in __init__.py)?

I agree… doesn’t make a ton of sense, but I’ve eliminated all of the Pi and install variables. The screen’s the only thing left.

The software is all the latest version, as I just installed it all this weekend, and it’s the same version that’s on my 5 install:
version = ‘1.4.0’

The screen does work, apparently, at least for drawing a picture to it, but only if I run it as root, which makes little sense as the 5 install doesn’t require root when attached to the 5 screen, but does when attached to the 7 screen… So it can’t be a permissions issue on the install, unless the 7 interacts with the code differently.

There’s definitely something different between the two screens, besides the obvious resolutions differences. The questions is what.

If you are brave, you could run strace -o trace.log ./identify.py. This will give you tons of output. But if this is a permission issue, you will find somewhere in your trace a line with EPERM or EACCESS.

None of that, but I did get “Inappropriate ioctl for device” towards the bottom.

I can’t attach a log, but here’s the last bunch of lines:

lstat64("/home/sal/.local", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib/python3.9", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib/python3.9/site-packages", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib/python3.9/site-packages/inky", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/local/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.cpython-39-arm-linux-gnueabihf.so", 0xbeba2bf8) = -1 ENOENT (No such file or directory)
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.abi3.so", 0xbeba2bf8) = -1 ENOENT (No such file or directory)
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.so", 0xbeba2bf8) = -1 ENOENT (No such file or directory)
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.py", {st_mode=S_IFREG|0644, st_size=796, ...}) = 0
lstat64("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib/python3.9", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib/python3.9/dist-packages/inky", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/python3/dist-packages", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat64("/usr/lib/python3/dist-packages", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat64("/usr/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/Pimoroni/inky/examples", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/python3.9", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat64("/usr/lib/python3.9/lib-dynload", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.cpython-39-arm-linux-gnueabihf.so", 0xbeba32e0) = -1 ENOENT (No such file or directory)
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.abi3.so", 0xbeba32e0) = -1 ENOENT (No such file or directory)
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.so", 0xbeba32e0) = -1 ENOENT (No such file or directory)
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.py", {st_mode=S_IFREG|0644, st_size=1314, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.py", {st_mode=S_IFREG|0644, st_size=1314, ...}) = 0
openat(AT_FDCWD, "/home/sal/.local/lib/python3.9/site-packages/smbus2/__pycache__/__init__.cpython-39.pyc", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=346, ...}) = 0
ioctl(3, TCGETS, 0xbeba3698)            = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR)            = 0
_llseek(3, 0, [0], SEEK_CUR)            = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=346, ...}) = 0
read(3, "a\r\r\n\0\0\0\0\316\232Uc\"\5\0\0\343\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 347) = 346
read(3, "", 1)                          = 0
close(3)                                = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
openat(AT_FDCWD, "/home/sal/.local/lib/python3.9/site-packages/smbus2", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
fstat64(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getdents64(3, 0xf1c060 /* 7 entries */, 32768) = 208
getdents64(3, 0xf1c060 /* 0 entries */, 32768) = 0
close(3)                                = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/smbus2.py", {st_mode=S_IFREG|0644, st_size=21157, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/smbus2.py", {st_mode=S_IFREG|0644, st_size=21157, ...}) = 0
openat(AT_FDCWD, "/home/sal/.local/lib/python3.9/site-packages/smbus2/__pycache__/smbus2.cpython-39.pyc", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=18469, ...}) = 0
ioctl(3, TCGETS, 0xbeba2dc0)            = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR)            = 0
_llseek(3, 0, [0], SEEK_CUR)            = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=18469, ...}) = 0
read(3, "a\r\r\n\0\0\0\0\316\232Uc\245R\0\0\343\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 18470) = 18469
read(3, "", 1)                          = 0
close(3)                                = 0
openat(AT_FDCWD, "/dev/i2c-1", O_RDWR|O_LARGEFILE|O_CLOEXEC) = 3
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x5, 0), 0xbeba3824) = 0
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x3, 0), 0x50) = 0
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x20, 0), 0xbeba3aec) = 0
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x20, 0), 0xbeba3aec) = 0
write(1, "Found: None\n", 12)           = 12
write(1, "Display: 800x480\nColor: None\nPCB"..., 96) = 96
write(1, "\n", 1)                       = 1
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6cb7900}, {sa_handler=0x21c584, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6cb7900}, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Apparently, that’s not unusual. The same command on the 5, which does correctly identify the 5 display, gives the same errors… so that’s not it.
(this is from the 5 install with the 5 screen attached)

lstat64("/home/sal/.local/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib/python3.9", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib/python3.9/site-packages", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
lstat64("/home/sal/.local/lib/python3.9/site-packages/inky", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/local/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.cpython-39-arm-linux-gnueabihf.so", 0xbef64c18) = -1 ENOENT (No such file or directory)
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.abi3.so", 0xbef64c18) = -1 ENOENT (No such file or directory)
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.so", 0xbef64c18) = -1 ENOENT (No such file or directory)
stat64("/usr/local/lib/python3.9/dist-packages/inky/__init__.py", {st_mode=S_IFREG|0644, st_size=796, ...}) = 0
lstat64("/usr", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib/python3.9", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
lstat64("/usr/local/lib/python3.9/dist-packages/inky", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/python3/dist-packages", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat64("/usr/lib/python3/dist-packages", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat64("/usr/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/python3.9/dist-packages", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/Pimoroni/inky/examples", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/usr/lib/python3.9", {st_mode=S_IFDIR|0755, st_size=12288, ...}) = 0
stat64("/usr/lib/python3.9/lib-dynload", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages", {st_mode=S_IFDIR|0700, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.cpython-39-arm-linux-gnueabihf.so", 0xbef65300) = -1 ENOENT (No such file or directory)
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.abi3.so", 0xbef65300) = -1 ENOENT (No such file or directory)
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.so", 0xbef65300) = -1 ENOENT (No such file or directory)
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.py", {st_mode=S_IFREG|0644, st_size=1314, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/__init__.py", {st_mode=S_IFREG|0644, st_size=1314, ...}) = 0
openat(AT_FDCWD, "/home/sal/.local/lib/python3.9/site-packages/smbus2/__pycache__/__init__.cpython-39.pyc", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=346, ...}) = 0
ioctl(3, TCGETS, 0xbef656b8)            = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR)            = 0
_llseek(3, 0, [0], SEEK_CUR)            = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=346, ...}) = 0
read(3, "a\r\r\n\0\0\0\0\316\232Uc\"\5\0\0\343\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 347) = 346
read(3, "", 1)                          = 0
close(3)                                = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2", {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
openat(AT_FDCWD, "/home/sal/.local/lib/python3.9/site-packages/smbus2", O_RDONLY|O_NONBLOCK|O_LARGEFILE|O_CLOEXEC|O_DIRECTORY) = 3
fstat64(3, {st_mode=S_IFDIR|0755, st_size=4096, ...}) = 0
getdents64(3, 0x1f1df28 /* 7 entries */, 32768) = 208
getdents64(3, 0x1f1df28 /* 0 entries */, 32768) = 0
close(3)                                = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/smbus2.py", {st_mode=S_IFREG|0644, st_size=21157, ...}) = 0
stat64("/home/sal/.local/lib/python3.9/site-packages/smbus2/smbus2.py", {st_mode=S_IFREG|0644, st_size=21157, ...}) = 0
openat(AT_FDCWD, "/home/sal/.local/lib/python3.9/site-packages/smbus2/__pycache__/smbus2.cpython-39.pyc", O_RDONLY|O_LARGEFILE|O_CLOEXEC) = 3
fstat64(3, {st_mode=S_IFREG|0644, st_size=18469, ...}) = 0
ioctl(3, TCGETS, 0xbef64de0)            = -1 ENOTTY (Inappropriate ioctl for device)
_llseek(3, 0, [0], SEEK_CUR)            = 0
_llseek(3, 0, [0], SEEK_CUR)            = 0
fstat64(3, {st_mode=S_IFREG|0644, st_size=18469, ...}) = 0
read(3, "a\r\r\n\0\0\0\0\316\232Uc\245R\0\0\343\0\0\0\0\0\0\0\0\0\0\0\0\0\0\0"..., 18470) = 18469
read(3, "", 1)                          = 0
close(3)                                = 0
openat(AT_FDCWD, "/dev/i2c-1", O_RDWR|O_LARGEFILE|O_CLOEXEC) = 3
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x5, 0), 0xbef65844) = 0
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x3, 0), 0x50) = 0
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x20, 0), 0xbef65b0c) = 0
ioctl(3, _IOC(_IOC_NONE, 0x7, 0x20, 0), 0xbef65b0c) = 0
write(1, "Found: 7-Colour (UC8159)\n", 25) = 25
write(1, "Display: 600x447\nColor: None\nPCB"..., 96) = 96
write(1, "\n", 1)                       = 1
rt_sigaction(SIGINT, {sa_handler=SIG_DFL, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6c85900}, {sa_handler=0x21c584, sa_mask=[], sa_flags=SA_RESTORER, sa_restorer=0xb6c85900}, 8) = 0
exit_group(0)                           = ?
+++ exited with 0 +++

Both those traces mention a globally installed version of inky, in /usr/local/lib/python3.9/dist-packages/inky/; if I was a betting man I’d say that is probably a different version to your other one, and one of them understands the 7" frame less (because it’s a newer product?)

Annoyingly, it looks like the version number wasn’t bumped by the patch that added 7" support, but you could check auto.py in both copies, and see if either include “impressions73” in the DISPLAY_TYPES list (line 11), which would appear to be a quick and dirty check.

Thing is: It works when I run under sudo and correctly identifies the display, so it can’t be the version… can it? I just pulled the files from the repo this weekend… can’t imaging it’s a version issue given that.

In any case, it does indeed have the current impressions listed:

        else:
            if args.type == "phat":
                return InkyPHAT(args.colour)
            if args.type == "phatssd1608":
                return InkyPHAT_SSD1608(args.colour)
            if args.type == "what":
                return InkyWHAT(args.colour)
            if args.type == "whatssd1683":
                return InkyWHAT_SSD1683(colour=args.colour)
            if args.type in ("impressions", "7colour"):
                return InkyUC8159()
            if args.type == "impressions73":
                return InkyAC073TC1A()

Next thing to try is to strace with root and compare. The strace tells you all the files it opens. Usually, the environment of root is different than the environment from a normal user, so it might pick up something different somewhere. This need not be one of the Pimoroni libs.

I mean, IT is not magic. You get different results with different users, and we can safely assume the programs work deterministically. So if it is not permissions, what else could it be? I’m in line with @ahnlak here: I would also bet that root is running different code since we ruled out permissions.

Great work! That was it!

Checking a diff of the two running, and filtering out all the different hex numbers that were cluttering things up, it was obvious that running it as a user used the ~/.local/lib/python3.9 (out of date) instead of the system libraries, which were up to date.

Moving the local python install out of the way caused it to use the system’s install and now it’s working fine!

I checked the 5 and had out of date user packages, too, but they both had up to date system packages.

Thanks for all of your help!

1 Like

Great news! Can you update your Github issue with this too, in case someone comes across that and doesn’t track back to this thread? Ta!

Good point. Will do!