2
.gitignore
vendored
2
.gitignore
vendored
@@ -23,6 +23,6 @@ __pycache__
|
|||||||
/package-lock.json
|
/package-lock.json
|
||||||
/src/bbserial/linux-rpi-raspberrypi-kernel*
|
/src/bbserial/linux-rpi-raspberrypi-kernel*
|
||||||
/src/bbserial/raspberrypi-kernel*
|
/src/bbserial/raspberrypi-kernel*
|
||||||
|
*.rej
|
||||||
*.elf
|
*.elf
|
||||||
*.hex
|
*.hex
|
||||||
|
|||||||
2
Makefile
2
Makefile
@@ -26,7 +26,7 @@ PKG_NAME := bbctrl-$(VERSION)
|
|||||||
SUBPROJECTS := avr boot pwr jig
|
SUBPROJECTS := avr boot pwr jig
|
||||||
|
|
||||||
ifndef HOST
|
ifndef HOST
|
||||||
HOST=onefinity
|
HOST=onefinity.local
|
||||||
endif
|
endif
|
||||||
|
|
||||||
ifndef PASSWORD
|
ifndef PASSWORD
|
||||||
|
|||||||
@@ -1,6 +1,6 @@
|
|||||||
{
|
{
|
||||||
"name": "bbctrl",
|
"name": "bbctrl",
|
||||||
"version": "1.2.1",
|
"version": "1.3.0",
|
||||||
"homepage": "https://onefinitycnc.com/",
|
"homepage": "https://onefinitycnc.com/",
|
||||||
"repository": "https://github.com/OneFinityCNC/onefinity",
|
"repository": "https://github.com/OneFinityCNC/onefinity",
|
||||||
"license": "GPL-3.0+",
|
"license": "GPL-3.0+",
|
||||||
|
|||||||
@@ -3,6 +3,7 @@
|
|||||||
cd /mnt/host
|
cd /mnt/host
|
||||||
scons -j 8 -C cbang disable_local="re2 libevent"
|
scons -j 8 -C cbang disable_local="re2 libevent"
|
||||||
export CBANG_HOME="/mnt/host/cbang"
|
export CBANG_HOME="/mnt/host/cbang"
|
||||||
|
export LC_ALL=C
|
||||||
|
|
||||||
CAMOTICS_ROOT="/mnt/host/camotics"
|
CAMOTICS_ROOT="/mnt/host/camotics"
|
||||||
CAMOTICS_PLAN="${CAMOTICS_ROOT}/src/gcode/plan"
|
CAMOTICS_PLAN="${CAMOTICS_ROOT}/src/gcode/plan"
|
||||||
|
|||||||
@@ -58,6 +58,7 @@ typedef enum
|
|||||||
SPINDLE_TYPE_SUNFAR_E300,
|
SPINDLE_TYPE_SUNFAR_E300,
|
||||||
SPINDLE_TYPE_OMRON_MX2,
|
SPINDLE_TYPE_OMRON_MX2,
|
||||||
SPINDLE_TYPE_V70,
|
SPINDLE_TYPE_V70,
|
||||||
|
SPINDLE_TYPE_PWNCNC,
|
||||||
} spindle_type_t;
|
} spindle_type_t;
|
||||||
|
|
||||||
typedef void (*deinit_cb_t)();
|
typedef void (*deinit_cb_t)();
|
||||||
|
|||||||
@@ -29,7 +29,6 @@
|
|||||||
#include "modbus.h"
|
#include "modbus.h"
|
||||||
#include "rtc.h"
|
#include "rtc.h"
|
||||||
#include "config.h"
|
#include "config.h"
|
||||||
#include "estop.h"
|
|
||||||
#include "pgmspace.h"
|
#include "pgmspace.h"
|
||||||
|
|
||||||
#include <util/atomic.h>
|
#include <util/atomic.h>
|
||||||
@@ -49,6 +48,7 @@ typedef enum
|
|||||||
|
|
||||||
REG_FREQ_SET,
|
REG_FREQ_SET,
|
||||||
REG_FREQ_SIGN_SET,
|
REG_FREQ_SIGN_SET,
|
||||||
|
REG_FREQ_SCALED_SET,
|
||||||
|
|
||||||
REG_STOP_WRITE,
|
REG_STOP_WRITE,
|
||||||
REG_FWD_WRITE,
|
REG_FWD_WRITE,
|
||||||
@@ -170,6 +170,18 @@ const vfd_reg_t v70_regs[] PROGMEM = {
|
|||||||
{REG_DISABLED},
|
{REG_DISABLED},
|
||||||
};
|
};
|
||||||
|
|
||||||
|
const vfd_reg_t pwncnc_regs[] PROGMEM = {
|
||||||
|
{REG_MAX_FREQ_READ, 0x0007, 0}, // Read max frequency
|
||||||
|
{REG_FREQ_SCALED_SET, 0xa001, 10000}, // Set scaled frequency
|
||||||
|
{REG_FREQ_READ, 0x9000, 0}, // Read frequency
|
||||||
|
{REG_FWD_WRITE, 0xa000, 1}, // Run forward
|
||||||
|
{REG_REV_WRITE, 0xa000, 2}, // Run reverse
|
||||||
|
{REG_STOP_WRITE, 0xa000, 5}, // Stop
|
||||||
|
{REG_DISCONNECT_WRITE, 0xa000, 5}, // Stop
|
||||||
|
{REG_STATUS_READ, 0xb000, 0}, // Read status
|
||||||
|
{REG_DISABLED},
|
||||||
|
};
|
||||||
|
|
||||||
static vfd_reg_t regs[VFDREG];
|
static vfd_reg_t regs[VFDREG];
|
||||||
static vfd_reg_t custom_regs[VFDREG];
|
static vfd_reg_t custom_regs[VFDREG];
|
||||||
|
|
||||||
@@ -209,8 +221,7 @@ static bool _next_state()
|
|||||||
else
|
else
|
||||||
vfd.state = REG_FREQ_SET;
|
vfd.state = REG_FREQ_SET;
|
||||||
break;
|
break;
|
||||||
|
case REG_FREQ_SCALED_SET:
|
||||||
case REG_FREQ_SIGN_SET:
|
|
||||||
if (vfd.power < 0)
|
if (vfd.power < 0)
|
||||||
vfd.state = REG_REV_WRITE;
|
vfd.state = REG_REV_WRITE;
|
||||||
else if (0 < vfd.power)
|
else if (0 < vfd.power)
|
||||||
@@ -219,6 +230,15 @@ static bool _next_state()
|
|||||||
vfd.state = REG_STOP_WRITE;
|
vfd.state = REG_STOP_WRITE;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
// case REG_FREQ_SIGN_SET:
|
||||||
|
// if (vfd.power < 0)
|
||||||
|
// vfd.state = REG_REV_WRITE;
|
||||||
|
// else if (0 < vfd.power)
|
||||||
|
// vfd.state = REG_FWD_WRITE;
|
||||||
|
// else
|
||||||
|
// vfd.state = REG_STOP_WRITE;
|
||||||
|
// break;
|
||||||
|
|
||||||
case REG_STOP_WRITE:
|
case REG_STOP_WRITE:
|
||||||
case REG_FWD_WRITE:
|
case REG_FWD_WRITE:
|
||||||
case REG_REV_WRITE:
|
case REG_REV_WRITE:
|
||||||
@@ -226,7 +246,8 @@ static bool _next_state()
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case REG_STATUS_READ:
|
case REG_STATUS_READ:
|
||||||
if (vfd.shutdown || estop_triggered())
|
// if (vfd.shutdown || estop_triggered()) vfd.state = REG_DISCONNECT_WRITE;
|
||||||
|
if (vfd.shutdown)
|
||||||
vfd.state = REG_DISCONNECT_WRITE;
|
vfd.state = REG_DISCONNECT_WRITE;
|
||||||
|
|
||||||
else if (vfd.changed)
|
else if (vfd.changed)
|
||||||
@@ -289,7 +310,8 @@ static void _modbus_cb(bool ok, uint16_t addr, uint16_t value)
|
|||||||
{
|
{
|
||||||
if (regs[vfd.reg].fails < 255)
|
if (regs[vfd.reg].fails < 255)
|
||||||
regs[vfd.reg].fails++;
|
regs[vfd.reg].fails++;
|
||||||
if (vfd.shutdown || estop_triggered())
|
// if (vfd.shutdown || estop_triggered()) _disconnected();
|
||||||
|
if (vfd.shutdown)
|
||||||
_disconnected();
|
_disconnected();
|
||||||
else
|
else
|
||||||
_connect();
|
_connect();
|
||||||
@@ -373,6 +395,11 @@ static bool _exec_command()
|
|||||||
reg.value = vfd.power * vfd.max_freq;
|
reg.value = vfd.power * vfd.max_freq;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case REG_FREQ_SCALED_SET:
|
||||||
|
write = true;
|
||||||
|
reg.value = fabs(vfd.power) * reg.value;
|
||||||
|
break;
|
||||||
|
|
||||||
case REG_CONNECT_WRITE:
|
case REG_CONNECT_WRITE:
|
||||||
case REG_STOP_WRITE:
|
case REG_STOP_WRITE:
|
||||||
case REG_FWD_WRITE:
|
case REG_FWD_WRITE:
|
||||||
@@ -452,6 +479,10 @@ void vfd_spindle_init()
|
|||||||
case SPINDLE_TYPE_V70:
|
case SPINDLE_TYPE_V70:
|
||||||
_load(v70_regs);
|
_load(v70_regs);
|
||||||
break;
|
break;
|
||||||
|
case SPINDLE_TYPE_PWNCNC:
|
||||||
|
_load(pwncnc_regs);
|
||||||
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -417,6 +417,7 @@ module.exports = new Vue({
|
|||||||
delete settings.tool["tool-type"];
|
delete settings.tool["tool-type"];
|
||||||
|
|
||||||
this.config["selected-tool-settings"][selected_tool] = settings;
|
this.config["selected-tool-settings"][selected_tool] = settings;
|
||||||
|
this.display_units = this.config.settings["units"];
|
||||||
|
|
||||||
try {
|
try {
|
||||||
await api.put("config/save", this.config);
|
await api.put("config/save", this.config);
|
||||||
|
|||||||
@@ -91,7 +91,9 @@ module.exports = {
|
|||||||
return this.$root.display_units;
|
return this.$root.display_units;
|
||||||
},
|
},
|
||||||
set: function(value) {
|
set: function(value) {
|
||||||
|
this.config.settings.units = value;
|
||||||
this.$root.display_units = value;
|
this.$root.display_units = value;
|
||||||
|
this.$dispatch("config-changed");
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -90,7 +90,7 @@ module.exports = {
|
|||||||
},
|
},
|
||||||
|
|
||||||
reload: function(file) {
|
reload: function(file) {
|
||||||
if (file == this.file) {
|
if (file != this.file) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
this.clear();
|
this.clear();
|
||||||
|
|||||||
@@ -8,7 +8,7 @@ module.exports = {
|
|||||||
computed: {
|
computed: {
|
||||||
has_user_value: function () {
|
has_user_value: function () {
|
||||||
var type = this.model["reg-type"];
|
var type = this.model["reg-type"];
|
||||||
return type.indexOf("write") != -1 || type.indexOf("fixed") != -1;
|
return type.includes("write") || type.includes("fixed") || type.includes("scaled");
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
|
||||||
|
|||||||
@@ -27,6 +27,10 @@ module.exports = {
|
|||||||
type: "PWM Spindle",
|
type: "PWM Spindle",
|
||||||
name: "Laser (J Tech, etc)",
|
name: "Laser (J Tech, etc)",
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "pwncnc-vfd",
|
||||||
|
name: "PwnCNC VFD",
|
||||||
|
},
|
||||||
{
|
{
|
||||||
id: "pwm",
|
id: "pwm",
|
||||||
name: "PWM Spindle",
|
name: "PWM Spindle",
|
||||||
@@ -82,6 +86,11 @@ module.exports = {
|
|||||||
name: "OMRON MX2",
|
name: "OMRON MX2",
|
||||||
unsupported: true,
|
unsupported: true,
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
id: "v70-vfd",
|
||||||
|
name: "V70",
|
||||||
|
unsupported: true
|
||||||
|
}
|
||||||
],
|
],
|
||||||
};
|
};
|
||||||
},
|
},
|
||||||
|
|||||||
@@ -43,7 +43,7 @@ script#tool-view-template(type="text/x-template")
|
|||||||
label.units RPM
|
label.units RPM
|
||||||
|
|
||||||
fieldset.modbus-program(
|
fieldset.modbus-program(
|
||||||
v-if="is_modbus && this.tool_type != 'HUANYANG VFD'")
|
v-if="is_modbus && tool_type != 'HUANYANG VFD' && tool_type != 'PWNCNC VFD'")
|
||||||
h2 Active Modbus Program
|
h2 Active Modbus Program
|
||||||
p(v-if="$root.modified")
|
p(v-if="$root.modified")
|
||||||
| (Click #[tt(class="save") Save] to activate the selected
|
| (Click #[tt(class="save") Save] to activate the selected
|
||||||
@@ -81,9 +81,7 @@ script#tool-view-template(type="text/x-template")
|
|||||||
tr(v-for="(index, reg) in config['modbus-spindle'].regs",
|
tr(v-for="(index, reg) in config['modbus-spindle'].regs",
|
||||||
is="modbus-reg", :index="index", :model.sync="reg",
|
is="modbus-reg", :index="index", :model.sync="reg",
|
||||||
:template="template['modbus-spindle'].regs.template",
|
:template="template['modbus-spindle'].regs.template",
|
||||||
v-if="!index || reg['reg-type'] != 'disabled' || " +
|
v-if="!index || reg['reg-type'] != 'disabled' || config['modbus-spindle'].regs[index - 1]['reg-type'] != 'disabled'")
|
||||||
"config['modbus-spindle'].regs[index - 1]['reg-type'] != " +
|
|
||||||
"'disabled'")
|
|
||||||
|
|
||||||
.notes(v-if="tool_type == 'HUANYANG VFD'")
|
.notes(v-if="tool_type == 'HUANYANG VFD'")
|
||||||
h2 Notes
|
h2 Notes
|
||||||
@@ -380,3 +378,65 @@ script#tool-view-template(type="text/x-template")
|
|||||||
|
|
|
|
||||||
| and spindle type. The VFD must be rebooted after changing
|
| and spindle type. The VFD must be rebooted after changing
|
||||||
| the above settings.
|
| the above settings.
|
||||||
|
|
||||||
|
|
||||||
|
.notes(v-if="tool_type.startsWith('V70')")
|
||||||
|
h2 Notes
|
||||||
|
p Set the following using the VFD's front panel.
|
||||||
|
table.modbus-regs.fixed-regs
|
||||||
|
tr
|
||||||
|
th Address
|
||||||
|
th Value
|
||||||
|
th Meaning
|
||||||
|
th Description
|
||||||
|
tr
|
||||||
|
td.reg-addr F001
|
||||||
|
td.reg-value 2
|
||||||
|
td Communication port
|
||||||
|
td Control mode
|
||||||
|
tr
|
||||||
|
td.reg-addr P0.0.04
|
||||||
|
td.reg-value 9
|
||||||
|
td Modbus
|
||||||
|
td Frequency source A
|
||||||
|
tr
|
||||||
|
td.reg-addr P0.1.00
|
||||||
|
td.reg-value 0
|
||||||
|
td Source A
|
||||||
|
td Frequency source
|
||||||
|
tr
|
||||||
|
td.reg-addr P4.1.00
|
||||||
|
td.reg-value 3
|
||||||
|
td 9600 BAUD
|
||||||
|
td Must match #[tt baud] above
|
||||||
|
tr
|
||||||
|
td.reg-addr F002
|
||||||
|
td.reg-value 2
|
||||||
|
td Communication port
|
||||||
|
td Frequency setting selection
|
||||||
|
tr
|
||||||
|
td.reg-addr F163
|
||||||
|
td.reg-value 1
|
||||||
|
td Slave address
|
||||||
|
td Must match #[tt bus-id] above
|
||||||
|
tr
|
||||||
|
td.reg-addr F164
|
||||||
|
td.reg-value 1
|
||||||
|
td 9600 BAUD
|
||||||
|
td Must match #[tt baud] above
|
||||||
|
tr
|
||||||
|
td.reg-addr F165
|
||||||
|
td.reg-value 3
|
||||||
|
td 8 data, no parity, 1 stop, RTU
|
||||||
|
td Must match #[tt parity] above
|
||||||
|
p
|
||||||
|
| Other settings according to the
|
||||||
|
|
|
||||||
|
a(href="https://buildbotics.com/upload/vfd/stepperonline-v70.pdf",
|
||||||
|
target="_blank") Stepper Online V70 VFD manual
|
||||||
|
|
||||||
|
.notes(v-if="tool_type.startsWith('PWNCNC')")
|
||||||
|
h2 Notes
|
||||||
|
p For support and more information about the PwnCNC Spindle Kit, please visit #{''}
|
||||||
|
a(href="https://pwncnc.com/onefinity-controller", target="_blank")
|
||||||
|
| https://pwncnc.com/onefinity-controller
|
||||||
@@ -43,7 +43,7 @@ class Config(object):
|
|||||||
self.values = {}
|
self.values = {}
|
||||||
|
|
||||||
try:
|
try:
|
||||||
self.version = "1.2.1"
|
self.version = "1.3.0"
|
||||||
|
|
||||||
# Load config template
|
# Load config template
|
||||||
with open(get_resource('http/config-template.json'), 'r',
|
with open(get_resource('http/config-template.json'), 'r',
|
||||||
@@ -156,6 +156,7 @@ class Config(object):
|
|||||||
def _upgrade(self, config):
|
def _upgrade(self, config):
|
||||||
version = config['version']
|
version = config['version']
|
||||||
version = version.split('b')[0] # Strip off any "beta" suffix
|
version = version.split('b')[0] # Strip off any "beta" suffix
|
||||||
|
version = version.split('-')[0]
|
||||||
version = tuple(map(int, version.split('.'))) # Break it into a tuple of integers
|
version = tuple(map(int, version.split('.'))) # Break it into a tuple of integers
|
||||||
|
|
||||||
if version < (1, 0, 7):
|
if version < (1, 0, 7):
|
||||||
|
|||||||
@@ -23,7 +23,10 @@ class FileHandler(bbctrl.APIHandler):
|
|||||||
|
|
||||||
filename = self.request.path.split('/')[-1]
|
filename = self.request.path.split('/')[-1]
|
||||||
self.uploadFilename = url_unescape(filename) \
|
self.uploadFilename = url_unescape(filename) \
|
||||||
.replace('\\', '/') \
|
.encode("ascii", errors="replace") \
|
||||||
|
.decode() \
|
||||||
|
.replace('\\', '_') \
|
||||||
|
.replace('/', '_') \
|
||||||
.replace('#', '-') \
|
.replace('#', '-') \
|
||||||
.replace('?', '-')
|
.replace('?', '-')
|
||||||
|
|
||||||
@@ -71,7 +74,8 @@ class FileHandler(bbctrl.APIHandler):
|
|||||||
def get(self, filename):
|
def get(self, filename):
|
||||||
if not filename:
|
if not filename:
|
||||||
raise HTTPError(400, 'Missing filename')
|
raise HTTPError(400, 'Missing filename')
|
||||||
filename = os.path.basename(filename)
|
|
||||||
|
filename = os.path.basename(url_unescape(filename))
|
||||||
|
|
||||||
try:
|
try:
|
||||||
with open(self.get_upload(filename).encode('utf8'), 'r') as f:
|
with open(self.get_upload(filename).encode('utf8'), 'r') as f:
|
||||||
|
|||||||
@@ -139,6 +139,12 @@ class Mach(Comm):
|
|||||||
if log['msg'] == 'Switch not found':
|
if log['msg'] == 'Switch not found':
|
||||||
self.estop()
|
self.estop()
|
||||||
|
|
||||||
|
def _end_cycle(self):
|
||||||
|
if (self._get_cycle() != 'idle' and self._is_ready()
|
||||||
|
and not self.planner.is_busy() and not super().is_active()):
|
||||||
|
self.planner.position_change()
|
||||||
|
self._set_cycle('idle')
|
||||||
|
|
||||||
|
|
||||||
def _update(self, update):
|
def _update(self, update):
|
||||||
# Detect motor faults
|
# Detect motor faults
|
||||||
|
|||||||
@@ -32,7 +32,7 @@ import os
|
|||||||
import bbctrl
|
import bbctrl
|
||||||
from watchdog.observers import Observer
|
from watchdog.observers import Observer
|
||||||
from watchdog.events import FileSystemEventHandler
|
from watchdog.events import FileSystemEventHandler
|
||||||
|
import glob
|
||||||
class UploadChangeHandler(FileSystemEventHandler):
|
class UploadChangeHandler(FileSystemEventHandler):
|
||||||
def __init__(self, state):
|
def __init__(self, state):
|
||||||
self.state = state
|
self.state = state
|
||||||
@@ -123,14 +123,12 @@ class State(object):
|
|||||||
|
|
||||||
if not os.path.exists(upload):
|
if not os.path.exists(upload):
|
||||||
os.mkdir(upload)
|
os.mkdir(upload)
|
||||||
from shutil import copy
|
|
||||||
copy(bbctrl.get_resource('http/buildbotics.nc'), upload)
|
|
||||||
|
|
||||||
for path in os.listdir(upload):
|
files = filter(os.path.isfile, glob.glob(upload + '/*'))
|
||||||
if os.path.isfile(upload + '/' + path):
|
# Sort list of files based on last modification time in ascending order
|
||||||
files.append(path)
|
files = sorted(files, key=os.path.getmtime, reverse=True)
|
||||||
|
files = list(map(lambda f: f.replace("./upload/", ""), files))
|
||||||
|
|
||||||
files.sort()
|
|
||||||
self.set('files', files)
|
self.set('files', files)
|
||||||
|
|
||||||
if len(files): self.select_file(files[0])
|
if len(files): self.select_file(files[0])
|
||||||
|
|||||||
@@ -270,7 +270,9 @@
|
|||||||
"YL600, YL620, YL620-A VFD (Beta)",
|
"YL600, YL620, YL620-A VFD (Beta)",
|
||||||
"FR-D700 (Beta)",
|
"FR-D700 (Beta)",
|
||||||
"Sunfar E300 (Beta)",
|
"Sunfar E300 (Beta)",
|
||||||
"OMRON MX2"
|
"OMRON MX2",
|
||||||
|
"V70",
|
||||||
|
"PwnCNC VFD"
|
||||||
],
|
],
|
||||||
"default": "Disabled",
|
"default": "Disabled",
|
||||||
"code": "st"
|
"code": "st"
|
||||||
@@ -364,6 +366,7 @@
|
|||||||
"max-freq-fixed",
|
"max-freq-fixed",
|
||||||
"freq-set",
|
"freq-set",
|
||||||
"freq-signed-set",
|
"freq-signed-set",
|
||||||
|
"freq-scaled-set",
|
||||||
"stop-write",
|
"stop-write",
|
||||||
"forward-write",
|
"forward-write",
|
||||||
"reverse-write",
|
"reverse-write",
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
{
|
{
|
||||||
"version": "1.2.1",
|
"version": "1.3.0",
|
||||||
"settings": {
|
"settings": {
|
||||||
"junction-accel": 200000,
|
"junction-accel": 200000,
|
||||||
"max-deviation": 0.05,
|
"max-deviation": 0.05,
|
||||||
|
|||||||
@@ -1,18 +1,19 @@
|
|||||||
import { get, type Writable } from "svelte/store";
|
import { get, type Writable } from "svelte/store";
|
||||||
|
|
||||||
export function listenForChange<T>(writable: Writable<T>, cb: (value: T) => void) {
|
export function waitForChange<T>(writable: Writable<T>): Promise<T> {
|
||||||
const priorValue = get(writable);
|
let unsubscribe:()=>{};
|
||||||
|
const promise = new Promise(resolve => {
|
||||||
const unsubscribe = writable.subscribe((value) => {
|
let receivedInitial = false;
|
||||||
if (value !== priorValue) {
|
let previousValue : any;
|
||||||
unsubscribe();
|
unsubscribe = writable.subscribe(value => {
|
||||||
cb(value);
|
if (!receivedInitial) {
|
||||||
|
receivedInitial = true;
|
||||||
|
previousValue = value;
|
||||||
|
} else if (value !== previousValue) {
|
||||||
|
resolve(value);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
}
|
|
||||||
|
|
||||||
export function waitForChange<T>(writable: Writable<T>): Promise<T> {
|
|
||||||
return new Promise((resolve) => {
|
|
||||||
listenForChange(writable, (value) => resolve(value));
|
|
||||||
});
|
});
|
||||||
|
promise.then(unsubscribe);
|
||||||
|
return promise;
|
||||||
}
|
}
|
||||||
Reference in New Issue
Block a user