Brewblox release 2020/08/26 (updated 2020/08/31)

Relevant links:

Brewblox release 2020/08/26

Updates 2020/08/31

  • (fix) Session log graph notes no longer incorrectly show an error that end date is before start date.
  • (fix) Restored the pause/resume autoconnect button in the Spark troubleshooter.
  • (fix) The traefik service now correctly restarts after a Pi reboot.
  • (feature) Added the brewblox-ctl service pull command, that can be used for updating single services without performing a full brewblox-ctl update.
  • (improve) Added current status for Brewblox service containers to brewblox-ctl log output.
  • (improve) avahi-daemon is added to the list of apt packages installed by brewblox-ctl install.

firmware release date: 2020/08/24

This release is bigger (and took longer) than usual. We’re introducing new features, but we’re also working towards having a stable and well-documented API that can be used for hobby projects or third-party applications.

To make the automation service more flexible, we’re introducing scripted actions and conditions. These provide an alternative to the existing UI-based configuration.

Brewblox is gradually becoming more stable, and we decided now is a good time to add public documentation for block data types. This will help anyone who wants to listen in on block state events or use their own service, script, or application to read or write blocks.

Recently, we switched from AMQP events to MQTT. We’re very happy with how this turned out, and are now updating the eventbus service to run Mosquitto. This lets us use some very useful MQTT features that were not available in RabbitMQ.

The infrastructure for Spark discovery over Wifi has been improved, resulting in the removal of the mdns service.

We also added two more Quickstart wizards, and gave the block / block widget wizards an overhaul.

Automation scripts

While implementing automation functionality, the limitations of a fully UI-based configuration became noticeable. If the action or condition is repetitive, complicated, or uncommon, then it quickly becomes cumbersome or even impossible to configure.

Our solution is to implement an optional JavaScript sandbox for actions and conditions.

Some of the highlights:

  • The scripting API is optional.

Scripts are not a replacement for UI-based configuration.
They are an extension of the Brewblox design philosophy, where we build everything to be flexible and accessible, but add shortcuts to make the popular easy.
Here, scripts provide the flexibility, and the UI-based options are the shortcuts.

  • The UI code editor helps.

The script editor has multiple features to make it easier to write and test your scripts.

While editing, you can run the script in the automation service, and immediately see the output.

We also added snippet generators for common functionality. These snippets can ask you some questions, and will then generate code.

For example, the Get block field snippet will show you a dropdown to select a block and field,
and will then add the getBlockField() function call with the arguments already filled in.

  • Helper functions are included.

There are functions to get and set block values, but also to help you check values.
For example, the qty(value, unit) function helps you write conditions where unit conversion is handled automatically.

Block types

With the introduction of the automation scripting sandbox, users can now access the raw block data.
To help with that, we’re declaring blocks a public interface, and added reference documentation.
Starting with the next release, we’ll use a deprecation period if we have to make any breaking changes to block data types.

Eventbus migration

In the 2020/06/15 release, we started to migrate from the AMQP event protocol to MQTT.
This release we’re making the MQTT-only Mosquitto broker the default image for the eventbus service.

We’re not aware of any third-party service still relying on AMQP, but you can switch back to using RabbitMQ if you want to.

To do so: add the following service override to your docker-compose.yml file.

  eventbus:
    image: brewblox/rabbitmq:${BREWBLOX_RELEASE}

Do note that the deprecation period for AMQP support ends 2020/09/15. After that, all AMQP events will be ignored.

mDNS changes

Previously, Brewblox used a separate service to do Wifi discovery of Spark controllers.
We’ve revisited this design, and replaced it with a change to the avahi-daemon configuration on the host.

This means we now have one less service, and no longer use port 5000.
For more details, see the decision document.

This change does depend on the host environment and network layout.
The change to Avahi settings is kept optional, and we mapped multiple alternatives. If you want to run Brewblox on a system without Avahi, or are having problems with the new settings, feel free to drop us a message.

Wizardry

This release includes two more Quick Start wizards: Brew kettle, and Fridge without beer sensor.

Brew kettle produces a control chain for a single input/output heater, comparable to the BK in a HERMS setup.

Fridge without beer sensor produces the same output as the Fermentation fridge wizard,
but without the beer mode controls.
This is useful if you wish to (temporarily) use your fermentation chamber as a normal fridge.

A common issue when running Quick Start wizards was that you’d arrive at the hardware step,
and then had to figure out if your beer sensor was New|TempSensorOneWire-1 or New|TempSensorOneWire-2.

We can’t magically decide what the purpose is of a newly discovered sensor, but we can help with identification. Most wizards now start with a discovery step. Here you are shown the current status and measured value of available OneWire sensors and chips, with prominent “change block name” buttons.
Unplug a device, and one of these blocks will suddenly have a disconnected status.

Block (widget) wizards were somewhat clunky, so we reworked those, and added a New Block option to wizardry.
In the New Widget wizard you can create a widget that is based on either a new, or an existing block.
In the New Block wizard you can create a new block, and optionally add a widget for displaying your block on a dashboard.

Changes

  • (improve) Changed the default eventbus broker from RabbitMQ to Mosquitto.
  • (remove) Removed support for UI plugins.
  • (feature) Added the New Block wizard to the Wizardry menu.
  • (feature) Quick Start wizards now have a step for identifying and renaming discovered blocks.
  • (feature) Added the Brew kettle Quick Start wizard.
  • (feature) Added the Fridge without beer sensor Quick Start wizard.
  • (feature) Added a Builder part for the Setpoint Driver block.
  • (improve) If the PID is controlling a Setpoint Driver, values in PID and Setpoint Driver parts are automatically converted to user temp units.
    • The underlying value is still unitless degC.
  • (improve) Added a Setpoint Driver part to the Builder layout generated by the HERMS Quickstart wizard.
  • (feature) brewblox-ctl setup and brewblox-ctl update enable reflection in the avahi-daemon config. This removes the need for a separate mdns service.
  • (remove) Removed the mdns service.
  • (improve) The Spark service no longer relies on the mdns service for Wifi device discovery.
  • (improve) Spark device discovery in brewblox-ctl no longer requires pulling and running an mdns container.
  • (improve) Removed the --mdns-port setting from brewblox-ctl service ports.
  • (documentation) Added documentation for the state/history events published by the Spark service.
    • These events are now considered a public interface, meaning we’ll strive to make any changes backwards compatible. A deprecation period will be used if this is impossible.
  • (documentation) Added documentation for block types. You can find it at https://brewblox.netlify.app/dev/reference/block_types.html.
    • Blocks are now also considered a public interface spec.
  • (improve) Updated traefik and traefik label syntax to v2.
  • (feature) The DS2408 block can now toggle between Valve mode and Actuator mode.
  • (feature) The last controller actions before shutdown are now logged when the Spark service connects. This will help us debug controller crashes.
  • (improve) The UI now immediately shows updated status if the Spark service stops or crashes.
  • (improve) If the Spark service is unable to connect to a controller, it will gradually increase the retry interval.
    • The minimum interval is 2s, the maximum is 30s. After 20 failed attempts, the service increases the interval, and restarts.
    • The retry interval is reset when a connection attempt succeeds.
  • (improve) Generated (default) labels in Graph/Metrics widgets now support degree units other dan Celsius/Fahrenheit/Kelvin.
    • For example: sensor/value[degP] will have the default graph label [sensor] value °P.
    • This change is not applied retroactively. To update the default label, remove and re-add the field.
  • (feature) The legend in graphs now shows the latest value for each field.
  • (improve) Improved dialogs for selecting blocks / block fields.
  • (feature) In dashboard edit mode, you can now move selected widgets by using the arrow keys.
  • (feature) In Brewery Builder, you can now move selected parts by using arrow keys.
  • (feature) You can now double click on widgets to toggle between Basic and Full modes.
  • (improve) Improved the block wizard and block widget wizard layout.
  • (improve) Overlaid dialogs now show a “back” button instead of a “close” button.
  • (feature) Added the brewblox-ctl add-plaato command to add a service for the Plaato digital airlock.
  • (feature) Added the brewblox-ctl makecert command to generate SSL certificates.
  • (feature) Added the brewblox-ctl libs command to reload the release-specific commands.
  • (improve) Tweaked Influx settings to reduce SD card wear and tear.
  • (improve) Added dmesg to the log generated by brewblox-ctl log.
  • (improve) brewblox-ctl add-spark now shows a warning if an existing Spark service is found that has no --device-id or --device-host flag set. This prevents errors where both services attempt to connect to the same controller.
  • (improve) brewblox-ctl setup no longer creates the Home dashboard and spark-one service in the UI. Quick Start wizards and service autodiscovery made presets redundant.
  • (improve) Added the --quiet flag when installing Python packages in brewblox-ctl update.
  • (improve) If the digital actuator state is pending, the Valve part will now show a spinner. This mirrors behavior of the ON/OFF button shown in digital actuator / valve / pin array blocks.
  • (improve) The enable/disable toggle in blocks is now more consistent, and mentions which block is (or isn’t) driven.
  • (update) Updated device-os in firmware to 1.5.2, with fix for uninitialized variable in network handler.
  • (improve) Improved test coverage tooling in firmware.
  • (fix) Fix rounding errors when converting Celsius to Fahrenheit in firmware.
  • (fix) Reduced impact of OneWire disconnects and communication errors in firmware, so they do not slow down the system.
  • (fix) The history service now correctly discards invalid history event data.
  • (fix) Fixed a bug where min/max range overrides in the Graph were converted to string values.
  • (fix) Dashboard widgets no longer make sudden large jumps when being dragged.
  • (fix) The Setpoint Profile graph is no longer sometimes initially rendered much smaller than the widget.
  • (fix) Fixed a bug where Spark blocks were not correctly logged in brewblox-ctl log.
  • (fix) Moving widgets no longer causes a document update conflict in the datastore.
  • (fix) The shelf height in the Fridge part is now editable again.

Automation changes

  • (improve) Improved visibility for inactive automation elements.
  • (improve) The title property is now editable when adding a new automation action/condition.
  • (improve) The automation editor is now enabled on mobile or small screens.
  • (fix) The automation editor now shows the correct template when loading a /ui/automation/<template-id> URL.
  • (feature) Added Scripted action.
  • (feature) Added Scripted condition.
  • (feature) Added code snippet generators to the script editor.
  • (improve) Block value conditions now correctly convert quantity values (eg. degC/degF) if the condition and block use different units.
  • (fix) HTTP Request action errors now show the error, and not just “request failed with status code XXX”.
  • (fix) Changing block links in the Block change action no longer causes an error.
5 Likes

WOW ! That’s a huge upgrade. Looks very good so far. :+1:t2:

1 Like

Wow thats a big update!!
When I run the update I get the following. When I run the pip3 instal… I get an error that it is not reconized. I run brewblox on a synology NAS btw.

login as: Dennis
Dennis@192.168.1.105's password:
Dennis@NASSIE:~$ ./brewblox/brewblox-ctl update
-sh: ./brewblox/brewblox-ctl: No such file or directory
Dennis@NASSIE:~$ cd ./brewblox
Dennis@NASSIE:~/brewblox$ brewblox-ctl update
Failed to import dependency from brewblox-ctl.
The minimum required version is 0.21.0.
To update brewblox-ctl, run:

     pip3 install --user --upgrade --no-cache-dir brewblox-ctl

module 'brewblox_ctl.utils' has no attribute 'clearenv'

You can run the suggested command (pip3 install etc), and then retry the update

On my synology:
python3 -m pip install --user --upgrade --no-cache-dir brewblox-ctl

the alias pip3 for python3 -m pip is missing.

I tried but I get the following:

Dennis@NASSIE:~$ python3 -m pip --user -- 
upgrade --no-cache-dir brewblox-ctl

Usage:
  /volume1/@appstore/python3/bin/python3 -m pip <command> [options]

no such option: --user

Elco made a typo and omitted install. I updated his comment.

Got it working! thanks!

1 Like

Update seemed to complete without any issues but now the UI service troubleshooter is giving the error

Your Spark service is paused, and not automatically connecting to your controller.
This status can be toggled manually.

I can’t seem to find where I toggle this pause status. Any ideas?

Edit 1:

Logs here.

The spark-one service seems to be throwing the following error:

spark-one_1  | 2020-08-29T04:04:25.218182040Z 2020/08/29 04:04:25 ERROR    brewblox_service.repeater       <SparkConduit for None> error during runtime: ClientConnectorError(Cannot connect to host 172.17.0.1:5000 ssl:default [Connect call failed ('172.17.0.1', 5000)])

edit 2:

172.17.0.1 was the mdns address?

I tried flashing the firmware over usb to see if that fixed anything. For some reason I was thinking that the update script would prompt me to flash the firmware if necessary.

Now I’m getting new and different errors from brewblox-ctl follow spark-one:

spark-one_1  | 2020/08/29 04:24:50 INFO     brewblox_service.couchdb        <CouchDBClient for 
http://datastore:5984> Existing document found (spark-one-service-db)
spark-one_1  | 2020/08/29 04:24:50 INFO     ...blox_devcon_spark.datastore  <CouchDBServiceStore for spark-service/spark-one-service-db> Read 3 setting(s). Rev = 3-131efc1d9ba6863c79568df51d38265c
spark-one_1  | 2020/08/29 04:24:52 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:24:52 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:24:52 INFO     ...lox_devcon_spark.connection  Automatically detected ['/dev/ttyACM0', 'P1 - P1 Serial', 'USB VID:PID=2B04:C008 SER=3e0021000551353432383931 LOCATION=1-1.4:1.0']
spark-one_1  | 2020/08/29 04:24:52 INFO     ...lox_devcon_spark.connection  discovered usb /dev/ttyACM0
spark-one_1  | 2020/08/29 04:24:52 INFO     ..._devcon_spark.communication  Connected <SparkConduit for /dev/ttyACM0>
spark-one_1  | 2020/08/29 04:24:52 INFO     ...blox_devcon_spark.commander  HandshakeMessage(name='BREWBLOX', firmware_version='94793741', proto_version='dfbd615', firmware_date='2020-08-24', proto_date='2020-08-23', system_version='1.5.2', platform='p1', reset_reason_hex='78', reset_data_hex='00', device_id='3E0021000551353432383931', reset_reason='DFU_MODE', reset_data='NOT_SPECIFIED')
spark-one_1  | 2020/08/29 04:24:52 INFO     ...blox_devcon_spark.commander  HandshakeMessage(name='BREWBLOX', firmware_version='94793741', proto_version='dfbd615', firmware_date='2020-08-24', proto_date='2020-08-23', system_version='1.5.2', platform='p1', reset_reason_hex='78', reset_data_hex='00', device_id='3E0021000551353432383931', reset_reason='DFU_MODE', reset_data='NOT_SPECIFIED')
spark-one_1  | 2020/08/29 04:24:52 ERROR    ...evcon_spark.synchronization  Sync subroutine failed: sync handshake - IncompatibleFirmware()
spark-one_1  | 2020/08/29 04:24:52 ERROR    ...evcon_spark.synchronization  Incompatible firmware version detected
spark-one_1  | 2020/08/29 04:25:22 INFO     ..._devcon_spark.communication  Closed <SparkConduit for /dev/ttyACM0>

Here’s the full log post-flashing.

Edit 3:

I noticed that it goes back to the original error if I disconnect the USB:

spark-one_1  | 2020/08/29 04:47:20 INFO     __main__                        firmware.ini: {'firmware_version': '423cbd6f', 'firmware_date': '2020-06-23 12:32:58 +0200', 'proto_version': '0da74dd', 'proto_date': '2020-05-03 18:55:52 +0200', 'system_version': '1.5.0'}
spark-one_1  | 2020/08/29 04:47:20 INFO     brewblox_service.service        Service name: spark-one
spark-one_1  | 2020/08/29 04:47:20 INFO     brewblox_service.service        Service info: 0.5.2-455-gac228eb @ Tue Jun 23 12:32:46 UTC 2020
spark-one_1  | 2020/08/29 04:47:20 INFO     brewblox_service.service        Service config: {'host': '0.0.0.0', 'port': 5000, 'output': None, 'name': 'spark-one', 'debug': False, 'eventbus_host': 'eventbus', 'eventbus_port': 5672, 'mqtt_protocol': 'mqtt', 'mqtt_host': 'eventbus', 'mqtt_port': None, 'mqtt_path': '/eventbus', 'history_topic': 'brewcast/history', 'state_topic': 'brewcast/state', 'simulation': False, 'device_host': None, 'device_port': 8332, 'device_serial': None, 'device_id': None, 'discovery': 'all', 'command_timeout': 10, 'broadcast_interval': 5, 'broadcast_timeout': 60, 'broadcast_valid': 60, 'read_timeout': 30, 'mdns_host': '172.17.0.1', 'mdns_port': 5000, 'volatile': False, 'skip_version_check': False}
spark-one_1  | 2020/08/29 04:47:20 INFO     brewblox_service.mqtt           Starting <EventHandler for mqtt://eventbus:1883>
spark-one_1  | 2020/08/29 04:47:20 INFO     brewblox_service.mqtt           <EventHandler for mqtt://eventbus:1883> connected
spark-one_1  | 2020/08/29 04:47:20 INFO     brewblox_service.couchdb        <CouchDBClient for http://datastore:5984> Existing document found (spark-one-service-db)
spark-one_1  | 2020/08/29 04:47:20 INFO     ...blox_devcon_spark.datastore  <CouchDBServiceStore for spark-service/spark-one-service-db> Read 3 setting(s). Rev = 3-131efc1d9ba6863c79568df51d38265c
spark-one_1  | 2020/08/29 04:47:20 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:20 ERROR    brewblox_service.repeater       <SparkConduit for None> error during runtime: ClientConnectorError(Cannot connect to host 172.17.0.1:5000 ssl:default [Connect call failed ('172.17.0.1', 5000)])
spark-one_1  | 2020/08/29 04:47:22 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:22 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:24 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:24 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:26 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:26 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:28 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:28 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:30 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:30 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:32 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:32 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:34 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:34 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:36 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:36 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:38 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:38 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:40 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:40 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:42 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:42 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:44 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:44 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:46 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:46 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:49 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:49 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:51 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:51 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:53 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:53 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:55 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:55 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:57 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:57 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:47:59 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:47:59 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:48:01 INFO     ..._devcon_spark.communication  Retrying connection...
spark-one_1  | 2020/08/29 04:48:01 INFO     ...lox_devcon_spark.connection  Starting device discovery, type=all
spark-one_1  | 2020/08/29 04:48:01 ERROR    ..._devcon_spark.communication  Connection retry attempts exhausted. Exiting now.
spark-one_1  | ======== Running on http://0.0.0.0:5000 ========
spark-one_1  | (Press CTRL+C to quit)

I seem to be having a similar problem.

@adempewolff @Trig The “pause autoconnect” button is an issue on our end. It should be fixed after running

docker-compose pull ui
docker-compose up -d

@adempewolff It looks like we made a typo when deploying the backwards compatible rpi-${BREWBLOX_RELEASE} image for the spark service.

Pushed a fixed version now, but you can also clean up your config by running:

brewblox-ctl add-spark -f --name spark-one
brewblox-ctl add-spark -f --name spark-sim --simulation

If you’d rather not update your config:

docker-compose pull spark-one
docker-compose up -d

Thanks. The new UI adds a resume auto-connect button, but clicking it doesn’t appear to do anything. I’m going to move on to the real fix now, but just wanted to give this UX feedback first.


edit:
The service connects to the spark correctly after the add-spark -f command. Looks like everything is working correctly now. Thanks!

The formatting of the service status event changed this update, so that was to be expected if service was not updated yet.

Good to hear. We’ll probably have a look at auto-detecting and migrating the rpi- prefixes in config. They’re no longer required, and the backwards compatibility apparently has become a source of bugs.

Still no joy.

Datastore startup issues are occasionally resolved by forcibly restarting the service:

docker-compose up -d --force-recreate datastore

The command line says its done but still the same with slightly different graphics

Just checking: what is the age of your SD card? The datastore is often the first to notice EOL read errors.

If you run docker-compose logs datastore, does it print its welcome message?

Not sure but several years, ~5.
Screen Shot 2020-08-30 at 10.39.18 AM

Looks like it already crashed and restarted once.

It may come online in a minute or so, or another restart may help.

I do advise making a backup and storing it externally. Continuous writing to SD cards (aka. history data) is not great for a card’s lifespan. Datastore troubles may be an indication disk sectors are reaching end of life.

I have just re-run the ctl update and all appears ok.

Thanks for your help.