|
Re-released v0.1.8-sdr with bugfixes
|
|
|
|
|
Re-released v0.1.8-sdr with CTCSS scan+lock, interactive controls
|
|
|
|
|
Re-released v0.1.8-sdr with CTCSS Tone Squelch too.
|
|
|
|
https://github.com/TheButterZone/MacIntercomScanned latest [v0.1.8-sdr]: Unzipped binary https://www.virustotal.com/gui/file/d4a9c04351dd8574782dd3de32bb317df95e9e51b36b37271f1765549fed23a2?nocache=1Features:- Bidirectional computer ↔ Bluetooth audio routing - Automatic hardware format detection - Integrated Bluetooth microphone support - USB & analog microphone support - Media-aware operation (enabled by default) - Optional standalone always-on intercom mode - Optional Software-Defined Radio (SDR) dual-method squelch mode with smart passive CTCSS tone scanner for on-the-fly frequency identification & switching - Test tone diagnostics - Low-latency, high-quality streaming audio pipeline - Integrated AGC and WebRTC Voice Activity Detection (VAD) * WebRTC VAD enabled by default for intelligent voice-gating * Replaces legacy envelope follower (toggleable via `DebugFlags`) to significantly reduce false triggers from room noise * Lightweight, zero external dependency footprint Modes:* Media-Aware Mode (Default): Run ./macintercom. The intercom automatically yields to media playback, pausing/resuming media when toggled. * Standalone Mode: Run ./macintercom --s. The intercom ignores media playback and stays active continuously until closed with Ctrl-C. * SDR Squelch Mode: Run ./macintercom --sdr. Mutes the Bluetooth microphone return path for SDR inputs (e.g., routed via Soundflower), supporting two squelch methods: * WebRTC VAD & Passive Scanner (Default): Automatically detects human voice activity in the noise floor to open the gate. While running, a passive, zero-latency scanner continuously evaluates the audio and prints detected sub-audible CTCSS tones to the terminal. Interactive Hotkey: Pressing Return instantly locks your squelch to the last detected tone (disabling VAD). Pressing Return again while a new tone is detected hot-swaps the lock to the new tone. Pressing Esc releases the lock entirely. Mac Menu Bar: Click ⩛ when it appears while MacIntercom is running, then lock & unlock squelch. * CTCSS Tone Squelch: Pass -tone <frequency> (e.g., ./macintercom --sdr -tone 100.0) to disable VAD and the scanner, and enforce strict, non-interactive tone squelch startup parameters. * Test Tone Mode: Run ./macintercom --t. Simultaneously plays a 220 Hz tone through the computer output and a 440 Hz tone through the Bluetooth speaker. This has been type II fun 
|
|
|
|
Kicked into gear again with Mandacaru 14.0's release enabling my real tests! I LOLed when I saw the 14.1 release GitHub email notification just before my debug app picked it up too. Another checkpoint debug apk after hours of rinse & repeat, now: - Download flow works via Android Download Manager in background/notifications drawer (watch progress or cancel) & is reflected by progress bar in Mandacaru itself. - Install intent works. - FileProvider works. - APK reaches Package Installer. - Remaining conflict was expected because debug and release signing keys differ. - Duplicate -1.apk, -2.apk, etc. is prevented during normal use (not edge cases): you press the download button once, it completes, an install button will appear immediately and after app relaunches. Without a download button to download again, no duplicate can be generated in-app. You only proceed to install or you don't. Edge cases, I say? Removed automatic recovery of APKs left in Downloads after app storage reset. These files may remain visible to the user but are no longer safely owned by Mandacaru, and Android does not provide a reliable way to reclaim externally stored APKs without an active DownloadManager/content URI grant. Documented this as an unsupported recovery case: users can manually install a remaining APK from Downloads. A future PR may add a user-assisted "Open Downloads" flow, allowing Mandacaru to detect a newer installer APK and guide the user to complete installation manually. ktfmt- the Kotlin code formatter helped save some more recent test builds from failing. Wish I had looked it up dozens sooner LOL... welcome to Type 2 Fun!
|
|
|
|
|
And of course GitHub goes down after I approve the first legit member in a while.
Not only that, it wasn't deploying the page via GitHub Actions anymore, so I've added that to the process-submission workflow & hopefully refactored it so the actions-bot doesn't comment that it was changed until the page deployment is successful.
|
|
|
|
|
Sad, now there is an equal number of people who have tried to sign up with invalid Freecycle usernames as valid ones. The auto username validator works!
The latest invalid just deleted out their issue, but I see the original before edit!
|
|
|
|
Dang, I just asked & 9/10 states don't mandate minimum per-pound rates for all recycling centers, really? That might kill this idea, even if I think about switching the program to counts only (who's going to count hundreds of containers unless they know they'll get paid as much as possible for them?) In CA I'm able to calculate a threshold for each container capacity (5 or 10 cent tier) weight to determine if I'll make more redeeming by count or by weight. eg. any <24 fl oz PET #1 container would be 5 cents by count, but if it's a Crystal Geyser water bottle, those weigh less than 0.6 oz/0.0375 lbs empty, so it doesn't make any sense to get less money from the recycling center weighing them than you'd get by count. But if it's a <24 fl oz Gatorade or Snapple drink bottle, they're probably all well-over 0.6 oz, so you get more back weighing them than you paid. Building this tool requires navigating an important quirk of U.S. recycling laws: California is the only bottle-bill state that officially legally mandates and publishes payout rates calculated by the pound.The other nine bottle-bill states (CT, HI, IA, ME, MA, MI, NY, OR, VT) legally define their minimum redemption strictly by the individual container count (usually $0.05 or $0.10 per bottle/can). When recycling centers in those states weigh materials, they use their own private, internally estimated "average container-per-pound" conversion multipliers to guess the count, or they require people to hand-count them.To make your script work seamlessly across all 10 states, your data script will need to hardcode a fallback mathematical model for the other 9 states using industry-standard conversion averages. ... // Internal data matrix updated with state-regulated minimums and mathematical averages const stateRatesPerPound = { CA: { name: "California", aluminum: 1.66, glass: 0.101, plastic_pet: 1.46 }, // Legally fixed by CalRecycle OR: { name: "Oregon", aluminum: 3.11, glass: 0.20, plastic_pet: 2.45 }, // $0.10 rate conversion MI: { name: "Michigan", aluminum: 3.11, glass: 0.20, plastic_pet: 2.45 }, // $0.10 rate conversion CT: { name: "Connecticut", aluminum: 3.11, glass: 0.20, plastic_pet: 2.45 },// $0.10 rate conversion NY: { name: "New York", aluminum: 1.55, glass: 0.10, plastic_pet: 1.22 }, // $0.05 rate conversion HI: { name: "Hawaii", aluminum: 1.55, glass: 0.10, plastic_pet: 1.22 }, // $0.05 rate conversion IA: { name: "Iowa", aluminum: 1.55, glass: 0.10, plastic_pet: 1.22 }, // $0.05 rate conversion MA: { name: "Massachusetts", aluminum: 1.55, glass: 0.10, plastic_pet: 1.22 },// $0.05 rate conversion VT: { name: "Vermont", aluminum: 1.55, glass: 0.10, plastic_pet: 1.22 }, // $0.05 rate conversion ME: { name: "Maine", aluminum: 1.55, glass: 0.10, plastic_pet: 1.22 } // Base $0.05 (Note: Maine liquor is $0.15, but mostly sorted manually by count) };
/** * Calculates the total value based on user inputs * @param {string} stateCode - Two letter state code (e.g. 'CA') * @param {Array} materialsInput - Array of objects containing { type: 'aluminum', weight: 10.5 } * @returns {Object} Breakdown of individual costs and the final total sum */ function calculateRedemptionTotal(stateCode, materialsInput) { const selectedState = stateRatesPerPound[stateCode.toUpperCase()]; if (!selectedState) { return { error: "State not supported or does not have a deposit law." }; }
let grandTotal = 0; const breakdown = [];
materialsInput.forEach(item => { const materialType = item.type.toLowerCase(); const weight = parseFloat(item.weight) || 0; // Pull the rate per pound from our state data matrix const ratePerPound = selectedState[materialType];
if (ratePerPound && weight > 0) { const itemSubtotal = weight * ratePerPound; grandTotal += itemSubtotal; breakdown.push({ material: materialType, weight: weight, rateApplied: ratePerPound, subtotal: parseFloat(itemSubtotal.toFixed(2)) }); } });
return { state: selectedState.name, lineItems: breakdown, totalPayout: parseFloat(grandTotal.toFixed(2)) // Round cleanly to normal currency format }; }
// --- Example Frontend Usage Simulation --- const userState = "CA"; const userMaterials = [ { type: "aluminum", weight: 12.5 }, { type: "plastic_pet", weight: 5.2 } ];
console.log(calculateRedemptionTotal(userState, userMaterials));
Figured I might as well throw the JS in here so the compute wasn't wasted.
|
|
|
|
What I've been doing is pinning posts that I GPG-clearsigned with my Bitcoin-OTC WoT key, containing the same address I put on BTC2Free, on my Nostr (npub19ctmsmtf9jtehddhctwmnacwqtnkh0p43tafttrgzdgy0wlppcpq50zf83), eg. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 #BTC2Free As numbers increase/decrease, this offer may be superseded by a newer post on Nostr - my deletion requests are often disregarded by relays. Send https://preev.com/btc/usd?usd=83.80 to bitcoin:bc1q4xs2vezxa946gcxrmptfe8hquu99wmp8uanst0& I'll give away * 96 gallon capacity Toter wheelie bin Cracked near the wheel so slightly that I missed it the first few times I looked for damage; but in better condition than most used bins I've seen. Also, has address painted on the side. * ~22.45 lbs of bagged CRV (PET #1) inside the Toter Bin. Those PET #1 CRV containers are in plastic bags, which is why that weight is approximate. * 9.0125 lbs of bagged PET #1 outside the bin (contained elsewhere) that won't fit. These bags' weight excluded. * $7.75 worth (by count) of mixed material CRV containers * 1 dime, 2 pennies to a random on Freecycle San Diego (currently 10,985 members). bitcoin-otc.com/viewratingdetail.php?nick=TheButterZone -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEwKYvetXBb7daFKINdQpmQMXklhsFAmp39u0ACgkQdQpmQMXk lhvoSQ//aSh6Q640vLauP5S/rPI2CcgXNBxfKz05fDMWxZN0ufC33kjqCHAlG2n3 SzmcZJmY+12t7voZ3mWjtJkVEfzCtcvg1KvzOFovy1lPK62j84iuYBntPt4Db2zA RvW7WVhk4KReZauZ73ZQocbrK9evKsSe2eR9a7v6WPjND+YHiYz4E6AVVKZ14hym IrH6K4/ZkYiRUuWoRtP5zKo+u6xLGoTTXY4sL4AwhDCpCEsKZIdj2pfBH43aiMl/ 1uJ20cL6d9mlwJnsF3G6n3fWC8baeX8dzxbyPxKTBgOUcHLYxCprYIIYil1JBnwn Z1S+xKmfQBfH4O8fepo7O/BZBohzbbzP28mfgi7Cl1ZwyGUDj/F255YNNHvss3IJ GIdJe6WgWW+GAH/j31wDB+3tIsfbTgm9L4J/7lWUWfdVvzUXwzXOuoj0vSRO85jh /ClrAhvbk0PkX/YO0SV7drcikFb9gftBtdPGkjsvPlsn+XU1ZkA6VYsLN2kKy1+Y grht1GUO+F5MuzZ3ynHg1e4Yg+f2Yn0+vWp8gjRjGRU5yjWfG5mYuXO5jdMjOt44 BV4iwqAukW4GHK9LdN3WFvxC0IeBL/BI/mWy7uY3/VorOAvv1doxCgONCeZwA8Bl vygXFMiMyJoArwHAJiUJEcLWpSiIf/fINfEYOglJ/wWntYvn5t4= =Ldvv -----END PGP SIGNATURE----- So that's a specific commitment to [receive specified amount to their BTC2Free profile address]->[post exact offer on Freecycle] that anyone can make anywhere they can post ads, then if they're successful, comment the proof of giveaway on their BTC2Free issue.
|
|
|
|
Forgot to mention, I spun off into a more general project along these lines, that was easier to vibe code (especially since bottle deposit states don't all have APIs for GitHub Actions to grab their current per-pound rates): BTC2Free People donate Bitcoin. Participants offer items on Freecycle in return.
Also, what I've been doing is pinning posts that I GPG-clearsigned with my Bitcoin-OTC WoT key, containing the same address I put on BTC2Free, on my Nostr (npub19ctmsmtf9jtehddhctwmnacwqtnkh0p43tafttrgzdgy0wlppcpq50zf83), eg. -----BEGIN PGP SIGNED MESSAGE----- Hash: SHA256 #BTC2Free As numbers increase/decrease, this offer may be superseded by a newer post on Nostr - my deletion requests are often disregarded by relays. Send https://preev.com/btc/usd?usd=83.80 to bitcoin:bc1q4xs2vezxa946gcxrmptfe8hquu99wmp8uanst0& I'll give away * 96 gallon capacity Toter wheelie bin Cracked near the wheel so slightly that I missed it the first few times I looked for damage; but in better condition than most used bins I've seen. Also, has address painted on the side. * ~22.45 lbs of bagged CRV (PET #1) inside the Toter Bin. Those PET #1 CRV containers are in plastic bags, which is why that weight is approximate. * 9.0125 lbs of bagged PET #1 outside the bin (contained elsewhere) that won't fit. These bags' weight excluded. * $7.75 worth (by count) of mixed material CRV containers * 1 dime, 2 pennies to a random on Freecycle San Diego (currently 10,985 members). bitcoin-otc.com/viewratingdetail.php?nick=TheButterZone -----BEGIN PGP SIGNATURE----- iQIzBAEBCAAdFiEEwKYvetXBb7daFKINdQpmQMXklhsFAmp39u0ACgkQdQpmQMXk lhvoSQ//aSh6Q640vLauP5S/rPI2CcgXNBxfKz05fDMWxZN0ufC33kjqCHAlG2n3 SzmcZJmY+12t7voZ3mWjtJkVEfzCtcvg1KvzOFovy1lPK62j84iuYBntPt4Db2zA RvW7WVhk4KReZauZ73ZQocbrK9evKsSe2eR9a7v6WPjND+YHiYz4E6AVVKZ14hym IrH6K4/ZkYiRUuWoRtP5zKo+u6xLGoTTXY4sL4AwhDCpCEsKZIdj2pfBH43aiMl/ 1uJ20cL6d9mlwJnsF3G6n3fWC8baeX8dzxbyPxKTBgOUcHLYxCprYIIYil1JBnwn Z1S+xKmfQBfH4O8fepo7O/BZBohzbbzP28mfgi7Cl1ZwyGUDj/F255YNNHvss3IJ GIdJe6WgWW+GAH/j31wDB+3tIsfbTgm9L4J/7lWUWfdVvzUXwzXOuoj0vSRO85jh /ClrAhvbk0PkX/YO0SV7drcikFb9gftBtdPGkjsvPlsn+XU1ZkA6VYsLN2kKy1+Y grht1GUO+F5MuzZ3ynHg1e4Yg+f2Yn0+vWp8gjRjGRU5yjWfG5mYuXO5jdMjOt44 BV4iwqAukW4GHK9LdN3WFvxC0IeBL/BI/mWy7uY3/VorOAvv1doxCgONCeZwA8Bl vygXFMiMyJoArwHAJiUJEcLWpSiIf/fINfEYOglJ/wWntYvn5t4= =Ldvv -----END PGP SIGNATURE----- So that's a specific commitment to [receive specified amount to their BTC2Free profile address]->[post exact offer on Freecycle] that anyone can make anywhere they can post ads, then if they're successful, comment the proof of giveaway on their BTC2Free issue.
|
|
|
|
Update: One of the members had a TX but the state machine didn't update/leave a comment on their issue, so added... - Permission for issues: write
- Corrected bot email format
- Debugging inside findIssueForUser()
- Retries for GitHub comment failures (exponential backoff)
- Persistent failure queue JSON
- Automatic retry of queued notifications every run
- No state advancement unless comment succeeds
- Prevention for silent loss of notifications
ETA: Aw crap it was a spend not a receive, so hopefully fixed here.ETA2: They got an incoming & the notification fired, now to see if a spend ever again fires a notification, regardless of coding against that.
|
|
|
|
My roommate found a Logitech M525 mouse, that presumably a scavenger took out of a bin & forgot to pick up off the ground (since it wasn't cracked like it had been tossed out of a bin). It was a bit gunky, so I cleaned it up. 2 Amazon AA alkalines inside that hadn't leaked yet, tested them: 80% capacity. Probably didn't have a receiver next to it on the ground, or my roommate just didn't see it (figures, they thought it was like-new despite the gunk I saw). But I did have a Logi Nano receiver, that I think I found in a giveaway box years ago, saved in case I ever found a Logi wireless mouse to pair with it. Now, the M525 is a Unifying mouse, so it would not natively work with the Nano receiver - yet in Logitech Control Center, the M525 showed up as a M310 (IIRC) while the battery level wouldn't display & movement/clicks weren't detected. But... After many more-complicated-than-they-needed-to-be iterations with Gemini pushing Solaar, ltunify, a nonexistent GitHub repo "hidpp-pair", and logi_tool, finally concluded with "pure Apple C code" (after a bunch of iterations just by itself): https://github.com/TheButterZone/logi-nano-pairAnd now, the found Unifying M525 mouse works with the found non-Unifying Nano receiver. Just no customization of all 5 "buttons"; will have to use Mac Mouse Fix for that.
|
|
|
|
As I slept, the phone rebooted for whatever reason & grayed out Mandacaru, Electrum, and BlueWallet (all on adopted storage).
Maybe it performed a system update during that time? But something terrible happened during the auto-update. You can check your phone's settings for signs of update, it usually shows if the system is updated in " System->Software update" settings. Jun 27 was last successful check for update, with Android (12) security update: Mar 5, 2025
|
|
|
|
Best of luck with the initiative!
This is the first time I hear about Freecycle to be honest. I thought it must be a US or UK-only type of service, but it isn't. There are many locations all over Europe as well. Almost nothing in Russia, though. Same thing in Africa and South America. There is no town in Croatia either. The closest ones to me are Sarajevo in Bosnia and Belgrade in Serbia.
Thanks. It's funny, sometimes you'll see the island countries (countries that are islands or have islands vs landlocked with not even an island in a lake) have Freecycle Towns, but Tenerife has 2 on 1 island, while none of the other Canaries have any. I only looked there closely because of bitcoinkook on Nostr, who's been cleaning up trash on Fuerteventura as #SatsForTrash & partly inspired BTC2Free. And today's update is... another person tried to register with a nonexistent username  , so I added a script that validates the initial submission & any edits until they actually put in one that exists!  I'd just been looking up their profile, but I'd rather be seeing that they're already a member of at least one town, versus only registered on the site - and also if their GitHub & Freecycle profiles bear any resemblance. Things you can only check if you're logged in to Freecycle, which you/bots don't need to be, just to see if the username exists.
|
|
|
|
As I slept, the phone rebooted for whatever reason & grayed out Mandacaru, Electrum, and BlueWallet (all on adopted storage). Previously I was able to restore them to running again by rebooting, but no amount of rebooting worked. Some of my internal storage apps broke too (at least until I pulled the card out, then they worked again). I dumped bugreport, no bueno: 06-27 21:59:07.337 root 493 493 E vold : Failed to mount /dev/block/dm-11: I/O error 06-27 21:59:07.337 root 493 493 E vold : private:179,34 failed to mount: I/O error Put the card in my computer & reformatted it for portable storage, then popped it back in the phone & another portable storage reformat by Android itself. But until https://github.com/jvsena42/mandacaru/issues/53 gets resolved the Floresta way, or Mandacaru has the ability added to run on internal storage but store its data on the portable storage, I think I probably shouldn't run Mandacaru anymore. Not sure how close to death the card is at this point, or what would really destroy it - it originally came in the CanaKit RPi 3B+. I don't have any other cards to burn. P.S. This is a non-rooted phone & for personal reasons, I shouldn't root it even though I want to.
|
|
|
|
|