質問をすることでしか得られない、回答やアドバイスがある。

15分調べてもわからないことは、質問しよう!

新規登録して質問してみよう
ただいま回答率
85.48%
Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

Q&A

解決済

1回答

15001閲覧

ターミナルでsudo python 〇〇.pyとするとモジュールがないと言われる。

meJ15

総合スコア55

Bluetooth

Bluetoothとは短距離の間でデータを交換するための無線通信規格である。固定・モバイル両方のデバイスから、短波の電波送信を行うことで、高いセキュリティをもつパーソナルエリアネットワーク(PAN)を構築する。

Python 3.x

Python 3はPythonプログラミング言語の最新バージョンであり、2008年12月3日にリリースされました。

Raspberry Pi

Raspberry Piは、ラズベリーパイ財団が開発した、名刺サイズのLinuxコンピュータです。 学校で基本的なコンピュータ科学の教育を促進することを意図しています。

Python

Pythonは、コードの読みやすさが特徴的なプログラミング言語の1つです。 強い型付け、動的型付けに対応しており、後方互換性がないバージョン2系とバージョン3系が使用されています。 商用製品の開発にも無料で使用でき、OSだけでなく仮想環境にも対応。Unicodeによる文字列操作をサポートしているため、日本語処理も標準で可能です。

0グッド

0クリップ

投稿2018/12/07 13:16

編集2018/12/08 08:11

前提・実現したいこと

センサデータをble通信でラズパイで受け取ろうと考えています。
このサイトを参考に
ラズベリーパイのターミナルでsudoをつけてpythonのコードを動かそうとするとエラーになる。

sudoをつけずに実行するとうまくいきます。
何がいけないのでしょうか?

とりあえずはラズパイでBLEデータを受け取れることが確認したいのですが、、、

発生している問題・エラーメッセージ

pi@raspberrypi:~ $ sudo python 123.py Traceback (most recent call last): File "123.py", line 7, in <module> from bluepy.btle import Peripheral, DefaultDelegate, Scanner, BTLEException, UUID ImportError: No module named bluepy.btle
pi@raspberrypi:~ $ python 123.py esp32 BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning. BTLE Exception while scannning.

該当のソースコード

python

1# -*- coding: shift-jis -*- 2# 環境センサーをLimited Broadcasterモードにして 3# 10秒アドバタイズ、290秒休み(開発中は50秒休み)に設定 4# 常時スキャンし、データーを取得したらAmbientに送信する 5# 1台(Single)のセンサー端末に対応 6 7from bluepy.btle import Peripheral, DefaultDelegate, Scanner, BTLEException, UUID 8import bluepy.btle 9import sys 10import struct 11from datetime import datetime 12import argparse 13import ambient 14import requests 15import time 16 17channelID = 100 18writeKey = 'writeKey' 19am = ambient.Ambient(channelID, writeKey) 20 21devs = { 22 'omron': {'companyID': 'd502'}, 23 'esp32': {'companyID': 'ffff'} 24} 25target = 'esp32' 26 27Debugging = False 28def DBG(*args): 29 if Debugging: 30 msg = " ".join([str(a) for a in args]) 31 print(msg) 32 sys.stdout.flush() 33 34Verbose = True 35def MSG(*args): 36 if Verbose: 37 msg = " ".join([str(a) for a in args]) 38 print(msg) 39 sys.stdout.flush() 40 41def sendWithRetry(data): 42 for retry in range(6): # 10秒間隔で6回リトライして、ダメならこの回は送信しない 43 try: 44 ret = am.send(data) 45 MSG('sent to Ambient (ret = %d)' % ret.status_code) 46 break 47 except requests.exceptions.RequestException as e: 48 MSG('request failed.') 49 time.sleep(10) 50 51def send2ambient(dataRow): 52 if companyID == 'ffff': 53 (temp, humid, press) = struct.unpack('<hhh', bytes.fromhex(dataRow)) 54 MSG(temp / 100, humid / 100, press / 10) 55 sendWithRetry({'d1': temp / 100, 'd2': humid / 100, 'd3': press / 10}) 56 else: 57 (temp, humid, light, uv, press, noise, accelX, accelY, accelZ, batt) = struct.unpack('<hhhhhhhhhB', bytes.fromhex(dataRow)) 58 MSG(temp / 100, humid / 100, light, uv / 100, press / 10, noise / 100, (batt + 100) / 100) 59 sendWithRetry({'d1': temp / 100, 'd2': humid / 100, 'd3': press / 10, 'd4': (batt + 100) / 100, 'd5': light, 'd6': noise / 100}) 60 61class ScanDelegate(DefaultDelegate): 62 def __init__(self): 63 DefaultDelegate.__init__(self) 64 self.lastseq = None 65 self.lasttime = datetime.fromtimestamp(0) 66 67 def handleDiscovery(self, dev, isNewDev, isNewData): 68 if isNewDev or isNewData: 69 for (adtype, desc, value) in dev.getScanData(): 70 # print(adtype, desc, value) 71 if target in ('omron', 'esp32'): 72 if desc == 'Manufacturer' and value[0:4] == devs[target]['companyID']: 73 delta = datetime.now() - self.lasttime 74 if value[4:6] != self.lastseq and delta.total_seconds() > 11: # アドバタイズする10秒の間に測定が実行されseqが加算されたものは捨てる 75 self.lastseq = value[4:6] 76 self.lasttime = datetime.now() 77 send2ambient(value[6:]) 78 elif target in ('microbit', 'microbit+BME280'): 79 if desc == '16b Service Data' and value[0:4] == 'aafe' and value[8:28] == '000000000000616d6269': 80 print(value) 81 seq = (int(value[32:33], 16) & 0xC) >> 2 82 print(seq) 83 if seq != self.lastseq: 84 self.lastseq = seq 85 if target == 'microbit': 86 temp = int(value[38:40], 16) 87 print('Micro:bit %d' % temp) 88 sendWithRetry({'d1': temp}) 89 elif target == 'microbit+BME280': 90 temp = (int(value[37:40], 16) & 0x3FF) / 10 91 humid = ((int(value[35:38], 16) & 0xFFC) >> 2) / 10 92 press = (int(value[32:35], 16) & 0x3FF) + 400 93 print('Micro:bit t: %f, h: %f, p: %f' % (temp, humid, press)) 94 sendWithRetry({'d1': temp, 'd2': humid, 'd3': press}) 95 96def main(): 97 parser = argparse.ArgumentParser() 98 parser.add_argument('-d',action='store_true', help='debug msg on') 99 parser.add_argument('-o',action='store_true', help='device is omron env sensor') 100 parser.add_argument('-b',action='store_true', help='device is BBC micro:bit') 101 parser.add_argument('-bb',action='store_true', help='device is BBC micro:bit + BME280') 102 103 args = parser.parse_args(sys.argv[1:]) 104 105 global Debugging 106 Debugging = args.d 107 bluepy.btle.Debugging = args.d 108 109 global target 110 if args.o: 111 target = 'omron' 112 elif args.b: 113 target = 'microbit' 114 elif args.bb: 115 target = 'microbit+BME280' 116 print(target) 117 118 scanner = Scanner().withDelegate(ScanDelegate()) 119 while True: 120 try: 121 scanner.scan(5.0) # スキャンする。デバイスを見つけた後の処理はScanDelegateに任せる 122 except BTLEException: 123 MSG('BTLE Exception while scannning.') 124 125if __name__ == "__main__": 126main()

試したこと

sudo をつけることでBLEデバイスにアクセスできるようになるらしいです。

補足
回答者から聞かれたことを試してみました。

イメージ説明

気になる質問をクリップする

クリップした質問は、後からいつでもMYページで確認できます。

またクリップした質問に回答があった際、通知やメールを受け取ることができます。

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

1T2R3M4

2018/12/07 14:30

sudo時のPATHはどうなってますか。
guest

回答1

0

ベストアンサー

pythonのバージョンを確認してください。
$python -V
$sudo python -V
ログインユーザーとrootの.bashrcが違うため環境構築の状況によってはバージョンが違うことがあります。
参考サイトにはpip3と書いてあったので、python3系環境と思うので、
$sudo python3 123.pyで実行するか または シバンにて指定をして$sudo ./123.pyで実行するとできるかもしれません。

投稿2018/12/07 14:59

編集2018/12/07 15:01
GOTA77

総合スコア160

バッドをするには、ログインかつ

こちらの条件を満たす必要があります。

meJ15

2018/12/08 08:09

補足しました これはpython3のほうにbluepyというものがインストールできていないということでしょうか?
GOTA77

2018/12/08 09:52

python3のほうには、インストールできていないか参照できないのだと思います。 ただ、python2.7でのsudo python 123.pyでも参照できないとなるとバージョンは同じですのでモジュールが2.7であれば、上記のように一般ユーザーからはエラーはでないでアクセスできないのだと思います。 少し気になったのは、参考サイトではpyenvで環境を構築していたことです。 もしpyenvを使用している場合は、which pythonとsudo which pythonで参照している場所が違う可能性もあります。よってモジュールが参照できないということも考えられます。
GOTA77

2018/12/08 10:08

追記です。モジュールがあるかはモジュール検索パスはさがしてみるといいと思います。 対話モード(python あればipython)で確認するとわかると思います。コマンドは以下です。 import sys sys.path
meJ15

2018/12/09 03:25

コメントありがとうございます。 pi@raspberrypi:~ $ sudo python3 Python 3.5.3 (default, Sep 27 2018, 17:25:39) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages'] >>> pi@raspberrypi:~ $ python3 Python 3.5.3 (default, Sep 27 2018, 17:25:39) [GCC 6.3.0 20170516] on linux Type "help", "copyright", "credits" or "license" for more information. >>> import sys >>> sys.path ['', '/usr/lib/python35.zip', '/usr/lib/python3.5', '/usr/lib/python3.5/plat-arm-linux-gnueabihf', '/usr/lib/python3.5/lib-dynload', '/home/pi/.local/lib/python3.5/site-packages', '/usr/local/lib/python3.5/dist-packages', '/usr/lib/python3/dist-packages'] >>> KeyboardInterrupt >>> sudoがない場合 sys.path に/home/pi/.local/lib/python3.5/site-packages があるということだけが唯一の違いでした。 今までインストールしてきたモジュール類がここに全部インストールされてるとみてもよいのでしょうか? sudoの時のsys.path に/home/pi/.local/lib/python3.5/site-packagesを追加すればうまくいく気がするのですが、システム的にそのような追加をしていいのか気になります このサイトをみて https://qiita.com/ogwmtnr/items/3ec2fab50d069a3cf335 sudoers.tmpを以下のように変えました # Defaults env_reset Defaults mail_badpass #Defaults secure_path="/usr/local/sbin:/usr/local/bin:/usr/sbin:/usr/bin:/sbin:/bin" Defaults env_keep += "PATH" その後sudo pip3 install blueby としてambent sudo python3 123.pyを実行するとエラーなく動きました。 このようなpath設定をして動いたので良かったのですが、本当にこの設定で良いのでしょうか?
GOTA77

2018/12/09 06:35

通常はpipでのインストールはsite-packages以下にインストールされます。環境変数PATHとモジュール検索パスの関係は私は理解していないので、正しいやり方かについてはコメントはできません。モジュール検索パス追加されているならpythonでは問題ないと思いますが、PATHを変更していいのかは、他の設定にも影響するので。。。 私ならですが、リンクにあるようにroot の~/.bashrcでexport PYTHONPATHでsite-packagesのパスを追加します。 https://note.nkmk.me/python-import-module-search-path/ あと思いついたのは、ユーザーにrootグループを追加して実行です。多分それでもできると思います。セキュリティー上は色々意見はあるやりかたと思いますが、利便性はあります。
meJ15

2018/12/10 05:20

すみません。コメントありがとうございます。参考サイトありがとうございます。
guest

あなたの回答

tips

太字

斜体

打ち消し線

見出し

引用テキストの挿入

コードの挿入

リンクの挿入

リストの挿入

番号リストの挿入

表の挿入

水平線の挿入

プレビュー

15分調べてもわからないことは
teratailで質問しよう!

ただいまの回答率
85.48%

質問をまとめることで
思考を整理して素早く解決

テンプレート機能で
簡単に質問をまとめる

質問する

関連した質問