123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352 |
- #!/usr/bin/env python3.5
- import paho.mqtt.client as mqtt
- import time
- import sys
- import http.client, urllib
- import json
- import threading
- import os
- import shutil
- import uuid
- import hashlib
- import serial
- import array
- import base64
- import urllib.request
- import datetime
- import requests
- import logging
- import RPi.GPIO as GPIO
- """ Device Information - the information about this device
- These device information is used for the MQTT topic. This program will subscribe and publish to
- the MQTT topic.
- MQTT topic to subscribe to: AISKY/<project_name>/<model_name>/<device_id>
- MQTT topic to publish to : AISKY/<project_name>/<model_name>/<device_id>/Log
- """
- # @var project_name The project name comes from the u-boot environment variable 'project'.
- # @var model_name The model name comes from the u-boot environment variable 'model'.
- # @var device_id The device id comes from the mac address of eth0.
- project_name = os.popen('cat /etc/aisky.conf | grep project').readline().split('=')[1].strip()
- model_name = os.popen('cat /etc/aisky.conf | grep model').readline().split('=')[1].strip()
- device_id = open('/sys/class/net/eth0/address').readline().strip()
- """ NOTE: Remember to setup the u-boot environment variables before executing this program. The
- commands to setup the u-boot environment variables are as follows.
- Setup the 'project' variable: The following command sets the 'project' variable to AppleFarm.
- root@mylinkit:~# fw_setenv project AppleFarm
- Setup the 'model' variable: The following command sets the 'model' variable to MK-G.
- root@mylinkit:~# fw_setenv model MK-G
- Then, the following command can be used to display the u-boot environment variables.
- root@mylinkit:~# fw_printenv
- """
- """ MQTT Server
- If you don't have your own MQTT server, you can use the public MQTT server 'iot.eclipse.org'. But
- with the public MQTT server, you can only publish and subscribe without a user name and password.
- Sometimes the public MQTT server is unstable.
- """
- # @var mqtt_server The URL or IP address of the MQTT server to connect to.
- # @var mqtt_port The port of the MQTT server to connect to.
- # @var mqtt_alive Maximum period in seconds allowed between communications with the broker. If
- # no other messages are being exchanged, this controls the rate at which the
- # client will send ping messages to the broker.
- mqtt_server = "60.250.156.234"
- mqtt_port = 1883
- mqtt_alive = 60
- # camera API command
- #php path
- #reboot_path ="http://www.aisky.com.tw/field/status.php"
- #log
- # @var mqtt_sub_topic The MQTT topic to subscribe to.
- # @var mqtt_pub_topic The MQTT topic to publish to.
- mqtt_sub_topic = "AISKY/" + project_name + "/" + model_name + "/" + device_id
- mqtt_pub_topic = mqtt_sub_topic + "/Log"
- ##nr
- nr = "AGV_CAR"
- ##gpio
- GPIO.setmode(GPIO.BOARD)
- GPIO.setwarnings(False)
- GPIO.setup(11, GPIO.OUT, initial=GPIO.LOW)
- GPIO.setup(12, GPIO.OUT, initial=GPIO.LOW)
- GPIO.setup(13, GPIO.OUT, initial=GPIO.LOW)
- GPIO.setup(15, GPIO.OUT, initial=GPIO.LOW)
- GPIO.setup(16, GPIO.OUT, initial=GPIO.LOW)
- ##sonic
- trigger_pin = 22
- echo_pin = 24
- GPIO.setup(trigger_pin, GPIO.OUT, initial=GPIO.LOW)
- GPIO.setup(echo_pin, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
- ##water_level
- water_level_pin1 =18
- signal_read_pin1 =19
- water_level_pin2 =21
- signal_read_pin2 =23
- GPIO.setup(water_level_pin1, GPIO.OUT, initial=GPIO.HIGH)
- GPIO.setup(signal_read_pin1, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
- GPIO.setup(water_level_pin2, GPIO.OUT, initial=GPIO.HIGH)
- GPIO.setup(signal_read_pin2, GPIO.IN,pull_up_down = GPIO.PUD_DOWN)
- ## Calculate the SHA256 checksum of the file.
- # @param file [in] The file path for which you want to calculate the checksum.
- def get_sha256sum(file):
- with open(file, "rb") as f:
- bytes = f.read()
- return hashlib.sha256(bytes).hexdigest()
- ## Send logs to the server.
- # @param command [in] The command received from the server.
- # @param response [in] The response message to the command.
- def server_log(command, rqnn):
- localtime = time.strftime("%Y-%m-%d %H:%M:%S", time.localtime())
- # message to be sent in JSON format
- payload = {
- # let server know which device the message came from
- 'device_id': device_id,
- # let server know when the message was sent from the device
- 'localtime': localtime,
- 'node_id': nr,
- 'command': command,
- 'rqnn': rqnn
- }
- jsonobj = json.dumps(payload, sort_keys=True, indent=4)
- mqtt_client.publish(mqtt_pub_topic, jsonobj, qos=2)
- print('Sent:')
- print(jsonobj)
- def get_ip_address(ifname):
- s = socket.socket(socket.AF_INET, socket.SOCK_DGRAM)
- try:
- return socket.inet_ntoa(fcntl.ioctl(
- s.fileno(),
- 0x8915, # SIOCGIFADDR
- struct.pack('256s', ifname[:15])
- )[20:24])
- except:
- return ""
- ## Reset this device.
- def system_reboot():
- server_log('a035', '1')
- time.sleep(5)
- os.system('sudo reboot')
- time.sleep(10)
- def system_update_code():
- os.system('sudo su')
- os.system('rm -rf /home/pi/AGVCAR')
- os.system('git clone -b AGVCAR --single-branch http://60.250.156.230:3000/allen/AGV.git /home/pi/AGVCAR')
- time.sleep(3)
- os.system('cp /home/pi/AGVCAR/aisky-mqttd /usr/sbin/')
- time.sleep(1)
- os.system('cp /home/pi/AGVCAR/udp_client.py /home/pi/')
- time.sleep(1)
- os.system('sudo chmod 777 /usr/sbin/aisky-mqttd')
- os.system('sudo chmod 777 /home/pi/udp_client.py')
- time.sleep(5)
- server_log('a033', '1')
- os.system('sudo reboot')
- time.sleep(10)
- ## Receive the system action to this device .
- def fan(msg):
- if (msg['value'] == 'on'):
- GPIO.output(11, GPIO.HIGH)
- server_log(' fan', "on")
- elif (msg['value'] == 'off'):
- GPIO.output(11, GPIO.LOW)
- server_log(' fan', "off")
- else:
- server_log(' fan', "NULL")
- def water_bump(msg):
- if (msg['value'] == 'on'):
- GPIO.output(12, GPIO.HIGH)
- server_log('water_bump', "on")
- elif (msg['value'] == 'off'):
- GPIO.output(12, GPIO.LOW)
- server_log('water_bump', "off")
- else:
- server_log(' water_bump', "NULL")
- def red_light(msg):
- if (msg['value'] == 'on'):
- GPIO.output(13, GPIO.HIGH)
- server_log(' red_light', "on")
- elif (msg['value'] == 'off'):
- GPIO.output(13, GPIO.LOW)
- server_log(' red_light', "off")
- else:
- server_log(' red_light', "NULL")
- def yellow_light(msg):
- if (msg['value'] == 'on'):
- GPIO.output(15, GPIO.HIGH)
- server_log(' yellow_light', "on")
- elif (msg['value'] == 'off'):
- GPIO.output(15, GPIO.LOW)
- server_log(' yellow_light', "off")
- else:
- server_log(' yellow_light', "NULL")
- def green_light(msg):
- if (msg['value'] == 'on'):
- GPIO.output(16, GPIO.HIGH)
- server_log(' green_light', "on")
- elif (msg['value'] == 'off'):
- GPIO.output(16, GPIO.LOW)
- server_log(' green_light', "off")
- else:
- server_log('green_light', "NULL")
- def send_trigger_pulse():
- GPIO.output(trigger_pin, True)
- time.sleep(0.001)
- GPIO.output(trigger_pin, False)
- def wait_for_echo(value, timeout):
- count = timeout
- while GPIO.input(echo_pin) != value and count > 0:
- count = count - 1
- def sonic():
- send_trigger_pulse()
- wait_for_echo(True, 5000)
- start = time.time()
- wait_for_echo(False, 5000)
- finish = time.time()
- pulse_len = finish - start
- distance_cm = pulse_len * 340 *100 /2
- distance_in = distance_cm / 2.5
- print(distance_cm)
- server_log('sonic',distance_cm)
- def water_level():
- level_1=GPIO.input(signal_read_pin1)
- level_2=GPIO.input(signal_read_pin2)
- print(level_1)
- print(level_2)
- if(level_1 == False):
- if(level_2 == False):
- server_log('water_level', "top")
- elif(level_2 == False):
- server_log('water_level', "error")
- elif(level_1 == True):
- if(level_2 == False):
- server_log('water_level', "center")
- elif(level_2 == True):
- server_log('water_level', "bottom")
- def video2(msg):
- if(msg['value']=="on"):
- os.system('sudo su')
- os.system('cd /hmoe/pi')
- os.system('sudo nohup python3.5 /home/pi/udp_client.py>/home/pi/nohup.out 2>&1 &')
- time.sleep(2)
- server_log('video2', 'on')
- elif (msg['value'] == 'off'):
- os.system('sudo su')
- os.system("ps aux | grep /home/pi/udp_client.py | awk '{print $2}' | xargs kill -9")
- time.sleep(2)
- server_log('video2', "off")
- else:
- server_log('video2', "error")
- ## The callback function for connecting.
- # @param client [in] The client instance for this callback.
- # @param userdata [in] The private user data as set in Client() or user_data_set().
- # @param flags [in] Response flags sent by the broker.
- # @param rc [in] The connection result.
- def on_connect(client, userdata, flags, rc):
- # subscribe MQTT topic on connection
- client.subscribe(mqtt_sub_topic, qos=2)
- server_log('a035', '1')
- #logging.info('system running')
- #data = {'nr': nr, 'status': 'reboot'}
- #data = urllib.parse.urlencode(data)
- #data = data.encode('utf-8')
- #req = urllib.request.Request(reboot_path, data)
- #req.add_header('User-Agent', 'Magic Browser')
- #resp = urllib.request.urlopen(req)
- #respData = resp.read()
- print("reboot check ok")
- ## The callback function for processing messages from the server.
- # @param client [in] The client instance for this callback.
- # @param userdata [in] The private user data as set in Client() or user_data_set().
- # @param msg [in] An instance of MQTT message.
- def on_message(client, userdata, msg):
- # print(msg.payload)
- msg.payload = msg.payload.decode('utf-8')
- jsonmsg = json.loads(msg.payload)
- #print(jsonmsg)
- print('Received:')
- print(json.dumps(jsonmsg, sort_keys=True, indent=4, separators=(',', ':')))
- # processing the command from the server
- if (jsonmsg['command'] == 'a035'):
- system_reboot()
- elif (jsonmsg['command'] == 'a033'):
- system_update_code()
- elif (jsonmsg['command'] == 'vpn_connect'):
- vpn_connect()
- elif (jsonmsg['command'] == 'vpn_disconnect'):
- vpn_disconnect()
- elif (jsonmsg['command'] == 'fan'):
- fan(jsonmsg)
- elif (jsonmsg['command'] == 'water_bump'):
- water_bump(jsonmsg)
- elif (jsonmsg['command'] == 'red_light'):
- red_light(jsonmsg)
- elif (jsonmsg['command'] == 'yellow_light'):
- yellow_light(jsonmsg)
- elif (jsonmsg['command'] == 'green_light'):
- green_light(jsonmsg)
- elif (jsonmsg['command'] == 'sonic'):
- sonic()
- elif (jsonmsg['command'] == 'water_level'):
- water_level()
- elif (jsonmsg['command'] == 'video2'):
- video2(jsonmsg)
- else:
- server_log(jsonmsg['command'], 'ERROR: Unknown command')
- ## A thread used to subscribe to and wait for messages from the server.
- def thread_job():
- # create a MQTT client with a user name and password to subscribe to the messages
- mqtt_thread_client = mqtt.Client()
- mqtt_thread_client.on_connect = on_connect
- mqtt_thread_client.on_message = on_message
- mqtt_thread_client.username_pw_set(username='aisky-client', password='aiskyc')
- mqtt_thread_client.connect(mqtt_server, mqtt_port, mqtt_alive)
- mqtt_thread_client.loop_forever()
- # create a MQTT client with a user name and password to publish messages
- mqtt_client = mqtt.Client()
- mqtt_client.username_pw_set(username='aisky-client', password='aiskyc')
- mqtt_client.connect(mqtt_server, mqtt_port, mqtt_alive)
- # create a thread to subscribe to and wait for messages from the server
- mqtt_subscribe_thread = threading.Thread(target=thread_job)
- mqtt_subscribe_thread.start()
- mqtt_client.loop_forever()
|