Qiita Teams that are logged in
You are not logged in to any team

Log in to Qiita Team
Community
OrganizationAdvent CalendarQiitadon (β)
Service
Qiita JobsQiita ZineQiita Blog
Help us understand the problem. What is going on with this article?

DigitalSignage with Raspberry Pi

More than 1 year has passed since last update.

DigitalSignage with Raspberry Pi

はじめに

こちらは みんなのラズパイコンテスト2019でラズベリーパイ財団賞を頂いた,デジタルサイネージ with Raspberry Piの記事となります。
紙の連絡掲示板をデジタル化して楽に置き換えられるものを目指して製作しました。

使用パーツ

  • Raspberry Pi 3 model B
  • HDMIケーブル
  • 液晶ディスプレイ
  • 電源

環境

  • Raspbian
  • Python3
pydrive (Google Drive API)
pdf2image
PIL
tkinter

処理の流れ

概要

  1. 連携しているアカウントのGoogle Driveに「ScanPDF」フォルダが存在するか確認(存在しない場合は「ScanPDF」フォルダを生成し,そのフォルダのidを記憶)
  2. 記憶したidのフォルダ配下のPDFファイルをすべて取得してローカルの一時フォルダに格納
  3. 一時フォルダ内のPDFをディスプレイに表示
  4. 複数のPDFファイルが有る場合は一定時間ごとに表示するPDFファイルを変更
  5. 以降2~5を繰り返す

認証

Google Oauthを使用してアカウントにGoogle Drive APIとプロジェクトのアクセスを許可

Main.py
gauth = GoogleAuth()
drive = GoogleDrive(gauth)
files = os.listdir('./data/')
count = len(files)
dirtxt = 'dirdata.txt'

保存用フォルダ生成・検索

初回連携時にはScanPDFフォルダが生成されます。
それ以降は該当フォルダを取得します。

Main.py
if not os.path.isfile(dirtxt):
    folder = drive.CreateFile({
        'title': 'ScanPDF',
        'mimeType': 'application/vnd.google-apps.folder'
    })
    folder.Upload()
    with open(dirtxt, mode='w') as f:
        f.write(folder['id'])
        dir_id = folder['id']
else:
    with open(dirtxt) as f:
        dir_id = f.read()

PDFファイル取得

ユーザーはScanPDFフォルダにサイネージに表示したいPDFファイルを追加します。
その後,フォルダ内がスキャンされると液晶に追加したPDFが表示されます。

Main.py
  def scan(self):
    global count
    404img_path = "./data/404.png"
    tmp_dir = "./tmp/"
    shutil.rmtree(tmp_dir)
    os.mkdir(tmp_dir)
    i = 1
    query = f"'{dir_id}' in parents and trashed=false"
    try:
        for file_list in drive.ListFile({'q': query, 'maxResults': 100}):
            for file in file_list:
                if file['mimeType'] == 'application/vnd.google-apps.folder':
                    pass
                else:
                    file.GetContentFile(f'./tmp/{i+1}.pdf')
                    i += 1
    except Exception as e:
        print(e)
    files = os.listdir(tmp_dir)
    count = len(files)
    if os.path.isfile(404img_path):
        os.remove(404img_path)
    if count == 0:
        shutil.copy('404.png', 404img_path)
        shutil.rmtree(tmp_dir)
        os.mkdir(tmp_dir)
    else:
        for i in range(0, count):
            shutil.copy(f'./tmp/{i+1}.pdf',
                        f'./data/{i+1}.pdf')
        files = os.listdir('./data/')

ファイル表示

Main.py
image = convert_from_path(f'./data/{cnt % (count) + 1}.pdf')
tmp = image[0].rotate(90, expand=True).resize((sw, sh))
self.img = ImageTk.PhotoImage(tmp)
self.canvas.itemconfig(self.imgArea, image=self.img)

※ ファイルが複数枚ある場合は30秒ごとに表示されるファイルが変更されます
※ ファイルに複数ページが有る場合は1ページ目のみ表示されます
※ また,ファイルが存在しない場合はプリセットされた「404 NotFound」(右図)が表示されます。

Digital Signage.png

動作画像

Digital Signage1.pngDigital Signage3.png

終わりに

ファイル保管場所にGoogle Driveのフォルダを使用しているので,外出中でも更新することができます。更に,フォルダへのアクセス権限を設定することで複数人で更新することもできます。
ラズパイ自体はほぼ場所を取らないので,コンパクトさに関しては液晶の薄さによります。
現在このシステムを大学の研究室の連絡掲示板として導入していますがうまく動作しています。
セキュリティ的な問題は考慮しておりません。

プルリク・ツッコミ歓迎しております。是非よろしくお願いします

nnn-school
IT×グローバル社会を生き抜く“創造力”を身につけ、世界で活躍する人材を育成する。
https://nnn.ed.jp/
Why not register and get more from Qiita?
  1. We will deliver articles that match you
    By following users and tags, you can catch up information on technical fields that you are interested in as a whole
  2. you can read useful information later efficiently
    By "stocking" the articles you like, you can search right away