Upgrade to 1.5.2, tooling for VPN API requests
This commit is contained in:
2
.gitignore
vendored
Normal file
2
.gitignore
vendored
Normal file
@@ -0,0 +1,2 @@
|
|||||||
|
I-Sight_Generated_Files*
|
||||||
|
DATAMODEL_*
|
||||||
@@ -1,21 +1,21 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Get all devices from an IoT Hub (iothub_name) that have the given tag (tag_key == tag_value)
|
# Get all devices from an IoT Hub (iothub_name) that have the given tag (tag_key == tag_value)
|
||||||
# Can also filter using tags.number
|
# Can also filter using tags.number
|
||||||
# Execute an Azure command for each of the devices found
|
# Execute an Azure command for each of the devices found
|
||||||
# Here the command will execute a Direct Method for the ThingsPro module on the devices. This Direct Method enable the Discovery Service.
|
# Here the command will execute a Direct Method for the ThingsPro module on the devices. This Direct Method enable the Discovery Service.
|
||||||
|
|
||||||
iothub_name="IotHub-CUBE-Prod"
|
iothub_name="IotHub-CUBE-Prod"
|
||||||
|
|
||||||
tag_key="site"
|
tag_key="site"
|
||||||
tag_value="DANISH"
|
tag_value="DANISH"
|
||||||
|
|
||||||
devices=$(az iot hub query --hub-name $iothub_name --query-command "SELECT * FROM devices WHERE tags.$tag_key = '$tag_value' AND capabilities.iotEdge = true" --output json)
|
devices=$(az iot hub query --hub-name $iothub_name --query-command "SELECT * FROM devices WHERE tags.$tag_key = '$tag_value' AND capabilities.iotEdge = true" --output json)
|
||||||
|
|
||||||
device_ids=$(echo "$devices" | jq -r '.[].deviceId')
|
device_ids=$(echo "$devices" | jq -r '.[].deviceId')
|
||||||
|
|
||||||
for device_id in $device_ids
|
for device_id in $device_ids
|
||||||
do
|
do
|
||||||
echo "$device_id"
|
echo "$device_id"
|
||||||
az iot hub invoke-module-method --method-name thingspro-api-v1 --method-payload "{\"method\":\"PUT\",\"path\":\"/system/discovery\",\"requestBody\":{\"enable\": true}""}" --device-id $device_id --module-id thingspro-agent --hub-name $iothub_name
|
az iot hub invoke-module-method --method-name thingspro-api-v1 --method-payload "{\"method\":\"PUT\",\"path\":\"/system/discovery\",\"requestBody\":{\"enable\": true}""}" --device-id $device_id --module-id thingspro-agent --hub-name $iothub_name
|
||||||
done
|
done
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Get all devices from an IoT Hub (iothub_name) that have the given tag (tag_key == tag_value)
|
# Get all devices from an IoT Hub (iothub_name) that have the given tag (tag_key == tag_value)
|
||||||
# Can also filter using tags.number
|
# Can also filter using tags.number
|
||||||
# Execute an Azure command for each of the devices found
|
# Execute an Azure command for each of the devices found
|
||||||
# Here the command will configure the modules of all the IoT Edge devices of Danish (as Danish have up to 29 devices) with the given template.
|
# Here the command will configure the modules of all the IoT Edge devices of Danish (as Danish have up to 29 devices) with the given template.
|
||||||
|
|
||||||
iothub_name="IotHub-CUBE-Prod"
|
iothub_name="IotHub-CUBE-Prod"
|
||||||
|
|
||||||
tag_key="site"
|
tag_key="site"
|
||||||
tag_value="DANISH"
|
tag_value="DANISH"
|
||||||
|
|
||||||
json_output=$(az iot hub query --hub-name $iothub_name --query-command "SELECT * FROM devices WHERE tags.$tag_key = '$tag_value' AND tags.number != '30' AND capabilities.iotEdge = true" --output json)
|
json_output=$(az iot hub query --hub-name $iothub_name --query-command "SELECT * FROM devices WHERE tags.$tag_key = '$tag_value' AND tags.number != '30' AND capabilities.iotEdge = true" --output json)
|
||||||
|
|
||||||
hashmap=$(echo "$json_output" | jq -r 'map({key: .tags.number, value: .deviceId}) | from_entries')
|
hashmap=$(echo "$json_output" | jq -r 'map({key: .tags.number, value: .deviceId}) | from_entries')
|
||||||
|
|
||||||
for key in $(echo "$hashmap" | jq -r 'keys | map(tonumber) | sort_by(.) | .[]'); do
|
for key in $(echo "$hashmap" | jq -r 'keys | map(tonumber) | sort_by(.) | .[]'); do
|
||||||
value=$(jq -r --arg k "$key" '.[$k]' <<< "$hashmap")
|
value=$(jq -r --arg k "$key" '.[$k]' <<< "$hashmap")
|
||||||
|
|
||||||
az iot edge set-modules --device-id $value --hub-name $iothub_name --content moxa_ac_template_1.5_patch.json
|
az iot edge set-modules --device-id $value --hub-name $iothub_name --content moxa_ac_template_1.5_patch.json
|
||||||
done
|
done
|
||||||
|
|
||||||
echo $hashmap
|
echo $hashmap
|
||||||
@@ -1,23 +1,23 @@
|
|||||||
#!/bin/bash
|
#!/bin/bash
|
||||||
|
|
||||||
# Get all devices from an IoT Hub (iothub_name) that have the given tag (tag_key == tag_value)
|
# Get all devices from an IoT Hub (iothub_name) that have the given tag (tag_key == tag_value)
|
||||||
# Can also filter using tags.number
|
# Can also filter using tags.number
|
||||||
# Execute an Azure command for each of the devices found
|
# Execute an Azure command for each of the devices found
|
||||||
# Here the command will execute a Direct Method for the ThingsPro module on the devices.
|
# Here the command will execute a Direct Method for the ThingsPro module on the devices.
|
||||||
|
|
||||||
iothub_name="IotHub-CUBE-Prod"
|
iothub_name="IotHub-CUBE-Prod"
|
||||||
|
|
||||||
tag_key="site"
|
tag_key="site"
|
||||||
tag_value="DANISH"
|
tag_value="DANISH"
|
||||||
|
|
||||||
json_output=$(az iot hub query --hub-name $iothub_name --query-command "SELECT * FROM devices WHERE tags.$tag_key = '$tag_value' AND (tags.number = '6' OR tags.number = '8' OR tags.number = '12' OR tags.number = '13') AND capabilities.iotEdge = true" --output json)
|
json_output=$(az iot hub query --hub-name $iothub_name --query-command "SELECT * FROM devices WHERE tags.$tag_key = '$tag_value' AND (tags.number = '6' OR tags.number = '8' OR tags.number = '12' OR tags.number = '13') AND capabilities.iotEdge = true" --output json)
|
||||||
|
|
||||||
hashmap=$(echo "$json_output" | jq -r 'map({key: .tags.number, value: .deviceId}) | from_entries')
|
hashmap=$(echo "$json_output" | jq -r 'map({key: .tags.number, value: .deviceId}) | from_entries')
|
||||||
|
|
||||||
for key in $(echo "$hashmap" | jq -r 'keys | map(tonumber) | sort_by(.) | .[]'); do
|
for key in $(echo "$hashmap" | jq -r 'keys | map(tonumber) | sort_by(.) | .[]'); do
|
||||||
value=$(jq -r --arg k "$key" '.[$k]' <<< "$hashmap")
|
value=$(jq -r --arg k "$key" '.[$k]' <<< "$hashmap")
|
||||||
status=$(az iot hub invoke-module-method --timeout 10 --method-name thingspro-api-v1 --method-payload '{"method":"GET","path":"/device/general"}' --device-id $value --module-id thingspro-agent --hub-name $iothub_name | jq .status)
|
status=$(az iot hub invoke-module-method --timeout 10 --method-name thingspro-api-v1 --method-payload '{"method":"GET","path":"/device/general"}' --device-id $value --module-id thingspro-agent --hub-name $iothub_name | jq .status)
|
||||||
echo "Key: $key, Value: $value, Status: $status"
|
echo "Key: $key, Value: $value, Status: $status"
|
||||||
done
|
done
|
||||||
|
|
||||||
#echo $hashmap
|
#echo $hashmap
|
||||||
|
|||||||
@@ -1,84 +1,84 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import subprocess
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# This Python script will read an Excel file containing a list of devices for a site (using --serials *file name*)
|
# This Python script will read an Excel file containing a list of devices for a site (using --serials *file name*)
|
||||||
# It will then create a IoT Edge device for each of the line in the file
|
# It will then create a IoT Edge device for each of the line in the file
|
||||||
# The user need to precise which IoT Hub is used (using --env *PROD or DEV*)
|
# The user need to precise which IoT Hub is used (using --env *PROD or DEV*)
|
||||||
# The user need provide the site name, which will be added as a tag (using --site *site name*)
|
# The user need provide the site name, which will be added as a tag (using --site *site name*)
|
||||||
# The user need to precise which configuration of the modules should be used, according to the running firmware on the devices (using --version *version number*)
|
# The user need to precise which configuration of the modules should be used, according to the running firmware on the devices (using --version *version number*)
|
||||||
# Example:
|
# Example:
|
||||||
# python create_devices_list.py --serials DANISH.xlsx --env PROD --site DANISH --version 1.5_patch
|
# python create_devices_list.py --serials DANISH.xlsx --env PROD --site DANISH --version 1.5_patch
|
||||||
# will create all the IoT Edge devices using the serial number found in the DANISH.xlsx file
|
# will create all the IoT Edge devices using the serial number found in the DANISH.xlsx file
|
||||||
# on the PROD IoT Hub
|
# on the PROD IoT Hub
|
||||||
# tag each new device with a site = DANISH
|
# tag each new device with a site = DANISH
|
||||||
# configure the modules for each devices with the corresponding version found in moxa_ac_template_1.5_patch.json
|
# configure the modules for each devices with the corresponding version found in moxa_ac_template_1.5_patch.json
|
||||||
# each device will have also be given a number = i where i is incremented automatically according to the number of device in the Excel file
|
# each device will have also be given a number = i where i is incremented automatically according to the number of device in the Excel file
|
||||||
# the provided Excel file will be modified, adding a column connection_string for each of the devices created with their corresponding connection string
|
# the provided Excel file will be modified, adding a column connection_string for each of the devices created with their corresponding connection string
|
||||||
# the output is therefore SENSITIVE
|
# the output is therefore SENSITIVE
|
||||||
|
|
||||||
def generate_commands(serials_file, env, site, version):
|
def generate_commands(serials_file, env, site, version):
|
||||||
# Read serial numbers from Excel file
|
# Read serial numbers from Excel file
|
||||||
df = pd.read_excel(serials_file)
|
df = pd.read_excel(serials_file)
|
||||||
df = df[df['device_name'].notnull()]
|
df = df[df['device_name'].notnull()]
|
||||||
serials = df['device_name'].tolist()
|
serials = df['device_name'].tolist()
|
||||||
|
|
||||||
# Initialize number
|
# Initialize number
|
||||||
number = 1
|
number = 1
|
||||||
|
|
||||||
# List to store connection strings
|
# List to store connection strings
|
||||||
connection_strings = []
|
connection_strings = []
|
||||||
|
|
||||||
# Generate commands for each serial number
|
# Generate commands for each serial number
|
||||||
for serial in serials:
|
for serial in serials:
|
||||||
# Replace placeholders with actual values
|
# Replace placeholders with actual values
|
||||||
print(serial, end=" ")
|
print(serial, end=" ")
|
||||||
device_id = f"DIGIT-{serial}"
|
device_id = f"DIGIT-{serial}"
|
||||||
print(device_id, end=" ")
|
print(device_id, end=" ")
|
||||||
tags = f'{{"deviceId":"{device_id}","site":"{site}","number":"{number}"}}'
|
tags = f'{{"deviceId":"{device_id}","site":"{site}","number":"{number}"}}'
|
||||||
content = f"moxa_ac_template_{version}.json"
|
content = f"moxa_ac_template_{version}.json"
|
||||||
# Construct command strings
|
# Construct command strings
|
||||||
create_command = f"az iot hub device-identity create --device-id {device_id} --hub-name IotHub-CUBE-{env} --edge-enabled"
|
create_command = f"az iot hub device-identity create --device-id {device_id} --hub-name IotHub-CUBE-{env} --edge-enabled"
|
||||||
twin_update_command = f"az iot hub device-twin update --device-id {device_id} --hub-name IotHub-CUBE-{env} --set tags='{tags}'"
|
twin_update_command = f"az iot hub device-twin update --device-id {device_id} --hub-name IotHub-CUBE-{env} --set tags='{tags}'"
|
||||||
set_modules_command = f"az iot edge set-modules --device-id {device_id} --hub-name IotHub-CUBE-{env} --content {content}"
|
set_modules_command = f"az iot edge set-modules --device-id {device_id} --hub-name IotHub-CUBE-{env} --content {content}"
|
||||||
|
|
||||||
# Execute create command and get primary key
|
# Execute create command and get primary key
|
||||||
create_output = subprocess.check_output(create_command, shell=True)
|
create_output = subprocess.check_output(create_command, shell=True)
|
||||||
create_output_json = json.loads(create_output.decode('utf-8'))
|
create_output_json = json.loads(create_output.decode('utf-8'))
|
||||||
primary_key = create_output_json['authentication']['symmetricKey']['primaryKey']
|
primary_key = create_output_json['authentication']['symmetricKey']['primaryKey']
|
||||||
print(primary_key, end=" ")
|
print(primary_key, end=" ")
|
||||||
|
|
||||||
# Generate connection string
|
# Generate connection string
|
||||||
connection_string = f"HostName=IotHub-CUBE-{env}.azure-devices.net;DeviceId={device_id};SharedAccessKey={primary_key}"
|
connection_string = f"HostName=IotHub-CUBE-{env}.azure-devices.net;DeviceId={device_id};SharedAccessKey={primary_key}"
|
||||||
print(connection_string)
|
print(connection_string)
|
||||||
connection_strings.append(connection_string)
|
connection_strings.append(connection_string)
|
||||||
|
|
||||||
tags_output = subprocess.run(twin_update_command, shell=True)
|
tags_output = subprocess.run(twin_update_command, shell=True)
|
||||||
modules_output = subprocess.run(set_modules_command, shell=True)
|
modules_output = subprocess.run(set_modules_command, shell=True)
|
||||||
# Increment number
|
# Increment number
|
||||||
number += 1
|
number += 1
|
||||||
|
|
||||||
# Add connection strings to DataFrame
|
# Add connection strings to DataFrame
|
||||||
df['connection_string'] = connection_strings
|
df['connection_string'] = connection_strings
|
||||||
|
|
||||||
# Save DataFrame to Excel file
|
# Save DataFrame to Excel file
|
||||||
df.to_excel(serials_file, index=False)
|
df.to_excel(serials_file, index=False)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Parse command line arguments
|
# Parse command line arguments
|
||||||
parser = argparse.ArgumentParser(description='Create devices list')
|
parser = argparse.ArgumentParser(description='Create devices list')
|
||||||
parser.add_argument('--serials', required=True, help='Excel file containing serial numbers')
|
parser.add_argument('--serials', required=True, help='Excel file containing serial numbers')
|
||||||
parser.add_argument('--env', required=True, help='Environment (PROD or DEV)')
|
parser.add_argument('--env', required=True, help='Environment (PROD or DEV)')
|
||||||
parser.add_argument('--site', required=True, help='Site name')
|
parser.add_argument('--site', required=True, help='Site name')
|
||||||
parser.add_argument('--version', required=True, help='Version number')
|
parser.add_argument('--version', required=True, help='Version number')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Generate commands
|
# Generate commands
|
||||||
generate_commands(args.serials, args.env, args.site, args.version)
|
generate_commands(args.serials, args.env, args.site, args.version)
|
||||||
|
|
||||||
|
|||||||
@@ -1,48 +1,48 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import subprocess
|
import subprocess
|
||||||
import argparse
|
import argparse
|
||||||
import sys
|
import sys
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# This Python script will create an IoT Edge device according to the provided parameters
|
# This Python script will create an IoT Edge device according to the provided parameters
|
||||||
# It will create the device with the name DIGIT-*serial number* (using --serial *serial number*)
|
# It will create the device with the name DIGIT-*serial number* (using --serial *serial number*)
|
||||||
# The user need to precise the number of the gateway on the site (using --number *number*)
|
# The user need to precise the number of the gateway on the site (using --number *number*)
|
||||||
# The user need to precise which IoT Hub is used (using --env *PROD or DEV*)
|
# The user need to precise which IoT Hub is used (using --env *PROD or DEV*)
|
||||||
# The user need provide the site name, which will be added as a tag (using --site *site name*)
|
# The user need provide the site name, which will be added as a tag (using --site *site name*)
|
||||||
# The user need to precise which configuration of the modules should be used, according to the running firmware on the device (using --version *version number*)
|
# The user need to precise which configuration of the modules should be used, according to the running firmware on the device (using --version *version number*)
|
||||||
# Example:
|
# Example:
|
||||||
# python create_moxa.py --serial TBBHB1044382 --number 5 --env PROD --site DANISH --version 1.5_patch
|
# python create_moxa.py --serial TBBHB1044382 --number 5 --env PROD --site DANISH --version 1.5_patch
|
||||||
# will create the IoT Edge device using the serial number provided (TBBHB1044382)
|
# will create the IoT Edge device using the serial number provided (TBBHB1044382)
|
||||||
# on the PROD IoT Hub
|
# on the PROD IoT Hub
|
||||||
# tag the device with number = 5
|
# tag the device with number = 5
|
||||||
# tag the device with site = DANISH
|
# tag the device with site = DANISH
|
||||||
# configure the modules for the device with the corresponding version found in moxa_ac_template_1.5_patch.json
|
# configure the modules for the device with the corresponding version found in moxa_ac_template_1.5_patch.json
|
||||||
|
|
||||||
def generate_commands(serial, number, env, site, version):
|
def generate_commands(serial, number, env, site, version):
|
||||||
|
|
||||||
device_id = f"DIGIT-{serial}"
|
device_id = f"DIGIT-{serial}"
|
||||||
tags = f'{{"deviceId":"{device_id}","site":"{site}","number":"{number}"}}'
|
tags = f'{{"deviceId":"{device_id}","site":"{site}","number":"{number}"}}'
|
||||||
content = f"moxa_ac_template_{version}.json"
|
content = f"moxa_ac_template_{version}.json"
|
||||||
create_device_command = f"az iot hub device-identity create --device-id {device_id} --hub-name IotHub-CUBE-{env} --edge-enabled"
|
create_device_command = f"az iot hub device-identity create --device-id {device_id} --hub-name IotHub-CUBE-{env} --edge-enabled"
|
||||||
twin_update_command = f"az iot hub device-twin update --device-id {device_id} --hub-name IotHub-CUBE-{env} --set tags='{tags}'"
|
twin_update_command = f"az iot hub device-twin update --device-id {device_id} --hub-name IotHub-CUBE-{env} --set tags='{tags}'"
|
||||||
set_modules_command = f"az iot edge set-modules --device-id {device_id} --hub-name IotHub-CUBE-{env} --content {content}"
|
set_modules_command = f"az iot edge set-modules --device-id {device_id} --hub-name IotHub-CUBE-{env} --content {content}"
|
||||||
subprocess.run(create_device_command, shell=True)
|
subprocess.run(create_device_command, shell=True)
|
||||||
subprocess.run(twin_update_command, shell=True)
|
subprocess.run(twin_update_command, shell=True)
|
||||||
subprocess.run(set_modules_command, shell=True)
|
subprocess.run(set_modules_command, shell=True)
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
# Parse command line arguments
|
# Parse command line arguments
|
||||||
parser = argparse.ArgumentParser(description='Create devices list')
|
parser = argparse.ArgumentParser(description='Create devices list')
|
||||||
parser.add_argument('--serial', required=True, help='Serial number of the gateway')
|
parser.add_argument('--serial', required=True, help='Serial number of the gateway')
|
||||||
parser.add_argument('--number', required=True, help='Gateway on-site number')
|
parser.add_argument('--number', required=True, help='Gateway on-site number')
|
||||||
parser.add_argument('--env', required=True, help='Environment (PROD or DEV)')
|
parser.add_argument('--env', required=True, help='Environment (PROD or DEV)')
|
||||||
parser.add_argument('--site', required=True, help='Site name')
|
parser.add_argument('--site', required=True, help='Site name')
|
||||||
parser.add_argument('--version', required=True, help='Version number')
|
parser.add_argument('--version', required=True, help='Version number')
|
||||||
args = parser.parse_args()
|
args = parser.parse_args()
|
||||||
|
|
||||||
if len(sys.argv) == 1:
|
if len(sys.argv) == 1:
|
||||||
parser.print_help()
|
parser.print_help()
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
# Generate commands
|
# Generate commands
|
||||||
generate_commands(args.serial, args.number, args.env, args.site, args.version)
|
generate_commands(args.serial, args.number, args.env, args.site, args.version)
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
az iot hub device-identity create --device-id DIGIT-TBBHB1044382 --hub-name IotHub-CUBE-PROD --edge-enabled
|
az iot hub device-identity create --device-id DIGIT-TBBHB1044382 --hub-name IotHub-CUBE-PROD --edge-enabled
|
||||||
az iot hub device-twin update --device-id DIGIT-TBBHB1044382 --hub-name IotHub-CUBE-PROD --set tags='{"deviceId":"DIGIT-TBBHB1044382","site":"SASK","number":"1"}'
|
az iot hub device-twin update --device-id DIGIT-TBBHB1044382 --hub-name IotHub-CUBE-PROD --set tags='{"deviceId":"DIGIT-TBBHB1044382","site":"SASK","number":"1"}'
|
||||||
az iot edge set-modules --device-id DIGIT-TBBHB1044382 --hub-name IotHub-CUBE-DEV --content moxa_ac_template.json
|
az iot edge set-modules --device-id DIGIT-TBBHB1044382 --hub-name IotHub-CUBE-DEV --content moxa_ac_template.json
|
||||||
|
|
||||||
This file is a just a note for usual Azure commands involved to create a device.
|
This file is a just a note for usual Azure commands involved to create a device.
|
||||||
@@ -1,71 +1,71 @@
|
|||||||
{
|
{
|
||||||
"modulesContent": {
|
"modulesContent": {
|
||||||
"$edgeAgent": {
|
"$edgeAgent": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
"settings": {}
|
"settings": {}
|
||||||
},
|
},
|
||||||
"systemModules": {
|
"systemModules": {
|
||||||
"edgeAgent": {
|
"edgeAgent": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
},
|
},
|
||||||
"SendRuntimeQualityTelemetry": {
|
"SendRuntimeQualityTelemetry": {
|
||||||
"value": false
|
"value": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.0.10",
|
"image": "mcr.microsoft.com/azureiotedge-agent:1.0.10",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
||||||
},
|
},
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
},
|
},
|
||||||
"edgeHub": {
|
"edgeHub": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.0.10",
|
"image": "mcr.microsoft.com/azureiotedge-hub:1.0.10",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "moxa2019/thingspro-agent:2.1.1-armhf",
|
"image": "moxa2019/thingspro-agent:2.1.1-armhf",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$edgeHub": {
|
"$edgeHub": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"storeAndForwardConfiguration": {
|
"storeAndForwardConfiguration": {
|
||||||
"timeToLiveSecs": 86400
|
"timeToLiveSecs": 86400
|
||||||
},
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"route": {
|
"route": {
|
||||||
"route": "FROM /messages/* INTO $upstream"
|
"route": "FROM /messages/* INTO $upstream"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"properties.desired": {}
|
"properties.desired": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
{
|
{
|
||||||
"modulesContent": {
|
"modulesContent": {
|
||||||
"$edgeAgent": {
|
"$edgeAgent": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
"settings": {}
|
"settings": {}
|
||||||
},
|
},
|
||||||
"systemModules": {
|
"systemModules": {
|
||||||
"edgeAgent": {
|
"edgeAgent": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
},
|
},
|
||||||
"SendRuntimeQualityTelemetry": {
|
"SendRuntimeQualityTelemetry": {
|
||||||
"value": false
|
"value": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.1.4",
|
"image": "mcr.microsoft.com/azureiotedge-agent:1.1.4",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
||||||
},
|
},
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
},
|
},
|
||||||
"edgeHub": {
|
"edgeHub": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.1.4",
|
"image": "mcr.microsoft.com/azureiotedge-hub:1.1.4",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "moxa2019/thingspro-agent:2.2.3-armhf",
|
"image": "moxa2019/thingspro-agent:2.2.3-armhf",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$edgeHub": {
|
"$edgeHub": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"storeAndForwardConfiguration": {
|
"storeAndForwardConfiguration": {
|
||||||
"timeToLiveSecs": 86400
|
"timeToLiveSecs": 86400
|
||||||
},
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"route": {
|
"route": {
|
||||||
"route": "FROM /messages/* INTO $upstream"
|
"route": "FROM /messages/* INTO $upstream"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"properties.desired": {}
|
"properties.desired": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
{
|
{
|
||||||
"modulesContent": {
|
"modulesContent": {
|
||||||
"$edgeAgent": {
|
"$edgeAgent": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
"settings": {}
|
"settings": {}
|
||||||
},
|
},
|
||||||
"systemModules": {
|
"systemModules": {
|
||||||
"edgeAgent": {
|
"edgeAgent": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
},
|
},
|
||||||
"SendRuntimeQualityTelemetry": {
|
"SendRuntimeQualityTelemetry": {
|
||||||
"value": false
|
"value": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.2.7",
|
"image": "mcr.microsoft.com/azureiotedge-agent:1.2.7",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
||||||
},
|
},
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
},
|
},
|
||||||
"edgeHub": {
|
"edgeHub": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.2.7",
|
"image": "mcr.microsoft.com/azureiotedge-hub:1.2.7",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "moxa2019/thingspro-agent:2.2.3-armhf",
|
"image": "moxa2019/thingspro-agent:2.2.3-armhf",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$edgeHub": {
|
"$edgeHub": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"storeAndForwardConfiguration": {
|
"storeAndForwardConfiguration": {
|
||||||
"timeToLiveSecs": 86400
|
"timeToLiveSecs": 86400
|
||||||
},
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"route": {
|
"route": {
|
||||||
"route": "FROM /messages/* INTO $upstream"
|
"route": "FROM /messages/* INTO $upstream"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"properties.desired": {}
|
"properties.desired": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
{
|
{
|
||||||
"modulesContent": {
|
"modulesContent": {
|
||||||
"$edgeAgent": {
|
"$edgeAgent": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
"settings": {}
|
"settings": {}
|
||||||
},
|
},
|
||||||
"systemModules": {
|
"systemModules": {
|
||||||
"edgeAgent": {
|
"edgeAgent": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
},
|
},
|
||||||
"SendRuntimeQualityTelemetry": {
|
"SendRuntimeQualityTelemetry": {
|
||||||
"value": false
|
"value": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.4.10",
|
"image": "mcr.microsoft.com/azureiotedge-agent:1.4.10",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
||||||
},
|
},
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
},
|
},
|
||||||
"edgeHub": {
|
"edgeHub": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.4.10",
|
"image": "mcr.microsoft.com/azureiotedge-hub:1.4.10",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "moxa2019/thingspro-agent:2.2.3-armhf",
|
"image": "moxa2019/thingspro-agent:2.2.3-armhf",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/cloud/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$edgeHub": {
|
"$edgeHub": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"storeAndForwardConfiguration": {
|
"storeAndForwardConfiguration": {
|
||||||
"timeToLiveSecs": 86400
|
"timeToLiveSecs": 86400
|
||||||
},
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"route": {
|
"route": {
|
||||||
"route": "FROM /messages/* INTO $upstream"
|
"route": "FROM /messages/* INTO $upstream"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"properties.desired": {}
|
"properties.desired": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,71 +1,71 @@
|
|||||||
{
|
{
|
||||||
"modulesContent": {
|
"modulesContent": {
|
||||||
"$edgeAgent": {
|
"$edgeAgent": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"runtime": {
|
"runtime": {
|
||||||
"type": "docker",
|
"type": "docker",
|
||||||
"settings": {}
|
"settings": {}
|
||||||
},
|
},
|
||||||
"systemModules": {
|
"systemModules": {
|
||||||
"edgeAgent": {
|
"edgeAgent": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
},
|
},
|
||||||
"SendRuntimeQualityTelemetry": {
|
"SendRuntimeQualityTelemetry": {
|
||||||
"value": false
|
"value": false
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-agent:1.4.27",
|
"image": "mcr.microsoft.com/azureiotedge-agent:1.4.27",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}}}}"
|
||||||
},
|
},
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
},
|
},
|
||||||
"edgeHub": {
|
"edgeHub": {
|
||||||
"env": {
|
"env": {
|
||||||
"UpstreamProtocol": {
|
"UpstreamProtocol": {
|
||||||
"value": "AMQPWS"
|
"value": "AMQPWS"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "mcr.microsoft.com/azureiotedge-hub:1.4.27",
|
"image": "mcr.microsoft.com/azureiotedge-hub:1.4.27",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"PortBindings\":{\"443/tcp\":[{\"HostPort\":\"443\"}],\"5671/tcp\":[{\"HostPort\":\"5671\"}],\"8883/tcp\":[{\"HostPort\":\"8883\"}]}}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"modules": {
|
"modules": {
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"restartPolicy": "always",
|
"restartPolicy": "always",
|
||||||
"settings": {
|
"settings": {
|
||||||
"image": "moxa2019/thingspro-agent:2.2.5-armhf",
|
"image": "moxa2019/thingspro-agent:2.2.5-armhf",
|
||||||
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/azureiotedge/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
"createOptions": "{\"HostConfig\":{\"LogConfig\":{\"Type\":\"json-file\",\"Config\":{\"max-size\":\"10m\",\"max-file\":\"3\"}},\"Binds\":[\"/var/thingspro/apps/azureiotedge/data/setting/:/var/thingspro/cloud/setting/\",\"/run/:/host/run/\",\"/var/thingspro/data/:/var/thingspro/data/\"]}}"
|
||||||
},
|
},
|
||||||
"status": "running",
|
"status": "running",
|
||||||
"type": "docker"
|
"type": "docker"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"$edgeHub": {
|
"$edgeHub": {
|
||||||
"properties.desired": {
|
"properties.desired": {
|
||||||
"schemaVersion": "1.1",
|
"schemaVersion": "1.1",
|
||||||
"storeAndForwardConfiguration": {
|
"storeAndForwardConfiguration": {
|
||||||
"timeToLiveSecs": 86400
|
"timeToLiveSecs": 86400
|
||||||
},
|
},
|
||||||
"routes": {
|
"routes": {
|
||||||
"route": {
|
"route": {
|
||||||
"route": "FROM /messages/* INTO $upstream"
|
"route": "FROM /messages/* INTO $upstream"
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"thingspro-agent": {
|
"thingspro-agent": {
|
||||||
"properties.desired": {}
|
"properties.desired": {}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,23 +1,23 @@
|
|||||||
MIT License
|
MIT License
|
||||||
|
|
||||||
Copyright (c) 2023 Amjad Badar
|
Copyright (c) 2023 Amjad Badar
|
||||||
|
|
||||||
Permission is hereby granted, free of charge, to any person obtaining a copy
|
Permission is hereby granted, free of charge, to any person obtaining a copy
|
||||||
of this software and associated documentation files (the "Software"), to deal
|
of this software and associated documentation files (the "Software"), to deal
|
||||||
in the Software without restriction, including without limitation the rights
|
in the Software without restriction, including without limitation the rights
|
||||||
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
||||||
copies of the Software, and to permit persons to whom the Software is
|
copies of the Software, and to permit persons to whom the Software is
|
||||||
furnished to do so, subject to the following conditions:
|
furnished to do so, subject to the following conditions:
|
||||||
|
|
||||||
The above copyright notice and this permission notice shall be included in all
|
The above copyright notice and this permission notice shall be included in all
|
||||||
copies or substantial portions of the Software.
|
copies or substantial portions of the Software.
|
||||||
|
|
||||||
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
||||||
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
||||||
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
||||||
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
||||||
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
||||||
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
||||||
SOFTWARE.
|
SOFTWARE.
|
||||||
|
|
||||||
Original code modified 2024 Quentin WEPHRE
|
Original code modified 2024 Quentin WEPHRE
|
||||||
@@ -1,95 +1,95 @@
|
|||||||
# ORIGINAL README FROM MOXA
|
# ORIGINAL README FROM MOXA
|
||||||
# COMPLETELY OUTDATED AS OF 06/2024
|
# COMPLETELY OUTDATED AS OF 06/2024
|
||||||
# DOES NOT WORK WITH CURRENT VERSION
|
# DOES NOT WORK WITH CURRENT VERSION
|
||||||
# KEPT FOR INFORMATION AND HISTORICAL DATA
|
# KEPT FOR INFORMATION AND HISTORICAL DATA
|
||||||
|
|
||||||
## Moxa AIG-301- Data Path Configuration
|
## Moxa AIG-301- Data Path Configuration
|
||||||
## Pre-requisites
|
## Pre-requisites
|
||||||
|
|
||||||
|
|
||||||
The following two Excel files from Saft are required
|
The following two Excel files from Saft are required
|
||||||
|
|
||||||
- [ ] 0000123704_SAFT_Generic_Data_Model.xlsx
|
- [ ] 0000123704_SAFT_Generic_Data_Model.xlsx
|
||||||
- [ ] I-Sight_Project_Communication_Network_Config.xlsx
|
- [ ] I-Sight_Project_Communication_Network_Config.xlsx
|
||||||
|
|
||||||
Python Script to generate shell sript from Execel files
|
Python Script to generate shell sript from Execel files
|
||||||
data_path_config.py
|
data_path_config.py
|
||||||
|
|
||||||
Note: The python script and the excel files must be kept in the same directory. The files generated by the python script will be present inside the "Generated_Files" folder.
|
Note: The python script and the excel files must be kept in the same directory. The files generated by the python script will be present inside the "Generated_Files" folder.
|
||||||
Also, make sure the data provided in the Excel sheet is correct. Else it can affect the configuration process.
|
Also, make sure the data provided in the Excel sheet is correct. Else it can affect the configuration process.
|
||||||
|
|
||||||
## Step1
|
## Step1
|
||||||
|
|
||||||
- [ ] The Python Version used for the project development is:
|
- [ ] The Python Version used for the project development is:
|
||||||
'''
|
'''
|
||||||
3.10.9
|
3.10.9
|
||||||
'''
|
'''
|
||||||
|
|
||||||
- [ ] Install all dependencies of the python by running following command:
|
- [ ] Install all dependencies of the python by running following command:
|
||||||
```
|
```
|
||||||
sudo pip3 install -r requirements.txt
|
sudo pip3 install -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
- [ ] Execute python script in the directory where Execl files are located
|
- [ ] Execute python script in the directory where Execl files are located
|
||||||
```
|
```
|
||||||
python3 data_path_config.py
|
python3 data_path_config.py
|
||||||
```
|
```
|
||||||
|
|
||||||
OUTPUT:
|
OUTPUT:
|
||||||
|
|
||||||
On successfull execution of the script, it generates the folder "Generated_Files". The folder contains:
|
On successfull execution of the script, it generates the folder "Generated_Files". The folder contains:
|
||||||
|
|
||||||
1. data_path_configuration_shell_script.sh
|
1. data_path_configuration_shell_script.sh
|
||||||
2. data_config_debug.log
|
2. data_config_debug.log
|
||||||
|
|
||||||
The "data_path_configuration_shell_script.sh" is the script that needs to be executed in the Moxa device for configuring the ThingsPro Edge software.
|
The "data_path_configuration_shell_script.sh" is the script that needs to be executed in the Moxa device for configuring the ThingsPro Edge software.
|
||||||
The "data_config_debug.log" is the log file generated after running the python script and it performs some basic error checks on the given excel files.
|
The "data_config_debug.log" is the log file generated after running the python script and it performs some basic error checks on the given excel files.
|
||||||
|
|
||||||
## Step2
|
## Step2
|
||||||
- [ ] Copy shell script into Moxa gateway in home directory via File Transfer tool example [winscp](https://winscp.net/download/WinSCP-5.21.7-Setup.exe) files
|
- [ ] Copy shell script into Moxa gateway in home directory via File Transfer tool example [winscp](https://winscp.net/download/WinSCP-5.21.7-Setup.exe) files
|
||||||
|
|
||||||
## Step3
|
## Step3
|
||||||
- [ ] Change file mode of shell script to make it executable by executing the following commands:
|
- [ ] Change file mode of shell script to make it executable by executing the following commands:
|
||||||
```
|
```
|
||||||
sudo sed -i -e 's/\r$//' data_path_configuration_shell_script.sh
|
sudo sed -i -e 's/\r$//' data_path_configuration_shell_script.sh
|
||||||
sudo chmod +x data_path_configuration_shell_script.sh
|
sudo chmod +x data_path_configuration_shell_script.sh
|
||||||
|
|
||||||
```
|
```
|
||||||
## Step4
|
## Step4
|
||||||
- [ ] Execute shell script in root directory, otheriwse tpfunc will not deployed
|
- [ ] Execute shell script in root directory, otheriwse tpfunc will not deployed
|
||||||
```
|
```
|
||||||
sudo su
|
sudo su
|
||||||
|
|
||||||
```
|
```
|
||||||
```
|
```
|
||||||
./data_path_configuration_shell_script.sh
|
./data_path_configuration_shell_script.sh
|
||||||
|
|
||||||
```
|
```
|
||||||
## Step5
|
## Step5
|
||||||
|
|
||||||
- [ ] A log report "data_shell_script.log" is generated in the same directory after executing the shell script "data_path_configuration_shell_script.sh". This log report provides information on whether the commands of the shell script were successful or not based on HTTP status codes. Some most common HTTP requests from the log are:
|
- [ ] A log report "data_shell_script.log" is generated in the same directory after executing the shell script "data_path_configuration_shell_script.sh". This log report provides information on whether the commands of the shell script were successful or not based on HTTP status codes. Some most common HTTP requests from the log are:
|
||||||
|
|
||||||
```
|
```
|
||||||
HTTP request 200 or 201 means that command was successfully executed
|
HTTP request 200 or 201 means that command was successfully executed
|
||||||
HTTP request 400 and above means that the command was NOT executed successfully
|
HTTP request 400 and above means that the command was NOT executed successfully
|
||||||
|
|
||||||
```
|
```
|
||||||
Note: An HTTP request of 400 and above can either mean that the data (which is obtained from the provided excel sheets) within the command is Incorrect or that the ThingsPro Edge software is already configured with that data.
|
Note: An HTTP request of 400 and above can either mean that the data (which is obtained from the provided excel sheets) within the command is Incorrect or that the ThingsPro Edge software is already configured with that data.
|
||||||
|
|
||||||
- [ ] Verify results on ThingsPro Edge webGUI
|
- [ ] Verify results on ThingsPro Edge webGUI
|
||||||
|
|
||||||
1) Check Modbus Configuration
|
1) Check Modbus Configuration
|
||||||
2) Check Azure IoT Edge Telemetry
|
2) Check Azure IoT Edge Telemetry
|
||||||
- A seperate topic will be created for each slave
|
- A seperate topic will be created for each slave
|
||||||
3) Tpfunc under Function
|
3) Tpfunc under Function
|
||||||
|
|
||||||
## Additional Information
|
## Additional Information
|
||||||
|
|
||||||
The "Generated_Files" folder in this repository was created by running the python script with the excel sheets in the same repository. It can be used for reference.
|
The "Generated_Files" folder in this repository was created by running the python script with the excel sheets in the same repository. It can be used for reference.
|
||||||
|
|
||||||
The Folder "Screenshots" has images that can be used for reference.
|
The Folder "Screenshots" has images that can be used for reference.
|
||||||
|
|
||||||
Also, each data model in "0000123704_SAFT_Generic_Data_Model.xlsx" file needs to be modified to include an additional column that provides information regarding which commands must be configured for TP function as shown in the screenshot below:
|
Also, each data model in "0000123704_SAFT_Generic_Data_Model.xlsx" file needs to be modified to include an additional column that provides information regarding which commands must be configured for TP function as shown in the screenshot below:
|
||||||
|
|
||||||

|

|
||||||
|
|
||||||
|
|||||||
File diff suppressed because one or more lines are too long
@@ -1,2 +1,2 @@
|
|||||||
pandas==1.4.3
|
pandas==1.4.3
|
||||||
openpyxl==3.1.0
|
openpyxl==3.1.0
|
||||||
|
|||||||
@@ -1,45 +1,49 @@
|
|||||||
from azure.iot.hub import IoTHubRegistryManager
|
from azure.iot.hub import IoTHubRegistryManager
|
||||||
from azure.iot.hub.protocol.models import QuerySpecification
|
from azure.iot.hub.protocol.models import QuerySpecification
|
||||||
from azure.iot.hub.models import CloudToDeviceMethod, CloudToDeviceMethodResult
|
from azure.iot.hub.models import CloudToDeviceMethod, CloudToDeviceMethodResult
|
||||||
|
|
||||||
import json
|
import json
|
||||||
|
|
||||||
module_id = "thingspro-agent"
|
module_id = "thingspro-agent"
|
||||||
method_name = "thingspro-api-v1"
|
method_name = "thingspro-api-v1"
|
||||||
payload = '{"method":"GET", "path":"/device/general"}'
|
payload = '{"method":"GET", "path":"/device/general"}'
|
||||||
|
|
||||||
# Install the Azure IoT Hub SDK:
|
# Install the Azure IoT Hub SDK:
|
||||||
# pip install azure-iot-hub
|
# pip install azure-iot-hub
|
||||||
|
|
||||||
# Authenticate to your Azure account
|
# Authenticate to your Azure account
|
||||||
CONNECTION_STRING = "HostName=IotHub-CUBE-PROD.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey= ..."
|
CONNECTION_STRING = "HostName=IotHub-CUBE-PROD.azure-devices.net;SharedAccessKeyName=iothubowner;SharedAccessKey=...="
|
||||||
if CONNECTION_STRING == "":
|
if CONNECTION_STRING == "":
|
||||||
print("Provide a connection string for the Iot Hub before running the script!")
|
print("Provide a connection string for the Iot Hub before running the script!")
|
||||||
exit(13)
|
exit(13)
|
||||||
|
|
||||||
|
|
||||||
registry_manager = IoTHubRegistryManager.from_connection_string(CONNECTION_STRING)
|
registry_manager = IoTHubRegistryManager.from_connection_string(CONNECTION_STRING)
|
||||||
query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.site != 'QWE' AND tags.number != '0' AND capabilities.iotEdge = true")
|
query_spec = QuerySpecification(query="SELECT * FROM devices WHERE tags.site = 'MYRTLE' AND tags.number != '0' AND capabilities.iotEdge = true")
|
||||||
|
|
||||||
query_result = registry_manager.query_iot_hub(query_spec)
|
query_result = registry_manager.query_iot_hub(query_spec)
|
||||||
devices = []
|
devices = []
|
||||||
for item in query_result.items:
|
for item in query_result.items:
|
||||||
devices.append([int(item.tags['number']), item.tags['deviceId'], item.tags['site']])
|
devices.append([int(item.tags['number']), item.tags['deviceId'], item.tags['site']])
|
||||||
|
|
||||||
ordered_devices = sorted(devices, key = lambda x: (x[2], x[0]))
|
ordered_devices = sorted(devices, key = lambda x: (x[2], x[0]))
|
||||||
|
|
||||||
for i in ordered_devices:
|
for i in ordered_devices:
|
||||||
current_device_modules = registry_manager.get_modules(i[1])
|
current_device_modules = registry_manager.get_modules(i[1])
|
||||||
for module in current_device_modules:
|
for module in current_device_modules:
|
||||||
if module.module_id == module_id:
|
if module.module_id == module_id:
|
||||||
thingspro_module = module
|
thingspro_module = module
|
||||||
if thingspro_module:
|
if thingspro_module:
|
||||||
#print("Found thingspro-agent for " + i[1] + " (" + i[2] + ")")
|
#print("Found thingspro-agent for " + i[1] + " (" + i[2] + ")")
|
||||||
try:
|
try:
|
||||||
direct_method = CloudToDeviceMethod(method_name=method_name, payload=json.loads(payload))
|
direct_method = CloudToDeviceMethod(method_name=method_name, payload=json.loads(payload))
|
||||||
response = registry_manager.invoke_device_module_method(device_id=i[1], module_id=module_id, direct_method_request=direct_method)
|
response = registry_manager.invoke_device_module_method(device_id=i[1], module_id=module_id, direct_method_request=direct_method)
|
||||||
print(str(i[2]), str(i[0]), str(i[1]), response.payload['data']['description'],sep=";")
|
#print(response.payload)
|
||||||
except:
|
if str(i[1]) == str(response.payload['data']['hostName']):
|
||||||
print(str(i[2]), str(i[0]), str(i[1]), "UNREACHABLE",sep=";")
|
print(str(i[2]), str(i[0]), str(i[1]), response.payload['data']['description'], response.payload['data']['firmwareVersion'], sep=";")
|
||||||
else:
|
else:
|
||||||
|
print(str(i[2]), str(i[0]), str(i[1]), response.payload['data']['description'], response.payload['data']['hostName'], response.payload['data']['firmwareVersion'], sep=";")
|
||||||
|
except:
|
||||||
|
print(str(i[2]), str(i[0]), str(i[1]), "UNREACHABLE",sep=";")
|
||||||
|
else:
|
||||||
print("No thingspro-agent available for " + i[1] + " (" + i[2] + ")")
|
print("No thingspro-agent available for " + i[1] + " (" + i[2] + ")")
|
||||||
@@ -1,144 +1,144 @@
|
|||||||
import datetime
|
import datetime
|
||||||
import time
|
import time
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import requests
|
import requests
|
||||||
from urllib3.exceptions import InsecureRequestWarning
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
import jq
|
import jq
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# Function to authenticate and get token
|
# Function to authenticate and get token
|
||||||
def authenticate(device_ip, payload):
|
def authenticate(device_ip, payload):
|
||||||
auth_url = f"https://{device_ip}:8443/api/v1/auth"
|
auth_url = f"https://{device_ip}:8443/api/v1/auth"
|
||||||
response = requests.post(auth_url, json=payload, verify=False)
|
response = requests.post(auth_url, json=payload, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
token = response.json()["data"]["token"]
|
token = response.json()["data"]["token"]
|
||||||
#print(f"Authentication successful. Token received: {token}")
|
#print(f"Authentication successful. Token received: {token}")
|
||||||
print(" authenticated!")
|
print(" authenticated!")
|
||||||
return token
|
return token
|
||||||
else:
|
else:
|
||||||
print(f"Authentication failed. Status code: {response.status_code}")
|
print(f"Authentication failed. Status code: {response.status_code}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Function to send PATCH request
|
# Function to send PATCH request
|
||||||
def send_patch_request(device_ip, token, connection_string):
|
def send_patch_request(device_ip, token, connection_string):
|
||||||
headers = {
|
headers = {
|
||||||
"mx-api-token": token
|
"mx-api-token": token
|
||||||
}
|
}
|
||||||
payload = {
|
payload = {
|
||||||
"provisioning": {
|
"provisioning": {
|
||||||
"source": "manual",
|
"source": "manual",
|
||||||
"connectionString": connection_string,
|
"connectionString": connection_string,
|
||||||
"enable": True
|
"enable": True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge"
|
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge"
|
||||||
response = requests.patch(patch_url, json=payload, headers=headers, verify=False)
|
response = requests.patch(patch_url, json=payload, headers=headers, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
print(f"PATCH request successful for device {device_ip}")
|
print(f"PATCH request successful for device {device_ip}")
|
||||||
else:
|
else:
|
||||||
print(f"Failed to send PATCH request to device {device_ip}. Status code: {response.status_code}")
|
print(f"Failed to send PATCH request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
|
||||||
# Function to send UPGRADE request
|
# Function to send UPGRADE request
|
||||||
def send_upgrade_request(device_ip, token, upgrade_url):
|
def send_upgrade_request(device_ip, token, upgrade_url):
|
||||||
headers = {
|
headers = {
|
||||||
"mx-api-token": token
|
"mx-api-token": token
|
||||||
}
|
}
|
||||||
payload = {
|
payload = {
|
||||||
"deleteFileAfterInstallComplete": True,
|
"deleteFileAfterInstallComplete": True,
|
||||||
"install": True,
|
"install": True,
|
||||||
"url": upgrade_url
|
"url": upgrade_url
|
||||||
}
|
}
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/upgrades"
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades"
|
||||||
response = requests.post(patch_url, json=payload, headers=headers, verify=False)
|
response = requests.post(patch_url, json=payload, headers=headers, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
print(f"POST request successful for device {device_ip}")
|
print(f"POST request successful for device {device_ip}")
|
||||||
else:
|
else:
|
||||||
print(f"Failed to send POST request to device {device_ip}. Status code: {response.status_code}")
|
print(f"Failed to send POST request to device {device_ip}. Status code: {response.status_code}")
|
||||||
print(response.content)
|
print(response.content)
|
||||||
|
|
||||||
# Function to send UPGRADE request
|
# Function to send UPGRADE request
|
||||||
def get_upgrade_jobs(device_ip, token):
|
def get_upgrade_jobs(device_ip, token):
|
||||||
headers = {
|
headers = {
|
||||||
"mx-api-token": token
|
"mx-api-token": token
|
||||||
}
|
}
|
||||||
payload = {
|
payload = {
|
||||||
}
|
}
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/7"
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/7"
|
||||||
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
#print(f"GET request successful for device {device_ip}")
|
#print(f"GET request successful for device {device_ip}")
|
||||||
json_data = json.loads(response.content.decode())
|
json_data = json.loads(response.content.decode())
|
||||||
json_str = json.dumps(json_data, indent=4)
|
json_str = json.dumps(json_data, indent=4)
|
||||||
#print(json_str)
|
#print(json_str)
|
||||||
print(jq.compile('.data.tasks[0].progress').input(json.loads(json_str)).first(), end="% speed: ")
|
print(jq.compile('.data.tasks[0].progress').input(json.loads(json_str)).first(), end="% speed: ")
|
||||||
print(jq.compile('.data.tasks[0].speed').input(json.loads(json_str)).first())
|
print(jq.compile('.data.tasks[0].speed').input(json.loads(json_str)).first())
|
||||||
|
|
||||||
else:
|
else:
|
||||||
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
print(response.content)
|
print(response.content)
|
||||||
|
|
||||||
# Function to send UPGRADE request
|
# Function to send UPGRADE request
|
||||||
def get_API_1(device_ip, token):
|
def get_API_1(device_ip, token):
|
||||||
headers = {
|
headers = {
|
||||||
"mx-api-token": token
|
"mx-api-token": token
|
||||||
}
|
}
|
||||||
payload = {
|
payload = {
|
||||||
}
|
}
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge/messages"
|
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge/messages"
|
||||||
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
#print(f"GET request successful for device {device_ip}")
|
#print(f"GET request successful for device {device_ip}")
|
||||||
#json_data = json.loads(response.content.decode())
|
#json_data = json.loads(response.content.decode())
|
||||||
#json_str = json.dumps(json_data)
|
#json_str = json.dumps(json_data)
|
||||||
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
||||||
parsed = json.loads(response.content.decode())
|
parsed = json.loads(response.content.decode())
|
||||||
print(json.dumps(parsed, indent=4))
|
print(json.dumps(parsed, indent=4))
|
||||||
else:
|
else:
|
||||||
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
print(response.content.decode())
|
print(response.content.decode())
|
||||||
|
|
||||||
|
|
||||||
# Read the Excel file
|
# Read the Excel file
|
||||||
# df = pd.read_excel("")
|
# df = pd.read_excel("")
|
||||||
# df = df[df["device_name"].notnull()]
|
# df = df[df["device_name"].notnull()]
|
||||||
|
|
||||||
# Iterate over each row in the DataFrame
|
# Iterate over each row in the DataFrame
|
||||||
|
|
||||||
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||||
|
|
||||||
payload_auth = {
|
payload_auth = {
|
||||||
"acceptEULA": True,
|
"acceptEULA": True,
|
||||||
"name": "",
|
"name": "",
|
||||||
"password": ""
|
"password": ""
|
||||||
}
|
}
|
||||||
if payload_auth["name"] == "" or payload_auth["password"] == "":
|
if payload_auth["name"] == "" or payload_auth["password"] == "":
|
||||||
print("Provide the credentials before running the script!")
|
print("Provide the credentials before running the script!")
|
||||||
exit(10)
|
exit(10)
|
||||||
ip_address = "10.197.35.116"
|
ip_address = "10.197.35.116"
|
||||||
token = authenticate(ip_address, payload_auth)
|
token = authenticate(ip_address, payload_auth)
|
||||||
upgrade_url = ""#"https://files.thingsprocloud.com/package/moxa-aig-301-series-includes-security-patch-firmware-v1.0.deb.yaml"
|
upgrade_url = ""#"https://files.thingsprocloud.com/package/moxa-aig-301-series-includes-security-patch-firmware-v1.0.deb.yaml"
|
||||||
if upgrade_url == "":
|
if upgrade_url == "":
|
||||||
print("Provide upgrade URL before running the script!")
|
print("Provide upgrade URL before running the script!")
|
||||||
exit(12)
|
exit(12)
|
||||||
if token:
|
if token:
|
||||||
while True:
|
while True:
|
||||||
print(datetime.datetime.now().strftime("%H:%M:%S"), end=" ")
|
print(datetime.datetime.now().strftime("%H:%M:%S"), end=" ")
|
||||||
get_upgrade_jobs(ip_address, token)
|
get_upgrade_jobs(ip_address, token)
|
||||||
time.sleep(60)
|
time.sleep(60)
|
||||||
# for index, row in df.iterrows():
|
# for index, row in df.iterrows():
|
||||||
# device_name = row['device_name']
|
# device_name = row['device_name']
|
||||||
# device_ip_address_https = row['device_ip_address_http']
|
# device_ip_address_https = row['device_ip_address_http']
|
||||||
# connection_string = row['connection_string']
|
# connection_string = row['connection_string']
|
||||||
# upgrade_url = "https://files.thingsprocloud.com/package/moxa-aig-301-series-includes-security-patch-firmware-v1.0.deb.yaml"
|
# upgrade_url = "https://files.thingsprocloud.com/package/moxa-aig-301-series-includes-security-patch-firmware-v1.0.deb.yaml"
|
||||||
|
|
||||||
# # Authenticate and get token
|
# # Authenticate and get token
|
||||||
# payload_auth = {
|
# payload_auth = {
|
||||||
# "acceptEULA": True,
|
# "acceptEULA": True,
|
||||||
# "name": "",
|
# "name": "",
|
||||||
# "password": ""
|
# "password": ""
|
||||||
# }
|
# }
|
||||||
# print(device_name, end="")
|
# print(device_name, end="")
|
||||||
# token = authenticate(device_ip_address_https, payload_auth)
|
# token = authenticate(device_ip_address_https, payload_auth)
|
||||||
# if token:
|
# if token:
|
||||||
# get_API(device_ip_address_https, token)
|
# get_API(device_ip_address_https, token)
|
||||||
# print("\n")
|
# print("\n")
|
||||||
|
|||||||
@@ -1,147 +1,302 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import requests
|
import requests
|
||||||
from urllib3.exceptions import InsecureRequestWarning
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
import jq
|
import jq
|
||||||
import json
|
import json
|
||||||
|
|
||||||
# Function to authenticate and get token
|
# Function to authenticate and get token
|
||||||
def authenticate(device_ip, payload):
|
def authenticate(device_ip, payload):
|
||||||
auth_url = f"https://{device_ip}:8443/api/v1/auth"
|
auth_url = f"https://{device_ip}:8443/api/v1/auth"
|
||||||
response = requests.post(auth_url, json=payload, verify=False)
|
response = requests.post(auth_url, json=payload, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
token = response.json()["data"]["token"]
|
token = response.json()["data"]["token"]
|
||||||
#print(f"Authentication successful. Token received: {token}")
|
#print(f"Authentication successful. Token received: {token}")
|
||||||
print(" authenticated!")
|
#print(" authenticated!")
|
||||||
return token
|
return token
|
||||||
else:
|
else:
|
||||||
print(f"Authentication failed. Status code: {response.status_code}")
|
print(f"Authentication failed. Status code: {response.status_code}")
|
||||||
return None
|
return None
|
||||||
|
|
||||||
# Function to send PATCH request
|
# Function to send PATCH request
|
||||||
def send_patch_request(device_ip, token, connection_string):
|
def send_patch_request(device_ip, token, connection_string):
|
||||||
headers = {
|
headers = {
|
||||||
"mx-api-token": token
|
"mx-api-token": token
|
||||||
}
|
}
|
||||||
payload = {
|
payload = {
|
||||||
"provisioning": {
|
"provisioning": {
|
||||||
"source": "manual",
|
"source": "manual",
|
||||||
"connectionString": connection_string,
|
"connectionString": connection_string,
|
||||||
"enable": True
|
"enable": True
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge"
|
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge"
|
||||||
response = requests.patch(patch_url, json=payload, headers=headers, verify=False)
|
response = requests.patch(patch_url, json=payload, headers=headers, verify=False)
|
||||||
if response.status_code == 200:
|
if response.status_code == 200:
|
||||||
print(f"PATCH request successful for device {device_ip}")
|
print(f"PATCH request successful for device {device_ip}")
|
||||||
else:
|
else:
|
||||||
print(f"Failed to send PATCH request to device {device_ip}. Status code: {response.status_code}")
|
print(f"Failed to send PATCH request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
|
||||||
# Function to send UPGRADE request
|
|
||||||
def send_upgrade_request(device_ip, token, upgrade_url):
|
# Function to send PATCH request
|
||||||
headers = {
|
def patch_time(device_ip, token):
|
||||||
"mx-api-token": token
|
headers = {
|
||||||
}
|
"mx-api-token": token
|
||||||
payload = {
|
}
|
||||||
"deleteFileAfterInstallComplete": True,
|
# payload = {
|
||||||
"install": True,
|
# "ntp": {
|
||||||
"url": upgrade_url
|
# "source": "timeserver",
|
||||||
}
|
# "server": "10.84.171.254",
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/upgrades"
|
# "enable": True
|
||||||
response = requests.post(patch_url, json=payload, headers=headers, verify=False)
|
# }
|
||||||
if response.status_code == 200:
|
# }
|
||||||
print(f"POST request successful for device {device_ip}")
|
payload = {
|
||||||
else:
|
"timezone": "America/Chicago"
|
||||||
print(f"Failed to send POST request to device {device_ip}. Status code: {response.status_code}")
|
}
|
||||||
print(response.content)
|
patch_url = f"https://{device_ip}:8443/api/v1/device/time"
|
||||||
|
response = requests.patch(patch_url, json=payload, headers=headers, verify=False)
|
||||||
# Function to send UPGRADE request
|
if response.status_code == 200:
|
||||||
def get_upgrade_jobs(device_ip, token):
|
json_data = json.loads(response.content.decode())
|
||||||
headers = {
|
time = json_data['data']['time']
|
||||||
"mx-api-token": token
|
timezone = json_data['data']['timezone']
|
||||||
}
|
last = json_data['data']['lastUpdateTime']
|
||||||
payload = {
|
server = json_data['data']['ntp']['server']
|
||||||
}
|
enabled = json_data['data']['ntp']['enable']
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/2"
|
print(time + " " + timezone + " " + last + " " + server + " " + str(enabled))
|
||||||
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
else:
|
||||||
if response.status_code == 200:
|
json_data = json.loads(response.content.decode())
|
||||||
#print(f"GET request successful for device {device_ip}")
|
#print(json.dumps(json_data, indent=2))
|
||||||
json_data = json.loads(response.content.decode())
|
|
||||||
json_str = json.dumps(json_data)
|
|
||||||
print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
# Function to send UPGRADE request
|
||||||
else:
|
def send_upgrade_request(device_ip, token, upgrade_url):
|
||||||
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
headers = {
|
||||||
print(response.content)
|
"mx-api-token": token
|
||||||
|
}
|
||||||
# Function to send UPGRADE request
|
payload = {
|
||||||
def put_API(device_ip, token):
|
"download": True,
|
||||||
headers = {
|
"install": True,
|
||||||
"mx-api-token": token
|
"url": upgrade_url,
|
||||||
}
|
}
|
||||||
payload = {
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades"
|
||||||
}
|
response = requests.post(patch_url, json=payload, headers=headers, verify=False)
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge/reset"
|
json_data = json.loads(response.content.decode())
|
||||||
response = requests.put(patch_url, json=payload, headers=headers, verify=False)
|
id = json_data['data']['id']
|
||||||
if response.status_code == 200:
|
return id
|
||||||
#print(f"GET request successful for device {device_ip}")
|
|
||||||
#json_data = json.loads(response.content.decode())
|
# Function to send UPGRADE request
|
||||||
#json_str = json.dumps(json_data)
|
def get_upgrade_job(device_ip, token, id):
|
||||||
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
headers = {
|
||||||
print(response.content.decode())
|
"mx-api-token": token
|
||||||
else:
|
}
|
||||||
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
payload = {
|
||||||
print(response.content.decode())
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/{id}"
|
||||||
def get_API(device_ip, token):
|
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
||||||
headers = {
|
if response.status_code == 200:
|
||||||
"mx-api-token": token
|
#print(f"GET request successful for device {device_ip}")
|
||||||
}
|
#print(json_str)
|
||||||
payload = {
|
#print(json_data['data'][json_data['count'] - 1]['parameter']['url'], json_data['data'][json_data['count'] - 1]['state'], json_data['count'])
|
||||||
}
|
json_data = json.loads(response.content.decode())
|
||||||
patch_url = f"https://{device_ip}:8443/api/v1/azure-iotedge"
|
getid = json_data['data']['id']
|
||||||
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
created = json_data['data']['createdAt']
|
||||||
if response.status_code == 200:
|
cur_status = json_data['data']['state']
|
||||||
#print(f"GET request successful for device {device_ip}")
|
current_tasks = json_data['data']['completedTask']
|
||||||
#json_data = json.loads(response.content.decode())
|
total_tasks = json_data['data']['totalTask']
|
||||||
#json_str = json.dumps(json_data)
|
print("JOB #" + str(getid) + " " + str(current_tasks) + "/" + str(total_tasks))
|
||||||
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
print("CREATED ON: " + str(created))
|
||||||
print(response.content.decode())
|
print("CURRENT STATUS: " + str(cur_status))
|
||||||
else:
|
print(json.dumps(json_data, indent=2))
|
||||||
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
else:
|
||||||
print(response.content.decode())
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
print(response.content)
|
||||||
# Read the Excel file
|
|
||||||
excel_file_path = ""
|
def get_upgrade_jobs(device_ip, token):
|
||||||
if excel_file_path == "":
|
headers = {
|
||||||
print("Provide Excel file path before running the script!")
|
"mx-api-token": token
|
||||||
exit(11)
|
}
|
||||||
df = pd.read_excel(excel_file_path)
|
payload = {
|
||||||
df = df[df["device_name"].notnull()]
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades"
|
||||||
# Iterate over each row in the DataFrame
|
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
||||||
|
if response.status_code == 200:
|
||||||
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
#print(f"GET request successful for device {device_ip}")
|
||||||
|
#print(json_str)
|
||||||
for index, row in df.iterrows():
|
#print(json_data['data'][json_data['count'] - 1]['parameter']['url'], json_data['data'][json_data['count'] - 1]['state'], json_data['count'])
|
||||||
device_name = row['device_name']
|
json_data = json.loads(response.content.decode())
|
||||||
device_ip_address_https = row['device_ip_address_http']
|
count = json_data['count']
|
||||||
connection_string = row['connection_string']
|
print(str(count))
|
||||||
upgrade_url = "" #https://files.thingsprocloud.com/package/moxa-aig-301-series-includes-security-patch-firmware-v1.0.deb.yaml
|
for i in range(count):
|
||||||
if upgrade_url == "":
|
getid = json_data['data'][i]['id']
|
||||||
print("Provide upgrade URL before running the script!")
|
created = json_data['data'][i]['createdAt']
|
||||||
exit(12)
|
cur_status = json_data['data'][i]['state']
|
||||||
|
current_tasks = json_data['data'][i]['completedTask']
|
||||||
|
total_tasks = json_data['data'][i]['totalTask']
|
||||||
# Authenticate and get token
|
print("JOB #" + str(getid) + " " + str(current_tasks) + "/" + str(total_tasks))
|
||||||
payload_auth = {
|
print("CREATED ON: " + str(created))
|
||||||
"acceptEULA": True,
|
print("CURRENT STATUS: " + str(cur_status))
|
||||||
"name": "",
|
else:
|
||||||
"password": ""
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
}
|
print(response.content)
|
||||||
if payload_auth["name"] == "" or payload_auth["password"] == "":
|
|
||||||
print("Provide the credentials before running the script!")
|
# Function to send UPGRADE request
|
||||||
exit(10)
|
def start_upgrade_job(device_ip, token, id):
|
||||||
print(device_name, end="")
|
headers = {
|
||||||
token = authenticate(device_ip_address_https, payload_auth)
|
"mx-api-token": token
|
||||||
if token:
|
}
|
||||||
get_API(device_ip_address_https, token)
|
payload = {
|
||||||
print("\n")
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/{id}/start"
|
||||||
|
response = requests.put(patch_url, json=payload, headers=headers, verify=False)
|
||||||
|
if response.status_code == 200:
|
||||||
|
json_data = json.loads(response.content.decode())
|
||||||
|
curid = json_data['data']['id']
|
||||||
|
startedat = json_data['data']['startedAt']
|
||||||
|
print("Job #" + str(curid) + " started on " + str(startedat))
|
||||||
|
else:
|
||||||
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
print(response.content.decode())
|
||||||
|
|
||||||
|
# Function to send UPGRADE request
|
||||||
|
def put_API(device_ip, token):
|
||||||
|
headers = {
|
||||||
|
"mx-api-token": token
|
||||||
|
}
|
||||||
|
payload = {
|
||||||
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/3/start"
|
||||||
|
response = requests.put(patch_url, json=payload, headers=headers, verify=False)
|
||||||
|
if response.status_code == 200:
|
||||||
|
#print(f"GET request successful for device {device_ip}")
|
||||||
|
#json_data = json.loads(response.content.decode())
|
||||||
|
#json_str = json.dumps(json_data)
|
||||||
|
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
||||||
|
json_data = json.loads(response.content.decode())
|
||||||
|
print(json_data['data']['firmwareVersion'])
|
||||||
|
else:
|
||||||
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
print(response.content.decode())
|
||||||
|
|
||||||
|
def get_API(device_ip, token):
|
||||||
|
headers = {
|
||||||
|
"mx-api-token": token
|
||||||
|
}
|
||||||
|
payload = {
|
||||||
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/device/general"
|
||||||
|
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
||||||
|
if response.status_code == 200:
|
||||||
|
#print(f"GET request successful for device {device_ip}")
|
||||||
|
#json_data = json.loads(response.content.decode())
|
||||||
|
#json_str = json.dumps(json_data)
|
||||||
|
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
||||||
|
json_data = json.loads(response.content.decode())
|
||||||
|
hostname = json_data['data']['hostName']
|
||||||
|
serial = json_data['data']['serialNumber']
|
||||||
|
version = json_data['data']['firmwareVersion']
|
||||||
|
description = json_data['data']['description']
|
||||||
|
print(hostname + " " + serial + " " + version + " " + description)
|
||||||
|
#json_str = json.dumps(json_data, indent=2)
|
||||||
|
#print(json_str)
|
||||||
|
else:
|
||||||
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
print(response.content.decode())
|
||||||
|
|
||||||
|
def get_time(device_ip, token):
|
||||||
|
headers = {
|
||||||
|
"mx-api-token": token
|
||||||
|
}
|
||||||
|
payload = {
|
||||||
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/device/time"
|
||||||
|
response = requests.get(patch_url, json=payload, headers=headers, verify=False)
|
||||||
|
if response.status_code == 200:
|
||||||
|
#print(f"GET request successful for device {device_ip}")
|
||||||
|
#json_data = json.loads(response.content.decode())
|
||||||
|
#json_str = json.dumps(json_data)
|
||||||
|
#print(jq.compile('.data.completedAt').input(json.loads(json_str)).first())
|
||||||
|
json_data = json.loads(response.content.decode())
|
||||||
|
time = json_data['data']['time']
|
||||||
|
timezone = json_data['data']['timezone']
|
||||||
|
last = json_data['data']['lastUpdateTime']
|
||||||
|
print(time + " " + timezone + " " + last)
|
||||||
|
#json_str = json.dumps(json_data, indent=2)
|
||||||
|
#print(json_str)
|
||||||
|
else:
|
||||||
|
print(f"Failed to send GET request to device {device_ip}. Status code: {response.status_code}")
|
||||||
|
print(response.content.decode())
|
||||||
|
|
||||||
|
def delete_API(device_ip, token):
|
||||||
|
headers = {
|
||||||
|
"mx-api-token": token
|
||||||
|
}
|
||||||
|
payload = {
|
||||||
|
}
|
||||||
|
patch_url = f"https://{device_ip}:8443/api/v1/upgrades/5"
|
||||||
|
response = requests.delete(patch_url, json=payload, headers=headers, verify=False)
|
||||||
|
print(response.status_code)
|
||||||
|
json_data = json.loads(response.content.decode())
|
||||||
|
json_str = json.dumps(json_data, indent=2)
|
||||||
|
print(json_str)
|
||||||
|
|
||||||
|
# Read the Excel file
|
||||||
|
# excel_file_path = ""
|
||||||
|
# if excel_file_path == "":
|
||||||
|
# print("Provide Excel file path before running the script!")
|
||||||
|
# exit(11)
|
||||||
|
# df = pd.read_excel(excel_file_path)
|
||||||
|
# df = df[df["device_name"].notnull()]
|
||||||
|
|
||||||
|
# Iterate over each row in the DataFrame
|
||||||
|
|
||||||
|
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||||
|
|
||||||
|
# for index, row in df.iterrows():
|
||||||
|
# device_name = row['device_name']
|
||||||
|
# device_ip_address_https = row['device_ip_address_http']
|
||||||
|
# connection_string = row['connection_string']
|
||||||
|
# upgrade_url = "" #https://files.thingsprocloud.com/package/moxa-aig-301-series-includes-security-patch-firmware-v1.0.deb.yaml
|
||||||
|
# if upgrade_url == "":
|
||||||
|
# print("Provide upgrade URL before running the script!")
|
||||||
|
# exit(12)
|
||||||
|
|
||||||
|
|
||||||
|
# # Authenticate and get token
|
||||||
|
# payload_auth = {
|
||||||
|
# "acceptEULA": True,
|
||||||
|
# "name": "",
|
||||||
|
# "password": ""
|
||||||
|
# }
|
||||||
|
# if payload_auth["name"] == "" or payload_auth["password"] == "":
|
||||||
|
# print("Provide the credentials before running the script!")
|
||||||
|
# exit(10)
|
||||||
|
# print(device_name, end="")
|
||||||
|
# token = authenticate(device_ip_address_https, payload_auth)
|
||||||
|
# if token:
|
||||||
|
# get_API(device_ip_address_https, token)
|
||||||
|
# print("\n")
|
||||||
|
|
||||||
|
|
||||||
|
for i in range(193, 222):
|
||||||
|
upgrade_url = "https://files.thingsprocloud.com/package/Upgrade_AIG-301_2.4.0-4020_IMG_1.4_to_1.5.deb.yaml"
|
||||||
|
payload_auth = {
|
||||||
|
"acceptEULA": True,
|
||||||
|
"name": "admin",
|
||||||
|
"password": "admin@123"
|
||||||
|
}
|
||||||
|
|
||||||
|
device_ip_address = str("10.84.171." + str(i))
|
||||||
|
|
||||||
|
#print(device_ip_address, end="")
|
||||||
|
token = authenticate(device_ip_address, payload_auth)
|
||||||
|
if token:
|
||||||
|
#id = send_upgrade_request(device_ip_address,token,upgrade_url)
|
||||||
|
#print(id)
|
||||||
|
#get_upgrade_job(device_ip_address, token, 6)
|
||||||
|
#start_upgrade_job(device_ip_address, token, id)
|
||||||
|
#put_API(device_ip_address, token)
|
||||||
|
#patch_time(device_ip_address,token)
|
||||||
|
#get_time(device_ip_address, token)
|
||||||
|
#delete_API(device_ip_address,token)
|
||||||
|
get_API(device_ip_address, token)
|
||||||
|
else:
|
||||||
|
print("Authentication failed!")
|
||||||
@@ -1,104 +1,112 @@
|
|||||||
import pandas as pd
|
import pandas as pd
|
||||||
import requests
|
import requests
|
||||||
from urllib3.exceptions import InsecureRequestWarning
|
from urllib3.exceptions import InsecureRequestWarning
|
||||||
import jq
|
import json
|
||||||
import json
|
import scp
|
||||||
import scp
|
import paramiko
|
||||||
import paramiko
|
|
||||||
|
def scp_file(local_path, remote_path, hostname, username, password):
|
||||||
def scp_file(local_path, remote_path, hostname, username, password):
|
try:
|
||||||
try:
|
# Create a new SSH client
|
||||||
# Create a new SSH client
|
ssh_client = paramiko.SSHClient()
|
||||||
ssh_client = paramiko.SSHClient()
|
|
||||||
|
# Automatically add the server's host key
|
||||||
# Automatically add the server's host key
|
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
||||||
|
# Connect to the server
|
||||||
# Connect to the server
|
ssh_client.connect(hostname, username=username, password=password)
|
||||||
ssh_client.connect(hostname, username=username, password=password)
|
|
||||||
|
# Use SCP to transfer the file
|
||||||
# Use SCP to transfer the file
|
with scp.SCPClient(ssh_client.get_transport()) as scp_client:
|
||||||
with scp.SCPClient(ssh_client.get_transport()) as scp_client:
|
scp_client.put(local_path, remote_path)
|
||||||
scp_client.put(local_path, remote_path)
|
|
||||||
|
print("File transferred successfully")
|
||||||
print("File transferred successfully")
|
|
||||||
|
except Exception as e:
|
||||||
except Exception as e:
|
print(f"Error: {e}")
|
||||||
print(f"Error: {e}")
|
|
||||||
|
finally:
|
||||||
finally:
|
# Close the SSH connection
|
||||||
# Close the SSH connection
|
ssh_client.close()
|
||||||
ssh_client.close()
|
|
||||||
|
def ssh_execute_command_with_password(hostname, username, password, command):
|
||||||
def ssh_execute_command_with_password(hostname, username, password, command):
|
try:
|
||||||
try:
|
# Create a new SSH client
|
||||||
# Create a new SSH client
|
ssh_client = paramiko.SSHClient()
|
||||||
ssh_client = paramiko.SSHClient()
|
|
||||||
|
# Automatically add the server's host key
|
||||||
# Automatically add the server's host key
|
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
|
||||||
|
# Connect to the server
|
||||||
# Connect to the server
|
ssh_client.connect(hostname, username=username, password=password)
|
||||||
ssh_client.connect(hostname, username=username, password=password)
|
|
||||||
|
# Execute the command with sudo -S to read password from stdin
|
||||||
# Execute the command with sudo -S to read password from stdin
|
stdin, stdout, stderr = ssh_client.exec_command('sudo -k -S ' + command)
|
||||||
stdin, stdout, stderr = ssh_client.exec_command('sudo -k -S ' + command)
|
stdin.write(password + '\n')
|
||||||
stdin.write(password + '\n')
|
stdin.flush()
|
||||||
stdin.flush()
|
|
||||||
|
# Read the output
|
||||||
# Read the output
|
output = stdout.read().decode('utf-8')
|
||||||
output = stdout.read().decode('utf-8')
|
error = stderr.read().decode('utf-8')
|
||||||
error = stderr.read().decode('utf-8')
|
|
||||||
|
# Print output and errors, if any
|
||||||
# Print output and errors, if any
|
if output:
|
||||||
if output:
|
print("Command output:")
|
||||||
print("Command output:")
|
print(output)
|
||||||
print(output)
|
if error:
|
||||||
if error:
|
print("Command error:")
|
||||||
print("Command error:")
|
print(error)
|
||||||
print(error)
|
|
||||||
|
print("Command executed successfully")
|
||||||
print("Command executed successfully")
|
|
||||||
|
except Exception as e:
|
||||||
except Exception as e:
|
print(f"Error: {e}")
|
||||||
print(f"Error: {e}")
|
|
||||||
|
finally:
|
||||||
finally:
|
# Close the SSH connection
|
||||||
# Close the SSH connection
|
ssh_client.close()
|
||||||
ssh_client.close()
|
|
||||||
|
# Read the Excel file
|
||||||
# Read the Excel file
|
# excel_file_path = ""
|
||||||
excel_file_path = ""
|
# if excel_file_path == "":
|
||||||
if excel_file_path == "":
|
# print("Provide Excel file path before running the script!")
|
||||||
print("Provide Excel file path before running the script!")
|
# exit(11)
|
||||||
exit(11)
|
# df = pd.read_excel(excel_file_path)
|
||||||
df = pd.read_excel(excel_file_path)
|
# df = df[df["device_name"].notnull()]
|
||||||
df = df[df["device_name"].notnull()]
|
|
||||||
|
# Iterate over each row in the DataFrame
|
||||||
# Iterate over each row in the DataFrame
|
|
||||||
|
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
||||||
requests.packages.urllib3.disable_warnings(category=InsecureRequestWarning)
|
|
||||||
|
local_file_path = "AIG-301_1.5.2-20240625_saft1_armhf.deb"
|
||||||
local_file_path = ""#"./azureiotedge_2.4.0-2697_armhf.mpkg"
|
if local_file_path == "":
|
||||||
if local_file_path == "":
|
print("Provide upgrade file path before running the script!")
|
||||||
print("Provide upgrade file path before running the script!")
|
exit(12)
|
||||||
exit(12)
|
remote_file_path = "./."
|
||||||
remote_file_path = "./."
|
username = "moxa"
|
||||||
username = ""
|
password = "moxa"
|
||||||
password = ""
|
if username == "" or password == "":
|
||||||
if username == "" or password == "":
|
print("Provide credentials before running the script!")
|
||||||
print("Provide credentials before running the script!")
|
exit(10)
|
||||||
exit(10)
|
|
||||||
|
command = ""#"appman app install azureiotedge_2.4.0-2697_armhf.mpkg"
|
||||||
command = ""#"appman app install azureiotedge_2.4.0-2697_armhf.mpkg"
|
if command == "dpkg -i AIG-301_1.5.2-20240625_saft1_armhf.deb":
|
||||||
if command == "":
|
print("Provide a command to execute before running the script!")
|
||||||
print("Provide a command to execute before running the script!")
|
exit(11)
|
||||||
exit(11)
|
|
||||||
|
# for index, row in df.iterrows():
|
||||||
for index, row in df.iterrows():
|
# device_name = row['device_name']
|
||||||
device_name = row['device_name']
|
# device_ip_address_https = row['device_ip_address_http']
|
||||||
device_ip_address_https = row['device_ip_address_http']
|
# print(device_name)
|
||||||
print(device_name)
|
# #ssh_execute_command_with_password(device_ip_address_https, username, password, command)
|
||||||
ssh_execute_command_with_password(device_ip_address_https, username, password, command)
|
# print("\n")
|
||||||
print("\n")
|
|
||||||
|
|
||||||
|
for i in range(131, 160):
|
||||||
|
device_ip_address = str("10.84.157." + str(i))
|
||||||
|
print(device_ip_address, end="")
|
||||||
|
if i == 136 or i == 138 or i == 151:
|
||||||
|
print(" DONE")
|
||||||
|
else:
|
||||||
|
print(" TODO")
|
||||||
|
scp_file(local_file_path, remote_file_path, device_ip_address, username, password)
|
||||||
@@ -1,87 +1,87 @@
|
|||||||
import paramiko
|
import paramiko
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import getpass
|
import getpass
|
||||||
import re
|
import re
|
||||||
import time
|
import time
|
||||||
import json
|
import json
|
||||||
|
|
||||||
def read_excel(filename, column_name):
|
def read_excel(filename, column_name):
|
||||||
df = pd.read_excel(filename)
|
df = pd.read_excel(filename)
|
||||||
df = df[df["device_name"].notnull()]
|
df = df[df["device_name"].notnull()]
|
||||||
global names
|
global names
|
||||||
global ips
|
global ips
|
||||||
global connections
|
global connections
|
||||||
names = df["device_name"].tolist()
|
names = df["device_name"].tolist()
|
||||||
ips = df["device_ip_address_http"].tolist()
|
ips = df["device_ip_address_http"].tolist()
|
||||||
connections = df["connection_string"].tolist()
|
connections = df["connection_string"].tolist()
|
||||||
return ips
|
return ips
|
||||||
|
|
||||||
def ssh_execute_commands(device_ip, username, password, commands, connection):
|
def ssh_execute_commands(device_ip, username, password, commands, connection):
|
||||||
ssh_client = paramiko.SSHClient()
|
ssh_client = paramiko.SSHClient()
|
||||||
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
ssh_client.set_missing_host_key_policy(paramiko.AutoAddPolicy())
|
||||||
ssh_client.connect(device_ip, username=username, password=password)
|
ssh_client.connect(device_ip, username=username, password=password)
|
||||||
transport = ssh_client.get_transport()
|
transport = ssh_client.get_transport()
|
||||||
session = transport.open_session()
|
session = transport.open_session()
|
||||||
session.set_combine_stderr(True)
|
session.set_combine_stderr(True)
|
||||||
session.get_pty()
|
session.get_pty()
|
||||||
session.exec_command("sudo cat /var/thingspro/data/mx-api-token")
|
session.exec_command("sudo cat /var/thingspro/data/mx-api-token")
|
||||||
stdin = session.makefile('wb', -1)
|
stdin = session.makefile('wb', -1)
|
||||||
stdout = session.makefile('rb', -1)
|
stdout = session.makefile('rb', -1)
|
||||||
stdin.write(password + '\n')
|
stdin.write(password + '\n')
|
||||||
stdin.flush()
|
stdin.flush()
|
||||||
for line in stdout.read().splitlines():
|
for line in stdout.read().splitlines():
|
||||||
if not re.search('[Pp]assword', line.decode()):
|
if not re.search('[Pp]assword', line.decode()):
|
||||||
token = line.decode()
|
token = line.decode()
|
||||||
|
|
||||||
# session = transport.open_session()
|
# session = transport.open_session()
|
||||||
# session.set_combine_stderr(True)
|
# session.set_combine_stderr(True)
|
||||||
# session.get_pty()
|
# session.get_pty()
|
||||||
# session.exec_command('curl -k -X PUT https://127.0.0.1:8443/api/v1/azure-iotedge/reset -H "Content-Type: application/json" -H "mx-api-token: ' + token + '"')
|
# session.exec_command('curl -k -X PUT https://127.0.0.1:8443/api/v1/azure-iotedge/reset -H "Content-Type: application/json" -H "mx-api-token: ' + token + '"')
|
||||||
# stdout = session.makefile('rb', -1)
|
# stdout = session.makefile('rb', -1)
|
||||||
# for line in stdout.read().splitlines():
|
# for line in stdout.read().splitlines():
|
||||||
# print(line.decode())
|
# print(line.decode())
|
||||||
print("\n" + connection + "\n")
|
print("\n" + connection + "\n")
|
||||||
|
|
||||||
print(token + "\n")
|
print(token + "\n")
|
||||||
|
|
||||||
jq_data = {}
|
jq_data = {}
|
||||||
jq_data_2 = {}
|
jq_data_2 = {}
|
||||||
jq_data_2["source"] = "manual"
|
jq_data_2["source"] = "manual"
|
||||||
jq_data_2["connectionString"] = connection
|
jq_data_2["connectionString"] = connection
|
||||||
jq_data_2["enable"] = True
|
jq_data_2["enable"] = True
|
||||||
jq_data["provisioning"] = jq_data_2
|
jq_data["provisioning"] = jq_data_2
|
||||||
json_object = json.dumps(jq_data)
|
json_object = json.dumps(jq_data)
|
||||||
print(json_object + "\n")
|
print(json_object + "\n")
|
||||||
|
|
||||||
session = transport.open_session()
|
session = transport.open_session()
|
||||||
session.set_combine_stderr(True)
|
session.set_combine_stderr(True)
|
||||||
session.get_pty()
|
session.get_pty()
|
||||||
# -H "Content-Type: application/json" -H "mx-api-token:$(token)'
|
# -H "Content-Type: application/json" -H "mx-api-token:$(token)'
|
||||||
session.exec_command('curl -k -X PATCH https://127.0.0.1:8443/api/v1/azure-iotedge -H "Content-Type: application/json" -H "mx-api-token: ' + token + '" -d "' + str(json_object) + '"')
|
session.exec_command('curl -k -X PATCH https://127.0.0.1:8443/api/v1/azure-iotedge -H "Content-Type: application/json" -H "mx-api-token: ' + token + '" -d "' + str(json_object) + '"')
|
||||||
stdout = session.makefile('rb', -1)
|
stdout = session.makefile('rb', -1)
|
||||||
for line in stdout.read().splitlines():
|
for line in stdout.read().splitlines():
|
||||||
print(line.decode())
|
print(line.decode())
|
||||||
|
|
||||||
def main():
|
def main():
|
||||||
filename = ""
|
filename = ""
|
||||||
if filename == "":
|
if filename == "":
|
||||||
print("Provide Excel file path before running the script!")
|
print("Provide Excel file path before running the script!")
|
||||||
exit(11)
|
exit(11)
|
||||||
column_name = "device_ip_address_http"
|
column_name = "device_ip_address_http"
|
||||||
global names
|
global names
|
||||||
global ips
|
global ips
|
||||||
global connections
|
global connections
|
||||||
devices = read_excel(filename, column_name)
|
devices = read_excel(filename, column_name)
|
||||||
username = input("Enter SSH username: ")
|
username = input("Enter SSH username: ")
|
||||||
password = input("Enter SSH password: ")
|
password = input("Enter SSH password: ")
|
||||||
print(names)
|
print(names)
|
||||||
commands = ["sudo bash"] # Add your commands here
|
commands = ["sudo bash"] # Add your commands here
|
||||||
|
|
||||||
for i, device in enumerate(names):
|
for i, device in enumerate(names):
|
||||||
print(f"Connecting to gateway #{i} {device} ({ips[i]})...")
|
print(f"Connecting to gateway #{i} {device} ({ips[i]})...")
|
||||||
ssh_execute_commands(ips[i], username, password, commands, connections[i])
|
ssh_execute_commands(ips[i], username, password, commands, connections[i])
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
names = []
|
names = []
|
||||||
ips = []
|
ips = []
|
||||||
main()
|
main()
|
||||||
|
|||||||
@@ -1,83 +1,83 @@
|
|||||||
#!/usr/bin/env python3
|
#!/usr/bin/env python3
|
||||||
import asyncio
|
import asyncio
|
||||||
import logging
|
import logging
|
||||||
|
|
||||||
import server_async
|
import server_async
|
||||||
import time
|
import time
|
||||||
import math
|
import math
|
||||||
|
|
||||||
from pymodbus.payload import BinaryPayloadBuilder
|
from pymodbus.payload import BinaryPayloadBuilder
|
||||||
from pymodbus.constants import Endian
|
from pymodbus.constants import Endian
|
||||||
|
|
||||||
from pymodbus.datastore import (
|
from pymodbus.datastore import (
|
||||||
ModbusSequentialDataBlock,
|
ModbusSequentialDataBlock,
|
||||||
ModbusServerContext,
|
ModbusServerContext,
|
||||||
ModbusSlaveContext,
|
ModbusSlaveContext,
|
||||||
)
|
)
|
||||||
|
|
||||||
|
|
||||||
_logger = logging.getLogger(__name__)
|
_logger = logging.getLogger(__name__)
|
||||||
|
|
||||||
|
|
||||||
async def updating_task(context):
|
async def updating_task(context):
|
||||||
# parameters
|
# parameters
|
||||||
fc_as_hex = 3
|
fc_as_hex = 3
|
||||||
slave_id = 0x00
|
slave_id = 0x00
|
||||||
address = 0x00
|
address = 0x00
|
||||||
count = 100
|
count = 100
|
||||||
|
|
||||||
# initialization: set values to zero
|
# initialization: set values to zero
|
||||||
values = context[slave_id].getValues(fc_as_hex, address, count=count)
|
values = context[slave_id].getValues(fc_as_hex, address, count=count)
|
||||||
values = [0 for v in values]
|
values = [0 for v in values]
|
||||||
|
|
||||||
# infinite loop updating every register to its sine value (period 1 hour, amplitude according to register number)
|
# infinite loop updating every register to its sine value (period 1 hour, amplitude according to register number)
|
||||||
while True:
|
while True:
|
||||||
await asyncio.sleep(1)
|
await asyncio.sleep(1)
|
||||||
current_time = time.time()
|
current_time = time.time()
|
||||||
sine_value = sin_wave(current_time)
|
sine_value = sin_wave(current_time)
|
||||||
# BinaryPayloadBuilder is used to convert a float to two Modbus registers
|
# BinaryPayloadBuilder is used to convert a float to two Modbus registers
|
||||||
builder = BinaryPayloadBuilder(byteorder=Endian.LITTLE)
|
builder = BinaryPayloadBuilder(byteorder=Endian.LITTLE)
|
||||||
for i in range(address, count):
|
for i in range(address, count):
|
||||||
builder.add_32bit_float((i+1) * sine_value)
|
builder.add_32bit_float((i+1) * sine_value)
|
||||||
payload = builder.to_registers()
|
payload = builder.to_registers()
|
||||||
# once the registers of all the sine waves are created, update the values in the simulator
|
# once the registers of all the sine waves are created, update the values in the simulator
|
||||||
context[slave_id].setValues(fc_as_hex, address, payload)
|
context[slave_id].setValues(fc_as_hex, address, payload)
|
||||||
|
|
||||||
# sin wave value calculator
|
# sin wave value calculator
|
||||||
period = 3600
|
period = 3600
|
||||||
def sin_wave(time_elapsed):
|
def sin_wave(time_elapsed):
|
||||||
return math.sin(2 * math.pi * time_elapsed / period)
|
return math.sin(2 * math.pi * time_elapsed / period)
|
||||||
|
|
||||||
|
|
||||||
# server start setup function
|
# server start setup function
|
||||||
def setup_updating_server(cmdline=None):
|
def setup_updating_server(cmdline=None):
|
||||||
# define the registers
|
# define the registers
|
||||||
num_floats = 100
|
num_floats = 100
|
||||||
float_values = [float(i + 0.5) for i in range(num_floats)]
|
float_values = [float(i + 0.5) for i in range(num_floats)]
|
||||||
builder = BinaryPayloadBuilder(byteorder=Endian.LITTLE)
|
builder = BinaryPayloadBuilder(byteorder=Endian.LITTLE)
|
||||||
for value in float_values:
|
for value in float_values:
|
||||||
builder.add_32bit_float(value)
|
builder.add_32bit_float(value)
|
||||||
payload = builder.to_registers()
|
payload = builder.to_registers()
|
||||||
|
|
||||||
# create a Modbus simulator with the previously generated registers
|
# create a Modbus simulator with the previously generated registers
|
||||||
datablock = ModbusSequentialDataBlock(0x01, payload)
|
datablock = ModbusSequentialDataBlock(0x01, payload)
|
||||||
context = ModbusSlaveContext(di=datablock, co=datablock, hr=datablock, ir=datablock)
|
context = ModbusSlaveContext(di=datablock, co=datablock, hr=datablock, ir=datablock)
|
||||||
context = ModbusServerContext(slaves=context, single=True)
|
context = ModbusServerContext(slaves=context, single=True)
|
||||||
return server_async.setup_server(
|
return server_async.setup_server(
|
||||||
description="Run asynchronous server.", context=context, cmdline=cmdline
|
description="Run asynchronous server.", context=context, cmdline=cmdline
|
||||||
)
|
)
|
||||||
|
|
||||||
# asynchronous function that will call the values updating function with the arguments (modbus registers layout) of the created server
|
# asynchronous function that will call the values updating function with the arguments (modbus registers layout) of the created server
|
||||||
async def run_updating_server(args):
|
async def run_updating_server(args):
|
||||||
task = asyncio.create_task(updating_task(args.context))
|
task = asyncio.create_task(updating_task(args.context))
|
||||||
await server_async.run_async_server(args) # start the server
|
await server_async.run_async_server(args) # start the server
|
||||||
task.cancel()
|
task.cancel()
|
||||||
|
|
||||||
# main function that will setup the server, start it and run the function what will update the values of the registers
|
# main function that will setup the server, start it and run the function what will update the values of the registers
|
||||||
async def main(cmdline=None):
|
async def main(cmdline=None):
|
||||||
run_args = setup_updating_server(cmdline=cmdline)
|
run_args = setup_updating_server(cmdline=cmdline)
|
||||||
await run_updating_server(run_args)
|
await run_updating_server(run_args)
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
asyncio.run(main(), debug=True)
|
asyncio.run(main(), debug=True)
|
||||||
|
|||||||
@@ -1,77 +1,77 @@
|
|||||||
import os
|
import os
|
||||||
import json
|
import json
|
||||||
import pandas as pd
|
import pandas as pd
|
||||||
import pprint
|
import pprint
|
||||||
import matplotlib.pyplot as plt
|
import matplotlib.pyplot as plt
|
||||||
from datetime import datetime
|
from datetime import datetime
|
||||||
import numpy as np
|
import numpy as np
|
||||||
|
|
||||||
def process_folder(folder_path, table):
|
def process_folder(folder_path, table):
|
||||||
"""
|
"""
|
||||||
Recursively process each file in the folder and its subfolders.
|
Recursively process each file in the folder and its subfolders.
|
||||||
"""
|
"""
|
||||||
for root, dirs, files in os.walk(folder_path):
|
for root, dirs, files in os.walk(folder_path):
|
||||||
for file in files:
|
for file in files:
|
||||||
file_path = os.path.join(root, file)
|
file_path = os.path.join(root, file)
|
||||||
process_file(file_path, table)
|
process_file(file_path, table)
|
||||||
|
|
||||||
def process_file(file_path, table):
|
def process_file(file_path, table):
|
||||||
"""
|
"""
|
||||||
Read each line of JSON data from the file and store it in the table.
|
Read each line of JSON data from the file and store it in the table.
|
||||||
"""
|
"""
|
||||||
with open(file_path, 'r') as f:
|
with open(file_path, 'r') as f:
|
||||||
for line in f:
|
for line in f:
|
||||||
try:
|
try:
|
||||||
json_data = json.loads(line)
|
json_data = json.loads(line)
|
||||||
table.append(json_data)
|
table.append(json_data)
|
||||||
except json.JSONDecodeError:
|
except json.JSONDecodeError:
|
||||||
print(f"Error decoding JSON in file: {file_path}")
|
print(f"Error decoding JSON in file: {file_path}")
|
||||||
|
|
||||||
def main(folder_path):
|
def main(folder_path):
|
||||||
table = []
|
table = []
|
||||||
process_folder(folder_path, table)
|
process_folder(folder_path, table)
|
||||||
|
|
||||||
# Convert table to pandas DataFrame for easy manipulation
|
# Convert table to pandas DataFrame for easy manipulation
|
||||||
df = pd.DataFrame(table)
|
df = pd.DataFrame(table)
|
||||||
index_table = []
|
index_table = []
|
||||||
enqueued_table = []
|
enqueued_table = []
|
||||||
emission_table = []
|
emission_table = []
|
||||||
|
|
||||||
for index, row in df.iterrows():
|
for index, row in df.iterrows():
|
||||||
print(index, end=' ')
|
print(index, end=' ')
|
||||||
index_table.append(index)
|
index_table.append(index)
|
||||||
print(row['EnqueuedTimeUtc'], end=' ')
|
print(row['EnqueuedTimeUtc'], end=' ')
|
||||||
enqueued_table.append(row['EnqueuedTimeUtc'])
|
enqueued_table.append(row['EnqueuedTimeUtc'])
|
||||||
body_table = []
|
body_table = []
|
||||||
body_table.append(row['Body'])
|
body_table.append(row['Body'])
|
||||||
body_df = pd.DataFrame(body_table)
|
body_df = pd.DataFrame(body_table)
|
||||||
for body_index, body_row in body_df.iterrows():
|
for body_index, body_row in body_df.iterrows():
|
||||||
print(body_row['emissionDate'])
|
print(body_row['emissionDate'])
|
||||||
emission_table.append(body_row['emissionDate'])
|
emission_table.append(body_row['emissionDate'])
|
||||||
|
|
||||||
emission_dates = [datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ') for date in emission_table]
|
emission_dates = [datetime.strptime(date, '%Y-%m-%dT%H:%M:%SZ') for date in emission_table]
|
||||||
enqueued_dates = [datetime.strptime(date[:19] + date[-1], '%Y-%m-%dT%H:%M:%SZ') for date in enqueued_table]
|
enqueued_dates = [datetime.strptime(date[:19] + date[-1], '%Y-%m-%dT%H:%M:%SZ') for date in enqueued_table]
|
||||||
|
|
||||||
plt.figure(figsize=(10, 6))
|
plt.figure(figsize=(10, 6))
|
||||||
plt.plot(enqueued_dates, index_table, label='Enqueued')
|
plt.plot(enqueued_dates, index_table, label='Enqueued')
|
||||||
plt.plot(emission_dates, index_table, label='Emission')
|
plt.plot(emission_dates, index_table, label='Emission')
|
||||||
|
|
||||||
plt.xlabel('Time')
|
plt.xlabel('Time')
|
||||||
plt.ylabel('Index')
|
plt.ylabel('Index')
|
||||||
plt.title('Index vs Time')
|
plt.title('Index vs Time')
|
||||||
plt.legend()
|
plt.legend()
|
||||||
plt.grid(True)
|
plt.grid(True)
|
||||||
|
|
||||||
plt.xticks(rotation=45)
|
plt.xticks(rotation=45)
|
||||||
|
|
||||||
parts = folder_path.split('/')[-4:]
|
parts = folder_path.split('/')[-4:]
|
||||||
result = '_'.join(parts)
|
result = '_'.join(parts)
|
||||||
|
|
||||||
figurename = "index_" + result + ".png"
|
figurename = "index_" + result + ".png"
|
||||||
|
|
||||||
plt.savefig(figurename, bbox_inches='tight')
|
plt.savefig(figurename, bbox_inches='tight')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == "__main__":
|
if __name__ == "__main__":
|
||||||
folder_path = '/mnt/c/Users/QWPHR/Downloads/JSON_BUFFER_7'
|
folder_path = '/mnt/c/Users/QWPHR/Downloads/JSON_BUFFER_7'
|
||||||
main(folder_path)
|
main(folder_path)
|
||||||
|
|||||||
28
Python/tranform_export_hierarchy.py
Normal file
28
Python/tranform_export_hierarchy.py
Normal file
@@ -0,0 +1,28 @@
|
|||||||
|
import re
|
||||||
|
|
||||||
|
# Function to transform each line
|
||||||
|
def transform_line(line):
|
||||||
|
# Use regex to extract parts of the line
|
||||||
|
match = re.match(r'"([^"]+)","([^"]+)","\[(.*)\]"', line)
|
||||||
|
if match:
|
||||||
|
id_part = match.group(1)
|
||||||
|
date_part = match.group(2)
|
||||||
|
categories_part = match.group(3)
|
||||||
|
|
||||||
|
# Remove extra quotes and split the categories
|
||||||
|
categories = categories_part.replace('""', '"').split(',')
|
||||||
|
|
||||||
|
# Swap categories order and join them with a semicolon
|
||||||
|
transformed_categories = ','.join(categories[::-1])
|
||||||
|
|
||||||
|
# Return the transformed line
|
||||||
|
return f'"{id_part}",{transformed_categories}'
|
||||||
|
else:
|
||||||
|
return None
|
||||||
|
|
||||||
|
# Open input file and output file
|
||||||
|
with open('export_hierarchy', 'r') as infile, open('export_hierarchy_transformed', 'w') as outfile:
|
||||||
|
for line in infile:
|
||||||
|
transformed_line = transform_line(line.strip())
|
||||||
|
if transformed_line:
|
||||||
|
outfile.write(transformed_line + '\n')
|
||||||
@@ -1,2 +1,2 @@
|
|||||||
# ess-moxa-configuration-tools
|
# ess-moxa-configuration-tools
|
||||||
Repository containing tools, scripts, configurations and command used in the deployment of Moxa AIG-301 devices for I-Sight with Azure IoT Hub.
|
Repository containing tools, scripts, configurations and command used in the deployment of Moxa AIG-301 devices for I-Sight with Azure IoT Hub.
|
||||||
Reference in New Issue
Block a user