再挑戦
わたくしは十数名の近衛兵に囲まれながら、畑へと向かいました。押し車には、新たな鹿除けの部品を載せています。
「これ本当に何に使うんですか?」
「完成してからのお楽しみです」
わたくしの畑にはネギが青々と茂っています。鹿がネギの美味しさに気付いてしまう前に、何とか対策を打たなければなりません。
「では、鹿びっくり作戦、その二をはじめましょう!」
「ぽふぃ~♪」
「はぁぴ♪」
「はぴっ!」
「きゅっ!」
「お~!」
灌水バルブ制御用の樽の近くに、シーソーの支点となる杭を打ち込みます。そこに板を載せますが、片方には水の受け皿となる箱を、もう片方には板バネの先にヘッドを取り付けた三連マレットを取り付けます。そして、水が満杯になるまでは三連マレットの側に傾くよう重心を調整します。
次に、三連マレットの側には、屋外用の特注鉄琴を少し傾けて設置し、反対側の箱には樽の排水口から樋を伸ばします。
「金だらいは、もう使わないんですか?」
「はい。金だらいは雑音が多く、音量が大きければ騒動を起こし、小さければ自然音に溶け込んでしまうのです」
「だから鉄琴かぁ。じゃあこれは?」
エイヤは空の庭園用ランタンを手に取ります。
「これはパリちゃんチームの作業小屋に使います」
これが最後の仕上げです。
庭園用ランタンを畑の四隅の杭に取り付けました。
「さあ、パリちゃん達――」
「きゅっ!」
四匹が一つのランタンに入ってしまいました。
「きゅっ!」
「きゅう」
「きゅっ」
「きゅう!」
仲よさそうにじゃれ合っています。せっかくランタンを四個用意したのですが、引き離すのも無粋ですね。
「ランタンは皆さんにそれぞれ一つ用意しています。狭くなったら、他のランタンも使ってくださいね」
「きゅ~?」
四匹同時に身体を傾ける姿を見ると、自然と口元が緩んでしまいます。
「ぽふぃぽふぃ」
「きゅっ!」
今度は四匹揃って、ランタンとランタンを移動します。
まあ、好きなときに好きなランタンに入ってもらえば良いでしょう。
「では、試運転です。近衛兵」
「はっ」
「これから鳴る音が鹿ビックリ装置の音です。それではアピィちゃん、アピエッタちゃんよろしくお願いします」
「はぁぴ!」
「はぴっ!」
「スキル〝C#〟――」
そして日は沈み、時刻は深夜。
わたくしがピケの監視映像を見ていると、鹿の一団が我が物顔で畑に現れました。性懲りのない奴らです。
ピケが動体検知し、即座にアピエッタがレバーを押し下げます。昼にアピィが操作するのと同じ灌水レバーです。
「はぴっ!」
樽から排出された制御用水は、樋を伝い、シーソー上の箱を満たします。やがて重心が動きシーソーが傾くと、箱の中の水が排出され、再び定位置に戻ります。石を打ったその時、板バネの三連マレットが慣性で鉄琴を叩き、
ポロリン~
と音を立てます。
聞き慣れぬ音に鹿は立ち止まり、シーソーを凝視します。ここで、パリちゃんチームの出番です。
「きゅっ!」
パリちゃんチームが色とりどりの光をチカチカと放ちます。赤、青、緑、白、黄、水色、マゼンタ。
「はぴっ」
ポロリン~
「きゅっ!」
チカチカ。
目の前で突如として始まった『古代文明のパーティー』。鹿の顔を七色に彩ります。鹿達は光源をしばらく凝視した後、
『ピェ……?』
と鳴き、困惑しながら去って行きました。
撃退成功です。
とはいえ、ここは王宮。それで終わりません。
城壁の番兵がその光を視認した後、伝令が走り、近衛兵の夜警班が畑の付近を見回ります。
夜警班のために、畑ではピケのステータスウィンドウを開いたままにしてあります。彼らはそのステータスウィンドウを操作して、数分前の状況を確認します。鹿ビックリシステムが発動した原因が鹿であったことを確認すると、彼らは警戒を解き、通常の巡回に戻っていきました。
万が一、鹿が慣れてしまったり、本当に侵入者だったりしても、近衛兵により対処が行われるという寸法です。
近衛兵に頼るのは若干、DIYの精神に反しているような気がしますが、王宮警備の都合上、異常を感知したならば必ず確認しなければならないと、そのような運用になったのでした。
「成功です!」
「ぽふぃ♪ ぽふぃ♪」
わたくしが発動したのは、過去で一番複雑なものでした。
『スキル〝C#〟一分ごとに最初に動体検知した時に昼の間はアピィちゃんお手だけ夜の間はアピエッタちゃんお手してパリちゃんチーム一分間カラフルに点灯』
``` csharp
var builder = WebApplication.CreateBuilder(args);
builder.Services.AddSwibo();
builder.Services.AddSkillDiscoveryMetadataGenerator();
var app = builder.Build();
app
.ExposeSkillDiscoveryMetadata("csharp.一分ごとに最初に動体検知した時に昼の間はアピィちゃんお手だけ夜の間はアピエッタちゃんお手してパリちゃんチーム一分間カラフルに点灯")
.WithSwiboEventHook("/");
var lastExecutionTime = DateTime.MinValue;
app.MapPost("/", async ([FromBody]SwiboEventNotification notification, ISwiboContext context, CancellationToken cancellationToken) =>
{
var now = DateTime.Now;
var sunsetHour = 18;
var sunriseHour = 6;
if(notification.EventType == SwiboEvent.ChangeReport &&
notification.TryParseContextData<SwiboCameraEventData>(out var data) &&
data.DetectionState == SwiboDetectionState.Detected &&
lastExecutionTime.AddMinutes(1) <= now)
{
lastExecutionTime = now;
var アピィ = context.Swibos.OfType<SwiboBot>().First(x => x.Name == "アピィ");
var アピエッタ = context.Swibos.OfType<SwiboBot>().First(x => x.Name == "アピエッタ");
var パリちゃんチーム = context.Swibos.OfType<SwiboSmartLight>().First(x => x.Name.StartsWith("パリ")).ToList();
if(sunriseHour <= now.Hour && now.Hour <= sunsetHour)
{
await アピィ.PressAsync(cancellationToken);
}
else
{
await アピエッタ.PressAsync(cancellationToken);
await Task.WhenAll(
パリちゃんチーム.Select(x => x.TurnOnAsync(cancellationToken))
);
var rand = new Random();
while(!cancellationToken.IsCancellationRequested && now.AddMinutes(1) > DateTime.Now)
{
await Task.WhenAll(
パリちゃんチーム.Select(x => x.SetColorAsync($"{rand.Next(0,255)}:{rand.Next(0,255)}:{rand.Next(0,255)}", cancellationToken))
);
await Task.Delay(TimeSpan.FromSeconds(1));
}
await Task.WhenAll(
パリちゃんチーム.Select(x => x.TurnOffAsync(cancellationToken))
);
}
}
return Results.Ok();
});
app.Run();
```
こうして、わたくしたちはスローライフを少しだけ取り戻したのでした。




