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()
mesh_init()
end
util.set_wakeup_led(1)
collect_sensor_data()
end
def wakeup_task()
disable_deepsleep()
util.set_wakeup_led(1)
wait_otaconf_finished()
end
......
......@@ -3,17 +3,31 @@ import json
import otaconf
import persist
import mesh
import path
import string
import re
var otaconf_finished = false
var _otaconf_timer_id = 'otaconf_timer'
var _file_transfer_timer_id = 'file_transfer_timer'
var _wifi_used = tasmota.cmd('Wifi')['Wifi'] == 'ON'
var _mesh_scan_retries = 3
var _configuration_uuid = nil
var _configuration_files = 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 _CHUNK_HEADER_SIZE = 12 + 3
def _set_ota_conf_interval(cmd, idx, payload)
if otaconf.set_poll_interval(payload)
......@@ -42,7 +56,7 @@ end
def _finish_otaconf(early_exit)
if !early_exit
persist.last_otaconf_poll = tasmota.rtc()['local']
persist.otaconf_last_poll = tasmota.rtc()['local']
persist.save()
end
......@@ -93,16 +107,144 @@ def _execute_commands()
_update_config_status()
end
def _distribute_files()
tasmota.log('OTA: distributing files', 2)
def _send_file_chunk()
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()
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()
tasmota.remove_timer(_otaconf_timer_id)
_distribute_files()
_initiate_file_transfer()
end
def _check_devices_registered()
......@@ -113,7 +255,7 @@ def _check_devices_registered()
otaconf.register_devices(unregistered_devices, _devices_registered)
tasmota.set_timer(3000, _otaconf_timeout, _otaconf_timer_id)
else
_distribute_files()
_initiate_file_transfer()
end
end
......@@ -152,7 +294,7 @@ def _process_config(response)
if response['configuration'].contains('mesh_scan') && response['configuration']['mesh_scan']
_scan_mesh()
else
_distribute_files()
_initiate_file_transfer()
end
else
_finish_otaconf(false)
......@@ -184,10 +326,10 @@ def _check_cluster_registered()
end
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']
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()
else
var remaining_hours = str((next_otaconf_time - current_time) / 3600)
......@@ -203,11 +345,43 @@ end
def _callback(sender, payload)
var recieved_data = json.load(payload)
print(recieved_data) # todo remove
print(mesh.get_peers()) # todo remove
print('receive payload: ' + payload) # todo remove
print('receive size: ' + str(size(payload)))
if recieved_data != nil && recieved_data.contains('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
......
......@@ -42,17 +42,16 @@ def _check_file_transfer_finished(uuid)
end
def _store_chunk(payload)
print('_store_chunk' + payload)
var uuid = payload[0..11]
var chunk_id = payload[12..14]
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()
end
def _callback(sender, payload)
print(payload)
print('receive payload: ' + payload)
var recieved_data = json.load(payload)
if recieved_data != nil && recieved_data.contains('action')
......@@ -66,12 +65,14 @@ def _callback(sender, payload)
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']}
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
elif action == 'MESH_SCAN'
mesh.send(sender, json.dump({'action': 'MESH_SCAN'}))
end
elif payload != nil && size(payload) > _CHUNK_HEADER_SIZE
elif payload != nil && size(payload) >= _CHUNK_HEADER_SIZE
var uuid = payload[0..11]
var chunk_id = payload[12..14]
......@@ -79,6 +80,8 @@ def _callback(sender, payload)
_store_chunk(payload)
_check_file_transfer_finished(uuid)
print('send payload: ' + payload[0..14])
mesh.send(sender, payload[0..14])
end
end
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment