Oxygen
The cargo hold door was open. That wasn't right, that door should always be closed. I went in, scared to death about Destiny, straight for the airlock.
The outside hatch of the airlock was open, which meant somebody was outside the boat. That relieved me a little, I'd worried one of the whores had thrown her out the airlock without a suit. But the open hatch said that thankfully hadn't happened.
It also said that I wasn't getting outside here. Thankfully there were three airlocks that doubled as boat docks. One was for the Captain's houseboat connected to the pilot's room, and the other two were at opposite ends of the ship. Sometimes dozens of ships coupled like this traveled together. It's supposed to be cheaper that way for big loads.
I flew as fast as I could to the other wing, put on a suit and went through the other docking airlock, closing it behind me.
The climb on the skyscraper-like boat was a lot easier without gravity. It was probably stupid of me but I was in a hurry to get to Destiny, who was probably dying by now so I didn't bother with tethers, I just moved as fast as I could. My God but this woman was my life! The thought of losing her... I climbed faster.
I kept trying to call her on the suit radio, knowing it was useless. Her radio probably wasn't even turned on or she would have tried to call me rather than following me out.
I finally made it around to the airlock she'd left open and saw her floating about six or so meters from the boat. I hooked two tethers to a rung next to the airlock and one to my suit and pushed off towards her. She wasn't moving and that worried the hell out of me, if she was conscious she'd be thrashing around in a panic. She was obviously out of air.
You would think climbing a tether without gravity pulling at you would be easy. You'd be wrong.
There's no gravity but there's still mass. There was the mass of two humans and two suits, which weren't all that light. I climbed the tether to the lock and pulled her in behind me.
Finally inside the airlock I shed my gloves and her helmet. She took a big gasp of air - she was alive! I got our suits off as the medical robot wheeled her away with an oxygen mask on her face.
I floated back to the pilot room to make the course correction. The ship's inspection would be a little late today.
I should have inspected the ship first.
For those of you new to my writing, I like to write while sitting in a bar stool and my favorite bar is a little redneck place in the ghetto. It's always full of interesting characters, most of whom I know well, and there are all kinds of folks. It's mostly construction workers but the crowd ranges the gamut from homeless crackheads to successful business people, from age 21 to quite elderly, from illiterate to college-educated.
Most of Nobots was written there. I left a signed copy in the bar for anyone to read with the admonition that it was not to leave the bar. Several folks wanted to read it, but not sitting in a bar stool. So I donated a second, unmarked copy for loaning out.
Heather, one of the patrons there, had been nagging me to loan her a copy and I kept forgetting to bring one. So I finally remembered, but she wasn't there so I loaned it to Art. Art is a bookworm, a little older than me who likes sitting in the beer garden with a book when the weather's nice. But it's a little dark inside for reading.
The next time I saw Heather she nagged again, and I told her I'd loaned it to Art. The next time I was in there, Art had left it with the bartender and Heather came up. "You got that book?" She demanded. "Ask Ruthie," I said. "It's behind the bar."
So yesterday a guy texted me (in code, of course) that he had some weed and did I want some? So I texted back "2@4" meaning two bags at four o'clock. I started the car about two or so; it was damned cold yesterday. It's been damned cold all winter. Yesterday it only got to 17F (minus eight point three in celcius). So I let the car warm up or I'd have hypothermia before I got there.
I walked inside from the parking lot and was snowblind when I went in. I couldn't tell who anybody was, just made out vague figures. A stool looked open, no drink in front of it so I sat down, still uable to see well. It was really bright outside and like I said, you'd have a hard time reading paper in there. Rachel, a co-owner, was tending bar and got be a beer. Damn it, their draft cooler had gone out a week ago so it was just bottles and cans, more expensive than draft.
My eyes finally dialated enough to see. There was a young guy I'd never seen before to my right, the woman to my left I could finally see was Jeri Lynn, and man was she loaded! I'd never seen her so messed up. Drunk as a skunk and sporting cocaine eyes. I think she was trying to seduce me, but she was way too loaded and I was way too sober; she's not bad looking but nobody looks good when they're shitfaced.
KY and a few other folks at one end of the bar waved. A woman I didn't recognize at first walked up - I dated her several years ago until I found out she was married to some rich guy, and there was no way I was going to put her kids through what my kids went through. Embarrisingly, I can't remember her name.
We chatted and reminisced about our short-lived romance. I mentioned that I almost didn't recognize her because she'd cut her hair short. She said "it went gray, too. That's why I cut it."
Damned if she wasn't hitting on me, too. Was I wearing a George Clooney mask or something?
She asked what I'd been doing, and I told her I'd written Nobots and had retired last week. She wanted to buy a copy, and I refused to sell her one. However, the loaner book was behind the bar so I got it from Rachel and told her it was a gift. She protested.
"Look," I said, "When we were dating you would never let me pay. You bought me beer, food, carriage rides, and this is just a little thank-you." She bought me a beer and I went back to my stool. Heather came up before I sat down. "I loved your book!" she exclaimed, and gave me a big hug. Man, the women must have all had some really thick beer goggles on.
Billy, sitting at the far end of the bar by the front door, motioned me over. "Hey, I got some hash if you want some." I declined, the price was ridiculously low so the quality surely would as well. And I had some coming around shift change when the bartenders would be too busy to notice.
Art was sitting next to him. "That book was sure different," he said, and grinned. To us like we are to australopithecus!" He stuck a folded up piece of paper in my pocket. I looked at it when I sat down - there was a small bud wrapped up in it.
My former girlfriend came over to say goodbyes and tried to give me her new phone number. She threw a twenty on the bar in front of me and hurried out. The guy I'd been waiting for finally showed up and slipped me a coupld of bags, and I slipped him a couple of twenties.
I went home in a very good mood. Some things are far better than money!
I typed that out a week or two ago and waited until I had what was written of Mars, Ho! posted. I'll probably write a new chapter of that in a day or two.
I ran across another snag with The Paxil Diaries this morning. I got the covers acceptable and went to upload it to Lulu, but I'd formatted it to A5 and they don't have that in hardcover, only American Standatd size (which I abbreviate as ASS) and an even more rediculously big book. The only books on my bookshelf that big and bigger are monsters like the entire Lord or the Rings trilogy.
And I'm very unsatisfied with their prices. I got a postcard, actual dead tree delivered by the USPS from a printer in St. Louis. Their prices were good but what the price listed was perfect bound softcover and I'd been looking for hardcover. So I stuck it in a fat science fiction anthology I've been reading that someone gave me.
So I was at Lulu's site getting ready to upload Paxil and damn, that sucks. Well, lets see, perfect bound?
Ridiculously expensive. So I'll reformat the damned thing to ASS and call the lady at mirabooksmart, the St Louis place, tomorrow.
No promises, but you may be able to get a soft cover Nobots for ten or fifteen bucks in a while, and maybe a really cheap pocket book most people read and pass along.
The next Mars, Ho! chapter has been making my brain itch, so like I said it will be soon.
Oh, BTW, this is another Soylent exclusive.
Meteors
The damned alarm woke me up. Damn them whores... but it wasn't whores, it was a meteor shower. Fuck. I went to the pilot room.
The meteors were tiny but when you're going fast, well, when a meteor shower is coming you want to slow down.
Or speed up. Usually it was slow down but not this time. I spoke into the fone. "Attention, passengers and cargo. Prepare for higher gravity in ten seconds." Ten seconds later I gradually added thrust. We were almost at Earth-normal now, and man it was not the least bit comfortable. I felt like I weighed a ton.
After these long interplanetary trips it was customary to spend a month or more in a gradually faster centrifuge until 1.3 normal. After a few days of this, Earth felt pretty good.
Right now it wasn't too comfortable, but we had to outrun those rocks. We'd be at .85G for the next hour. It looked like I was going to be up early today, I had inspection in two hours. I was glad we'd gone to bed early instead of drinking, this would have been hell with a hangover. I went to my quarters and made coffee, wishing again that robots could make decent coffee.
I flipped on the video and saw the last quarter of the zero-G football semifinals. That's one hell of a sport. Too bad Memphis lost.
I was wishing we were back to half gravity again, just sitting here was tiring. When the game was over I headed back to the pilot room.
I couldn't get in, over fifty angry whores were blocking the hallway. "You're all going to be confined if you don't let me through."
One of them laughed. "You and whose army? You think you can take us all on?"
I pulled out my taser. Most of them laughed. "Go inspect your boat, Joe." I don't know why the whores call me that, they know my name. The woman continued. "This full gravity is great, Joe, and we ain't givin' it up!"
"Look," I said, "this acceleration is going to need a course correction. I have to get in that pilot room!"
"Fuck off, Joe." Scattered giggling from the whores. I turned around and slunk off to the cargo area. I sure wasn't looking forward to this.
Damn but the cargo area was a lot longer off than at half G. I finally got there, suited up, and went through the airlock.
My God but I was scared. With the boat's acceleration it was like hanging from the side of a skyscraper. With weights on you. In a space suit with clumsy gloves.
I hooked the A tether to the highest rung I could reach and climbed. When the tether was below me I hooked the B tether above and unhooked the A tether.
I don't know how long it took me to get to the houseboat. I had to stop and rest a few times. I was sweating so hard I was afraid I'd drown in my suit.
I finally got there, went inside, and pressurized it. I took off the suit and went through the dock into the pilot room, pulling the suit in behind me. I was soaked in sweat, I wouldn't have been wetter if I'd been caught in a thunderstorm on Earth.
All my muscles ached, on fire. Them whores was going to be floating in a minute, I was really pissed off. I strapped into the pilot chair and killed the thrusters. The asteroid threat had long since passed and we'd been at high G way too long. Damn, our trajectory was way off.
Well, I'd fix that later. Right now I had a bunch of whores to lock up, and I wasn't about to be gentle. I was hurting like hell from the climb, I stunk, I was really pissed off at those damned whores and almost hoped they'd give me an excuse to tase them.
I was also looking forward to a shower. I was nasty.
I checked the monitor - they were all still outside the pilot room, floating, guarding it from me, ignorant of how the houseboat was docked to the ship. I wonder what went through their heads when we started floating?
I pulled out my taser and went outside. "All of you worthless bitches, hands behind your backs or God damn it I'm going to tase the shit out of you!"
This time they complied. It took half an hour to get them all cuffed and another half hour to get them to their rooms. I stopped by my quarters to make sure Destiny was OK.
She wasn't there. I knocked on Tammy's door. She opened it and said "You're probably looking for Destiny."
"Yeah, you seen her?"
"She was worried about you. She was heading toward the cargo bay right before we lost gravity."
Holy hell, I hoped she hadn't gone outside the boat to find me. If she did, she was probably dead, or would be soon.
I kicked off as hard as I could towards the cargo hold, flying as fast as I could.
This is a crude, rough draft of an upcoming book that is less than 10% finished.
This chapter is a Soylent's Fiction exclusive for a few days or so. It continues.
First off, a correction - in my last journal entry I said the Security Labs SLW-164 was around $220. I came across the invoice and it was $160.
So let's write some code!
I'll start with the TrendNet IP501P code. It's simpler than the iGuard because it uses basic authentication instead of cookies. The code to grab the pictures should do the following:
- Since it's not infrared, it should start requesting images about 45 minutes before sunrise and finish 2 hours after sunset (I came about these 2 time frames through much experimentation, YMMV).
- Each day's pictures should be stored in its own directory.
- Test the image request result and re-request it if it's not a jpeg.
- Add a timestamp to each image.
- While testing the code for a while, make it easy to log any issues with a debug hook.
Let's take a look at each chunk of code. The full script can be found here.
#!/usr/bin/perl -w
use strict;
use LWP::UserAgent;
use HTTP::Request;
use Date::Calc qw{ Today Today_and_Now Delta_YMDHMS Add_Delta_YMDHMS System_Clock };
use Astro::Sunrise;
use Image::Magick;
use Data::Dumper;
Pretty standard start to a perl script. Date::Calc is used to figure out the time and date for directory creation and also for the timestamp that's added to each image. In the case of a non-infrared camera, it'll also be used to determine if we're even going to request an image at all. Lastly, we'll use it to figure out if it's daylight saving time or not. Astro::Sunrise is used to calculate the sunrise and sunset times for my longitude and latitude. Image::Magick will annotate the timestamp to each image.
use constant DEBUG => 1;
use constant PAUSE => 10;
use constant BASE_DIR => '/home/fliptop/tv-ip501p/';
open LOG, '>>/tmp/grab_pic_tv-ip501p.log' or die "can't open log file: $!";
print LOG "\n------------------------------------------\n" if DEBUG;
printf LOG "Today is %s/%02d/%02d\n", Today if DEBUG;
print LOG "calculating 45 minutes before sunrise and 2 hours after sunset: " if DEBUG;
Pretty self explanatory, declare a few constants like the debug hook, how often we want to request an image, and where the images will be stored. Then we open the log file and give it some initial info.
my @time = System_Clock; # dst is last value in list
my ($sunrise, $sunset) = sunrise(Today, xx.xx, yy.yy, 5, $time[8]);
my ($srh, $srm) = split /:/, $sunrise;
my ($ssh, $ssm) = split /:/, $sunset;
my @sr_adjusted = Add_Delta_YMDHMS(Today, $srh, $srm, 0, 0, 0, 0, 0, -45, 0);
my @ss_adjusted = Add_Delta_YMDHMS(Today, $ssh, $ssm, 0, 0, 0, 0, 2, 00, 0);
printf LOG "%s:%s %s:%s\n", $sr_adjusted[3], $sr_adjusted[4], $ss_adjusted[3], $ss_adjusted[4] if DEBUG;
my @start_time = ($sr_adjusted[3], $sr_adjusted[4], '00');
my @end_time = ($ss_adjusted[3], $ss_adjusted[4], '00');
Here we figure out the start/end times for requesting images. sunrise is a method in Astro::Sunrise that returns a two scalar times for sunrise/sunset when you pass in the date, your longitude, latitude, timezone, and a DST flag (which we get from the System_Clock method in Date::Calc). Make sure you substitute your own longitude/latitude values for xx.xx and yy.yy. The start/end times we'll use are stored in @start_time and @end_time.
my $uri = 'http://username:password@192.168.1.246/IMAGE.JPG';
my $ua = LWP::UserAgent->new;
$ua->agent("Mozilla/5.0 (X11; U; Linux i686; en-US; rv:1.9.0.13) Gecko/2009080317 Fedora/3.0.13-1.fc10 Firefox/3.0.13");
Here we set up the URL we'll use to request images. Note that with basic authentication the login credentials are part of the URL.
my $im = Image::Magick->new();
for (0..86400/PAUSE) {
my @Today = Today;
my @Today_and_Now = Today_and_Now;
# create dir if it doesn't exist
my $dir = sprintf "%s%s/%02d/%02d", BASE_DIR, @Today;
unless (-e $dir) {
printf LOG "creating base directory %s\n", $dir if DEBUG;
my $resp = qx{ /bin/mkdir -p $dir };
if ($resp) {
printf LOG "unable to create image dir: %s\n", $resp;
die;
}
}
After instantiating an Image::Magick object ref, we'll execute the next set of code for every image request. In this case, it'll be 86,400 seconds per day divided by the number of seconds between each request. First is to make sure the directory we'll be storing the images in exists. If it doesn't, create it. If we can't create it, something is wrong and there's no point in continuing.
if ( &_take_pic(\@Today, \@Today_and_Now) ) {
my $not_jpeg = 1;
my $res = $ua->request(HTTP::Request->new(GET => $uri));
my $status = $res->status_line;
unless ($status eq '200 OK' || $status eq '302 Found') {
printf LOG "unable to request image, status code is: %s\n", $status if DEBUG;
}
&_take_pic is a method we'll show later that figures out if the current time is between the sunrise/sunset times we declared earlier. We set a $not_jpeg flag to TRUE so we can figure out (later) if we need to request the image again (I mentioned it before, the firmware on these cheap cameras if flaky and occasionally it doesn't return what you're looking for). Then we request the image, and if it doesn't return OK or FOUND we log the status code that is returned.
while ($not_jpeg) {
my $headers = $res->{_headers};
my $ct = $headers->{'content-type'};
At first, $not_jpeg is TRUE, so we'll look at the content-type of the request result.
if ($ct eq 'text/plain') {
print LOG 'text/plain (no image) result: ', Dumper($res), "\n" if DEBUG;
sleep 2;
# request it again
$res = $ua->request(HTTP::Request->new(GET => $uri));
$status = $res->status_line;
unless ($status eq '200 OK' || $status eq '302 Found') {
printf LOG "unable to request image, status code is: %s", $status, "\n" if DEBUG;
}
}
If the content-type is plain text, we didn't get the result we were looking for, so we sleep for a couple of seconds and request it again.
elsif ($ct eq 'image/jpeg') {
print LOG 'image/jpge found: ', $headers->{'client-date'}, "\n" if DEBUG;
$not_jpeg = 0;
}
If it returns a jpeg image, all is well, and we can exit the loop.
else {
print LOG "unknown content-type: ", $ct, "\n" if DEBUG;
sleep 2;
$res = $ua->request(HTTP::Request->new(GET => $uri));
$status = $res->status_line;
unless ($status eq '200 OK' || $status eq '302 Found') {
printf LOG "unable to request image, status code is: %s", $status, "\n" if DEBUG;
}
}
}
And just in case something else is returned (besides plain text or an image), sleep a couple of seconds and try again. Now that I'm looking at all this again, it would probably be easier/simpler to do some kind of recursive call to a method for requesting the image instead of the if-then-else approach. Maybe I'll look into that later...
my $content = $res->{_content};
my $filename = sprintf "%s/%s.jpg", $dir, time;
printf LOG "writing image %s\n", $filename if DEBUG;
open BIN, ">$filename" or die "can't open binary output file: $!";
binmode BIN;
print BIN $content;
close BIN;
The content should be a binary image file, so give it a unique filename and write it to disk.
my $x = $im->Read($filename);
print LOG "$x: $filename\n" if $x && DEBUG;
$x = $im->Annotate(
text => sprintf("%s/%02d/%02d %02d:%02d:%02d", @Today_and_Now),
font => '/usr/share/fonts/dejavu/DejaVuSans-ExtraLight.ttf',
pointsize => 12,
stroke => 'white',
undercolor => 'blue',
fill => 'red',
x => 510,
y => 465
);
print LOG "$x: $filename\n" if $x && DEBUG;
$x = $im->Write($filename);
print LOG "$x: $filename\n" if $x && DEBUG;
@{$im} = (); # clear the buffer
}
sleep PAUSE;
}
Now we use Image::Magick to annotate the timestamp. I found the red/white/blue combination to be the easiest to read. I configured my camera to return images that are 640x480, so I'm placing the timestamp in the lower right-hand corner (note that when working with Image::Magick (0,0) is the upper left-hand corner!). Then we pause and do it all again.
close LOG;
exit();
sub _take_pic {
my ($todayref, $today_and_nowref) = @_;
my @Today = @{ $todayref };
my @Today_and_Now = @{ $today_and_nowref };
my @after_start = Delta_YMDHMS(@Today, @start_time, @Today_and_Now);
my @before_end = Delta_YMDHMS(@Today_and_Now, @Today, @end_time);
# time is array elements 3, 4 and 5
return 0 if $after_start[3] < 0 || $after_start[4] < 0 || $after_start[5] < 0;
return 0 if $before_end[3] < 0 || $before_end[4] < 0 || $before_end[5] < 0;
return 1;
}
The _take_pic subroutine uses the Delta_YMDHMS method of Date::Calc to see if the current time falls between what we declared earlier as the start/end time based on our sunrise/sunset calculation.
Coming up next, cookie-based authentication.
Addiction
I woke up before her for once. I took a shit... hey, you wanted everything, right? Started the coffee because the robots really suck at making coffee, and got dressed. I was just taking my first sip when the doorbell rang. It was Tammy.
"Hi, uh Destiny invited me for coffee."
"Come in. She's still asleep, I'll get you a cup."
"Thanks."
"Uh," I said, handing her a cup, "Destiny says you're a psychologist and a, uh I forgot. You're not a whore, you're studying them.."
"Did destiny tell you that?"
"She didn't have to. I ain't went to college but I ain't stupid, I can add two and two and get something between three and five. It's obvious."
"Is it?"
"Yeah, I wondered how you got the money for a ticket, but shit, you got two doctorates. You ain't gotta look for work."
"Nope. Want to know about my studies?"
"Huh?"
"Jesus, you're a dumbass. I'm studying drug abuse and prostitution and you have two hundred drug addicted whores on board! Do you want an education, dumbass?"
I felt like a dumbass. "Yeah, I guess it might help."
"Here," she said, giving me a small memory chip.
"What's this?"
"Just read it. Don't worry, anything you don't understand I can explain."
Shit, I hate reading. That's one thing where me and Destiny are different, she loves reading. "Well, you had me fooled when I met you."
She laughed. "I study them, you don't know them at all. Don't let them know they're being studied or the study will be ruined."
"I'm discrete. Guess I have some studying to do."
"It'll save you a whole lot of trouble. I have some studying to do myself," Tammy said. "Tell Destiny to drop by when she wakes up. I'll be in the commons."
I put the chip in the tablet and started reading.
After reading for an hour and a half I had to put the tablet down. I was in trouble. No wonder they was paying me so good.
Most of these girls were abused and sexually molested as children, most of them raised in foster care. Many and maybe most were children of criminal parents; thieves, often very violent. They were the kids society allowed to be ruined for life.
It was sad. Most of them were droppers. There's a chemical name for drops in Tammy's book but I'd have to look it up.
These girls hated sex, having a normal sex life was ruined in their childhoods when they were molested and abused. But drops made the whores enjoy getting fucked. Most of them had never had an enjoyable sexual experience until they put a drop in an eye before work.
There were other psychoaffective (and yeah, I had to look that and lots of other shit up when I read that damned book) stuff. Her book had a lot of other big words like neurotransmitters and I just kind of glossed over them, I ain't went to college or nothing.
I gathered the whores just stayed really fucked up.
And the drug was highly addictive physically as well as in worse ways. It made the user the opposite of pissed off when under the influence. When that was taken away, well... it ain't pretty.
"Damn," I thought, "Addiction must be a bitch" as I got another cup of coffee.
It seemed I was in for serious trouble.
This is a crude, rough draft of an upcoming book that is less than 10% finished. This is the last of the chapters that were posted at slashdot, and in fact has a little added to the end.
I just "finished" tomorrow's chapter, which will be a Soylent's Fiction exclusive for a few days or so. Continues.
Barrabas and NCommander need to stop with the drama, I think. The continued posting of ever-longer emails and IRC logs doesn't seem to be serving the purpose of transparency anymore, and I think it's actually going to become counterproductive. The last thing you guys need to do right now is rile up the community or poison the environment. Take it offline, or just agree to end it.