tag:blogger.com,1999:blog-58694354965387711322024-03-13T22:11:30.051+13:00jasonrumney.netrandom thoughts at random intervalsJason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.comBlogger53125tag:blogger.com,1999:blog-5869435496538771132.post-14470173510199549082020-02-23T16:24:00.000+13:002020-05-27T16:32:04.011+12:00Kogan Smart Plugs<h2>
The Physical Device</h2>
These are piggyback plugs with a toggle button, on-off LED (ring around the button) and status LED. They plug into a wall, with the device you want to control plugged into the back, which can be switched on and off by the button, or you can use the smartphone app.<br />
<br />
<h2>
The Smarts</h2>
The Wi-Fi module for this device comes from <a href="https://www.blogger.com/2020/02/tuya-smart-devices.html">Tuya</a>, along with the app and server infrastructure. In addition to off/on functionality, the app also provides you with power consumption information, and timer and more complex programming capabilities. The smart automation gives you access to data from other Tuya based devices you own, Weather, Sunset/Sunrise, Location, so fairly complex automation is possible. Location is from the smartphone, which could be useful to turn things on when you are arriving home, and off when you are leaving, provided you live alone. Anyone with a family or flatmates though probably needs a presence detection that covers multiple people, which this does not provide. The app also interfaces with Alexa and Google Home, as well as IFTTT, to provide access to basic functionality and automation scenes.<br />
<br />
<h2>
The Details</h2>
To free yourself from the Tuya ecosystem, you first need to know more details about how the device is wired internally. This applies whether you are using something like <a href="https://github.com/codetheweb/tuyapi">tuyapi</a> to control the device without changing the firmware, or reflashing alternate firmware like <a href="https://github.com/arendst/Tasmota">Tasmota</a> or <a href="https://esphome.io/">ESPHome</a>.<br />
<br />
<a name='more'></a><br />
<h3>
Tuya Protocol</h3>
To control the device locally with libraries such as tuyapi, you need to know how the different features map to "dps" (data point state).<br />
<br />
These are the dps that are reported at startup (based on eavesdropping the protocol before encryption starts):<br />
<br />
<b>dps 1</b> this is the power status. You can write true to turn the switch on, false to turn it off. Reading it will report the current status, including when it has been changed by the button on the plug.<br />
<br />
<b>dps 2</b> this I suspect has something to do with timers, and if so, it should be read/write.<br />
<b>Edit</b>: confirmed that this is the timeout in seconds until the state is toggled.<br />
if set to 10 when the switch is on, it will turn off after 10 seconds.<br />
if set to 10 when the switch is off, it will turn on after 10 seconds.<br />
I haven't confirmed the upper limit, but the Tuya app lets you set up to 24 hours.<br />
<br />
The following are readonly<br />
<b>dps 4 </b>this is the instantaneous current in milliamps.<br />
<b>dps 5 </b>this is the instantaneous power in tenths of a watt.<br />
<b>dps 6 </b>this is the voltage in tenths of vol<br />
<br />
This seems to be a common assignment for other brands as well, so this device is likely based on an off the shelf whitelabel product, or reference design from Tuya.<br />
<br />
<h3>
Hardware Connections</h3>
To use alternate firmware, the Tuya protocol is not so much of interest, instead you need to know what is connected where on the ESP8266 module.<br />
<br />
The Tuya <a href="https://docs.tuya.com/docDetail?code=K8uhkbb1ihp8u">TYWE3S</a> module is connected to a HLW8012 power monitoring IC and general I/O for button, LED and relay as follows on these devices:<br />
<br />
GPIO 0: Toggle Button<br />
GPIO 4: HLW8012 CF<br />
GPIO 5: HLW8012 CF1<br />
GPIO 12: HLW8012 SELi<br />
GPIO 13: Status LED (inverted)<br />
GPIO 14: Relay<br />
<br />
The LED ring around the button seems to be connected to the relay, and cannot be controlled independently.<br />
<br />
Here is an ESPHome configuration for use with Home Assistant that gives you almost the same functionality as the original product without any need for a cloud service. The button toggles the relay directly, so can operate offline. The one missing feature is that timers are not implemented inside the device itself with this configuration. Since ESPHome hardcodes the Wi-Fi configuration, rather than using the status LED to indicate Wi-Fi connection state, I modified it to indicate whether any power has been drawn since it was turned on.<br />
<br />
<pre style="background-color: #f3f3f3;">esphome:
name: kogan_socket_1
platform: ESP8266
board: esp01_1m
wifi:
ssid: "<i>ACCESSPOINT</i>"
password: "<i>PASSWORD</i>"
# Enable fallback hotspot (captive portal) in case wifi connection fails
ap:
ssid: "Kogan Socket 1 Fallback Hotspot"
password: "<i>XXXXXXXXXXX</i>"
captive_portal:
# Enable logging
logger:
# Enable Home Assistant API
api:
ota:
binary_sensor:
- platform: gpio
pin:
number: GPIO0
mode: INPUT_PULLUP
inverted: true
id: power_button
on_press:
- switch.toggle: relay
- platform: status
name: "Kogan Plug 1 Status"
switch:
- platform: gpio
id: green_led
pin:
number: GPIO13
inverted: true
restore_mode: ALWAYS_OFF
- platform: gpio
name: "Kogan Plug 1"
pin: GPIO14
id: relay
icon: mdi:power
restore_mode: ALWAYS_OFF
on_turn_off:
- switch.turn_off: green_led
sensor:
- platform: hlw8012
sel_pin:
number: GPIO12
inverted: true
cf_pin: GPIO04
cf1_pin: GPIO05
current:
name: "Kogan Plug 1 Current"
unit_of_measurement: A
voltage:
name: "Kogan Plug 1 Voltage"
unit_of_measurement: V
power:
id: kogan_plug_1_wattage
name: "Kogan Plug 1 Power"
unit_of_measurement: W
on_value_range:
above: 1
then:
switch.turn_on: green_led
current_resistor: "0.00087" ### HIGHER VALUE GIVES LOWER WATTAGE
voltage_divider: "2030" ### LOWER VALUE GIVES LOWER VOLTAGE
change_mode_every: 8
update_interval: 5s
- platform: total_daily_energy
name: "Kogan Plug 1 Daily Energy"
power_id: kogan_plug_1_wattage
filters:
- multiply: 0.001
unit_of_measurement: kWh
time:
- platform: homeassistant
id: homeassistant_time
</pre>
<br />Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-74665905906134770582020-02-01T16:02:00.001+13:002020-02-23T16:27:45.013+13:00Tuya smart devicesOver the past year, I have collected a number of smart home devices, the majority of which are based on the Tuya platform.<br />
Here is some of what I have learnt about these devices.<br />
<ol>
<li><b>The apps are all compatible.</b><br />
If you buy a new device, it is worth checking whether it works with the app you already have installed before installing yet another brand specific app on your phone.</li>
<li><b>The features are defined by the device, not the app.</b><br />
I bought two heaters, the first branded by Kogan, the second by Goldair. The Kogan heater had full automation enabled, the Goldair heater app worked only as a remote control and for setting simple off/on timers. On seeing that the apps had identical UIs apart from color scheme and available features, i thought to try the Goldair heater with the Kogan app. It worked, but the Goldair heater was still unavailable in the automation UI, and interestingly, the Goldair color scheme was still used to display the Goldair heater.</li>
<li><b>Tuya also publishes their own brand app.</b><br />
I ended up switching away from the brands own app on the assumption that Tuya's own app should have the full feature set (the Goldair one was missing the automation UI completely, though I never tried using the Kogan heater with it, so it may have just been hidden due to no paired devices supporting it). It also gets updates before the branded apps, but from what I saw during the few months I kept multiple apps installed, it is only a couple of weeks ahead at most.
</li>
<li><b>Local control is possible<a name='more'></a></b><br />A big issue if you are concerned about privacy and security is that Smart Home devices typically send data through the cloud rather than directly from your phone to the device. In the case of Tuya, the connection is going via Amazon servers in the US, Europe, or Tencent servers in China, which is collecting data your device is sending in order to show you graphs of usage over time. If you have a home automation server like <a href="https://www.openhab.org/">openHAB</a> or <a href="https://www.home-assistant.io/">Home Assistant</a> on your local network though, you can send commands directly to the device. If you firewall the tuya servers so the devices cannot send data to them, this can give you a completely offline solution.
A better way to go completely offline is to reflash the devices with open source firmware such as <a href="https://github.com/arendst/Tasmota">Tasmota</a> or <a href="https://esphome.io/">ESPHome</a>. Many of the Tuya devices are based on ESP8266 or ESP8285 modules, which are easily reflashable, even without opening any devices up by subverting the Tuya OTA capability. For simple devices such as Smart Plugs, Lightbulbs and switches, there is good support in the open source firmware, and you can likely find some simple instructions to follow. I have successfully flashed my Kogan Smart Plugs to ESPHome using <a href="https://github.com/ct-Open-Source/tuya-convert">tuya-convert</a>, keeping all of their original functionality. I also tweaked the status LED to show whether any significant current had been drawn since it was last switched on, as mostly my smartplugs are connected to heaters with their own thermostat, so I can see easily whether the heater has actually been running or not from the LED.
<br />
For more complex devices, you'll most likely need to do some research or investigation to understand how the device works first. Some Tuya modules are based on RTL8710 microcontrollers, which do not have as many options as ESP8266 devices for reflashing. Another potential issue you'll want to avoid is that many of the more complex devices connect to a separate microcontroller through a UART on the ESP8266, but default ESPHome configurations configure that UART as a debug logging port, which can lead to a bricked device needing serial flashing to recover if you take a simple ESPHome configuration to start, thinking you can reflash it as you learn about the details of your device.
</li>
</ol>
Following this general post, I'll make a few device specific posts to give anyone with the same devices some guidance if they want to follow the same path.Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-34887884398415901242014-09-02T04:11:00.003+12:002020-02-23T16:28:35.658+13:00More remote control decodingAstro have now retired their old decoders, which I spent some time a few years ago trying to <a href="http://blog.jasonrumney.net/2010/07/remote-control.html">control from my PC</a>. It seems at least <a href="http://talk.maemo.org/showthread.php?p=1415402">someone</a> has found a use for that info, but from reading the thread, what they actually wanted was the remote codes for the latest generation Samsung decoders that Astro replaced all the old decoders with.
<br />
In the public interest then, here is an updated LIRC config, and additionally a kernel rc configuration file for the Samsung Astro Byond decoders. Be warned: the kernel rc configuration is using standard key codes, including KEY_POWER, which may cause your PC to shutdown in many default configurations of GNU/Linux desktops - where all available input devices are grabbed by X. Changing to KEY_POWER2 might help with that particular problem - but unless you configure X to ignore the remote control, you'll still see side effects from other keys.
<br />
<a name='more'></a><br />
1. The kernel configuration file (/etc/rc_keymaps/AstroByond).
<br />
<pre style="background-color: #f8f8e0;">#table AstroByond, type: RC6
0x80562700 KEY_0
0x80562701 KEY_1
0x80562702 KEY_2
0x80562703 KEY_3
0x80562704 KEY_4
0x80562705 KEY_5
0x80562706 KEY_6
0x80562707 KEY_7
0x80562708 KEY_8
0x80562709 KEY_9
0x8056270C KEY_POWER
0x8056270F KEY_INFO
0x80562720 KEY_CHANNELUP
0x80562721 KEY_CHANNELDOWN
0x8056274B KEY_SUBTITLE
0x80562754 KEY_HOME
0x80562758 KEY_UP
0x80562759 KEY_DOWN
0x8056275A KEY_LEFT
0x8056275B KEY_RIGHT
0x8056275C KEY_OK
0x8056276D KEY_RED
0x8056276E KEY_GREEN
0x8056276F KEY_YELLOW
0x80562770 KEY_BLUE
0x80562783 KEY_SHOP
0x80562784 KEY_FAVORITES
0x805627A9 KEY_BACK
0x805627CC KEY_TV
0x805627D8 KEY_SCREEN
0x805627F2 KEY_RADIO
0x805627F5 KEY_BUTTONCONFIG
0x805627FB KEY_DOT
</pre>
<br />
2. A traditional lirc configuration file (/usr/local/share/lirc/remotes/AstroByond.conf). Note that the codes seem to be 2s complements of the values above, with an additional prefix. I'm not sure whether this is due to a difference in the way LIRC interprets codes compared with the kernel drivers, or if it is a result of misdetection of other parameters. LIRC's auto-detection is a bit off anyway, as it failed to detect the toggle_bit_mask, and I had to first detect as raw codes, then analyze the resulting file. I think spotted a pattern of alternation between 85xx and 8Dxx for the lower 16 bits, so figured that the toggle_bit_mask was 0x8000. After setting that manually, the remote became very responsive in irw. I did similar manual patching of bit 15 in the ir-keytable results above, but it doesn't seem to make a difference there, just looks cleaner if the keys all have the same prefix.
<br />
<pre style="background-color: #f8f8e0;">#
# this config file was automatically generated
# using lirc-0.9.0(emulation) on Mon Sep 1 22:10:16 2014
#
# contributed by Jason Rumney
#
# brand: Astro Byond
# model no. of remote control: URC931000-01R00
# devices being controlled by this remote: Samsung Astro Byond Decoder
#
begin remote
name ASTROBYOND
bits 37
flags RC6|CONST_LENGTH
eps 30
aeps 100
header 2709 757
one 476 394
zero 476 394
gap 105172
toggle_bit_mask 0x0000008000
rc6_mask 0x100000000
begin codes
KEY_POWER 0x037FA958F3
KEY_CHANNELUP 0x037FA958DF
KEY_CHANNELDOWN 0x037FA958DE
KEY_0 0x037FA958FF
KEY_1 0x037FA958FE
KEY_2 0x037FA958FD
KEY_3 0x037FA958FC
KEY_4 0x037FA958FB
KEY_5 0x037FA958FA
KEY_6 0x037FA958F9
KEY_7 0x037FA958F8
KEY_8 0x037FA958F7
KEY_9 0x037FA958F6
KEY_DOT 0x037FA95804
KEY_OK 0x037FA958A3
KEY_UP 0x037FA958A7
KEY_DOWN 0x037FA958A6
KEY_LEFT 0x037FA958A5
KEY_RIGHT 0x037FA958A4
KEY_TV 0x037FA95833
KEY_RADIO 0x037FA9580D
KEY_HOME 0x037FA958AB
KEY_BACK 0x037FA95856
KEY_RED 0x037FA95892
KEY_GREEN 0x037FA95891
KEY_YELLOW 0x037FA95890
KEY_BLUE 0x037FA9588F
KEY_INFO 0x037FA958F0
KEY_FAVORITES 0x037FA9587B
KEY_SUBTITLE 0x037FA958B4
KEY_SHOP 0x037FA9587C
KEY_SCREEN 0x037FA95827
KEY_BUTTONCONFIG 0x037FA9580A
end codes
end remote
</pre>
Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-88271891845485531062014-08-24T16:46:00.001+12:002020-02-23T16:29:19.140+13:00Android Studio - a frustrating experience in usabilityLately Eclipse has become excessively slow and unstable. So I decided its time to take a look at Android Studio.<br />
<div class="separator" style="clear: both; text-align: center;">
<img border="0" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEhp1vuyW83oJI8_xQgOU26AeytfVuI5cGe22hnMuFuWqVsyrbXfCIuYF7bUY6tyql7RuZu7y8Bj8YZGQ9Hkwmk3bcOo6DMrTv4loaCyiwMnFhdusRPIxsdIvxqJUHpl2uNFZlQ7sKcfIfw/s1600/studio.png" /></div>
I downloaded, and installed with the default settings - mistake number one, as I found out later. Startup took forever, just like Eclipse. I created a new project, choosing the Settings Template, as I know I'm going to need a Settings page for this app, which also took forever. When it eventually finished, there was an error about gradle failing to sync...so basic operations like <i>editing</i> and compiling will not work. WTF! So about half an hour of poking around and searching the net later, I find that my proxy got set when I installed, but today I'm working from home. Apparently some of the other slowness is attributable to that too, as it seems much more responsive when I have disabled the proxy.<br />
<div class="separator" style="clear: both; text-align: center;">
<img imageanchor="1" src="https://blogger.googleusercontent.com/img/b/R29vZ2xl/AVvXsEh6cSOJRX1AjzRX9jfeOYHYNu81ABYZtZbfpWucKdxWvaOBpffFdNNp84gwTmWJsSmU-jAP9AflaxDIOtFpwhf5dPtTckdjM-lMkLTYpX_D3mhpaLaK-9oWWosQMOyE_yPRDMeUphd4dzs/s1600/gradle_sync.png" style="margin-left: 1em; margin-right: 1em;" /></div>
<blockquote>
<b>Advice #1:</b> When designing software, use the system proxy settings, don't introduce your own. People move between networks, and they shouldn't have to reconfigure a dozen separate places when they do.</blockquote>
<br />
<a name='more'></a>So now I have a project, and gradle seems to be happy for now. I'm going to be using websockets, so I add in <a href="http://autobahn.ws/android/">autobahn</a>, and its dependencies <a href="http://jackson.codehaus.org/">jackson-core</a> and <a href="http://jackson.codehaus.org/">jackson-mapper</a>. But before adding any code that actually uses them, maybe I should make sure the basic boilerplate that was generated compiles and runs.<br />
Compiling goes OK. So now to run on my emulator. I am targeting a specific device here, so I don't really want to run it on the Android-L emulator that was installed by default, so time for some more downloading. Start SDK manager from the Tools menu. A dialog comes up, shows a progress bar goes across the screen showing me that SDK manager is taking a long time to start, 10 seconds later it disappears. Nothing happens. Start checking the paths in config - is there something missing. 5 minutes later, the SDK manager appears on the screen. Check RAM and CPU usage for an explanation - 5GB free, nothing taking more than 4% CPU. Kill SDK Manager, and check again while it is starting. The same. So its not a CPU or memory problem. 5 minutes, maybe a network timeout. Maybe its getting its proxy settings from yet another place that I haven't yet discovered and is waiting for the timeout.<br />
<blockquote>
<b>Advice #2:</b> Pop up a window, or at least a splash screen as soon as you can, to let users know that your program is starting. And don't do network stuff on the main thread. Preferably put a message somewhere saying what you are doing when something might take a long time, so users know what to troubleshoot.</blockquote>
Once SDK Manager has started, I select the SDK I need to download, and start the process. It fails. Why? Because it does not have permission to write temporary files. Since Vista, Windows has had this policy that programs have no business writing into the Program Files directory. This stops viruses and trojans from overwriting perfectly good programs. It's a good thing, and Linux and Solaris have similar policies. Temporary files go in the system TEMP directory (/tmp, /var/tmp, %USERPROFILE%\Temporary Files, whatever). Files that need to be updated by a program go into a directory for that purpose (/var/cache/..., %USERPROFILE%\Application Data\..., whereever). This isn't an unusual or unreasonable requirement. But applications like Android Studio, and Eclipse, choose to ignore it, which causes headaches to users on all platforms.<br />
<blockquote>
<b>Advice #3:</b> Follow platform conventions about where to put your files. It's understandable in 2005, when Vista has just come out, that some software has not had time to mend the error of its ways. In 2014, it is inexcusable, especially for cross platform software that also runs on platforms that have had the convention of separating programs and data since at least the 1980's.
</blockquote>
To resolve this, I managed to set the SDK to point to my old copy from the Eclipse days. I think I'd already gone through this problem in the early days with Eclipse, so I had an SDK already in a separate directory. The latest SDK in there is Kit Kat, not Android L, but the bonus was that it already had the even older SDK I need for my emulator. A bit of patching of project files to set the compiler and target to android-19 instead of android-L, and I'm back at the point I was before with the older SDK installation. I could have just updated the SDK now, but I don't fancy waiting around for the 500MB download to complete.<br />
So now to launch the emulator. The custom device I created long ago is now visible, but it isn't working. Eventually I ended up deleting it and recreating. It still didn't work. Unknown to me, the fact that I've installed the Intel HAXM acceleration through SDK manager has made the Intel target visible (which I chose, as it is supposed to be faster, and I don't really care about ARM vs Intel differences for this Java only project), but the HAXM accelerator is not actually installed, only downloaded by the SDK manager. Some messing around at the command-line and a web search later, I find this info, and manually install the HAXM accelerator. But this isn't the only thing stopping my emulator from starting. Another web search, and I find that Hardware Graphics acceleration is only available in Android 4.3 and later, something that wasn't at all obvious when I checked the box. In both cases, there was no obvious error message. The emulator just failed to start, and only by going to the command line and trying the command where I could see the output was I able to diagnose the problem.<br />
<br />
<blockquote>
<b>Advice #4:</b> When you install things, install them properly. Or at least give a prominent warning to the user when you find it is not properly installed, telling them what manual steps they need to do. And if you have options that only work in certain situations, say so, right there next to the checkbox, so users don't waste their time selecting options that won't work. When users don't heed your warnings, don't just fail silently, tell them what went wrong so they can quickly fix it.
</blockquote>
What should have been a five minute session getting the initial boilerplate for my program set up and working turned out to be a four hour mission. I'm tired, so I'm putting it away for now. When I come back, I'll probably be doing most of the work in Emacs to avoid the hassle. Development tools should not be like this. When you have a download that tops 2GB when you add up all the parts, at least some of that code bloat should be going into usability, especially for that first setup experience. I've never used IDEA before, and to be fair, most of the problems seem to be with the Android specific portions, but still, I don't think I'd consider paying for the commercial version IDEA based on my experience today. It may not be fair, but that is how association with a mess like this affects peoples' perceptions. And Android Studio is still a beta product you say? It's been in beta for over a year now. It's had plenty of time to improve, and like every Google product by the time it comes out of beta, it either won't be relevant any more, or you'll have missed the boat if you aren't already using it.<br />
<br />
Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com2tag:blogger.com,1999:blog-5869435496538771132.post-21550920071038922612013-04-12T02:29:00.000+12:002020-02-23T16:30:03.734+13:00Astro xmltv listingsFor quite a while now, I've been pulling TV listings from the Astro website. At first this involved scraping some HTML and the scripts I had were pretty ugly and worked only for the channels I wanted. Then they added some RSS feeds, which made the scraping a bit easier and less prone to breaking every time they updated the look of the website (which was often). For a couple of years now, the RSS feed has been replaced with a JSON API, and I had a pretty good grabber written for that, but never got around to sharing it. Recently they switched to a dedicated server for the JSON API, and gave it an overhaul, so my script stopped working. Now that I've updated it to the new API, its a good time to share.<br />
<br />
<a name='more'></a><br />
<script src="https://google-code-prettify.googlecode.com/svn/loader/run_prettify.js"></script>
<pre class="prettyprint lang-perl">#!/usr/bin/perl -w
eval 'exec /usr/bin/perl -w -S $0 ${1+"$@"}'
if 0; # not running under some shell
=pod
=head1 NAME
tv_grab_my_astro - Grab TV listings for Malaysia using Astro JSON feeds.
=head1 SYNOPSIS
tv_grab_my_astro --help
tv_grab_my_astro --configure [--config-file FILE] [--gui OPTION]
tv_grab_my_astro [--config-file FILE]
[--days N] [--offset N]
[--output FILE] [--quiet] [--debug]
tv_grab_my_astro --list-channels [--config-file FILE]
[--output FILE] [--quiet] [--debug]
=head1 DESCRIPTION
Output TV and listings in XMLTV format for channels available on
Malaysia's Astro subscription satellite service.
First you must run B<tv_grab_my_astro --configure> to choose which stations
you want to receive.
Then running B<tv_grab_my_astro> with no arguments will get a listings for
the stations you chose for five days including today.
=head1 OPTIONS
B<--configure> Prompt for which stations to download and write the
configuration file.
B<--config-file FILE> Set the name of the configuration file, the
default is B<~/.xmltv/tv_grab_my_astro.conf>. This is the file written by
B<--configure> and read when grabbing.
B<--gui OPTION> Use this option to enable a graphical interface to be used.
OPTION may be 'Tk', or left blank for the best available choice.
Additional allowed values of OPTION are 'Term' for normal terminal output
(default) and 'TermNoProgressBar' to disable the use of Term::ProgressBar.
B<--output FILE> When grabbing, write output to FILE rather than
standard output.
B<--days N> When grabbing, grab N days rather than 5.
B<--offset N> Start grabbing at today + N days. N may be negative.
B<--quiet> Suppress the progress-bar normally shown on standard error.
B<--debug> Provide more information on progress to stderr to help in
debugging.
B<--list-channels> Output a list of all channels that data is available
for. The list is in xmltv-format.
B<--version> Show the version of the grabber.
B<--help> Print a help message and exit.
=head1 ERROR HANDLING
If the grabber fails to download data for some channel on a specific day,
it will print an errormessage to STDERR and then continue with the other
channels and days. The grabber will exit with a status code of 1 to indicate
that the data is incomplete.
=head1 ENVIRONMENT VARIABLES
The environment variable HOME can be set to change where configuration
files are stored. All configuration is stored in $HOME/.xmltv/. On Windows,
it might be necessary to set HOME to a path without spaces in it.
=head1 SUPPORTED CHANNELS
For information on supported channels, see http://www.astro.com.my/
=head1 AUTHOR
Jason Rumney, jasonr -at- gnu -dot- org. This documentation and some code
copied from tv_grab_se_swedb by Mattias Holmlund, mattias -at-
holmlund -dot- se, which was in turn partially copied from tv_grab_uk
by Ed Avis, ed -at- membled -dot- com. Overall code based on
documentation at http://wiki.xmltv.org/index.php/HowtoWriteAGrabber
=head1 BUGS
=cut
use strict;
use XMLTV;
use XMLTV::ProgressBar;
use XMLTV::Options qw/ParseOptions/;
use XMLTV::Configure::Writer;
use JSON;
use DateTime;
use Date::Parse;
use Date::Format;
use File::Path;
use File::Basename;
use LWP::Simple qw($ua get);
sub t;
$ua->agent("xmltv/$XMLTV::VERSION");
use HTTP::Cache::Transparent;
# Although we use HTTP::Cache::Transparent, this undocumented --cache
# option for debugging is still useful, since it will always use a
# cached copy of a page, without contacting the server at all.
#
use XMLTV::Memoize; XMLTV::Memoize::check_argv('get');
my $default_root_url = 'http://api-epg.astro.com.my/api';
my $default_cachedir = get_default_cachedir();
my ($opt, $conf) = ParseOptions( {
grabber_name => "tv_grab_my_astro",
capabilities => [qw/baseline manualconfig apiconfig/],
stage_sub => \&config_stage,
listchannels_sub => \&list_channels,
version =*> "0.1",
description => "Malaysia (www.astro.com.my)",
} );
#check config
if (not defined( $conf->{cachedir} )) {
print STDERR "No cachedir defined in config file " .
$opt->{'config-file'} . "\n" .
"Please run the grabber with --configure.\n";
exit 1;
}
if (not defined ( $conf->{'root-url'} )) {
print STDERR "No root-url defined in config file " .
$opt->{'config-file'} . "\n" .
"Please run the grabber with --configure.\n";
}
if (not defined ( $conf->{'channel'} )) {
print STDERR "No channels selected in config file " .
$opt->{'config-file'} . "\n" .
"Please run the grabber with --configure.\n";
exit 1;
}
# Astro webserver is slow to generate responses, with lots of little
# JSON requests, so initialise the caching to use a 12hr timeout.
init_cachedir( $conf->{cachedir}->[0] );
HTTP::Cache::Transparent::init( {
BasePath => $conf->{cachedir}->[0],
NoUpdate => 12*3600,
Verbose => $opt->{debug},
ApproveContent => sub { return $_[0]->is_success },
} );
# Get the actual data and print it to stdout.
my ($xmldecl, $channels) = load_channels( $conf->{'root-url'}->[0] );
my ($odoc, $root );
my $warnings = 0;
binmode STDOUT, ":utf8";
write_header( $xmldecl );
write_channel_list( $conf->{channel} );
my $now = DateTime->today();
t $now;
my $date = $now;
$date = $now->add_duration($DateTime::Duration->new( days => $opt->{offset}))
if ( $opt->{offset} );
my $bar = undef;
$bar = new XMLTV::ProgressBar( {
name => 'downloading listings',
count => $opt->{days} * @{$conf->{channel}},
} ) if (not $opt->{quiet}) && (not $opt->{debug});
for ( my $i=0; $i < $opt->{days}; $i++ )
{
t "Date: $date";
foreach my $channel_id (@{$conf->{channel}})
{
# We already warned the user if the channel doesn't exist.
if ( exists $channels->{$channel_id} )
{
t " $channel_id";
my ( $ch_name, $ch_code, $url, $ch_num, $ch_cat, $ch_astroid ) = @{$channels->{$channel_id}};
print_data( $url, $channel_id, $date, $ch_astroid, $ch_cat )
or warning( "Failed to download data for $channel_id on " .
UnixDate( $date, "%Y-%m-%d" ) . "." );
}
$bar->update() if defined( $bar );
}
$date = $date->add_duration(DateTime::Duration->new(days => 1));
}
$bar->finish() if defined( $bar );
write_footer();
# Signal that something went wrong if there are warnings.
exit(1) if $warnings;
t "Exiting without warnings.";
exit(0);
sub t
{
my( $message ) = @_;
print STDERR $message . "\n" if $opt->{debug};
}
sub warning
{
my( $message ) = @_;
print STDERR $message . "\n";
$warnings++;
}
sub list_channels
{
my ( $conf, $opt ) = @_;
( $xmldecl, $channels ) = load_channels( $conf->{'root-url'}->[0] );
my $result="";
my $fh = new IO::Scalar \$result;
my $oldfh = select( $fh );
write_header( $xmldecl );
write_channel_list ( [sort keys %{$channels}] );
write_footer();
select( $oldfh );
$fh->close();
return $result;
}
sub config_stage
{
my( $stage, $conf ) = @_;
die "Unknown stage $stage" if $stage ne "start";
my $result;
my $writer = new XMLTV::Configure::Writer( OUTPUT => \$result,
encoding => 'utf-8' );
$writer->start( { grabber => 'tv_grab_my_astro' } );
$writer->write_string( {
id => 'root-url',
title => [ [ 'Root URL for grabbing data', 'en' ] ],
description => [
[ 'The file at this URL describes which channels are available ' .
'and where data can be found for them. ', 'en' ] ],
default => $default_root_url,
} );
$writer->write_string( {
id => 'cachedir',
title => [ [ 'Directory to store the cache in', 'en' ] ],
description => [
[ 'tv_grab_my_astro uses a cache with files that it has already ' .
'downloaded. Please specify where the cache shall be stored. ',
'en' ] ],
default => $default_cachedir,
} );
$writer->end( 'select-channels' );
return $result;
}
sub get_default_cachedir
{
my $winhome = $ENV{HOMEDRIVE} . $ENV{HOMEPATH}
if defined( $ENV{HOMEDRIVE} )
and defined( $ENV{HOMEPATH} );
my $home = $ENV{HOME} || $winhome || ".";
return "$home/.xmltv/cache";
}
sub init_cachedir
{
my ( $path ) = @_;
if ( not -d $path )
{
mkpath( $path ) or die "Failed to create cache-directory $path: $@";
}
}
sub load_channels
{
my ($baseurl) = @_;
my %channels;
my $xmldecl = "<\?xml version='1.0' encoding='utf-8'\?>\n";
my $full_url = $baseurl . "/pack?format=jsonp";
my $download = get( $full_url );
my $json = new JSON;
my $chan_data = $json->allow_nonref->utf8->relaxed->decode($download);
$chan_data = $chan_data->{'services'};
foreach my $ch (@{$chan_data})
{
my $ch_id = $ch->{'service_id'};
my $ch_name = $ch->{'title'};
my $ch_code = $ch->{'service_key'};
my $ch_num = $ch->{'channel_number'};
my $ch_cat = $ch->{'channel_category'} || 'unknown';
my $ch_uri = "$ch_num.$ch_cat.astro.com.my";
$ch_uri =~ s/ /_/g;
$ch_name = xml_escape($ch_name);
$ch_uri = lc($ch_uri);
$channels{$ch_uri} = [
$ch_name, $ch_code, $baseurl, $ch_num, $ch_cat, $ch_id ];
}
# TODO: Parse from astro website
return ($xmldecl, \%channels);
}
sub print_data
{
my( $url, $channel_id, $date, $astroid, $category ) = @_;
my $start_date = $date->ymd('-') . 'T00:00';
my $end_date = $date->ymd('-') . 'T23:59';
my $full_url = "$url/guide/start/$start_date/end/$end_date/channels/$astroid?format=jsonp";
my $download = get( $full_url );
my $json = new JSON;
my $schedule = $json->allow_nonref->utf8->relaxed->decode($download);
if ($schedule && ref($schedule) eq "HASH")
{
$schedule = $schedule->{'guides'};
foreach my $programme (@{$schedule})
{
my $event_id = $programme->{'event_id'};
if ($event_id != 0)
{
my $prog_id = $programme->{'program_id'};
my $title = $programme->{'name'};
my $episode_title = $programme->{''};
my $episode_id = $programme->{'group_order_num'};
my $desc = $programme->{'description'};
my $startTime = $programme->{'display_datetime_utc'};
my $stopTime = $programme->{'display_datetime_end_utc'};
my $start = str2time($startTime);
my $stop = str2time($stopTime);
$start = time2str('%Y%m%d%H%M%S %z', $start);
$stop = time2str('%Y%m%d%H%M%S %z', $stop);
# XML escaping of fields that are likely to contain problem chars.
$title = xml_escape($title);
print " <programme channel=\"$channel_id\" start=\"$start\" stop=\"$stop\">\n"
. " <title>$title</title>\n";
if ($episode_title)
{
$episode_title = xml_escape($episode_title);
print " <sub-title>$episode_title</sub-title>\n";
}
if ($desc)
{
$desc = xml_escape($desc);
print " <desc>$desc</desc>\n";
}
print " <category>$category</category>\n";
print " <url>http://api-epg.astro.com.my/api/event/$event_id?format=html</url>\n";
if ($episode_id)
{
print " <episode-num system=\"onscreen\">$episode_id</episode-num>\n";
}
print " </programme>\n";
}
}
}
if ($@) {
# Exception occurred above. Add a comment to the xmltv file
# about the error, and allow the details for other channels to
# keep being processed.
print "<!-- Error parsing channel listings for "
. $channel_id . "\n from URL: " . $full_url
. "\n Message: " . xml_escape($@)
. "\n-->";
}
return 1;
}
sub write_header
{
my ( $xmldecl ) = @_;
print $xmldecl;
print '<!DOCTYPE tv SYSTEM "xmltv.dtd">' . "\n";
print '<tv>' . "\n";
}
sub write_channel_list
{
my ( $channel_list ) = @_;
# Write list of channels.
t 'Writing list of channels.';
foreach my $channel_id (@{$channel_list})
{
if ( not exists $channels->{$channel_id} )
{
print STDERR "Unknown channel $channel_id." .
" See http://www.astro.com.my/" .
" for a list of available channels or run" .
" tv_grab_my_astro --configure to reconfigure.";
next;
}
my ( $ch_name, $ch_code, $namespace, $ch_num, $ch_cat, $ch_astroid ) = @{$channels->{$channel_id}};
print " <channel id=\"$channel_id\">\n"
. " <display-name>$ch_name</display-name>\n"
. " <display-name>$ch_num</display-name>\n"
. " <icon src=\"http://www.astro.com.my/channels/images/channellogo/$ch_num.png\"/>\n"
. " <url>http://api-epg.astro.com.my/api/service/$ch_astroid?format=html</url>\n"
. " </channel>\n";
}
}
sub write_footer
{
print "</tv>\n";
}
sub xml_escape()
{
my ($string) = @_;
if ($string)
{
$string =~ s/&/&amp;/g;
$string =~ s/</&lt;/g;
$string =~ s/>/&gt;/g;
$string =~ s/"/&#34;/g;
# Some of the feeds come in as ISO8859-1 and I can't figure out how
# to get them encoded properly as UTF-8 in perl, so convert all non-ASCII
# to character references.
$string =~ s/([^\x{20}-\x{7E}])/'&#' . ord($1) . ';'/gse;
}
return $string;
}
### Setup indentation in Emacs
## Local Variables:
## perl-indent-level: 4
## perl-continued-statement-offset: 4
## perl-continued-brace-offset: 0
## perl-brace-offset: -4
## perl-brace-imaginary-offset: 0
## perl-label-offset: -2
## cperl-indent-level: 4
## cperl-brace-offset: 0
## cperl-continued-brace-offset: 0
## cperl-label-offset: -2
## cperl-extra-newline-before-brace: t
## cperl-merge-trailing-else: nil
## cperl-continued-statement-offset: 2
## End:
</pre>
Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com11tag:blogger.com,1999:blog-5869435496538771132.post-83831166797741342602010-07-29T02:49:00.005+12:002020-02-23T16:30:34.836+13:00Remote ControlI eventually gave up on the idea of trying to prod the serial port on my <a href="http://www.astro.com.my/">Astro</a> STB and bought a cheap IR transceiver from some guy in Hong Kong via ebay. My first attempts at learning the remote codes were frustrating - irrecord complained about something being wrong after incorrectly guessing the settings, and when I finally got some codes learned, I found that a lot of the buttons had the same code, so 2, 6 and 8 were all being detected as <tt>KEY_2</tt>. Eventually I started trying to manually configure the basic settings based on some of the standard protocols, and eventually hit on RCMM-32, which learned all the codes and can reliably detect them when I press the buttons on the remote.<br />
<br />So now the codes are learned, along with the codes for the extra buttons for controlling a Panasonic DVD player on the bottom of my TV remote, which have now found a use giving basic control of <a href="http://freevo.org/">Freevo</a> in case the <a href="http://www.geniusnet.com/geniusOnline/online.portal?_nfpb=true&productPortlet_actionOverride=%2Fportlets%2FproductArea%2Fcategory%2FqueryPro&_windowLabel=productPortlet&productPortletproductId=1186022&_pageLabel=productPage&test=portlet-action">wireless keyboard</a>, <a href="http://developer.sonyericsson.com/wportal/devworld/technology/more/bluetooth">bluetooth equipped mobile phone</a> or one of many <a href="http://europe.nokia.com/support/product-support/nokia-770">wifi</a> <a href="http://www.htc.com/www/product/desire/overview.html">equipped</a> <a href="http://www.apple.com/ipad/">gadgets</a> is not close at hand.<br />
<br />Next step is to go the other way and send the codes out to the STB. The transceiver doesn't seem to be sending anything out at all. I still haven't narrowed down the problem, it may be a faulty IR LED, or an incompatibility between the transceiver (MCEUSB gen 1) and the software driving it (LIRC 0.86). Now that I have the remote codes, it might also be a good time to go back to trying the serial link, but that'll have to wait for another night. For now, I'll just post up the Astro remote codes, in case anyone else is struggling to get them working with LIRC.<br />
<br />
<a name='more'></a><br /><br />
<blockquote>
<br />
<pre>
# brand: ASTRO
# model no. of remote control:
# devices being controlled by this remote:
# Astro Satellite Decoder STB (Malaysia) [Philips DSR4201/68]
begin remote
name ASTRO
bits 8
flags RCMM|CONST_LENGTH
eps 2
aeps 100
header 417 278
three 167 778
two 167 611
one 167 444
zero 167 278
ptrail 167
pre_data_bits 24
pre_data 0x225027
gap 99817
toggle_bit_mask 0x0
begin codes
KEY_0 0x00
KEY_1 0x01
KEY_2 0x02
KEY_3 0x03
KEY_4 0x04
KEY_5 0x05
KEY_6 0x06
KEY_7 0x07
KEY_8 0x08
KEY_9 0x09
KEY_RED 0x6D
KEY_GREEN 0x6E
KEY_YELLOW 0x6F
KEY_BLUE 0x70
KEY_KPASTERISK 0xF6
KEY_TEXT 0x3C
KEY_MENU 0x54
KEY_SHOP 0xAA
KEY_EXIT 0x83
KEY_BACK 0xA9
KEY_EPG 0xCC
KEY_INFO 0x0F
KEY_UP 0x58
KEY_DOWN 0x59
KEY_LEFT 0x5A
KEY_RIGHT 0x5B
KEY_OK 0x5C
KEY_VOLUMEUP 0x10
KEY_VOLUMEDOWN 0x11
KEY_CHANNELUP 0x20
KEY_CHANNELDOWN 0x21
KEY_AUDIO 0x4E
KEY_SUBTITLE 0x4B
KEY_MUTE 0x0D
KEY_MAIL 0xF3
KEY_FAVORITES 0x84
KEY_HELP 0x81
KEY_POWER 0x0C
end codes
end remote</pre>
<br /></blockquote>
<br />Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com3tag:blogger.com,1999:blog-5869435496538771132.post-29231353559490711222010-03-18T03:36:00.005+13:002020-02-23T16:30:54.927+13:00Controlling my STBMy latest experiment is to see if I can control my Astro decoder via the serial port on the back, so I can have Freevo record from different channels (currently I'm mostly recording the kids shows from NHK that are on in the middle of the night, so we have to remember to leave the decoder on channel 963 each evening). There is of course no documentation about the serial port anywhere on the net, but a few US set top boxes have been hacked, so there is some hope.<br />
<br />
What I know after an hour of poking around:<br />
<br />
<a name='more'></a><br /><br />
Manufacturer: Philips<br />
Model Number: DSR4201/68<br />
Serial port: 115200 8N1 (diagnosed by observing the output)<br />
<br />
Firmware seems to be developed in France, as the only thing I have got out of the decoder so far is some debug messages in French as I shut down. Thomson also supply decoders to Astro, so maybe they are providing the firmware for both their own and Philips boxes?<br />
<br />
Here is the output I see:<br />
<br />
TE : c0c9877c : Ln : b40 > ini_mem<br />
TE : c0c9877c : Ln : b40 > : free_mem<br />
TE : c0c9877c : Ln : b40 > gmhw_init<br />
TE : c0c9877c : Ln : b40 > appel a la fonction Get_Dynamic_mem, retour 0<br />
TE : c0c9877c : Ln : b40 > Valeur de la taille totale dispo pour Partition Privee =2363736<br />
TE : c0c9877c : Ln : b40 > Adresse de la memoire Dynamique 0xc0dbeea8<br />
TE : c0c9877c : Ln : b40 > ok<br />
<br />
No hits on any of that on Google unfortunately, so I'm on my own.Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com2tag:blogger.com,1999:blog-5869435496538771132.post-33214643729214916152008-09-22T22:14:00.004+12:002020-02-23T16:31:16.537+13:00Atoms MovedI've now successfully imported a 700 post blog into draft.blogger.com<br />
<br />
There were a few more quirks of blogger.com along the way. Having <i>next</i> and <i>previous</i> links in the Atom feed causes blogger to reject the entire import file, so I ended up putting them in as comments. There were also some old posts that didn't have an author (perhaps from some beta version of Roller, and blogger rejected those due to the empty <i>name</i> field.<br />
Finally, I had an old comment from the blog's early days that was not UTF-8 encoded in the database (it doesn't appear correctly in Roller either), so I had to reencode that before blogger.com would accept it for import.<br />
<br />
<a name='more'></a><br /><br />
Here is the final export template for Apache Roller 4.0.<br />
<br />
<pre style="background: #fcfcfc; overflow: auto;">
#set($pager = $model.getWeblogEntriesPager())
#set($map = $pager.getEntries())
<?xml version="1.0" encoding='utf-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" xmlns:thr="http://purl.org/syndication/thread/1.0">
<id>$model.weblog.id</id>
<title>$utils.escapeXML($model.weblog.name)</title>
<subtitle>$utils.escapeXML($model.weblog.description)</subtitle>
<updated>$utils.formatIso8601Date($model.weblog.lastModified)</updated>
#if ($pager.nextLink)
<!-- link rel="next" type="application/atom+xml" href="$pager.nextLink"/ -->
#end
#if ($pager.prevLink)
<!-- link rel="previous" type="application/atom+xml" href="$pager.prevLink"/ -->
#end
#foreach( $day in $map.keySet())
#set($entries = $map.get($day))
#foreach( $entry in $entries )
<entry>
<id>$entry.id</id>
<title>$utils.escapeXML($entry.title)</title>
<author>
#if ("$entry.creator.fullName" != "")
<name>$entry.creator.fullName</name>
#end
</author>
<published>$utils.formatIso8601Date($entry.pubTime)</published>
<updated>$utils.formatIso8601Date($entry.updateTime)</updated>
<content type="html"><![CDATA[$entry.text]]></content>
<category scheme="http://schemas.google.com/g/2005#kind"
term="http://schemas.google.com/blogger/2008/kind#post"/>
<link rel="self" type="application/atom+xml" href="http://example.com/$entry.id" />
</entry>
## use Atom threading extensions for comment annotation
#foreach( $comment in $entry.comments )
<entry>
<id>$comment.id</id>
<title>$utils.escapeXML($utils.truncate($utils.removeHTML($comment.content), 40, 50, "..."))</title>
<author>
#if ("$comment.name" != "")
<name>$utils.escapeXML($comment.name)</name>
#end
#if ("$comment.url" != "")
<uri>$utils.escapeXML($comment.url)</uri>
#end
#if ("$comment.email" != "")
<email>$comment.email</email>
#end
</author>
<published>$utils.formatIso8601Date($comment.postTime)</published>
<updated>$utils.formatIso8601Date($comment.postTime)</updated>
<content>$utils.escapeXML($utils.removeHTML($comment.content))></content>
<thr:in-reply-to ref="$entry.id" type="application/atom+xml" href="$entry.permalink"/>
<category scheme="http://schemas.google.com/g/2005#kind"
term="http://schemas.google.com/blogger/2008/kind#comment"/>
<link rel="self" type="application/atom+xml" href="http://example.com/$entry.id" />
</entry>
#end
#end
#end
</feed></pre>
Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-14823642832539467682008-09-14T23:21:00.022+12:002020-02-23T16:31:39.574+13:00Moving AtomsHaving now found an apartment in Malaysia, I'm now faced with the logistics of moving. One problem I'm facing is that for the last 5 years I've run my own server, which now supports several blogs, a forum and my mobile phone's OTA backup. If I knew it was just for a week or two, I could take it offline temporarily, but from what I can tell, internet connectivity in Malaysia is probably not going to be reliable enough to keep all this online for a reasonable proportion of the time, and unless I pay serious money I'll be stuck with the hassle of a dynamic IP address. So I'm looking to migrate at least the blogs and forum off to other services. I've just finished migrating the posts and comments from my first blog (there are still hard links back to my server that need fixing), which was no easy task, as although draft.blogger.com supports Atom based import, it is very particular about some things, with very little documentation and completely useless error handling - it just seems to stop processing as soon as it finds something it doesn't like, and if nothing has been imported yet you get a general meaningless error message, but if one or more posts were successfully imported, it just silently fails to import the posts starting with where it failed. So here is what I found.<br />
<br />
<a name='more'></a><br /><br />
In addition to needing to be a valid Atom 1.0 feed, each entry needs a unique self referencing link: <b><link rel="self" type="application/atom+xml" href="</b><i>post-id</i><b>"/></b> The href does not have to be real, just unique, so I used example.com in my export from roller. The import process also does not accept empty tags for the post or comment author's email, name or uri (according to the rnc schema, only email cannot be empty).<br />
<br />
The following is the template I used to export posts and comments from <a href="http://roller.apache.org/">Apache Roller 4.0</a>. It is based on an <a href="http://www.jroller.com/kame/entry/export_and_backup_your_jroller">earlier export template</a> for JRoller by Damien Bonvillain that output Atom 0.3, with updates for Roller 4.0, Atom 1.0 and blogger.com's undocumented quirks. The exported content still needs some post processing; removing or filling in empty author child tags, checking the truncation of comment titles or misformed content has not broken anything, and replacing relative references (which shouldn't be there in the first place), but generally it works for short blogs. There seems to be a hard-coded limit in getRecentWeblogEntries of 100 posts, so it needs rework to use a pager and an external script to fetch all the pages.<br />
<br />
As with the original, paste the contents below into a new roller template, then use the template to access your blog. If you have too many posts for blogger.com or the export script to handle, you could try using a pager in the export template, or break up the export file manually after extracting everything.<br />
<br />
<br />
<pre style="background: #fcfcfc; overflow: auto;">
#set($entries = $model.weblog.getRecentWeblogEntries('', 100))
<?xml version="1.0" encoding='utf-8'?>
<feed xmlns="http://www.w3.org/2005/Atom" thr="http://purl.org/syndication/thread/1.0">
<id>$model.weblog.id</id>
<title>$utils.escapeXML($model.weblog.name)</title>
<subtitle>$utils.escapeXML($model.weblog.description)</subtitle>
<updated>$utils.formatIso8601Date($model.weblog.lastModified)</updated>
#foreach( $entry in $entries )
<entry>
<id>$entry.id</id>
<title>$utils.escapeXML($entry.title)</title>
<author>
<name>$entry.creator.fullName</name>
</author>
<published>$utils.formatIso8601Date($entry.pubTime)</published>
<updated>$utils.formatIso8601Date($entry.updateTime)</updated>
<content type="html"><![CDATA[$entry.text]]></content>
<category scheme="http://schemas.google.com/g/2005#kind"
term="http://schemas.google.com/blogger/2008/kind#post"/>
<link rel="self" type="application/atom+xml" href="http://example.com/$entry.id"/>
</entry>
## use Atom threading extensions for comment annotation
#foreach( $comment in $entry.comments )
<entry>
<id>$comment.id</id>
<title>$utils.escapeXML($utils.truncate($utils.removeHTML($comment.content), 40, 50, "..."))</title>
<author>
<name>$utils.escapeXML($comment.name)</name>
<uri>$utils.escapeXML($comment.url)</uri>
<email>$comment.email</email>
</author>
<published>$utils.formatIso8601Date($comment.postTime)</published>
<updated>$utils.formatIso8601Date($comment.postTime)</updated>
<content>$utils.escapeXML($utils.removeHTML($comment.content))></content>
<thr:in-reply-to ref="$entry.id" type="application/atom+xml" href="$entry.permalink">
<category scheme="http://schemas.google.com/g/2005#kind"
term="http://schemas.google.com/blogger/2008/kind#comment"/>
<link rel="self" type="application/atom+xml" href="http://example.com/$entry.id"/>
</entry>
#end
#end
</feed></pre>
Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com2tag:blogger.com,1999:blog-5869435496538771132.post-273704784846725302007-10-31T01:27:00.004+13:002010-03-21T20:24:31.421+13:00Unicode and fonts<p><br />Kenichi Handa has been hard at work on a Unicode based Emacs for some years now. For Windows users, there is nothing radical in the default build, a few more languages are supported, and a wider range of Unicode characters, but the Windows specific code has only been updated enough to keep working. In future, optimisations and simplifications can be made due to the internal encodings of Emacs and Windows being both based on Unicode. Messing around with code pages to get fonts displaying will be a thing of the past, and can be already thanks to the new font backend.<br /></p><br /><p><br />While work progressed in parallel on Emacs 22 and the Unicode codebase, there were several other developments happening outside the core Emacs development team. Multiple terminal support (multi-tty) has already been merged with the CVS trunk, though it doesn't mean much to Windows users. Limitations in the way Windows handles console output mean that it is never likely to provide much in the way of new features on Windows, though it may be possible to rid ourselves of the runemacs.exe hack without sacrificing console support using the multi-tty feature.</p><br /><p>Another new development was support for X freetype font rendering. On the face of it, this doesn't seem to mean much to Windows users either, but after being merged with the Unicode branch, it has been refactored into a new font backend design, with better support for unicode fonts. No longer are fonts defined by their character-set, Emacs can make use of font meta-data to determine which Unicode subranges each font supports. Currently the font backend is not enabled by default, but has to be enabled with a configure option. A backend has been implemented for Windows native fonts, and is ready for testing.<br /></p><br /><ul><br /><li>Checking out the Unicode branch:<br /><br /><code>cvs -d:pserver:anonymous@cvs.sv.gnu.org:/sources/emacs co <b>-r emacs-unicode-2</b> emacs</code><br /></li><br /><li>Building Emacs with font backend support:<br /><br /><code>cd emacs\nt<br /><br />configure <b>--enable-font-backend</b><br /><br />make bootstrap<br /></code><br /></li><br /></ul><br /><h3>Future work</h3><br /><p><br />The new font backend is noticeably slower on Windows. A lot of this is probably down to the fact that the old font code cached the font metrics for ASCII characters of fixed width fonts, whereas the new font backend does no such caching yet. We can probably do a better job of caching by calculating which ranges of characters the fixed width applies to, rather than just ASCII. We might even allow multiple such range/width combinations to be associated with a font, to speed up CJK text display (where characters in the font are one of two widths).</p><br /><p>There is no support for BDF fonts in the new font backend. BDF fonts will be given their own font backend, hopefully mostly reusable on other platforms.</p><br /><p>A Uniscribe font backend may be introduced to enable some of the more advanced layout features in Windows XP and later. The new font backend design makes it easier to add new support like this without complex dynamic loading logic to support older versions of Windows.<br /></p><br /><div style="display: none;">topic:[emacs]</div>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-47887382770187931002007-03-29T16:06:00.003+12:002008-09-14T22:59:52.053+12:00Izakaya ryori (pub food) - 居酒屋料理<img src="http://jasonrumney.net/japan-food/Ginza-Tomoru3.JPG" alt="Tomoro: Coaster" /><p>An izakaya is a typical drinking establishment in Japan, though they have always had more emphasis on food than the typical English or New Zealand pub. Like English pubs, and New Zealand cafes, some izakaya have recently started to modernize their menus, combining different styles and bringing foreign influence to traditional Japanese favorites to create new "modern Japanese" dishes. This is especially noticeable in competitive areas like Ginza, where izakaya have to differentiate themselves from the hundreds of other eating and drinking establishments in the area to attract customers.</p><br /> <img src="http://jasonrumney.net/japan-food/Ginza-Tomoru1.JPG" alt="Lobster Salad" /><br /><p><br />Unlike Western pubs, much of the izakaya is private areas where you reserve a table, so more like what we would see as a restaurant, although many after-work groups use it as we would a pub. Some traditional izakaya have seats at the bar, where you interact with and are served by the owner, but more upmarket ones are strictly table service, with waiters and waitresses rushing about in response to bells at each table, making you imagine you are on an aeroplane.</p><br /> <img src="http://jasonrumney.net/japan-food/Ginza-Tomoru2.JPG" alt="Oden"/><br /><p>Despite being in notoriously expensive <a href="http://maps.google.co.jp/?ie=UTF8&om=1&z=19&ll=35.669837,139.759706&spn=0.001113,0.002618" title="map">Ginza</a> at the heart of downtown Tokyo, a variety of dishes and several hours drinking at <a href="http://www.gnavi.co.jp/tomoru/" title="link">Tomoru</a> came to approximately ¥6000 per head. As well as the crayfish salad, branded omelette and meaty morsels pictured, we also had several other mouth watering dishes washed down with wine and beer.</p><br />Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-14265411298790286612007-03-29T14:17:00.003+12:002008-09-14T22:59:52.069+12:00Okonomiyaki (savoury pancake) - お好み焼き<p>Okonomiyaki is native to the Osaka and Hiroshima areas of Japan. It is a pancake made with potato flour, and containing cabbage, and assorted other vegetables and meats, and in the Osaka variation, noodles. Once cooked, the pancake is topped with brown sauce, mayonnaise and bonito flakes or tiny flakes of nori (seaweed), which appear to dance as the heat rises around them. If you are a connoisseur of Korean pa-jeon and Vietnamese banh xeo, then okonomiyaki is a must try dish, along with takoyaki, small dough balls containing octopus that are often sold from carts on the street.</p><br /><img src="http://jasonrumney.net/japan-food/Hiroshima-Okonomiyaki2.JPG" alt="Okonomiyaki" /><br /><p><br />This Okonomiyaki Special was ¥900 from a small store <a href="http://maps.google.co.jp/?ie=UTF8&z=19&ll=34.397544,132.473021&spn=0.001131,0.002618&om=1">near Hiroshima station</a>. We had another in a quick lunch stop at <a href="http://maps.google.co.jp/?ie=UTF8&om=1&z=16&ll=34.73329,135.5005&spn=0.009011,0.020943">Shin-Osaka</a> for ¥650.</p><br /><img src="http://jasonrumney.net/japan-food/Hiroshima-Okonomiyaki-shop.JPG" alt="Hiroshima Okonomiyaki Restaurant"/> <br /><p><br />You can easily make okonomiyaki at home following <a href="http://www.bob-an.com/recipe/dailyjc/basic/oknomi/oknomi.html">this recipe</a> or many like it. Often at restaurants, you will be given a bowl of raw mix, and cook it youself on a hotplate at the table. At other restaurants, you might sit at a counter in front of the chef as they cook in front of you, as common in many types of Japanese restaurants, and probably the closest you'll come to "teppanyaki" style cooking in Japan.<br /></p><br />Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-77692087585170127472007-03-19T11:55:00.004+12:002010-03-21T20:25:43.630+13:00Adding some zest to Picasa's HTML export.<p><br />Google's <a href="http://picasa.google.com" title="link" target="picasa">Picasa</a> is great for managing your photos. It even has an <i>Export as HTML Page</i> option, which lets you generate a webpage for your photos. But all of the page styles it generates are very simple - if all your photos aren't the same size and orientation, the result is messy.<br /></p><br /><p><br />There are some good web page designs around for photos. <a href="http://www.huddletogether.com/projects/lightbox2/" title="link" target="lightbox">Lightbox 2.0</a> is one, but you have to code all the HTML pages by hand, which is tedious and error-prone.<br /></p><br /><p><br />Picasa lets you generate ugly web pages easily, and Lightbox 2.0 lets you generate good looking web pages with a lot of effort. Wouldn't it be great if there was a way to generate good looking web pages as easily as you can with Picasa?<br /></p><br /><p><br />When exporting from Picasa, you have the option to export the page as <i>XML Code</i>. This isn't very useful by itself, but with an appropriate stylesheet, you can easily transform it to anything you want. I wrote a stylesheet for converting to a Lightbox 2.0 style blog entry.<br /></p><br /><blockquote><p><br /><a href="http://jasonrumney.net/jason/picasa-to-lightbox.xsl" title="XSL stylesheet" type="application/octet-stream">picasa-to-lightbox.xsl</a><br /></p></blockquote><br /><p><br />Because I use this for <a href="http://jasonrumney.net/roller/arata/entry/new_zealand_%E3%83%8B%E3%83%A5%E3%83%BC%E3%82%B8%E3%83%BC%E3%83%A9%E3%83%B3%E3%83%89" title="example">blog entries</a>, not complete webpages, there are some stylesheet definitions missing from the generated html, along with the rest of the html head section. See the <a href="http://www.huddletogether.com/projects/lightbox2/" title="link" target="lightbox">Lightbox 2.0 webpage</a> for details on what is needed.<br /></p><br /><p><br />To convert Picasa's generated index.xml using <a href="http://xml.apache.org/xalan-j/" title="link" target="xalan">Xalan</a>, I use the following command-line:<br /></p><br /><blockquote><p><br />java -cp xalan2.jar org.apache.xalan.xslt.Process -IN index.xml -XSL picasa-to-lightblox.xsl -OUT blogpost.html<br /></p></blockquote><br /><p><br />Leave a comment if you have any more Picasa tips.<br /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-51933102981438895092007-03-18T03:01:00.003+12:002008-09-14T22:59:52.108+12:00Hiyashi udon (Cold noodles) - 冷やしうどん<img src="http://jasonrumney.net/japan-food/Yoshimi-Hyakketsu.jpg" alt="Yoshimi 100 caves" align="right" /><br /><p>At every tourist attraction, people will get hungry, so there is always a restaurant somewhere, usually something quick and cheap, so families can get on with sightseeing and save their money for the gifts they need to take back to friends, family and workmates back home. Here at <a href="http://maps.google.co.jp/?ie=UTF8&om=1&z=18&ll=36.039266,139.421192&spn=0.002095,0.005236" title="map">Yoshimi Hyakettsu</a> (Yoshimi "100 caves"), there was a small family run restaurant which had run out of everything on this chilly spring day except hiyashi udon - cold udon noodles. <a href="http://en.wikipedia.org/wiki/Udon" title="wikipedia entry">Udon</a> are a thick white noodle made from wheat flour. They are normally served in a hot soup, but in summer they can also be eaten cold with a soy based <a href="http://japanesefood.about.com/od/saucecondiment/r/sobatsuyu.htm" title="recipe">dipping sauce</a> on the side. Here you see the noodles, sauce and wasabi, chilli and ginger to be optionally added to the sauce.<br /></p><br /><img src="http://jasonrumney.net/japan-food/Yoshimi-HiyashiUdon.JPG" alt="冷やしうどん" /><br /><p><br />Udon are not the only noodles eaten cold. Zaru soba (buckwheat noodles on a bamboo mat) is another popular dish, as is hiyashi chuka (cold <a href="http://jasonrumney.net/roller/jason/entry/ramen_%E3%83%A9%E3%83%BC%E3%83%A1%E3%83%B3">ramen</a> noodles). Harusame (rice or bean vermicelli) is another noodle that is commonly eaten cold in Japan and elsewhere.<br /></p><br />Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-54114714136183131422007-03-17T12:05:00.003+13:002008-09-14T22:59:52.125+12:00Asari (Clams) - あさり<img src="http://jasonrumney.net/japan-food/Suzuka-Asari2.JPG" alt="A bowl of clams"/><br /><p>Fresh seafood is very big in Japan, and it doesn't get fresher than when you collect it yourself. These live clams were collected in <a href="http://maps.google.co.jp/?ie=UTF8&z=10&ll=34.569906,136.658249&spn=0.577841,1.340332&om=1">Ise Bay</a> by the uncle of the family I stayed with as an exchange student in 1989. We used them in miso soup and spaghetti vongole, it sure beats the canned or frozen variety you would get in most Italian restaurants here in the UK.</p><br /><p><br />While I was staying with the family, and whenever I have visited since, uncle Jouji would often bring some fresh food over. He lives just out of town, and is retired so has plenty of time for gardening, fishing and gathering shellfish.<br /></p><br />Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-56091830509139419522007-03-16T02:43:00.003+13:002008-09-14T22:59:52.142+12:00Asking to be sued<p><br />Spotted today on the front page of Google News UK. The article itself was worded slightly differently.<br /></p><br /><img src="http://jasonrumney.net/roller/jason/resource/GoogleNews.png" alt="Google News snapshot" /> <br /><img src="http://jasonrumney.net/roller/jason/resource/abcnews.png" alt="ABC News snapshot" /><br /><p><br />Someone's asking to be sued, but is it Google, or ABC News?<br /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-19327658316381296552007-02-26T06:56:00.003+13:002008-09-14T22:59:52.160+12:00Yuba ryori (Yuba cuisine) - 湯葉料理<img src="http://jasonrumney.net/japan-food/Kyoto-Yuba-shop.jpg" alt="shozankaku Matsuyama" /><br /><img src="http://jasonrumney.net/japan-food/Kyoto-Yuba1.jpg" alt="Yuba with sashima" /><br /><p><br />Japan is home to many restaurants specializing in one specific type of food. <a href="http://www.shozankaku.jp/">Shozankaku Matsuyama</a>, on the top floor of the Isetan shopping centre above <a title="map" href="http://maps.google.co.jp/?ie=UTF8&om=1&z=16&ll=34.985667,135.758781&spn=0.008526,0.020943">Kyoto Station</a>, specialises in <a title="Wikipedia definition" href="http://en.wikipedia.org/wiki/Yuba_%28food%29">Yuba</a> - a byproduct of the tofu manufacturing process sometimes called <em>tofu skin</em>. Every dish they serve contains yuba, and their menu is extensive. I opted for the Takenoko Zukushi (Bamboo shoot set menu) for ¥5000, while Chizu went for the plain Yuba Zukushi for ¥4500. Each set menu consisted of around 7 courses and a drink. We both started with yuba sashimi, slightly different variations but both with fresh cold yuba alongside the more conventional raw fish.<br /></p><br /><img alt="Yuba in soymilk" src="http://jasonrumney.net/japan-food/Kyoto-Yuba2.jpg" /><br /><img src="http://jasonrumney.net/japan-food/Kyoto-Yuba3.jpg" alt="Yuba with bamboo shoot" /><br /><p><br />Next up was another cold dish, of yuba in soymilk. After that the dishes diverged, and the bamboo shoot theme became apparent in my dishes, such as the steamed rice topped with peas served with pickled bamboo shoot, yuba and other pickles.<br /></p><br /> <img src="http://jasonrumney.net/japan-food/Kyoto-Yuba4.jpg" alt="Yuba tempura" /><br /> <img alt="Yuba fried rice" src="http://jasonrumney.net/japan-food/Kyoto-Yuba6.jpg" /><br /><p><br />The dishes continued coming out, with yuba tempura, <a href="http://www.bob-an.com/recipe/English/Kyotodis/en/yubagne.html" title="Recipe">yuba rice</a>, yuba noodles and others not pictured here (the photos were out of focus, or we were too busy enjoying the food and forgot to capture them), including yuba desserts.<br /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-12684246629410383772006-09-15T23:37:00.003+12:002008-09-14T22:59:52.178+12:00Jin chess client<P>I have just learned of a <A href="http://www.linux.com/article.pl?sid=06/09/14/155222">Linux.com article</A> about the alleged GPL violation by IChessU using the <A href="http://www.jinchess.com/">Jin chess client</A> with their proprietary video chat extension. I was somewhat surprised to read that Alexander Rabinovitch was quoting this blog as supporting his position. I cannot imagine what post he is referring to, and noone has contacted me about this. For the record, I do not support his position. From what I understand of the case, Rabinovich initially contacted the author of Jin about licensing his code for a proprietary chess client he was intending to distribute. The Jin author made an offer of licensing the Jin source for a one off fee of US$4000, which would have allowed Rabinovich to distribute unlimited copies without needing to comply fully with the GPL. Rabonivich turned down this offer and decided to try to sneakily get around the GPL, by linking to the Jin code via a socket layer which he wrote [update: it seems he may not have even used sockets in the end, and in fact linked more directly].</P><br /><P>It is a common misconception that the GPL only applies to statically linked modules within a program. It is an even more common misconception that the GPL cannot apply if there is a socket link between two modules. This has never been tested in court as far as I am aware, and it all boils down to what constitutes a derived work under copyright law.</P><br /><P>My opinion is that if you add a network protocol to a GPL program specifically to get your proprietary module working with it, then you are creating a derived work, and the GPL applies to the work as a whole.</P>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0tag:blogger.com,1999:blog-5869435496538771132.post-35881955736386973752006-05-19T22:55:00.003+12:002008-09-14T22:59:52.193+12:00Hi Mum<P><A href="http://maps.google.com/maps?f=q&hl=en&ll=-41.109049,174.905852&spn=0.003581,0.007886&om=1">Google Maps</A> has just extended their mapping to Australia and New Zealand. The NZ maps even show the boundaries between sections! I wish I had this before I went to New Zealand in December / January. If only I could figure out how the searching works, at the moment it only seems useful for locating places that you already know where they are. </P>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com1tag:blogger.com,1999:blog-5869435496538771132.post-30044681513440614662006-05-07T04:08:00.002+12:002008-09-14T22:59:52.217+12:0015 minutes of fame<P>My brother Adrian has just had his <A href="http://www.stuff.co.nz/stuff/0,2106,3659103a10,00.html">15 minutes of fame</A>, after a $12.2M cock up by his bank which they couldn't seem to put right for three days. I'm still fighting my own bank over a £20 penalty they charged me a few months ago because I paid my credit card off before they sent the bill out so I wouldn't get stung with late charges while I was away. Thats the £20 penalty for <B>late</B> payment that OFT ruled as excessive <A href="http://www.creditsearcher.co.uk/features-1122413931.html">last July</A> and gave the banks three months to change, then finally followed up on <A href="http://business.timesonline.co.uk/article/0,,9555-2119968,00.html">last month</A> after the EU competition commision came to the same conclusion. </P>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com1tag:blogger.com,1999:blog-5869435496538771132.post-29387665579125137632006-04-14T12:02:00.004+12:002010-03-21T20:29:45.004+13:00Road to nowhere<p>Check out this <a href="http://maps.google.co.uk/?ll=51.35567,-0.493988&spn=0.002975,0.007725&t=k">Satellite image</a> of the M25 near Woking, from Google Maps. No wonder google's directions always seem to be about a block out.<br /></p><br /><p><b>Update:</b> It looks like they've <a href="http://maps.google.co.uk/?t=k&ll=51.378832,-0.511562&spn=0.002973,0.007542&om=1">moved the problem</a> <br />a few hundred meters north now.<br /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com2tag:blogger.com,1999:blog-5869435496538771132.post-48040321006690458592006-01-28T11:58:00.002+13:002008-09-14T22:59:52.265+12:00Sanitized search<p><img src="http://www.google.cn/images?q=tbn:yoI5AXnLrlUnHM:www.usembassy-china.org.cn/fcs/secy_guitierrez_july_2005_visit_to_beijing/secy_mrs_tiananmen_square.jpg" alt="Tiananmen Square from google.cn" align="left" /> Image 1 of 42 from a <a href="http://images.google.cn/images?hl=zh-CN&q=tiananmen%20square">Google image search</a> for Tiananmen Square on google.cn.</p><br /><br clear="left" /><br /><p><img src="http://www.google.com/images?q=tbn:M2OVdRHUUJLkUM:www.rollins.edu/history/Web%2520Pictures/Tiananmen%2520Square%25202.jpg" alt="Tiananmen Square from google.com" align="left" /> Image 1 of about 14000 results for the <a href="http://images.google.com/images?hl=en&q=tiananmen%20square">same search</a> on google.com.</p><br /><p>[Courtesy of a <a href="http://yro.slashdot.org/comments.pl?sid=175345&cid=14579150">Slashdot post</a>]</p><br /><br clear="left" /><br /><p>It appears from this and a few other quick searches I tried, that Google's capitulating to China and "filtering" their results amounts to <b>only returning results for pages that are located inside the Great Firewall</b>.</p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com3tag:blogger.com,1999:blog-5869435496538771132.post-16335086300847563812005-10-24T02:34:00.002+13:002008-09-14T22:59:52.301+12:00Time to think<p><br />With Chizuko and Arata in Japan for the last 2 weeks, I've had a lot of time to catch up on where the industry is and do some thinking about projects of my own that might have some potential. I've been up late <a href="http://www.w3.org/">reading</a> <a href="http://www.openmobilealliance.org/">specs</a>, and trying out <a href="http://www.flock.com/">new</a> <a href="http://www.blogbridge.com">soft</a><a href="http://www.qumana.com">ware</a>. <a href="http://www.flock.com/">Flock</a> has introduced me to <a href="http://del.icio.us/jasonrumney.net">social bookmarking</a>, something that sounded like a fad to me before, but with it built into the browser, I am finding it useful, if only to keep my bookmarks in sync between the different PC's I use.<br /></p><p><br />The other main features of Flock are a built-in RSS aggregator, but it is not as good as <a href="http://www.blogbridge.com">BlogBridge</a> which I've also discovered recently, and a built in blogging client, which looks suspciously like <a href="http://www.qumana.com/">Qumana</a>, but does not work with <a href="http://www.rollerweblogger.org">Roller</a>, so is useless to me. Qumana on the other hand does work with Roller, but not with non-Latin languages, so for now I'm sticking with the web based "editor" built into Roller.<br /></p><p><br />Part of the thinking about projects I could start has been thinking of names. The main criteria is whether a domain name is available. I thought briefly about placing dot's strangely, a la <a href="http://del.icio.us/jasonrumney.net">del.icio.us</a>, but then I thought of the first site I'd heard of that did that - goatse.cx (not linked for a reason!), which put me off that idea. If I hadn't been put off already, I would have been today, after <a href="http://feeds.feedburner.com/Techcrunch?m=342">reading</a> about the upcoming social bookmarking site <a href="http://ma.gnolia.com">ma.gnolia.com</a>. Too much bandwagon jumping for me, and with the .com on the end they seem a bit confused about whether they want to be a hip Web 2.0 co.mpa.ny or a <i>so last millenium</i> dotcom. I'm sure the VCs are banging down the doors.<br /></p><br /><p>Looking at the latest buzz around Web 2.0, my impression is that tagging is to the <a href="http://www.w3.org/2001/sw/">Semantic Web</a> what the web (or HTML) is to <a href="http://www.xanadu.net/">Xanadu</a>. Its the inferior technology that comes along much later and steals your thunder. Its a simpler idea, and is here now and gaining mindshare quickly.<br /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com2tag:blogger.com,1999:blog-5869435496538771132.post-6313627750012321412005-10-21T12:58:00.002+13:002008-09-14T22:59:52.332+12:00Sashimi - 刺身<p><br />Often what the uninitiated think of when they imagine <a href="http://jasonrumney.net/roller/page/jason?entry=sushi_%E5%AF%BF%E5%8F%B8">sushi</a>, sashimi is raw fish, dipped in soy sauce and wasabi, and accompanied by ginger to clear the taste buds between bites. The fish has to be fresh, which is the main reason why it seldom tastes as good outside Japan.<br /></p><p><br />Sashimi chef's will go to the fish market early in the morning to choose their fish for the day, in some towns, they may buy it straight off the boat as soon as it comes in. Being a good sashimi chef means expert knifework, as well as being at the fish market early and being able to spot the best fish.<br /></p><img src="http://jasonrumney.net/japan-food/Suzuka-Sashimi.JPG" alt="Fresh Sashimi" width="316" height="255" /><p><br />This fish was prepared in my <a href="http://maps.google.co.jp/maps?q=%E9%88%B4%E9%B9%BF%E5%B8%82%E3%80%80%E4%B8%AD%E7%80%AC%E5%8F%A4&ll=34.807893,136.541648&spn=0.003967,0.008918&hl=en">former host family's kitchen</a> by my host brother, Ichiyo, who is now a chef in nearby <a href="http://maps.google.co.jp/maps?q=%E6%9D%BE%E9%98%AA&ll=34.575278,136.541176&spn=16.257188,36.529541&hl=en">Matsusaka</a>, after working in Hawaii for a number of years. It was served on a bed of shredded <a href="http://www.foodreference.com/html/fdaikon.html">daikon</a> and <a href="http://www.gardenguides.com/seedcatalog/herbs/shisogreen.htm">shiso</a> leaves, filled with slices of tuna in addition to its own meat.<br /><br clear="left" /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com1tag:blogger.com,1999:blog-5869435496538771132.post-45377266053169449552005-10-13T12:30:00.002+13:002008-09-14T22:59:52.364+12:00Boys' Toys<p>With Chizuko and Arata away, I have spent the last week stocking up on "toys" of my own. A new hard drive for the web server, which has dropped the background noise in the spare bedroom by several decibels, as well as giving us plenty of space to backup Arata's photos and videos to. A bluetooth headset for my phone (which I got as an upgrade last month), and a spare charger for it. The last two items have highlighted a trend. USB is becoming the new standard for power cables.<br /></p><p><br />I deliberately ordered a travel power supply for the phone, as I'm going to Japan at the end of the month to chaffeur my family home, and to New Zealand for Christmas. I need a spare charger, as I'm forever going to work with an almost flat battery and not realising until I get there. The contents of the package were a USB to Ericsson cable (to charge from a PC), a car cigarette lighter to USB adapter, and a mains to USB adapter with clip on US, Euro and UK plugs. No NZ plug, but I'm sure I can find a PC or car when I'm there.<br /></p><p><br />The bluetooth headset, I also intend to try out with my PC for Skype. Chizu complained that she couldn't hear properly last time I called, and forced me back to a real telephone, so hopefully the headset will do better than the built in microphone of my laptop. It also came with a USB charger, plus a mains and car charger, but they weren't smart enough to leave the cables off those and put a USB socket there instead. I guess I'll just use the USB cable and the adapters I got with my phone.<br /></p><p><br />As for the phone itself, its a Sony Ericsson V800. I got a 3G phone, not so I can waste vast amounts of money downloading video and music from Vodafone, but so I can roam in Japan. The guy that sold it to me was a bit disappointed I think when I declined an "upgrade" to one of their 3G price plans for the bargain price of £40/month. <i>"But it comes with free video, you'll have to pay lots more if you stay with your current plan", "Not if I don't download video". "But you get 200 minutes of calls and 300 free text messages a month", "I don't even use the 25 free minutes and 50 free text messages I get now".</i> I guess his eyes lit up when I asked for a 3G phone straight away, but he ended up having to do the sales pitch in vain in the end.<br /></p><p><br />As an MP3 player, its rubbish. You can't use any headphones other than the handsfree kit that came with it because of the stupid <img src="http://jasonrumney.net/arata/train-ride.jpg" alt="Arata on the train" width="188" height="150" align="right" /> non-standard plug. After 3 uses, there's already a broken wire in there somewhere and the sound comes and goes from my left ear as I walk. The sound is flat and lifeless, and having listened to the same tracks on a Gizmondo with decent headphones, I know its not just badly encoded MP3s.<br /></p><p><br />As a camera, its not bad. Not good either, but better than I expected. In low light the pictures get very noisy, and despite having the brightest LED spotlight of any phone I've seen, they're not bright enough to eliminate the noise. In decent light though, the pictures are OK. Probably comparable to the cardboard throwaway cameras you buy when you're normal camera breaks or gets left behind, but you just have to take some pictures.<br /></p><p><br />My internet usage has gone up slightly, but its still well within the free allowance that I get pooled with the text messages. I've set up a SyncML server, so I can take a backup of my phonebook whereever I am (I could have used Vodafone's server for this like everyone else, but setting up my own was more fun, and I'm always suspicious about giving out my entire contact list to some third party to use for marketing purposes). It is slightly better browsing the web than my old GPRS phone, as long as there's a 3G signal, but its still pretty painful, especially if you have to type something. I set up the email to check my work account, but I mostly get spam, so I don't think I'll get much use out of that.<br /></p><p><br />I might have to revisit the Java midlet I wrote a while ago, based on an idea that Chizu had for an alarm clock. At the time I found that my phone didn't support enough of the Midlet 2.0 spec for it to work, but hopefully, 2 years on, J2ME implementations have improved.<br /></p><p><br />You might have noticed the addition of a "Mobile" category at the top of the page. I almost got the phone set up for mobile photo-blogging. Almost. Actually its the server that's still a problem.<br /></p>Jason Rumneyhttp://www.blogger.com/profile/13356045111965506282noreply@blogger.com0