An idlying chromecast is a bad chromecast. Cast a dashboard instead.
Bricodash is an informational dashboard displayed on an overhead TV in the main work area and on a small monitor mounted by the coat-racks next to the machine shop.
The server back-end is housed on a black tower named bricolage—literally, "Something constructed using whatever was available at the time".
In October of 2017, Hack Manhattan installed a TV by the workspace tables. To make it easily accessible to everyone in the space, we added a Chromecast. To make that more useful, we're casting a "default" dashboard now. The same default dashboard is also displayed on a screen over the intercom at the entrance to our shop. This screen is driven by an old Raspberry Pi.
Bricodash represents a major revision to last year's defaultcast, originally developed by mz, providing more functionality while using a thin-client architecture.
If the early version Raspberry Pi we're using is low powered, the Chromecast is especially so. The goal has been to provide as much functionality as possible while keeping client load to a minimum. With this in mind, we rely heavily on a server-side cron hierarchy to update various HTML components, allowing the browser to poll for those files at appropriate intervals.
At last count, Bricodash incorporates eight (8) different APIs.
I'm an old-school programmer, and prefer to avoid bloat and wall-of-text source files, in favor of clean, single-purpose, Small-is-Beautiful modules that do what they do with minimal byte-tonage. That said, the source files hacked together to get the system off the ground are just that, hacks. They're ugly and experimental and will hurt the eyes and brains of anyone accustomed to the regimented, framework-heavy best practices of contemporary Web design. Hic sunt dracones.
This is not meant to be an example of professional, full-stack Web development. It is meant, instead, to demonstrate what can be accomplished when working without a net, allowing creativity and resourcefulness to drive the writing process, rather than convention and established practices. Moreover, that this system even uses a Web architecture is an artefact of the prototyping process. The ultimate intention—once all proposed features have been addressed—is to rewrite the entire system in Elixir to run as an embedded system on a single-board dongle that will drive its own display, rather that rely on Web protocols.
Each panel polls HTML files built periodically by back-end scripts on the bricodash server. Each file includes a timestamp tag indicating when the file was last generated by its respective script. If a script fails to complete successfully, the client will merely receive the last successfully written version when the file is next polled.
As part of the polling step, each panel checks the age of the HTML file received against its polling interval. When age exceeds polling interval by a small multiple, the file is deemed stale and a yellow warning icon () is displayed in the center of the panel. Intermittent appearances of yellow warning icons can indicate network issues or excessively short polling cycles. Persistent indicators are a sign that the relevant back-end script should be executed at the console to determine why it might be failing.
The community and building calendars are compiled via a two-stage process. For each calendar data source, there is a back-end script that polls that source at an interval appropriate to its API and/or volatility. The results of these polls are written to json files for later use. A separate, master script then collates the contents of these variously updated JSON files to produce consolidated HTML files for display on the dashboard.
The master script does not check for freshness of the intermediate JSON files. Rather, each successful run of the master script will show as having a fresh timestamp, regardless of the age of the source JSON files. No yellow warning icon will be shown if any of the data source scripts fail.
Instead, a failing source script will become apparent if either the calendar is seen to be listing events that have passed days prior and/or fails to show current event listings that one would expect from the source. In either case, an error condition can then be confirmed by checking the system timestamps on all intermediate calendar JSON files.
(It should be noted that there are some events, notably events that start at a specific time, that may continue to be listed on the day immediately following their start time. Usually these will be holidays on lunar or lunisolar calendars, astronomical events, or events that last beyond midnight. Such yesterday events do not represent errors or script failures, but rather are by design.)
The dashboard is comprised of five panels, or panes, and two overlays, described below starting clockwise from the top:
A cleaned up stream from our door camera graces the upper-right corner of the dashboard. The dashboard pulls an MJPG stream from a proxy gateway. Rather than relay the MJPG stream raw to our display devices, the gateway accepts sequential snapshot requests from the client devices, which are displayed by said client devices as a flipshow, allowing the chromecast and shoppi to control their own frame rates as a function of local load, rather than attempt to consume the firehose of a full mjpeg stream. This is done to avoid stalling out the Chromecast and Pi devices. Additionally, our script discards broken frames to reduce the number of grey-bottom artefacts appearing in the displayed feed.
NOTE: That all said, the current gateway architecture is to be replaced by BindSight—a dedicated MJPG consumer-broadcaster written in Elixir, now under development.
The upper-right corner of the feed, in turn, displays regularly updated weather information, including wind speed and "feels like" temperatures, when appropriate. A time clock, meanwhile, is superimposed over the lower-right corner of the camera feed.
The lower-right corner of the dashboard displays subway line status information, as provided by our local transit authority. The widget is a variation of that intermittently displayed on the digital information kiosks now becoming common in the city.
As provided, however, the transit authority's widget provides only for real-time status at time of page load. Thus, our back-end polls the widget, and caches the result for polled retrieval via a gateway script. This allows for any number of dashboard display devices to show minute-by-minute updates to subway status while keeping traffic to the information provider constant. Additionally, our back-end script strips live components unnecessary to a non-interactive display and munges colors in styles and images to conform to the rest of the dashboard.
That all said, the script providing this functionality is currently an imperative hack, and could do with some refactoring.
Future Ideas: The polling module is ripe for refactoring.
Centered on the bottom half of the dashboard are recent posts to the #hackerspace channel on Hack Manhattan's Slack. This panel does not attempt to emulate the content layout of a Slack client. Instead, various strategies are used to concisely and crisply represent the content of the channel while making optimal use of the limited screen real estate available.
Originally implemented via Slack's deprecated "Integration" mechanism, the back-end script for this panel has recently been migrated to a Slack's newer "App" model. The new model implements a finagley permissions system consisting of scopes and paired API keys (one for the app proper, one for a bot associated with the app), where certain methods available to one API context are not available to the other.
At this time, it appears that the migration was successful. But it is possible that certain obscure features not regularly used will, when introduced into the channel stream, result in a
HM Cloud Log
This panel provides a running log of recent changes to the Hack Manhattan community's online activities. This includes changes to pages on this mediawiki server and to event listings on our Meetup group, as well as a activity on Hack Manhattan's Github repository. In addition to listing recent activity for all projects under the the github.com/hackmanhattan, members may optionally register their own repository services accounts via Bricodash/Extra:Repos.
Meanwhile, a thumbnail gallery feature indicates whenever new images are uploaded to this mediawiki server or our Meetup group. (Integration of our Instragram and Twitter accounts is pending.)
The upper-left hand side of the dashboard alternates between a calendar showing events of interest to the Hack Manhattan community and a calendar showing events occurring within the Rat Park building.
Event listings are polled periodically from a number of different cloud services and data sources, each by way a source-specific script that extracts relevant event information then writes formatted and decorated output to an intermediary JSON file. A master script then regularly collates these files to generate three files, two HTML files for polling by the dashboard, and a third file formatted for posting to Slack.
The community calendar draws events from the following sources:
Without line wrapping, the calendar panel has room for listing seven (7) upcoming events on the main screen. The smaller screen by the shop can display eight (8) lines of events, but as lines are shorter, lines wrap more often. To privilege events happening at Hack Manhattan's space, the number of non-space events are capped at four (4). Within this constrained line count, more trivial sources are further filtered to only appear on the day of or immediately before, to avoid (somewhat) crowding out of more salient upcoming events like national holidays.
Although relevant to our community, the Rat Park calendar is not of primary interest. For this reason, the Building Calendar is displayed only one out of every five minutes, just long enough to get a general glance of events happening in the building.
The event calendar draws events from the following sources:
Events hosted by Secret Loft and Offside Tavern more often than not involve loud music, and in the case of some Secret Loft events, heavy use of the hallway leading to our space. The listings for these events are formatted and decorated to indicate the possibility of noise. In addition, Eventbrite's API license requires that event listings obtained from their service include a link to their event page on Eventbrite's site. As our dashboard is non-interactive, a URL shortener is used to provide a useable link as a superscript following each such listing.
Meanwhile, Offside Tavern often serves as a venue for various Meetup Groups, more often than not in some manner tech-related.
The remaining calendar is generated by combining all of the above sources, and stripping away much of the formatting and decoration used in the dashboard's HTML panels. Twice a day, the Bricodash bot posts all events from both of the above calendars due to occur in the next 72 hours to the channel
Also planned are Slack Events API bot functionality, such that the same calendar data can feed bah-style responses to user questions like "What's happening?"
Future Ideas: Slack Calendar Response Bot
The same feature that supports the dashboard door camera feed also allows for viewing Hack Manhattan's Space Cam. When viewed access the MJPG feed through the dashboard's bricolage gateway, an animated GIF of a disembodied eyeball appears as an overlay on the upper right corner of the Calendar panel.
Unlike the bo.x0.rs-hosted sousveillance system that inspired it, the Bricodash sous/veil system tracks both the connect and disconnect time of live streams. The eyeball animation appears and fades quickly for snapshots, appears and fades slowly for live streams while they are active, and then fades away more swiftly after a disconnect. Multiple simultaneous feeds have an additive effect, such that the eyeball will remain opaque longer and fade less rapidly, than for a single feed.
It should be noted that the Creepy Eyeball is only activated when our Space Cam is viewed via the Bricodash-bundled gateway. Snapshots and streams accessed via the bo.x0.rs gateway—such as link provided for viewing the Space Cam via VLC Media Player, or snapshots provided by the "Who's at the space?" trigger on our Slack—do not register as Creepy Eyeball activity.
At random intervals, a photo overlay will fade-zoom out from the center-left of the dashboard, remain briefly, and then fade--zoom back toward the center and disappear.
Due to limited screen real-estate, there is no ready way to share photos related to our space on the dashboard. This may change once an door buzzer IR remote solution is implemented. Until then, the Weird Photos mechanism is a compromise solution. Photos are displayed long enough to grab attention, but not so long as to obscure calendar or slack panel content for a prolonged period. Further, photos, when they do fade-zoom into view, are offset to the left to avoid obscuring the Door Cam feed.
Presently, photos are only drawn from the 100 most recently posted images on our Meetup group. (Instagram integration is pending.)
One of our members was conducting a year-long project involving representing holidays and notable events with tableaus involving rubber chickens and rubber ducks—often blue screened into appropriate settings. Many of these photos were posted to the albums for then-upcoming Open House events on the Meetup Group, hence the prevalence of rubber fowl in many of the photos that fade-zoom into and out of view on our dashboard.
Caveats and Policies
Performance and Maintenance
Long Overdue Calendarical Overhaul
Reverse Engineer FCNA/ECFR Calculations
See also: BindSight project page
Concurrent, extensible, frame-scrubbing webcam gateway.
Web API service to stream doorcam and spacecam to Bricodash and public gateway, respectively, while tracking activity and performance of these and other webcams at the space. Will be more efficient and reliable than spawning PHP and Python processes on an as-they-come basis.
Written in Elixir, will be taking advantage of various new features of the language, building on the strengths of Erlang/OTP, including
Standardize Web server setup and fully integrate BindSight.
Flesh out project documentation—after fixing existing problems with our Mediawiki server.
Incorporate remaining sources into rolling update log shown in lower left-hand corner.
Other Cloud Services
Retire IFFF Wiki Updates
Incorporate additional calculated and externally sourced calendar events.
Remaining features and code maintenance before calling it a major release.
Once built, streamline and rewrite as a truly beautiful application.