Skip to content
Snippets Groups Projects
Commit 483b6f5d authored by Strasser, Andreas's avatar Strasser, Andreas
Browse files

implemented file transfer

parent 8b8ab065
No related branches found
No related tags found
No related merge requests found
...@@ -133,12 +133,13 @@ def wait_otaconf_finished() ...@@ -133,12 +133,13 @@ def wait_otaconf_finished()
mesh_init() mesh_init()
end end
util.set_wakeup_led(1)
collect_sensor_data() collect_sensor_data()
end end
def wakeup_task() def wakeup_task()
disable_deepsleep() disable_deepsleep()
util.set_wakeup_led(1)
wait_otaconf_finished() wait_otaconf_finished()
end end
......
...@@ -3,17 +3,31 @@ import json ...@@ -3,17 +3,31 @@ import json
import otaconf import otaconf
import persist import persist
import mesh import mesh
import path
import string
import re
var otaconf_finished = false var otaconf_finished = false
var _otaconf_timer_id = 'otaconf_timer' var _otaconf_timer_id = 'otaconf_timer'
var _file_transfer_timer_id = 'file_transfer_timer'
var _wifi_used = tasmota.cmd('Wifi')['Wifi'] == 'ON' var _wifi_used = tasmota.cmd('Wifi')['Wifi'] == 'ON'
var _mesh_scan_retries = 3 var _mesh_scan_retries = 3
var _configuration_uuid = nil var _configuration_uuid = nil
var _configuration_files = nil var _configuration_files = nil
var _configuration_commands = nil var _configuration_commands = nil
var _own_file = nil
var _current_chunk = nil
var _current_chunk_id = 0
var _last_chunk_id = 0
var _file_uuid_in_process = nil
var _file_in_process = nil
var _devices_to_receive_file = {}
var _file_send_retries = 3
var _own_command = nil var _own_command = nil
var _CHUNK_HEADER_SIZE = 12 + 3
def _set_ota_conf_interval(cmd, idx, payload) def _set_ota_conf_interval(cmd, idx, payload)
if otaconf.set_poll_interval(payload) if otaconf.set_poll_interval(payload)
...@@ -42,7 +56,7 @@ end ...@@ -42,7 +56,7 @@ end
def _finish_otaconf(early_exit) def _finish_otaconf(early_exit)
if !early_exit if !early_exit
persist.last_otaconf_poll = tasmota.rtc()['local'] persist.otaconf_last_poll = tasmota.rtc()['local']
persist.save() persist.save()
end end
...@@ -93,16 +107,144 @@ def _execute_commands() ...@@ -93,16 +107,144 @@ def _execute_commands()
_update_config_status() _update_config_status()
end end
def _distribute_files() def _send_file_chunk()
tasmota.log('OTA: distributing files', 2) tasmota.remove_timer(_file_transfer_timer_id)
if _configuration_files.size() > 0
var file = _configuration_files[0]
var uuid = file['uuid']
if !_devices_to_receive_file.contains(uuid) || _devices_to_receive_file[uuid].size() == 0
_configuration_files.remove(0)
_send_file_chunk()
end
print('test')
var mac = _devices_to_receive_file[uuid][0]
print('anus')
if _file_in_process == nil
if !path.exists(uuid)
tasmota.log('OTA: file: ' + uuid + ' not found - skip', 2)
_configuration_files.remove(0)
_send_file_chunk()
end
tasmota.log('OTA: opening file: ' + uuid, 2)
_file_in_process = open(uuid)
_file_send_retries = 3
_current_chunk_id = 0
_last_chunk_id = 0
_current_chunk = _file_in_process.read(mesh.MAX_LEN - _CHUNK_HEADER_SIZE)
tasmota.log('OTA: sending chunk: ' + str(_current_chunk_id) + ' to: ' + mac, 2)
var payload = uuid + string.format("%03i", _current_chunk_id) + _current_chunk
print('send payload: ' + payload)
mesh.send(mac, payload)
else
if _current_chunk_id == _last_chunk_id
_file_send_retries -= 1
if _file_send_retries > 0
tasmota.log('OTA: retry sending chunk: ' + str(_current_chunk_id) + ' to: ' + mac + ', retries left: ' + str(_file_send_retries), 2)
var payload = uuid + string.format("%03i", _current_chunk_id) + _current_chunk
print('send payload: ' + payload)
mesh.send(mac, payload)
else
_devices_to_receive_file[uuid].remove(0)
_file_in_process.close()
_file_in_process = nil
tasmota.log('OTA: retries exceeded: ' + str(_current_chunk_id) + ' to: ' + mac, 2)
end
else
_current_chunk = _file_in_process.read(mesh.MAX_LEN - _CHUNK_HEADER_SIZE)
if size(_current_chunk) == 0
_file_in_process.close()
_file_in_process = nil
_devices_to_receive_file[uuid].remove(0)
tasmota.log('OTA: finished transfering file: ' + uuid + ' to: ' + mac, 2)
else
tasmota.log('OTA: sending chunk: ' + str(_current_chunk_id) + ' to: ' + mac, 2)
var payload = uuid + string.format("%03i", _current_chunk_id) + _current_chunk
print('send payload: ' + payload)
_last_chunk_id = _current_chunk_id
mesh.send(mac, payload)
end
end
end
tasmota.set_timer(2000, _send_file_chunk, _file_transfer_timer_id)
else
_execute_commands() _execute_commands()
end end
end
def _initiate_file_transfer()
if _configuration_files.size() > 0
for file : _configuration_files
var device_macs = file['macs']
var uuid = file['uuid']
var name = file['name']
tasmota.log('OTA: processing file: ' + uuid, 2)
var f = open(uuid)
var num_chunks = size(f) / (mesh.MAX_LEN - _CHUNK_HEADER_SIZE)
if num_chunks == 0 && size(f) > 0
num_chunks = 1
end
if size(f) % (mesh.MAX_LEN - _CHUNK_HEADER_SIZE) != 0
num_chunks + 1
end
f.close()
for device_mac : device_macs
if device_mac == otaconf.get_mac()
# todo own file
_own_file = file
else
tasmota.log('OTA: initiating file transfer with device: ' + device_mac, 2)
var payload = {'action': 'TRANSFER_FILE', 'name': name, 'uuid': uuid, 'num_chunks': num_chunks}
print('send payload: ' + json.dump(payload))
mesh.send(otaconf.format_mac(device_mac), json.dump(payload))
end
end
end
tasmota.set_timer(2000, _send_file_chunk, _file_transfer_timer_id)
else
_execute_commands()
end
end
def _devices_registered() def _devices_registered()
tasmota.remove_timer(_otaconf_timer_id) tasmota.remove_timer(_otaconf_timer_id)
_distribute_files() _initiate_file_transfer()
end end
def _check_devices_registered() def _check_devices_registered()
...@@ -113,7 +255,7 @@ def _check_devices_registered() ...@@ -113,7 +255,7 @@ def _check_devices_registered()
otaconf.register_devices(unregistered_devices, _devices_registered) otaconf.register_devices(unregistered_devices, _devices_registered)
tasmota.set_timer(3000, _otaconf_timeout, _otaconf_timer_id) tasmota.set_timer(3000, _otaconf_timeout, _otaconf_timer_id)
else else
_distribute_files() _initiate_file_transfer()
end end
end end
...@@ -152,7 +294,7 @@ def _process_config(response) ...@@ -152,7 +294,7 @@ def _process_config(response)
if response['configuration'].contains('mesh_scan') && response['configuration']['mesh_scan'] if response['configuration'].contains('mesh_scan') && response['configuration']['mesh_scan']
_scan_mesh() _scan_mesh()
else else
_distribute_files() _initiate_file_transfer()
end end
else else
_finish_otaconf(false) _finish_otaconf(false)
...@@ -184,10 +326,10 @@ def _check_cluster_registered() ...@@ -184,10 +326,10 @@ def _check_cluster_registered()
end end
def _check_otaconf() def _check_otaconf()
var next_otaconf_time = int(persist.find('last_otaconf_poll')) + otaconf.get_poll_interval() var next_otaconf_time = int(persist.find('otaconf_last_poll')) + otaconf.get_poll_interval()
var current_time = tasmota.rtc()['local'] var current_time = tasmota.rtc()['local']
if !persist.has('last_otaconf_poll') || (current_time > next_otaconf_time) if !persist.has('otaconf_last_poll') || (current_time > next_otaconf_time)
_check_cluster_registered() _check_cluster_registered()
else else
var remaining_hours = str((next_otaconf_time - current_time) / 3600) var remaining_hours = str((next_otaconf_time - current_time) / 3600)
...@@ -203,11 +345,43 @@ end ...@@ -203,11 +345,43 @@ end
def _callback(sender, payload) def _callback(sender, payload)
var recieved_data = json.load(payload) var recieved_data = json.load(payload)
print(recieved_data) # todo remove print('receive payload: ' + payload) # todo remove
print(mesh.get_peers()) # todo remove print('receive size: ' + str(size(payload)))
if recieved_data != nil && recieved_data.contains('action') if recieved_data != nil && recieved_data.contains('action')
var action = recieved_data['action'] var action = recieved_data['action']
if action == 'TRANSFER_FILE'
if recieved_data.contains('uuid')
var uuid = recieved_data['uuid']
if _devices_to_receive_file.contains(uuid)
_devices_to_receive_file[uuid].push(sender)
else
_devices_to_receive_file[uuid] = [sender]
end
print(_devices_to_receive_file)
end
end
elif payload != nil && size(payload) == _CHUNK_HEADER_SIZE
var uuid = payload[0..11]
var chunk_id = payload[12..14]
print('chunks')
print(chunk_id)
print(_current_chunk_id)
print('chunks')
if re.match('^[0-9]*$', chunk_id) != nil
print('yey')
if int(chunk_id) == _current_chunk_id
print('update')
_current_chunk_id += 1
end
_send_file_chunk()
end
end end
end end
......
...@@ -42,17 +42,16 @@ def _check_file_transfer_finished(uuid) ...@@ -42,17 +42,16 @@ def _check_file_transfer_finished(uuid)
end end
def _store_chunk(payload) def _store_chunk(payload)
print('_store_chunk' + payload)
var uuid = payload[0..11] var uuid = payload[0..11]
var chunk_id = payload[12..14] var chunk_id = payload[12..14]
var file = open(uuid + '_' + chunk_id + '.part', 'w') var file = open(uuid + '_' + chunk_id + '.part', 'w')
file.write(payload[15..mesh.max_packet_size()]) file.write(payload[15..mesh.MAX_LEN])
file.close() file.close()
end end
def _callback(sender, payload) def _callback(sender, payload)
print(payload) print('receive payload: ' + payload)
var recieved_data = json.load(payload) var recieved_data = json.load(payload)
if recieved_data != nil && recieved_data.contains('action') if recieved_data != nil && recieved_data.contains('action')
...@@ -66,12 +65,14 @@ def _callback(sender, payload) ...@@ -66,12 +65,14 @@ def _callback(sender, payload)
if recieved_data.contains('name') && recieved_data.contains('uuid') && recieved_data.contains('num_chunks') if recieved_data.contains('name') && recieved_data.contains('uuid') && recieved_data.contains('num_chunks')
_files_in_process[recieved_data['uuid']] = {'name': recieved_data['name'], 'num_chunks': recieved_data['num_chunks']} _files_in_process[recieved_data['uuid']] = {'name': recieved_data['name'], 'num_chunks': recieved_data['num_chunks']}
mesh.send(sender, json.dump({'action': 'TRANSFER_FILE'})) print('send payload: ' + json.dump({'action': 'TRANSFER_FILE', 'uuid': recieved_data['uuid']}))
mesh.send(sender, json.dump({'action': 'TRANSFER_FILE', 'uuid': recieved_data['uuid']}))
end end
elif action == 'MESH_SCAN' elif action == 'MESH_SCAN'
mesh.send(sender, json.dump({'action': 'MESH_SCAN'})) mesh.send(sender, json.dump({'action': 'MESH_SCAN'}))
end end
elif payload != nil && size(payload) > _CHUNK_HEADER_SIZE elif payload != nil && size(payload) >= _CHUNK_HEADER_SIZE
var uuid = payload[0..11] var uuid = payload[0..11]
var chunk_id = payload[12..14] var chunk_id = payload[12..14]
...@@ -79,6 +80,8 @@ def _callback(sender, payload) ...@@ -79,6 +80,8 @@ def _callback(sender, payload)
_store_chunk(payload) _store_chunk(payload)
_check_file_transfer_finished(uuid) _check_file_transfer_finished(uuid)
print('send payload: ' + payload[0..14])
mesh.send(sender, payload[0..14]) mesh.send(sender, payload[0..14])
end end
end end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment