前回ESP32でサーバーへ重量データと臭気データを送ることに成功しました。
今回はサーバーに送られてきた重量変化のデータから
- 体重
- 排泄物計量
- トイレ滞在時間
を分析するコードを書きました。
コードの概要
- 重量変化を降順に並べ、3回計測分の平均値を重量とします(体重計側で8回分の平均を出しているので、正確には24回計測分の平均値)。
- 最後が猫が降りた後の重量を基準として、1.5Kg以上の重さがあり、且つ3秒以内の誤差が4g以下(最初20gからいろいろ試して最終的に4gになりました)の場合に用を足している最中の静止状態として猫の体重とします。
- 猫の体重が求められたら、猫の体重から1.5kg以上減り、且つ計測器が1g以内の誤差で静止している場所を初期値(オフセット値)として記録します。
- 基準値から初期値を引いたら排泄量が求められます。
- 初期値が求められるまでの間をカウントし、トイレ滞在時間とします。
コード
データは
data = [ 369377, 369357, 369376,....(300個ぐらいのint値)..366694]
このようなオフセット値無しの生データの配列です。
#重量データから猫の排泄状況解析。エラーの場合、offsetが0になる
def analyse_weight( datas ):
cnt = 0
w_stock = []
w_offset = 0 #オフセット
w_pee = 0 #降りたときの値
w_weight = 0 #乗って落ち着いたときの重量
cnt_stay = 0 #滞在時間
for w in reversed( weights ):
#3つの数値の平均値
w_stock.append( w )
w_stock = w_stock[-3:]
avl = statistics.mean( w_stock )
#最後から3つまでを降りたときの重量とする
if cnt == 3:
w_pee = avl
if w_pee != 0 and w_weight == 0:
#降りた時の重量より1500g以上重く、3秒間誤差が4g以内に収まっている状態
if w_pee +1500 < avl:
if cnt_stay == 0:
cnt_stay = cnt #滞在中の時間計測用
if w_stock[0]-2 < w_stock[1] and w_stock[1] < w_stock[0]+2 and w_stock[1]-2 < w_stock[2] and w_stock[2] < w_stock[1]+2:
w_weight = avl
#乗る前の重量なので、3秒間で+=1gの静止時で、1500g以上の重量変化の前
if w_weight != 0 and w_offset == 0 and w_weight -1500 > avl:
if w_stock[0]-1 < w_stock[1] and w_stock[1] < w_stock[0]+1 and w_stock[1]-1 < w_stock[2] and w_stock[2] < w_stock[1]+1:
w_offset = avl
cnt_stay = cnt - cnt_stay
break
cnt+=1
#オフセット値を引く
w_pee = w_pee -w_offset
w_weight = w_weight -w_offset
res = {'offset':w_offset ,'pee': int(w_pee), 'weight': int(w_weight) ,'Stay': cnt_stay }
return res
トイレ掃除などの場合はoffset値が0となり、猫が乗って排泄して降りるという行為が5分以内に行われた場合には正常に機能します。
マイナス値や一桁値はおそらくトイレに入っただけだと思います。(トイレ砂が出た量?)
オフセット値は都度変化しています。これは、
- 室温の影響
- 体重計(木材)の変形
- 排泄物の蒸発
- トイレ砂の増減
- 掃除
など理由は多岐にわたりますが、重量の増減前の静止時の値をオフセット値としているので問題ありません。
そして想像以上に体重が正確に出ていることに驚きました。排泄後に食事無しで入った場合、しっかりと排泄分が減っています。
10g程度は誤差があると思いますが、このロードセルは安いしかなり優秀ではないでしょうか。
次に、排泄時の重量変化をグラフ化してみました。
大
大
小
小
大と小
結構特徴的なグラフになりますね。
トイレの滞在時間だけでも違いますが、静止(排泄行為)の後のネコババ行為の長さが圧倒的に違うので、ここだけでも割と判断ができそうです。
排泄行為後の長さをbabaとして集計しました。
大凡ですが、1分以上排泄後に滞在している場合はほぼ確実に大だと推測することができます。
両方の場合はもう少し良いアルゴリズムを考えないといけません。
この重量変化に加えてにおいセンサーで精度よく判断したいところですが、部屋自体の臭気など日によって環境が違うことから確実に判断できるとは今のところ言えません。
匂いの反応値と、反応までにかかった時間を書き出してみました。
整髪料の使用時など、部屋の空気清浄機の反応と同じタイミングで発火しているのでセンサーは問題なく機能していますが、臭気センサーのレベル調整が少し面倒でした。
結果として、0.7%程度のセンサー電圧の変化でデータを送信するようにしました。
何度か排泄などのタイミングでセンサー値を比べてみると、整髪料を使った時は200以上の値が100計測(50秒)以内に出現しているのに対して、排泄臭はやや穏やかな反応(20程度が100計測以上)を示しているのでこの辺で生活臭との分別は出来そうです。
いずれにせよ、排泄のタイミングと臭気は追って分析していく必用がありそうです。
これでサーバー側の処理の必要最低限の処理は一通り出来ましたが、精度を求めるとなるとまだまだ工夫が必要です。
次回の第7回目の記事はもう少しデータを蓄積した後に掲載したいと思います。
ちなみにですが、製品のトレッタはデータを動物病院と連携させるプログラムが実現されていて自作ではとても不可能な充実したケアが行えるようです。
至れり尽くせりで本当にすごいプログラムなので一見の価値アリです↓