#!/usr/bin/env perl use strict; use warnings; use Carp; use Data::Dumper; # Command map (text to command number). This should be parsed from radioduino/globals.h, # but for now it's just hardcoded my %commandmap = ( WRITECONFIG => 2, READCONFIG => 3, RECONFIGURE_RADIO => 5, WRITEFRAM => 6, READFRAM => 7, PING => 9, WRITE_RTC => 16, READ_RTC => 17, STREAM_TELEMETRY => 19, READINPUTREGISTERS => 20, READHOLDINGREGISTERS => 22, WRITEHOLDINGREGISTERS => 24, READCOIL => 26, WRITECOIL => 28, READDISCRETE => 30, '32KHZ' => 50, SWITCHED_POWER => 52, DEEPSLEEP => 54, DEBUG => 60, ); # Open the file handles open(my $ifh, '<', 'crontab') or croak($!); open(my $ofh, '>', 'crontab.bin') or croak($!); binmode $ofh; # Format of the plaintext crontab #runonce hour minute second command offset values my $cnt = 0; while((my $line = <$ifh>)) { $cnt++; chomp $line; # Ignore comments next if($line =~ /^\#/); # Make sure there is only one space between columns $line =~ s/\ +/ /g; # Split elements and do some very basic validation my ($runonce, $hour, $minute, $second, $command, $offset, @values) = split/\ /, $line; if(!scalar @values) { croak("Line $cnt: has not enough values: $line\n"); } # Turn the given command NAME into the correct command NUMBER if(!defined($commandmap{$command})) { croak("Line $cnt: Unknown command $command\n"); } my $numcommand = $commandmap{$command}; # Internally in the Radioduino, the "runonce" flag also serves as "invalid record" flag, so turn the plaintext 0/1 boolean into the correct number my $mode = 0; if($runonce == 1) { $mode = 2; } else { $mode = 1; } # Bulk up @values to the correct length of 16 bytes while((scalar @values) < 16) { push @values, 0; } # Turn everything into binary my $event = ''; $event .= chr($mode); $event .= chr($hour); $event .= chr($minute); $event .= chr($second); $event .= chr(($offset >> 8) & 0xff); $event .= chr($offset & 0xff); $event .= chr($numcommand); $event .= chr(scalar @values); foreach my $val (@values) { $event .= chr($val); } # Write binary entry to file print $ofh $event; print $line, "\n"; } # Fill in empty records, so we overwrite any old entries with empty/invalid ones while($cnt < 86) { my $event = chr(0) x 24; print $ofh $event; $cnt++; } # Fill the remaining 8 bytes with zeroes as well for(1..8) { print $ofh chr(0); } # close filehandles close $ifh; close $ofh