This shows you the differences between two versions of the page.
Both sides previous revision Previous revision Next revision | Previous revision | ||
wiki:test [2021/02/13 13:14] vizycam |
wiki:test [2021/10/16 18:30] (current) vizycam |
||
---|---|---|---|
Line 1: | Line 1: | ||
- | Set or get the (virtual) DIP switch state. The DIP switches are a set | + | [[wiki:running_utilities|utilities]] |
- | of "switches" that allow you to control Vizy's power-on or power-off | + | |
- | behavior. Once they are set, they will retain the setting even if | + | |
- | power is removed. hello [here](https://vizycamcam.com). | + | |
- | The switches are a set of values that can be ORed together: | + | |
- | * DIPSWITCH_EXT_BUTTON, used to set external/remote power button, | + | [[wiki:pinoouts|pinouts]] |
- | e.g. with outdoor enclosure. Default disabled. | + | |
- | * DIPSWITCH_MUTE_BUZZER, used to mute the buzzer. Default disabled. | + | [[wiki:ssh|ssh]] |
- | * DIPSWITCH_NO_BG_LED, used to disable the background LED, which is | + | |
- | normally set to yellow upon power up. Default disabled. | + | [[wiki:birdfeeder_app|birdfeeder]] |
- | * DIPSWITCH_POWER_DEFAULT_OFF, if this power mode is set and you | + | |
+ | [[wiki:stage|stage]] | ||
+ | |||
+ | hello | ||
+ | <HTML> | ||
+ | <!doctype html> | ||
+ | <html lang="en"> | ||
+ | <head> | ||
+ | <meta charset="utf-8"> | ||
+ | <meta name="viewport" content="width=device-width, initial-scale=1, minimum-scale=1" /> | ||
+ | <meta name="generator" content="pdoc 0.9.2" /> | ||
+ | <title>vizypowerboard API documentation</title> | ||
+ | <meta name="description" content="This module is used with the Vizy Power Board, which is a printed circuit | ||
+ | board that plugs into the Raspberry Pi I/O connector and is included | ||
+ | with …" /> | ||
+ | <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/sanitize.min.css" integrity="sha256-PK9q560IAAa6WVRRh76LtCaI8pjTJ2z11v0miyNNjrs=" crossorigin> | ||
+ | <link rel="preload stylesheet" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/10up-sanitize.css/11.0.1/typography.min.css" integrity="sha256-7l/o7C8jubJiy74VsKTidCy1yBkRtiUGbVkYBylBqUg=" crossorigin> | ||
+ | <link rel="stylesheet preload" as="style" href="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/styles/github.min.css" crossorigin> | ||
+ | <style>:root{--highlight-color:#fe9}.flex{display:flex !important}body{line-height:1.5em}#content{padding:10px}#sidebar{padding:15px;overflow:hidden}#sidebar > *:last-child{margin-bottom:2cm}.http-server-breadcrumbs{font-size:130%;margin:0 0 15px 0}#footer{font-size:.75em;padding:5px 30px;border-top:1px solid #ddd;text-align:right}#footer p{margin:0 0 0 1em;display:inline-block}#footer p:last-child{margin-right:30px}h1,h2,h3,h4,h5{font-weight:300}h1{font-size:2.5em;line-height:1.1em}h2{font-size:1.75em;margin:1em 0 .50em 0}h3{font-size:1.4em;margin:25px 0 10px 0}h4{margin:0;font-size:105%}h1:target,h2:target,h3:target,h4:target,h5:target,h6:target{background:var(--highlight-color);padding:.2em 0}a{color:#058;text-decoration:none;transition:color .3s ease-in-out}a:hover{color:#e82}.title code{font-weight:bold}h2[id^="header-"]{margin-top:2em}.ident{color:#900}pre code{background:#f8f8f8;font-size:.8em;line-height:1.4em}code{background:#f2f2f1;padding:1px 4px;overflow-wrap:break-word}h1 code{background:transparent}pre{background:#f8f8f8;border:0;border-top:1px solid #ccc;border-bottom:1px solid #ccc;margin:1em 0;padding:1ex}#http-server-module-list{display:flex;flex-flow:column}#http-server-module-list div{display:flex}#http-server-module-list dt{min-width:10%}#http-server-module-list p{margin-top:0}.toc ul,#index{list-style-type:none;margin:0;padding:0}#index code{background:transparent}#index h3{border-bottom:1px solid #ddd}#index ul{padding:0}#index h4{margin-top:.6em;font-weight:bold}@media (min-width:200ex){#index .two-column{column-count:2}}@media (min-width:300ex){#index .two-column{column-count:3}}dl{margin-bottom:2em}dl dl:last-child{margin-bottom:4em}dd{margin:0 0 1em 3em}#header-classes + dl > dd{margin-bottom:3em}dd dd{margin-left:2em}dd p{margin:10px 0}.name{background:#eee;font-weight:bold;font-size:.85em;padding:5px 10px;display:inline-block;min-width:40%}.name:hover{background:#e0e0e0}dt:target .name{background:var(--highlight-color)}.name > span:first-child{white-space:nowrap}.name.class > span:nth-child(2){margin-left:.4em}.inherited{color:#999;border-left:5px solid #eee;padding-left:1em}.inheritance em{font-style:normal;font-weight:bold}.desc h2{font-weight:400;font-size:1.25em}.desc h3{font-size:1em}.desc dt code{background:inherit}.source summary,.git-link-div{color:#666;text-align:right;font-weight:400;font-size:.8em;text-transform:uppercase}.source summary > *{white-space:nowrap;cursor:pointer}.git-link{color:inherit;margin-left:1em}.source pre{max-height:500px;overflow:auto;margin:0}.source pre code{font-size:12px;overflow:visible}.hlist{list-style:none}.hlist li{display:inline}.hlist li:after{content:',\2002'}.hlist li:last-child:after{content:none}.hlist .hlist{display:inline;padding-left:1em}img{max-width:100%}td{padding:0 .5em}.admonition{padding:.1em .5em;margin-bottom:1em}.admonition-title{font-weight:bold}.admonition.note,.admonition.info,.admonition.important{background:#aef}.admonition.todo,.admonition.versionadded,.admonition.tip,.admonition.hint{background:#dfd}.admonition.warning,.admonition.versionchanged,.admonition.deprecated{background:#fd4}.admonition.error,.admonition.danger,.admonition.caution{background:lightpink}</style> | ||
+ | <style media="screen and (min-width: 700px)">@media screen and (min-width:700px){#sidebar{width:35%;position:sticky;top:0}#content{width:70%;max-width:100ch;padding:3em 4em;border-left:1px solid #ddd}pre code{font-size:1em}.item .name{font-size:1em}main{display:flex;flex-direction:row-reverse;justify-content:flex-end}.toc ul ul,#index ul{padding-left:1.5em}.toc > ul > li{margin-top:.5em}}</style> | ||
+ | <style media="print">@media print{#sidebar h1{page-break-before:always}.source{display:none}}@media print{*{background:transparent !important;color:#000 !important;box-shadow:none !important;text-shadow:none !important}a[href]:after{content:" (" attr(href) ")";font-size:90%}a[href][title]:after{content:none}abbr[title]:after{content:" (" attr(title) ")"}.ir a:after,a[href^="javascript:"]:after,a[href^="#"]:after{content:""}pre,blockquote{border:1px solid #999;page-break-inside:avoid}thead{display:table-header-group}tr,img{page-break-inside:avoid}img{max-width:100% !important}@page{margin:0.5cm}p,h2,h3{orphans:3;widows:3}h1,h2,h3,h4,h5,h6{page-break-after:avoid}}</style> | ||
+ | <script defer src="https://cdnjs.cloudflare.com/ajax/libs/highlight.js/10.1.1/highlight.min.js" integrity="sha256-Uv3H6lx7dJmRfRvH8TH6kJD1TSK1aFcwgx+mdg3epi8=" crossorigin></script> | ||
+ | <script>window.addEventListener('DOMContentLoaded', () => hljs.initHighlighting())</script> | ||
+ | </head> | ||
+ | <body> | ||
+ | <main> | ||
+ | <article id="content"> | ||
+ | <header> | ||
+ | <h1 class="title">Module <code>vizypowerboard</code></h1> | ||
+ | </header> | ||
+ | <section id="section-intro"> | ||
+ | <p>This module is used with the Vizy Power Board, which is a printed circuit | ||
+ | board that plugs into the Raspberry Pi I/O connector and is included | ||
+ | with the Vizy camera. | ||
+ | More information | ||
+ | about Vizy can be found <a href="https://vizycamcam.com">here</a>.</p> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python"># Copyright (C) 2021 Charmed Labs LLC | ||
+ | # | ||
+ | # begin license header | ||
+ | # | ||
+ | # This file is part of Vizy Software. | ||
+ | # | ||
+ | # This source code is provided under the terms of the | ||
+ | # GNU General Public License v2 (http://www.gnu.org/licenses/gpl-2.0.html). | ||
+ | # Those wishing to use this source code, software and/or | ||
+ | # technologies under different licensing terms should contact us at | ||
+ | # support@charmedlabs.com. | ||
+ | # | ||
+ | # end license header | ||
+ | """ | ||
+ | This module is used with the Vizy Power Board, which is a printed circuit | ||
+ | board that plugs into the Raspberry Pi I/O connector and is included | ||
+ | with the Vizy camera. More information | ||
+ | about Vizy can be found [here](https://vizycamcam.com). | ||
+ | """ | ||
+ | import smbus | ||
+ | import RPi.GPIO as GPIO | ||
+ | import time | ||
+ | import datetime | ||
+ | import os | ||
+ | |||
+ | FILE_VERSION = 1 | ||
+ | COMPAT_HW_VERSION = [3, 0] | ||
+ | |||
+ | ERROR_GENERIC = 255 | ||
+ | ERROR_BUSY = 254 | ||
+ | ERROR_READ_ONLY = 253 | ||
+ | ERROR_NOT_SUPPORTED = 252 | ||
+ | |||
+ | EXEC_OFFSET = 0xc0 | ||
+ | EXEC_RW = 0x80 | ||
+ | EXEC_WRITE = 0x80 | ||
+ | EXEC_NVCONFIG = 1 | ||
+ | EXEC_AD = 2 | ||
+ | EXEC_DA = 3 | ||
+ | EXEC_RTC = 16 | ||
+ | EXEC_RTC_CALIBRATE = 17 | ||
+ | |||
+ | IO_MODE_INPUT = 0 | ||
+ | """Used with `VizyPowerBoard.io_set_mode()`.""" | ||
+ | IO_MODE_OUTPUT = 0x80 | ||
+ | """Used with `VizyPowerBoard.io_set_mode()`.""" | ||
+ | IO_MODE_HIGH_CURRENT = IO_MODE_OUTPUT | 0x40 | ||
+ | """Used with `VizyPowerBoard.io_set_mode()`.""" | ||
+ | |||
+ | DIPSWITCH_EXT_BUTTON = 0x01 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | DIPSWITCH_MUTE_BUZZER = 0x02 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | DIPSWITCH_NO_BG_LED = 0x04 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | DIPSWITCH_POWER_DEFAULT_OFF = 0x00 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | DIPSWITCH_POWER_DEFAULT_ON = 0x40 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | DIPSWITCH_POWER_SWITCH = 0x80 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | DIPSWITCH_POWER_PLUG = 0xc0 | ||
+ | """Used with `VizyPowerBoard.dip_switches()`.""" | ||
+ | |||
+ | POWER_ON_SOURCE_ALARM = 0x01 | ||
+ | """Used with `VizyPowerBoard.power_on_source()`.""" | ||
+ | POWER_ON_SOURCE_POWER_BUTTON = 0x02 | ||
+ | """Used with `VizyPowerBoard.power_on_source()`.""" | ||
+ | POWER_ON_SOURCE_12V = 0x03 | ||
+ | """Used with `VizyPowerBoard.power_on_source()`.""" | ||
+ | POWER_ON_SOURCE_5V = 0x04 | ||
+ | """Used with `VizyPowerBoard.power_on_source()`.""" | ||
+ | |||
+ | CHANNEL_VIN = 4 | ||
+ | """Used with `VizyPowerBoard.measure()`.""" | ||
+ | CHANNEL_5V = 5 | ||
+ | """Used with `VizyPowerBoard.measure()`.""" | ||
+ | |||
+ | class VizyPowerBoard: | ||
+ | """ | ||
+ | This class may be | ||
+ | instantiated by more than one process. The vizy-powerd service | ||
+ | instantiates this class and uses it to monitor and control things such | ||
+ | as power-off requests, CPU temperature, fan speed, etc. | ||
+ | User programs can also instantiate this class and | ||
+ | use its methods simultaneously. | ||
+ | """ | ||
+ | def __init__(self, addr=0x14, bus=1): | ||
+ | """ | ||
+ | Args: | ||
+ | addr (integer, optional, default=0x14): I2C address of the board | ||
+ | bus (integer, optional, default=1): the I2C bus number | ||
+ | |||
+ | """ | ||
+ | self.bus = smbus.SMBus(bus) | ||
+ | self.addr = addr | ||
+ | hwv = self.hw_version() | ||
+ | if hwv!=COMPAT_HW_VERSION: | ||
+ | raise RuntimeError("The hardware version of your Vizy Power Board (" + str(hwv[0])+'.'+str(hwv[1]) + ") is incompatible with this software file (" + str(COMPAT_HW_VERSION[0])+'.'+str(COMPAT_HW_VERSION[1]) + ").") | ||
+ | |||
+ | @staticmethod | ||
+ | def _bcd2decimal(bcd): | ||
+ | tens = (bcd&0xf0)>>4 | ||
+ | ones = bcd&0x0f | ||
+ | return tens*10 + ones | ||
+ | |||
+ | @staticmethod | ||
+ | def _decimal2bcd(dec): | ||
+ | tens = int(dec/10) | ||
+ | ones = dec%10 | ||
+ | return (tens<<4) | ones | ||
+ | |||
+ | @staticmethod | ||
+ | def _u_int8(i): | ||
+ | i = round(i) | ||
+ | if i>0xff: | ||
+ | return 0xff | ||
+ | if i<0: | ||
+ | return 0 | ||
+ | return i | ||
+ | |||
+ | @staticmethod | ||
+ | def _int8(i): | ||
+ | i = round(i) | ||
+ | if i>0x7f: | ||
+ | return 0x7f | ||
+ | if i<-0x80: | ||
+ | return 0x80 | ||
+ | if i<0: | ||
+ | return 0x100+i | ||
+ | return i | ||
+ | |||
+ | @staticmethod | ||
+ | def _uint16(i): | ||
+ | i = round(i) | ||
+ | if i>0xffff: | ||
+ | return 0xffff | ||
+ | if i<0: | ||
+ | return 0 | ||
+ | return i | ||
+ | |||
+ | def _status(self): | ||
+ | return self.bus.read_i2c_block_data(self.addr, 0, 1)[0] | ||
+ | |||
+ | def _wait_until_not_busy(self): | ||
+ | while self._status()==ERROR_BUSY: | ||
+ | time.sleep(0.001) | ||
+ | |||
+ | def hw_version(self): | ||
+ | """ | ||
+ | Returns the major and minor versions of the PCB as a 2-item list. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 1, 2) | ||
+ | |||
+ | def fw_version(self): | ||
+ | """ | ||
+ | Returns the major, minor and build versions of the firmware as | ||
+ | a 3-item list. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 3, 3) | ||
+ | |||
+ | def resource_url(self): | ||
+ | """ | ||
+ | Returns the url of a JSON file that contains information about | ||
+ | resources, such as the location of the latest version of this code, | ||
+ | latest firmware, etc. | ||
+ | """ | ||
+ | chars = self.bus.read_i2c_block_data(self.addr, 6, 32) | ||
+ | s = '' | ||
+ | for c in chars: | ||
+ | if c==0: # read up to the null character | ||
+ | break | ||
+ | s += chr(c) | ||
+ | return s | ||
+ | |||
+ | def uuid(self): | ||
+ | """ | ||
+ | Returns a 16-byte unique ID that can be used an a unique | ||
+ | ID for your Vizy camera. This unique ID is stored on the Vizy Power | ||
+ | Board and remains constant regardless of firmware upgrades, etc. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 22, 16) | ||
+ | |||
+ | def power_off_requested(self): | ||
+ | """ | ||
+ | Returns `True` if Vizy's button is held down for more than 5 seconds | ||
+ | indicating that the user wishes to initiate safe shutdown and power | ||
+ | off. Returns `False` otherwise. | ||
+ | |||
+ | This is used by the vizy-powerd service. | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 38, 1) | ||
+ | if button[0]==0x0f: | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | def power_off(self, t=5000): | ||
+ | """ | ||
+ | Powers Vizy off. The `t` argument specifies how long | ||
+ | to wait before turning off (specified in milliseconds). The | ||
+ | vizy-powerd service calls this upon shutdown. | ||
+ | """ | ||
+ | self.bus.write_i2c_block_data(self.addr, 38, [0x1f, int(t/100)]) | ||
+ | |||
+ | def power_on_alarm_date(self, datetime_=None): | ||
+ | """ | ||
+ | If you wish to power off your Vizy and have it "wake up" at a | ||
+ | specified time and date, call this method with the desired | ||
+ | datetime object and initiate a shutdown. (e.g. `sudo shutdown now`). | ||
+ | |||
+ | |||
+ | The code below tells Vizy to turn on on December 2, 2022, 11:18am. | ||
+ | |||
+ | import vizypowerboard as vpb | ||
+ | from datetime import datetime | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | d=datetime(year=2022, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.power_on_alarm_date(d) | ||
+ | |||
+ | Args: | ||
+ | datetime_ (datetime, optional, default=None): `datetime` object that | ||
+ | specifies the date/time to "wake up" (turn on). | ||
+ | |||
+ | Returns: | ||
+ | Calling without a datetime object returns a `datetime` object | ||
+ | reflecting the active alarm time. If there is no active alarm, | ||
+ | `None` is returned. | ||
+ | |||
+ | Notes: | ||
+ | * Once setting the alarm date, Vizy will retain it even if Vizy loses | ||
+ | power for extended periods of time. | ||
+ | * If the alarm expires while Vizy is on, Vizy will emit a buzzer tone | ||
+ | and remain on. | ||
+ | * If the alarm expires while Vizy is off (but plugged into and | ||
+ | receiving power), Vizy will turn on. | ||
+ | * If the alarm expires while Vizy is unplugged from (or not receiving) | ||
+ | power, Vizy will turn on as soon as it receives power. | ||
+ | """ | ||
+ | if datetime_ is None: | ||
+ | t = self.bus.read_i2c_block_data(self.addr, 41, 6) | ||
+ | if t[5]==0: | ||
+ | return None | ||
+ | return datetime.datetime(year=self._bcd2decimal(t[5])+2016, month=self._bcd2decimal(t[4]), day=self._bcd2decimal(t[3]), hour=self._bcd2decimal(t[2]), minute=self._bcd2decimal(t[1]), second=self._bcd2decimal(t[0])) | ||
+ | t = [self._decimal2bcd(datetime_.second), self._decimal2bcd(datetime_.minute), self._decimal2bcd(datetime_.hour), self._decimal2bcd(datetime_.day), self._decimal2bcd(datetime_.month), self._decimal2bcd(datetime_.year-2016)] | ||
+ | self.bus.write_i2c_block_data(self.addr, 41, t) | ||
+ | |||
+ | |||
+ | def power_on_alarm_seconds(self, seconds=None): | ||
+ | """ | ||
+ | Allows you to specify a power on alarm in seconds in the future. | ||
+ | For example, if you wish for Vizy to turn back on in 5 minutes, you | ||
+ | would call `power_on_alarm_seconds(300)` and then initiate a shutdown. | ||
+ | See `VizyPowerBoard.power_on_alarm_date()` for more information about the power on | ||
+ | alarm. | ||
+ | |||
+ | Args: | ||
+ | seconds (integer, optional, default=None): Number of seconds in the | ||
+ | future you wish Vizy to turn on in. | ||
+ | |||
+ | Returns: | ||
+ | Calling this method without arguments returns the number of seconds | ||
+ | until the alarm expires. If no alarm is pending, `None` is returned. | ||
+ | """ | ||
+ | if seconds is None: | ||
+ | pod = self.power_on_alarm_date() | ||
+ | if pod is None: | ||
+ | return None | ||
+ | diff = pod - self.rtc() | ||
+ | return diff.days*86400+diff.seconds | ||
+ | # Add seconds to current time and set power on alarm | ||
+ | self.power_on_alarm_date(self.rtc()+datetime.timedelta(seconds=seconds)) | ||
+ | |||
+ | def power_on_source(self): | ||
+ | """ | ||
+ | Returns the source of what turned on Vizy for the current power cycle. | ||
+ | It is one of either: | ||
+ | |||
+ | * POWER_ON_SOURCE_ALARM, indicates that Vizy was powered on | ||
+ | by the power on alarm expiring. See power_on_alarm_date() and | ||
+ | power_on_alarm_seconds(). | ||
+ | * POWER_ON_SOURCE_POWER_BUTTON, indicates that Vizy was powered | ||
+ | on by someone pressing the button. | ||
+ | * POWER_ON_SOURCE_12V = indicates that Vizy was powered on | ||
+ | by power being applied to 12V power input. This only applies if the | ||
+ | dip switch power mode allows powering on by plugging in power via the | ||
+ | 12V power input. | ||
+ | * POWER_ON_SOURCE_5V, indicates that Vizy was powered on by applying | ||
+ | power to the Raspberry Pi's USB-C power input. | ||
+ | """ | ||
+ | source = self.bus.read_i2c_block_data(self.addr, 40, 1)[0] | ||
+ | return source | ||
+ | |||
+ | def button(self): | ||
+ | """ | ||
+ | Returns `True` if the button is being pressed currently, `False` otherwise. | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 47, 1) | ||
+ | if button[0]&0x02: | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | def button_pressed(self): | ||
+ | """ | ||
+ | Returns `True` if the button was pressed within the last 5 seconds, | ||
+ | `False` otherwise. This is useful if the polling is intermittant or | ||
+ | slow, as button presses are not missed (as long as you check at least | ||
+ | every 5 seconds!) | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 47, 1) | ||
+ | if button[0]&0x01: | ||
+ | # Reset bit | ||
+ | self.bus.write_i2c_block_data(self.addr, 47, [0]) | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | def vcc12(self, state=None): | ||
+ | """ | ||
+ | If `state` is `True`, the 12V output on Vizy's I/O connector (pin 2) will be enabled and output 12V. If `state` is `False`, the 12V output | ||
+ | will be disabled. Calling without arguments returns its current state. | ||
+ | """ | ||
+ | config = self.bus.read_i2c_block_data(self.addr, 48, 1) | ||
+ | if state is None: | ||
+ | return True if config&0x01 else False | ||
+ | if state: | ||
+ | config[0] |= 0x01 | ||
+ | else: | ||
+ | config[0] &= ~0x01 | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, 48, config) | ||
+ | |||
+ | def vcc5(self, state=None): | ||
+ | """ | ||
+ | If `state` is `True`, the 5V output on Vizy's I/O connector (pin 3) will | ||
+ | be enabled and output 5V. If `state` is `False`, the 5V output will be | ||
+ | disabled. Calling without arguments returns its current state. | ||
+ | """ | ||
+ | if state is None: | ||
+ | return True if config&0x02 else False | ||
+ | if state: | ||
+ | config[0] |= 0x02 | ||
+ | else: | ||
+ | config[0] &= ~0x02 | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, 48, config) | ||
+ | |||
+ | def led(self, r=0, g=0, b=0, flashes=0, repeat=False, atten=255, on=100, off=100, pause=200): | ||
+ | """ | ||
+ | Controls the RGB LED in one of several modes: | ||
+ | |||
+ | * **Continuous**: just setting `r`, `g`, and `b` will set set the LED color | ||
+ | and turn it on continuously. `r`, `g`, and `b` values range between 0 | ||
+ | and 255. | ||
+ | |||
+ | led(255, 0, 0) # turn on LED, red color | ||
+ | led(255, 255, 0) # turn on LED, yellow color | ||
+ | led(0, 0, 255) # turn on LED, blue color | ||
+ | led(0, 0, 0) # turn off LED | ||
+ | |||
+ | * **Flashes**: setting the `flashes` value to a non-zero value will | ||
+ | cause the LED to flash the indicated number of times. You can also | ||
+ | specify the `on` and `off` arguments to indicate the amount of time | ||
+ | the LED is on and off for each flash (specified in milliseconds). | ||
+ | |||
+ | led(0, 0, 255, 3) # flash blue 3 times (then stop) | ||
+ | led(0, 0, 255, 3, on=500, off=500) # flash blue 3 times, much more slowly | ||
+ | |||
+ | * **Repeated flashes**: setting the `repeat` argument to `True` | ||
+ | will cause the indicated flash pattern to repeat forever. You can | ||
+ | modify the pause time between flash sequences by setting `pause` | ||
+ | (milliseconds). | ||
+ | |||
+ | led(0, 0, 255, 3, True, pause=500) # flash blue 3 times, pause, then repeat | ||
+ | led(0, 0, 255, repeat=True, on=500, off=500)` # flash blue forever | ||
+ | |||
+ | * **Flashing with attenuation**: you can also set the `atten` | ||
+ | argument to make the LED to turn on and off slowly, like an | ||
+ | incandescent light. The value is the rate of change, so lower values | ||
+ | cause the LED color to change more slowly. | ||
+ | |||
+ | led(0, 0, 255, repeat=True, atten=10, on=500, off=500) # flash blue forever, but turn on and turn off very slowly | ||
+ | """ | ||
+ | on = self._u_int8(on/10) | ||
+ | off = self._u_int8(off/10) | ||
+ | pause = self._u_int8(pause/10) | ||
+ | if flashes==0: | ||
+ | mode = 0 | ||
+ | if repeat: | ||
+ | mode = 0x02 | ||
+ | else: | ||
+ | mode = 0x01 | ||
+ | self.bus.write_i2c_block_data(self.addr, 49, [mode, self._u_int8(r), self._u_int8(g), self._u_int8(b), | ||
+ | on, off, self._u_int8(flashes), pause, self._u_int8(atten)]) | ||
+ | |||
+ | def led_unicorn(self, speed=10): | ||
+ | """ | ||
+ | This causes the LED to change color in succession: red, orange, yellow, | ||
+ | green, cyan, blue, violet and then repeat again. The `speed` argument | ||
+ | ranges between 0 and 10. For example, a `speed` of 0 causes the color | ||
+ | to change once every couple of seconds. A `speed` of 10 causes the color to change about 6 times per second. | ||
+ | """ | ||
+ | if speed>10: | ||
+ | speed = 10 | ||
+ | elif speed<0: | ||
+ | speed = 0 | ||
+ | |||
+ | on = self._u_int8(10 + (10-speed)*140/10) | ||
+ | atten = self._u_int8(3 + speed*47/10) | ||
+ | self.bus.write_i2c_block_data(self.addr, 49, [0x08, 0, 0, 0, on, 0, 0, 0, atten]) | ||
+ | |||
+ | def led_background(self, r=-1, g=-1, b=-1): | ||
+ | """ | ||
+ | The "background" LED color is the color of the LED when the LED is | ||
+ | turned "off". It is used by system programs such as vizy-powerd to | ||
+ | indicate Vizy's system state such as, booting (yellow), finished | ||
+ | booting (green), running server (blue), etc. Note, the background | ||
+ | color does not influence the LED colors set by calls to led(). | ||
+ | |||
+ | Calling led_background() without arguments returns the current | ||
+ | background color r, g, and b values in a list. | ||
+ | |||
+ | led_background(48, 48, 0) # set background color to yellow | ||
+ | led(0, 255, 0) # turn on LED, green (as expected) | ||
+ | led(0, 0, 0) # turn LED off, and restore background color (yellow as set previously) | ||
+ | """ | ||
+ | if r==-1: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 58, 3) | ||
+ | self.bus.write_i2c_block_data(self.addr, 58, [self._u_int8(r), self._u_int8(g), self._u_int8(b)]) | ||
+ | |||
+ | |||
+ | def buzzer(self, freq, on=250, off=250, count=1, shift=0): | ||
+ | """ | ||
+ | Emit tones through the buzzer. The `freq` argument sets the frequency | ||
+ | of the tone in Hz and the `on` argument sets the length of the tone in | ||
+ | milliseconds. | ||
+ | |||
+ | If you wish to emit more than 1 tone, you can set the | ||
+ | `count` argument to the desired number. | ||
+ | |||
+ | The `off` argument sets | ||
+ | the pause between tones in milliseconds. The `shift` argument is a | ||
+ | value ranging between -128 and 127 that causes the tone's frequency to | ||
+ | raise if `shift` is greater than 0, or descend if `shift` is less | ||
+ | than 0. | ||
+ | |||
+ | buzzer(2000, 500) # emit a 2000Hz tone for 500ms | ||
+ | buzzer(1000, count=3) # emit a 1000Hz tone 3 times | ||
+ | buzzer(1000, 500, 100, 3) # emit a longer 1000Hz tone 3 times | ||
+ | buzzer(500, 250, 0, 10, 50) # emit 10 warbling tones like a siren | ||
+ | """ | ||
+ | freq = self._uint16(freq) | ||
+ | f0 = freq&0xff | ||
+ | f1 = (freq>>8)&0xff | ||
+ | self.bus.write_i2c_block_data(self.addr, 61, [0, f0, f1, self._u_int8(on/10), self._u_int8(off/10), | ||
+ | self._u_int8(count), self._int8(shift)]) | ||
+ | |||
+ | |||
+ | def io_set_mode(self, bit, mode=None): | ||
+ | """ | ||
+ | Sets or gets the io mode of the given bit. The `bit` argument ranges | ||
+ | between 0 and 3 and corresponds to pins 4 through 7 on Vizy's IO | ||
+ | connector. Calling this method with no mode argument returns the mode | ||
+ | of the given bit, otherwise, the `mode` argument can be one of | ||
+ | the following: | ||
+ | |||
+ | * IO_MODE_INPUT, sets the bit to high impedance input mode with | ||
+ | a weak pull-up resistor to 3.3V. The input voltage can range between | ||
+ | 0 and Vin where Vin is the supply voltage. Voltages lower than 1V | ||
+ | read as logic 0 via `VizyPowerBoard.io_bits()`. Voltages higher | ||
+ | than 1V are read as logic 1. | ||
+ | * IO_MODE_OUTPUT, sets the bit to output mode. If the bit is set to | ||
+ | logic 0 via `VizyPowerBoard.io_bits()`, the output voltage is 0V. | ||
+ | If the bit is set to logic 1, the output voltage is 3.3V. In this mode, each bit can source and sink 5mA. | ||
+ | * IO_MODE_HIGH_CURRENT, sets the bit to a special high current mode | ||
+ | that allows the bit to sink as much as 1000mA, when the bit | ||
+ | set to logic 0 via `VizyPowerBoard.io_bits()`. Otherwise, this mode | ||
+ | behaves exactly as IO_MODE_OUTPUT. | ||
+ | """ | ||
+ | if mode is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 68+bit, 1)[0] | ||
+ | if bit==2: | ||
+ | # set GPIO14 (UART TXD) as input so it doesn't conflict | ||
+ | GPIO.setwarnings(False) | ||
+ | GPIO.setmode(GPIO.BOARD) | ||
+ | GPIO.setup(8, GPIO.IN) | ||
+ | self.bus.write_i2c_block_data(self.addr, 68+bit, [self._u_int8(mode)]) | ||
+ | |||
+ | def io_bits(self, bits=None): | ||
+ | """ | ||
+ | Sets or gets the logic state of the IO bits 0 through 3, corresponding | ||
+ | to pins 4 through 7 on Vizy's IO connector. The `bits` argument ranges | ||
+ | between 0 and 15 as it is a binary representation of the logic state | ||
+ | of the 4 IO bits. If the `bits` argument isn't specified, the logic | ||
+ | state of the 4 bits are returned. | ||
+ | |||
+ | io_bits(1) # set IO bit 0 to logic 1 and bits 1, 2, 3 to logic 0 | ||
+ | io_bits(10) # set IO bits 1 and 3 to logic 1 and bits 0 and 2 to logic 0 | ||
+ | bits = io_bits() # get logic state of IO bits | ||
+ | io_bits(io_bits()|1) # set IO bit 0 to logic 1, leave bits 1, 2, 3 unchanged. | ||
+ | """ | ||
+ | if bits is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 72, 1) | ||
+ | self.bus.write_i2c_block_data(self.addr, 72, [bits]) | ||
+ | |||
+ | |||
+ | def ir_filter(self, state=None, duration=None): | ||
+ | """ | ||
+ | Actuates the electro-mechanical IR-cut filter on Vizy's camera. Vizy | ||
+ | uses a CMOS sensor which is very sensitive to IR light. IR light can | ||
+ | adversely affect color fidelity during the daytime so an IR-cut filter | ||
+ | is used to block the IR light (`state`=True). During nighttime IR light | ||
+ | is typically used as a discreet method of illumination and the IR-cut | ||
+ | filter is removed (`state`=False). If the `state` argument is `True`, | ||
+ | the filter is actuated in place (and will stay there) until another | ||
+ | call is made with the state argument set to `False` (in which case the | ||
+ | IR-cut filter will be removed). | ||
+ | |||
+ | The `duration` argument is optional and | ||
+ | controls how long (in milliseconds) the actuation coil receives power. | ||
+ | |||
+ | Calling this method without arguments returns the state of IR-cut | ||
+ | filter. | ||
+ | """ | ||
+ | if state is None: | ||
+ | return True if self.bus.read_i2c_block_data(self.addr, 73, 1)[0] else False | ||
+ | data = [1] if state else [0] | ||
+ | if duration is not None: | ||
+ | data.append(int(duration/10)) | ||
+ | self.bus.write_i2c_block_data(self.addr, 73, data) | ||
+ | |||
+ | def fan(self, speed=None): | ||
+ | """ | ||
+ | Set or get the fan speed. The `speed` argument can range between 0 | ||
+ | and 12 where 0 is off and 12 is maximum speed. The fan speed | ||
+ | is typically regulated automatically by vizy-powerd. | ||
+ | |||
+ | Calling this method without arguments returns the current fan speed. | ||
+ | """ | ||
+ | if speed is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 75, 1)[0] | ||
+ | self.bus.write_i2c_block_data(self.addr, 75, [self._u_int8(speed)]) | ||
+ | |||
+ | |||
+ | def rtc(self, datetime_=None): | ||
+ | """ | ||
+ | Set or get the real-time clock time/date. The Vizy power board has a | ||
+ | battery-backed real-time clock that keeps track of time/date, power | ||
+ | alarms, etc. even while Vizy is receiving no power. Passing in a | ||
+ | datetime object sets the time/date. | ||
+ | |||
+ | Calling this method with no | ||
+ | arguments returns a datetime object representing the current | ||
+ | date/time. | ||
+ | |||
+ | For example, the code below sets the date to December 2, 2020, 11:18am: | ||
+ | |||
+ | from datetime import datetime | ||
+ | import vizypowerboard as vpb | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | t = datetime(year=2020, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.rtc(t) | ||
+ | """ | ||
+ | if datetime_ is None: | ||
+ | # Initiate RTC retrieval. | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | t = self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 8) | ||
+ | return datetime.datetime(year=self._bcd2decimal(t[7])+2016, month=self._bcd2decimal(t[6]), day=self._bcd2decimal(t[4]), hour=self._bcd2decimal(t[3]), minute=self._bcd2decimal(t[2]), second=self._bcd2decimal(t[1])) | ||
+ | |||
+ | t = [EXEC_RTC|EXEC_WRITE, 0, self._decimal2bcd(datetime_.second), self._decimal2bcd(datetime_.minute), self._decimal2bcd(datetime_.hour), self._decimal2bcd(datetime_.day), 0, self._decimal2bcd(datetime_.month), self._decimal2bcd(datetime_.year-2016)] | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, t) | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | def dip_switches(self, val=None): | ||
+ | """ | ||
+ | Set or get the (virtual) DIP switch state. The DIP switches are a set | ||
+ | of "switches" that allow you to control Vizy's power-on or power-off | ||
+ | behavior. Once they are set, they will retain the setting even if | ||
+ | power is removed. | ||
+ | The switches are a set of values that can be ORed together: | ||
+ | |||
+ | * DIPSWITCH_EXT_BUTTON, used to set external/remote power button, | ||
+ | e.g. with outdoor enclosure. Default disabled. | ||
+ | * DIPSWITCH_MUTE_BUZZER, used to mute the buzzer. Default disabled. | ||
+ | * DIPSWITCH_NO_BG_LED, used to disable the background LED, which is | ||
+ | normally set to yellow upon power up. Default disabled. | ||
+ | * DIPSWITCH_POWER_DEFAULT_OFF, if this power mode is set and you | ||
+ | plug in power via the 12V power input, Vizy will remain off by default | ||
+ | until you press the button to power Vizy on. And if power is | ||
+ | interrupted while Vizy is on, *Vizy will turn off*. If power is | ||
+ | interrupted while Vizy is off, Vizy will remain off. This is the | ||
+ | default power mode. | ||
+ | * DIPSWITCH_POWER_DEFAULT_ON, if this power mode is set and you | ||
+ | plug in power via the 12V power input, Vizy will turn on by default | ||
+ | without pressing the button. And if power is interrupted while Vizy | ||
+ | is on, Vizy will reset, but remain on. If power is interrupted while | ||
+ | Vizy is off, *Vizy will turn on*. Default disabled. | ||
+ | * DIPSWITCH_POWER_SWITCH, if this power mode is set and you plug in | ||
+ | power via the 12V power input, Vizy will remain off (as in | ||
+ | DIPSWITCH_POWER_DEFAULT_OFF mode), unless power was | ||
+ | removed while Vizy was on. In this case Vizy will turn on when you | ||
+ | (re)apply power. If power is interrupted while Vizy is off, Vizy | ||
+ | will remain off. This behavior is similar to the behavior of a real | ||
+ | power switch in that it retains the power "state" (on or off) and acts | ||
+ | accordingly. Default disabled. | ||
+ | * DIPSWITCH_POWER_PLUG, if this power mode is set Vizy will remain | ||
+ | powered on as long as it receives power through the 12V power plug, | ||
+ | and you will not be able to turn off Vizy via button or software as | ||
+ | long as it's plugged in and receiving power. Default disabled. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | dip_switches(DIPSWITCH_EXT_BUTTON | DIPSWITCH_POWER_SWITCH) # set external power button and power switch mode | ||
+ | """ | ||
+ | if val is None: | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_NVCONFIG]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | return self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 1)[0] | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_NVCONFIG|EXEC_WRITE, self._u_int8(val)]) | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | def rtc_adjust(self, val=None): | ||
+ | """ | ||
+ | Set or get the real-time clock adjustment. Vizy's real-time clock | ||
+ | crystal has an accuracy of 20ppm, which means that it can lose or gain | ||
+ | up to 20 seconds for every 1 million elapsed seconds. Normally, this | ||
+ | isn't an issue, but if Vizy spends a lengthy period of time (months) | ||
+ | without Internet access, it could lose or gain minutes, which | ||
+ | depending on the application could be significant. The adjustment | ||
+ | value can offset this inaccuracy. The `val` argument can range | ||
+ | between -128 and 127 and has a multiplier of 2.170 ppm. | ||
+ | |||
+ | For example, | ||
+ | if the RTC is gaining 10 seconds every 1 million seconds, you would | ||
+ | call `rtc_adjust(-5)`. If the RTC is losing 10 seconds every million | ||
+ | seconds you would call `rtc_adjust(5)`. | ||
+ | |||
+ | The adjustment value is retained by the real-time clock even when | ||
+ | Vizy's power is removed. | ||
+ | """ | ||
+ | if val is None: | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC_CALIBRATE]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | return self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 1)[0] | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC_CALIBRATE|EXEC_WRITE, self._int8(val)]) | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | |||
+ | def measure(self, channel): | ||
+ | """ | ||
+ | Get the voltage values of various channels. The returned value is | ||
+ | the voltage measured (in Volts) of the given channel. The `channel` | ||
+ | argument can be one of the following: | ||
+ | |||
+ | * CHANNEL_VIN, this channel measures the voltage present at the 12V | ||
+ | power input. | ||
+ | * CHANNEL_5V, this channel measures the voltage present at the 5V | ||
+ | voltage rail provided to the Raspberry Pi. | ||
+ | """ | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_AD, self._u_int8(channel)]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | val = self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+2, 2) | ||
+ | return (val[1]*0x100 + val[0])/1000 | ||
+ | |||
+ | |||
+ | def rtc_set_system_datetime(self, datetime_=None): | ||
+ | """ | ||
+ | A convenience method that sets the system time/date based on the | ||
+ | real-time time/date. This is called by vizy-powerd upon power-up. | ||
+ | """ | ||
+ | if os.geteuid()!=0: | ||
+ | raise PermissionError("You need root permission to set the time/date.") | ||
+ | if datetime_ is None: | ||
+ | datetime_ = self.rtc() | ||
+ | s = datetime_.isoformat() | ||
+ | os.system(f"sudo date -s {s}")</code></pre> | ||
+ | </details> | ||
+ | </section> | ||
+ | <section> | ||
+ | </section> | ||
+ | <section> | ||
+ | <h2 class="section-title" id="header-variables">Global variables</h2> | ||
+ | <dl> | ||
+ | <dt id="vizypowerboard.CHANNEL_5V"><code class="name">var <span class="ident">CHANNEL_5V</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.measure" href="#vizypowerboard.VizyPowerBoard.measure">VizyPowerBoard.measure()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.CHANNEL_VIN"><code class="name">var <span class="ident">CHANNEL_VIN</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.measure" href="#vizypowerboard.VizyPowerBoard.measure">VizyPowerBoard.measure()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_EXT_BUTTON"><code class="name">var <span class="ident">DIPSWITCH_EXT_BUTTON</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_MUTE_BUZZER"><code class="name">var <span class="ident">DIPSWITCH_MUTE_BUZZER</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_NO_BG_LED"><code class="name">var <span class="ident">DIPSWITCH_NO_BG_LED</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_POWER_DEFAULT_OFF"><code class="name">var <span class="ident">DIPSWITCH_POWER_DEFAULT_OFF</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_POWER_DEFAULT_ON"><code class="name">var <span class="ident">DIPSWITCH_POWER_DEFAULT_ON</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_POWER_PLUG"><code class="name">var <span class="ident">DIPSWITCH_POWER_PLUG</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.DIPSWITCH_POWER_SWITCH"><code class="name">var <span class="ident">DIPSWITCH_POWER_SWITCH</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">VizyPowerBoard.dip_switches()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.IO_MODE_HIGH_CURRENT"><code class="name">var <span class="ident">IO_MODE_HIGH_CURRENT</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.io_set_mode" href="#vizypowerboard.VizyPowerBoard.io_set_mode">VizyPowerBoard.io_set_mode()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.IO_MODE_INPUT"><code class="name">var <span class="ident">IO_MODE_INPUT</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.io_set_mode" href="#vizypowerboard.VizyPowerBoard.io_set_mode">VizyPowerBoard.io_set_mode()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.IO_MODE_OUTPUT"><code class="name">var <span class="ident">IO_MODE_OUTPUT</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.io_set_mode" href="#vizypowerboard.VizyPowerBoard.io_set_mode">VizyPowerBoard.io_set_mode()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.POWER_ON_SOURCE_12V"><code class="name">var <span class="ident">POWER_ON_SOURCE_12V</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.power_on_source" href="#vizypowerboard.VizyPowerBoard.power_on_source">VizyPowerBoard.power_on_source()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.POWER_ON_SOURCE_5V"><code class="name">var <span class="ident">POWER_ON_SOURCE_5V</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.power_on_source" href="#vizypowerboard.VizyPowerBoard.power_on_source">VizyPowerBoard.power_on_source()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.POWER_ON_SOURCE_ALARM"><code class="name">var <span class="ident">POWER_ON_SOURCE_ALARM</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.power_on_source" href="#vizypowerboard.VizyPowerBoard.power_on_source">VizyPowerBoard.power_on_source()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.POWER_ON_SOURCE_POWER_BUTTON"><code class="name">var <span class="ident">POWER_ON_SOURCE_POWER_BUTTON</span></code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Used with <code><a title="vizypowerboard.VizyPowerBoard.power_on_source" href="#vizypowerboard.VizyPowerBoard.power_on_source">VizyPowerBoard.power_on_source()</a></code>.</p></div> | ||
+ | </dd> | ||
+ | </dl> | ||
+ | </section> | ||
+ | <section> | ||
+ | </section> | ||
+ | <section> | ||
+ | <h2 class="section-title" id="header-classes">Classes</h2> | ||
+ | <dl> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard"><code class="flex name class"> | ||
+ | <span>class <span class="ident">VizyPowerBoard</span></span> | ||
+ | <span>(</span><span>addr=20, bus=1)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>This class may be | ||
+ | instantiated by more than one process. | ||
+ | The vizy-powerd service | ||
+ | instantiates this class and uses it to monitor and control things such | ||
+ | as power-off requests, CPU temperature, fan speed, etc.<br> | ||
+ | User programs can also instantiate this class and | ||
+ | use its methods simultaneously.</p> | ||
+ | <h2 id="args">Args</h2> | ||
+ | <dl> | ||
+ | <dt><strong><code>addr</code></strong> : <code>integer</code>, optional, default=<code>0x14</code></dt> | ||
+ | <dd>I2C address of the board</dd> | ||
+ | <dt><strong><code>bus</code></strong> : <code>integer</code>, optional, default=<code>1</code></dt> | ||
+ | <dd>the I2C bus number</dd> | ||
+ | </dl></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">class VizyPowerBoard: | ||
+ | """ | ||
+ | This class may be | ||
+ | instantiated by more than one process. The vizy-powerd service | ||
+ | instantiates this class and uses it to monitor and control things such | ||
+ | as power-off requests, CPU temperature, fan speed, etc. | ||
+ | User programs can also instantiate this class and | ||
+ | use its methods simultaneously. | ||
+ | """ | ||
+ | def __init__(self, addr=0x14, bus=1): | ||
+ | """ | ||
+ | Args: | ||
+ | addr (integer, optional, default=0x14): I2C address of the board | ||
+ | bus (integer, optional, default=1): the I2C bus number | ||
+ | |||
+ | """ | ||
+ | self.bus = smbus.SMBus(bus) | ||
+ | self.addr = addr | ||
+ | hwv = self.hw_version() | ||
+ | if hwv!=COMPAT_HW_VERSION: | ||
+ | raise RuntimeError("The hardware version of your Vizy Power Board (" + str(hwv[0])+'.'+str(hwv[1]) + ") is incompatible with this software file (" + str(COMPAT_HW_VERSION[0])+'.'+str(COMPAT_HW_VERSION[1]) + ").") | ||
+ | |||
+ | @staticmethod | ||
+ | def _bcd2decimal(bcd): | ||
+ | tens = (bcd&0xf0)>>4 | ||
+ | ones = bcd&0x0f | ||
+ | return tens*10 + ones | ||
+ | |||
+ | @staticmethod | ||
+ | def _decimal2bcd(dec): | ||
+ | tens = int(dec/10) | ||
+ | ones = dec%10 | ||
+ | return (tens<<4) | ones | ||
+ | |||
+ | @staticmethod | ||
+ | def _u_int8(i): | ||
+ | i = round(i) | ||
+ | if i>0xff: | ||
+ | return 0xff | ||
+ | if i<0: | ||
+ | return 0 | ||
+ | return i | ||
+ | |||
+ | @staticmethod | ||
+ | def _int8(i): | ||
+ | i = round(i) | ||
+ | if i>0x7f: | ||
+ | return 0x7f | ||
+ | if i<-0x80: | ||
+ | return 0x80 | ||
+ | if i<0: | ||
+ | return 0x100+i | ||
+ | return i | ||
+ | |||
+ | @staticmethod | ||
+ | def _uint16(i): | ||
+ | i = round(i) | ||
+ | if i>0xffff: | ||
+ | return 0xffff | ||
+ | if i<0: | ||
+ | return 0 | ||
+ | return i | ||
+ | |||
+ | def _status(self): | ||
+ | return self.bus.read_i2c_block_data(self.addr, 0, 1)[0] | ||
+ | |||
+ | def _wait_until_not_busy(self): | ||
+ | while self._status()==ERROR_BUSY: | ||
+ | time.sleep(0.001) | ||
+ | |||
+ | def hw_version(self): | ||
+ | """ | ||
+ | Returns the major and minor versions of the PCB as a 2-item list. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 1, 2) | ||
+ | |||
+ | def fw_version(self): | ||
+ | """ | ||
+ | Returns the major, minor and build versions of the firmware as | ||
+ | a 3-item list. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 3, 3) | ||
+ | |||
+ | def resource_url(self): | ||
+ | """ | ||
+ | Returns the url of a JSON file that contains information about | ||
+ | resources, such as the location of the latest version of this code, | ||
+ | latest firmware, etc. | ||
+ | """ | ||
+ | chars = self.bus.read_i2c_block_data(self.addr, 6, 32) | ||
+ | s = '' | ||
+ | for c in chars: | ||
+ | if c==0: # read up to the null character | ||
+ | break | ||
+ | s += chr(c) | ||
+ | return s | ||
+ | |||
+ | def uuid(self): | ||
+ | """ | ||
+ | Returns a 16-byte unique ID that can be used an a unique | ||
+ | ID for your Vizy camera. This unique ID is stored on the Vizy Power | ||
+ | Board and remains constant regardless of firmware upgrades, etc. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 22, 16) | ||
+ | |||
+ | def power_off_requested(self): | ||
+ | """ | ||
+ | Returns `True` if Vizy's button is held down for more than 5 seconds | ||
+ | indicating that the user wishes to initiate safe shutdown and power | ||
+ | off. Returns `False` otherwise. | ||
+ | |||
+ | This is used by the vizy-powerd service. | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 38, 1) | ||
+ | if button[0]==0x0f: | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | def power_off(self, t=5000): | ||
+ | """ | ||
+ | Powers Vizy off. The `t` argument specifies how long | ||
+ | to wait before turning off (specified in milliseconds). The | ||
+ | vizy-powerd service calls this upon shutdown. | ||
+ | """ | ||
+ | self.bus.write_i2c_block_data(self.addr, 38, [0x1f, int(t/100)]) | ||
+ | |||
+ | def power_on_alarm_date(self, datetime_=None): | ||
+ | """ | ||
+ | If you wish to power off your Vizy and have it "wake up" at a | ||
+ | specified time and date, call this method with the desired | ||
+ | datetime object and initiate a shutdown. (e.g. `sudo shutdown now`). | ||
+ | |||
+ | |||
+ | The code below tells Vizy to turn on on December 2, 2022, 11:18am. | ||
+ | |||
+ | import vizypowerboard as vpb | ||
+ | from datetime import datetime | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | d=datetime(year=2022, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.power_on_alarm_date(d) | ||
+ | |||
+ | Args: | ||
+ | datetime_ (datetime, optional, default=None): `datetime` object that | ||
+ | specifies the date/time to "wake up" (turn on). | ||
+ | |||
+ | Returns: | ||
+ | Calling without a datetime object returns a `datetime` object | ||
+ | reflecting the active alarm time. If there is no active alarm, | ||
+ | `None` is returned. | ||
+ | |||
+ | Notes: | ||
+ | * Once setting the alarm date, Vizy will retain it even if Vizy loses | ||
+ | power for extended periods of time. | ||
+ | * If the alarm expires while Vizy is on, Vizy will emit a buzzer tone | ||
+ | and remain on. | ||
+ | * If the alarm expires while Vizy is off (but plugged into and | ||
+ | receiving power), Vizy will turn on. | ||
+ | * If the alarm expires while Vizy is unplugged from (or not receiving) | ||
+ | power, Vizy will turn on as soon as it receives power. | ||
+ | """ | ||
+ | if datetime_ is None: | ||
+ | t = self.bus.read_i2c_block_data(self.addr, 41, 6) | ||
+ | if t[5]==0: | ||
+ | return None | ||
+ | return datetime.datetime(year=self._bcd2decimal(t[5])+2016, month=self._bcd2decimal(t[4]), day=self._bcd2decimal(t[3]), hour=self._bcd2decimal(t[2]), minute=self._bcd2decimal(t[1]), second=self._bcd2decimal(t[0])) | ||
+ | t = [self._decimal2bcd(datetime_.second), self._decimal2bcd(datetime_.minute), self._decimal2bcd(datetime_.hour), self._decimal2bcd(datetime_.day), self._decimal2bcd(datetime_.month), self._decimal2bcd(datetime_.year-2016)] | ||
+ | self.bus.write_i2c_block_data(self.addr, 41, t) | ||
+ | |||
+ | |||
+ | def power_on_alarm_seconds(self, seconds=None): | ||
+ | """ | ||
+ | Allows you to specify a power on alarm in seconds in the future. | ||
+ | For example, if you wish for Vizy to turn back on in 5 minutes, you | ||
+ | would call `power_on_alarm_seconds(300)` and then initiate a shutdown. | ||
+ | See `VizyPowerBoard.power_on_alarm_date()` for more information about the power on | ||
+ | alarm. | ||
+ | |||
+ | Args: | ||
+ | seconds (integer, optional, default=None): Number of seconds in the | ||
+ | future you wish Vizy to turn on in. | ||
+ | |||
+ | Returns: | ||
+ | Calling this method without arguments returns the number of seconds | ||
+ | until the alarm expires. If no alarm is pending, `None` is returned. | ||
+ | """ | ||
+ | if seconds is None: | ||
+ | pod = self.power_on_alarm_date() | ||
+ | if pod is None: | ||
+ | return None | ||
+ | diff = pod - self.rtc() | ||
+ | return diff.days*86400+diff.seconds | ||
+ | # Add seconds to current time and set power on alarm | ||
+ | self.power_on_alarm_date(self.rtc()+datetime.timedelta(seconds=seconds)) | ||
+ | |||
+ | def power_on_source(self): | ||
+ | """ | ||
+ | Returns the source of what turned on Vizy for the current power cycle. | ||
+ | It is one of either: | ||
+ | |||
+ | * POWER_ON_SOURCE_ALARM, indicates that Vizy was powered on | ||
+ | by the power on alarm expiring. See power_on_alarm_date() and | ||
+ | power_on_alarm_seconds(). | ||
+ | * POWER_ON_SOURCE_POWER_BUTTON, indicates that Vizy was powered | ||
+ | on by someone pressing the button. | ||
+ | * POWER_ON_SOURCE_12V = indicates that Vizy was powered on | ||
+ | by power being applied to 12V power input. This only applies if the | ||
+ | dip switch power mode allows powering on by plugging in power via the | ||
+ | 12V power input. | ||
+ | * POWER_ON_SOURCE_5V, indicates that Vizy was powered on by applying | ||
+ | power to the Raspberry Pi's USB-C power input. | ||
+ | """ | ||
+ | source = self.bus.read_i2c_block_data(self.addr, 40, 1)[0] | ||
+ | return source | ||
+ | |||
+ | def button(self): | ||
+ | """ | ||
+ | Returns `True` if the button is being pressed currently, `False` otherwise. | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 47, 1) | ||
+ | if button[0]&0x02: | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | def button_pressed(self): | ||
+ | """ | ||
+ | Returns `True` if the button was pressed within the last 5 seconds, | ||
+ | `False` otherwise. This is useful if the polling is intermittant or | ||
+ | slow, as button presses are not missed (as long as you check at least | ||
+ | every 5 seconds!) | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 47, 1) | ||
+ | if button[0]&0x01: | ||
+ | # Reset bit | ||
+ | self.bus.write_i2c_block_data(self.addr, 47, [0]) | ||
+ | return True | ||
+ | else: | ||
+ | return False | ||
+ | |||
+ | def vcc12(self, state=None): | ||
+ | """ | ||
+ | If `state` is `True`, the 12V output on Vizy's I/O connector (pin 2) will be enabled and output 12V. If `state` is `False`, the 12V output | ||
+ | will be disabled. Calling without arguments returns its current state. | ||
+ | """ | ||
+ | config = self.bus.read_i2c_block_data(self.addr, 48, 1) | ||
+ | if state is None: | ||
+ | return True if config&0x01 else False | ||
+ | if state: | ||
+ | config[0] |= 0x01 | ||
+ | else: | ||
+ | config[0] &= ~0x01 | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, 48, config) | ||
+ | |||
+ | def vcc5(self, state=None): | ||
+ | """ | ||
+ | If `state` is `True`, the 5V output on Vizy's I/O connector (pin 3) will | ||
+ | be enabled and output 5V. If `state` is `False`, the 5V output will be | ||
+ | disabled. Calling without arguments returns its current state. | ||
+ | """ | ||
+ | if state is None: | ||
+ | return True if config&0x02 else False | ||
+ | if state: | ||
+ | config[0] |= 0x02 | ||
+ | else: | ||
+ | config[0] &= ~0x02 | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, 48, config) | ||
+ | |||
+ | def led(self, r=0, g=0, b=0, flashes=0, repeat=False, atten=255, on=100, off=100, pause=200): | ||
+ | """ | ||
+ | Controls the RGB LED in one of several modes: | ||
+ | |||
+ | * **Continuous**: just setting `r`, `g`, and `b` will set set the LED color | ||
+ | and turn it on continuously. `r`, `g`, and `b` values range between 0 | ||
+ | and 255. | ||
+ | |||
+ | led(255, 0, 0) # turn on LED, red color | ||
+ | led(255, 255, 0) # turn on LED, yellow color | ||
+ | led(0, 0, 255) # turn on LED, blue color | ||
+ | led(0, 0, 0) # turn off LED | ||
+ | |||
+ | * **Flashes**: setting the `flashes` value to a non-zero value will | ||
+ | cause the LED to flash the indicated number of times. You can also | ||
+ | specify the `on` and `off` arguments to indicate the amount of time | ||
+ | the LED is on and off for each flash (specified in milliseconds). | ||
+ | |||
+ | led(0, 0, 255, 3) # flash blue 3 times (then stop) | ||
+ | led(0, 0, 255, 3, on=500, off=500) # flash blue 3 times, much more slowly | ||
+ | |||
+ | * **Repeated flashes**: setting the `repeat` argument to `True` | ||
+ | will cause the indicated flash pattern to repeat forever. You can | ||
+ | modify the pause time between flash sequences by setting `pause` | ||
+ | (milliseconds). | ||
+ | |||
+ | led(0, 0, 255, 3, True, pause=500) # flash blue 3 times, pause, then repeat | ||
+ | led(0, 0, 255, repeat=True, on=500, off=500)` # flash blue forever | ||
+ | |||
+ | * **Flashing with attenuation**: you can also set the `atten` | ||
+ | argument to make the LED to turn on and off slowly, like an | ||
+ | incandescent light. The value is the rate of change, so lower values | ||
+ | cause the LED color to change more slowly. | ||
+ | |||
+ | led(0, 0, 255, repeat=True, atten=10, on=500, off=500) # flash blue forever, but turn on and turn off very slowly | ||
+ | """ | ||
+ | on = self._u_int8(on/10) | ||
+ | off = self._u_int8(off/10) | ||
+ | pause = self._u_int8(pause/10) | ||
+ | if flashes==0: | ||
+ | mode = 0 | ||
+ | if repeat: | ||
+ | mode = 0x02 | ||
+ | else: | ||
+ | mode = 0x01 | ||
+ | self.bus.write_i2c_block_data(self.addr, 49, [mode, self._u_int8(r), self._u_int8(g), self._u_int8(b), | ||
+ | on, off, self._u_int8(flashes), pause, self._u_int8(atten)]) | ||
+ | |||
+ | def led_unicorn(self, speed=10): | ||
+ | """ | ||
+ | This causes the LED to change color in succession: red, orange, yellow, | ||
+ | green, cyan, blue, violet and then repeat again. The `speed` argument | ||
+ | ranges between 0 and 10. For example, a `speed` of 0 causes the color | ||
+ | to change once every couple of seconds. A `speed` of 10 causes the color to change about 6 times per second. | ||
+ | """ | ||
+ | if speed>10: | ||
+ | speed = 10 | ||
+ | elif speed<0: | ||
+ | speed = 0 | ||
+ | |||
+ | on = self._u_int8(10 + (10-speed)*140/10) | ||
+ | atten = self._u_int8(3 + speed*47/10) | ||
+ | self.bus.write_i2c_block_data(self.addr, 49, [0x08, 0, 0, 0, on, 0, 0, 0, atten]) | ||
+ | |||
+ | def led_background(self, r=-1, g=-1, b=-1): | ||
+ | """ | ||
+ | The "background" LED color is the color of the LED when the LED is | ||
+ | turned "off". It is used by system programs such as vizy-powerd to | ||
+ | indicate Vizy's system state such as, booting (yellow), finished | ||
+ | booting (green), running server (blue), etc. Note, the background | ||
+ | color does not influence the LED colors set by calls to led(). | ||
+ | |||
+ | Calling led_background() without arguments returns the current | ||
+ | background color r, g, and b values in a list. | ||
+ | |||
+ | led_background(48, 48, 0) # set background color to yellow | ||
+ | led(0, 255, 0) # turn on LED, green (as expected) | ||
+ | led(0, 0, 0) # turn LED off, and restore background color (yellow as set previously) | ||
+ | """ | ||
+ | if r==-1: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 58, 3) | ||
+ | self.bus.write_i2c_block_data(self.addr, 58, [self._u_int8(r), self._u_int8(g), self._u_int8(b)]) | ||
+ | |||
+ | |||
+ | def buzzer(self, freq, on=250, off=250, count=1, shift=0): | ||
+ | """ | ||
+ | Emit tones through the buzzer. The `freq` argument sets the frequency | ||
+ | of the tone in Hz and the `on` argument sets the length of the tone in | ||
+ | milliseconds. | ||
+ | |||
+ | If you wish to emit more than 1 tone, you can set the | ||
+ | `count` argument to the desired number. | ||
+ | |||
+ | The `off` argument sets | ||
+ | the pause between tones in milliseconds. The `shift` argument is a | ||
+ | value ranging between -128 and 127 that causes the tone's frequency to | ||
+ | raise if `shift` is greater than 0, or descend if `shift` is less | ||
+ | than 0. | ||
+ | |||
+ | buzzer(2000, 500) # emit a 2000Hz tone for 500ms | ||
+ | buzzer(1000, count=3) # emit a 1000Hz tone 3 times | ||
+ | buzzer(1000, 500, 100, 3) # emit a longer 1000Hz tone 3 times | ||
+ | buzzer(500, 250, 0, 10, 50) # emit 10 warbling tones like a siren | ||
+ | """ | ||
+ | freq = self._uint16(freq) | ||
+ | f0 = freq&0xff | ||
+ | f1 = (freq>>8)&0xff | ||
+ | self.bus.write_i2c_block_data(self.addr, 61, [0, f0, f1, self._u_int8(on/10), self._u_int8(off/10), | ||
+ | self._u_int8(count), self._int8(shift)]) | ||
+ | |||
+ | |||
+ | def io_set_mode(self, bit, mode=None): | ||
+ | """ | ||
+ | Sets or gets the io mode of the given bit. The `bit` argument ranges | ||
+ | between 0 and 3 and corresponds to pins 4 through 7 on Vizy's IO | ||
+ | connector. Calling this method with no mode argument returns the mode | ||
+ | of the given bit, otherwise, the `mode` argument can be one of | ||
+ | the following: | ||
+ | |||
+ | * IO_MODE_INPUT, sets the bit to high impedance input mode with | ||
+ | a weak pull-up resistor to 3.3V. The input voltage can range between | ||
+ | 0 and Vin where Vin is the supply voltage. Voltages lower than 1V | ||
+ | read as logic 0 via `VizyPowerBoard.io_bits()`. Voltages higher | ||
+ | than 1V are read as logic 1. | ||
+ | * IO_MODE_OUTPUT, sets the bit to output mode. If the bit is set to | ||
+ | logic 0 via `VizyPowerBoard.io_bits()`, the output voltage is 0V. | ||
+ | If the bit is set to logic 1, the output voltage is 3.3V. In this mode, each bit can source and sink 5mA. | ||
+ | * IO_MODE_HIGH_CURRENT, sets the bit to a special high current mode | ||
+ | that allows the bit to sink as much as 1000mA, when the bit | ||
+ | set to logic 0 via `VizyPowerBoard.io_bits()`. Otherwise, this mode | ||
+ | behaves exactly as IO_MODE_OUTPUT. | ||
+ | """ | ||
+ | if mode is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 68+bit, 1)[0] | ||
+ | if bit==2: | ||
+ | # set GPIO14 (UART TXD) as input so it doesn't conflict | ||
+ | GPIO.setwarnings(False) | ||
+ | GPIO.setmode(GPIO.BOARD) | ||
+ | GPIO.setup(8, GPIO.IN) | ||
+ | self.bus.write_i2c_block_data(self.addr, 68+bit, [self._u_int8(mode)]) | ||
+ | |||
+ | def io_bits(self, bits=None): | ||
+ | """ | ||
+ | Sets or gets the logic state of the IO bits 0 through 3, corresponding | ||
+ | to pins 4 through 7 on Vizy's IO connector. The `bits` argument ranges | ||
+ | between 0 and 15 as it is a binary representation of the logic state | ||
+ | of the 4 IO bits. If the `bits` argument isn't specified, the logic | ||
+ | state of the 4 bits are returned. | ||
+ | |||
+ | io_bits(1) # set IO bit 0 to logic 1 and bits 1, 2, 3 to logic 0 | ||
+ | io_bits(10) # set IO bits 1 and 3 to logic 1 and bits 0 and 2 to logic 0 | ||
+ | bits = io_bits() # get logic state of IO bits | ||
+ | io_bits(io_bits()|1) # set IO bit 0 to logic 1, leave bits 1, 2, 3 unchanged. | ||
+ | """ | ||
+ | if bits is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 72, 1) | ||
+ | self.bus.write_i2c_block_data(self.addr, 72, [bits]) | ||
+ | |||
+ | |||
+ | def ir_filter(self, state=None, duration=None): | ||
+ | """ | ||
+ | Actuates the electro-mechanical IR-cut filter on Vizy's camera. Vizy | ||
+ | uses a CMOS sensor which is very sensitive to IR light. IR light can | ||
+ | adversely affect color fidelity during the daytime so an IR-cut filter | ||
+ | is used to block the IR light (`state`=True). During nighttime IR light | ||
+ | is typically used as a discreet method of illumination and the IR-cut | ||
+ | filter is removed (`state`=False). If the `state` argument is `True`, | ||
+ | the filter is actuated in place (and will stay there) until another | ||
+ | call is made with the state argument set to `False` (in which case the | ||
+ | IR-cut filter will be removed). | ||
+ | |||
+ | The `duration` argument is optional and | ||
+ | controls how long (in milliseconds) the actuation coil receives power. | ||
+ | |||
+ | Calling this method without arguments returns the state of IR-cut | ||
+ | filter. | ||
+ | """ | ||
+ | if state is None: | ||
+ | return True if self.bus.read_i2c_block_data(self.addr, 73, 1)[0] else False | ||
+ | data = [1] if state else [0] | ||
+ | if duration is not None: | ||
+ | data.append(int(duration/10)) | ||
+ | self.bus.write_i2c_block_data(self.addr, 73, data) | ||
+ | |||
+ | def fan(self, speed=None): | ||
+ | """ | ||
+ | Set or get the fan speed. The `speed` argument can range between 0 | ||
+ | and 12 where 0 is off and 12 is maximum speed. The fan speed | ||
+ | is typically regulated automatically by vizy-powerd. | ||
+ | |||
+ | Calling this method without arguments returns the current fan speed. | ||
+ | """ | ||
+ | if speed is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 75, 1)[0] | ||
+ | self.bus.write_i2c_block_data(self.addr, 75, [self._u_int8(speed)]) | ||
+ | |||
+ | |||
+ | def rtc(self, datetime_=None): | ||
+ | """ | ||
+ | Set or get the real-time clock time/date. The Vizy power board has a | ||
+ | battery-backed real-time clock that keeps track of time/date, power | ||
+ | alarms, etc. even while Vizy is receiving no power. Passing in a | ||
+ | datetime object sets the time/date. | ||
+ | |||
+ | Calling this method with no | ||
+ | arguments returns a datetime object representing the current | ||
+ | date/time. | ||
+ | |||
+ | For example, the code below sets the date to December 2, 2020, 11:18am: | ||
+ | |||
+ | from datetime import datetime | ||
+ | import vizypowerboard as vpb | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | t = datetime(year=2020, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.rtc(t) | ||
+ | """ | ||
+ | if datetime_ is None: | ||
+ | # Initiate RTC retrieval. | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | t = self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 8) | ||
+ | return datetime.datetime(year=self._bcd2decimal(t[7])+2016, month=self._bcd2decimal(t[6]), day=self._bcd2decimal(t[4]), hour=self._bcd2decimal(t[3]), minute=self._bcd2decimal(t[2]), second=self._bcd2decimal(t[1])) | ||
+ | |||
+ | t = [EXEC_RTC|EXEC_WRITE, 0, self._decimal2bcd(datetime_.second), self._decimal2bcd(datetime_.minute), self._decimal2bcd(datetime_.hour), self._decimal2bcd(datetime_.day), 0, self._decimal2bcd(datetime_.month), self._decimal2bcd(datetime_.year-2016)] | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, t) | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | def dip_switches(self, val=None): | ||
+ | """ | ||
+ | Set or get the (virtual) DIP switch state. The DIP switches are a set | ||
+ | of "switches" that allow you to control Vizy's power-on or power-off | ||
+ | behavior. Once they are set, they will retain the setting even if | ||
+ | power is removed. | ||
+ | The switches are a set of values that can be ORed together: | ||
+ | |||
+ | * DIPSWITCH_EXT_BUTTON, used to set external/remote power button, | ||
+ | e.g. with outdoor enclosure. Default disabled. | ||
+ | * DIPSWITCH_MUTE_BUZZER, used to mute the buzzer. Default disabled. | ||
+ | * DIPSWITCH_NO_BG_LED, used to disable the background LED, which is | ||
+ | normally set to yellow upon power up. Default disabled. | ||
+ | * DIPSWITCH_POWER_DEFAULT_OFF, if this power mode is set and you | ||
+ | plug in power via the 12V power input, Vizy will remain off by default | ||
+ | until you press the button to power Vizy on. And if power is | ||
+ | interrupted while Vizy is on, *Vizy will turn off*. If power is | ||
+ | interrupted while Vizy is off, Vizy will remain off. This is the | ||
+ | default power mode. | ||
+ | * DIPSWITCH_POWER_DEFAULT_ON, if this power mode is set and you | ||
+ | plug in power via the 12V power input, Vizy will turn on by default | ||
+ | without pressing the button. And if power is interrupted while Vizy | ||
+ | is on, Vizy will reset, but remain on. If power is interrupted while | ||
+ | Vizy is off, *Vizy will turn on*. Default disabled. | ||
+ | * DIPSWITCH_POWER_SWITCH, if this power mode is set and you plug in | ||
+ | power via the 12V power input, Vizy will remain off (as in | ||
+ | DIPSWITCH_POWER_DEFAULT_OFF mode), unless power was | ||
+ | removed while Vizy was on. In this case Vizy will turn on when you | ||
+ | (re)apply power. If power is interrupted while Vizy is off, Vizy | ||
+ | will remain off. This behavior is similar to the behavior of a real | ||
+ | power switch in that it retains the power "state" (on or off) and acts | ||
+ | accordingly. Default disabled. | ||
+ | * DIPSWITCH_POWER_PLUG, if this power mode is set Vizy will remain | ||
+ | powered on as long as it receives power through the 12V power plug, | ||
+ | and you will not be able to turn off Vizy via button or software as | ||
+ | long as it's plugged in and receiving power. Default disabled. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | dip_switches(DIPSWITCH_EXT_BUTTON | DIPSWITCH_POWER_SWITCH) # set external power button and power switch mode | ||
+ | """ | ||
+ | if val is None: | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_NVCONFIG]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | return self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 1)[0] | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_NVCONFIG|EXEC_WRITE, self._u_int8(val)]) | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | def rtc_adjust(self, val=None): | ||
+ | """ | ||
+ | Set or get the real-time clock adjustment. Vizy's real-time clock | ||
+ | crystal has an accuracy of 20ppm, which means that it can lose or gain | ||
+ | up to 20 seconds for every 1 million elapsed seconds. Normally, this | ||
+ | isn't an issue, but if Vizy spends a lengthy period of time (months) | ||
+ | without Internet access, it could lose or gain minutes, which | ||
+ | depending on the application could be significant. The adjustment | ||
+ | value can offset this inaccuracy. The `val` argument can range | ||
+ | between -128 and 127 and has a multiplier of 2.170 ppm. | ||
+ | |||
+ | For example, | ||
+ | if the RTC is gaining 10 seconds every 1 million seconds, you would | ||
+ | call `rtc_adjust(-5)`. If the RTC is losing 10 seconds every million | ||
+ | seconds you would call `rtc_adjust(5)`. | ||
+ | |||
+ | The adjustment value is retained by the real-time clock even when | ||
+ | Vizy's power is removed. | ||
+ | """ | ||
+ | if val is None: | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC_CALIBRATE]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | return self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 1)[0] | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC_CALIBRATE|EXEC_WRITE, self._int8(val)]) | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | |||
+ | def measure(self, channel): | ||
+ | """ | ||
+ | Get the voltage values of various channels. The returned value is | ||
+ | the voltage measured (in Volts) of the given channel. The `channel` | ||
+ | argument can be one of the following: | ||
+ | |||
+ | * CHANNEL_VIN, this channel measures the voltage present at the 12V | ||
+ | power input. | ||
+ | * CHANNEL_5V, this channel measures the voltage present at the 5V | ||
+ | voltage rail provided to the Raspberry Pi. | ||
+ | """ | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_AD, self._u_int8(channel)]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | val = self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+2, 2) | ||
+ | return (val[1]*0x100 + val[0])/1000 | ||
+ | |||
+ | |||
+ | def rtc_set_system_datetime(self, datetime_=None): | ||
+ | """ | ||
+ | A convenience method that sets the system time/date based on the | ||
+ | real-time time/date. This is called by vizy-powerd upon power-up. | ||
+ | """ | ||
+ | if os.geteuid()!=0: | ||
+ | raise PermissionError("You need root permission to set the time/date.") | ||
+ | if datetime_ is None: | ||
+ | datetime_ = self.rtc() | ||
+ | s = datetime_.isoformat() | ||
+ | os.system(f"sudo date -s {s}")</code></pre> | ||
+ | </details> | ||
+ | <h3>Methods</h3> | ||
+ | <dl> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.button"><code class="name flex"> | ||
+ | <span>def <span class="ident">button</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns <code>True</code> if the button is being pressed currently, <code>False</code> otherwise.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def button(self): | ||
+ | """ | ||
+ | Returns `True` if the button is being pressed currently, `False` otherwise. | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 47, 1) | ||
+ | if button[0]&0x02: | ||
+ | return True | ||
+ | else: | ||
+ | return False</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.button_pressed"><code class="name flex"> | ||
+ | <span>def <span class="ident">button_pressed</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns <code>True</code> if the button was pressed within the last 5 seconds, | ||
+ | <code>False</code> otherwise. | ||
+ | This is useful if the polling is intermittant or | ||
+ | slow, as button presses are not missed (as long as you check at least | ||
+ | every 5 seconds!)</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def button_pressed(self): | ||
+ | """ | ||
+ | Returns `True` if the button was pressed within the last 5 seconds, | ||
+ | `False` otherwise. This is useful if the polling is intermittant or | ||
+ | slow, as button presses are not missed (as long as you check at least | ||
+ | every 5 seconds!) | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 47, 1) | ||
+ | if button[0]&0x01: | ||
+ | # Reset bit | ||
+ | self.bus.write_i2c_block_data(self.addr, 47, [0]) | ||
+ | return True | ||
+ | else: | ||
+ | return False</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.buzzer"><code class="name flex"> | ||
+ | <span>def <span class="ident">buzzer</span></span>(<span>self, freq, on=250, off=250, count=1, shift=0)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Emit tones through the buzzer. | ||
+ | The <code>freq</code> argument sets the frequency | ||
+ | of the tone in Hz and the <code>on</code> argument sets the length of the tone in | ||
+ | milliseconds. | ||
+ | </p> | ||
+ | <p>If you wish to emit more than 1 tone, you can set the | ||
+ | <code>count</code> argument to the desired number. | ||
+ | </p> | ||
+ | <p>The <code>off</code> argument sets | ||
+ | the pause between tones in milliseconds. | ||
+ | The <code>shift</code> argument is a | ||
+ | value ranging between -128 and 127 that causes the tone's frequency to | ||
+ | raise if <code>shift</code> is greater than 0, or descend if <code>shift</code> is less | ||
+ | than 0.</p> | ||
+ | <pre><code>buzzer(2000, 500) # emit a 2000Hz tone for 500ms | ||
+ | buzzer(1000, count=3) # emit a 1000Hz tone 3 times | ||
+ | buzzer(1000, 500, 100, 3) # emit a longer 1000Hz tone 3 times | ||
+ | buzzer(500, 250, 0, 10, 50) # emit 10 warbling tones like a siren | ||
+ | </code></pre></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def buzzer(self, freq, on=250, off=250, count=1, shift=0): | ||
+ | """ | ||
+ | Emit tones through the buzzer. The `freq` argument sets the frequency | ||
+ | of the tone in Hz and the `on` argument sets the length of the tone in | ||
+ | milliseconds. | ||
+ | |||
+ | If you wish to emit more than 1 tone, you can set the | ||
+ | `count` argument to the desired number. | ||
+ | |||
+ | The `off` argument sets | ||
+ | the pause between tones in milliseconds. The `shift` argument is a | ||
+ | value ranging between -128 and 127 that causes the tone's frequency to | ||
+ | raise if `shift` is greater than 0, or descend if `shift` is less | ||
+ | than 0. | ||
+ | |||
+ | buzzer(2000, 500) # emit a 2000Hz tone for 500ms | ||
+ | buzzer(1000, count=3) # emit a 1000Hz tone 3 times | ||
+ | buzzer(1000, 500, 100, 3) # emit a longer 1000Hz tone 3 times | ||
+ | buzzer(500, 250, 0, 10, 50) # emit 10 warbling tones like a siren | ||
+ | """ | ||
+ | freq = self._uint16(freq) | ||
+ | f0 = freq&0xff | ||
+ | f1 = (freq>>8)&0xff | ||
+ | self.bus.write_i2c_block_data(self.addr, 61, [0, f0, f1, self._u_int8(on/10), self._u_int8(off/10), | ||
+ | self._u_int8(count), self._int8(shift)])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.dip_switches"><code class="name flex"> | ||
+ | <span>def <span class="ident">dip_switches</span></span>(<span>self, val=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Set or get the (virtual) DIP switch state. | ||
+ | The DIP switches are a set | ||
+ | of "switches" that allow you to control Vizy's power-on or power-off | ||
+ | behavior. | ||
+ | Once they are set, they will retain the setting even if | ||
+ | power is removed. | ||
+ | The switches are a set of values that can be ORed together:</p> | ||
+ | <ul> | ||
+ | <li>DIPSWITCH_EXT_BUTTON, used to set external/remote power button, | ||
+ | e.g. with outdoor enclosure. | ||
+ | Default disabled.</li> | ||
+ | <li>DIPSWITCH_MUTE_BUZZER, used to mute the buzzer. | ||
+ | Default disabled.</li> | ||
+ | <li>DIPSWITCH_NO_BG_LED, used to disable the background LED, which is | ||
+ | normally set to yellow upon power up. | ||
+ | Default disabled.</li> | ||
+ | <li>DIPSWITCH_POWER_DEFAULT_OFF, if this power mode is set and you | ||
plug in power via the 12V power input, Vizy will remain off by default | plug in power via the 12V power input, Vizy will remain off by default | ||
- | until you press the button to power Vizy on. And if power is | + | until you press the button to power Vizy on. |
- | interrupted while Vizy is on, *Vizy will turn off*. If power is | + | And if power is |
- | interrupted while Vizy is off, Vizy will remain off. This is the | + | interrupted while Vizy is on, <em>Vizy will turn off</em>. |
- | default power mode. | + | If power is |
- | * DIPSWITCH_POWER_DEFAULT_ON, if this power mode is set and you | + | interrupted while Vizy is off, Vizy will remain off. |
+ | This is the | ||
+ | default power mode.</li> | ||
+ | <li>DIPSWITCH_POWER_DEFAULT_ON, if this power mode is set and you | ||
plug in power via the 12V power input, Vizy will turn on by default | plug in power via the 12V power input, Vizy will turn on by default | ||
- | without pressing the button. And if power is interrupted while Vizy | + | without pressing the button. |
- | is on, Vizy will reset, but remain on. If power is interrupted while | + | And if power is interrupted while Vizy |
- | Vizy is off, *Vizy will turn on*. Default disabled. | + | is on, Vizy will reset, but remain on. |
- | * DIPSWITCH_POWER_SWITCH, if this power mode is set and you plug in | + | If power is interrupted while |
+ | Vizy is off, <em>Vizy will turn on</em>. | ||
+ | Default disabled.</li> | ||
+ | <li>DIPSWITCH_POWER_SWITCH, if this power mode is set and you plug in | ||
power via the 12V power input, Vizy will remain off (as in | power via the 12V power input, Vizy will remain off (as in | ||
- | DIPSWITCH_POWER_DEFAULT_OFF mode), unless power was | + | DIPSWITCH_POWER_DEFAULT_OFF mode), unless power was |
- | removed while Vizy was on. In this case Vizy will turn on when you | + | removed while Vizy was on. |
- | (re)apply power. If power is interrupted while Vizy is off, Vizy | + | In this case Vizy will turn on when you |
- | will remain off. This behavior is similar to the behavior of a real | + | (re)apply power. |
+ | If power is interrupted while Vizy is off, Vizy | ||
+ | will remain off. | ||
+ | This behavior is similar to the behavior of a real | ||
power switch in that it retains the power "state" (on or off) and acts | power switch in that it retains the power "state" (on or off) and acts | ||
- | accordingly. Default disabled. | + | accordingly. |
- | * DIPSWITCH_POWER_PLUG, if this power mode is set Vizy will remain | + | Default disabled.</li> |
- | powered on as long as it receives power through the 12V power plug, | + | <li>DIPSWITCH_POWER_PLUG, if this power mode is set Vizy will remain |
+ | powered on as long as it receives power through the 12V power plug, | ||
and you will not be able to turn off Vizy via button or software as | and you will not be able to turn off Vizy via button or software as | ||
- | long as it's plugged in and receiving power. Default disabled. | + | long as it's plugged in and receiving power. |
+ | Default disabled.</li> | ||
+ | </ul> | ||
+ | <p>For example: </p> | ||
+ | <pre><code>dip_switches(DIPSWITCH_EXT_BUTTON | DIPSWITCH_POWER_SWITCH) # set external power button and power switch mode | ||
+ | </code></pre></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def dip_switches(self, val=None): | ||
+ | """ | ||
+ | Set or get the (virtual) DIP switch state. The DIP switches are a set | ||
+ | of "switches" that allow you to control Vizy's power-on or power-off | ||
+ | behavior. Once they are set, they will retain the setting even if | ||
+ | power is removed. | ||
+ | The switches are a set of values that can be ORed together: | ||
+ | |||
+ | * DIPSWITCH_EXT_BUTTON, used to set external/remote power button, | ||
+ | e.g. with outdoor enclosure. Default disabled. | ||
+ | * DIPSWITCH_MUTE_BUZZER, used to mute the buzzer. Default disabled. | ||
+ | * DIPSWITCH_NO_BG_LED, used to disable the background LED, which is | ||
+ | normally set to yellow upon power up. Default disabled. | ||
+ | * DIPSWITCH_POWER_DEFAULT_OFF, if this power mode is set and you | ||
+ | plug in power via the 12V power input, Vizy will remain off by default | ||
+ | until you press the button to power Vizy on. And if power is | ||
+ | interrupted while Vizy is on, *Vizy will turn off*. If power is | ||
+ | interrupted while Vizy is off, Vizy will remain off. This is the | ||
+ | default power mode. | ||
+ | * DIPSWITCH_POWER_DEFAULT_ON, if this power mode is set and you | ||
+ | plug in power via the 12V power input, Vizy will turn on by default | ||
+ | without pressing the button. And if power is interrupted while Vizy | ||
+ | is on, Vizy will reset, but remain on. If power is interrupted while | ||
+ | Vizy is off, *Vizy will turn on*. Default disabled. | ||
+ | * DIPSWITCH_POWER_SWITCH, if this power mode is set and you plug in | ||
+ | power via the 12V power input, Vizy will remain off (as in | ||
+ | DIPSWITCH_POWER_DEFAULT_OFF mode), unless power was | ||
+ | removed while Vizy was on. In this case Vizy will turn on when you | ||
+ | (re)apply power. If power is interrupted while Vizy is off, Vizy | ||
+ | will remain off. This behavior is similar to the behavior of a real | ||
+ | power switch in that it retains the power "state" (on or off) and acts | ||
+ | accordingly. Default disabled. | ||
+ | * DIPSWITCH_POWER_PLUG, if this power mode is set Vizy will remain | ||
+ | powered on as long as it receives power through the 12V power plug, | ||
+ | and you will not be able to turn off Vizy via button or software as | ||
+ | long as it's plugged in and receiving power. Default disabled. | ||
+ | |||
+ | For example: | ||
+ | |||
+ | dip_switches(DIPSWITCH_EXT_BUTTON | DIPSWITCH_POWER_SWITCH) # set external power button and power switch mode | ||
+ | """ | ||
+ | if val is None: | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_NVCONFIG]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | return self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 1)[0] | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_NVCONFIG|EXEC_WRITE, self._u_int8(val)]) | ||
+ | self._wait_until_not_busy()</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.fan"><code class="name flex"> | ||
+ | <span>def <span class="ident">fan</span></span>(<span>self, speed=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Set or get the fan speed. | ||
+ | The <code>speed</code> argument can range between 0 | ||
+ | and 12 where 0 is off and 12 is maximum speed. | ||
+ | The fan speed | ||
+ | is typically regulated automatically by vizy-powerd.</p> | ||
+ | <p>Calling this method without arguments returns the current fan speed.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def fan(self, speed=None): | ||
+ | """ | ||
+ | Set or get the fan speed. The `speed` argument can range between 0 | ||
+ | and 12 where 0 is off and 12 is maximum speed. The fan speed | ||
+ | is typically regulated automatically by vizy-powerd. | ||
+ | |||
+ | Calling this method without arguments returns the current fan speed. | ||
+ | """ | ||
+ | if speed is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 75, 1)[0] | ||
+ | self.bus.write_i2c_block_data(self.addr, 75, [self._u_int8(speed)])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.fw_version"><code class="name flex"> | ||
+ | <span>def <span class="ident">fw_version</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns the major, minor and build versions of the firmware as | ||
+ | a 3-item list.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def fw_version(self): | ||
+ | """ | ||
+ | Returns the major, minor and build versions of the firmware as | ||
+ | a 3-item list. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 3, 3)</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.hw_version"><code class="name flex"> | ||
+ | <span>def <span class="ident">hw_version</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns the major and minor versions of the PCB as a 2-item list.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def hw_version(self): | ||
+ | """ | ||
+ | Returns the major and minor versions of the PCB as a 2-item list. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 1, 2)</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.io_bits"><code class="name flex"> | ||
+ | <span>def <span class="ident">io_bits</span></span>(<span>self, bits=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Sets or gets the logic state of the IO bits 0 through 3, corresponding | ||
+ | to pins 4 through 7 on Vizy's IO connector. | ||
+ | The <code>bits</code> argument ranges | ||
+ | between 0 and 15 as it is a binary representation of the logic state | ||
+ | of the 4 IO bits. | ||
+ | If the <code>bits</code> argument isn't specified, the logic | ||
+ | state of the 4 bits are returned.</p> | ||
+ | <pre><code>io_bits(1) # set IO bit 0 to logic 1 and bits 1, 2, 3 to logic 0 | ||
+ | io_bits(10) # set IO bits 1 and 3 to logic 1 and bits 0 and 2 to logic 0 | ||
+ | bits = io_bits() # get logic state of IO bits | ||
+ | io_bits(io_bits()|1) # set IO bit 0 to logic 1, leave bits 1, 2, 3 unchanged. | ||
+ | </code></pre></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def io_bits(self, bits=None): | ||
+ | """ | ||
+ | Sets or gets the logic state of the IO bits 0 through 3, corresponding | ||
+ | to pins 4 through 7 on Vizy's IO connector. The `bits` argument ranges | ||
+ | between 0 and 15 as it is a binary representation of the logic state | ||
+ | of the 4 IO bits. If the `bits` argument isn't specified, the logic | ||
+ | state of the 4 bits are returned. | ||
+ | |||
+ | io_bits(1) # set IO bit 0 to logic 1 and bits 1, 2, 3 to logic 0 | ||
+ | io_bits(10) # set IO bits 1 and 3 to logic 1 and bits 0 and 2 to logic 0 | ||
+ | bits = io_bits() # get logic state of IO bits | ||
+ | io_bits(io_bits()|1) # set IO bit 0 to logic 1, leave bits 1, 2, 3 unchanged. | ||
+ | """ | ||
+ | if bits is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 72, 1) | ||
+ | self.bus.write_i2c_block_data(self.addr, 72, [bits])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.io_set_mode"><code class="name flex"> | ||
+ | <span>def <span class="ident">io_set_mode</span></span>(<span>self, bit, mode=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Sets or gets the io mode of the given bit. | ||
+ | The <code>bit</code> argument ranges | ||
+ | between | ||
+ | 0 and 3 and corresponds to pins 4 through 7 on Vizy's IO | ||
+ | connector. Calling this method with no mode argument returns the mode | ||
+ | of the given bit, otherwise, the <code>mode</code> argument can be one of | ||
+ | the following:</p> | ||
+ | <ul> | ||
+ | <li>IO_MODE_INPUT, sets the bit to high impedance input mode with | ||
+ | a weak pull-up resistor to 3.3V. | ||
+ | The input voltage can range between | ||
+ | 0 and Vin where Vin is the supply voltage. | ||
+ | Voltages lower than 1V | ||
+ | read as logic 0 via <code><a title="vizypowerboard.VizyPowerBoard.io_bits" href="#vizypowerboard.VizyPowerBoard.io_bits">VizyPowerBoard.io_bits()</a></code>. | ||
+ | Voltages higher | ||
+ | than 1V are read as logic 1.</li> | ||
+ | <li>IO_MODE_OUTPUT, sets the bit to output mode. | ||
+ | If the bit is set to | ||
+ | logic 0 via <code><a title="vizypowerboard.VizyPowerBoard.io_bits" href="#vizypowerboard.VizyPowerBoard.io_bits">VizyPowerBoard.io_bits()</a></code>, the output voltage is 0V.<br> | ||
+ | If the bit is set to logic 1, the output voltage is 3.3V. | ||
+ | In this mode, each bit can source and sink 5mA. | ||
+ | </li> | ||
+ | <li>IO_MODE_HIGH_CURRENT, sets the bit to a special high current mode | ||
+ | that allows the bit to sink as much as 1000mA, when the bit | ||
+ | set to logic 0 via <code><a title="vizypowerboard.VizyPowerBoard.io_bits" href="#vizypowerboard.VizyPowerBoard.io_bits">VizyPowerBoard.io_bits()</a></code>. | ||
+ | Otherwise, this mode | ||
+ | behaves exactly as IO_MODE_OUTPUT.</li> | ||
+ | </ul></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def io_set_mode(self, bit, mode=None): | ||
+ | """ | ||
+ | Sets or gets the io mode of the given bit. The `bit` argument ranges | ||
+ | between 0 and 3 and corresponds to pins 4 through 7 on Vizy's IO | ||
+ | connector. Calling this method with no mode argument returns the mode | ||
+ | of the given bit, otherwise, the `mode` argument can be one of | ||
+ | the following: | ||
+ | |||
+ | * IO_MODE_INPUT, sets the bit to high impedance input mode with | ||
+ | a weak pull-up resistor to 3.3V. The input voltage can range between | ||
+ | 0 and Vin where Vin is the supply voltage. Voltages lower than 1V | ||
+ | read as logic 0 via `VizyPowerBoard.io_bits()`. Voltages higher | ||
+ | than 1V are read as logic 1. | ||
+ | * IO_MODE_OUTPUT, sets the bit to output mode. If the bit is set to | ||
+ | logic 0 via `VizyPowerBoard.io_bits()`, the output voltage is 0V. | ||
+ | If the bit is set to logic 1, the output voltage is 3.3V. In this mode, each bit can source and sink 5mA. | ||
+ | * IO_MODE_HIGH_CURRENT, sets the bit to a special high current mode | ||
+ | that allows the bit to sink as much as 1000mA, when the bit | ||
+ | set to logic 0 via `VizyPowerBoard.io_bits()`. Otherwise, this mode | ||
+ | behaves exactly as IO_MODE_OUTPUT. | ||
+ | """ | ||
+ | if mode is None: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 68+bit, 1)[0] | ||
+ | if bit==2: | ||
+ | # set GPIO14 (UART TXD) as input so it doesn't conflict | ||
+ | GPIO.setwarnings(False) | ||
+ | GPIO.setmode(GPIO.BOARD) | ||
+ | GPIO.setup(8, GPIO.IN) | ||
+ | self.bus.write_i2c_block_data(self.addr, 68+bit, [self._u_int8(mode)])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.ir_filter"><code class="name flex"> | ||
+ | <span>def <span class="ident">ir_filter</span></span>(<span>self, state=None, duration=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Actuates the electro-mechanical IR-cut filter on Vizy's camera. | ||
+ | Vizy | ||
+ | uses a CMOS sensor which is very sensitive to IR light. | ||
+ | IR light can | ||
+ | adversely affect color fidelity during the daytime so an IR-cut filter | ||
+ | is used to block the IR light (<code>state</code>=True). | ||
+ | During nighttime IR light | ||
+ | is typically used as a discreet method of illumination and the IR-cut | ||
+ | filter is removed (<code>state</code>=False). | ||
+ | If the <code>state</code> argument is <code>True</code>, | ||
+ | the filter is actuated in place (and will stay there) until another | ||
+ | call is made with the state argument set to <code>False</code> (in which case the | ||
+ | IR-cut filter will be removed). | ||
+ | </p> | ||
+ | <p>The <code>duration</code> argument is optional and | ||
+ | controls how long (in milliseconds) the actuation coil receives power.</p> | ||
+ | <p>Calling this method without arguments returns the state of IR-cut | ||
+ | filter.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def ir_filter(self, state=None, duration=None): | ||
+ | """ | ||
+ | Actuates the electro-mechanical IR-cut filter on Vizy's camera. Vizy | ||
+ | uses a CMOS sensor which is very sensitive to IR light. IR light can | ||
+ | adversely affect color fidelity during the daytime so an IR-cut filter | ||
+ | is used to block the IR light (`state`=True). During nighttime IR light | ||
+ | is typically used as a discreet method of illumination and the IR-cut | ||
+ | filter is removed (`state`=False). If the `state` argument is `True`, | ||
+ | the filter is actuated in place (and will stay there) until another | ||
+ | call is made with the state argument set to `False` (in which case the | ||
+ | IR-cut filter will be removed). | ||
+ | |||
+ | The `duration` argument is optional and | ||
+ | controls how long (in milliseconds) the actuation coil receives power. | ||
+ | |||
+ | Calling this method without arguments returns the state of IR-cut | ||
+ | filter. | ||
+ | """ | ||
+ | if state is None: | ||
+ | return True if self.bus.read_i2c_block_data(self.addr, 73, 1)[0] else False | ||
+ | data = [1] if state else [0] | ||
+ | if duration is not None: | ||
+ | data.append(int(duration/10)) | ||
+ | self.bus.write_i2c_block_data(self.addr, 73, data)</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.led"><code class="name flex"> | ||
+ | <span>def <span class="ident">led</span></span>(<span>self, r=0, g=0, b=0, flashes=0, repeat=False, atten=255, on=100, off=100, pause=200)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Controls the RGB LED in one of several modes:</p> | ||
+ | <ul> | ||
+ | <li> | ||
+ | <p><strong>Continuous</strong>: just setting <code>r</code>, <code>g</code>, and <code>b</code> will set set the LED color | ||
+ | and turn it on continuously. | ||
+ | <code>r</code>, <code>g</code>, and <code>b</code> values range between 0 | ||
+ | and | ||
+ | 255.</p> | ||
+ | <pre><code>led(255, 0, 0) # turn on LED, red color | ||
+ | led(255, 255, 0) # turn on LED, yellow color | ||
+ | led(0, 0, 255) # turn on LED, blue color | ||
+ | led(0, 0, 0) # turn off LED | ||
+ | </code></pre> | ||
+ | </li> | ||
+ | <li> | ||
+ | <p><strong>Flashes</strong>: setting the <code>flashes</code> value to a non-zero value will | ||
+ | cause the LED to flash the indicated number of times. | ||
+ | You can also | ||
+ | specify the <code>on</code> and <code>off</code> arguments to indicate the amount of time | ||
+ | the LED is on and off for each flash (specified in milliseconds).</p> | ||
+ | <pre><code>led(0, 0, 255, 3) # flash blue 3 times (then stop) | ||
+ | led(0, 0, 255, 3, on=500, off=500) # flash blue 3 times, much more slowly | ||
+ | </code></pre> | ||
+ | </li> | ||
+ | <li> | ||
+ | <p><strong>Repeated flashes</strong>: setting the <code>repeat</code> argument to <code>True</code> | ||
+ | will cause the indicated flash pattern to repeat forever. | ||
+ | You can | ||
+ | modify the pause time between flash sequences by setting <code>pause</code> | ||
+ | (milliseconds).</p> | ||
+ | <pre><code>led(0, 0, 255, 3, True, pause=500) # flash blue 3 times, pause, then repeat | ||
+ | led(0, 0, 255, repeat=True, on=500, off=500)` # flash blue forever | ||
+ | </code></pre> | ||
+ | </li> | ||
+ | <li> | ||
+ | <p><strong>Flashing with attenuation</strong>: you can also set the <code>atten</code> | ||
+ | argument to make the LED to turn on and off slowly, like an | ||
+ | incandescent light. | ||
+ | The value is the rate of change, so lower values | ||
+ | cause the LED color to change more slowly. </p> | ||
+ | <pre><code>led(0, 0, 255, repeat=True, atten=10, on=500, off=500) # flash blue forever, but turn on and turn off very slowly | ||
+ | </code></pre> | ||
+ | </li> | ||
+ | </ul></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def led(self, r=0, g=0, b=0, flashes=0, repeat=False, atten=255, on=100, off=100, pause=200): | ||
+ | """ | ||
+ | Controls the RGB LED in one of several modes: | ||
+ | |||
+ | * **Continuous**: just setting `r`, `g`, and `b` will set set the LED color | ||
+ | and turn it on continuously. `r`, `g`, and `b` values range between 0 | ||
+ | and 255. | ||
+ | |||
+ | led(255, 0, 0) # turn on LED, red color | ||
+ | led(255, 255, 0) # turn on LED, yellow color | ||
+ | led(0, 0, 255) # turn on LED, blue color | ||
+ | led(0, 0, 0) # turn off LED | ||
+ | |||
+ | * **Flashes**: setting the `flashes` value to a non-zero value will | ||
+ | cause the LED to flash the indicated number of times. You can also | ||
+ | specify the `on` and `off` arguments to indicate the amount of time | ||
+ | the LED is on and off for each flash (specified in milliseconds). | ||
+ | |||
+ | led(0, 0, 255, 3) # flash blue 3 times (then stop) | ||
+ | led(0, 0, 255, 3, on=500, off=500) # flash blue 3 times, much more slowly | ||
+ | |||
+ | * **Repeated flashes**: setting the `repeat` argument to `True` | ||
+ | will cause the indicated flash pattern to repeat forever. You can | ||
+ | modify the pause time between flash sequences by setting `pause` | ||
+ | (milliseconds). | ||
+ | |||
+ | led(0, 0, 255, 3, True, pause=500) # flash blue 3 times, pause, then repeat | ||
+ | led(0, 0, 255, repeat=True, on=500, off=500)` # flash blue forever | ||
+ | |||
+ | * **Flashing with attenuation**: you can also set the `atten` | ||
+ | argument to make the LED to turn on and off slowly, like an | ||
+ | incandescent light. The value is the rate of change, so lower values | ||
+ | cause the LED color to change more slowly. | ||
+ | |||
+ | led(0, 0, 255, repeat=True, atten=10, on=500, off=500) # flash blue forever, but turn on and turn off very slowly | ||
+ | """ | ||
+ | on = self._u_int8(on/10) | ||
+ | off = self._u_int8(off/10) | ||
+ | pause = self._u_int8(pause/10) | ||
+ | if flashes==0: | ||
+ | mode = 0 | ||
+ | if repeat: | ||
+ | mode = 0x02 | ||
+ | else: | ||
+ | mode = 0x01 | ||
+ | self.bus.write_i2c_block_data(self.addr, 49, [mode, self._u_int8(r), self._u_int8(g), self._u_int8(b), | ||
+ | on, off, self._u_int8(flashes), pause, self._u_int8(atten)])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.led_background"><code class="name flex"> | ||
+ | <span>def <span class="ident">led_background</span></span>(<span>self, r=-1, g=-1, b=-1)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>The "background" LED color is the color of the LED when the LED is | ||
+ | turned "off". | ||
+ | It is used by system programs such as vizy-powerd to | ||
+ | indicate Vizy's system state such as, booting (yellow), finished | ||
+ | booting (green), running server (blue), etc. | ||
+ | Note, the background | ||
+ | color does not influence the LED colors set by calls to led().</p> | ||
+ | <p>Calling led_background() without arguments returns the current | ||
+ | background color r, g, and b values in a list. </p> | ||
+ | <pre><code>led_background(48, 48, 0) # set background color to yellow | ||
+ | led(0, 255, 0) # turn on LED, green (as expected) | ||
+ | led(0, 0, 0) # turn LED off, and restore background color (yellow as set previously) | ||
+ | </code></pre></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def led_background(self, r=-1, g=-1, b=-1): | ||
+ | """ | ||
+ | The "background" LED color is the color of the LED when the LED is | ||
+ | turned "off". It is used by system programs such as vizy-powerd to | ||
+ | indicate Vizy's system state such as, booting (yellow), finished | ||
+ | booting (green), running server (blue), etc. Note, the background | ||
+ | color does not influence the LED colors set by calls to led(). | ||
+ | |||
+ | Calling led_background() without arguments returns the current | ||
+ | background color r, g, and b values in a list. | ||
+ | |||
+ | led_background(48, 48, 0) # set background color to yellow | ||
+ | led(0, 255, 0) # turn on LED, green (as expected) | ||
+ | led(0, 0, 0) # turn LED off, and restore background color (yellow as set previously) | ||
+ | """ | ||
+ | if r==-1: | ||
+ | return self.bus.read_i2c_block_data(self.addr, 58, 3) | ||
+ | self.bus.write_i2c_block_data(self.addr, 58, [self._u_int8(r), self._u_int8(g), self._u_int8(b)])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.led_unicorn"><code class="name flex"> | ||
+ | <span>def <span class="ident">led_unicorn</span></span>(<span>self, speed=10)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>This causes the LED to change color in succession: red, orange, yellow, | ||
+ | green, cyan, blue, violet and then repeat again. | ||
+ | The <code>speed</code> argument | ||
+ | ranges between 0 and 10. | ||
+ | For example, a <code>speed</code> of 0 causes the color | ||
+ | to change once every couple of seconds. | ||
+ | A <code>speed</code> of 10 causes the color to change about 6 times per second.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def led_unicorn(self, speed=10): | ||
+ | """ | ||
+ | This causes the LED to change color in succession: red, orange, yellow, | ||
+ | green, cyan, blue, violet and then repeat again. The `speed` argument | ||
+ | ranges between 0 and 10. For example, a `speed` of 0 causes the color | ||
+ | to change once every couple of seconds. A `speed` of 10 causes the color to change about 6 times per second. | ||
+ | """ | ||
+ | if speed>10: | ||
+ | speed = 10 | ||
+ | elif speed<0: | ||
+ | speed = 0 | ||
+ | |||
+ | on = self._u_int8(10 + (10-speed)*140/10) | ||
+ | atten = self._u_int8(3 + speed*47/10) | ||
+ | self.bus.write_i2c_block_data(self.addr, 49, [0x08, 0, 0, 0, on, 0, 0, 0, atten])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.measure"><code class="name flex"> | ||
+ | <span>def <span class="ident">measure</span></span>(<span>self, channel)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Get the voltage values of various channels. | ||
+ | The returned value is | ||
+ | the voltage measured (in Volts) of the given channel. | ||
+ | The <code>channel</code> | ||
+ | argument can be one of the following:</p> | ||
+ | <ul> | ||
+ | <li>CHANNEL_VIN, this channel measures the voltage present at the 12V | ||
+ | power input.</li> | ||
+ | <li>CHANNEL_5V, this channel measures the voltage present at the 5V | ||
+ | voltage rail provided to the Raspberry Pi.</li> | ||
+ | </ul></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def measure(self, channel): | ||
+ | """ | ||
+ | Get the voltage values of various channels. The returned value is | ||
+ | the voltage measured (in Volts) of the given channel. The `channel` | ||
+ | argument can be one of the following: | ||
+ | |||
+ | * CHANNEL_VIN, this channel measures the voltage present at the 12V | ||
+ | power input. | ||
+ | * CHANNEL_5V, this channel measures the voltage present at the 5V | ||
+ | voltage rail provided to the Raspberry Pi. | ||
+ | """ | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_AD, self._u_int8(channel)]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | val = self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+2, 2) | ||
+ | return (val[1]*0x100 + val[0])/1000</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.power_off"><code class="name flex"> | ||
+ | <span>def <span class="ident">power_off</span></span>(<span>self, t=5000)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Powers Vizy off. The <code>t</code> argument specifies how long | ||
+ | to wait before turning off (specified in milliseconds). | ||
+ | The | ||
+ | vizy-powerd service calls this upon shutdown.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def power_off(self, t=5000): | ||
+ | """ | ||
+ | Powers Vizy off. The `t` argument specifies how long | ||
+ | to wait before turning off (specified in milliseconds). The | ||
+ | vizy-powerd service calls this upon shutdown. | ||
+ | """ | ||
+ | self.bus.write_i2c_block_data(self.addr, 38, [0x1f, int(t/100)])</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.power_off_requested"><code class="name flex"> | ||
+ | <span>def <span class="ident">power_off_requested</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns <code>True</code> if Vizy's button is held down for more than 5 seconds | ||
+ | indicating that the user wishes to initiate safe shutdown and power | ||
+ | off. | ||
+ | Returns <code>False</code> otherwise.</p> | ||
+ | <p>This is used by the vizy-powerd service.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def power_off_requested(self): | ||
+ | """ | ||
+ | Returns `True` if Vizy's button is held down for more than 5 seconds | ||
+ | indicating that the user wishes to initiate safe shutdown and power | ||
+ | off. Returns `False` otherwise. | ||
+ | |||
+ | This is used by the vizy-powerd service. | ||
+ | """ | ||
+ | button = self.bus.read_i2c_block_data(self.addr, 38, 1) | ||
+ | if button[0]==0x0f: | ||
+ | return True | ||
+ | else: | ||
+ | return False</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.power_on_alarm_date"><code class="name flex"> | ||
+ | <span>def <span class="ident">power_on_alarm_date</span></span>(<span>self, datetime_=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>If you wish to power off your Vizy and have it "wake up" at a | ||
+ | specified time and date, call this method with the desired | ||
+ | datetime object and initiate a shutdown. (e.g. <code>sudo shutdown now</code>).</p> | ||
+ | <p>The code below tells Vizy to turn on on December 2, 2022, 11:18am.</p> | ||
+ | <pre><code>import vizypowerboard as vpb | ||
+ | from datetime import datetime | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | d=datetime(year=2022, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.power_on_alarm_date(d) | ||
+ | </code></pre> | ||
+ | <h2 id="args">Args</h2> | ||
+ | <dl> | ||
+ | <dt><strong><code>datetime_</code></strong> : <code>datetime</code>, optional, default=<code>None</code></dt> | ||
+ | <dd><code>datetime</code> object that | ||
+ | specifies the date/time to "wake up" (turn on).</dd> | ||
+ | </dl> | ||
+ | <h2 id="returns">Returns</h2> | ||
+ | <p>Calling without a datetime object returns a <code>datetime</code> object | ||
+ | reflecting the active alarm time. | ||
+ | If there is no active alarm, | ||
+ | <code>None</code> is returned.</p> | ||
+ | <h2 id="notes">Notes</h2> | ||
+ | <ul> | ||
+ | <li>Once setting the alarm date, Vizy will retain it even if Vizy loses | ||
+ | power for extended periods of time.</li> | ||
+ | <li>If the alarm expires while Vizy is on, Vizy will emit a buzzer tone | ||
+ | and remain on.</li> | ||
+ | <li>If the alarm expires while Vizy is off (but plugged into and | ||
+ | receiving power), Vizy will turn on.</li> | ||
+ | <li>If the alarm expires while Vizy is unplugged from (or not receiving) | ||
+ | power, Vizy will turn on as soon as it receives power.</li> | ||
+ | </ul></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def power_on_alarm_date(self, datetime_=None): | ||
+ | """ | ||
+ | If you wish to power off your Vizy and have it "wake up" at a | ||
+ | specified time and date, call this method with the desired | ||
+ | datetime object and initiate a shutdown. (e.g. `sudo shutdown now`). | ||
+ | |||
+ | |||
+ | The code below tells Vizy to turn on on December 2, 2022, 11:18am. | ||
+ | |||
+ | import vizypowerboard as vpb | ||
+ | from datetime import datetime | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | d=datetime(year=2022, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.power_on_alarm_date(d) | ||
+ | |||
+ | Args: | ||
+ | datetime_ (datetime, optional, default=None): `datetime` object that | ||
+ | specifies the date/time to "wake up" (turn on). | ||
+ | |||
+ | Returns: | ||
+ | Calling without a datetime object returns a `datetime` object | ||
+ | reflecting the active alarm time. If there is no active alarm, | ||
+ | `None` is returned. | ||
+ | |||
+ | Notes: | ||
+ | * Once setting the alarm date, Vizy will retain it even if Vizy loses | ||
+ | power for extended periods of time. | ||
+ | * If the alarm expires while Vizy is on, Vizy will emit a buzzer tone | ||
+ | and remain on. | ||
+ | * If the alarm expires while Vizy is off (but plugged into and | ||
+ | receiving power), Vizy will turn on. | ||
+ | * If the alarm expires while Vizy is unplugged from (or not receiving) | ||
+ | power, Vizy will turn on as soon as it receives power. | ||
+ | """ | ||
+ | if datetime_ is None: | ||
+ | t = self.bus.read_i2c_block_data(self.addr, 41, 6) | ||
+ | if t[5]==0: | ||
+ | return None | ||
+ | return datetime.datetime(year=self._bcd2decimal(t[5])+2016, month=self._bcd2decimal(t[4]), day=self._bcd2decimal(t[3]), hour=self._bcd2decimal(t[2]), minute=self._bcd2decimal(t[1]), second=self._bcd2decimal(t[0])) | ||
+ | t = [self._decimal2bcd(datetime_.second), self._decimal2bcd(datetime_.minute), self._decimal2bcd(datetime_.hour), self._decimal2bcd(datetime_.day), self._decimal2bcd(datetime_.month), self._decimal2bcd(datetime_.year-2016)] | ||
+ | self.bus.write_i2c_block_data(self.addr, 41, t)</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.power_on_alarm_seconds"><code class="name flex"> | ||
+ | <span>def <span class="ident">power_on_alarm_seconds</span></span>(<span>self, seconds=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Allows you to specify a power on alarm in seconds in the future. | ||
+ | For example, if you wish for Vizy to turn back on in 5 minutes, you | ||
+ | would call <code>power_on_alarm_seconds(300)</code> and then initiate a shutdown. | ||
+ | See <code><a title="vizypowerboard.VizyPowerBoard.power_on_alarm_date" href="#vizypowerboard.VizyPowerBoard.power_on_alarm_date">VizyPowerBoard.power_on_alarm_date()</a></code> for more information about the power on | ||
+ | alarm.</p> | ||
+ | <h2 id="args">Args</h2> | ||
+ | <dl> | ||
+ | <dt><strong><code>seconds</code></strong> : <code>integer</code>, optional, default=<code>None</code></dt> | ||
+ | <dd>Number of seconds in the | ||
+ | future you wish Vizy to turn on in.</dd> | ||
+ | </dl> | ||
+ | <h2 id="returns">Returns</h2> | ||
+ | <p>Calling this method without arguments returns the number of seconds | ||
+ | until the alarm expires. | ||
+ | If no alarm is pending, <code>None</code> is returned.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def power_on_alarm_seconds(self, seconds=None): | ||
+ | """ | ||
+ | Allows you to specify a power on alarm in seconds in the future. | ||
+ | For example, if you wish for Vizy to turn back on in 5 minutes, you | ||
+ | would call `power_on_alarm_seconds(300)` and then initiate a shutdown. | ||
+ | See `VizyPowerBoard.power_on_alarm_date()` for more information about the power on | ||
+ | alarm. | ||
+ | |||
+ | Args: | ||
+ | seconds (integer, optional, default=None): Number of seconds in the | ||
+ | future you wish Vizy to turn on in. | ||
+ | |||
+ | Returns: | ||
+ | Calling this method without arguments returns the number of seconds | ||
+ | until the alarm expires. If no alarm is pending, `None` is returned. | ||
+ | """ | ||
+ | if seconds is None: | ||
+ | pod = self.power_on_alarm_date() | ||
+ | if pod is None: | ||
+ | return None | ||
+ | diff = pod - self.rtc() | ||
+ | return diff.days*86400+diff.seconds | ||
+ | # Add seconds to current time and set power on alarm | ||
+ | self.power_on_alarm_date(self.rtc()+datetime.timedelta(seconds=seconds))</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.power_on_source"><code class="name flex"> | ||
+ | <span>def <span class="ident">power_on_source</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns the source of what turned on Vizy for the current power cycle. | ||
+ | It is one of either:</p> | ||
+ | <ul> | ||
+ | <li>POWER_ON_SOURCE_ALARM, indicates that Vizy was powered on | ||
+ | by the power on alarm expiring. | ||
+ | See power_on_alarm_date() and | ||
+ | power_on_alarm_seconds().</li> | ||
+ | <li>POWER_ON_SOURCE_POWER_BUTTON, indicates that Vizy was powered | ||
+ | on by someone pressing the button.</li> | ||
+ | <li>POWER_ON_SOURCE_12V = indicates that Vizy was powered on | ||
+ | by power being applied to 12V power input. | ||
+ | This only applies if the | ||
+ | dip switch power mode allows powering on by plugging in power via the | ||
+ | 12V power input.</li> | ||
+ | <li>POWER_ON_SOURCE_5V, indicates that Vizy was powered on by applying | ||
+ | power to the Raspberry Pi's USB-C power input.</li> | ||
+ | </ul></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def power_on_source(self): | ||
+ | """ | ||
+ | Returns the source of what turned on Vizy for the current power cycle. | ||
+ | It is one of either: | ||
+ | |||
+ | * POWER_ON_SOURCE_ALARM, indicates that Vizy was powered on | ||
+ | by the power on alarm expiring. See power_on_alarm_date() and | ||
+ | power_on_alarm_seconds(). | ||
+ | * POWER_ON_SOURCE_POWER_BUTTON, indicates that Vizy was powered | ||
+ | on by someone pressing the button. | ||
+ | * POWER_ON_SOURCE_12V = indicates that Vizy was powered on | ||
+ | by power being applied to 12V power input. This only applies if the | ||
+ | dip switch power mode allows powering on by plugging in power via the | ||
+ | 12V power input. | ||
+ | * POWER_ON_SOURCE_5V, indicates that Vizy was powered on by applying | ||
+ | power to the Raspberry Pi's USB-C power input. | ||
+ | """ | ||
+ | source = self.bus.read_i2c_block_data(self.addr, 40, 1)[0] | ||
+ | return source</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.resource_url"><code class="name flex"> | ||
+ | <span>def <span class="ident">resource_url</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns the url of a JSON file that contains information about | ||
+ | resources, such as the location of the latest version of this code, | ||
+ | latest firmware, etc.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def resource_url(self): | ||
+ | """ | ||
+ | Returns the url of a JSON file that contains information about | ||
+ | resources, such as the location of the latest version of this code, | ||
+ | latest firmware, etc. | ||
+ | """ | ||
+ | chars = self.bus.read_i2c_block_data(self.addr, 6, 32) | ||
+ | s = '' | ||
+ | for c in chars: | ||
+ | if c==0: # read up to the null character | ||
+ | break | ||
+ | s += chr(c) | ||
+ | return s</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.rtc"><code class="name flex"> | ||
+ | <span>def <span class="ident">rtc</span></span>(<span>self, datetime_=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Set or get the real-time clock time/date. | ||
+ | The Vizy power board has a | ||
+ | battery-backed real-time clock that keeps track of time/date, power | ||
+ | alarms, etc. even while Vizy is receiving no power. | ||
+ | Passing in a | ||
+ | datetime object sets the time/date. | ||
+ | </p> | ||
+ | <p>Calling this method with no | ||
+ | arguments returns a datetime object representing the current | ||
+ | date/time. </p> | ||
+ | <p>For example, the code below sets the date to December 2, 2020, 11:18am:</p> | ||
+ | <pre><code>from datetime import datetime | ||
+ | import vizypowerboard as vpb | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | t = datetime(year=2020, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.rtc(t) | ||
+ | </code></pre></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def rtc(self, datetime_=None): | ||
+ | """ | ||
+ | Set or get the real-time clock time/date. The Vizy power board has a | ||
+ | battery-backed real-time clock that keeps track of time/date, power | ||
+ | alarms, etc. even while Vizy is receiving no power. Passing in a | ||
+ | datetime object sets the time/date. | ||
+ | |||
+ | Calling this method with no | ||
+ | arguments returns a datetime object representing the current | ||
+ | date/time. | ||
+ | |||
+ | For example, the code below sets the date to December 2, 2020, 11:18am: | ||
+ | |||
+ | from datetime import datetime | ||
+ | import vizypowerboard as vpb | ||
+ | v = vpb.VizyPowerBoard() | ||
+ | t = datetime(year=2020, month=12, day=2, hour=11, minute=18, second=0) | ||
+ | v.rtc(t) | ||
+ | """ | ||
+ | if datetime_ is None: | ||
+ | # Initiate RTC retrieval. | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | |||
+ | t = self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 8) | ||
+ | return datetime.datetime(year=self._bcd2decimal(t[7])+2016, month=self._bcd2decimal(t[6]), day=self._bcd2decimal(t[4]), hour=self._bcd2decimal(t[3]), minute=self._bcd2decimal(t[2]), second=self._bcd2decimal(t[1])) | ||
+ | |||
+ | t = [EXEC_RTC|EXEC_WRITE, 0, self._decimal2bcd(datetime_.second), self._decimal2bcd(datetime_.minute), self._decimal2bcd(datetime_.hour), self._decimal2bcd(datetime_.day), 0, self._decimal2bcd(datetime_.month), self._decimal2bcd(datetime_.year-2016)] | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, t) | ||
+ | self._wait_until_not_busy()</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.rtc_adjust"><code class="name flex"> | ||
+ | <span>def <span class="ident">rtc_adjust</span></span>(<span>self, val=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Set or get the real-time clock adjustment. | ||
+ | Vizy's real-time clock | ||
+ | crystal has an accuracy of 20ppm, which means that it can lose or gain | ||
+ | up to 20 seconds for every 1 million elapsed seconds. | ||
+ | Normally, this | ||
+ | isn't an issue, but if Vizy spends a lengthy period of time (months) | ||
+ | without Internet access, it could lose or gain minutes, which | ||
+ | depending on the application could be significant. The adjustment | ||
+ | value can offset this inaccuracy. | ||
+ | The <code>val</code> argument can range | ||
+ | between -128 and 127 and has a multiplier of 2.170 ppm. | ||
+ | </p> | ||
+ | <p>For example, | ||
+ | if the RTC is gaining 10 seconds every 1 million seconds, you would | ||
+ | call <code>rtc_adjust(-5)</code>. | ||
+ | If the RTC is losing 10 seconds every million | ||
+ | seconds you would call <code>rtc_adjust(5)</code>.</p> | ||
+ | <p>The adjustment value is retained by the real-time clock even when | ||
+ | Vizy's power is removed.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def rtc_adjust(self, val=None): | ||
+ | """ | ||
+ | Set or get the real-time clock adjustment. Vizy's real-time clock | ||
+ | crystal has an accuracy of 20ppm, which means that it can lose or gain | ||
+ | up to 20 seconds for every 1 million elapsed seconds. Normally, this | ||
+ | isn't an issue, but if Vizy spends a lengthy period of time (months) | ||
+ | without Internet access, it could lose or gain minutes, which | ||
+ | depending on the application could be significant. The adjustment | ||
+ | value can offset this inaccuracy. The `val` argument can range | ||
+ | between -128 and 127 and has a multiplier of 2.170 ppm. | ||
+ | |||
+ | For example, | ||
+ | if the RTC is gaining 10 seconds every 1 million seconds, you would | ||
+ | call `rtc_adjust(-5)`. If the RTC is losing 10 seconds every million | ||
+ | seconds you would call `rtc_adjust(5)`. | ||
+ | |||
+ | The adjustment value is retained by the real-time clock even when | ||
+ | Vizy's power is removed. | ||
+ | """ | ||
+ | if val is None: | ||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC_CALIBRATE]) | ||
+ | # Wait until it's ready. | ||
+ | self._wait_until_not_busy() | ||
+ | return self.bus.read_i2c_block_data(self.addr, EXEC_OFFSET+1, 1)[0] | ||
+ | |||
+ | self.bus.write_i2c_block_data(self.addr, EXEC_OFFSET, [EXEC_RTC_CALIBRATE|EXEC_WRITE, self._int8(val)]) | ||
+ | self._wait_until_not_busy()</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.rtc_set_system_datetime"><code class="name flex"> | ||
+ | <span>def <span class="ident">rtc_set_system_datetime</span></span>(<span>self, datetime_=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>A convenience method that sets the system time/date based on the | ||
+ | real-time time/date. | ||
+ | This is called by vizy-powerd upon power-up.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def rtc_set_system_datetime(self, datetime_=None): | ||
+ | """ | ||
+ | A convenience method that sets the system time/date based on the | ||
+ | real-time time/date. This is called by vizy-powerd upon power-up. | ||
+ | """ | ||
+ | if os.geteuid()!=0: | ||
+ | raise PermissionError("You need root permission to set the time/date.") | ||
+ | if datetime_ is None: | ||
+ | datetime_ = self.rtc() | ||
+ | s = datetime_.isoformat() | ||
+ | os.system(f"sudo date -s {s}")</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.uuid"><code class="name flex"> | ||
+ | <span>def <span class="ident">uuid</span></span>(<span>self)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>Returns a 16-byte unique ID that can be used an a unique | ||
+ | ID for your Vizy camera. | ||
+ | This unique ID is stored on the Vizy Power | ||
+ | Board and remains constant regardless of firmware upgrades, etc.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def uuid(self): | ||
+ | """ | ||
+ | Returns a 16-byte unique ID that can be used an a unique | ||
+ | ID for your Vizy camera. This unique ID is stored on the Vizy Power | ||
+ | Board and remains constant regardless of firmware upgrades, etc. | ||
+ | """ | ||
+ | return self.bus.read_i2c_block_data(self.addr, 22, 16)</code></pre> | ||
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.vcc12"><code class="name flex"> | ||
+ | <span>def <span class="ident">vcc12</span></span>(<span>self, state=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>If <code>state</code> is <code>True</code>, the 12V output on Vizy's I/O connector (pin 2) will be enabled and output 12V. | ||
+ | If <code>state</code> is <code>False</code>, the 12V output | ||
+ | will be disabled. | ||
+ | Calling without arguments returns its current state.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def vcc12(self, state=None): | ||
+ | """ | ||
+ | If `state` is `True`, the 12V output on Vizy's I/O connector (pin 2) will be enabled and output 12V. If `state` is `False`, the 12V output | ||
+ | will be disabled. Calling without arguments returns its current state. | ||
+ | """ | ||
+ | config = self.bus.read_i2c_block_data(self.addr, 48, 1) | ||
+ | if state is None: | ||
+ | return True if config&0x01 else False | ||
+ | if state: | ||
+ | config[0] |= 0x01 | ||
+ | else: | ||
+ | config[0] &= ~0x01 | ||
- | For example: | + | self.bus.write_i2c_block_data(self.addr, 48, config)</code></pre> |
+ | </details> | ||
+ | </dd> | ||
+ | <dt id="vizypowerboard.VizyPowerBoard.vcc5"><code class="name flex"> | ||
+ | <span>def <span class="ident">vcc5</span></span>(<span>self, state=None)</span> | ||
+ | </code></dt> | ||
+ | <dd> | ||
+ | <div class="desc"><p>If <code>state</code> is <code>True</code>, the 5V output on Vizy's I/O connector (pin 3) will | ||
+ | be enabled and output 5V. | ||
+ | If <code>state</code> is <code>False</code>, the 5V output will be | ||
+ | disabled. | ||
+ | Calling without arguments returns its current state.</p></div> | ||
+ | <details class="source"> | ||
+ | <summary> | ||
+ | <span>Expand source code</span> | ||
+ | </summary> | ||
+ | <pre><code class="python">def vcc5(self, state=None): | ||
+ | """ | ||
+ | If `state` is `True`, the 5V output on Vizy's I/O connector (pin 3) will | ||
+ | be enabled and output 5V. If `state` is `False`, the 5V output will be | ||
+ | disabled. Calling without arguments returns its current state. | ||
+ | """ | ||
+ | if state is None: | ||
+ | return True if config&0x02 else False | ||
+ | if state: | ||
+ | config[0] |= 0x02 | ||
+ | else: | ||
+ | config[0] &= ~0x02 | ||
- | dip_switches(DIPSWITCH_EXT_BUTTON | DIPSWITCH_POWER_SWITCH) # set external power button and power switch mode | + | self.bus.write_i2c_block_data(self.addr, 48, config)</code></pre> |
+ | </details> | ||
+ | </dd> | ||
+ | </dl> | ||
+ | </dd> | ||
+ | </dl> | ||
+ | </section> | ||
+ | </article> | ||
+ | <nav id="sidebar"> | ||
+ | <h1>Index</h1> | ||
+ | <div class="toc"> | ||
+ | <ul></ul> | ||
+ | </div> | ||
+ | <ul id="index"> | ||
+ | <li><h3><a href="#header-variables">Global variables</a></h3> | ||
+ | <ul class=""> | ||
+ | <li><code><a title="vizypowerboard.CHANNEL_5V" href="#vizypowerboard.CHANNEL_5V">CHANNEL_5V</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.CHANNEL_VIN" href="#vizypowerboard.CHANNEL_VIN">CHANNEL_VIN</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_EXT_BUTTON" href="#vizypowerboard.DIPSWITCH_EXT_BUTTON">DIPSWITCH_EXT_BUTTON</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_MUTE_BUZZER" href="#vizypowerboard.DIPSWITCH_MUTE_BUZZER">DIPSWITCH_MUTE_BUZZER</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_NO_BG_LED" href="#vizypowerboard.DIPSWITCH_NO_BG_LED">DIPSWITCH_NO_BG_LED</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_POWER_DEFAULT_OFF" href="#vizypowerboard.DIPSWITCH_POWER_DEFAULT_OFF">DIPSWITCH_POWER_DEFAULT_OFF</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_POWER_DEFAULT_ON" href="#vizypowerboard.DIPSWITCH_POWER_DEFAULT_ON">DIPSWITCH_POWER_DEFAULT_ON</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_POWER_PLUG" href="#vizypowerboard.DIPSWITCH_POWER_PLUG">DIPSWITCH_POWER_PLUG</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.DIPSWITCH_POWER_SWITCH" href="#vizypowerboard.DIPSWITCH_POWER_SWITCH">DIPSWITCH_POWER_SWITCH</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.IO_MODE_HIGH_CURRENT" href="#vizypowerboard.IO_MODE_HIGH_CURRENT">IO_MODE_HIGH_CURRENT</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.IO_MODE_INPUT" href="#vizypowerboard.IO_MODE_INPUT">IO_MODE_INPUT</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.IO_MODE_OUTPUT" href="#vizypowerboard.IO_MODE_OUTPUT">IO_MODE_OUTPUT</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.POWER_ON_SOURCE_12V" href="#vizypowerboard.POWER_ON_SOURCE_12V">POWER_ON_SOURCE_12V</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.POWER_ON_SOURCE_5V" href="#vizypowerboard.POWER_ON_SOURCE_5V">POWER_ON_SOURCE_5V</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.POWER_ON_SOURCE_ALARM" href="#vizypowerboard.POWER_ON_SOURCE_ALARM">POWER_ON_SOURCE_ALARM</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.POWER_ON_SOURCE_POWER_BUTTON" href="#vizypowerboard.POWER_ON_SOURCE_POWER_BUTTON">POWER_ON_SOURCE_POWER_BUTTON</a></code></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | <li><h3><a href="#header-classes">Classes</a></h3> | ||
+ | <ul> | ||
+ | <li> | ||
+ | <h4><code><a title="vizypowerboard.VizyPowerBoard" href="#vizypowerboard.VizyPowerBoard">VizyPowerBoard</a></code></h4> | ||
+ | <ul class=""> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.button" href="#vizypowerboard.VizyPowerBoard.button">button</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.button_pressed" href="#vizypowerboard.VizyPowerBoard.button_pressed">button_pressed</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.buzzer" href="#vizypowerboard.VizyPowerBoard.buzzer">buzzer</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.dip_switches" href="#vizypowerboard.VizyPowerBoard.dip_switches">dip_switches</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.fan" href="#vizypowerboard.VizyPowerBoard.fan">fan</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.fw_version" href="#vizypowerboard.VizyPowerBoard.fw_version">fw_version</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.hw_version" href="#vizypowerboard.VizyPowerBoard.hw_version">hw_version</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.io_bits" href="#vizypowerboard.VizyPowerBoard.io_bits">io_bits</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.io_set_mode" href="#vizypowerboard.VizyPowerBoard.io_set_mode">io_set_mode</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.ir_filter" href="#vizypowerboard.VizyPowerBoard.ir_filter">ir_filter</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.led" href="#vizypowerboard.VizyPowerBoard.led">led</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.led_background" href="#vizypowerboard.VizyPowerBoard.led_background">led_background</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.led_unicorn" href="#vizypowerboard.VizyPowerBoard.led_unicorn">led_unicorn</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.measure" href="#vizypowerboard.VizyPowerBoard.measure">measure</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.power_off" href="#vizypowerboard.VizyPowerBoard.power_off">power_off</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.power_off_requested" href="#vizypowerboard.VizyPowerBoard.power_off_requested">power_off_requested</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.power_on_alarm_date" href="#vizypowerboard.VizyPowerBoard.power_on_alarm_date">power_on_alarm_date</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.power_on_alarm_seconds" href="#vizypowerboard.VizyPowerBoard.power_on_alarm_seconds">power_on_alarm_seconds</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.power_on_source" href="#vizypowerboard.VizyPowerBoard.power_on_source">power_on_source</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.resource_url" href="#vizypowerboard.VizyPowerBoard.resource_url">resource_url</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.rtc" href="#vizypowerboard.VizyPowerBoard.rtc">rtc</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.rtc_adjust" href="#vizypowerboard.VizyPowerBoard.rtc_adjust">rtc_adjust</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.rtc_set_system_datetime" href="#vizypowerboard.VizyPowerBoard.rtc_set_system_datetime">rtc_set_system_datetime</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.uuid" href="#vizypowerboard.VizyPowerBoard.uuid">uuid</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.vcc12" href="#vizypowerboard.VizyPowerBoard.vcc12">vcc12</a></code></li> | ||
+ | <li><code><a title="vizypowerboard.VizyPowerBoard.vcc5" href="#vizypowerboard.VizyPowerBoard.vcc5">vcc5</a></code></li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | </ul> | ||
+ | </li> | ||
+ | </ul> | ||
+ | </nav> | ||
+ | </main> | ||
+ | <footer id="footer"> | ||
+ | <p>Generated by <a href="https://pdoc3.github.io/pdoc"><cite>pdoc</cite> 0.9.2</a>.</p> | ||
+ | </footer> | ||
+ | </body> | ||
+ | </html> | ||
+ | </HTML> | ||