aircampro

enocean to various cloud python

Jul 7th, 2023 (edited)
109
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
Python 38.76 KB | Source Code | 0 0
  1. #!/usr/bin/python3
  2. #
  3. # client is publishing enocean sensors to various listed iOt telemetry or email or sms text message
  4. # subscriber sister application is to read this from the mosquito broker for example if you are doing the mqtt internally on raspberry pi 4
  5. #
  6. # import neccessary libraries
  7. import paho.mqtt.client as mqtt
  8. import requests
  9. import json
  10. import base64
  11. import serial
  12. import time
  13. from sys import exit
  14. from datetime import datetime
  15.  
  16. # enocean
  17. PORT = '/dev/ttyUSB400J'              # USB400J The name of the device to which it is connected
  18. SENSORID1 = '04:01:53:e1'             # ID of the 1st STM-431J
  19. SENSORID2 = '04:00:6f:e5'             # ID of the 2nd STM-431J
  20. s_port = 0                            # serial port number handle
  21. BAUD_RT = 57600                       # serial baud rate
  22.  
  23. # soracom
  24. URL = 'http://harvest.soracom.io/'    # SORACOM HarvestのURL
  25.  
  26. # mosquito
  27. MTOPIC = "topic/B/"
  28. MQTT_PORT = 1883
  29. KEEP_ALIVE = 60
  30.  
  31. # beebotte
  32. TOKEN = "[BeebotteTKName]"
  33. HOSTNAME = "mqtt.beebotte.com"
  34. BPORT = 8883
  35. BTOPIC = "MyEnOceanSensors/temperature"                    # beebotte channel/resource
  36. CACERT = "mqtt.beebotte.com.pem"
  37.  
  38. # ubidots
  39. # pip install ubidots==1.6.6
  40. # sudo apt-get install python-setuptools
  41. UBI_URL=https://industrial.api.ubidots.com/api/v1.6
  42.  
  43. # machinist
  44. MAPIKEY = "xxxxxx"
  45. MUrl = "https://gw.machinist.iij.jp/endpoint"
  46.  
  47. # aws
  48. AWS_TOPIC_NAME = "my/temperatures"
  49. AWS_CLIENT="iot-data"
  50.  
  51. # azure
  52. AZURE_TYPE = "connection_string"          # choose connection_string or provisioning_host
  53. AZURE_CONN_STR="yourConnectionString"
  54. # ensure environment variables are set for your device and IoT Central application credentials
  55. PROVISIONING_HOST = "your host"
  56. ID_SCOPE = "your_scope"
  57. DEVICE_ID = "your_device"
  58. DEVICE_KEY = "your_key"
  59. provisioning_host = PROVISIONING_HOST
  60. id_scope = ID_SCOPE
  61. registration_id = DEVICE_ID
  62. symmetric_key = DEVICE_KEY
  63.  
  64. # yandex
  65. YPORT=8443
  66. YHOST="rc1c-xxxx123456.mdb.yandexcloud.net"
  67. YCERTNAME="your_cert_name" 
  68. YUrl=r'https://api.iot.yandex.net/v1.0/devices/actions'
  69. YAPI_KEY="xxxxxx"
  70. import datetime
  71. import pytz
  72.  
  73. # smtp
  74. smtp_server = "smtp.gmail.com"
  75. port = 587
  76.  
  77. # ssl server with tls_set
  78. SSLHOST, SSLPORT = "127.0.0.1", 12345
  79. # ssl23
  80. SSL_URL = '127.0.0.1'
  81. SSL_PORT = 10023
  82.  
  83. # cloud MQTT
  84. CHOSTNAME = "driver.cloudmqtt.com"
  85. CPORT = 28607
  86. CTOPIC = "pi/sub2"                    
  87. CCACERT = "/etc/ssl/certs/ca-certificates.crt"
  88.  
  89. #define a global MQTT Topic which will be set upon choices
  90. GTOPIC=" "
  91.        
  92. # ------------ here list the choices and options for iOt -----------------      
  93. TELEM_CHOICES=[ "soracom", "beebotte", "mosquito", "ubidots", "machinist", "aws", "azure", "yandex", "twillio", "smtp_email", "ssl_tls_server", "ssl_23_server", "cloud_mqtt", "gcs_blob", "splunk" ]
  94. SORACOM=0
  95. BEEBOTTE=1
  96. MOSQUITO=2
  97. UBIDOTS=3
  98. MACHINIST=4
  99. AWS=5
  100. AZURE=6
  101. YANDEX=7
  102. TWILLIO=8
  103. SMTP_EMAIL=9
  104. SSL_TLS_SERVER=10
  105. SSL_23_SERVER=11
  106. CLOUD_MQTT=12
  107. BLOB_GCS=13
  108. SPLUNK=14
  109. # ============= make your choice of cloud service here from list above ==================
  110. MY_CURRENT_TELEM=TELEM_CHOICES[SORACOM]
  111.  
  112. # if you want to use AES with SSLv23
  113. AES_ENCRYPT=0
  114.  
  115. # Broker processes when connected to
  116. def on_connect(client, userdata, flag, rc):
  117.     print("Connect Broker:" + str(rc))
  118.     client.subscribe(GTOPIC)
  119.  
  120. # Broker processes when disconnected
  121. def on_disconnect(client, userdata, rc):
  122.     if rc != 0:
  123.         print("disconnect broker")
  124.  
  125. # publish processes when publish done
  126. def on_publish(client, userdata, mid):
  127.     print("publish Done")
  128.  
  129. # This function reads 1 byte of data from the serial port and parses the EnOcean telegram. After analyzing
  130. # Telegram, data is sent to the chosen iOt system
  131. def Enocean2Telemetry(s_port,telem_opt):
  132.  
  133.     # SORACOM Harvest。
  134.     def sendDataSoraCom(string1, temp_data1, string2, temp_data2):
  135.         headers = {'content-type': 'application/json'}
  136.         payload = {string1:temp_data1}
  137.         print payload
  138.         try:
  139.             req = requests.post(URL, data=json.dumps(payload), headers=headers)
  140.             req.raise_for_status()
  141.         except requests.exceptions.HTTPError as errh:
  142.             print ("Http Error:",errh)
  143.         except requests.exceptions.ConnectionError as errc:
  144.             print ("Error Connecting:",errc)
  145.         except requests.exceptions.Timeout as errt:
  146.             print ("Timeout Error:",errt)
  147.         except requests.exceptions.RequestException as err:
  148.             print ("OOps: Something Else",err)
  149.         headers = {'content-type': 'application/json'}
  150.         payload = {string2:temp_data2}
  151.         print payload
  152.         try:
  153.             req = requests.post(URL, data=json.dumps(payload), headers=headers)
  154.             req.raise_for_status()
  155.         except requests.exceptions.HTTPError as errh:
  156.             print ("Http Error:",errh)
  157.         except requests.exceptions.ConnectionError as errc:
  158.             print ("Error Connecting:",errc)
  159.         except requests.exceptions.Timeout as errt:
  160.             print ("Timeout Error:",errt)
  161.         except requests.exceptions.RequestException as err:
  162.             print ("OOps: Something Else",err)
  163.  
  164.     # SPLUNK
  165.     def sendDataSplunk(string1, temp_data1, string2, temp_data2):
  166.         splunk_config = {
  167.             "wifi": {
  168.                 "ssid": "WIFI SID",
  169.                 "password": "WIFI YOUR_PASSWD"
  170.             },
  171.             "hec": {
  172.                 "url": "http://SplunkMY_IDIP:8088/services/collector/event",
  173.                 "token": "HTTP Event Collector YOUR_TOKEN",
  174.                 "hostname": "MySplunkServer"
  175.             }
  176.         }
  177.         url = splunk_config['hec']['url']
  178.         token = splunk_config['hec']['token']
  179.         host = splunk_config['hec']['hostname']
  180.         data_val = { "values" : [ {"metric_name" : string1, "sensor" : SENSORID1, "_value" : temp_data1}, {"metric_name" : string2 , "sensor" : SENSORID2, "_value" : temp_data2} ] }
  181.         source=None
  182.         index=None
  183.         timestamp=round(datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())
  184.        
  185.         u'Send measured data to Splunk HEC'
  186.         headers = {'Authorization': 'Splunk {}'.format(token)}
  187.         payload = []
  188.         #for data in values:
  189.         for cnt in range(len(data_val['values'])):
  190.             p = {
  191.                 "event": "metric",
  192.                 "source": source if source is not None else data_val['values'][int(cnt)]['sensor'],
  193.                 "host": host,
  194.                 "fields": {
  195.                     "metric_name": data_val['values'][int(cnt)]['metric_name'],
  196.                     "sensor": data_val['values'][int(cnt)]['sensor'],
  197.                     "_value": data_val['values'][int(cnt)]['_value'],
  198.                 }
  199.             }
  200.             if index is not None:
  201.                 p['index'] = index
  202.             if timestamp is not None:
  203.                 p['time'] = timestamp
  204.             payload.append(p)
  205.  
  206.         print("[DEBUG] HEC payload", payload)
  207.         try:
  208.             res = requests.post(url, headers=headers, data=json.dumps(payload))
  209.             req.raise_for_status()
  210.         except requests.exceptions.HTTPError as errh:
  211.             print ("Http Error:",errh)
  212.         except requests.exceptions.ConnectionError as errc:
  213.             print ("Error Connecting:",errc)
  214.         except requests.exceptions.Timeout as errt:
  215.             print ("Timeout Error:",errt)
  216.         except requests.exceptions.RequestException as err:
  217.             print ("OOps: Something Else",err)
  218.    
  219.     # MOSQUITO
  220.     def sendDataMosquito(string1, enO_temp_value1, string2, enO_temp_value2):
  221.         msg = string1 + enO_temp_value1
  222.         client.publish(MTOPIC,msg)
  223.         msg = string2 + enO_temp_value2
  224.         client.publish(MTOPIC,msg)
  225.         client.disconnect()
  226.        
  227.     # BEEBOTTE
  228.     def sendDataBeebotte(string1, enO_temp_value1, string2, enO_temp_value2):
  229.         msg = string1 + enO_temp_value1
  230.         client.publish(BTOPIC,msg)
  231.         msg = string2 + enO_temp_value2
  232.         client.publish(BTOPIC,msg)
  233.         client.disconnect()
  234.  
  235.     # CLOUD MQTT
  236.     def sendDataCloudMqtt(string1, enO_temp_value1, string2, enO_temp_value2):
  237.         msg = string1 + enO_temp_value1
  238.         client.publish(CTOPIC,msg,0)
  239.         msg = string2 + enO_temp_value2
  240.         client.publish(CTOPIC,msg,0)
  241.         client.disconnect()
  242.        
  243.     # AWS
  244.     def sendDataAws(string1, enO_temp_value1, string2, enO_temp_value2):
  245.         data = {
  246.             "temp1": enO_temp_value1,
  247.             "temp1_desc": string1,
  248.             "temp2": enO_temp_value2,
  249.             "temp2_desc": string2,
  250.         }
  251.         json_data = bytes(json.dumps(data),"utf-8")
  252.         print(f"sending to aws -> {sys.getsizeof(json_data)} bytes")
  253.         client = boto3.client(AWS_CLIENT)
  254.         client.publish(topic=AWS_TOPIC_NAME, payload=json_data)
  255.        
  256.     # UBIDOTS
  257.     def sendDataUbiDots(string1, temp_data1, string2, temp_data2):
  258.        try:
  259.            my_variable = api.get_variable('56799cf1231b28459f976417')
  260.        except UbidotsError400 as e:
  261.            print("General Description: %s; and the detail: %s" % (e.message, e.detail))
  262.        except UbidotsForbiddenError as e:
  263.            print("For some reason my account does not have permission to read this variable")
  264.            print("General Description: %s; and the detail: %s" % (e.message, e.detail))
  265.         payload = {string1:int(temp_data1)}
  266.         print payload
  267.         new_value = my_variable.save_value(payload)
  268.         try:
  269.             my_variable2 = api.get_variable('56799cf1031b28459f976718')
  270.         except UbidotsError400 as e:
  271.             print("General Description: %s; and the detail: %s" % (e.message, e.detail))
  272.         except UbidotsForbiddenError as e:
  273.             print("For some reason my account does not have permission to read this variable")
  274.             print("General Description: %s; and the detail: %s" % (e.message, e.detail))
  275.         payload = {string2:int(temp_data2)}
  276.         print payload
  277.         new_value = my_variable2.save_value(payload)
  278.  
  279.     # AZURE
  280.     def sendDataAzure(descrip1,temp_data1,descrip2,temp_data2):
  281.         print("Sending telemetry for temperature to azure")
  282.         temperature_msg = {descrip1 : temp_data1}
  283.         msg = Message(json.dumps(temperature_msg))
  284.         msg.content_encoding = "utf-8"
  285.         msg.content_type = "application/json"
  286.         print("Send message : ",msg)
  287.         device_client.send_message(msg)
  288.         temperature_msg1 = {descrip2 : temp_data2}
  289.         msg1 = Message(json.dumps(temperature_msg1))
  290.         msg1.content_encoding = "utf-8"
  291.         msg1.content_type = "application/json"
  292.         print("Send message : ",msg1)
  293.         device_client.send_message(msg1)
  294.         device_client.disconnect()
  295.         device_client.shutdown()
  296.        
  297.     # sub functions to store certs in azure key vaalts and may be useful for management of certs
  298.     #
  299.     def createCertAzure():
  300.         from azure.identity import DefaultAzureCredential
  301.         from azure.keyvault.certificates import CertificateClient, CertificatePolicy
  302.         credential = DefaultAzureCredential()
  303.         certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
  304.         create_certificate_poller = certificate_client.begin_create_certificate(certificate_name="cert-name", policy=CertificatePolicy.get_default())
  305.         print(create_certificate_poller.result())
  306.     def getLatestCertAzure():
  307.         from azure.identity import DefaultAzureCredential
  308.         from azure.keyvault.certificates import CertificateClient
  309.         credential = DefaultAzureCredential()
  310.         certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
  311.         certificate = certificate_client.get_certificate("cert-name")
  312.         print(certificate.name)
  313.         print(certificate.properties.version)
  314.         print(certificate.policy.issuer_name)
  315.     def updateCertAzure():
  316.         from azure.identity import DefaultAzureCredential
  317.         from azure.keyvault.certificates import CertificateClient
  318.         credential = DefaultAzureCredential()
  319.         certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
  320.         # we will now disable the certificate for further use
  321.         updated_certificate= certificate_client.update_certificate_properties(certificate_name="cert-name", enabled=False)
  322.     def deleteCertAzure():
  323.         from azure.identity import DefaultAzureCredential
  324.         from azure.keyvault.certificates import CertificateClient
  325.         credential = DefaultAzureCredential()
  326.         certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
  327.         deleted_certificate_poller = certificate_client.begin_delete_certificate("cert-name")
  328.         deleted_certificate = deleted_certificate_poller.result()
  329.         print(deleted_certificate.name)
  330.         print(deleted_certificate.deleted_on)
  331.         print(updated_certificate.name)
  332.         print(updated_certificate.properties.enabled)
  333.     def listCertAzure():
  334.         from azure.identity import DefaultAzureCredential
  335.         from azure.keyvault.certificates import CertificateClient
  336.         credential = DefaultAzureCredential()
  337.         certificate_client = CertificateClient(vault_url="https://my-key-vault.vault.azure.net/", credential=credential)
  338.         certificates = certificate_client.list_properties_of_certificates()
  339.  
  340.         for certificate in certificates:
  341.         # this list doesn't include versions of the certificates
  342.             print(certificate.name)
  343.    
  344.     # YANDEX
  345.     def makeYandexTable(table_name):
  346.  
  347.         statement = f"""CREATE TABLE {table_name} (
  348.        ( telemetry_timestamp timestamp,
  349.          device_nm varchar(200),
  350.          payload varchar(2000)
  351.        );
  352.        """
  353.         return statement
  354.  
  355.     def sendCreateYandexTable(my_query):
  356.    
  357.         timestamp = datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp()  # set the timezone as you wish for your location
  358.         event_ts=round(timestamp)
  359.         insert=  my_query  
  360.    
  361.         data = {
  362.             'ca': YCERTNAME,
  363.  
  364.             'path': '/myHome/', {
  365.                 'database': 'pxc_cloud_db',
  366.                 'query': insert,
  367.             },
  368.             'port': YPORT,
  369.             'hostname': YHOST,
  370.         }
  371.        
  372.         headers = {
  373.             "Content-Type": "application/json",
  374.             "Authorization": f"Api-Key {YAPI_KEY}",
  375.             "User-Agent": "Python3"
  376.         }
  377.  
  378.         senddatajson = json.dumps(data).encode("ascii")
  379.         try:
  380.             req = requests.post(YUrl, data=senddatajson, headers=headers)
  381.             req.raise_for_status()
  382.         except requests.exceptions.HTTPError as errh:
  383.             print ("Http Error:",errh)
  384.         except requests.exceptions.ConnectionError as errc:
  385.             print ("Error Connecting:",errc)
  386.         except requests.exceptions.Timeout as errt:
  387.             print ("Timeout Error:",errt)
  388.         except requests.exceptions.RequestException as err:
  389.             print ("OOps: Something Else",err)
  390.  
  391.     # YANDEX
  392.     def sendDataYandex(descrip1,temp_data1,descrip2,temp_data2):
  393.    
  394.         #msg = json.loads(payload_json)
  395.         #msg_str = json.dumps(msg)
  396.         msg_str = temp_data1
  397.         timestamp = datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp()  # set the timezone as you wish for your location
  398.         event_ts=round(timestamp)
  399.         insert=  f"""INSERT INTO pxc_cloud_db.timeseries_example (telemetry_timestamp , device_nm , payload) VALUES ('{event_ts}','{descrip1}', '{msg_str}')"""
  400.    
  401.         data = {
  402.             'ca': YCERTNAME,
  403.  
  404.             'path': '/myHome/', {
  405.                 'database': 'pxc_cloud_db',
  406.                 'query': insert,
  407.             },
  408.             'port': YPORT,
  409.             'hostname': YHOST,
  410.         }
  411.        
  412.         headers = {
  413.             "Content-Type": "application/json",
  414.             "Authorization": f"Api-Key {YAPI_KEY}",
  415.             "User-Agent": "Python3"
  416.         }
  417.  
  418.         senddatajson = json.dumps(data).encode("ascii")
  419.         try:
  420.             req = requests.post(YUrl, data=senddatajson, headers=headers)
  421.             req.raise_for_status()
  422.         except requests.exceptions.HTTPError as errh:
  423.             print ("Http Error:",errh)
  424.         except requests.exceptions.ConnectionError as errc:
  425.             print ("Error Connecting:",errc)
  426.         except requests.exceptions.Timeout as errt:
  427.             print ("Timeout Error:",errt)
  428.         except requests.exceptions.RequestException as err:
  429.             print ("OOps: Something Else",err)
  430.  
  431.         msg_str = temp_data2
  432.         timestamp = datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp()  # set the timezone as you wish for your location
  433.         event_ts=round(timestamp)
  434.         insert=  f"""INSERT INTO pxc_cloud_db.timeseries_example (telemetry_timestamp , device_nm , payload) VALUES ('{event_ts}','{descrip2}', '{msg_str}')"""
  435.    
  436.         data = {
  437.             'ca': YCERTNAME,
  438.  
  439.             'path': '/myHome/', {
  440.                 'database': 'pxc_cloud_db',
  441.                 'query': insert,
  442.             },
  443.             'port': YPORT,
  444.             'hostname': YHOST,
  445.         }
  446.        
  447.         headers = {
  448.             // 'X-ClickHouse-User': user,
  449.             // 'X-ClickHouse-Key': password,
  450.             "Content-Type": "application/json",
  451.             "Authorization": f"Api-Key {YAPI_KEY}",
  452.             "User-Agent": "Python3"
  453.         }
  454.  
  455.         senddatajson = json.dumps(data).encode("ascii")
  456.         try:
  457.             req = requests.post(YUrl, data=senddatajson, headers=headers)
  458.             req.raise_for_status()
  459.         except requests.exceptions.HTTPError as errh:
  460.             print ("Http Error:",errh)
  461.         except requests.exceptions.ConnectionError as errc:
  462.             print ("Error Connecting:",errc)
  463.         except requests.exceptions.Timeout as errt:
  464.             print ("Timeout Error:",errt)
  465.         except requests.exceptions.RequestException as err:
  466.             print ("OOps: Something Else",err) 
  467.  
  468.     # GCS BLOB UPLOAD
  469.     def uploadBlobGcs(descrip1,temp_data1,descrip2,temp_data2):
  470.         """Writes json to file then uploads csv to the bucket on GCS """
  471.         import csv
  472.         from google.cloud import storage
  473.         destination_blob_name = "your_data_1"
  474.         source_file_name = f'/tmp/{destination_blob_name}'
  475.         bucket_name = 'yourdataalarms'
  476.  
  477.         fieldnames = ['sensor1_desc', 'sensor1_temp', 'sensor2_desc', 'sensor2_temp', 'timestamp']
  478.         json_obj = {}
  479.         json_obj['sensor1_desc'] = descrip1
  480.         json_obj['sensor1_temp'] = temp_data1
  481.         json_obj['sensor2_desc'] = descrip2
  482.         json_obj['sensor2_temp'] = temp_data2
  483.         json_obj['timestamp'] = round(timestamp = datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())
  484.         json_obj['timestamp'] = datetime.datetime.utcfromtimestamp(int(json_obj['timestamp'])//1000).strftime('%Y-%m-%d %H:%M:%S')
  485.         with open(source_file_name, 'w') as f:
  486.             writer = csv.DictWriter(f, fieldnames=fieldnames)
  487.             writer.writeheader()
  488.             writer.writerow(json_obj)
  489.         storage_client = storage.Client()
  490.         bucket = storage_client.bucket(bucket_name)
  491.         blob = bucket.blob(destination_blob_name)
  492.         blob.upload_from_filename(source_file_name)
  493.         print("File {} uploaded to {}.".format(source_file_name, destination_blob_name))
  494.        
  495.     # MACHINIST
  496.     def sendDataMachinist(descrip1,temp_data1,descrip2,temp_data2):
  497.         data = {
  498.             "agent": "GPIO",
  499.             "metrics": [
  500.                 {
  501.                     "name": descrip1,
  502.                     "namespace": "STM-431J Temp Sensor",
  503.                     "data_point": {
  504.                         "value": temp_data1
  505.                     }
  506.                 }
  507.             ]
  508.         }
  509.  
  510.         headers = {
  511.             "Content-Type": "application/json",
  512.             "Authorization": "Bearer " + MAPIKEY,
  513.             "User-Agent": "Python3"
  514.         }
  515.  
  516.         senddatajson = json.dumps(data).encode("ascii")
  517.         try:
  518.             req = requests.post(MUrl, data=senddatajson, headers=headers)
  519.             req.raise_for_status()
  520.         except requests.exceptions.HTTPError as errh:
  521.             print ("Http Error:",errh)
  522.         except requests.exceptions.ConnectionError as errc:
  523.             print ("Error Connecting:",errc)
  524.         except requests.exceptions.Timeout as errt:
  525.             print ("Timeout Error:",errt)
  526.         except requests.exceptions.RequestException as err:
  527.             print ("OOps: Something Else",err)
  528.  
  529.         data2 = {
  530.             "agent": "GPIO",
  531.             "metrics": [
  532.                 {
  533.                     "name": descrip2,
  534.                     "namespace": "STM-431J Temp Sensor",
  535.                     "data_point": {
  536.                         "value": temp_data2
  537.                     }
  538.                 }
  539.             ]
  540.         }
  541.         senddatajson = json.dumps(data2).encode("ascii")
  542.         try:
  543.             req = requests.post(MUrl, data=senddatajson, headers=headers)
  544.             req.raise_for_status()
  545.         except requests.exceptions.HTTPError as errh:
  546.             print ("Http Error:",errh)
  547.         except requests.exceptions.ConnectionError as errc:
  548.             print ("Error Connecting:",errc)
  549.         except requests.exceptions.Timeout as errt:
  550.             print ("Timeout Error:",errt)
  551.         except requests.exceptions.RequestException as err:
  552.             print ("OOps: Something Else",err)
  553.  
  554.     # TWILIO SMS
  555.     def sendTwilioSMS(descrip1,temp_data1,descrip2,temp_data2):
  556.         from twilio.rest import Client
  557.         tw_account_sid = "Account SID"
  558.         tw_auth_teoken = "AUTHTOKEN"
  559.         tw_to_number = "Destination phone number"
  560.         tw_from_number = "Twilio phone number for the trial obtained"
  561.         client = Client(account_sid, auth_teoken)
  562.         ts = round(datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())  # set the timezone as you wish for your location
  563.         bodytext=" got the data at " + ts + " " + descrip1 + " : " + str(temp_data1) + " " + descrip2 + " : " + str(temp_data2)
  564.         message = client.messages.create(body=bodytext,from_=from_number,to=to_number)
  565.         print(message.sid)  
  566.         #return message.sid        
  567.  
  568.     # SMTP EMAIL SERVER
  569.     # to check library classes import inspect then
  570.     # inspect.getmro(MIMEText)
  571.     def sendSMTPemail(descrip1,temp_data1,descrip2,temp_data2):
  572.         import smtplib
  573.         #from email.mime.multipart import MIMEMultipart ---> you can uncomment insted of message = MIMEText(bodytext, "plain", 'utf-8') but i think its okay
  574.         from email.mime.text import MIMEText
  575.         try:
  576.             server = smtplib.SMTP(smtp_server, port)
  577.             server.starttls()
  578.             login_address ="Enter the sender's email address"
  579.             login_password ="Enter password"
  580.             server.login(login_address, login_password)
  581.             #message = MIMEMultipart()
  582.             ts = round(datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())  # set the timezone as you wish for your location
  583.             bodytext=" got the data at " + ts + " " + descrip1 + " : " + str(temp_data1) + " " + descrip2 + " : " + str(temp_data2)
  584.             message = MIMEText(bodytext, "plain", 'utf-8')
  585.             message['Subject']="Email Subject"
  586.             message['From']="your eamil address"
  587.             message['To']="recipient email address"
  588.             #text = MIMEText(bodytext)
  589.             #message.attach(text)
  590.             server.send_message(message)
  591.             server.quit()
  592.         except requests.exceptions.RequestException as err:
  593.             print ("SMTP connect error : ",err)
  594.  
  595.     # ------------- Ciphers / Cryptography -----------------
  596.     # AES_GCM
  597.     def aes_gcm_encrypt(key,iv,text):
  598.         cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
  599.         ciphertext, mac = cipher.encrypt_and_digest(text)
  600.         return ciphertext, mac
  601.     def aes_gcm_decrypt(key,iv,ciphertext,mac):
  602.         plaintext = 0
  603.         cipher = AES.new(key, AES.MODE_GCM, nonce=iv)
  604.         try:
  605.             plaintext = cipher.decrypt_and_verify(ciphertext,mac)
  606.         except (ValueError, KeyError):
  607.             print("Incorrect decryption")
  608.         return plaintext
  609.  
  610.     # CHACHA - POLY1305
  611.     def chacha20_poly1305_encrypt(key,byte_data):
  612.         from Crypto.Cipher import ChaCha20_Poly1305 as cha
  613.         chacha20 = cha.new(key=key)
  614.         cipher_text, mac = chacha20.encrypt_and_digest(byte_data)
  615.         nonce = chacha20.nonce
  616.         print('cipher_text: ', cipher_text)
  617.         print('mac: ', mac)
  618.         return cipher_text,nonce
  619.     def chacha20_poly1305_decrypt(key,nonce,mac,cipher_text):
  620.         from Crypto.Cipher import ChaCha20_Poly1305 as cha
  621.         decrypt_data="no data"
  622.         try:
  623.             chacha_poly = cha.new(key=key, nonce=nonce)
  624.             decrypt_data = chacha_poly.decrypt_and_verify(cipher_text, mac)
  625.             print('The message is: ', decrypt_data)
  626.         except:
  627.             print("The message couldn't be verified")  
  628.         return decrypt_data      
  629.        
  630.     # RSA_cryptography (Rivest-Shamir-Adleman)
  631.     def RSA_encrypt(message, ):
  632.         from Crypto.Cipher import PKCS1_OAEP
  633.         from Crypto.PublicKey import RSA
  634.         from binascii import hexlify
  635.         #Generating private key (RsaKey object) of key length of 1024 bits
  636.         private_key = RSA.generate(1024)
  637.         #Generating the public key (RsaKey object) from the private key
  638.         public_key = private_key.publickey()
  639.         print(type(private_key), type(public_key))
  640.         #Converting the RsaKey objects to string
  641.         private_pem = private_key.export_key().decode()
  642.         public_pem = public_key.export_key().decode()
  643.         print(type(private_pem), type(public_pem))
  644.         #Writing down the private and public keys to 'pem' files
  645.         with open('private_pem.pem', 'w') as pr:
  646.             pr.write(private_pem)
  647.         with open('public_pem.pem', 'w') as pu:
  648.             pu.write(public_pem)
  649.         #Importing keys from files, converting it into the RsaKey object  
  650.         pr_key = RSA.import_key(open('private_pem.pem', 'r').read())
  651.         pu_key = RSA.import_key(open('public_pem.pem', 'r').read())
  652.         print(type(pr_key), type(pu_key))
  653.         #Instantiating PKCS1_OAEP object with the public key for encryption
  654.         cipher = PKCS1_OAEP.new(key=pu_key)
  655.         #Encrypting the message with the PKCS1_OAEP object
  656.         cipher_text = cipher.encrypt(message.encode('UTF-8'))
  657.         print(cipher_text)
  658.     def RSA_decrypt(cipher_text,pr_key):
  659.         from Crypto.Cipher import PKCS1_OAEP
  660.         #Instantiating PKCS1_OAEP object with the private key for decryption
  661.         decrypt = PKCS1_OAEP.new(key=pr_key)
  662.         #Decrypting the message with the PKCS1_OAEP object
  663.         decrypted_message = decrypt.decrypt(cipher_text)
  664.         print(decrypted_message)        
  665.     # common packers
  666.     #
  667.     # messagepack
  668.     def msgPackPack(descrip1,temp_data1,descrip2,temp_data2):
  669.         import msgpack
  670.         json_obj = {}
  671.         json_obj['sensor1_desc'] = descrip1
  672.         json_obj['sensor1_temp'] = temp_data1
  673.         json_obj['sensor2_desc'] = descrip2
  674.         json_obj['sensor2_temp'] = temp_data2
  675.         json_obj['timestamp'] = round(timestamp = datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())
  676.         msgpack_data = msgpack.packb(json.dumps(json_obj, ensure_ascii=False))      
  677.         return msgpack_data
  678.     def msgPackUnPack(msgpck_str):
  679.         import msgpack
  680.         msgs=[]
  681.         for msg in msgpack.Unpacker(msgpck_str):
  682.             print msg
  683.             msgs.append(msg)
  684.         return msgs            
  685.     # cbor
  686.     def cborPack(descrip1,temp_data1,descrip2,temp_data2):
  687.         import cbor
  688.         json_obj = {}
  689.         json_obj['sensor1_desc'] = descrip1
  690.         json_obj['sensor1_temp'] = temp_data1
  691.         json_obj['sensor2_desc'] = descrip2
  692.         json_obj['sensor2_temp'] = temp_data2
  693.         json_obj['timestamp'] = round(timestamp = datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())
  694.         cbor_data = cbor.load(json.dumps(json_obj, ensure_ascii=False))      
  695.         return cbor_data
  696.     def cborUnPack(cbor_str):
  697.         import cbor
  698.         msgs=[]
  699.         for msg in cbor.dump(cbor_str):
  700.             print msg
  701.             msgs.append(msg)
  702.         return msgs
  703.        
  704.     # SSL TLS Client connection to your own SSL server which echos the response back in reply
  705.     def sendTLSClient(descrip1,temp_data1,descrip2,temp_data2):
  706.         import socket, ssl
  707.         # SSL with TLS
  708.         context = ssl.SSLContext(ssl.PROTOCOL_TLS_CLIENT)   # refer to the options https://www.pyopenssl.org/en/21.0.0/api/ssl.html
  709.         context.options |= ssl.OP_NO_TLSv1_3        # OP_NO_TLSv1_3 = Disable TLS1.3 PROTOCOL_TLS_CLIENT = tls client, PROTOCOL_TLS_SERVER = TLS Server
  710.         #context.options |= ssl.OP_SINGLE_ECDH_USE    example a new key will always be created when using ephemeral (Elliptic curve) Diffie-Hellman.
  711.         context.check_hostname = False              # do not check hostname
  712.         context.load_verify_locations('cert.pem')   # specify the certificate
  713.         context.set_ciphers('kRSA')                 # specify the cipher suite
  714.  
  715.         # Create a socket and wrap it in an SSL socket
  716.         sock = socket.socket(socket.AF_INET, socket.SOCK_STREAM)
  717.         ssock = context.wrap_socket(sock)
  718.  
  719.         # Connect to the server and send data
  720.         ssock.connect((SSLHOST,SSLPORT))
  721.         ts = round(datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())  # set the timezone as you wish for your location
  722.         msgdata = " got the data at " + ts + " " + descrip1 + " : " + str(temp_data1) + " " + descrip2 + " : " + str(temp_data2)
  723.         ssock.sendall(bytes(msgdata  + "\n", "utf-8"))
  724.  
  725.         # Receive data from the server and exit
  726.         received = str(ssock.recv(1024), "utf-8")
  727.         ssock.close()
  728.  
  729.         print("Sent:     " + msgdata)
  730.         print("Received: " + received)
  731.  
  732.     # SSL TLS Client connection to your own SSL server which echos the response back in reply    
  733.     def sendSSL23Client(descrip1,temp_data1,descrip2,temp_data2):
  734.         import ssl
  735.         import socket
  736.         import pprint      
  737.         context = ssl.create_default_context()
  738.         context = ssl.SSLContext(ssl.PROTOCOL_SSLv23)
  739.         context.verify_mode = ssl.CERT_NONE
  740.         context.check_hostname = False
  741.         conn = context.wrap_socket(socket.socket(socket.AF_INET), server_hostname=URL)
  742.         conn.connect((SSL_URL, SSL_PORT))
  743.         cert = conn.getpeercert()
  744.         pprint.pprint(cert)
  745.         ts = round(datetime.datetime.now(pytz.timezone('Europe/Moscow')).timestamp())  # set the timezone as you wish for your location
  746.         msgdata = b" got the data at " + str(ts).encode('UTF-8') + b" " + descrip1.encode('UTF-8') + b" : " + str(temp_data1).encode('UTF-8') + b" " + descrip2.encode('UTF-8') + b" : " + str(temp_data2).encode('UTF-8') + b"\r\n\r\n"
  747.         #conn.sendall(b"HEAD / HTTP/1.0\r\nHost: linuxfr.org\r\n\r\n")
  748.         if AES_ENCRYPT == 1:
  749.             from Crypto.Cipher import AES
  750.             from Crypto.Random import get_random_bytes
  751.             key = get_random_bytes(16)
  752.             nonce = get_random_bytes(12)
  753.             ciphertext, mac = aes_gcm_encrypt(key,nonce,msgdata)
  754.             conn.sendall(ciphertext)
  755.             indata = conn.recv(1024).split(b"\r\n"))
  756.             pprint.pprint(aes_gcm_decrypt(key,nonce,indata,mac))
  757.         else:
  758.             conn.sendall(msgdata)
  759.             indat = conn.recv(1024).split(b"\r\n"))
  760.             pprint.pprint(indat)
  761.         conn.close()
  762.        
  763.     # Choose the iOt you want to use according to the define in top section        
  764.     if telem_opt == "soracom":
  765.         sendData=sendDataSoraCom
  766.     elif telem_opt == "beebotte":
  767.         client = mqtt.Client()
  768.         client.username_pw_set("token:%s"%TOKEN)
  769.         client.on_connect = on_connect
  770.         client.on_disconnect = on_disconnect
  771.         client.on_publish = on_publish
  772.         client.tls_set(CACERT)
  773.         client.connect(HOSTNAME, port=BPORT, keepalive=KEEP_ALIVE)
  774.         sendData=sendDataBeebotte
  775.         GTOPIC=BTOPIC
  776.     elif telem_opt == "ubidots":
  777.         from ubidots import ApiClient      
  778.         api = ApiClient(token="4b00-xxxxxxxxxxxxxxxxxxx", base_url="http://yourcompanyname.api.ubidots.com/api/v1.6/")      
  779.         sendData=sendDataUbiDots
  780.     elif telem_opt == "machinist":
  781.         sendData=sendDataMachinist  
  782.     elif telem_opt == "aws":
  783.         import boto3
  784.         sendData=sendDataAws    
  785.     elif telem_opt == "yandex":
  786.         # un comment if you didnt already make the table
  787.         # makeTableQuery=makeYandexTable("pxc_cloud_db.timeseries_example")
  788.         # sendCreateYandexTable(makeTableQuery)
  789.         sendData=sendDataYandex        
  790.     elif telem_opt == "azure":
  791.         if AZURE_TYPE == "connection_string" :
  792.             from azure.iot.device.aio import IoTHubDeviceClient
  793.             from azure.iot.device import Message
  794.             device_client = IoTHubDeviceClient.create_from_connection_string(AZURE_CONN_STR)
  795.         else:
  796.             from azure.iot.device.aio import ProvisioningDeviceClient
  797.             from azure.iot.device.aio import IoTHubDeviceClient
  798.             from azure.iot.device import Message
  799.             provisioning_device_client = ProvisioningDeviceClient.create_from_symmetric_key(
  800.                 provisioning_host=provisioning_host,
  801.                 registration_id=registration_id,
  802.                 id_scope=id_scope,
  803.                 symmetric_key=symmetric_key,
  804.             )
  805.             registration_result = provisioning_device_client.register()
  806.             print("The complete registration result is")
  807.             print(registration_result.registration_state)
  808.             if registration_result.status == "assigned":
  809.                print("Your device has been provisioned. It will now begin sending telemetry.")
  810.                device_client = IoTHubDeviceClient.create_from_symmetric_key(
  811.                    symmetric_key=symmetric_key,
  812.                    hostname=registration_result.registration_state.assigned_hub,
  813.                    device_id=registration_result.registration_state.device_id,
  814.                )            
  815.         device_client.connect()
  816.         sendData=sendDataAzure  
  817.     elif telem_opt == "twillio":
  818.         sendData=sendTwilioSMS
  819.     elif telem_opt == "smtp_email":
  820.         sendData=sendSMTPemail
  821.     elif telem_opt == "ssl_tls_server":
  822.         sendData=sendTLSClient
  823.     elif telem_opt == "ssl_23_server":
  824.         sendData=sendSSL23Client
  825.     elif telem_opt == "gcs_blob":
  826.         sendData=uploadBlobGcs
  827.     elif telem_opt = "cloud_mqtt":            
  828.         client = mqtt.Client(protocol=mqtt.MQTTv311)
  829.         client.tls_set(CCACERT)
  830.         client.username_pw_set("aircampro", "air987")
  831.         client.on_connect = on_connect
  832.         client.on_disconnect = on_disconnect
  833.         client.on_publish = on_publish
  834.         client.connect(CHOSTNAME, CPORT, KEEP_ALIVE)    
  835.         sendData=sendDataCloudMqtt
  836.         GTOPIC=CTOPIC
  837.     elif telem_opt == "splunk":
  838.         sendData=sendDataSplunk
  839.     else:                                                    # we assume its for mosquito broker internally running on host e.g. raspberry pi 4
  840.         client = mqtt.Client()
  841.         client.on_connect = on_connect
  842.         client.on_disconnect = on_disconnect
  843.         client.on_publish = on_publish
  844.         client.connect("localhost", MQTT_PORT, KEEP_ALIVE)    
  845.         sendData=sendDataMosquito
  846.         GTOPIC=MTOPIC
  847.        
  848.     # read the enOcean sensor        
  849.     sensor1_rdy = False
  850.     sensor2_rdy = False
  851.     cnt = 0
  852.     dataLen = 0
  853.     optLen = 0
  854.     telegraph,headList,dataList,optList = [],[],[],[]
  855.     ready = True
  856.        
  857.     while True:
  858.         if sensor1_rdy and sensor2_rdy:
  859.             break
  860.  
  861.         # 1byte Reads data from the serial port one by one.
  862.         s_data = s_port.read().encode('hex') # read 1byte
  863.  
  864.         # Sync-Recognizes the start of Telegram data from Byte 0x55.。
  865.         if s_data == '55' and ready: # Telegram start
  866.             # valuable reset
  867.             cnt = 0
  868.             dataLen = 0
  869.             optLen = 0
  870.             ready = False
  871.             telegraph,headList,dataList,optList = [],[],[],[]
  872.  
  873.         cnt += 1
  874.         telegraph.append(s_data)
  875.  
  876.         # We are analyzing Telegram data.
  877.         if 2 <= cnt <= 5: # header
  878.             headList.append(s_data)
  879.         if cnt == 5: # header end, get data length
  880.             dataLen = int(headList[1],16)
  881.             optLen  = int(headList[2],16)
  882.         if 7 <= cnt <= (6+dataLen): # data
  883.             dataList.append(s_data)
  884.         if (7+dataLen) <= cnt <= (6+dataLen+optLen): # optional data
  885.             optList.append(s_data)
  886.         if cnt == (6+dataLen+optLen+1): # Telegram end
  887.             ready = True
  888.             sensorId = ':'.join(dataList[1:5]) # Sensor ID
  889.             timestamp = datetime.now().strftime('%Y-%m-%d %H:%M:%S')
  890.  
  891.             # The data is displayed for debugging purposes.
  892.             print "========"
  893.             print timestamp
  894.             print("telegraph...:", ":".join(telegraph))
  895.             print( "head...", ":".join(headList))
  896.             print( "data...", ":".join(dataList), "(length=%d)" % dataLen)
  897.             print( "opt ...", ":".join(optList),  "(length=%d)" % optLen)
  898.             print( "sensorID...", sensorId)
  899.  
  900.             # Temp sensor1 Send data when the sensor ID matches.
  901.             if sensorId == SENSORID1 and sensor1_rdy == False:
  902.                 val = int(dataList[7],16)
  903.                 sensor1_temp = round((255.0-val)/255.0*40.0, 2)
  904.                 sensor_desc1 = 'temperature01 ' + SENSORID1 + " : "
  905.                 sensor1_rdy = True
  906.  
  907.             # Temp sensor1 Send data when the sensor ID matches.
  908.             elif sensorId == SENSORID2 and sensor2_rdy == False:
  909.                 val = int(dataList[7],16)
  910.                 sensor2_temp = round((255.0-val)/255.0*40.0, 2)
  911.                 sensor_desc1 = 'temperature02 ' + SENSORID2 + " : "
  912.                 sensor2_rdy = True
  913.  
  914.             # Other sensors, ignore ID
  915.             else:
  916.                 continue
  917.                
  918.     # return this data for webpage display via flask->uwgsi->nginx        
  919.     if sensor1_rdy and sensor2_rdy:
  920.         sendData(sensor_desc1, sensor1_temp, sensor_desc2, sensor2_temp)
  921.         return str(sensor1_temp),str(sensor2_temp)
  922.  
  923. if __name__ == '__main__':
  924.  
  925.     # Open serial port for communication with enOcean sensors
  926.     try:
  927.         s_port = serial.Serial(PORT, BAUD_RT)
  928.         print("open serial port: %s" % PORT)
  929.     except:
  930.         print("cannot open serial port: %s" % PORT)
  931.         exit(1)
  932.                
  933.     t1,t2 = Enocean2Telemetry(s_port,MY_CURRENT_TELEM)
  934.     print("sensorID..." % SENSORID1)
  935.     print("temperature" % t1)
  936.     print("sensorID..." % SENSORID2)
  937.     print("temperature" % t2)  
Add Comment
Please, Sign In to add comment