ニコ生の予定をGoogleカレンダーと同期するやつ

この記事はロ技研秋のブログリレー6回目の記事です

こんにちは、16のマッキーです。
みなさんはアイドルマスターシャイニーカラーズをやっていますでしょうか?やっていない方は今すぐ始めよう!→ https://shinycolors.idolmaster.jp/

現在そのアイドルマスターシャイニーカラーズの声優さんが個人で出演されているニコ生の番組が無限に増えています。今年に入ってから新しいニコニコチャンネルが10個以上できて、元からあったチャンネル内の番組としても10個ほど番組が新しくできています。
つまり何がいいたいのかというと
_人人人人人人人人人_
> 時間が足りない <
 ̄Y^Y^Y^Y^Y^Y^Y ̄
そして番組のスケジュールが把握しきれないという問題があります。
(番組にもいろいろあって毎週完全に時間が決まっている番組もあれば、月一回で時間は不定の番組も数多くあるのです)

そこでニコニコ生放送の予定をGoogleカレンダーと同期するやつを作りました。

Googleカレンダーがこんな感じになります。明らかに番組被りすぎてるところがあるんだよなぁ…

やることは簡単
1.Googleカレンダーから現在登録されている番組を取得
2.チェックするチャンネルのこれからの番組をニコニコのAPIから取得
3.未登録の番組をGoogleカレンダーに追加

この3つです。今回はこれをPythonでやってみました(Pythonを選んだ理由は自分が慣れていただけなので深い理由は特にないです)

今回解説するのは・PythonからGoogleカレンダーにアクセスする部分とニコ生APIから番組の取得する部分です。

Googleカレンダー

最初にGoogleカレンダーについてですが、GoogleカレンダーのAPIのページにいろいろ書いてあります。 https://developers.google.com/calendar/quickstart/python
またこちらのページを参考にしました。
https://non-dimension.com/python-googlecalendarapi/

1.Google Calender APIの有効化Google Calender APIよりEnable the Google Calendar APIボタンから
credentials.json
をダウンロード

2.以下のコマンドよりクライアントライブラリのインストールする
pip install --upgrade google-api-python-client google-auth-httplib2 google-auth-oauthlib

3.以下のコードを実行するとGoogleカレンダーの権限を要求されるので許可するとtoken.pickleというファイルが生成されます。
このファイルがあると次回から何も聞かれずカレンダーにアクセスできます。
操作したいGoogleカレンダーの操作したいカレンダーの”設定と共有”からカレンダーIDをコピーしてきてgoogle_calendarIdに代入して操作するカレンダーを指定します。
以下Googleカレンダーの読み書きをする例です。

import os
import pickle
import os.path

from googleapiclient.discovery import build
from google_auth_oauthlib.flow import InstalledAppFlow
from google.auth.transport.requests import Request

from datetime import datetime, timezone, timedelta

TIMEZONE = '+09:00'

google_calendarID='ここにカレンダーID'
SCOPES = ['https://www.googleapis.com/auth/calendar']

## Add calender
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
print(creds)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token.pickle', 'wb') as token:
pickle.dump(creds, token)
print(token)
service = build('calendar', 'v3', credentials=creds)
event = {
'summary': 'title',
'location': 'location',
'description': 'description',
'start': {
'dateTime': '2020-10-27T20:00:00+09:00',
'timeZone': 'Japan'
},
'end': {
'dateTime': '2020-10-27T21:00:00+09:00',
'timeZone': 'Japan'
}
}

print(event)
event = service.events().insert(calendarId=google_calendarID,body=event).execute()

## Read calender
creds = None
if os.path.exists('token.pickle'):
with open('token.pickle', 'rb') as token:
creds = pickle.load(token)
# If there are no (valid) credentials available, let the user log in.
if not creds or not creds.valid:
if creds and creds.expired and creds.refresh_token:
creds.refresh(Request())
else:
flow = InstalledAppFlow.from_client_secrets_file(
'credentials.json', SCOPES)
creds = flow.run_local_server(port=0)
# Save the credentials for the next run
with open('token/token.pickle', 'wb') as token:
pickle.dump(creds, token)

service = build('calendar', 'v3', credentials=creds)

timefrom=datetime.now().isoformat()+TIMEZONE
timeto= (datetime.now() + timedelta(days=60))
timeto=timeto.isoformat()+TIMEZONE

events_result = service.events().list(calendarId=google_calendarID,
timeMin=timefrom,
timeMax=timeto,
singleEvents=True,
orderBy='startTime').execute()
events = events_result.get('items', [])

print(events)

ニコ生API

次にニコニコのAPIについてです。例えば

https://api.search.nicovideo.jp/api/v2/live/contents/search?q=%E4%B8%80%E8%88%AC%28%E3%81%9D%E3%81%AE%E4%BB%96%29&targets=tags&fields=contentId,channelId,title,startTime,liveEndTime,description&filters[channelId][0]=2644423&filters[liveStatus][0]=reserved&_sort=-startTime&_context=nico%20live%20to%20google%20calendar&_limit=60

のようにAPIエンドポイントhttps://api.search.nicovideo.jp/api/v2/live/contents/search
の後ろにクエリパラメータをいろいろ付けてあげるとデータが返ってきます。これをブラウザなどのURLを入れるところに入れれば検索結果が返ってきます。

pythonでの例は以下の通り

import requests
import urllib.parse

nicolive_API_endpoint='https://api.search.nicovideo.jp/api/v2/live/contents/search'
q_='一般(その他)' #タグ
q=urllib.parse.quote(q_)
targets='tags' #タグ検索

fields='contentId,channelId,title,startTime,liveEndTime,description'
filters_channelId='&filters[channelId][0]='+str('2644423') #チャンネルのID
filters_liveStatus='&filters[liveStatus][0]=reserved' #enum('past','onair','reserved')

_sort='-startTime'
_context='nico live to google calendar'
_limit=str(60)

url=nicolive_API_endpoint+'?q='+q+'&targets='+targets+'&fields='+fields+filters_channelId+filters_liveStatus+'&_sort='+_sort+'&_context='+_context+'&_limit='+_limit 
res = requests.get(url).json()
print(res)

ニコニコのAPIの説明はこちら
https://site.nicovideo.jp/search-api-docs/search.html

基本的にはこれでいろいろ取得できるはずです。

最終的にできたもの

以上の2つを使っていろいろ見やすくしたり、LINE LIVEに対応したりして実際に使ってるのはこちら↓

https://github.com/mmaakkyyii/NicoLive2GoogleCalendar

私はこれを毎日自動で実行するようにしているので最新のニコ生の情報が同期するようになって最高になりました(番組を見る時間は足りない)

AdCなのでADCを作った

こんにちは16のマッキーです。
この記事はrogy Advent Calendar 2018の15日の記事です。

タイトルの通りですが、AdC(Advent Calendar)ということでADC(Analog Digital Converter)を作ってみました。

ADCはマイコンとかを使う人はおなじみの機能だったりすると思うのですが、それを使うのではなく自分で作ろうといったところです。

そんな感じで作ったものを紹介します。

 

ADCの概要についてはここ → https://www.rohm.co.jp/electronics-basics/ad-converters/ad_what1 などを見ると以下の説明もだいたいわかると思います。

今回はフラッシュ型と逐次比較型のADCを作りました。とりあえず動作すればいいかなということで性能は特に気にして作ってませんが、最終的にAD変換したものをLEDにレベルメーターのように出力できればいいかなと思ったのでどちらも5bitのADCにしました。

フラッシュ型


回路自体もコンパレータを大量に並べただけなのでシンプルでいい感じですね。

逐次比較型


本当はサンプルホールド回路が入るのですが、時間が足りなかったのでついてません。ただ人がLEDのメーターを見る分には問題なさそうです。(動画は1Hzの三角波)

二分探索してる様子です。青い信号(DACの出力)が少しずつ黄色い入力電圧に近づいてます。

比較部分のロジックはFPGAを使いました。
またそのためのHDLのコードをMATLABのHDL Coderというツールを使ってみました。このため、コードは書かずにブロックをごちゃごちゃいじってHDLを生成できました。

↑Simulink上の回路の雰囲気

FPAG周りの回路はユニバーサル基板上に作りました。(こんな感じの配線は初めてやったけど意外とできることが分かった)

まとめ

  • AdCでADC作ったっていうのができてよかった(これが一番やりたかった)
  • AD変換ができたっぽかったのでよかった
  • なんかFPGA使いたかったので使えてよかった
  • MATLAB最高だった
  • はんだ付け楽しかった
  • 他の変換方式もやろうと思ってたけど時間が足りなくて悲しかった

 

 

EAGLEでツイートしようPart1

こんにちは16のマッキーです。
この記事は春の新歓ブログリレー17日目の投稿です.

EAGLEからツイートしたい…!(願望

EAGLEのULPにはもともとsystemという関数があってこれで外部のプログラムが実行できます。これで予めつくっておいたプログラムを起動してツイートします。

こんなかんじです。作っている回路の画像と一緒にツイートできるようにしてみました。

これで進捗してると思わせておいていつでもツイートができますね♪

 

ほんとうは外部のプログラムを使わないでやりたかったのですが時間がなくてできなかったので今回はここまで

次回Part2へつづく