Symfoware

Symfowareについての考察blog

AWS IoTにPythonでMQTTイベントの送信、受信するまで

AWS IoTにPythonでメッセージのやり取りを行ってみます。

こちらがとても参考になりました。
AWS IoTをPythonで簡単に始めるまで


必要最低限の設定



AWSコンソールで「IoT Core」の設定画面を表示します。
[管理] - [モノ]を選択し、「モノの登録」をクリックします。

905_01.png

「モノ」を登録するウィザードが始まります。
「単一のモノを作成する」をクリック。

905_02.png

適当に「モノ」の名前を入力します。
「タイプ」や「グループ」の指定は未設定でもOKです。

905_03.png

名前を入力したら、画面下の「次へ」をクリックしてウィザードを進めます。

905_04.png

続いて証明書の追加です。
推奨となっている1-Click証明書を作成します。

905_05.png

証明書が作成されるのでダウンロードしておきます。

905_06.png

「AWS IoTのルートCA」のダウンロードをクリックすると、別ウインドウでテキストが表示されます。

905_07.png

表示された内容を「rootCA.pem」という名前で保存しておきます。(重要)

プログラムで使用するのは、前の画面でダウンロードした
「このモノの証明書」「プライベートキー」
そして、先程保存した「rootCA.pem」になります。

・XXXXXXXXXX-certificate.pem.crt
・XXXXXXXXXX-private.pem.key
・rootCA.pem

ここまでの操作で、
[管理] - [モノ]

905_08.png

[安全性] - [証明書]

905_09.png

にそれぞれ項目が追加されているはずです。



ポリシーのアタッチ



作成した証明書で何ができるか、ポリシーを作成して指定してやります。
[安全性] - [ポリシー]を選択し、「ポリシーの作成」をクリック。

905_10.png

ポリシーの名前は適当に「python-policy」としました。

とりあえずのテストなので、すべての権限を与えます。
アクションは「iot:*」
リソースARNは「*」
とし、効果は「許可」

この状態で作成します。

905_11.png


作成したポリシーを証明書にアタッチします。
証明書右上の「...」をクリックしてメニューを表示し、「ポリシーのアタッチ」を選択。

905_12.png

先程作成したポリシーを選択して「アタッチ」実行。

905_13.png

これで証明書が「アクティブ」になりました。

905_14.png




AWS IoT Device SDK for Python



ここからPythonのプログラムを作成していきます。
AWS IoT Device SDK for Python
こちらのライブラリをインストール。


$ pip3 install AWSIoTPythonSDK



バージョン1.4.0がインストールできました。

basicPubSub.py
こちらのサンプルを参考に、AWSコンソールから送信されたメッセージを受信する
プログラムを作成してみます。

configureEndpointで指定している接続ポイントは、
管理コンソールの「設定」で確認できます。

905_15.png

configureCredentialsは、ダウンロードしておいた
・rootCA.pem
・xxxxxxxxxxxx-private.pem.key
・xxxxxxxxxxxx-certificate.pem.crt
へのファイルパスを指定します。


  1. # -*- coding:utf8 -*-
  2. from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
  3. import time
  4. import json
  5. def customCallback(client, userdata, message):
  6.     print('Received a new message: ')
  7.     print(message.payload)
  8.     print('from topic: ')
  9.     print(message.topic)
  10.     print('--------------\n\n')
  11. # For certificate based connection
  12. myMQTTClient = AWSIoTMQTTClient('myClientID') # 適当な値でOK
  13. myMQTTClient.configureEndpoint('xxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com', 8883) # 管理画面で確認
  14. myMQTTClient.configureCredentials('rootCA.pem', 'xxxxxxxxxxxx-private.pem.key', 'xxxxxxxxxxxx-certificate.pem.crt')
  15. myMQTTClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing
  16. myMQTTClient.configureDrainingFrequency(2) # Draining: 2 Hz
  17. myMQTTClient.configureConnectDisconnectTimeout(10) # 10 sec
  18. myMQTTClient.configureMQTTOperationTimeout(5) # 5 sec
  19. myMQTTClient.connect()
  20. while True:
  21.     myMQTTClient.subscribe("myTopic", 1, customCallback)
  22.     time.sleep(1)




作成したプログラムを動かしておきます。


$ python3 sample.py



AWSコンソールのテストから、待ち受けている「myTopic」に対してメッセージを送信してみます。

905_16.png


受信できました。

905_17.png



メッセージの送信



送信も試してみます。
subscribeをpublishに変更し、メッセージを送信。


  1. # -*- coding:utf8 -*-
  2. from AWSIoTPythonSDK.MQTTLib import AWSIoTMQTTClient
  3. import time
  4. import json
  5. def customCallback(client, userdata, message):
  6.     print('Received a new message: ')
  7.     print(message.payload)
  8.     print('from topic: ')
  9.     print(message.topic)
  10.     print('--------------\n\n')
  11. # For certificate based connection
  12. myMQTTClient = AWSIoTMQTTClient('myClientID') # 適当な値でOK
  13. myMQTTClient.configureEndpoint('xxxxxxxxxxxx.iot.ap-northeast-1.amazonaws.com', 8883) # 管理画面で確認
  14. myMQTTClient.configureCredentials('rootCA.pem', 'xxxxxxxxxxxx-private.pem.key', 'xxxxxxxxxxxx-certificate.pem.crt')
  15. myMQTTClient.configureOfflinePublishQueueing(-1) # Infinite offline Publish queueing
  16. myMQTTClient.configureDrainingFrequency(2) # Draining: 2 Hz
  17. myMQTTClient.configureConnectDisconnectTimeout(10) # 10 sec
  18. myMQTTClient.configureMQTTOperationTimeout(5) # 5 sec
  19. myMQTTClient.connect()
  20. while True:
  21.     #myMQTTClient.subscribe("myTopic", 1, customCallback)
  22.     myMQTTClient.publish("myTopic", json.dumps({'message' : 'from python!'}), 1)
  23.     time.sleep(1)



AWSコンソールで、「myTopic」をサブスクライブ。

905_18.png

待受状態となります。

905_19.png

プログラムを実行すると、もりもりメッセージが届きます。

905_20.png

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/07/02(月) 22:12:01|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

DynamoDB データのインクリメント、デクリメント(アトミックカウンター)

UbuntuでDynamoDB Localを動かし、boto3で接続してみました。
DynamoDB LocalにPython(boto3)でテーブルの作成、データの登録

今回は、チュートリアルの「アトミックカウンター」を試してみます。
ステップ 3.4: アトミックカウンターを増分する


サンプルデータの登録



サンプルデータ登録用に、こんなプロクラムを作成して実行しておきました。


  1. # -*- coding:utf-8 -*-
  2. import boto3
  3. # 接続
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. # テーブル作成
  12. table = dynamodb.create_table(
  13.     TableName='Sample',
  14.     KeySchema=[
  15.         {
  16.             'AttributeName': 'id',
  17.             'KeyType': 'HASH' #Partition key
  18.         },
  19.         {
  20.             'AttributeName': 'team',
  21.             'KeyType': 'RANGE' #Sort key
  22.         }
  23.     ],
  24.     AttributeDefinitions=[
  25.         {
  26.             'AttributeName': 'id',
  27.             'AttributeType': 'N'
  28.         },
  29.         {
  30.             'AttributeName': 'team',
  31.             'AttributeType': 'S'
  32.         },
  33.     ],
  34.     ProvisionedThroughput={
  35.         'ReadCapacityUnits': 10,
  36.         'WriteCapacityUnits': 10
  37.     }
  38. )
  39. print("Table status:", table.table_status)
  40. # データ登録
  41. table.put_item(
  42.     Item={
  43.         'id': 1,
  44.         'team': 'あんこう',
  45.         'members': ['西住 みほ', '武部 沙織', '五十鈴 華', '秋山 優花里', '冷泉 麻子'],
  46.         'defeat_count' : 0
  47.     }
  48. )
  49. table.put_item(
  50.     Item={
  51.         'id': 2,
  52.         'team': 'カメ',
  53.         'members': ['角谷 杏', '小山 柚子', '河嶋 桃'],
  54.         'defeat_count' : 0
  55.     }
  56. )
  57. table.put_item(
  58.     Item={
  59.         'id': 3,
  60.         'team': 'アヒル',
  61.         'members': ['磯辺 典子', '近藤 妙子', '河西 忍', '佐々木 あけび'],
  62.         'defeat_count' : 0
  63.     }
  64. )
  65. table.put_item(
  66.     Item={
  67.         'id': 4,
  68.         'team': 'カバ',
  69.         'members': ['カエサル', 'エルヴィン', '左衛門佐', 'おりょう'],
  70.         'defeat_count' : 0
  71.     }
  72. )





アトミックカウンター



id:1のdefeat_countを増加させてみます。


  1. # -*- coding:utf-8 -*-
  2. import boto3
  3. # 接続
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. # テーブル取得
  12. table = dynamodb.Table('Sample')
  13. # defeat_countをインクリメント
  14. response = table.update_item(
  15.     Key={
  16.         'id': 1,
  17.         'team': 'あんこう'
  18.     },
  19.     UpdateExpression='set defeat_count = defeat_count + :val',
  20.     ExpressionAttributeValues={
  21.         ':val': 1
  22.     },
  23.     ReturnValues='UPDATED_NEW'
  24. )
  25. print('UpdateItem succeeded:')
  26. print(response)




実行結果


$ python3 sample.py
UpdateItem succeeded:
{'Attributes': {
    'defeat_count': Decimal('1')
},
'ResponseMetadata': {
    'RequestId': '2a2f4d43-71be-42d4-a2b4-61d9df46d1a8',
    'HTTPStatusCode': 200,
    'HTTPHeaders': {
        'content-type': 'application/x-amz-json-1.0',
        'x-amz-crc32': '2351066368',
        'x-amzn-requestid': '2a2f4d43-71be-42d4-a2b4-61d9df46d1a8',
        'content-length': '41',
        'server': 'Jetty(8.1.12.v20130726)'
},
'RetryAttempts': 0}
}



もう一度実行すると、

'defeat_count': Decimal('2')


となります。


同じ要領で、今度は数字を減らしてみます。


  1. # -*- coding:utf-8 -*-
  2. import boto3
  3. # 接続
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. # テーブル取得
  12. table = dynamodb.Table('Sample')
  13. # defeat_countをインクリメント
  14. response = table.update_item(
  15.     Key={
  16.         'id': 1,
  17.         'team': 'あんこう'
  18.     },
  19.     UpdateExpression='set defeat_count = defeat_count - :val',
  20.     ExpressionAttributeValues={
  21.         ':val': 1
  22.     },
  23.     ReturnValues='UPDATED_NEW'
  24. )
  25. print('UpdateItem succeeded:')
  26. print(response)



実行すると、defeat_countが1つ減っているのが確認できました。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/25(月) 22:31:18|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

DynamoDB LocalにPython(boto3)でテーブルの作成、データの登録

DynamoDBのデバッグ用サーバー「DynamoDB Local」を動かしてみました。
Ubuntu 18.04でDynamoDB Localを動作させる

Python + boto3でテーブルの作成やデータの登録を試してみます。


boto3のインストール



boto3はpipでインストールしました。


$ pip3 install boto3





ステップ 1: テーブルを作成する



こちらのチュートリアルを参考に写経していきます。

https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.01.html

テーブルを作成するプログラムはこうなりました。


  1. # -*- coding:utf-8 -*-
  2. import boto3
  3. dynamodb = boto3.resource(
  4.     'dynamodb',
  5.     region_name='ap-northeast-1.',
  6.     endpoint_url="http://192.168.1.102:8000",
  7.     aws_access_key_id='ACCESS_ID',
  8.     aws_secret_access_key='ACCESS_KEY'
  9. )
  10. table = dynamodb.create_table(
  11.     TableName='Movies',
  12.     KeySchema=[
  13.         {
  14.             'AttributeName': 'year',
  15.             'KeyType': 'HASH' #Partition key
  16.         },
  17.         {
  18.             'AttributeName': 'title',
  19.             'KeyType': 'RANGE' #Sort key
  20.         }
  21.     ],
  22.     AttributeDefinitions=[
  23.         {
  24.             'AttributeName': 'year',
  25.             'AttributeType': 'N'
  26.         },
  27.         {
  28.             'AttributeName': 'title',
  29.             'AttributeType': 'S'
  30.         },
  31.     ],
  32.     ProvisionedThroughput={
  33.         'ReadCapacityUnits': 10,
  34.         'WriteCapacityUnits': 10
  35.     }
  36. )
  37. print("Table status:", table.table_status)




ローカルのDynamoDBに対して実行するので、
・region_name
・aws_access_key_id
・aws_secret_access_key
これらの項目は本来不要なのですが、boto3が要求するので、適当な値を入れておきます。

ちなみに、region_nameを指定しなかった場合は、


botocore.exceptions.NoRegionError: You must specify a region.



aws_access_key_id、aws_secret_access_keyを指定しなかった場合は、


botocore.exceptions.NoCredentialsError: Unable to locate credentials



このようなエラーが発生します。

プログラムを実行すると、「Table status: ACTIVE」という応答が得られました。


$ python3 sample.py
Table status: ACTIVE



awsコマンドでも確認してみます。


$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": [
        "Movies"
    ]
}



テーブルが作成されていることが確認できました。



ステップ 2: サンプルデータをロードする



https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.02.html

サンプルでは、ファイルを読み込んでデータを登録していますが、
1件だけ登録するプログラムに変更しました。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. year = 2013
  13. title = 'Turn It Down, Or Else!'
  14. info = {
  15.     'directors' : [
  16.         'Alice Smith',
  17.         'Bob Jones'
  18.     ],
  19.     'release_date' : '2013-01-18T00:00:00Z',
  20.     'rating' : decimal.Decimal('6.2'),
  21.     'genres' : [
  22.         'Comedy',
  23.         'Drama'
  24.     ],
  25.     'image_url' : 'http://ia.media-imdb.com/images/N/O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg',
  26.     'plot' : 'A rock band plays their music at high volumes, annoying the neighbors.',
  27.     'rank' : 11,
  28.     'running_time_secs' : 5215,
  29.     'actors' : [
  30.         'David Matthewman',
  31.         'Ann Thomas',
  32.         'Jonathan G. Neff'
  33.     ]
  34. }
  35. table.put_item(
  36.     Item={
  37.         'year': year,
  38.         'title': title,
  39.         'info': info,
  40.     }
  41. )



ポイントは、小数点を含む値の登録。
何も考えずfloat値を指定すると、以下のエラーが発生します。


TypeError: Float types are not supported. Use Decimal types instead.



こちらを参考に、Decimalに変換して指定してやります。
How can I store 30.40 in DynamoDb?




ステップ 3.2: 項目を読み取る



>https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.03.html

登録したデータを検索してみます。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. title = 'Turn It Down, Or Else!'
  13. year = 2013
  14. try:
  15.     response = table.get_item(
  16.         Key={
  17.             'year': year,
  18.             'title': title
  19.         }
  20.     )
  21. except ClientError as e:
  22.     print(e.response['Error']['Message'])
  23. else:
  24.     item = response['Item']
  25.     print('GetItem succeeded:')
  26.     print(item)




実行結果です。
(json部分は整形しています)


$ python3 sample.py
GetItem succeeded:
{
    'title': 'Turn It Down, Or Else!',
    'year': Decimal('2013'),
    'info': {
        'actors': ['David Matthewman', 'Ann Thomas', 'Jonathan G. Neff'],
        'release_date': '2013-01-18T00:00:00Z',
        'plot': 'A rock band plays their music at high volumes, annoying the neighbors.',
        'genres': ['Comedy', 'Drama'],
        'image_url': 'http://ia.media-imdb.com/images/N/O9ERWAU7FS797AJ7LU8HN09AMUP908RLlo5JF90EWR7LJKQ7@@._V1_SX400_.jpg',
        'directors': ['Alice Smith', 'Bob Jones'],
        'rating': Decimal('6.2'),
        'rank': Decimal('11'),
        'running_time_secs': Decimal('5215')
    }
}






ステップ 3.3: 項目を更新する




  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. title = 'Turn It Down, Or Else!'
  13. year = 2013
  14. try:
  15.     response = table.update_item(
  16.         Key={
  17.             'year': year,
  18.             'title': title
  19.         },
  20.         UpdateExpression='set info.image_url = :url, info.rating=:rate',
  21.         ExpressionAttributeValues={
  22.             ':url' : 'https://www.example.com/image.jpg',
  23.             ':rate' : decimal.Decimal('8.2')
  24.         },
  25.         ReturnValues='UPDATED_NEW'
  26.     )
  27. except ClientError as e:
  28.     print(e.response['Error']['Message'])
  29. else:
  30.     #item = response['Item']
  31.     item = response
  32.     print('UpdateItem succeeded:')
  33.     print(item)



UpdateExpressionで、更新の条件式を指定。
ExpressionAttributeValuesで、条件式に渡す値を設定。
...という流れのようです。

実行すると、こんな結果が帰ってきました。
ちゃんと値が更新されています。





ステップ 3.6: 項目を削除する



ちょっと飛ばして、データの削除。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. title = 'Turn It Down, Or Else!'
  13. year = 2013
  14. try:
  15.     response = table.delete_item(
  16.         Key={
  17.             'year': year,
  18.             'title': title
  19.         }
  20.     )
  21. except ClientError as e:
  22.     print(e.response['Error']['Message'])
  23. else:
  24.     #item = response['Item']
  25.     item = response
  26.     print('DeleteItem succeeded:')
  27.     print(item)



実行結果


$ python3 sample.py
DeleteItem succeeded:
{'ResponseMetadata': {
    'RequestId': '6c75f576-7b6c-4590-a1c7-242ed4beee36',
    'HTTPStatusCode': 200,
    'HTTPHeaders': {
        'content-type': 'application/x-amz-json-1.0',
        'x-amz-crc32': '2745614147',
        'x-amzn-requestid': '6c75f576-7b6c-4590-a1c7-242ed4beee36',
        'content-length': '2',
        'server': 'Jetty(8.1.12.v20130726)'
    },
    'RetryAttempts': 0
}}





ステップ 5: (オプション) テーブルを削除する



https://docs.aws.amazon.com/ja_jp/amazondynamodb/latest/developerguide/GettingStarted.Python.05.html

最初に作成したMovieテーブルを削除します。


  1. # -*- coding:utf-8 -*-
  2. import decimal
  3. import boto3
  4. dynamodb = boto3.resource(
  5.     'dynamodb',
  6.     region_name='ap-northeast-1.',
  7.     endpoint_url="http://192.168.1.102:8000",
  8.     aws_access_key_id='ACCESS_ID',
  9.     aws_secret_access_key='ACCESS_KEY'
  10. )
  11. table = dynamodb.Table('Movies')
  12. table.delete()



awsコマンドで確認します。


$ aws dynamodb list-tables --endpoint-url http://localhost:8000
{
    "TableNames": []
}




次は、今回飛ばした
・ステップ 3.4: アトミックカウンターを増分する
・ステップ 3.5: 項目を更新する (条件付き)
・ステップ 4: データをクエリおよびスキャンする
を試してみようと思います。

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/24(日) 19:29:39|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

MQTTクライアントpahoでmosquittoに接続する(Python使用)

MQTTブローカー mosquittoをインストールしてみました。
MQTTブローカー mosquittoをUbuntu 18.04へインストールする

Pythonで操作してみます。

paho



https://www.eclipse.org/paho/

各種言語のライブラリが公開されています。
https://www.eclipse.org/paho/downloads.php

今回はPythonのライブラリを使ってみることにしました。
https://github.com/eclipse/paho.mqtt.python


$ pip3 install paho-mqtt




送信側のソース

・publisher.py


  1. # -*- coding:utf-8 -*-
  2. import paho.mqtt.client as mqtt
  3. client = mqtt.Client()
  4. client.connect('192.168.1.102', 1883, keepalive=60)
  5. client.publish('test/topic', 'hello world')




受信側のソース

・subscriber.py


  1. # -*- coding:utf-8 -*-
  2. import paho.mqtt.client as mqtt
  3. def on_connect(client, userdata, flags, respons_code):
  4.     topic = 'test/topic'
  5.     print('watch %s' % topic)
  6.     client.subscribe(topic)
  7. def on_message(client, userdata, msg):
  8.     print(msg.topic + ' ' + str(msg.payload))
  9. client = mqtt.Client()
  10. client.on_connect = on_connect
  11. client.on_message = on_message
  12. client.connect('192.168.1.102', 1883, keepalive=60)
  13. client.loop_forever()




受信側のプログラムを起動しておきます。


$ python3 subscriber.py
watch test/topic



送信側のプログラムを実行。


$ python3 publisher.py



受信側のコンソールがこんな表示になるはずです。

903_01.png




トピックのワイルドカード指定



トピックは[項目1]/[項目2]/[項目3]/...のようにスラッシュで分類するのが作法です。
こうしておくことで、監視するトピック名をワイルドカードで指定できるようになります。


+/[項目2]



前半は何でも良いので、後半は[項目2]にマッチするもの。


[項目1]/#



後半は何でも良いので、前半は項目1にマッチするのも。

サンプルを書き換えて試してみます。

・publisher.py


  1. # -*- coding:utf-8 -*-
  2. import paho.mqtt.client as mqtt
  3. client = mqtt.Client()
  4. client.connect('192.168.1.102', 1883, keepalive=60)
  5. client.publish('test/topic', 'hello world')
  6. client.publish('test/any', 'hello world')
  7. client.publish('any/topic', 'hello world')




・subscriber.py


  1. # -*- coding:utf-8 -*-
  2. import sys
  3. import paho.mqtt.client as mqtt
  4. def on_connect(client, userdata, flags, respons_code):
  5.     print('watch %s' % topic)
  6.     client.subscribe(topic)
  7. def on_message(client, userdata, msg):
  8.     print(msg.topic + ' ' + str(msg.payload))
  9. topic = sys.argv[1]
  10. client = mqtt.Client()
  11. client.on_connect = on_connect
  12. client.on_message = on_message
  13. client.connect('192.168.1.102', 1883, keepalive=60)
  14. client.loop_forever()




狙い通りの実行結果です。

903_02.gif



Retain



subscriberを起動していないときにpublisherから送信されたメッセージを
知ることはできません。

Retainを指定しておけば、publisherから送信された最後の1件の
メッセージを取得できるようになります。

・publisher.py


  1. # -*- coding:utf-8 -*-
  2. import paho.mqtt.client as mqtt
  3. client = mqtt.Client()
  4. client.connect('192.168.1.102', 1883, keepalive=60)
  5. client.publish('test/topic', 'hello', retain=True)
  6. client.publish('test/topic', 'world', retain=True)
  7. client.publish('test/topic', 'last message', retain=True)




publisherを実行した後、subscriberを実行してみます。


$ python3 subscriber.py test/topic
watch test/topic
test/topic b'last message'



最後のメッセージが取得できました。


【参考URL】
IoT時代のプログラミング(主にMQTTについて)
初めての MQTT
https://github.com/eclipse/paho.mqtt.python

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/24(日) 16:56:30|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集

Python + OpenCV3 指定領域のノイズを修復する(Inpaint)

画像内に写り込んだ不要なものやノイズを除去したい場合は、
OpenCVの「Inpaint」を使えば良いことを知りました。

画像内の不要部分を取り除き、修復する(OpenCV / iOS)
その他の画像変換
Image Inpainting

早速試してみます。


画像の準備



元画像

891_01.png

適当に落書きします。
・noize.png

891_02.png

落書きした箇所を白で塗りつぶし。
ここが修復を行う範囲になります。

891_03.png

修復を行わない箇所は黒塗りに変換。
・filter.png

891_04.png

これで準備は整いました。


サンプル



プログラムは至って簡単。
用意したノイズ入りの画像とフィルター画像をinpaintに指定するだけです。


  1. # -*- coding:utf-8 -*-
  2. import cv2 as cv
  3. def main():
  4.     # ファイルを読み込み
  5.     img = cv.imread('noize.png', cv.IMREAD_COLOR)
  6.     mask = cv.imread('filter.png', cv.IMREAD_GRAYSCALE)
  7.     # 修復実行
  8.     dst = cv.inpaint(img, mask, 3, cv.INPAINT_TELEA)
  9.     #dst = cv.inpaint(img, mask, 3, cv.INPAINT_NS)
  10.     
  11.     cv.imwrite('result.png', dst)
  12.         
  13.     
  14. if __name__ == '__main__':
  15.     main()




INPAINT_TELEAを指定した場合の結果。

891_05.png


INPAINT_NSを指定した場合の結果。

891_06.png

近傍円形領域の半径を15とした場合
dst = cv.inpaint(img, mask, 15, cv.INPAINT_TELEA)

891_07.png


【参考URL】
画像内の不要部分を取り除き、修復する(OpenCV / iOS)
その他の画像変換
Image Inpainting

テーマ:プログラミング - ジャンル:コンピュータ

  1. 2018/06/14(木) 23:38:11|
  2. Python
  3. | トラックバック:0
  4. | コメント:0
  5. | 編集
次のページ