chrisys / train-departure-display Goto Github PK
View Code? Open in Web Editor NEWA replica, near real-time, miniature UK railway station train departure sign based upon a Raspberry Pi Zero and 256x64 SPI OLED display
A replica, near real-time, miniature UK railway station train departure sign based upon a Raspberry Pi Zero and 256x64 SPI OLED display
Odd one to track down the issue, but if I have the board (running locally) set to WBQ as the station, it can work fine for a while, but then the screen will go blank. It will appear to cycle through the start screen a couple of times and then remain blank.
Rebooting the Pi goes through the same cycle.
If I change the station to anything else, it seems fine.
Not sure where to look for logs to see why nothing is showing - any tips appreciated.
I have a flakey internet connection at the moment - when it's down I get an unhandled exception (see error.txt attached). Workaround is to specify Restart=always
in the systemd service but maybe there is a better way to handle
P.S. the project is awesome, thanks for porting to the free national rail API.
I tried to install the latest version which fixed the permissions issue by adding a CHMOD a+x. I got this file not found error. I went back to the old version and got the familiar permission error. I SSH to OS and found two instances of the file balena-run.sh. One in VAR and one in MNT. Once I manually CHMOD both files, I rebooted. Then, I started getting the "not found" error. Something about the CHMOD is breaking my container.
Installed everything as per the Belina import, changed the API code to my own and seem to hit an issue where the service constantly restarts after flashing up the UKTrainDepartureDisplay - Powered by National Rail Enquiries
Any ideas at all?
Here's a log which repeats in the log
Service exited 'main sha256:b7e488964f2c1fee59caa39981ce41314fa040bdfb029ec29813c7017e15ddae'
Restarting service 'main sha256:b7e488964f2c1fee59caa39981ce41314fa040bdfb029ec29813c7017e15ddae'
main Starting Train Departure Display v0.1.1
main Effective FPS: 0.0
main Traceback (most recent call last):
main File "src/main.py", line 336, in
main data = loadData(config["api"], config["journey"])
main File "src/main.py", line 159, in loadData
main journeyConfig, apiConfig["apiKey"])
main File "/src/trains.py", line 171, in loadDeparturesForStation
main Departures, departureStationName = ProcessDepartures(APIOut)
main File "/src/trains.py", line 33, in ProcessDepartures
main departureStationName = APIElements['soap:Envelope']['soap:Body']['GetDepBoardWithDetailsResponse']['GetStationBoardResult']['lt4:locationName']
main KeyError: 'soap:Envelope'
Service exited 'main sha256:b7e488964f2c1fee59caa39981ce41314fa040bdfb029ec29813c7017e15ddae'
Would it be possible to add environment variable so that only trains leaving from platform X are displayed? I noticed this info is available in the TransportAPI. If the string is null or * then all trains are displayed
Thanks
Tim
Looking in the dashboard, I see that my RPi Zero WH is constantly maxing out at 99-100% CPU and the effective FPS is anywhere from about 2.2 to 2.22 - consequently the refresh on the screen (when text scrolls) is very slow and jumpy rather than smooth as with the Pi3. I also notice that the clock at the bottom sometimes misses a second or catches up after a pause (especially at the time when scrolling begins on the 'calling at' stations).
It could well be that the Pi Zero WH is just not powerful enough for this, but wanted to raise it in case it's something else causing an issue with this device.
This is only for the Pi Zero WH - the Pi3 is fine.
Sorry I can't be a bit more specific here. I've just come back and noticed that the displays on both my Pis are blank - this seems to happen after a few days. Only a reboot brings them back on.
I've not updated the APIKey to the new format - but I think this was happening before that. I suspect they can't get a connection or something at some point and then just time out and never bother trying to connect again.
I'm running standalone, not in Balena Cloud.
Any initial thoughts?
Hi,
What do you think about the option to have multiple displays? The Pi could support this as it has 2 i2c busses (rm-hull/luma.core#55 (comment)).
My use case is that I have a 2 platform station and would like to have one display for platform 1 and one display for platform 2.
I found out that transport api is very unreliable, any chance of swapping to national rail api?
I have recently installed this, however I have noticed the clock does not smoothly "tick" sometimes dropping seconds. Is this a known issue? It seems everything is done in a single thread in the while True loop, wonder if this is causing the slow performance.
in config.py I see
data["journey"]['timeOffset'] = os.getenv("screenRotation") or "0"
I'm guessing the os.getenv should be for "timeOffset"
User GOTO GOTOSUB
in this comment asks for an alternative case design that would allow the unit to sit on a desk rather than hang from support as existing.
Attempting to run the python code on Raspian, I get
/home/pi/.local/lib/python3.7/site-packages/luma/core/interface/serial.py:185: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
self._gpio.setup(pin, self._gpio.OUT)
Traceback (most recent call last):
File "/home/pi/.local/lib/python3.7/site-packages/luma/core/interface/serial.py", line 280, in __init__
self._spi.open(port, device)
FileNotFoundError: [Errno 2] No such file or directory
During handling of the above exception, another exception occurred:
Traceback (most recent call last):
File "./src/main.py", line 256, in <module>
serial = spi()
File "/home/pi/.local/lib/python3.7/site-packages/luma/core/interface/serial.py", line 284, in __init__
raise luma.core.error.DeviceNotFoundError('SPI device not found')
luma.core.error.DeviceNotFoundError: SPI device not found
My python version is 3.7.3
Not sure where Im going wrong here.
At startup of the Train Departure Display service I get several warnings like listed below. Seems to spell doom on or after 2023/07.
Starting Train Departure Display v0.3.4
src/main.py:175: DeprecationWarning: textsize is deprecated and will be removed in Pillow 10 (2023-07-01). Use textbbox or textlength instead.
nameSize = draw.textsize("UK Train Departure Display", fontBold)
Would it be possible to add option via new variable and amendment in trains.py to allow the alternative web call?
London underground data calls require the Line name to be included in the call.
New variable: SERVICE_TYPE - value is text: null / blank / train / tube (I haven't looked at other networks)
New variable: SUB-TYPE - value is text: null / blank or text string [A-Z|a-z]*
URL - with null/blank entry in SERVICE_TYPE (presently in trains.py at line 22):
URL = f"http://transportapi.com/v3/uk/train/station/{departureStation}/live.json"
Non-null:
URL = f"http://transportapi.com/v3/uk/(service_type)/(sub_type)/(departureStation)/live.json"
e.g.
url = f"http://transportapi.com/v3/uk/tube/metropolitan/CLF/live.json"
url = f"http://transportapi.com/v3/uk/train/station/CFO/live.json"
of course these could be extended with another optional variable: PLATFORM - value null/blank or integer
if null / blank - url as above
not null/blank
URL = f"http://transportapi.com/v3/uk/(servicetype)/(line)/(departureStation)/(platform)/live.json"
Summary of suggested variables:
SERVICE_TYPE "train" for Netwok Rail or "tube" for London Underground
SUB_TYPE "station" for Network Rail or (underground line name) for London Underground
departureStation - no change
PLATFORM (optional)
I've had a few people contact me wondering if there are kits available, as well as people giving these as gifts to non-technical friends/family members for novelty and practical reasons.
I have been thinking of ways how to make this easier for people. Some things to investigate:
These are a bunch of ideas I've been thinking about to address the various pain points I've seen people encounter over the past couple of years. I'd like to continue developing the project and allow more people to build these displays, so if anyone has any input or if anything particular in the above list sounds good, let me know!
Currently the project does not build if you select the Pi Zero 2 (or other aarch64 device) as your default device type in balenaCloud.
The way to get it to work at the moment is to set the default device type for the balenaCloud application to the Zero 1 (as you would have done before), then add a Zero 2 to the Zero 1 application. This way the builders build for the 32 bit architecture of the Zero 1 but it still runs on the Zero 2 (64 bit) as it's backward compatible. I will look into the changes necessary to update the project to make it build for 64 bit architectures.
I would like to create my own train departure board using three 32 x 64 rgb led panels but i have no idea how to change the coding and i did not want to spend a fortune on the pre built ones as making it myself would be much more rewarding and cheaper!
Interesting idea from the forums - https://forums.balena.io/t/uk-train-times-enhancements/68093
Hi - one possible enhancement request would be to add train stopping times and last known location, such as:
Calling at: Wigan North Western (11:25), Preston (11:38), Lancaster (11:55) - Last reported passing Crewe Junction at 10:55
I think this information still comes from the National Rail API (Alternative) - like this one, for example:
https://departureboards.mobi/departures/WBQ
Howdy- I'm trying to get the screen to show the time 24/7. What I'm finding is that the variable(s) operatingHours, screenBlankHours, and/or outOfHoursName seem to be in effect even if deleted. I tried setting screenBlankHours to "0" and that didn't seem to make a difference. Is there some combination of these variable settings that will lead to the clock showing 24/7? Thanks, and fun thing to build. I had the same screen as you, and I might have used a lot of bad language moving that resistor. :)
Hey all, having got this working, I am now having an issue with a GPIO warning - Logs below if anyone knows how this can be resolved?
I am running on a Raspberry Pi3
main Starting Train Departure Display v0.1.1
main /usr/src/python-packages/luma/core/interface/serial.py:200: RuntimeWarning: This channel is already in use, continuing anyway. Use GPIO.setwarnings(False) to disable warnings.
main self._gpio.setup(pin, self._gpio.OUT)
I was sure there was an option for this once, but I can't see it in the variables now. Could you please add the option to be able to filter by only specific platforms - eg Platform 2. You can do this on multi-screen, but can't see a way on single screen.
Thanks.
Excellent project and thanks to those involved.
The transportapi accounts that are created now only get 30 days free now (but at a higher tier), so the ability to use a different api (such as network rail, realtime trains, etc.) would be welcomed and would help keep this running for those who started using the project after transportapi changed the free tier.
Thanks!
There is logic in the balena-run.sh file to decide whether to use an existing config.json
file or copy from config.sample.json
.
if [ ! -f config.json ]; then
cp config.sample.json config.json
...
Having seen that logic, I advised a user in a forum thread to create a config.json
as I thought it would be more convenient than setting the environment variables on the command line when pushing to a local-mode device:
balena push <ipAddress> --env var1=value1 --env var2=value2 ...
They tried it and it failed. On investigation, I found that there was a line for config.json
in the repo's .gitignore
file. The CLI (balena push
) currently considers both the .gitignore
and .dockerignore
files to decide what files to ignore (balena-io/balena-cli/issues/1032) when pushing to the cloud or to local devices, so the config.json
file was not being pushed. Deleting the line for config.json
in the .gitignore
file solved the issue.
(If it is a design decision that config.json
should not be pushed, then what would the use case be for the test in balena-run.sh
?)
You may want to add a note in the documentation that the API provider seems to have changed from TransportAPI to OpenLDBWS API. If you have a setup where you have a separate Application ID and Application Key - you need to register for the new API.
Had me scratching my head for a bit to work out why my setup had stopped working.
In order for users in future open fleets to know when the software has been updated.
I'm looking at you, refreshTime. If this is not set you might get an error like Error: Expecting value: line 1 column 1 (char 0)
.
Worked through the configuration - which is brilliant BTW, I've already got Chris Hutchinsons' version working. The balena console logs in balena cloud is constantly going round complaining about the 'departures' environment variable not being set. I've tried setting one and restarting the Pi and its still complaining.. Have set departures as an environment variable in the Application Environment variables and in Device Service variables - I know the hardware is good - all I've done is swapped the microSD and deployed the application and watched it deploy to the device.
I'm very impressed with my display which I built over the weekend, thanks to everyone who has contributed. Setting it up in Balena was fairly simple.
I unfortunately have very little experience with Python but was wondering if multiprocessing could help smooth the scrolling of "calling at:" if the clock and destination displays were in separate processes? The clock display could then also persist with only the destination display being refreshed for each update? I was also thinking about only updating information which has changed and a full display refresh when the destination stations change?
Paul
I received an error when using Balena desktop of:
Error: Please ensure the ‘departures’ environment variable is set
well there is no global variable called 'departures' cane you please rename to the actual variable required
15.08.19 16:29:10 (+0100) main /bin/sh: 1: ./balena-run.sh: Permission denied
15.08.19 16:29:13 (+0100) Killed service 'main sha256:1f47a99718ae0b9c019aa4787361e8e3e90a14ad2a8ddf89e906a9bd2ab9b4b7'
How do I give the script the right permissions to run?
At the point the refresh happens, the screen goes blank for about a second. Is it possible to retain the previously drawn screen whilst the refresh is happening, without going down the route of multi-threading etc?
Occasionally, on refresh, I see the "Powered by National Rail Enquiries" message, then a blank screen, then the display resumes. Here's an export from the log at the time that it happened:
03.11.21 22:27:18 (+0000) main Traceback (most recent call last):
03.11.21 22:27:18 (+0000) main File "src/main.py", line 336, in <module>
03.11.21 22:27:18 (+0000) main data = loadData(config["api"], config["journey"])
03.11.21 22:27:18 (+0000) main File "src/main.py", line 159, in loadData
03.11.21 22:27:18 (+0000) main journeyConfig, apiConfig["apiKey"])
03.11.21 22:27:18 (+0000) main File "/src/trains.py", line 171, in loadDeparturesForStation
03.11.21 22:27:18 (+0000) main Departures, departureStationName = ProcessDepartures(APIOut)
03.11.21 22:27:18 (+0000) main File "/src/trains.py", line 33, in ProcessDepartures
03.11.21 22:27:18 (+0000) main departureStationName = APIElements['soap:Envelope']['soap:Body']['GetDepBoardWithDetailsResponse']['GetStationBoardResult']['lt4:locationName']
03.11.21 22:27:18 (+0000) main KeyError: 'GetDepBoardWithDetailsResponse'
03.11.21 22:27:19 (+0000) Service exited 'main sha256_{removed in case this part is unique}_'
03.11.21 22:27:21 (+0000) Restarting service 'main sha256:_{removed in case this part is unique}_'
03.11.21 22:27:21 (+0000) main Starting Train Departure Display v0.1.1
03.11.21 22:27:26 (+0000) main Effective FPS: 0.0
03.11.21 22:29:47 (+0000) main Effective FPS: 18.61
03.11.21 22:32:07 (+0000) main Effective FPS: 18.63
Hey - I finally got round to building this and it's working great, so thanks very much for your work on this! I'm trying to change the timezone from the default which appears to be UTC. I've read around and it seems I should have a balena-timezone
program on my host OS, but I don't appear to:
I'm sure I must be missing something simple! Any idea how I can go about changing the timezone, thanks!
Great walk through and deployment info, struggling to set live and getting 'Error: Please ensure the 'departures' environment variable is set' message in Balena Log, just keeps looping round leading to no output to the oled screen.
Error code below:
main Error: Please ensure the 'departures' environment variable is set
(date time etc) Service exited 'main sha256:da3734455afb949d9d9a7535470d0377c7722abec1eac95a03929e7fd6fc9a2f'
When adding a variable "departurePlatform" to my fleet or individual device the display no longer shows information.
It is not possible to filter shown train services to only one, or more, platforms. Instead only all platforms at a station can be shown.
Hey Chris, hope you're keeping well chap.
I stumbled across your awesome Pi train departure board project after a random conversation with a mate over the weekend. It got me thinking that it would be very cool if I could, for his birthday, make him a nice display to go on the wall of his pub to display the train times (his pub is right next to our local station). However, to make this useful, it would need to have a much bigger screen attached to it (something like an 11.9" HDMI connected panel for instance). My fear here is that simply outputting the data to an "normal" screen would mean it would lose all of it's authenticity therefore, a larger matrix style screen would really make it pop!
I've seen (in the comments) someone else asking about this however, with my very limited knowledge, I'd have no chance of getting it working with a different type of display. To this end, I was just wondering if you were aware of anyone who may have already tackled this or, perhaps there's someone you know that could maybe take a look at it?
Kind regards,
Steve.
Not sure how easy or feasible this will be to achieve, but having got the dual screen setup working, I'm wondering if it'd be possible to have each screen showing a different station.
In order to do this, it would probably be best to have seaparate variables such as apiKey, so that a different APIKey can be used (if required) for each of the 2 stations.
Just a thought...
Just noticed this in config.py
data["journey"]['timeOffset'] = os.getenv("screenRotation") or "0"
It looks like timeOffset
will be equal to whatever you have your screen rotation set to (0 or in my case, 2).
Is this right?
Balena configuration tab does not include dual screen/destination station/ and more.
It would be nice to add information how to power the Pi Zero. The original article at https://www.balena.io/blog/build-a-raspberry-pi-powered-train-station-oled-sign-for-your-desk/ describes how to use a USB cable for powering the zero, but it overlooks the information as how to connect the power and ground pins to the Zero board. I found it here: https://thepihut.com/blogs/raspberry-pi-tutorials/how-do-i-power-my-raspberry-pi
Although there is a station operating hours variable, it would be good if there was an option to turn off the display completely between certain hours.
eg:
screenBlankHours 00-06
(Same format as the out of hours variable).
In readme.md, it says:
screenPlatform1 | 1 (sets the platform you want to have displayed on the first display)
screenPlatform2 | 2 (sets the platform you want to have displayed on the second display)
This should read screen1Platform
and screen2Platform
, as per the config.py
Is it possible to add an additional environment parameter to show the operator of a train service?
Not an issue, but an enhancement request...
I know you can have 1 station, 2 different platforms set up with dual screen, but would it be possible to set up dual screen on 1 Pi, so that you can show 2 different stations?
Hi,
I've been trying to deploy this app using balena to a Raspberry Pi 0 W, however there's either an issue with Balena to this app, as the Pi doesn't seem to boot and is not visible on the Balena dashboard.
Has anyone else experienced this issue?
Thanks.
A declarative, efficient, and flexible JavaScript library for building user interfaces.
🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.
TypeScript is a superset of JavaScript that compiles to clean JavaScript output.
An Open Source Machine Learning Framework for Everyone
The Web framework for perfectionists with deadlines.
A PHP framework for web artisans
Bring data to life with SVG, Canvas and HTML. 📊📈🎉
JavaScript (JS) is a lightweight interpreted programming language with first-class functions.
Some thing interesting about web. New door for the world.
A server is a program made to process requests and deliver data to clients.
Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.
Some thing interesting about visualization, use data art
Some thing interesting about game, make everyone happy.
We are working to build community through open source technology. NB: members must have two-factor auth.
Open source projects and samples from Microsoft.
Google ❤️ Open Source for everyone.
Alibaba Open Source for everyone
Data-Driven Documents codes.
China tencent open source team.